diff --git a/.gitattributes b/.gitattributes index fdd31021f72..7d1fdfe33e5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -11,6 +11,9 @@ *.jpg binary *.dxf binary *.mpy binary +*.deb binary +*.zip binary +*.pdf binary # These should also not be modified by git. tests/basics/string_cr_conversion.py -text diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000000..0268d4ce0e8 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,192 @@ +name: Build CI + +on: [push, pull_request, release] + +jobs: + test: + runs-on: ubuntu-16.04 + steps: + - name: Dump GitHub context + env: + GITHUB_CONTEXT: ${{ toJson(github) }} + run: echo "$GITHUB_CONTEXT" + - name: Fail if not a release publish # workaround has `on` doesn't have this filter + run: exit 1 + if: github.event_name == 'release' && (github.event.action != 'published' && github.event.action != 'rerequested') + - name: Set up Python 3.5 + uses: actions/setup-python@v1 + with: + python-version: 3.5 + - name: Install deps + run: | + sudo apt-get install -y gettext librsvg2-bin + pip install requests sh click setuptools cpp-coveralls Sphinx sphinx-rtd-theme recommonmark sphinxcontrib-svg2pdfconverter polib pyyaml + - name: Versions + run: | + gcc --version + python3 --version + - uses: actions/checkout@v1 + with: + submodules: true + - name: CircuitPython version + run: git describe --dirty --always --tags + - name: Build mpy-cross + run: make -C mpy-cross -j2 + - name: Build unix port + run: | + make -C ports/unix deplibs -j2 + make -C ports/unix -j2 + make -C ports/unix coverage -j2 + - name: Test all + run: MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 + working-directory: tests + - name: Print failure info + run: | + for exp in *.exp; + do testbase=$(basename $exp .exp); + echo -e "\nFAILURE $testbase"; + diff -u $testbase.exp $testbase.out; + done + working-directory: tests + if: failure() + - name: Test threads + run: MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 -d thread + working-directory: tests + - name: Native Tests + run: MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --emit native + working-directory: tests + - name: mpy Tests + run: MICROPY_CPYTHON3=python3.5 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -j1 --via-mpy -d basics float + working-directory: tests + - name: Docs + run: sphinx-build -E -W -b html . _build/html + - name: Translations + run: make check-translate + - name: New boards check + run: python3 -u ci_new_boards_check.py + working-directory: tools + + build-arm: + runs-on: ubuntu-16.04 + strategy: + fail-fast: false + matrix: + board: + - "arduino_mkr1300" + - "arduino_mkrzero" + - "arduino_zero" + - "bast_pro_mini_m0" + - "capablerobot_usbhub" + - "catwan_usbstick" + - "circuitplayground_bluefruit" + - "circuitplayground_express" + - "circuitplayground_express_crickit" + - "cp32-m4" + - "datalore_ip_m4" + - "datum_distance" + - "datum_imu" + - "datum_light" + - "datum_weather" + - "electronut_labs_blip" + - "electronut_labs_papyr" + - "escornabot_makech" + - "feather_m0_adalogger" + - "feather_m0_basic" + - "feather_m0_express" + - "feather_m0_express_crickit" + - "feather_m0_rfm69" + - "feather_m0_rfm9x" + - "feather_m0_supersized" + - "feather_m4_express" + - "feather_nrf52840_express" + - "feather_radiofruit_zigbee" + - "gemma_m0" + - "grandcentral_m4_express" + - "hallowing_m0_express" + - "hallowing_m4_express" + - "itsybitsy_m0_express" + - "itsybitsy_m4_express" + - "kicksat-sprite" + - "makerdiary_nrf52840_mdk" + - "makerdiary_nrf52840_mdk_usb_dongle" + - "meowmeow" + - "metro_m0_express" + - "metro_m4_airlift_lite" + - "metro_m4_express" + - "metro_nrf52840_express" + - "mini_sam_m4" + - "monster_m4sk" + - "particle_argon" + - "particle_boron" + - "particle_xenon" + - "pca10056" + - "pca10059" + - "pewpew10" + - "pirkey_m0" + - "pybadge" + - "pybadge_airlift" + - "pygamer" + - "pygamer_advance" + - "pyportal" + - "pyportal_titano" + - "pyruler" + - "robohatmm1_m0" + - "robohatmm1_m4" + - "sam32" + - "snekboard" + - "sparkfun_lumidrive" + - "sparkfun_nrf52840_mini" + - "sparkfun_redboard_turbo" + - "sparkfun_samd21_dev" + - "sparkfun_samd21_mini" + - "trellis_m4_express" + - "trinket_m0" + - "trinket_m0_haxpress" + - "uchip" + - "ugame10" + + steps: + - name: Set up Python 3.5 + uses: actions/setup-python@v1 + with: + python-version: 3.5 + - name: Install deps + run: | + sudo apt-get install -y gettext + pip install requests sh click setuptools awscli + wget https://s3.amazonaws.com/adafruit-circuit-python/gcc-arm-embedded_7-2018q2-1~xenial1_amd64.deb && sudo dpkg -i gcc-arm-embedded*_amd64.deb + - name: Versions + run: | + gcc --version + arm-none-eabi-gcc --version + python3 --version + - uses: actions/checkout@v1 + with: + submodules: true + - name: mpy-cross + run: make -C mpy-cross -j2 + - name: build + run: python3 -u build_release_files.py + working-directory: tools + env: + BOARDS: ${{ matrix.board }} + - uses: actions/upload-artifact@v1.0.0 + with: + name: ${{ matrix.board }} + path: bin/${{ matrix.board }} + - name: Upload to S3 + run: aws s3 cp bin/ s3://adafruit-circuit-python/bin/ --recursive --no-progress --region us-east-1 + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + if: github.event_name == 'push' || (github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested')) + - name: Install upload deps + run: | + pip install uritemplate + - name: Upload to Release + run: python3 -u upload_release_files.py + working-directory: tools + env: + UPLOAD_URL: ${{ github.event.release.upload_url }} + ADABOT_GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} + if: github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested') diff --git a/.github/workflows/create_website_pr.yml b/.github/workflows/create_website_pr.yml new file mode 100644 index 00000000000..9ba1110eb8c --- /dev/null +++ b/.github/workflows/create_website_pr.yml @@ -0,0 +1,38 @@ +name: Update CircuitPython.org + +on: release + +jobs: + website: + runs-on: ubuntu-latest + steps: + - name: Dump GitHub context + env: + GITHUB_CONTEXT: ${{ toJson(github) }} + run: echo "$GITHUB_CONTEXT" + - name: Fail if not a release publish # workaround has `on` doesn't have this filter + run: exit 1 + if: github.event.action != 'published' + - name: Set up Python 3.5 + uses: actions/setup-python@v1 + with: + python-version: 3.5 + - name: Install deps + run: | + pip install requests sh click + - name: Versions + run: | + gcc --version + python3 --version + - uses: actions/checkout@v1 + with: + submodules: true + - name: CircuitPython version + run: git describe --dirty --always --tags + - name: Website + run: python3 build_board_info.py + working-directory: tools + env: + RELEASE_TAG: ${{ github.event.release.tag_name }} + ADABOT_GITHUB_ACCESS_TOKEN: ${{ secrets.ADABOT_GITHUB_ACCESS_TOKEN }} + if: github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested') diff --git a/.gitignore b/.gitignore index 5e841a89c05..3e5bd283004 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ ################### *.o *.a +!atmel-samd/asf/**/*.a *.elf *.bin *.map @@ -11,6 +12,8 @@ # Packages ############ +dist/ +*.egg-info # Logs and Databases ###################### @@ -23,6 +26,8 @@ # Build directory ###################### build/ +bin/ +circuitpython-stubs/ # Test failure outputs ###################### @@ -39,6 +44,30 @@ __pycache__/ GNUmakefile user.props +# Sphinx output +############### +_build + # Generated rst files ###################### genrst/ + +# ctags and similar +################### +TAGS + +# Merge leftovers +################# +*.orig + +# Emacs backup files +#################### +*~ + +*.DS_Store + +# POEdit mo files +#################### +*.mo + +.vscode diff --git a/.gitmodules b/.gitmodules index c3f4c55aca2..7b57cab5479 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,13 +5,96 @@ [submodule "lib/libffi"] path = lib/libffi url = https://github.com/atgreen/libffi -[submodule "lib/lwip"] - path = lib/lwip - url = https://git.savannah.gnu.org/r/lwip.git [submodule "lib/berkeley-db-1.xx"] path = lib/berkeley-db-1.xx url = https://github.com/pfalcon/berkeley-db-1.xx +[submodule "lib/uzlib"] + path = lib/uzlib + url = https://github.com/pfalcon/uzlib +[submodule "tools/uf2"] + path = tools/uf2 + url = https://github.com/Microsoft/uf2.git +[submodule "atmel-samd/frozen/Adafruit_CircuitPython_NeoPixel"] + path = frozen/Adafruit_CircuitPython_NeoPixel + url = https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel +[submodule "frozen/Adafruit_CircuitPython_Thermistor"] + path = frozen/Adafruit_CircuitPython_Thermistor + url = https://github.com/adafruit/Adafruit_CircuitPython_Thermistor.git +[submodule "frozen/Adafruit_CircuitPython_LIS3DH"] + path = frozen/Adafruit_CircuitPython_LIS3DH + url = https://github.com/adafruit/Adafruit_CircuitPython_LIS3DH.git +[submodule "frozen/Adafruit_CircuitPython_BusDevice"] + path = frozen/Adafruit_CircuitPython_BusDevice + url = https://github.com/adafruit/Adafruit_CircuitPython_BusDevice.git +[submodule "tools/python-semver"] + path = tools/python-semver + url = https://github.com/k-bx/python-semver.git [submodule "lib/stm32lib"] path = lib/stm32lib url = https://github.com/micropython/stm32lib branch = work-F4-1.13.1+F7-1.5.0+L4-1.3.0 +[submodule "atmel-samd/asf4"] + path = ports/atmel-samd/asf4 + url = https://github.com/adafruit/asf4.git + branch = circuitpython +[submodule "tools/usb_descriptor"] + path = tools/usb_descriptor + url = https://github.com/adafruit/usb_descriptor.git +[submodule "lib/nrfutil"] + path = lib/nrfutil + url = https://github.com/adafruit/nRF52_nrfutil +[submodule "ports/atmel-samd/freetouch"] + path = ports/atmel-samd/freetouch + url = https://github.com/adafruit/Adafruit_FreeTouch.git +[submodule "frozen/Adafruit_CircuitPython_CircuitPlayground"] + path = frozen/Adafruit_CircuitPython_CircuitPlayground + url = https://github.com/adafruit/Adafruit_CircuitPython_CircuitPlayground.git +[submodule "frozen/Adafruit_CircuitPython_HID"] + path = frozen/Adafruit_CircuitPython_HID + url = https://github.com/adafruit/Adafruit_CircuitPython_HID.git +[submodule "ports/atmel-samd/Adafruit_CircuitPython_Motor"] + path = frozen/Adafruit_CircuitPython_Motor + url = https://github.com/adafruit/Adafruit_CircuitPython_Motor.git +[submodule "ports/atmel-samd/Adafruit_CircuitPython_seesaw"] + path = frozen/Adafruit_CircuitPython_seesaw + url = https://github.com/adafruit/Adafruit_CircuitPython_seesaw.git +[submodule "frozen/Adafruit_CircuitPython_IRRemote"] + path = frozen/Adafruit_CircuitPython_IRRemote + url = https://github.com/adafruit/Adafruit_CircuitPython_IRRemote.git +[submodule "frozen/Adafruit_CircuitPython_DotStar"] + path = frozen/Adafruit_CircuitPython_DotStar + url = https://github.com/adafruit/Adafruit_CircuitPython_DotStar.git +[submodule "ports/atmel-samd/peripherals"] + path = ports/atmel-samd/peripherals + url = https://github.com/adafruit/samd-peripherals.git +[submodule "frozen/Adafruit_CircuitPython_Crickit"] + path = frozen/Adafruit_CircuitPython_Crickit + url = https://github.com/adafruit/Adafruit_CircuitPython_Crickit +[submodule "ports/nrf/nrfx"] + path = ports/nrf/nrfx + url = https://github.com/adafruit/nrfx.git +[submodule "lib/tinyusb"] + path = lib/tinyusb + url = https://github.com/hathach/tinyusb.git + branch = develop +[submodule "tools/huffman"] + path = tools/huffman + url = https://github.com/tannewt/huffman.git +[submodule "tools/adabot"] + path = tools/adabot + url = https://github.com/adafruit/adabot.git +[submodule "tools/bitmap_font"] + path = tools/bitmap_font + url = https://github.com/adafruit/Adafruit_CircuitPython_BitmapFont.git +[submodule "tools/Tecate-bitmap-fonts"] + path = tools/Tecate-bitmap-fonts + url = https://github.com/Tecate/bitmap-fonts.git +[submodule "frozen/pew-pewpew-standalone-10.x"] + path = frozen/pew-pewpew-standalone-10.x + url = https://github.com/pewpew-game/pew-pewpew-standalone-10.x.git +[submodule "frozen/circuitpython-stage"] + path = frozen/circuitpython-stage + url = https://github.com/python-ugame/circuitpython-stage.git +[submodule "ports/stm32f4/stm32f4"] + path = ports/stm32f4/stm32f4 + url = https://github.com/adafruit/stm32f4.git diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 00000000000..6ff5f2422de --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,10 @@ +# .readthedocs.yml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +version: 2 + +python: + version: 3 + install: + - requirements: docs/requirements.txt diff --git a/.rosie.yml b/.rosie.yml new file mode 100644 index 00000000000..3f7f9bb1d7b --- /dev/null +++ b/.rosie.yml @@ -0,0 +1,16 @@ +# This configuration file tells Rosie where to find prebuilt .bin files (Travis +# builds them) and where to find the tests. + +binaries: + prebuilt_s3: + bucket: adafruit-circuit-python + file_pattern: bin/{board}/adafruit-circuitpython-{board}-*-{short_sha}.{extension} + rosie_upload: + file_pattern: adafruit-circuitpython-{board}-*{short_sha}.{extension} + +circuitpython_tests: + test_directories: + - tests/basics + - tests/circuitpython + test_helper: + - tests/skip_if.py diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 35d3e051984..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,77 +0,0 @@ -sudo: required -dist: trusty -language: c -compiler: - - gcc -cache: - directories: - - "${HOME}/persist" -env: - - MAKEOPTS="-j4" - -before_script: -# Extra CPython versions -# - 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 (a specific urllib3 version is needed for requests and cpp-coveralls to work together) - - sudo pip install -Iv urllib3==1.22 - - sudo pip install cpp-coveralls - - gcc --version - - arm-none-eabi-gcc --version - - python3 --version - -script: - - make ${MAKEOPTS} -C mpy-cross - - 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' - - make ${MAKEOPTS} -C ports/unix deplibs - - make ${MAKEOPTS} -C ports/unix - - make ${MAKEOPTS} -C ports/unix nanbox - - make ${MAKEOPTS} -C ports/bare-arm - - make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test test - - make ${MAKEOPTS} -C ports/stm32 - - make ${MAKEOPTS} -C ports/stm32 BOARD=PYBV11 MICROPY_PY_WIZNET5K=5200 MICROPY_PY_CC3K=1 - - make ${MAKEOPTS} -C ports/stm32 BOARD=STM32F769DISC - - make ${MAKEOPTS} -C ports/stm32 BOARD=STM32L476DISC - - make ${MAKEOPTS} -C ports/teensy - - make ${MAKEOPTS} -C ports/cc3200 BTARGET=application BTYPE=release - - make ${MAKEOPTS} -C ports/cc3200 BTARGET=bootloader BTYPE=release - - make ${MAKEOPTS} -C ports/windows CROSS_COMPILE=i686-w64-mingw32- - - # run tests without coverage info - #- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests) - #- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests --emit native) - - # run tests with coverage info - - make ${MAKEOPTS} -C ports/unix coverage - - (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests) - - (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -d thread) - - (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests --emit native) - - (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests --via-mpy -d basics float) - - # test when input script comes from stdin - - cat tests/basics/0prelim.py | ports/unix/micropython_coverage | grep -q 'abc' - - # 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) - - # run tests on stackless build - - rm -rf ports/unix/build-coverage - - make ${MAKEOPTS} -C ports/unix coverage CFLAGS_EXTRA="-DMICROPY_STACKLESS=1 -DMICROPY_STACKLESS_STRICT=1" - - (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests) - -after_failure: - - (cd tests && for exp in *.exp; do testbase=$(basename $exp .exp); echo -e "\nFAILURE $testbase"; diff -u $testbase.exp $testbase.out; done) - - (grep "FAIL" ports/qemu-arm/build/console.out) diff --git a/CODECONVENTIONS.md b/CODECONVENTIONS.md deleted file mode 100644 index 982b9583131..00000000000 --- a/CODECONVENTIONS.md +++ /dev/null @@ -1,210 +0,0 @@ -Git commit conventions -====================== - -Each commit message should start with a directory or full file path -prefix, so it was clear which part of codebase a commit affects. If -a change affects one file, it's better to use path to a file. If it -affects few files in a subdirectory, using subdirectory as a prefix -is ok. For longish paths, it's acceptable to drop intermediate -components, which still should provide good context of a change. -It's also ok to drop file extensions. - -Besides prefix, first line of a commit message should describe a -change clearly and to the point, and be a grammatical sentence with -final full stop. First line should fit within 78 characters. Examples -of good first line of commit messages: - - py/objstr: Add splitlines() method. - py: Rename FOO to BAR. - docs/machine: Fix typo in reset() description. - ports: Switch to use lib/foo instead of duplicated code. - -After the first line, add an empty line and in following lines describe -a change in a detail, if needed. Any change beyond 5 lines would likely -require such detailed description. - -To get good practical examples of good commits and their messages, browse -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 follows [PEP 8](http://legacy.python.org/dev/peps/pep-0008/). - -Naming conventions: -- Module names are short and all lowercase; eg pyb, stm. -- Class names are CamelCase, with abreviations all uppercase; eg I2C, not - I2c. -- Function and method names are all lowercase with words separated by - a single underscore as necessary to improve readability; eg mem_read. -- Constants are all uppercase with words separated by a single underscore; - eg GPIO_IDR. - -C code conventions -================== - -When writing new C code, please adhere to the following conventions. - -White space: -- Expand tabs to 4 spaces. -- Don't leave trailing whitespace at the end of a line. -- For control blocks (if, for, while), put 1 space between the - keyword and the opening parenthesis. -- Put 1 space after a comma, and 1 space around operators. - -Braces: -- Use braces for all blocks, even no-line and single-line pieces of - code. -- Put opening braces on the end of the line it belongs to, not on - a new line. -- For else-statements, put the else on the same line as the previous - closing brace. - -Header files: -- Header files should be protected from multiple inclusion with #if - directives. See an existing header for naming convention. - -Names: -- Use underscore_case, not camelCase for all names. -- Use CAPS_WITH_UNDERSCORE for enums and macros. -- When defining a type use underscore_case and put '_t' after it. - -Integer types: MicroPython runs on 16, 32, and 64 bit machines, so it's -important to use the correctly-sized (and signed) integer types. The -general guidelines are: -- For most cases use mp_int_t for signed and mp_uint_t for unsigned - integer values. These are guaranteed to be machine-word sized and - therefore big enough to hold the value from a MicroPython small-int - object. -- Use size_t for things that count bytes / sizes of objects. -- You can use int/uint, but remember that they may be 16-bits wide. -- If in doubt, use mp_int_t/mp_uint_t. - -Comments: -- Be concise and only write comments for things that are not obvious. -- Use `// ` prefix, NOT `/* ... */`. No extra fluff. - -Memory allocation: -- Use m_new, m_renew, m_del (and friends) to allocate and free heap memory. - These macros are defined in py/misc.h. - -Examples --------- - -Braces, spaces, names and comments: - - #define TO_ADD (123) - - // This function will always recurse indefinitely and is only used to show - // coding style - int foo_function(int x, int some_value) { - if (x < some_value) { - foo(some_value, x); - } else { - foo(x + TO_ADD, some_value - 1); - } - - for (int my_counter = 0; my_counter < x; my_counter++) { - } - } - -Type declarations: - - typedef struct _my_struct_t { - int member; - void *data; - } 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 ` - 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 `. - -(If xref target is followed by section title, can be just -:ref:`xref_target`). -~~~ - -* Linking to external URL: -``` -`link text `_ -``` - -* 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 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000000..1617586f3ae --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,74 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +nationality, personal appearance, race, religion, or sexual identity and +orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or +advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at support@adafruit.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 06f970607b9..7477df61cfd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,8 +1,51 @@ -When reporting an issue and especially submitting a pull request, please -make sure that you are acquainted with Contributor Guidelines: +# Contributing +Please note that this project is released with a +[Contributor Code of Conduct](https://github.com/adafruit/circuitpython/blob/master/CODE_OF_CONDUCT.md). +By participating in this project you agree to abide by its terms. Participation +covers any forum used to converse about CircuitPython including unofficial and official spaces. Failure to do +so will result in corrective actions such as time out or ban from the project. -https://github.com/micropython/micropython/wiki/ContributorGuidelines +## Licensing +By contributing to this repository you are certifying that you have all necessary +permissions to license the code under an MIT License. You still retain the +copyright but are granting many permissions under the MIT License. -and Code Conventions: +If you have an employment contract with your employer please make sure that they +don't automatically own your work product. Make sure to get any necessary approvals +before contributing. Another term for this contribution off-hours is moonlighting. -https://github.com/micropython/micropython/blob/master/CODECONVENTIONS.md +## Ways to contribute +As CircuitPython grows, there are more and more ways to contribute. Here are some ideas: + +* Build a project with CircuitPython and share how to do it online. +* Test the latest libraries and CircuitPython versions with your projects and file issues for any bugs you find. +* Contribute Python code to CircuitPython libraries that support new devices or features of an existing device. +* Contribute C code to CircuitPython which fixes an open issue or adds a new feature. + +## Getting started with C +CircuitPython developer Dan Halbert (@dhalbert) has written up build instructions using native build +tools [here](https://learn.adafruit.com/building-circuitpython). + +For SAMD21 debugging workflow tips check out [this learn guide](https://learn.adafruit.com/debugging-the-samd21-with-gdb) from Scott (@tannewt). + +## Developer contacts +Scott Shawcroft ([@tannewt](https://github.com/tannewt)) is the lead developer of CircuitPython +and is sponsored by [Adafruit Industries LLC](https://adafruit.com). Scott is usually available +during US West Coast working hours. Dan Halbert ([@dhalbert](https://github.com/dhalbert)) and +Kattni Rembor ([@kattni](https://github.com/kattni)) are also sponsored by [Adafruit Industries + LLC](https://adafruit.com) and are usually available during US East Coast daytime hours including +some weekends. + +They are all reachable on [Discord](https://adafru.it/discord), GitHub issues and the [Adafruit +support forum](https://forums.adafruit.com/viewforum.php?f=60). + +## Code guidelines +We aim to keep our code and commit style compatible with MicroPython upstream. +Please review their +[code conventions](https://github.com/micropython/micropython/blob/master/CODECONVENTIONS.md) to do so. +Familiarity with their [design philosophy](https://github.com/micropython/micropython/wiki/ContributorGuidelines) +is also useful though not always applicable to CircuitPython. + +Furthermore, CircuitPython has a +[design guide](https://circuitpython.readthedocs.io/en/latest/docs/design_guide.html) +that covers a variety of different topics. Please read it as well. diff --git a/Makefile b/Makefile new file mode 100644 index 00000000000..b9c489fd404 --- /dev/null +++ b/Makefile @@ -0,0 +1,221 @@ +# Top-level Makefile for documentation builds and miscellaneous tasks. +# + +# You can set these variables from the command line. +PYTHON = python3 +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +# path to build the generated docs +BUILDDIR = _build +# path to source files to process +SOURCEDIR = . +# path to conf.py +CONFDIR = . +# Run "make FORCE= ..." to avoid rebuilding from scratch (and risk +# producing incorrect docs). +FORCE = -E +VERBOSE = -v + +# path to generated type stubs +STUBDIR = circuitpython-stubs +# Run "make VALIDATE= stubs" to avoid validating generated stub files +VALIDATE = -v +# path to pypi source distributions +DISTDIR = dist + +# Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the +# full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the +# executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +BASEOPTS = -c $(CONFDIR) $(PAPEROPT_$(PAPER)) $(FORCE) $(VERBOSE) $(SPHINXOPTS) $(SOURCEDIR) +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(BASEOPTS) +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(BASEOPTS) + +TRANSLATE_SOURCES = extmod lib main.c ports/atmel-samd ports/nrf py shared-bindings shared-module supervisor + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext stubs + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + rm -rf $(STUBDIR) $(DISTDIR) *.egg-info + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/MicroPython.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/MicroPython.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/MicroPython" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/MicroPython" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +# seems to be malfunctioning +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +# seems to be malfunctioning +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +# seems to be malfunctioning +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +# seems to be malfunctioning +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." + +# phony target so we always run +all-source: + +locale/circuitpython.pot: all-source + find $(TRANSLATE_SOURCES) -iname "*.c" -print0 | (LC_ALL=C sort -z) | xargs -0 xgettext -L C -s --add-location=file --keyword=translate -o circuitpython.pot -p locale + +translate: locale/circuitpython.pot + for po in $(shell ls locale/*.po); do msgmerge -U $$po -s --no-fuzzy-matching --add-location=file locale/circuitpython.pot; done + +check-translate: locale/circuitpython.pot $(wildcard locale/*.po) + $(PYTHON) tools/check_translations.py $^ + +stubs: + rst2pyi $(VALIDATE) shared-bindings/ $(STUBDIR) + python setup.py sdist + +update-frozen-libraries: + @echo "Updating all frozen libraries to latest tagged version." + cd frozen; for library in *; do cd $$library; ../../tools/git-checkout-latest-tag.sh; cd ..; done diff --git a/README.md b/README.md deleted file mode 100644 index 44d062e8771..00000000000 --- a/README.md +++ /dev/null @@ -1,174 +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 -======================= -

- MicroPython Logo -

- -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 (be sure - to select needed board/port at the bottom left corner). - -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/ -- an experimental port for ESP8266 WiFi modules. -- 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 (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): - - $ git submodule update --init - $ cd ports/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 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, first fetch git submodules for them: - - $ git submodule update --init - -Use the same command to get the latest versions of dependencies, as -they are updated from time to time. After that, in the port directory -(e.g. `ports/unix/`), 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. They still need to be fetched with the git submodule command -above. - -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: - - $ git submodule update --init - $ cd ports/stm32 - $ 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. diff --git a/README.rst b/README.rst new file mode 100644 index 00000000000..f5f9cccea21 --- /dev/null +++ b/README.rst @@ -0,0 +1,222 @@ +CircuitPython +============= + +.. image:: https://s3.amazonaws.com/adafruit-circuit-python/CircuitPython_Repo_header_logo.png + +|Build Status| |Doc Status| |License| |Discord| + +`circuitpython.org `__ \| `Get CircuitPython <#get-circuitpython>`__ \| +`Documentation <#documentation>`__ \| `Contributing <#contributing>`__ \| +`Branding <#branding>`__ \| `Differences from Micropython <#differences-from-micropython>`__ \| +`Project Structure <#project-structure>`__ + +**CircuitPython** is a *beginner friendly*, open source version of Python for tiny, inexpensive +computers called microcontrollers. Microcontrollers are the brains of many electronics including a +wide variety of development boards used to build hobby projects and prototypes. CircuitPython in +electronics is one of the best ways to learn to code because it connects code to reality. Simply +install CircuitPython on a supported board via drag and drop and then edit a ``code.py`` file on +the CIRCUITPY drive. The code will automatically reload. No software installs are needed besides a +text editor (we recommend `Mu `_ for beginners.) + +CircuitPython features unified Python core APIs and a growing list of 150+ device libraries and +drivers that work with it. These libraries also work on single board computers with regular +Python via the `Adafruit Blinka Library `_. + +CircuitPython is based on `MicroPython `_. See +`below <#differences-from-micropython>`_ for differences. CircuitPython development is sponsored by +`Adafruit `_ and is available on their educational development boards. Please +support both MicroPython and Adafruit. + +Get CircuitPython +------------------ + +Official binaries for all supported boards are available through +`circuitpython.org/downloads `_. The site includes stable, unstable and +continuous builds. Full release notes and assets are available through +`GitHub releases `_ as well. + +Documentation +------------- + +Guides and videos are available through the `Adafruit Learning +System `__ under the `CircuitPython +category `__. An API +reference is also available on `Read the Docs +`__. A collection of awesome +resources can be found at `Awesome CircuitPython `__. + +Specifically useful documentation when starting out: + +- `Welcome to CircuitPython `__ +- `CircuitPython Essentials `__ +- `Example Code `__ + +Contributing +------------ + +See +`CONTRIBUTING.md `__ +for full guidelines but please be aware that by contributing to this +project you are agreeing to the `Code of +Conduct `__. +Contributors who follow the `Code of +Conduct `__ +are welcome to submit pull requests and they will be promptly reviewed +by project admins. Please join the +`Discord `__ too. + +Branding +------------ + +While we are happy to see CircuitPython forked and modified, we'd appreciate it if forked releases +not use the name "CircuitPython" or the Blinka logo. "CircuitPython" means something special to +us and those who learn about it. As a result, we'd like to make sure products referring to it meet a +common set of requirements. + +If you'd like to use the term "CircuitPython" and Blinka for your product here is what we ask: + +* Your product is supported by the primary + `"adafruit/circuitpython" `_ repo. This way we can + update any custom code as we update the CircuitPython internals. +* Your product is listed on `circuitpython.org `__ (source + `here `_). This is to ensure that a user of your + product can always download the latest version of CircuitPython from the standard place. +* Your product has a user accessible USB plug which appears as a CIRCUITPY drive when plugged in. + +If you choose not to meet these requirements, then we ask you call your version of CircuitPython +something else (for example, SuperDuperPython) and not use the Blinka logo. You can say it is +"CircuitPython-compatible" if most CircuitPython drivers will work with it. + +-------------- + +Differences from `MicroPython `__ +----------------------------------------------------------------------------- + +CircuitPython: + +- includes ports for MicroChip SAMD21 (Commonly known as M0 in Adafruit + product names) and SAMD51 (M4). +- supports only SAMD21, SAMD51, and nRF52840 ports. +- tracks MicroPython's releases (not master). +- floats (aka decimals) are enabled for all builds. +- error messages are translated into 10+ languages. +- does not support concurrency within Python (including interrupts and threading). Some concurrency + is achieved with native modules for tasks that require it such as audio file playback. + +Behavior +~~~~~~~~ + +- The order that files are run and the state that is shared between + them. CircuitPython's goal is to clarify the role of each file and + make each file independent from each other. +- ``boot.py`` (or ``settings.py``) runs only once on start up before + USB is initialized. This lays the ground work for configuring USB at + startup rather than it being fixed. Since serial is not available, + output is written to ``boot_out.txt``. +- ``code.py`` (or ``main.py``) is run after every reload until it + finishes or is interrupted. After it is done running, the vm and + hardware is reinitialized. **This means you cannot read state from** + ``code.py`` **in the REPL anymore.** CircuitPython's goal for this + change includes reduce confusion about pins and memory being used. +- After ``code.py`` the REPL can be entered by pressing any key. It no + longer shares state with ``code.py`` so it is a fresh vm. +- Autoreload state will be maintained across reload. +- Adds a safe mode that does not run user code after a hard crash or + brown out. The hope is that this will make it easier to fix code that + causes nasty crashes by making it available through mass storage + after the crash. A reset (the button) is needed after its fixed to + get back into normal mode. +- RGB status LED indicating CircuitPython state, and errors through a sequence of colored flashes. +- Re-runs ``code.py`` or other main file after file system writes over USB mass storage. (Disable with + ``samd.disable_autoreload()``) +- Entering the REPL after the main code is finished requires a key press which enters the REPL and + disables autoreload. +- Main is one of these: ``code.txt``, ``code.py``, ``main.py``, + ``main.txt`` +- Boot is one of these: ``settings.txt``, ``settings.py``, ``boot.py``, + ``boot.txt`` + +API +~~~ + +- Unified hardware APIs. Documented + `on ReadTheDocs `_. +- API docs are rST within the C files in ``shared-bindings``. +- No ``machine`` API. + +Modules +~~~~~~~ + +- No module aliasing. (``uos`` and ``utime`` are not available as + ``os`` and ``time`` respectively.) Instead ``os``, ``time``, and + ``random`` are CPython compatible. +- New ``storage`` module which manages file system mounts. + (Functionality from ``uos`` in MicroPython.) +- Modules with a CPython counterpart, such as ``time``, ``os`` and + ``random``, are strict + `subsets `__ + of their `CPython + version `__. + Therefore, code from CircuitPython is runnable on CPython but not + necessarily the reverse. +- tick count is available as + `time.monotonic() `__ + +-------------- + +Project Structure +----------------- + +Here is an overview of the top-level source code directories. + +Core +~~~~ + +The core code of +`MicroPython `__ is shared +amongst ports including CircuitPython: + +- ``docs`` High level user documentation in Sphinx reStructuredText + format. +- ``drivers`` External device drivers written in Python. +- ``examples`` A few example Python scripts. +- ``extmod`` Shared C code used in multiple ports' modules. +- ``lib`` Shared core C code including externally developed libraries + such as FATFS. +- ``logo`` The CircuitPython logo. +- ``mpy-cross`` A cross compiler that converts Python files to byte + code prior to being run in MicroPython. Useful for reducing library + size. +- ``py`` Core Python implementation, including compiler, runtime, and + core library. +- ``shared-bindings`` Shared definition of Python modules, their docs + and backing C APIs. Ports must implement the C API to support the + corresponding module. +- ``shared-module`` Shared implementation of Python modules that may be + based on ``common-hal``. +- ``tests`` Test framework and test scripts. +- ``tools`` Various tools, including the pyboard.py module. + +Ports +~~~~~ + +Ports include the code unique to a microcontroller line and also +variations based on the board. + +- ``atmel-samd`` Support for SAMD21 and SAMD51 based boards. +- ``nrf`` Support for the nRF52840 based boards. +- ``unix`` Support for UNIX. Only used for automated testing. + +The remaining port directories not listed above are in the repo to maintain compatibility with the +`MicroPython `__ parent project. + +`back to top <#circuitpython>`__ + +.. |Build Status| image:: https://travis-ci.com/adafruit/circuitpython.svg?branch=master + :target: https://travis-ci.org/adafruit/circuitpython +.. |Doc Status| image:: https://readthedocs.org/projects/circuitpython/badge/?version=latest + :target: http://circuitpython.readthedocs.io/ +.. |Discord| image:: https://img.shields.io/discord/327254708534116352.svg + :target: https://adafru.it/discord +.. |License| image:: https://img.shields.io/badge/License-MIT-brightgreen.svg + :target: https://choosealicense.com/licenses/mit/ diff --git a/conf.py b/conf.py new file mode 100644 index 00000000000..3df958fe1fc --- /dev/null +++ b/conf.py @@ -0,0 +1,374 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# MicroPython documentation build configuration file, created by +# sphinx-quickstart on Sun Sep 21 11:42:03 2014. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import json +import sys +import os + +from recommonmark.parser import CommonMarkParser + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath('docs')) +sys.path.insert(0, os.path.abspath('.')) + +import shared_bindings_matrix + +master_doc = 'docs/index' + +# Grab the JSON values to use while building the module support matrix +# in 'shared-bindings/index.rst' + +#modules_support_matrix = shared_bindings_matrix.support_matrix_excluded_boards() +modules_support_matrix = shared_bindings_matrix.support_matrix_by_board() + +html_context = { + 'support_matrix': modules_support_matrix +} + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = '1.3' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.doctest', + 'sphinxcontrib.rsvgconverter', + 'sphinx.ext.intersphinx', + 'sphinx.ext.todo', + 'sphinx.ext.coverage', + 'rstjinja', + 'c2rst' +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['templates'] + +# The suffix of source filenames. +source_suffix = ['.rst', '.md', '.c', '.h'] + +source_parsers = {'.md': CommonMarkParser} + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +#master_doc = 'index' + +# General information about the project. +project = 'Adafruit CircuitPython' +copyright = '2014-2018, MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)' + +# These are overwritten on ReadTheDocs. +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# We don't follow "The short X.Y version" vs "The full version, including alpha/beta/rc tags" +# breakdown, so use the same version identifier for both to avoid confusion. +version = release = '0.0.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ["**/build*", + ".git", + ".venv", + ".direnv", + "docs/README.md", + "drivers", + "examples", + "extmod", + "frozen", + "lib", + "main.c", + "mpy-cross", + "ports/*/*.c", + "ports/*/*.h", + "ports/*/boards", + "ports/*/common-hal", + "ports/*/supervisor", + "ports/atmel-samd/asf4", + "ports/atmel-samd/asf4_conf", + "ports/atmel-samd/external_flash", + "ports/atmel-samd/freetouch", + "ports/atmel-samd/peripherals", + "ports/atmel-samd/QTouch", + "ports/atmel-samd/tools", + "ports/bare-arm", + "ports/cc3200", + "ports/cc3200/FreeRTOS", + "ports/cc3200/hal", + "ports/esp32", + "ports/esp8266/boards", + "ports/esp8266/common-hal", + "ports/esp8266/modules", + "ports/minimal", + "ports/nrf/device", + "ports/nrf/bluetooth", + "ports/nrf/modules", + "ports/nrf/nrfx", + "ports/nrf/peripherals", + "ports/nrf/usb", + "ports/stm32f4/stm32f4", + "ports/stm32f4/peripherals", + "ports/stm32f4/ref", + "ports/stm32f4/README.md", + "ports/pic16bit", + "ports/qemu-arm", + "ports/stm32", + "ports/stm32/hal", + "ports/stm32/cmsis", + "ports/stm32/usbdev", + "ports/stm32/usbhost", + "ports/teensy", + "ports/unix", + "ports/windows", + "ports/zephyr", + "py", + "shared-bindings/util.*", + "shared-module", + "supervisor", + "tests", + "tools"] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +default_role = 'any' + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + +# Global include files. Sphinx docs suggest using rst_epilog in preference +# of rst_prolog, so we follow. Absolute paths below mean "from the base +# of the doctree". +rst_epilog = """ +.. include:: /docs/templates/replace.inc +""" + +# -- Options for HTML output ---------------------------------------------- + +# on_rtd is whether we are on readthedocs.org +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' + +if not on_rtd: # only import and set the theme if we're building docs locally + try: + import sphinx_rtd_theme + html_theme = 'sphinx_rtd_theme' + html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.'] + except: + html_theme = 'default' + html_theme_path = ['.'] +else: + html_theme_path = ['.'] + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = ['.'] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = '../../logo/trans-logo.png' + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +html_favicon = 'docs/static/favicon.ico' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['docs/static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +html_last_updated_fmt = '%d %b %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {"index": "topindex.html"} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'CircuitPythondoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +# Include 3 levels of headers in PDF ToC +'preamble': '\setcounter{tocdepth}{2}', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'CircuitPython.tex', 'CircuitPython Documentation', + 'CircuitPython Contributors', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'CircuitPython', 'CircuitPython Documentation', + ['CircuitPython contributors'], 1), +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'CircuitPython', 'CircuitPython Documentation', + 'CircuitPython contributors', 'CircuitPython', 'Python for Microcontrollers.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {"cpython": ('https://docs.python.org/3/', None), + "bus_device": ('https://circuitpython.readthedocs.io/projects/busdevice/en/latest/', None), + "register": ('https://circuitpython.readthedocs.io/projects/register/en/latest/', None)} + +def setup(app): + app.add_stylesheet("customstyle.css") diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index e9c128e9007..00000000000 --- a/docs/Makefile +++ /dev/null @@ -1,191 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -PYTHON = python3 -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = build/$(MICROPY_PORT) -CPYDIFFDIR = ../tools -CPYDIFF = gen-cpydiff.py -GENRSTDIR = genrst -# Run "make FORCE= ..." to avoid rebuilding from scratch (and risk -# producing incorrect docs). -FORCE = -E - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - @echo " cpydiff to generate the MicroPython differences from CPython" - -clean: - rm -rf $(BUILDDIR)/* - rm -f $(GENRSTDIR)/* - -cpydiff: - @echo "Generating MicroPython Differences." - rm -f $(GENRSTDIR)/* - cd $(CPYDIFFDIR) && $(PYTHON) $(CPYDIFF) - -html: cpydiff - $(SPHINXBUILD) $(FORCE) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/MicroPython.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/MicroPython.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/MicroPython" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/MicroPython" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: cpydiff - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: cpydiff - $(SPHINXBUILD) $(FORCE) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: cpydiff - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/docs/README.md b/docs/README.md index faf386710a0..b01ae9d491d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,40 +1,48 @@ -MicroPython Documentation +Adafruit's CircuitPython Documentation ========================= -The MicroPython documentation can be found at: -http://docs.micropython.org/en/latest/ +The latest documentation can be found at: +http://circuitpython.readthedocs.io/en/latest/ -The documentation you see there is generated from the files in the docs tree: -https://github.com/micropython/micropython/tree/master/docs +The documentation you see there is generated from the files in the whole tree: +https://github.com/adafruit/circuitpython/tree/master Building the documentation locally ---------------------------------- -If you're making changes to the documentation, you may want to build the +If you're making changes to the documentation, you should build the documentation locally so that you can preview your changes. -Install Sphinx, and optionally (for the RTD-styling), sphinx_rtd_theme, +Install Sphinx, recommonmark, and optionally (for the RTD-styling), sphinx_rtd_theme, preferably in a virtualenv: pip install sphinx + pip install recommonmark pip install sphinx_rtd_theme -In `micropython/docs`, build the docs: +In `circuitpython/`, build the docs: - make MICROPY_PORT= html + make html -Where `` can be `unix`, `pyboard`, `wipy` or `esp8266`. +You'll find the index page at `_build/html/index.html`. -You'll find the index page at `micropython/docs/build//html/index.html`. +### More flexibility -PDF manual generation ---------------------- +Running `make` by itself will list out the multiple doc generating commands available. -This can be achieved with: +All commands will, by default, run with `-E` (forces a rebuild from scratch of docs) and `-v` (verbosity level 1). This can be customized as desired: - make MICROPY_PORT= latexpdf + # will turn OFF the force rebuild + make html FORCE= + + # will turn OFF the verbosity + make html VERBOSE= + + # will turn OFF the force rebuild and make it doubly verbose when running + make html FORCE= VERBOSE="-v -v" -but require rather complete install of LaTeX with various extensions. On -Debian/Ubuntu, try (500MB+ download): +You can also pass other options to sphinx by using `SPHINXOPTS`. - apt-get install texlive-latex-recommended texlive-latex-extra + make html SPHINXOPTS="-T" + +For more flexibility and customization, take a look at the Makefile for all variables you can pass in and overwrite. diff --git a/docs/c2rst.py b/docs/c2rst.py new file mode 100644 index 00000000000..76489dca30f --- /dev/null +++ b/docs/c2rst.py @@ -0,0 +1,31 @@ +def c2rst(app, docname, source): + """ Pre-parse '.c' & '.h' files that contain rST source. + """ + # Make sure we're outputting HTML + if app.builder.format != 'html': + return + + fname = app.env.doc2path(docname) + if (not fname.endswith(".c") and + not fname.endswith(".h")): + #print("skipping:", fname) + return + + src = source[0] + + stripped = [] + for line in src.split("\n"): + line = line.strip() + if line == "//|": + stripped.append("") + elif line.startswith("//| "): + stripped.append(line[len("//| "):]) + stripped = "\r\n".join(stripped) + + rendered = app.builder.templates.render_string( + stripped, app.config.html_context + ) + source[0] = rendered + +def setup(app): + app.connect("source-read", c2rst) diff --git a/docs/common_hal.md b/docs/common_hal.md new file mode 100644 index 00000000000..024c1582c22 --- /dev/null +++ b/docs/common_hal.md @@ -0,0 +1,87 @@ +# Adding ``*io`` support to other ports +`digitalio` provides a well-defined, cross-port hardware abstraction layer built to support different devices and their drivers. It's backed by the Common HAL, a C api suitable for supporting different hardware in a similar manner. By sharing this C api, developers can support new hardware easily and cross-port functionality to the new hardware. + +These instructions also apply to `analogio`, `busio`, `pulseio` and `touchio`. Most drivers depend on `analogio`, `digitalio` and `busio` so start with those. + +## File layout +Common HAL related files are found in these locations: + +* `shared-bindings` Shared home for the Python <-> C bindings which includes inline RST documentation for the created interfaces. The common hal functions are defined in the .h files of the corresponding C files. +* `shared-modules` Shared home for C code built on the Common HAL and used by all ports. This code only uses `common_hal` methods defined in `shared-bindings`. +* `/common-hal` Port-specific implementation of the Common HAL. + +Each folder has the substructure of / and they should match 1:1. `__init__.c` is used for module globals that are not classes (similar to `__init__.py`). + +## Adding support + +### Modifying the build +The first step is to hook the `shared-bindings` into your build for the modules you wish to support. Here's an example of this step for the `atmel-samd/Makefile`: + +``` +SRC_BINDINGS = \ + board/__init__.c \ + microcontroller/__init__.c \ + microcontroller/Pin.c \ + analogio/__init__.c \ + analogio/AnalogIn.c \ + analogio/AnalogOut.c \ + digitalio/__init__.c \ + digitalio/DigitalInOut.c \ + pulseio/__init__.c \ + pulseio/PulseIn.c \ + pulseio/PulseOut.c \ + pulseio/PWMOut.c \ + busio/__init__.c \ + busio/I2C.c \ + busio/SPI.c \ + busio/UART.c \ + neopixel_write/__init__.c \ + time/__init__.c \ + usb_hid/__init__.c \ + usb_hid/Device.c + +SRC_BINDINGS_EXPANDED = $(addprefix shared-bindings/, $(SRC_BINDINGS)) \ + $(addprefix common-hal/, $(SRC_BINDINGS)) + +# Add the resulting objects to the full list +OBJ += $(addprefix $(BUILD)/, $(SRC_BINDINGS_EXPANDED:.c=.o)) +# Add the sources for QSTR generation +SRC_QSTR += $(SRC_C) $(SRC_BINDINGS_EXPANDED) $(STM_SRC_C) +``` + +The `Makefile` defines the modules to build and adds the sources to include the `shared-bindings` version and the `common-hal` version within the port specific directory. You may comment out certain subfolders to reduce the number of modules to add but don't comment out individual classes. It won't compile then. + +### Hooking the modules in +Built in modules are typically defined in `mpconfigport.h`. To add support you should have something like: + +``` +extern const struct _mp_obj_module_t microcontroller_module; +extern const struct _mp_obj_module_t analogio_module; +extern const struct _mp_obj_module_t digitalio_module; +extern const struct _mp_obj_module_t pulseio_module; +extern const struct _mp_obj_module_t busio_module; +extern const struct _mp_obj_module_t board_module; +extern const struct _mp_obj_module_t time_module; +extern const struct _mp_obj_module_t neopixel_write_module; + +#define MICROPY_PORT_BUILTIN_MODULES \ + { MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)µcontroller_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_digitalio), (mp_obj_t)&digitalio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_busio), (mp_obj_t)&busio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&board_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write),(mp_obj_t)&neopixel_write_module } \ +``` + +### Implementing the Common HAL +At this point in the port, nothing will compile yet, because there's still work to be done to fix missing sources, compile issues, and link issues. I suggest start with a common-hal directory from another port that implements it such as `atmel-samd` or `esp8266`, deleting the function contents and stubbing out any return statements. Once that is done, you should be able to compile cleanly and import the modules, but nothing will work (though you are getting closer). + +The last step is actually implementing each function in a port specific way. I can't help you with this. :-) If you have any questions how a Common HAL function should work then see the corresponding .h file in `shared-bindings`. + +### Testing +Woohoo! You are almost done. After you implement everything, lots of drivers and sample code should just work. There are a number of drivers and examples written for Adafruit's Feather ecosystem. Here are places to start: + +* [Adafruit repos with CircuitPython topic](https://github.com/search?q=topic%3Acircuitpython+org%3Aadafruit+fork%3Atrue) +* [Adafruit driver bundle](https://github.com/adafruit/Adafruit_CircuitPython_Bundle) diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100755 index bb8faea88e3..00000000000 --- a/docs/conf.py +++ /dev/null @@ -1,346 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# MicroPython documentation build configuration file, created by -# sphinx-quickstart on Sun Sep 21 11:42:03 2014. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys -import os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath('.')) - -# Work out the port to generate the docs for -from collections import OrderedDict -micropy_port = os.getenv('MICROPY_PORT') or 'pyboard' -tags.add('port_' + micropy_port) -ports = OrderedDict(( - ('unix', 'unix'), - ('pyboard', 'the pyboard'), - ('wipy', 'the WiPy'), - ('esp8266', 'the ESP8266'), -)) - -# The members of the html_context dict are available inside topindex.html -micropy_version = os.getenv('MICROPY_VERSION') or 'latest' -micropy_all_versions = (os.getenv('MICROPY_ALL_VERSIONS') or 'latest').split(',') -url_pattern = '%s/en/%%s/%%s' % (os.getenv('MICROPY_URL_PREFIX') or '/',) -html_context = { - 'port':micropy_port, - 'port_name':ports[micropy_port], - 'port_version':micropy_version, - 'all_ports':[ - (port_id, url_pattern % (micropy_version, port_id)) - for port_id, port_name in ports.items() - ], - 'all_versions':[ - (ver, url_pattern % (ver, micropy_port)) - for ver in micropy_all_versions - ], - 'downloads':[ - ('PDF', url_pattern % (micropy_version, 'micropython-%s.pdf' % micropy_port)), - ], -} - - -# Specify a custom master document based on the port name -master_doc = micropy_port + '_' + 'index' - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.doctest', - 'sphinx.ext.intersphinx', - 'sphinx.ext.todo', - 'sphinx.ext.coverage', - 'sphinx_selective_exclude.modindex_exclude', - 'sphinx_selective_exclude.eager_only', - 'sphinx_selective_exclude.search_auto_exclude', -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -#master_doc = 'index' - -# General information about the project. -project = 'MicroPython' -copyright = '2014-2018, Damien P. George, Paul Sokolovsky, and contributors' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# We don't follow "The short X.Y version" vs "The full version, including alpha/beta/rc tags" -# breakdown, so use the same version identifier for both to avoid confusion. -version = release = '1.9.4' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['build', '.venv'] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -default_role = 'any' - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False - -# Global include files. Sphinx docs suggest using rst_epilog in preference -# of rst_prolog, so we follow. Absolute paths below mean "from the base -# of the doctree". -rst_epilog = """ -.. include:: /templates/replace.inc -""" - -# -- Options for HTML output ---------------------------------------------- - -# on_rtd is whether we are on readthedocs.org -on_rtd = os.environ.get('READTHEDOCS', None) == 'True' - -if not on_rtd: # only import and set the theme if we're building docs locally - try: - import sphinx_rtd_theme - html_theme = 'sphinx_rtd_theme' - html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.'] - except: - html_theme = 'default' - html_theme_path = ['.'] -else: - html_theme_path = ['.'] - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -# html_theme_path = ['.'] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = '../../logo/trans-logo.png' - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -html_favicon = 'favicon.ico' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -#html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -html_last_updated_fmt = '%d %b %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -html_additional_pages = {"index": "topindex.html"} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'MicroPythondoc' - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', -# Include 3 levels of headers in PDF ToC -'preamble': '\setcounter{tocdepth}{2}', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'MicroPython.tex', 'MicroPython Documentation', - 'Damien P. George, Paul Sokolovsky, and contributors', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'micropython', 'MicroPython Documentation', - ['Damien P. George, Paul Sokolovsky, and contributors'], 1), -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'MicroPython', 'MicroPython Documentation', - 'Damien P. George, Paul Sokolovsky, and contributors', 'MicroPython', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False - - -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'python': ('http://docs.python.org/3.5', None)} - -# Append the other ports' specific folders/files to the exclude pattern -exclude_patterns.extend([port + '*' for port in ports if port != micropy_port]) - -modules_port_specific = { - 'pyboard': ['pyb'], - 'wipy': ['wipy'], - 'esp8266': ['esp'], -} - -modindex_exclude = [] - -for p, l in modules_port_specific.items(): - if p != micropy_port: - modindex_exclude += l - -# Exclude extra modules per port -modindex_exclude += { - 'esp8266': ['cmath', 'select'], - 'wipy': ['cmath'], -}.get(micropy_port, []) diff --git a/docs/design_guide.rst b/docs/design_guide.rst new file mode 100644 index 00000000000..5d965f9074e --- /dev/null +++ b/docs/design_guide.rst @@ -0,0 +1,529 @@ +Design Guide +============ + +This guide covers a variety of development practices for CircuitPython core and library APIs. These +APIs are both `built-into CircuitPython +`_ and those that are +`distributed on GitHub `_ +and in the `Adafruit `_ and `Community +`_ bundles. Consistency with these +practices ensures that beginners can learn a pattern once and apply it throughout the CircuitPython +ecosystem. + +Start libraries with the cookiecutter +------------------------------------- + +Cookiecutter is a tool that lets you bootstrap a new repo based on another repo. +We've made one `here `_ +for CircuitPython libraries that include configs for Travis CI and ReadTheDocs +along with a setup.py, license, code of conduct and readme. + +.. code-block::sh + + # The first time + pip install cookiecutter + + cookiecutter gh:adafruit/cookiecutter-adafruit-circuitpython + +Cookiecutter will provide a series of prompts relating to the library and then create a new +directory with all of the files. See `the CircuitPython cookiecutter README +`_ for more details. + +Module Naming +------------- + +Adafruit funded libraries should be under the +`adafruit organization `_ and have the format +``Adafruit_CircuitPython_`` and have a corresponding ``adafruit_`` +directory (aka package) or ``adafruit_.py`` file (aka module). + +If the name would normally have a space, such as "Thermal Printer", use an underscore instead +("Thermal_Printer"). This underscore will be used everywhere even when the separation between +"adafruit" and "circuitpython" is done with a ``-``. Use the underscore in the cookiecutter prompts. + +Community created libraries should have the repo format ``CircuitPython_`` and +not have the ``adafruit_`` module or package prefix. + +Both should have the CircuitPython repository topic on GitHub. + +.. _lifetime-and-contextmanagers: + +Lifetime and ContextManagers +-------------------------------------------------------------------------------- + +A driver should be initialized and ready to use after construction. If the +device requires deinitialization, then provide it through ``deinit()`` and also +provide ``__enter__`` and ``__exit__`` to create a context manager usable with +``with``. + +For example, a user can then use ``deinit()```:: + + import digitalio + import board + import time + + led = digitalio.DigitalInOut(board.D13) + led.direction = digitalio.Direction.OUTPUT + + for i in range(10): + led.value = True + time.sleep(0.5) + + led.value = False + time.sleep(0.5) + led.deinit() + +This will deinit the underlying hardware at the end of the program as long as no +exceptions occur. + +Alternatively, using a ``with`` statement ensures that the hardware is deinitialized:: + + import digitalio + import board + import time + + with digitalio.DigitalInOut(board.D13) as led: + led.direction = digitalio.Direction.OUTPUT + + for i in range(10): + led.value = True + time.sleep(0.5) + + led.value = False + time.sleep(0.5) + +Python's ``with`` statement ensures that the deinit code is run regardless of +whether the code within the with statement executes without exceptions. + +For small programs like the examples this isn't a major concern because all +user usable hardware is reset after programs are run or the REPL is run. However, +for more complex programs that may use hardware intermittently and may also +handle exceptions on their own, deinitializing the hardware using a with +statement will ensure hardware isn't enabled longer than needed. + +Verify your device +-------------------------------------------------------------------------------- + +Whenever possible, make sure device you are talking to is the device you expect. +If not, raise a RuntimeError. Beware that I2C addresses can be identical on +different devices so read registers you know to make sure they match your +expectation. Validating this upfront will help catch mistakes. + +Getters/Setters +-------------------------------------------------------------------------------- + +When designing a driver for a device, use properties for device state and use +methods for sequences of abstract actions that the device performs. State is a +property of the device as a whole that exists regardless of what the code is +doing. This includes things like temperature, time, sound, light and the state +of a switch. For a more complete list see the sensor properties bullet below. + +Another way to separate state from actions is that state is usually something +the user can sense themselves by sight or feel for example. Actions are +something the user can watch. The device does this and then this. + +Making this separation clear to the user will help beginners understand when to +use what. + +Here is more info on properties from +`Python `_. + +Design for compatibility with CPython +-------------------------------------------------------------------------------- + +CircuitPython is aimed to be one's first experience with code. It will be the +first step into the world of hardware and software. To ease one's exploration +out from this first step, make sure that functionality shared with CPython shares +the same API. It doesn't need to be the full API it can be a subset. However, do +not add non-CPython APIs to the same modules. Instead, use separate non-CPython +modules to add extra functionality. By distinguishing API boundaries at modules +you increase the likelihood that incorrect expectations are found on import and +not randomly during runtime. + +When adding a new module for additional functionality related to a CPython +module do NOT simply prefix it with u. This is not a large enough differentiation +from CPython. This is the MicroPython convention and they use u* modules +interchangeably with the CPython name. This is confusing. Instead, think up a +new name that is related to the extra functionality you are adding. + +For example, storage mounting and unmounting related functions were moved from +``uos`` into a new `storage` module. Terminal related functions were moved into +`multiterminal`. These names better match their functionality and do not +conflict with CPython names. Make sure to check that you don't conflict with +CPython libraries too. That way we can port the API to CPython in the future. + +Example +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When adding extra functionality to CircuitPython to mimic what a normal +operating system would do, either copy an existing CPython API (for example file +writing) or create a separate module to achieve what you want. For example, +mounting and unmount drives is not a part of CPython so it should be done in a +module, such as a new ``storage`` module, that is only available in CircuitPython. +That way when someone moves the code to CPython they know what parts need to be +adapted. + +Document inline +-------------------------------------------------------------------------------- + +Whenever possible, document your code right next to the code that implements it. +This makes it more likely to stay up to date with the implementation itself. Use +Sphinx's automodule to format these all nicely in ReadTheDocs. The cookiecutter +helps set these up. + +Use `Sphinx flavor rST `_ for markup. + +Lots of documentation is a good thing but it can take a lot of space. To +minimize the space used on disk and on load, distribute the library as both .py +and .mpy, MicroPython and CircuitPython's bytecode format that omits comments. + +Module description +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +After the license comment:: + + """ + `` - + ================================================= + + """ + +Class description +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +At the class level document what class does and how to initialize it:: + + class DS3231: + """DS3231 real-time clock. + + :param ~busio.I2C i2c_bus: The I2C bus the DS3231 is connected to. + :param int address: The I2C address of the device. + """ + + def __init__(self, i2c_bus, address=0x40): + self._i2c = i2c_bus + + +Renders as: + +.. py:class:: DS3231(i2c_bus, address=64) + :noindex: + + DS3231 real-time clock. + + :param ~busio.I2C i2c_bus: The I2C bus the DS3231 is connected to. + :param int address: The I2C address of the device. + +Attributes +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Attributes are state on objects. (See `Getters/Setters`_ above for more discussion +about when to use them.) They can be defined internally in a number of different +ways. Each approach is enumerated below with an explanation of where the comment +goes. + +Regardless of how the attribute is implemented, it should have a short +description of what state it represents including the type, possible values and/or +units. It should be marked as ``(read-only)`` or ``(write-only)`` at the end of +the first line for attributes that are not both readable and writable. + +Instance attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Comment comes from after the assignment:: + + def __init__(self, drive_mode): + self.drive_mode = drive_mode + """ + The pin drive mode. One of: + + - `digitalio.DriveMode.PUSH_PULL` + - `digitalio.DriveMode.OPEN_DRAIN` + """ + +Renders as: + +.. py:attribute:: drive_mode + :noindex: + + The pin drive mode. One of: + + - `digitalio.DriveMode.PUSH_PULL` + - `digitalio.DriveMode.OPEN_DRAIN` + +Property description +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Comment comes from the getter:: + + @property + def datetime(self): + """The current date and time as a `time.struct_time`.""" + return self.datetime_register + + @datetime.setter + def datetime(self, value): + pass + +Renders as: + +.. py:attribute:: datetime + :noindex: + + The current date and time as a `time.struct_time`. + +Read-only example:: + + @property + def temperature(self): + """ + The current temperature in degrees Celsius. (read-only) + + The device may require calibration to get accurate readings. + """ + return self._read(TEMPERATURE) + + +Renders as: + +.. py:attribute:: temperature + :noindex: + + The current temperature in degrees Celsius. (read-only) + + The device may require calibration to get accurate readings. + +Data descriptor description +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Comment is after the definition:: + + lost_power = i2c_bit.RWBit(0x0f, 7) + """True if the device has lost power since the time was set.""" + +Renders as: + +.. py:attribute:: lost_power + :noindex: + + True if the device has lost power since the time was set. + +Method description +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +First line after the method definition:: + + def turn_right(self, degrees): + """Turns the bot ``degrees`` right. + + :param float degrees: Degrees to turn right + """ + +Renders as: + +.. py:method:: turn_right(degrees) + :noindex: + + Turns the bot ``degrees`` right. + + :param float degrees: Degrees to turn right + +Use BusDevice +-------------------------------------------------------------------------------- + +`BusDevice `_ is an +awesome foundational library that manages talking on a shared I2C or SPI device +for you. The devices manage locking which ensures that a transfer is done as a +single unit despite CircuitPython internals and, in the future, other Python +threads. For I2C, the device also manages the device address. The SPI device, +manages baudrate settings, chip select line and extra post-transaction clock +cycles. + +I2C Example +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: python + + from adafruit_bus_device import i2c_device + + DEVICE_DEFAULT_I2C_ADDR = 0x42 + + class Widget: + """A generic widget.""" + + def __init__(self, i2c, address=DEVICE_DEFAULT_I2C_ADDR): + self.i2c_device = i2c_device.I2CDevice(i2c, address) + self.buf = bytearray(1) + + @property + def register(self): + """Widget's one register.""" + with self.i2c_device as i2c: + i2c.writeto(b'0x00') + i2c.readfrom_into(self.buf) + return self.buf[0] + + +SPI Example +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: python + + from adafruit_bus_device import spi_device + + class SPIWidget: + """A generic widget with a weird baudrate.""" + + def __init__(self, spi, chip_select): + # chip_select is a pin reference such as board.D10. + self.spi_device = spi_device.SPIDevice(spi, chip_select, baudrate=12345) + self.buf = bytearray(1) + + @property + def register(self): + """Widget's one register.""" + with self.spi_device as spi: + spi.write(b'0x00') + i2c.readinto(self.buf) + return self.buf[0] + +Use composition +-------------------------------------------------------------------------------- + +When writing a driver, take in objects that provide the functionality you need +rather than taking their arguments and constructing them yourself or subclassing +a parent class with functionality. This technique is known as composition and +leads to code that is more flexible and testable than traditional inheritance. + +.. seealso:: `Wikipedia `_ + has more information on "dependency inversion". + +For example, if you are writing a driver for an I2C device, then take in an I2C +object instead of the pins themselves. This allows the calling code to provide +any object with the appropriate methods such as an I2C expansion board. + +Another example is to expect a :py:class:`~digitalio.DigitalInOut` for a pin to +toggle instead of a :py:class:`~microcontroller.Pin` from `board`. Taking in the +:py:class:`~microcontroller.Pin` object alone would limit the driver to pins on +the actual microcontroller instead of pins provided by another driver such as an +IO expander. + +Lots of small modules +-------------------------------------------------------------------------------- + +CircuitPython boards tend to have a small amount of internal flash and a small +amount of ram but large amounts of external flash for the file system. So, create +many small libraries that can be loaded as needed instead of one large file that +does everything. + +Speed second +-------------------------------------------------------------------------------- + +Speed isn't as important as API clarity and code size. So, prefer simple APIs +like properties for state even if it sacrifices a bit of speed. + +Avoid allocations in drivers +-------------------------------------------------------------------------------- + +Although Python doesn't require managing memory, its still a good practice for +library writers to think about memory allocations. Avoid them in drivers if +you can because you never know how much something will be called. Fewer +allocations means less time spent cleaning up. So, where you can, prefer +bytearray buffers that are created in ``__init__`` and used throughout the +object with methods that read or write into the buffer instead of creating new +objects. Unified hardware API classes such as `busio.SPI` are design to read and +write to subsections of buffers. + +Its ok to allocate an object to return to the user. Just beware of causing more +than one allocation per call due to internal logic. + +**However**, this is a memory tradeoff so do not do it for large or rarely used +buffers. + +Examples +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +struct.pack +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Use `struct.pack_into` instead of `struct.pack`. + +Sensor properties and units +-------------------------------------------------------------------------------- + +The `Adafruit Unified Sensor Driver Arduino library `_ has a +`great list `_ +of measurements and their units. Use the same ones including the property name +itself so that drivers can be used interchangeably when they have the same +properties. + ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| Property name | Python type | Units | ++=======================+=======================+=========================================================================+ +| ``acceleration`` | (float, float, float) | x, y, z meter per second per second | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``magnetic`` | (float, float, float) | x, y, z micro-Tesla (uT) | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``orientation`` | (float, float, float) | x, y, z degrees | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``gyro`` | (float, float, float) | x, y, z radians per second | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``temperature`` | float | degrees centigrade | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``eCO2`` | float | equivalent CO2 in ppm | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``TVOC`` | float | Total Volatile Organic Compounds in ppb | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``distance`` | float | centimeters | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``light`` | float | non-unit-specific light levels (should be monotonic but is not lux) | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``lux`` | float | SI lux | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``pressure`` | float | hectopascal (hPa) | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``relative_humidity`` | float | percent | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``current`` | float | milliamps (mA) | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``voltage`` | float | volts (V) | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``color`` | int | RGB, eight bits per channel (0xff0000 is red) | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``alarm`` | (time.struct, str) | Sample alarm time and string to characterize frequency such as "hourly" | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``datetime`` | time.struct | date and time | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``duty_cycle`` | int | 16-bit PWM duty cycle (regardless of output resolution) | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``frequency`` | int | Hertz | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``value`` | bool | Digital logic | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``value`` | int | 16-bit Analog value, unit-less | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ +| ``weight`` | float | grams (g) | ++-----------------------+-----------------------+-------------------------------------------------------------------------+ + +Adding native modules +-------------------------------------------------------------------------------- + +The Python API for a new module should be defined and documented in +``shared-bindings`` and define an underlying C API. If the implementation is +port-agnostic or relies on underlying APIs of another module, the code should +live in ``shared-module``. If it is port specific then it should live in ``common-hal`` +within the port's folder. In either case, the file and folder structure should +mimic the structure in ``shared-bindings``. + +To test your native modules or core enhancements, follow these Adafruit Learning Guides +for building local firmware to flash onto your device(s): + +`SAMD21 - Build Firmware Learning Guide `_ + +`ESP8266 - Build Firmware Learning Guide `_ + +MicroPython compatibility +-------------------------------------------------------------------------------- + +Keeping compatibility with MicroPython isn't a high priority. It should be done +when its not in conflict with any of the above goals. diff --git a/docs/differences/index_template.txt b/docs/differences/index_template.txt deleted file mode 100644 index eb8b3ba6409..00000000000 --- a/docs/differences/index_template.txt +++ /dev/null @@ -1,10 +0,0 @@ -.. _cpython_diffs: - -MicroPython differences from CPython -==================================== - -The operations listed in this section produce conflicting results in MicroPython when compared to standard Python. - -.. toctree:: - :maxdepth: 2 - diff --git a/docs/drivers.rst b/docs/drivers.rst new file mode 100644 index 00000000000..241415cc1cd --- /dev/null +++ b/docs/drivers.rst @@ -0,0 +1,33 @@ +Additional CircuitPython Libraries and Drivers on GitHub +========================================================= + +These are libraries and drivers available in separate GitHub repos. They are +designed for use with CircuitPython and may or may not work with +`MicroPython `_. + + +Adafruit CircuitPython Library Bundle +-------------------------------------- + +We provide a bundle of all our libraries to ease installation of drivers and +their dependencies. The bundle is primarily geared to the Adafruit Express line +of boards which feature a relatively large external flash. With Express boards, +its easy to copy them all onto the filesystem. However, if you don't have +enough space simply copy things over as they are needed. + +- The Adafruit bundles are available on GitHub: . + +- Documentation for the bundle, which includes links to documentation for all + libraries, is available here: . + + +CircuitPython Community Library Bundle +--------------------------------------- + +This bundle contains non-Adafruit sponsored libraries, that are written and submitted +by members of the community. + +- The Community bundles are available on GitHub: . + +- Documentation is not available on ReadTheDocs at this time. See each library for any + included documentation. diff --git a/docs/esp8266/general.rst b/docs/esp8266/general.rst deleted file mode 100644 index 08d8b4756ab..00000000000 --- a/docs/esp8266/general.rst +++ /dev/null @@ -1,195 +0,0 @@ -General information about the ESP8266 port -========================================== - -ESP8266 is a popular WiFi-enabled System-on-Chip (SoC) by Espressif Systems. - -Multitude of boards -------------------- - -There is a multitude of modules and boards from different sources which carry -the ESP8266 chip. MicroPython tries to provide a generic port which would run on -as many boards/modules as possible, but there may be limitations. Adafruit -Feather HUZZAH board is taken as a reference board for the port (for example, -testing is performed on it). If you have another board, please make sure you -have a datasheet, schematics and other reference materials for your board -handy to look up various aspects of your board functioning. - -To make a generic ESP8266 port and support as many boards as possible, -the following design and implementation decision were made: - -* GPIO pin numbering is based on ESP8266 chip numbering, not some "logical" - numbering of a particular board. Please have the manual/pin diagram of your board - at hand to find correspondence between your board pins and actual ESP8266 pins. - We also encourage users of various boards to share this mapping via MicroPython - forum, with the idea to collect community-maintained reference materials - eventually. -* All pins which make sense to support, are supported by MicroPython - (for example, pins which are used to connect SPI flash - are not exposed, as they're unlikely useful for anything else, and - operating on them will lead to board lock-up). However, any particular - board may expose only subset of pins. Consult your board reference manual. -* Some boards may lack external pins/internal connectivity to support - ESP8266 deepsleep mode. - - -Technical specifications and SoC datasheets -------------------------------------------- - -The datasheets and other reference material for ESP8266 chip are available -from the vendor site: http://bbs.espressif.com/viewtopic.php?f=67&t=225 . -They are the primary reference for the chip technical specifications, capabilities, -operating modes, internal functioning, etc. - -For your convenience, some of technical specifications are provided below: - -* Architecture: Xtensa lx106 -* CPU frequency: 80MHz overclockable to 160MHz -* Total RAM available: 96KB (part of it reserved for system) -* BootROM: 64KB -* Internal FlashROM: None -* External FlashROM: code and data, via SPI Flash. Normal sizes 512KB-4MB. -* GPIO: 16 + 1 (GPIOs are multiplexed with other functions, including - external FlashROM, UART, deep sleep wake-up, etc.) -* UART: One RX/TX UART (no hardware handshaking), one TX-only UART. -* SPI: 2 SPI interfaces (one used for FlashROM). -* I2C: No native external I2C (bitbang implementation available on any pins). -* I2S: 1. -* Programming: using BootROM bootloader from UART. Due to external FlashROM - and always-available BootROM bootloader, ESP8266 is not brickable. - - -Scarcity of runtime resources ------------------------------ - -ESP8266 has very modest resources (first of all, RAM memory). So, please -avoid allocating too big container objects (lists, dictionaries) and -buffers. There is also no full-fledged OS to keep track of resources -and automatically clean them up, so that's the task of a user/user -application: please be sure to close open files, sockets, etc. as soon -as possible after use. - - -Boot process ------------- - -On boot, MicroPython EPS8266 port executes ``_boot.py`` script from internal -frozen modules. It mounts filesystem in FlashROM, or if it's not available, -performs first-time setup of the module and creates the filesystem. This -part of the boot process is considered fixed, and not available for customization -for end users (even if you build from source, please refrain from changes to -it; customization of early boot process is available only to advanced users -and developers, who can diagnose themselves any issues arising from -modifying the standard process). - -Once the filesystem is mounted, ``boot.py`` is executed from it. The standard -version of this file is created during first-time module set up and has -commands to start a WebREPL daemon (disabled by default, configurable -with ``webrepl_setup`` module), etc. This -file is customizable by end users (for example, you may want to set some -parameters or add other services which should be run on -a module start-up). But keep in mind that incorrect modifications to boot.py -may still lead to boot loops or lock ups, requiring to reflash a module -from scratch. (In particular, it's recommended that you use either -``webrepl_setup`` module or manual editing to configure WebREPL, but not -both). - -As a final step of boot procedure, ``main.py`` is executed from filesystem, -if exists. This file is a hook to start up a user application each time -on boot (instead of going to REPL). For small test applications, you may -name them directly as ``main.py``, and upload to module, but instead it's -recommended to keep your application(s) in separate files, and have just -the following in ``main.py``:: - - import my_app - my_app.main() - -This will allow to keep the structure of your application clear, as well as -allow to install multiple applications on a board, and switch among them. - - -Known Issues ------------- - -Real-time clock -~~~~~~~~~~~~~~~ - -RTC in ESP8266 has very bad accuracy, drift may be seconds per minute. As -a workaround, to measure short enough intervals you can use -``utime.time()``, etc. functions, and for wall clock time, synchronize from -the net using included ``ntptime.py`` module. - -Due to limitations of the ESP8266 chip the internal real-time clock (RTC) -will overflow every 7:45h. If a long-term working RTC time is required then -``time()`` or ``localtime()`` must be called at least once within 7 hours. -MicroPython will then handle the overflow. - -Sockets and WiFi buffers overflow -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Socket instances remain active until they are explicitly closed. This has two -consequences. Firstly they occupy RAM, so an application which opens sockets -without closing them may eventually run out of memory. Secondly not properly -closed socket can cause the low-level part of the vendor WiFi stack to emit -``Lmac`` errors. This occurs if data comes in for a socket and is not -processed in a timely manner. This can overflow the WiFi stack input queue -and lead to a deadlock. The only recovery is by a hard reset. - -The above may also happen after an application terminates and quits to the REPL -for any reason including an exception. Subsequent arrival of data provokes the -failure with the above error message repeatedly issued. So, sockets should be -closed in any case, regardless whether an application terminates successfully -or by an exeption, for example using try/finally:: - - sock = socket(...) - try: - # Use sock - finally: - sock.close() - - -SSL/TLS limitations -~~~~~~~~~~~~~~~~~~~ - -ESP8266 uses `axTLS `_ library, which is one -of the smallest TLS libraries with the compatible licensing. However, it -also has some known issues/limitations: - -1. No support for Diffie-Hellman (DH) key exchange and Elliptic-curve - cryptography (ECC). This means it can't work with sites which force - the use of these features (it works ok with classic RSA certifactes). -2. Half-duplex communication nature. axTLS uses a single buffer for both - sending and receiving, which leads to considerable memory saving and - works well with protocols like HTTP. But there may be problems with - protocols which don't follow classic request-response model. - -Besides axTLS own limitations, the configuration used for MicroPython is -highly optimized for code size, which leads to additional limitations -(these may be lifted in the future): - -3. Optimized RSA algorithms are not enabled, which may lead to slow - SSL handshakes. -4. Stored sessions are not supported (may allow faster repeated connections - to the same site in some circumstances). - -Besides axTLS specific limitations described above, there's another generic -limitation with usage of TLS on the low-memory devices: - -5. The TLS standard specifies the maximum length of the TLS record (unit - of TLS communication, the entire record must be buffered before it can - be processed) as 16KB. That's almost half of the available ESP8266 memory, - and inside a more or less advanced application would be hard to allocate - due to memory fragmentation issues. As a compromise, a smaller buffer is - used, with the idea that the most interesting usage for SSL would be - accessing various REST APIs, which usually require much smaller messages. - The buffers size is on the order of 5KB, and is adjusted from time to - time, taking as a reference being able to access https://google.com . - The smaller buffer hower means that some sites can't be accessed using - it, and it's not possible to stream large amounts of data. - -There are also some not implemented features specifically in MicroPython's -``ussl`` module based on axTLS: - -6. Certificates are not validated (this may make connections susceptible - to man-in-the-middle attacks). -7. There is no support for client certificates (scheduled to be fixed in - 1.9.4 release). diff --git a/docs/esp8266/img/adafruit_products_pinoutstop.jpg b/docs/esp8266/img/adafruit_products_pinoutstop.jpg deleted file mode 100644 index 655e27aee31..00000000000 Binary files a/docs/esp8266/img/adafruit_products_pinoutstop.jpg and /dev/null differ diff --git a/docs/esp8266/quickref.rst b/docs/esp8266/quickref.rst deleted file mode 100644 index c510e40640c..00000000000 --- a/docs/esp8266/quickref.rst +++ /dev/null @@ -1,375 +0,0 @@ -.. _quickref: - -Quick reference for the ESP8266 -=============================== - -.. image:: img/adafruit_products_pinoutstop.jpg - :alt: Adafruit Feather HUZZAH board - :width: 640px - -The Adafruit Feather HUZZAH board (image attribution: Adafruit). - -Installing MicroPython ----------------------- - -See the corresponding section of tutorial: :ref:`intro`. It also includes -a troubleshooting subsection. - -General board control ---------------------- - -The MicroPython REPL is on UART0 (GPIO1=TX, GPIO3=RX) at baudrate 115200. -Tab-completion is useful to find out what methods an object has. -Paste mode (ctrl-E) is useful to paste a large slab of Python code into -the REPL. - -The :mod:`machine` module:: - - import machine - - machine.freq() # get the current frequency of the CPU - machine.freq(160000000) # set the CPU frequency to 160 MHz - -The :mod:`esp` module:: - - import esp - - esp.osdebug(None) # turn off vendor O/S debugging messages - esp.osdebug(0) # redirect vendor O/S debugging messages to UART(0) - -Networking ----------- - -The :mod:`network` module:: - - import network - - wlan = network.WLAN(network.STA_IF) # create station interface - wlan.active(True) # activate the interface - wlan.scan() # scan for access points - wlan.isconnected() # check if the station is connected to an AP - wlan.connect('essid', 'password') # connect to an AP - wlan.config('mac') # get the interface's MAC adddress - wlan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses - - ap = network.WLAN(network.AP_IF) # create access-point interface - ap.active(True) # activate the interface - ap.config(essid='ESP-AP') # set the ESSID of the access point - -A useful function for connecting to your local WiFi network is:: - - def do_connect(): - import network - wlan = network.WLAN(network.STA_IF) - wlan.active(True) - if not wlan.isconnected(): - print('connecting to network...') - wlan.connect('essid', 'password') - while not wlan.isconnected(): - pass - print('network config:', wlan.ifconfig()) - -Once the network is established the :mod:`socket ` module can be used -to create and use TCP/UDP sockets as usual. - -Delay and timing ----------------- - -Use the :mod:`time ` module:: - - import time - - time.sleep(1) # sleep for 1 second - time.sleep_ms(500) # sleep for 500 milliseconds - time.sleep_us(10) # sleep for 10 microseconds - start = time.ticks_ms() # get millisecond counter - delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference - -Timers ------- - -Virtual (RTOS-based) timers are supported. Use the :ref:`machine.Timer ` class -with timer ID of -1:: - - from machine import Timer - - tim = Timer(-1) - tim.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(1)) - tim.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(2)) - -The period is in milliseconds. - -Pins and GPIO -------------- - -Use the :ref:`machine.Pin ` class:: - - from machine import Pin - - p0 = Pin(0, Pin.OUT) # create output pin on GPIO0 - p0.on() # set pin to "on" (high) level - p0.off() # set pin to "off" (low) level - p0.value(1) # set pin to on/high - - p2 = Pin(2, Pin.IN) # create input pin on GPIO2 - print(p2.value()) # get value, 0 or 1 - - p4 = Pin(4, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor - p5 = Pin(5, Pin.OUT, value=1) # set pin high on creation - -Available pins are: 0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, which correspond -to the actual GPIO pin numbers of ESP8266 chip. Note that many end-user -boards use their own adhoc pin numbering (marked e.g. D0, D1, ...). As -MicroPython supports different boards and modules, physical pin numbering -was chosen as the lowest common denominator. For mapping between board -logical pins and physical chip pins, consult your board documentation. - -Note that Pin(1) and Pin(3) are REPL UART TX and RX respectively. -Also note that Pin(16) is a special pin (used for wakeup from deepsleep -mode) and may be not available for use with higher-level classes like -``Neopixel``. - -PWM (pulse width modulation) ----------------------------- - -PWM can be enabled on all pins except Pin(16). There is a single frequency -for all channels, with range between 1 and 1000 (measured in Hz). The duty -cycle is between 0 and 1023 inclusive. - -Use the ``machine.PWM`` class:: - - from machine import Pin, PWM - - pwm0 = PWM(Pin(0)) # create PWM object from a pin - pwm0.freq() # get current frequency - pwm0.freq(1000) # set frequency - pwm0.duty() # get current duty cycle - pwm0.duty(200) # set duty cycle - pwm0.deinit() # turn off PWM on the pin - - pwm2 = PWM(Pin(2), freq=500, duty=512) # create and configure in one go - -ADC (analog to digital conversion) ----------------------------------- - -ADC is available on a dedicated pin. -Note that input voltages on the ADC pin must be between 0v and 1.0v. - -Use the :ref:`machine.ADC ` class:: - - from machine import ADC - - adc = ADC(0) # create ADC object on ADC pin - adc.read() # read value, 0-1024 - -Software SPI bus ----------------- - -There are two SPI drivers. One is implemented in software (bit-banging) -and works on all pins, and is accessed via the :ref:`machine.SPI ` -class:: - - from machine import Pin, SPI - - # construct an SPI bus on the given pins - # polarity is the idle state of SCK - # phase=0 means sample on the first edge of SCK, phase=1 means the second - spi = SPI(-1, baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4)) - - spi.init(baudrate=200000) # set the baudrate - - spi.read(10) # read 10 bytes on MISO - spi.read(10, 0xff) # read 10 bytes while outputing 0xff on MOSI - - buf = bytearray(50) # create a buffer - spi.readinto(buf) # read into the given buffer (reads 50 bytes in this case) - spi.readinto(buf, 0xff) # read into the given buffer and output 0xff on MOSI - - spi.write(b'12345') # write 5 bytes on MOSI - - buf = bytearray(4) # create a buffer - spi.write_readinto(b'1234', buf) # write to MOSI and read from MISO into the buffer - spi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf - - -Hardware SPI bus ----------------- - -The hardware SPI is faster (up to 80Mhz), but only works on following pins: -``MISO`` is GPIO12, ``MOSI`` is GPIO13, and ``SCK`` is GPIO14. It has the same -methods as the bitbanging SPI class above, except for the pin parameters for the -constructor and init (as those are fixed):: - - from machine import Pin, SPI - - hspi = SPI(1, baudrate=80000000, polarity=0, phase=0) - -(``SPI(0)`` is used for FlashROM and not available to users.) - -I2C bus -------- - -The I2C driver is implemented in software and works on all pins, -and is accessed via the :ref:`machine.I2C ` class:: - - from machine import Pin, I2C - - # construct an I2C bus - i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000) - - i2c.readfrom(0x3a, 4) # read 4 bytes from slave device with address 0x3a - i2c.writeto(0x3a, '12') # write '12' to slave device with address 0x3a - - buf = bytearray(10) # create a buffer with 10 bytes - i2c.writeto(0x3a, buf) # write the given buffer to the slave - -Real time clock (RTC) ---------------------- - -See :ref:`machine.RTC ` :: - - from machine import RTC - - rtc = RTC() - rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time - rtc.datetime() # get date and time - -Deep-sleep mode ---------------- - -Connect GPIO16 to the reset pin (RST on HUZZAH). Then the following code -can be used to sleep, wake and check the reset cause:: - - import machine - - # configure RTC.ALARM0 to be able to wake the device - rtc = machine.RTC() - rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP) - - # check if the device woke from a deep sleep - if machine.reset_cause() == machine.DEEPSLEEP_RESET: - print('woke from a deep sleep') - - # set RTC.ALARM0 to fire after 10 seconds (waking the device) - rtc.alarm(rtc.ALARM0, 10000) - - # put the device to sleep - machine.deepsleep() - -OneWire driver --------------- - -The OneWire driver is implemented in software and works on all pins:: - - from machine import Pin - import onewire - - ow = onewire.OneWire(Pin(12)) # create a OneWire bus on GPIO12 - ow.scan() # return a list of devices on the bus - ow.reset() # reset the bus - ow.readbyte() # read a byte - ow.writebyte(0x12) # write a byte on the bus - ow.write('123') # write bytes on the bus - ow.select_rom(b'12345678') # select a specific device by its ROM code - -There is a specific driver for DS18S20 and DS18B20 devices:: - - import time, ds18x20 - ds = ds18x20.DS18X20(ow) - roms = ds.scan() - ds.convert_temp() - time.sleep_ms(750) - for rom in roms: - print(ds.read_temp(rom)) - -Be sure to put a 4.7k pull-up resistor on the data line. Note that -the ``convert_temp()`` method must be called each time you want to -sample the temperature. - -NeoPixel driver ---------------- - -Use the ``neopixel`` module:: - - from machine import Pin - from neopixel import NeoPixel - - pin = Pin(0, Pin.OUT) # set GPIO0 to output to drive NeoPixels - np = NeoPixel(pin, 8) # create NeoPixel driver on GPIO0 for 8 pixels - np[0] = (255, 255, 255) # set the first pixel to white - np.write() # write data to all pixels - r, g, b = np[0] # get first pixel colour - -For low-level driving of a NeoPixel:: - - import esp - esp.neopixel_write(pin, grb_buf, is800khz) - -APA102 driver -------------- - -Use the ``apa102`` module:: - - from machine import Pin - from apa102 import APA102 - - clock = Pin(14, Pin.OUT) # set GPIO14 to output to drive the clock - data = Pin(13, Pin.OUT) # set GPIO13 to output to drive the data - apa = APA102(clock, data, 8) # create APA102 driver on the clock and the data pin for 8 pixels - apa[0] = (255, 255, 255, 31) # set the first pixel to white with a maximum brightness of 31 - apa.write() # write data to all pixels - r, g, b, brightness = apa[0] # get first pixel colour - -For low-level driving of an APA102:: - - import esp - esp.apa102_write(clock_pin, data_pin, rgbi_buf) - -DHT driver ----------- - -The DHT driver is implemented in software and works on all pins:: - - import dht - import machine - - d = dht.DHT11(machine.Pin(4)) - d.measure() - d.temperature() # eg. 23 (°C) - d.humidity() # eg. 41 (% RH) - - d = dht.DHT22(machine.Pin(4)) - d.measure() - d.temperature() # eg. 23.6 (°C) - d.humidity() # eg. 41.3 (% RH) - -WebREPL (web browser interactive prompt) ----------------------------------------- - -WebREPL (REPL over WebSockets, accessible via a web browser) is an -experimental feature available in ESP8266 port. Download web client -from https://github.com/micropython/webrepl (hosted version available -at http://micropython.org/webrepl), and configure it by executing:: - - import webrepl_setup - -and following on-screen instructions. After reboot, it will be available -for connection. If you disabled automatic start-up on boot, you may -run configured daemon on demand using:: - - import webrepl - webrepl.start() - -The supported way to use WebREPL is by connecting to ESP8266 access point, -but the daemon is also started on STA interface if it is active, so if your -router is set up and works correctly, you may also use WebREPL while connected -to your normal Internet access point (use the ESP8266 AP connection method -if you face any issues). - -Besides terminal/command prompt access, WebREPL also has provision for file -transfer (both upload and download). Web client has buttons for the -corresponding functions, or you can use command-line client ``webrepl_cli.py`` -from the repository above. - -See the MicroPython forum for other community-supported alternatives -to transfer files to ESP8266. diff --git a/docs/esp8266/tutorial/adc.rst b/docs/esp8266/tutorial/adc.rst deleted file mode 100644 index fa6fdaba73b..00000000000 --- a/docs/esp8266/tutorial/adc.rst +++ /dev/null @@ -1,19 +0,0 @@ -Analog to Digital Conversion -============================ - -The ESP8266 has a single pin (separate to the GPIO pins) which can be used to -read analog voltages and convert them to a digital value. You can construct -such an ADC pin object using:: - - >>> import machine - >>> adc = machine.ADC(0) - -Then read its value with:: - - >>> adc.read() - 58 - -The values returned from the ``read()`` function are between 0 (for 0.0 volts) -and 1024 (for 1.0 volts). Please note that this input can only tolerate a -maximum of 1.0 volts and you must use a voltage divider circuit to measure -larger voltages. diff --git a/docs/esp8266/tutorial/dht.rst b/docs/esp8266/tutorial/dht.rst deleted file mode 100644 index 1602e8a3374..00000000000 --- a/docs/esp8266/tutorial/dht.rst +++ /dev/null @@ -1,65 +0,0 @@ -Temperature and Humidity -======================== - -DHT (Digital Humidity & Temperature) sensors are low cost digital sensors with -capacitive humidity sensors and thermistors to measure the surrounding air. -They feature a chip that handles analog to digital conversion and provide a -1-wire interface. Newer sensors additionally provide an I2C interface. - -The DHT11 (blue) and DHT22 (white) sensors provide the same 1-wire interface, -however, the DHT22 requires a separate object as it has more complex -calculation. DHT22 have 1 decimal place resolution for both humidity and -temperature readings. DHT11 have whole number for both. - -A custom 1-wire protocol, which is different to Dallas 1-wire, is used to get -the measurements from the sensor. The payload consists of a humidity value, -a temperature value and a checksum. - -To use the 1-wire interface, construct the objects referring to their data pin:: - - >>> import dht - >>> import machine - >>> d = dht.DHT11(machine.Pin(4)) - - >>> import dht - >>> import machine - >>> d = dht.DHT22(machine.Pin(4)) - -Then measure and read their values with:: - - >>> d.measure() - >>> d.temperature() - >>> d.humidity() - -Values returned from ``temperature()`` are in degrees Celsius and values -returned from ``humidity()`` are a percentage of relative humidity. - -The DHT11 can be called no more than once per second and the DHT22 once every -two seconds for most accurate results. Sensor accuracy will degrade over time. -Each sensor supports a different operating range. Refer to the product -datasheets for specifics. - -In 1-wire mode, only three of the four pins are used and in I2C mode, all four -pins are used. Older sensors may still have 4 pins even though they do not -support I2C. The 3rd pin is simply not connected. - -Pin configurations: - -Sensor without I2C in 1-wire mode (eg. DHT11, DHT22, AM2301, AM2302): - - 1=VDD, 2=Data, 3=NC, 4=GND - -Sensor with I2C in 1-wire mode (eg. DHT12, AM2320, AM2321, AM2322): - - 1=VDD, 2=Data, 3=GND, 4=GND - -Sensor with I2C in I2C mode (eg. DHT12, AM2320, AM2321, AM2322): - - 1=VDD, 2=SDA, 3=GND, 4=SCL - -You should use pull-up resistors for the Data, SDA and SCL pins. - -To make newer I2C sensors work in backwards compatible 1-wire mode, you must -connect both pins 3 and 4 to GND. This disables the I2C interface. - -DHT22 sensors are now sold under the name AM2302 and are otherwise identical. diff --git a/docs/esp8266/tutorial/filesystem.rst b/docs/esp8266/tutorial/filesystem.rst deleted file mode 100644 index 27b0d2608c5..00000000000 --- a/docs/esp8266/tutorial/filesystem.rst +++ /dev/null @@ -1,69 +0,0 @@ -The internal filesystem -======================= - -If your devices has 1Mbyte or more of storage then it will be set up (upon first -boot) to contain a filesystem. This filesystem uses the FAT format and is -stored in the flash after the MicroPython firmware. - -Creating and reading files --------------------------- - -MicroPython on the ESP8266 supports the standard way of accessing files in -Python, using the built-in ``open()`` function. - -To create a file try:: - - >>> f = open('data.txt', 'w') - >>> f.write('some data') - 9 - >>> f.close() - -The "9" is the number of bytes that were written with the ``write()`` method. -Then you can read back the contents of this new file using:: - - >>> f = open('data.txt') - >>> f.read() - 'some data' - >>> f.close() - -Note that the default mode when opening a file is to open it in read-only mode, -and as a text file. Specify ``'wb'`` as the second argument to ``open()`` to -open for writing in binary mode, and ``'rb'`` to open for reading in binary -mode. - -Listing file and more ---------------------- - -The os module can be used for further control over the filesystem. First -import the module:: - - >>> import os - -Then try listing the contents of the filesystem:: - - >>> os.listdir() - ['boot.py', 'port_config.py', 'data.txt'] - -You can make directories:: - - >>> os.mkdir('dir') - -And remove entries:: - - >>> os.remove('data.txt') - -Start up scripts ----------------- - -There are two files that are treated specially by the ESP8266 when it starts up: -boot.py and main.py. The boot.py script is executed first (if it exists) and -then once it completes the main.py script is executed. You can create these -files yourself and populate them with the code that you want to run when the -device starts up. - -Accessing the filesystem via WebREPL ------------------------------------- - -You can access the filesystem over WebREPL using the web client in a browser -or via the command-line tool. Please refer to Quick Reference and Tutorial -sections for more information about WebREPL. diff --git a/docs/esp8266/tutorial/index.rst b/docs/esp8266/tutorial/index.rst deleted file mode 100644 index 39b4592600c..00000000000 --- a/docs/esp8266/tutorial/index.rst +++ /dev/null @@ -1,33 +0,0 @@ -.. _tutorial-index: - -MicroPython tutorial for ESP8266 -================================ - -This tutorial is intended to get you started using MicroPython on the ESP8266 -system-on-a-chip. If it is your first time it is recommended to follow the -tutorial through in the order below. Otherwise the sections are mostly self -contained, so feel free to skip to those that interest you. - -The tutorial does not assume that you know Python, but it also does not attempt -to explain any of the details of the Python language. Instead it provides you -with commands that are ready to run, and hopes that you will gain a bit of -Python knowledge along the way. To learn more about Python itself please refer -to ``__. - -.. toctree:: - :maxdepth: 1 - :numbered: - - intro.rst - repl.rst - filesystem.rst - network_basics.rst - network_tcp.rst - pins.rst - pwm.rst - adc.rst - powerctrl.rst - onewire.rst - neopixel.rst - dht.rst - nextsteps.rst diff --git a/docs/esp8266/tutorial/intro.rst b/docs/esp8266/tutorial/intro.rst deleted file mode 100644 index 711db3fcebb..00000000000 --- a/docs/esp8266/tutorial/intro.rst +++ /dev/null @@ -1,202 +0,0 @@ -.. _intro: - -Getting started with MicroPython on the ESP8266 -=============================================== - -Using MicroPython is a great way to get the most of your ESP8266 board. And -vice versa, the ESP8266 chip is a great platform for using MicroPython. This -tutorial will guide you through setting up MicroPython, getting a prompt, using -WebREPL, connecting to the network and communicating with the Internet, using -the hardware peripherals, and controlling some external components. - -Let's get started! - -Requirements ------------- - -The first thing you need is a board with an ESP8266 chip. The MicroPython -software supports the ESP8266 chip itself and any board should work. The main -characteristic of a board is how much flash it has, how the GPIO pins are -connected to the outside world, and whether it includes a built-in USB-serial -convertor to make the UART available to your PC. - -The minimum requirement for flash size is 1Mbyte. There is also a special -build for boards with 512KB, but it is highly limited comparing to the -normal build: there is no support for filesystem, and thus features which -depend on it won't work (WebREPL, upip, etc.). As such, 512KB build will -be more interesting for users who build from source and fine-tune parameters -for their particular application. - -Names of pins will be given in this tutorial using the chip names (eg GPIO0) -and it should be straightforward to find which pin this corresponds to on your -particular board. - -Powering the board ------------------- - -If your board has a USB connector on it then most likely it is powered through -this when connected to your PC. Otherwise you will need to power it directly. -Please refer to the documentation for your board for further details. - -Getting the firmware --------------------- - -The first thing you need to do is download the most recent MicroPython firmware -.bin file to load onto your ESP8266 device. You can download it from the -`MicroPython downloads page `_. -From here, you have 3 main choices - -* Stable firmware builds for 1024kb modules and above. -* Daily firmware builds for 1024kb modules and above. -* Daily firmware builds for 512kb modules. - -If you are just starting with MicroPython, the best bet is to go for the Stable -firmware builds. If you are an advanced, experienced MicroPython ESP8266 user -who would like to follow development closely and help with testing new -features, there are daily builds (note: you actually may need some -development experience, e.g. being ready to follow git history to know -what new changes and features were introduced). - -Support for 512kb modules is provided on a feature preview basis. For end -users, it's recommended to use modules with flash of 1024kb or more. As -such, only daily builds for 512kb modules are provided. - -Deploying the firmware ----------------------- - -Once you have the MicroPython firmware (compiled code), you need to load it onto -your ESP8266 device. There are two main steps to do this: first you -need to put your device in boot-loader mode, and second you need to copy across -the firmware. The exact procedure for these steps is highly dependent on the -particular board and you will need to refer to its documentation for details. - -If you have a board that has a USB connector, a USB-serial convertor, and has -the DTR and RTS pins wired in a special way then deploying the firmware should -be easy as all steps can be done automatically. Boards that have such features -include the Adafruit Feather HUZZAH and NodeMCU boards. - -For best results it is recommended to first erase the entire flash of your -device before putting on new MicroPython firmware. - -Currently we only support esptool.py to copy across the firmware. You can find -this tool here: ``__, or install it -using pip:: - - pip install esptool - -Versions starting with 1.3 support both Python 2.7 and Python 3.4 (or newer). -An older version (at least 1.2.1 is needed) works fine but will require Python -2.7. - -Any other flashing program should work, so feel free to try them out or refer -to the documentation for your board to see its recommendations. - -Using esptool.py you can erase the flash with the command:: - - esptool.py --port /dev/ttyUSB0 erase_flash - -And then deploy the new firmware using:: - - esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect 0 esp8266-20170108-v1.8.7.bin - -You might need to change the "port" setting to something else relevant for your -PC. You may also need to reduce the baudrate if you get errors when flashing -(eg down to 115200). The filename of the firmware should also match the file -that you have. - -For some boards with a particular FlashROM configuration (e.g. some variants of -a NodeMCU board) you may need to use the following command to deploy -the firmware (note the ``-fm dio`` option):: - - esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect -fm dio 0 esp8266-20170108-v1.8.7.bin - -If the above commands run without error then MicroPython should be installed on -your board! - -Serial prompt -------------- - -Once you have the firmware on the device you can access the REPL (Python prompt) -over UART0 (GPIO1=TX, GPIO3=RX), which might be connected to a USB-serial -convertor, depending on your board. The baudrate is 115200. The next part of -the tutorial will discuss the prompt in more detail. - -WiFi ----- - -After a fresh install and boot the device configures itself as a WiFi access -point (AP) that you can connect to. The ESSID is of the form MicroPython-xxxxxx -where the x's are replaced with part of the MAC address of your device (so will -be the same everytime, and most likely different for all ESP8266 chips). The -password for the WiFi is micropythoN (note the upper-case N). Its IP address -will be 192.168.4.1 once you connect to its network. WiFi configuration will -be discussed in more detail later in the tutorial. - -Troubleshooting installation problems -------------------------------------- - -If you experience problems during flashing or with running firmware immediately -after it, here are troubleshooting recommendations: - -* Be aware of and try to exclude hardware problems. There are 2 common problems: - bad power source quality and worn-out/defective FlashROM. Speaking of power - source, not just raw amperage is important, but also low ripple and noise/EMI - in general. If you experience issues with self-made or wall-wart style power - supply, try USB power from a computer. Unearthed power supplies are also known - to cause problems as they source of increased EMI (electromagnetic interference) - - at the very least, and may lead to electrical devices breakdown. So, you are - advised to avoid using unearthed power connections when working with ESP8266 - and other boards. In regard to FlashROM hardware problems, there are independent - (not related to MicroPython in any way) reports - `(e.g.) `_ - that on some ESP8266 modules, FlashROM can be programmed as little as 20 times - before programming errors occur. This is *much* less than 100,000 programming - cycles cited for FlashROM chips of a type used with ESP8266 by reputable - vendors, which points to either production rejects, or second-hand worn-out - flash chips to be used on some (apparently cheap) modules/boards. You may want - to use your best judgement about source, price, documentation, warranty, - post-sales support for the modules/boards you purchase. - -* The flashing instructions above use flashing speed of 460800 baud, which is - good compromise between speed and stability. However, depending on your - module/board, USB-UART convertor, cables, host OS, etc., the above baud - rate may be too high and lead to errors. Try a more common 115200 baud - rate instead in such cases. - -* If lower baud rate didn't help, you may want to try older version of - esptool.py, which had a different programming algorithm:: - - pip install esptool==1.0.1 - - This version doesn't support ``--flash_size=detect`` option, so you will - need to specify FlashROM size explicitly (in megabits). It also requires - Python 2.7, so you may need to use ``pip2`` instead of ``pip`` in the - command above. - -* The ``--flash_size`` option in the commands above is mandatory. Omitting - it will lead to a corrupted firmware. - -* To catch incorrect flash content (e.g. from a defective sector on a chip), - add ``--verify`` switch to the commands above. - -* Additionally, you can check the firmware integrity from a MicroPython REPL - prompt (assuming you were able to flash it and ``--verify`` option doesn't - report errors):: - - import esp - esp.check_fw() - - If the last output value is True, the firmware is OK. Otherwise, it's - corrupted and need to be reflashed correctly. - -* If you experience any issues with another flashing application (not - esptool.py), try esptool.py, it is a generally accepted flashing - application in the ESP8266 community. - -* If you still experience problems with even flashing the firmware, please - refer to esptool.py project page, https://github.com/espressif/esptool - for additional documentation and bug tracker where you can report problems. - -* If you are able to flash firmware, but ``--verify`` option or - ``esp.check_fw()`` return errors even after multiple retries, you - may have a defective FlashROM chip, as explained above. diff --git a/docs/esp8266/tutorial/neopixel.rst b/docs/esp8266/tutorial/neopixel.rst deleted file mode 100644 index a1537526f30..00000000000 --- a/docs/esp8266/tutorial/neopixel.rst +++ /dev/null @@ -1,84 +0,0 @@ -Controlling NeoPixels -===================== - -NeoPixels, also known as WS2812 LEDs, are full-colour LEDs that are connected in -serial, are individually addressable, and can have their red, green and blue -components set between 0 and 255. They require precise timing to control them -and there is a special neopixel module to do just this. - -To create a NeoPixel object do the following:: - - >>> import machine, neopixel - >>> np = neopixel.NeoPixel(machine.Pin(4), 8) - -This configures a NeoPixel strip on GPIO4 with 8 pixels. You can adjust the -"4" (pin number) and the "8" (number of pixel) to suit your set up. - -To set the colour of pixels use:: - - >>> np[0] = (255, 0, 0) # set to red, full brightness - >>> np[1] = (0, 128, 0) # set to green, half brightness - >>> np[2] = (0, 0, 64) # set to blue, quarter brightness - -For LEDs with more than 3 colours, such as RGBW pixels or RGBY pixels, the -NeoPixel class takes a ``bpp`` parameter. To setup a NeoPixel object for an -RGBW Pixel, do the following:: - - >>> import machine, neopixel - >>> np = neopixel.NeoPixel(machine.Pin(4), 8, bpp=4) - -In a 4-bpp mode, remember to use 4-tuples instead of 3-tuples to set the colour. -For example to set the first three pixels use:: - - >>> np[0] = (255, 0, 0, 128) # Orange in an RGBY Setup - >>> np[1] = (0, 255, 0, 128) # Yellow-green in an RGBY Setup - >>> np[2] = (0, 0, 255, 128) # Green-blue in an RGBY Setup - -Then use the ``write()`` method to output the colours to the LEDs:: - - >>> np.write() - -The following demo function makes a fancy show on the LEDs:: - - import time - - def demo(np): - n = np.n - - # cycle - for i in range(4 * n): - for j in range(n): - np[j] = (0, 0, 0) - np[i % n] = (255, 255, 255) - np.write() - time.sleep_ms(25) - - # bounce - for i in range(4 * n): - for j in range(n): - np[j] = (0, 0, 128) - if (i // n) % 2 == 0: - np[i % n] = (0, 0, 0) - else: - np[n - 1 - (i % n)] = (0, 0, 0) - np.write() - time.sleep_ms(60) - - # fade in/out - for i in range(0, 4 * 256, 8): - for j in range(n): - if (i // 256) % 2 == 0: - val = i & 0xff - else: - val = 255 - (i & 0xff) - np[j] = (val, 0, 0) - np.write() - - # clear - for i in range(n): - np[i] = (0, 0, 0) - np.write() - -Execute it using:: - - >>> demo(np) diff --git a/docs/esp8266/tutorial/network_basics.rst b/docs/esp8266/tutorial/network_basics.rst deleted file mode 100644 index 95d8cba4f9f..00000000000 --- a/docs/esp8266/tutorial/network_basics.rst +++ /dev/null @@ -1,81 +0,0 @@ -Network basics -============== - -The network module is used to configure the WiFi connection. There are two WiFi -interfaces, one for the station (when the ESP8266 connects to a router) and one -for the access point (for other devices to connect to the ESP8266). Create -instances of these objects using:: - - >>> import network - >>> sta_if = network.WLAN(network.STA_IF) - >>> ap_if = network.WLAN(network.AP_IF) - -You can check if the interfaces are active by:: - - >>> sta_if.active() - False - >>> ap_if.active() - True - -You can also check the network settings of the interface by:: - - >>> ap_if.ifconfig() - ('192.168.4.1', '255.255.255.0', '192.168.4.1', '8.8.8.8') - -The returned values are: IP address, netmask, gateway, DNS. - -Configuration of the WiFi -------------------------- - -Upon a fresh install the ESP8266 is configured in access point mode, so the -AP_IF interface is active and the STA_IF interface is inactive. You can -configure the module to connect to your own network using the STA_IF interface. - -First activate the station interface:: - - >>> sta_if.active(True) - -Then connect to your WiFi network:: - - >>> sta_if.connect('', '') - -To check if the connection is established use:: - - >>> sta_if.isconnected() - -Once established you can check the IP address:: - - >>> sta_if.ifconfig() - ('192.168.0.2', '255.255.255.0', '192.168.0.1', '8.8.8.8') - -You can then disable the access-point interface if you no longer need it:: - - >>> ap_if.active(False) - -Here is a function you can run (or put in your boot.py file) to automatically -connect to your WiFi network:: - - def do_connect(): - import network - sta_if = network.WLAN(network.STA_IF) - if not sta_if.isconnected(): - print('connecting to network...') - sta_if.active(True) - sta_if.connect('', '') - while not sta_if.isconnected(): - pass - print('network config:', sta_if.ifconfig()) - -Sockets -------- - -Once the WiFi is set up the way to access the network is by using sockets. -A socket represents an endpoint on a network device, and when two sockets are -connected together communication can proceed. -Internet protocols are built on top of sockets, such as email (SMTP), the web -(HTTP), telnet, ssh, among many others. Each of these protocols is assigned -a specific port, which is just an integer. Given an IP address and a port -number you can connect to a remote device and start talking with it. - -The next part of the tutorial discusses how to use sockets to do some common -and useful network tasks. diff --git a/docs/esp8266/tutorial/network_tcp.rst b/docs/esp8266/tutorial/network_tcp.rst deleted file mode 100644 index 26a2f469ce1..00000000000 --- a/docs/esp8266/tutorial/network_tcp.rst +++ /dev/null @@ -1,122 +0,0 @@ -Network - TCP sockets -===================== - -The building block of most of the internet is the TCP socket. These sockets -provide a reliable stream of bytes between the connected network devices. -This part of the tutorial will show how to use TCP sockets in a few different -cases. - -Star Wars Asciimation ---------------------- - -The simplest thing to do is to download data from the internet. In this case -we will use the Star Wars Asciimation service provided by the blinkenlights.nl -website. It uses the telnet protocol on port 23 to stream data to anyone that -connects. It's very simple to use because it doesn't require you to -authenticate (give a username or password), you can just start downloading data -straight away. - -The first thing to do is make sure we have the socket module available:: - - >>> import socket - -Then get the IP address of the server:: - - >>> addr_info = socket.getaddrinfo("towel.blinkenlights.nl", 23) - -The ``getaddrinfo`` function actually returns a list of addresses, and each -address has more information than we need. We want to get just the first valid -address, and then just the IP address and port of the server. To do this use:: - - >>> addr = addr_info[0][-1] - -If you type ``addr_info`` and ``addr`` at the prompt you will see exactly what -information they hold. - -Using the IP address we can make a socket and connect to the server:: - - >>> s = socket.socket() - >>> s.connect(addr) - -Now that we are connected we can download and display the data:: - - >>> while True: - ... data = s.recv(500) - ... print(str(data, 'utf8'), end='') - ... - -When this loop executes it should start showing the animation (use ctrl-C to -interrupt it). - -You should also be able to run this same code on your PC using normal Python if -you want to try it out there. - -HTTP GET request ----------------- - -The next example shows how to download a webpage. HTTP uses port 80 and you -first need to send a "GET" request before you can download anything. As part -of the request you need to specify the page to retrieve. - -Let's define a function that can download and print a URL:: - - def http_get(url): - _, _, host, path = url.split('/', 3) - addr = socket.getaddrinfo(host, 80)[0][-1] - s = socket.socket() - s.connect(addr) - s.send(bytes('GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host), 'utf8')) - while True: - data = s.recv(100) - if data: - print(str(data, 'utf8'), end='') - else: - break - s.close() - -Make sure that you import the socket module before running this function. Then -you can try:: - - >>> http_get('http://micropython.org/ks/test.html') - -This should retrieve the webpage and print the HTML to the console. - -Simple HTTP server ------------------- - -The following code creates an simple HTTP server which serves a single webpage -that contains a table with the state of all the GPIO pins:: - - import machine - pins = [machine.Pin(i, machine.Pin.IN) for i in (0, 2, 4, 5, 12, 13, 14, 15)] - - html = """ - - ESP8266 Pins -

ESP8266 Pins

- %s
PinValue
- - - """ - - import socket - addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1] - - s = socket.socket() - s.bind(addr) - s.listen(1) - - print('listening on', addr) - - while True: - cl, addr = s.accept() - print('client connected from', addr) - cl_file = cl.makefile('rwb', 0) - while True: - line = cl_file.readline() - if not line or line == b'\r\n': - break - rows = ['%s%d' % (str(p), p.value()) for p in pins] - response = html % '\n'.join(rows) - cl.send(response) - cl.close() diff --git a/docs/esp8266/tutorial/nextsteps.rst b/docs/esp8266/tutorial/nextsteps.rst deleted file mode 100644 index 318bd7ddf86..00000000000 --- a/docs/esp8266/tutorial/nextsteps.rst +++ /dev/null @@ -1,12 +0,0 @@ -Next steps -========== - -That brings us to the end of the tutorial! Hopefully by now you have a good -feel for the capabilities of MicroPython on the ESP8266 and understand how to -control both the WiFi and IO aspects of the chip. - -There are many features that were not covered in this tutorial. The best way -to learn about them is to read the full documentation of the modules, and to -experiment! - -Good luck creating your Internet of Things devices! diff --git a/docs/esp8266/tutorial/onewire.rst b/docs/esp8266/tutorial/onewire.rst deleted file mode 100644 index c2cede9e389..00000000000 --- a/docs/esp8266/tutorial/onewire.rst +++ /dev/null @@ -1,37 +0,0 @@ -Controlling 1-wire devices -========================== - -The 1-wire bus is a serial bus that uses just a single wire for communication -(in addition to wires for ground and power). The DS18B20 temperature sensor -is a very popular 1-wire device, and here we show how to use the onewire module -to read from such a device. - -For the following code to work you need to have at least one DS18S20 or DS18B20 temperature -sensor with its data line connected to GPIO12. You must also power the sensors -and connect a 4.7k Ohm resistor between the data pin and the power pin. :: - - import time - import machine - import onewire, ds18x20 - - # the device is on GPIO12 - dat = machine.Pin(12) - - # create the onewire object - ds = ds18x20.DS18X20(onewire.OneWire(dat)) - - # scan for devices on the bus - roms = ds.scan() - print('found devices:', roms) - - # loop 10 times and print all temperatures - for i in range(10): - print('temperatures:', end=' ') - ds.convert_temp() - time.sleep_ms(750) - for rom in roms: - print(ds.read_temp(rom), end=' ') - print() - -Note that you must execute the ``convert_temp()`` function to initiate a -temperature reading, then wait at least 750ms before reading the value. diff --git a/docs/esp8266/tutorial/pins.rst b/docs/esp8266/tutorial/pins.rst deleted file mode 100644 index d304cd55b74..00000000000 --- a/docs/esp8266/tutorial/pins.rst +++ /dev/null @@ -1,76 +0,0 @@ -GPIO Pins -========= - -The way to connect your board to the external world, and control other -components, is through the GPIO pins. Not all pins are available to use, -in most cases only pins 0, 2, 4, 5, 12, 13, 14, 15, and 16 can be used. - -The pins are available in the machine module, so make sure you import that -first. Then you can create a pin using:: - - >>> pin = machine.Pin(0) - -Here, the "0" is the pin that you want to access. Usually you want to -configure the pin to be input or output, and you do this when constructing -it. To make an input pin use:: - - >>> pin = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP) - -You can either use PULL_UP or None for the input pull-mode. If it's -not specified then it defaults to None, which is no pull resistor. GPIO16 -has no pull-up mode. -You can read the value on the pin using:: - - >>> pin.value() - 0 - -The pin on your board may return 0 or 1 here, depending on what it's connected -to. To make an output pin use:: - - >>> pin = machine.Pin(0, machine.Pin.OUT) - -Then set its value using:: - - >>> pin.value(0) - >>> pin.value(1) - -Or:: - - >>> pin.off() - >>> pin.on() - -External interrupts -------------------- - -All pins except number 16 can be configured to trigger a hard interrupt if their -input changes. You can set code (a callback function) to be executed on the -trigger. - -Let's first define a callback function, which must take a single argument, -being the pin that triggered the function. We will make the function just print -the pin:: - - >>> def callback(p): - ... print('pin change', p) - -Next we will create two pins and configure them as inputs:: - - >>> from machine import Pin - >>> p0 = Pin(0, Pin.IN) - >>> p2 = Pin(2, Pin.IN) - -An finally we need to tell the pins when to trigger, and the function to call -when they detect an event:: - - >>> p0.irq(trigger=Pin.IRQ_FALLING, handler=callback) - >>> p2.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=callback) - -We set pin 0 to trigger only on a falling edge of the input (when it goes from -high to low), and set pin 2 to trigger on both a rising and falling edge. After -entering this code you can apply high and low voltages to pins 0 and 2 to see -the interrupt being executed. - -A hard interrupt will trigger as soon as the event occurs and will interrupt any -running code, including Python code. As such your callback functions are -limited in what they can do (they cannot allocate memory, for example) and -should be as short and simple as possible. diff --git a/docs/esp8266/tutorial/powerctrl.rst b/docs/esp8266/tutorial/powerctrl.rst deleted file mode 100644 index 289b4c42fd2..00000000000 --- a/docs/esp8266/tutorial/powerctrl.rst +++ /dev/null @@ -1,61 +0,0 @@ -Power control -============= - -The ESP8266 provides the ability to change the CPU frequency on the fly, and -enter a deep-sleep state. Both can be used to manage power consumption. - -Changing the CPU frequency --------------------------- - -The machine module has a function to get and set the CPU frequency. To get the -current frequency use:: - - >>> import machine - >>> machine.freq() - 80000000 - -By default the CPU runs at 80MHz. It can be changed to 160MHz if you need more -processing power, at the expense of current consumption:: - - >>> machine.freq(160000000) - >>> machine.freq() - 160000000 - -You can change to the higher frequency just while your code does the heavy -processing and then change back when it's finished. - -Deep-sleep mode ---------------- - -The deep-sleep mode will shut down the ESP8266 and all its peripherals, -including the WiFi (but not including the real-time-clock, which is used to wake -the chip). This drastically reduces current consumption and is a good way to -make devices that can run for a while on a battery. - -To be able to use the deep-sleep feature you must connect GPIO16 to the reset -pin (RST on the Adafruit Feather HUZZAH board). Then the following code can be -used to sleep and wake the device:: - - import machine - - # configure RTC.ALARM0 to be able to wake the device - rtc = machine.RTC() - rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP) - - # set RTC.ALARM0 to fire after 10 seconds (waking the device) - rtc.alarm(rtc.ALARM0, 10000) - - # put the device to sleep - machine.deepsleep() - -Note that when the chip wakes from a deep-sleep it is completely reset, -including all of the memory. The boot scripts will run as usual and you can -put code in them to check the reset cause to perhaps do something different if -the device just woke from a deep-sleep. For example, to print the reset cause -you can use:: - - if machine.reset_cause() == machine.DEEPSLEEP_RESET: - print('woke from a deep sleep') - else: - print('power on or hard reset') - diff --git a/docs/esp8266/tutorial/pwm.rst b/docs/esp8266/tutorial/pwm.rst deleted file mode 100644 index 61eb190f665..00000000000 --- a/docs/esp8266/tutorial/pwm.rst +++ /dev/null @@ -1,87 +0,0 @@ -Pulse Width Modulation -====================== - -Pulse width modulation (PWM) is a way to get an artificial analog output on a -digital pin. It achieves this by rapidly toggling the pin from low to high. -There are two parameters associated with this: the frequency of the toggling, -and the duty cycle. The duty cycle is defined to be how long the pin is high -compared with the length of a single period (low plus high time). Maximum -duty cycle is when the pin is high all of the time, and minimum is when it is -low all of the time. - -On the ESP8266 the pins 0, 2, 4, 5, 12, 13, 14 and 15 all support PWM. The -limitation is that they must all be at the same frequency, and the frequency -must be between 1Hz and 1kHz. - -To use PWM on a pin you must first create the pin object, for example:: - - >>> import machine - >>> p12 = machine.Pin(12) - -Then create the PWM object using:: - - >>> pwm12 = machine.PWM(p12) - -You can set the frequency and duty cycle using:: - - >>> pwm12.freq(500) - >>> pwm12.duty(512) - -Note that the duty cycle is between 0 (all off) and 1023 (all on), with 512 -being a 50% duty. Values beyond this min/max will be clipped. If you -print the PWM object then it will tell you its current configuration:: - - >>> pwm12 - PWM(12, freq=500, duty=512) - -You can also call the ``freq()`` and ``duty()`` methods with no arguments to -get their current values. - -The pin will continue to be in PWM mode until you deinitialise it using:: - - >>> pwm12.deinit() - -Fading an LED -------------- - -Let's use the PWM feature to fade an LED. Assuming your board has an LED -connected to pin 2 (ESP-12 modules do) we can create an LED-PWM object using:: - - >>> led = machine.PWM(machine.Pin(2), freq=1000) - -Notice that we can set the frequency in the PWM constructor. - -For the next part we will use timing and some math, so import these modules:: - - >>> import time, math - -Then create a function to pulse the LED:: - - >>> def pulse(l, t): - ... for i in range(20): - ... l.duty(int(math.sin(i / 10 * math.pi) * 500 + 500)) - ... time.sleep_ms(t) - -You can try this function out using:: - - >>> pulse(led, 50) - -For a nice effect you can pulse many times in a row:: - - >>> for i in range(10): - ... pulse(led, 20) - -Remember you can use ctrl-C to interrupt the code. - -Control a hobby servo ---------------------- - -Hobby servo motors can be controlled using PWM. They require a frequency of -50Hz and then a duty between about 40 and 115, with 77 being the centre value. -If you connect a servo to the power and ground pins, and then the signal line -to pin 12 (other pins will work just as well), you can control the motor using:: - - >>> servo = machine.PWM(machine.Pin(12), freq=50) - >>> servo.duty(40) - >>> servo.duty(115) - >>> servo.duty(77) diff --git a/docs/esp8266/tutorial/repl.rst b/docs/esp8266/tutorial/repl.rst deleted file mode 100644 index ba64fcccbe6..00000000000 --- a/docs/esp8266/tutorial/repl.rst +++ /dev/null @@ -1,212 +0,0 @@ -Getting a MicroPython REPL prompt -================================= - -REPL stands for Read Evaluate Print Loop, and is the name given to the -interactive MicroPython prompt that you can access on the ESP8266. Using the -REPL is by far the easiest way to test out your code and run commands. - -There are two ways to access the REPL: either via a wired connection through the -UART serial port, or via WiFi. - -REPL over the serial port -------------------------- - -The REPL is always available on the UART0 serial peripheral, which is connected -to the pins GPIO1 for TX and GPIO3 for RX. The baudrate of the REPL is 115200. -If your board has a USB-serial convertor on it then you should be able to access -the REPL directly from your PC. Otherwise you will need to have a way of -communicating with the UART. - -To access the prompt over USB-serial you need to use a terminal emulator program. -On Windows TeraTerm is a good choice, on Mac you can use the built-in screen -program, and Linux has picocom and minicom. Of course, there are many other -terminal programs that will work, so pick your favourite! - -For example, on Linux you can try running:: - - picocom /dev/ttyUSB0 -b115200 - -Once you have made the connection over the serial port you can test if it is -working by hitting enter a few times. You should see the Python REPL prompt, -indicated by ``>>>``. - -WebREPL - a prompt over WiFi ----------------------------- - -WebREPL allows you to use the Python prompt over WiFi, connecting through a -browser. The latest versions of Firefox and Chrome are supported. - -For your convenience, WebREPL client is hosted at -``__ . Alternatively, you can install it -locally from the the GitHub repository -``__ . - -Before connecting to WebREPL, you should set a password and enable it via -a normal serial connection. Initial versions of MicroPython for ESP8266 -came with WebREPL automatically enabled on the boot and with the -ability to set a password via WiFi on the first connection, but as WebREPL -was becoming more widely known and popular, the initial setup has switched -to a wired connection for improved security:: - - import webrepl_setup - -Follow the on-screen instructions and prompts. To make any changes active, -you will need to reboot your device. - -To use WebREPL connect your computer to the ESP8266's access point -(MicroPython-xxxxxx, see the previous section about this). If you have -already reconfigured your ESP8266 to connect to a router then you can -skip this part. - -Once you are on the same network as the ESP8266 you click the "Connect" button -(if you are connecting via a router then you may need to change the IP address, -by default the IP address is correct when connected to the ESP8266's access -point). If the connection succeeds then you should see a password prompt. - -Once you type the password configured at the setup step above, press Enter once -more and you should get a prompt looking like ``>>>``. You can now start -typing Python commands! - -Using the REPL --------------- - -Once you have a prompt you can start experimenting! Anything you type at the -prompt will be executed after you press the Enter key. MicroPython will run -the code that you enter and print the result (if there is one). If there is an -error with the text that you enter then an error message is printed. - -Try typing the following at the prompt:: - - >>> print('hello esp8266!') - hello esp8266! - -Note that you shouldn't type the ``>>>`` arrows, they are there to indicate that -you should type the text after it at the prompt. And then the line following is -what the device should respond with. In the end, once you have entered the text -``print("hello esp8266!")`` and pressed the Enter key, the output on your screen -should look exactly like it does above. - -If you already know some python you can now try some basic commands here. For -example:: - - >>> 1 + 2 - 3 - >>> 1 / 2 - 0.5 - >>> 12**34 - 4922235242952026704037113243122008064 - -If your board has an LED attached to GPIO2 (the ESP-12 modules do) then you can -turn it on and off using the following code:: - - >>> import machine - >>> pin = machine.Pin(2, machine.Pin.OUT) - >>> pin.on() - >>> pin.off() - -Note that ``on`` method of a Pin might turn the LED off and ``off`` might -turn it on (or vice versa), depending on how the LED is wired on your board. -To resolve this, machine.Signal class is provided. - -Line editing -~~~~~~~~~~~~ - -You can edit the current line that you are entering using the left and right -arrow keys to move the cursor, as well as the delete and backspace keys. Also, -pressing Home or ctrl-A moves the cursor to the start of the line, and pressing -End or ctrl-E moves to the end of the line. - -Input history -~~~~~~~~~~~~~ - -The REPL remembers a certain number of previous lines of text that you entered -(up to 8 on the ESP8266). To recall previous lines use the up and down arrow -keys. - -Tab completion -~~~~~~~~~~~~~~ - -Pressing the Tab key will do an auto-completion of the current word that you are -entering. This can be very useful to find out functions and methods that a -module or object has. Try it out by typing "ma" and then pressing Tab. It -should complete to "machine" (assuming you imported machine in the above -example). Then type "." and press Tab again to see a list of all the functions -that the machine module has. - -Line continuation and auto-indent -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Certain things that you type will need "continuing", that is, will need more -lines of text to make a proper Python statement. In this case the prompt will -change to ``...`` and the cursor will auto-indent the correct amount so you can -start typing the next line straight away. Try this by defining the following -function:: - - >>> def toggle(p): - ... p.value(not p.value()) - ... - ... - ... - >>> - -In the above, you needed to press the Enter key three times in a row to finish -the compound statement (that's the three lines with just dots on them). The -other way to finish a compound statement is to press backspace to get to the -start of the line, then press the Enter key. (If you did something wrong and -want to escape the continuation mode then press ctrl-C; all lines will be -ignored.) - -The function you just defined allows you to toggle a pin. The pin object you -created earlier should still exist (recreate it if it doesn't) and you can -toggle the LED using:: - - >>> toggle(pin) - -Let's now toggle the LED in a loop (if you don't have an LED then you can just -print some text instead of calling toggle, to see the effect):: - - >>> import time - >>> while True: - ... toggle(pin) - ... time.sleep_ms(500) - ... - ... - ... - >>> - -This will toggle the LED at 1Hz (half a second on, half a second off). To stop -the toggling press ctrl-C, which will raise a KeyboardInterrupt exception and -break out of the loop. - -The time module provides some useful functions for making delays and doing -timing. Use tab completion to find out what they are and play around with them! - -Paste mode -~~~~~~~~~~ - -Pressing ctrl-E will enter a special paste mode. This allows you to copy and -paste a chunk of text into the REPL. If you press ctrl-E you will see the -paste-mode prompt:: - - paste mode; Ctrl-C to cancel, Ctrl-D to finish - === - -You can then paste (or type) your text in. Note that none of the special keys -or commands work in paste mode (eg Tab or backspace), they are just accepted -as-is. Press ctrl-D to finish entering the text and execute it. - -Other control commands -~~~~~~~~~~~~~~~~~~~~~~ - -There are four other control commands: - -* Ctrl-A on a blank line will enter raw REPL mode. This is like a permanent - paste mode, except that characters are not echoed back. - -* Ctrl-B on a blank like goes to normal REPL mode. - -* Ctrl-C cancels any input, or interrupts the currently running code. - -* Ctrl-D on a blank line will do a soft reset. - -Note that ctrl-A and ctrl-D do not work with WebREPL. diff --git a/docs/esp8266_index.rst b/docs/esp8266_index.rst deleted file mode 100644 index 519acecda54..00000000000 --- a/docs/esp8266_index.rst +++ /dev/null @@ -1,12 +0,0 @@ -MicroPython documentation and references -======================================== - -.. toctree:: - - esp8266/quickref.rst - esp8266/general.rst - esp8266/tutorial/index.rst - library/index.rst - reference/index.rst - genrst/index.rst - license.rst diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 00000000000..a85772fdc9c --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,54 @@ +Adafruit CircuitPython API Reference +==================================== + +Welcome to the API reference documentation for Adafruit CircuitPython. +This contains low-level API reference docs which may link out to separate +*"getting started"* guides. `Adafruit `_ has many +excellent tutorials available through the +`Adafruit Learning System `_. + +.. include:: ../README.rst + +.. _contents: + +Full Table of Contents +---------------------- + +.. toctree:: + :maxdepth: 3 + :caption: API and Usage + + ../shared-bindings/index.rst + supported_ports.rst + troubleshooting.rst + drivers.rst + +.. toctree:: + :maxdepth: 1 + :caption: Design and porting reference + + design_guide + porting + common_hal + +.. toctree:: + :maxdepth: 2 + :caption: MicroPython specific + + library/index.rst + +.. toctree:: + :maxdepth: 1 + :caption: About the project + + ../README + ../CONTRIBUTING + ../CODE_OF_CONDUCT + ../license.rst + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/library/_thread.rst b/docs/library/_thread.rst deleted file mode 100644 index 47c1c2392d8..00000000000 --- a/docs/library/_thread.rst +++ /dev/null @@ -1,12 +0,0 @@ -:mod:`_thread` -- multithreading support -======================================== - -.. module:: _thread - :synopsis: multithreading support - -|see_cpython_module| :mod:`python:_thread`. - -This module implements multithreading support. - -This module is highly experimental and its API is not yet fully settled -and not yet described in this documentation. diff --git a/docs/library/array.rst b/docs/library/array.rst index f837b034369..d0121cb3ea0 100644 --- a/docs/library/array.rst +++ b/docs/library/array.rst @@ -4,7 +4,7 @@ .. module:: array :synopsis: efficient arrays of numeric data -|see_cpython_module| :mod:`python:array`. +|see_cpython_module| :mod:`cpython:array`. Supported format codes: ``b``, ``B``, ``h``, ``H``, ``i``, ``I``, ``l``, ``L``, ``q``, ``Q``, ``f``, ``d`` (the latter 2 depending on the @@ -16,14 +16,14 @@ Classes .. class:: array.array(typecode, [iterable]) Create array with elements of given type. Initial contents of the - array are given by *iterable*. If it is not provided, an empty + array are given by an `iterable`. If it is not provided, an empty array is created. .. method:: append(val) - Append new element *val* to the end of array, growing it. + Append new element ``val`` to the end of array, growing it. .. method:: extend(iterable) - Append new elements as contained in *iterable* to the end of + Append new elements as contained in `iterable` to the end of array, growing it. diff --git a/docs/library/binascii.rst b/docs/library/binascii.rst new file mode 100644 index 00000000000..e4878a6faad --- /dev/null +++ b/docs/library/binascii.rst @@ -0,0 +1,40 @@ +:mod:`binascii` -- binary/ASCII conversions +============================================ + +.. module:: binascii + :synopsis: binary/ASCII conversions + +|see_cpython_module| :mod:`cpython:binascii`. + +This module implements conversions between binary data and various +encodings of it in ASCII form (in both directions). + +Functions +--------- + +.. function:: hexlify(data, [sep]) + + Convert binary data to hexadecimal representation. Returns bytes string. + + .. admonition:: Difference to CPython + :class: attention + + If additional argument, *sep* is supplied, it is used as a separator + between hexadecimal values. + +.. function:: unhexlify(data) + + Convert hexadecimal data to binary representation. Returns bytes string. + (i.e. inverse of hexlify) + +.. function:: a2b_base64(data) + + Decode base64-encoded data, ignoring invalid characters in the input. + Conforms to `RFC 2045 s.6.8 `_. + Returns a bytes object. + +.. function:: b2a_base64(data) + + Encode binary data in base64 format, as in `RFC 3548 + `_. Returns the encoded data + followed by a newline character, as a bytes object. diff --git a/docs/library/btree.rst b/docs/library/btree.rst index 3578acd8fd4..4c7b30d5ca7 100644 --- a/docs/library/btree.rst +++ b/docs/library/btree.rst @@ -1,11 +1,13 @@ :mod:`btree` -- simple BTree database ===================================== +.. include:: ../templates/unsupported_in_circuitpython.inc + .. module:: btree :synopsis: simple BTree database The ``btree`` module implements a simple key-value database using external -storage (disk files, or in general case, a random-access `stream`). Keys are +storage (disk files, or in general case, a random-access ``stream``). Keys are stored sorted in the database, and besides efficient retrieval by a key value, a database also supports efficient ordered range scans (retrieval of values with the keys in a given range). On the application interface @@ -78,7 +80,7 @@ Functions .. function:: open(stream, \*, flags=0, pagesize=0, cachesize=0, minkeypage=0) - Open a database from a random-access `stream` (like an open file). All + Open a database from a random-access ``stream`` (like an open file). All other parameters are optional and keyword-only, and allow to tweak advanced parameters of the database operation (most users will not need them): diff --git a/docs/library/builtins.rst b/docs/library/builtins.rst index 365248dc764..6cbf95d53c5 100644 --- a/docs/library/builtins.rst +++ b/docs/library/builtins.rst @@ -7,6 +7,8 @@ available via ``builtins`` module. Functions and types ------------------- +Not all of these functions and types are turned on in all CircuitPython ports, for space reasons. + .. function:: abs() .. function:: all() @@ -21,7 +23,7 @@ Functions and types .. class:: bytes() - |see_cpython| `python:bytes`. + |see_cpython| `bytes`. .. function:: callable() @@ -56,6 +58,8 @@ Functions and types .. class:: frozenset() +`frozenset()` is not enabled on non-Express CircuitPython boards. + .. function:: getattr() .. function:: globals() @@ -74,12 +78,12 @@ Functions and types .. classmethod:: from_bytes(bytes, byteorder) - In MicroPython, `byteorder` parameter must be positional (this is + In CircuitPython, ``byteorder`` parameter must be positional (this is compatible with CPython). .. method:: to_bytes(size, byteorder) - In MicroPython, `byteorder` parameter must be positional (this is + In CircuitPython, ``byteorder`` parameter must be positional (this is compatible with CPython). .. function:: isinstance() @@ -124,6 +128,8 @@ Functions and types .. function:: reversed() +`reversed()` is not enabled on non-Express CircuitPython boards. + .. function:: round() .. class:: set() @@ -176,23 +182,27 @@ Exceptions .. exception:: OSError - |see_cpython| `python:OSError`. MicroPython doesn't implement ``errno`` + |see_cpython| :py:class:`cpython:OSError`. CircuitPython doesn't implement the ``errno`` attribute, instead use the standard way to access exception arguments: ``exc.args[0]``. .. exception:: RuntimeError +.. exception:: ReloadException + + `ReloadException` is used internally to deal with soft restarts. + .. exception:: StopIteration .. exception:: SyntaxError .. exception:: SystemExit - |see_cpython| `python:SystemExit`. + |see_cpython| :py:class:`cpython:SystemExit`. .. exception:: TypeError - |see_cpython| `python:TypeError`. + |see_cpython| :py:class:`cpython:TypeError`. .. exception:: ValueError diff --git a/docs/library/cmath.rst b/docs/library/cmath.rst deleted file mode 100644 index 59e4ec17229..00000000000 --- a/docs/library/cmath.rst +++ /dev/null @@ -1,63 +0,0 @@ -:mod:`cmath` -- mathematical functions for complex numbers -========================================================== - -.. module:: cmath - :synopsis: mathematical functions for complex numbers - -|see_cpython_module| :mod:`python:cmath`. - -The ``cmath`` module provides some basic mathematical functions for -working with complex numbers. - -Availability: not available on WiPy and ESP8266. Floating point support -required for this module. - -Functions ---------- - -.. function:: cos(z) - - Return the cosine of ``z``. - -.. function:: exp(z) - - Return the exponential of ``z``. - -.. function:: log(z) - - Return the natural logarithm of ``z``. The branch cut is along the negative real axis. - -.. function:: log10(z) - - Return the base-10 logarithm of ``z``. The branch cut is along the negative real axis. - -.. function:: phase(z) - - Returns the phase of the number ``z``, in the range (-pi, +pi]. - -.. function:: polar(z) - - Returns, as a tuple, the polar form of ``z``. - -.. function:: rect(r, phi) - - Returns the complex number with modulus ``r`` and phase ``phi``. - -.. function:: sin(z) - - Return the sine of ``z``. - -.. function:: sqrt(z) - - Return the square-root of ``z``. - -Constants ---------- - -.. data:: e - - base of the natural logarithm - -.. data:: pi - - the ratio of a circle's circumference to its diameter diff --git a/docs/library/collections.rst b/docs/library/collections.rst new file mode 100644 index 00000000000..849e8b69445 --- /dev/null +++ b/docs/library/collections.rst @@ -0,0 +1,57 @@ +:mod:`collections` -- collection and container types +===================================================== + +.. include:: ../templates/unsupported_in_circuitpython.inc + +.. module:: collections + :synopsis: collection and container types + +|see_cpython_module| :mod:`cpython:collections`. + +This module implements advanced collection and container types to +hold/accumulate various objects. + +Classes +------- + +.. function:: namedtuple(name, fields) + + This is factory function to create a new namedtuple type with a specific + name and set of fields. A namedtuple is a subclass of tuple which allows + to access its fields not just by numeric index, but also with an attribute + access syntax using symbolic field names. Fields is a sequence of strings + specifying field names. For compatibility with CPython it can also be a + a string with space-separated field named (but this is less efficient). + Example of use:: + + from collections import namedtuple + + MyTuple = namedtuple("MyTuple", ("id", "name")) + t1 = MyTuple(1, "foo") + t2 = MyTuple(2, "bar") + print(t1.name) + assert t2.name == t2[1] + +.. function:: OrderedDict(...) + + ``dict`` type subclass which remembers and preserves the order of keys + added. When ordered dict is iterated over, keys/items are returned in + the order they were added:: + + from collections import OrderedDict + + # To make benefit of ordered keys, OrderedDict should be initialized + # from sequence of (key, value) pairs. + d = OrderedDict([("z", 1), ("a", 2)]) + # More items can be added as usual + d["w"] = 5 + d["b"] = 3 + for k, v in d.items(): + print(k, v) + + Output:: + + z 1 + a 2 + w 5 + b 3 diff --git a/docs/library/esp.rst b/docs/library/esp.rst index 121a80d42e7..125aaa890f9 100644 --- a/docs/library/esp.rst +++ b/docs/library/esp.rst @@ -1,6 +1,8 @@ :mod:`esp` --- functions related to the ESP8266 =============================================== +.. include:: ../templates/unsupported_in_circuitpython.inc + .. module:: esp :synopsis: functions related to the ESP8266 diff --git a/docs/library/framebuf.rst b/docs/library/framebuf.rst index ed4b78ab146..3117525dda3 100644 --- a/docs/library/framebuf.rst +++ b/docs/library/framebuf.rst @@ -1,6 +1,8 @@ :mod:`framebuf` --- Frame buffer manipulation ============================================= +.. include:: ../templates/unsupported_in_circuitpython.inc + .. module:: framebuf :synopsis: Frame buffer manipulation diff --git a/docs/library/gc.rst b/docs/library/gc.rst index c823aed3e68..1a6c3d68c05 100644 --- a/docs/library/gc.rst +++ b/docs/library/gc.rst @@ -1,10 +1,12 @@ :mod:`gc` -- control the garbage collector ========================================== +.. include:: ../templates/unsupported_in_circuitpython.inc + .. module:: gc :synopsis: control the garbage collector -|see_cpython_module| :mod:`python:gc`. +|see_cpython_module| :mod:`cpython:gc`. Functions --------- @@ -29,7 +31,7 @@ Functions .. admonition:: Difference to CPython :class: attention - This function is MicroPython extension. + This function is a MicroPython extension. .. function:: mem_free() @@ -39,7 +41,7 @@ Functions .. admonition:: Difference to CPython :class: attention - This function is MicroPython extension. + This function is a MicroPython extension. .. function:: threshold([amount]) @@ -61,6 +63,6 @@ Functions .. admonition:: Difference to CPython :class: attention - This function is a MicroPython extension. CPython has a similar + This function is a a MicroPython extension. CPython has a similar function - ``set_threshold()``, but due to different GC implementations, its signature and semantics are different. diff --git a/docs/library/hashlib.rst b/docs/library/hashlib.rst new file mode 100644 index 00000000000..0205d5e6a8c --- /dev/null +++ b/docs/library/hashlib.rst @@ -0,0 +1,59 @@ +:mod:`hashlib` -- hashing algorithms +===================================== + +.. include:: ../templates/unsupported_in_circuitpython.inc + +.. module:: hashlib + :synopsis: hashing algorithms + +|see_cpython_module| :mod:`cpython:hashlib`. + +This module implements binary data hashing algorithms. The exact inventory +of available algorithms depends on a board. Among the algorithms which may +be implemented: + +* SHA256 - The current generation, modern hashing algorithm (of SHA2 series). + It is suitable for cryptographically-secure purposes. Included in the + MicroPython core and any board is recommended to provide this, unless + it has particular code size constraints. + +* SHA1 - A previous generation algorithm. Not recommended for new usages, + but SHA1 is a part of number of Internet standards and existing + applications, so boards targeting network connectivity and + interoperatiability will try to provide this. + +* MD5 - A legacy algorithm, not considered cryptographically secure. Only + selected boards, targeting interoperatibility with legacy applications, + will offer this. + +Constructors +------------ + +.. class:: hashlib.sha256([data]) + + Create an SHA256 hasher object and optionally feed ``data`` into it. + +.. class:: hashlib.sha1([data]) + + Create an SHA1 hasher object and optionally feed ``data`` into it. + +.. class:: hashlib.md5([data]) + + Create an MD5 hasher object and optionally feed ``data`` into it. + +Methods +------- + +.. method:: hash.update(data) + + Feed more binary data into hash. + +.. method:: hash.digest() + + Return hash for all data passed through hash, as a bytes object. After this + method is called, more data cannot be fed into the hash any longer. + +.. method:: hash.hexdigest() + + This method is NOT implemented. Use ``binascii.hexlify(hash.digest())`` + to achieve a similar effect. diff --git a/docs/library/index.rst b/docs/library/index.rst index d5678d37e36..6c2e576e7de 100644 --- a/docs/library/index.rst +++ b/docs/library/index.rst @@ -3,219 +3,90 @@ MicroPython libraries ===================== -.. warning:: - - Important summary of this section - - * MicroPython implements a subset of Python functionality for each module. - * To ease extensibility, MicroPython versions of standard Python modules - usually have ``u`` ("micro") prefix. - * Any particular MicroPython variant or port may miss any feature/function - described in this general documentation (due to resource constraints or - other limitations). - - -This chapter describes modules (function and class libraries) which are built -into MicroPython. There are a few categories of such modules: - -* Modules which implement a subset of standard Python functionality and are not - intended to be extended by the user. -* Modules which implement a subset of Python functionality, with a provision - for extension by the user (via Python code). -* Modules which implement MicroPython extensions to the Python standard libraries. -* Modules specific to a particular `MicroPython port` and thus not portable. - -Note about the availability of the modules and their contents: This documentation -in general aspires to describe all modules and functions/classes which are -implemented in MicroPython project. However, MicroPython is highly configurable, and -each port to a particular board/embedded system makes available only a subset -of MicroPython libraries. For officially supported ports, there is an effort -to either filter out non-applicable items, or mark individual descriptions -with "Availability:" clauses describing which ports provide a given feature. - -With that in mind, please still be warned that some functions/classes -in a module (or even the entire module) described in this documentation **may be -unavailable** in a particular build of MicroPython on a particular system. The -best place to find general information of the availability/non-availability -of a particular feature is the "General Information" section which contains -information pertaining to a specific `MicroPython port`. - -Beyond the built-in libraries described in this documentation, many more -modules from the Python standard library, as well as further MicroPython -extensions to it, can be found in `micropython-lib`. - Python standard libraries and micro-libraries --------------------------------------------- -The following standard Python libraries have been "micro-ified" to fit in with -the philosophy of MicroPython. They provide the core functionality of that -module and are intended to be a drop-in replacement for the standard Python -library. Some modules below use a standard Python name, but prefixed with "u", -e.g. ``ujson`` instead of ``json``. This is to signify that such a module is -micro-library, i.e. implements only a subset of CPython module functionality. -By naming them differently, a user has a choice to write a Python-level module -to extend functionality for better compatibility with CPython (indeed, this is -what done by the `micropython-lib` project mentioned above). - -On some embedded platforms, where it may be cumbersome to add Python-level -wrapper modules to achieve naming compatibility with CPython, micro-modules -are available both by their u-name, and also by their non-u-name. The -non-u-name can be overridden by a file of that name in your library path (``sys.path``). -For example, ``import json`` will first search for a file ``json.py`` (or package -directory ``json``) and load that module if it is found. If nothing is found, -it will fallback to loading the built-in ``ujson`` module. - -.. only:: port_unix - - .. toctree:: - :maxdepth: 1 - - builtins.rst - array.rst - cmath.rst - gc.rst - math.rst - sys.rst - ubinascii.rst - ucollections.rst - uerrno.rst - uhashlib.rst - uheapq.rst - uio.rst - ujson.rst - uos.rst - ure.rst - uselect.rst - usocket.rst - ussl.rst - ustruct.rst - utime.rst - uzlib.rst - _thread.rst - -.. only:: port_pyboard - - .. toctree:: - :maxdepth: 1 - - builtins.rst - array.rst - cmath.rst - gc.rst - math.rst - sys.rst - ubinascii.rst - ucollections.rst - uerrno.rst - uhashlib.rst - uheapq.rst - uio.rst - ujson.rst - uos.rst - ure.rst - uselect.rst - usocket.rst - ustruct.rst - utime.rst - uzlib.rst - _thread.rst - -.. only:: port_wipy - - .. toctree:: - :maxdepth: 1 - - builtins.rst - array.rst - gc.rst - sys.rst - ubinascii.rst - ujson.rst - uos.rst - ure.rst - uselect.rst - usocket.rst - ussl.rst - utime.rst - -.. only:: port_esp8266 - - .. toctree:: - :maxdepth: 1 - - builtins.rst - array.rst - gc.rst - math.rst - sys.rst - ubinascii.rst - ucollections.rst - uerrno.rst - uhashlib.rst - uheapq.rst - uio.rst - ujson.rst - uos.rst - ure.rst - uselect.rst - usocket.rst - ussl.rst - ustruct.rst - utime.rst - uzlib.rst - - -MicroPython-specific libraries ------------------------------- - -Functionality specific to the MicroPython implementation is available in -the following libraries. - -.. toctree:: - :maxdepth: 1 - - btree.rst - framebuf.rst - machine.rst - micropython.rst - network.rst - uctypes.rst - +These libraries are inherited from MicroPython. +They are similar to the standard Python libraries with the same name +or with the "u" prefix dropped. +They implement a subset of or a variant of the corresponding +standard Python library. -.. only:: port_pyboard - - Libraries specific to the pyboard - --------------------------------- - - The following libraries are specific to the pyboard. +.. warning:: - .. toctree:: - :maxdepth: 2 + Though these MicroPython-based libraries are available in CircuitPython, + their functionality may change in the future, perhaps significantly. + As CircuitPython continues to develop, new versions of these libraries will + be created that are more compliant with the standard Python libraries. + You may need to change your code later if you rely + on any non-standard functionality they currently provide. - pyb.rst - lcd160cr.rst +CircuitPython's goal long-term goalis that code written in CircuitPython +using Python standard libraries will be runnable on CPython without changes. -.. only:: port_wipy +Some libraries below are not enabled on CircuitPython builds with +limited flash memory, usually on non-Express builds: +``uerrno``, ``ure``. - Libraries specific to the WiPy - --------------------------------- +Some libraries are not currently enabled in any CircuitPython build, but may be in the future: +``uio``, ``ujson``, ``uzlib``. - The following libraries are specific to the WiPy. +Some libraries are only enabled only WiFi-capable ports (ESP8266, nRF) +because they are typically used for network software: +``binascii``, ``hashlib``, ``uheapq``, ``uselect``, ``ussl``. +Not all of these are enabled on all WiFi-capable ports. - .. toctree:: - :maxdepth: 2 +.. toctree:: + :maxdepth: 1 - wipy.rst + builtins.rst + uheapq.rst + array.rst + binascii.rst + collections.rst + gc.rst + hashlib.rst + sys.rst + uerrno.rst + uio.rst + ujson.rst + ure.rst + uselect.rst + usocket.rst + ussl.rst + uzlib.rst + +Omitted functions in the ``string`` library +------------------------------------------- + +A few string operations are not enabled on CircuitPython +M0 non-Express builds, due to limited flash memory: +``string.center()``, ``string.partition()``, ``string.splitlines()``, +``string.reversed()``. + + +CircuitPython/MicroPython-specific libraries +-------------------------------------------- + +Functionality specific to the CircuitPython/MicroPython implementation is available in +the following libraries. These libraries may change signficantly or be removed in future +versions of CircuitPtyon. +.. toctree:: + :maxdepth: 1 -.. only:: port_esp8266 + btree.rst + framebuf.rst + micropython.rst + network.rst + uctypes.rst - Libraries specific to the ESP8266 - --------------------------------- +Libraries specific to the ESP8266 +--------------------------------- - The following libraries are specific to the ESP8266. +The following libraries are specific to the ESP8266. - .. toctree:: - :maxdepth: 2 +.. toctree:: + :maxdepth: 2 - esp.rst + esp.rst diff --git a/docs/library/lcd160cr.rst b/docs/library/lcd160cr.rst deleted file mode 100644 index bb8e6da22ce..00000000000 --- a/docs/library/lcd160cr.rst +++ /dev/null @@ -1,394 +0,0 @@ -:mod:`lcd160cr` --- control of LCD160CR display -=============================================== - -.. module:: lcd160cr - :synopsis: control of LCD160CR display - -This module provides control of the MicroPython LCD160CR display. - -.. image:: http://micropython.org/resources/LCD160CRv10-persp.jpg - :alt: LCD160CRv1.0 picture - :width: 640px - -Further resources are available via the following links: - -* `LCD160CRv1.0 reference manual `_ (100KiB PDF) -* `LCD160CRv1.0 schematics `_ (1.6MiB PDF) - -class LCD160CR --------------- - -The LCD160CR class provides an interface to the display. Create an -instance of this class and use its methods to draw to the LCD and get -the status of the touch panel. - -For example:: - - import lcd160cr - - lcd = lcd160cr.LCD160CR('X') - lcd.set_orient(lcd160cr.PORTRAIT) - lcd.set_pos(0, 0) - lcd.set_text_color(lcd.rgb(255, 0, 0), lcd.rgb(0, 0, 0)) - lcd.set_font(1) - lcd.write('Hello MicroPython!') - print('touch:', lcd.get_touch()) - -Constructors ------------- - -.. class:: LCD160CR(connect=None, \*, pwr=None, i2c=None, spi=None, i2c_addr=98) - - Construct an LCD160CR object. The parameters are: - - - *connect* is a string specifying the physical connection of the LCD - display to the board; valid values are "X", "Y", "XY", "YX". - Use "X" when the display is connected to a pyboard in the X-skin - position, and "Y" when connected in the Y-skin position. "XY" - and "YX" are used when the display is connected to the right or - left side of the pyboard, respectively. - - *pwr* is a Pin object connected to the LCD's power/enabled pin. - - *i2c* is an I2C object connected to the LCD's I2C interface. - - *spi* is an SPI object connected to the LCD's SPI interface. - - *i2c_addr* is the I2C address of the display. - - One must specify either a valid *connect* or all of *pwr*, *i2c* and *spi*. - If a valid *connect* is given then any of *pwr*, *i2c* or *spi* which are - not passed as parameters (i.e. they are ``None``) will be created based on the - value of *connect*. This allows to override the default interface to the - display if needed. - - The default values are: - - - "X" is for the X-skin and uses: - ``pwr=Pin("X4")``, ``i2c=I2C("X")``, ``spi=SPI("X")`` - - "Y" is for the Y-skin and uses: - ``pwr=Pin("Y4")``, ``i2c=I2C("Y")``, ``spi=SPI("Y")`` - - "XY" is for the right-side and uses: - ``pwr=Pin("X4")``, ``i2c=I2C("Y")``, ``spi=SPI("X")`` - - "YX" is for the left-side and uses: - ``pwr=Pin("Y4")``, ``i2c=I2C("X")``, ``spi=SPI("Y")`` - - See `this image `_ - for how the display can be connected to the pyboard. - -Static methods --------------- - -.. staticmethod:: LCD160CR.rgb(r, g, b) - - Return a 16-bit integer representing the given rgb color values. The - 16-bit value can be used to set the font color (see - :meth:`LCD160CR.set_text_color`) pen color (see :meth:`LCD160CR.set_pen`) - and draw individual pixels. - -.. staticmethod:: LCD160CR.clip_line(data, w, h): - - Clip the given line data. This is for internal use. - -Instance members ----------------- - -The following instance members are publicly accessible. - -.. data:: LCD160CR.w -.. data:: LCD160CR.h - - The width and height of the display, respectively, in pixels. These - members are updated when calling :meth:`LCD160CR.set_orient` and should - be considered read-only. - -Setup commands --------------- - -.. method:: LCD160CR.set_power(on) - - Turn the display on or off, depending on the given value of *on*: 0 or ``False`` - will turn the display off, and 1 or ``True`` will turn it on. - -.. method:: LCD160CR.set_orient(orient) - - Set the orientation of the display. The *orient* parameter can be one - of `PORTRAIT`, `LANDSCAPE`, `PORTRAIT_UPSIDEDOWN`, `LANDSCAPE_UPSIDEDOWN`. - -.. method:: LCD160CR.set_brightness(value) - - Set the brightness of the display, between 0 and 31. - -.. method:: LCD160CR.set_i2c_addr(addr) - - Set the I2C address of the display. The *addr* value must have the - lower 2 bits cleared. - -.. method:: LCD160CR.set_uart_baudrate(baudrate) - - Set the baudrate of the UART interface. - -.. method:: LCD160CR.set_startup_deco(value) - - Set the start-up decoration of the display. The *value* parameter can be a - logical or of `STARTUP_DECO_NONE`, `STARTUP_DECO_MLOGO`, `STARTUP_DECO_INFO`. - -.. method:: LCD160CR.save_to_flash() - - Save the following parameters to flash so they persist on restart and power up: - initial decoration, orientation, brightness, UART baud rate, I2C address. - -Pixel access methods --------------------- - -The following methods manipulate individual pixels on the display. - -.. method:: LCD160CR.set_pixel(x, y, c) - - Set the specified pixel to the given color. The color should be a 16-bit - integer and can be created by :meth:`LCD160CR.rgb`. - -.. method:: LCD160CR.get_pixel(x, y) - - Get the 16-bit value of the specified pixel. - -.. method:: LCD160CR.get_line(x, y, buf) - - Low-level method to get a line of pixels into the given buffer. - To read *n* pixels *buf* should be *2*n+1* bytes in length. The first byte - is a dummy byte and should be ignored, and subsequent bytes represent the - pixels in the line starting at coordinate *(x, y)*. - -.. method:: LCD160CR.screen_dump(buf, x=0, y=0, w=None, h=None) - - Dump the contents of the screen to the given buffer. The parameters *x* and *y* - specify the starting coordinate, and *w* and *h* the size of the region. If *w* - or *h* are ``None`` then they will take on their maximum values, set by the size - of the screen minus the given *x* and *y* values. *buf* should be large enough - to hold ``2*w*h`` bytes. If it's smaller then only the initial horizontal lines - will be stored. - -.. method:: LCD160CR.screen_load(buf) - - Load the entire screen from the given buffer. - -Drawing text ------------- - -To draw text one sets the position, color and font, and then uses -`LCD160CR.write` to draw the text. - -.. method:: LCD160CR.set_pos(x, y) - - Set the position for text output using :meth:`LCD160CR.write`. The position - is the upper-left corner of the text. - -.. method:: LCD160CR.set_text_color(fg, bg) - - Set the foreground and background color of the text. - -.. method:: LCD160CR.set_font(font, scale=0, bold=0, trans=0, scroll=0) - - Set the font for the text. Subsequent calls to `write` will use the newly - configured font. The parameters are: - - - *font* is the font family to use, valid values are 0, 1, 2, 3. - - *scale* is a scaling value for each character pixel, where the pixels - are drawn as a square with side length equal to *scale + 1*. The value - can be between 0 and 63. - - *bold* controls the number of pixels to overdraw each character pixel, - making a bold effect. The lower 2 bits of *bold* are the number of - pixels to overdraw in the horizontal direction, and the next 2 bits are - for the vertical direction. For example, a *bold* value of 5 will - overdraw 1 pixel in both the horizontal and vertical directions. - - *trans* can be either 0 or 1 and if set to 1 the characters will be - drawn with a transparent background. - - *scroll* can be either 0 or 1 and if set to 1 the display will do a - soft scroll if the text moves to the next line. - -.. method:: LCD160CR.write(s) - - Write text to the display, using the current position, color and font. - As text is written the position is automatically incremented. The - display supports basic VT100 control codes such as newline and backspace. - -Drawing primitive shapes ------------------------- - -Primitive drawing commands use a foreground and background color set by the -`set_pen` method. - -.. method:: LCD160CR.set_pen(line, fill) - - Set the line and fill color for primitive shapes. - -.. method:: LCD160CR.erase() - - Erase the entire display to the pen fill color. - -.. method:: LCD160CR.dot(x, y) - - Draw a single pixel at the given location using the pen line color. - -.. method:: LCD160CR.rect(x, y, w, h) -.. method:: LCD160CR.rect_outline(x, y, w, h) -.. method:: LCD160CR.rect_interior(x, y, w, h) - - Draw a rectangle at the given location and size using the pen line - color for the outline, and the pen fill color for the interior. - The `rect` method draws the outline and interior, while the other methods - just draw one or the other. - -.. method:: LCD160CR.line(x1, y1, x2, y2) - - Draw a line between the given coordinates using the pen line color. - -.. method:: LCD160CR.dot_no_clip(x, y) -.. method:: LCD160CR.rect_no_clip(x, y, w, h) -.. method:: LCD160CR.rect_outline_no_clip(x, y, w, h) -.. method:: LCD160CR.rect_interior_no_clip(x, y, w, h) -.. method:: LCD160CR.line_no_clip(x1, y1, x2, y2) - - These methods are as above but don't do any clipping on the input - coordinates. They are faster than the clipping versions and can be - used when you know that the coordinates are within the display. - -.. method:: LCD160CR.poly_dot(data) - - Draw a sequence of dots using the pen line color. - The *data* should be a buffer of bytes, with each successive pair of - bytes corresponding to coordinate pairs (x, y). - -.. method:: LCD160CR.poly_line(data) - - Similar to :meth:`LCD160CR.poly_dot` but draws lines between the dots. - -Touch screen methods --------------------- - -.. method:: LCD160CR.touch_config(calib=False, save=False, irq=None) - - Configure the touch panel: - - - If *calib* is ``True`` then the call will trigger a touch calibration of - the resistive touch sensor. This requires the user to touch various - parts of the screen. - - If *save* is ``True`` then the touch parameters will be saved to NVRAM - to persist across reset/power up. - - If *irq* is ``True`` then the display will be configured to pull the IRQ - line low when a touch force is detected. If *irq* is ``False`` then this - feature is disabled. If *irq* is ``None`` (the default value) then no - change is made to this setting. - -.. method:: LCD160CR.is_touched() - - Returns a boolean: ``True`` if there is currently a touch force on the screen, - ``False`` otherwise. - -.. method:: LCD160CR.get_touch() - - Returns a 3-tuple of: *(active, x, y)*. If there is currently a touch force - on the screen then *active* is 1, otherwise it is 0. The *x* and *y* values - indicate the position of the current or most recent touch. - -Advanced commands ------------------ - -.. method:: LCD160CR.set_spi_win(x, y, w, h) - - Set the window that SPI data is written to. - -.. method:: LCD160CR.fast_spi(flush=True) - - Ready the display to accept RGB pixel data on the SPI bus, resetting the location - of the first byte to go to the top-left corner of the window set by - :meth:`LCD160CR.set_spi_win`. - The method returns an SPI object which can be used to write the pixel data. - - Pixels should be sent as 16-bit RGB values in the 5-6-5 format. The destination - counter will increase as data is sent, and data can be sent in arbitrary sized - chunks. Once the destination counter reaches the end of the window specified by - :meth:`LCD160CR.set_spi_win` it will wrap around to the top-left corner of that window. - -.. method:: LCD160CR.show_framebuf(buf) - - Show the given buffer on the display. *buf* should be an array of bytes containing - the 16-bit RGB values for the pixels, and they will be written to the area - specified by :meth:`LCD160CR.set_spi_win`, starting from the top-left corner. - - The `framebuf `_ module can be used to construct frame buffers - and provides drawing primitives. Using a frame buffer will improve - performance of animations when compared to drawing directly to the screen. - -.. method:: LCD160CR.set_scroll(on) - - Turn scrolling on or off. This controls globally whether any window regions will - scroll. - -.. method:: LCD160CR.set_scroll_win(win, x=-1, y=0, w=0, h=0, vec=0, pat=0, fill=0x07e0, color=0) - - Configure a window region for scrolling: - - - *win* is the window id to configure. There are 0..7 standard windows for - general purpose use. Window 8 is the text scroll window (the ticker). - - *x*, *y*, *w*, *h* specify the location of the window in the display. - - *vec* specifies the direction and speed of scroll: it is a 16-bit value - of the form ``0bF.ddSSSSSSSSSSSS``. *dd* is 0, 1, 2, 3 for +x, +y, -x, - -y scrolling. *F* sets the speed format, with 0 meaning that the window - is shifted *S % 256* pixel every frame, and 1 meaning that the window - is shifted 1 pixel every *S* frames. - - *pat* is a 16-bit pattern mask for the background. - - *fill* is the fill color. - - *color* is the extra color, either of the text or pattern foreground. - -.. method:: LCD160CR.set_scroll_win_param(win, param, value) - - Set a single parameter of a scrolling window region: - - - *win* is the window id, 0..8. - - *param* is the parameter number to configure, 0..7, and corresponds - to the parameters in the `set_scroll_win` method. - - *value* is the value to set. - -.. method:: LCD160CR.set_scroll_buf(s) - - Set the string for scrolling in window 8. The parameter *s* must be a string - with length 32 or less. - -.. method:: LCD160CR.jpeg(buf) - - Display a JPEG. *buf* should contain the entire JPEG data. JPEG data should - not include EXIF information. The following encodings are supported: Baseline - DCT, Huffman coding, 8 bits per sample, 3 color components, YCbCr4:2:2. - The origin of the JPEG is set by :meth:`LCD160CR.set_pos`. - -.. method:: LCD160CR.jpeg_start(total_len) -.. method:: LCD160CR.jpeg_data(buf) - - Display a JPEG with the data split across multiple buffers. There must be - a single call to `jpeg_start` to begin with, specifying the total number of - bytes in the JPEG. Then this number of bytes must be transferred to the - display using one or more calls to the `jpeg_data` command. - -.. method:: LCD160CR.feed_wdt() - - The first call to this method will start the display's internal watchdog - timer. Subsequent calls will feed the watchdog. The timeout is roughly 30 - seconds. - -.. method:: LCD160CR.reset() - - Reset the display. - -Constants ---------- - -.. data:: lcd160cr.PORTRAIT - lcd160cr.LANDSCAPE - lcd160cr.PORTRAIT_UPSIDEDOWN - lcd160cr.LANDSCAPE_UPSIDEDOWN - - Orientations of the display, used by :meth:`LCD160CR.set_orient`. - -.. data:: lcd160cr.STARTUP_DECO_NONE - lcd160cr.STARTUP_DECO_MLOGO - lcd160cr.STARTUP_DECO_INFO - - Types of start-up decoration, can be OR'ed together, used by - :meth:`LCD160CR.set_startup_deco`. diff --git a/docs/library/machine.ADC.rst b/docs/library/machine.ADC.rst deleted file mode 100644 index 4c7a04d74f0..00000000000 --- a/docs/library/machine.ADC.rst +++ /dev/null @@ -1,74 +0,0 @@ -.. currentmodule:: machine -.. _machine.ADC: - -class ADC -- analog to digital conversion -========================================= - -Usage:: - - import machine - - adc = machine.ADC() # create an ADC object - apin = adc.channel(pin='GP3') # create an analog pin on GP3 - val = apin() # read an analog value - -Constructors ------------- - -.. class:: ADC(id=0, \*, bits=12) - - Create an ADC object associated with the given pin. - This allows you to then read analog values on that pin. - For more info check the `pinout and alternate functions - table. `_ - - .. warning:: - - ADC pin input range is 0-1.4V (being 1.8V the absolute maximum that it - can withstand). When GP2, GP3, GP4 or GP5 are remapped to the - ADC block, 1.8 V is the maximum. If these pins are used in digital mode, - then the maximum allowed input is 3.6V. - -Methods -------- - -.. method:: ADC.channel(id, \*, pin) - - Create an analog pin. If only channel ID is given, the correct pin will - be selected. Alternatively, only the pin can be passed and the correct - channel will be selected. Examples:: - - # all of these are equivalent and enable ADC channel 1 on GP3 - apin = adc.channel(1) - apin = adc.channel(pin='GP3') - apin = adc.channel(id=1, pin='GP3') - -.. method:: ADC.init() - - Enable the ADC block. - -.. method:: ADC.deinit() - - Disable the ADC block. - -class ADCChannel --- read analog values from internal or external sources -========================================================================= - -ADC channels can be connected to internal points of the MCU or to GPIO pins. -ADC channels are created using the ADC.channel method. - -.. method:: adcchannel() - - Fast method to read the channel value. - -.. method:: adcchannel.value() - - Read the channel value. - -.. method:: adcchannel.init() - - Re-init (and effectively enable) the ADC channel. - -.. method:: adcchannel.deinit() - - Disable the ADC channel. diff --git a/docs/library/machine.I2C.rst b/docs/library/machine.I2C.rst deleted file mode 100644 index a69c58999ff..00000000000 --- a/docs/library/machine.I2C.rst +++ /dev/null @@ -1,172 +0,0 @@ -.. currentmodule:: machine -.. _machine.I2C: - -class I2C -- a two-wire serial protocol -======================================= - -I2C is a two-wire protocol for communicating between devices. At the physical -level it consists of 2 wires: SCL and SDA, the clock and data lines respectively. - -I2C objects are created attached to a specific bus. They can be initialised -when created, or initialised later on. - -Printing the I2C object gives you information about its configuration. - -Example usage:: - - from machine import I2C - - i2c = I2C(freq=400000) # create I2C peripheral at frequency of 400kHz - # depending on the port, extra parameters may be required - # to select the peripheral and/or pins to use - - i2c.scan() # scan for slaves, returning a list of 7-bit addresses - - i2c.writeto(42, b'123') # write 3 bytes to slave with 7-bit address 42 - i2c.readfrom(42, 4) # read 4 bytes from slave with 7-bit address 42 - - i2c.readfrom_mem(42, 8, 3) # read 3 bytes from memory of slave 42, - # starting at memory-address 8 in the slave - i2c.writeto_mem(42, 2, b'\x10') # write 1 byte to memory of slave 42 - # starting at address 2 in the slave - -Constructors ------------- - -.. class:: I2C(id=-1, \*, scl, sda, freq=400000) - - Construct and return a new I2C object using the following parameters: - - - *id* identifies a particular I2C peripheral. The default - value of -1 selects a software implementation of I2C which can - work (in most cases) with arbitrary pins for SCL and SDA. - If *id* is -1 then *scl* and *sda* must be specified. Other - allowed values for *id* depend on the particular port/board, - and specifying *scl* and *sda* may or may not be required or - allowed in this case. - - *scl* should be a pin object specifying the pin to use for SCL. - - *sda* should be a pin object specifying the pin to use for SDA. - - *freq* should be an integer which sets the maximum frequency - for SCL. - -General Methods ---------------- - -.. method:: I2C.init(scl, sda, \*, freq=400000) - - Initialise the I2C bus with the given arguments: - - - *scl* is a pin object for the SCL line - - *sda* is a pin object for the SDA line - - *freq* is the SCL clock rate - -.. method:: I2C.deinit() - - Turn off the I2C bus. - - Availability: WiPy. - -.. method:: I2C.scan() - - Scan all I2C addresses between 0x08 and 0x77 inclusive and return a list of - those that respond. A device responds if it pulls the SDA line low after - its address (including a write bit) is sent on the bus. - -Primitive I2C operations ------------------------- - -The following methods implement the primitive I2C master bus operations and can -be combined to make any I2C transaction. They are provided if you need more -control over the bus, otherwise the standard methods (see below) can be used. - -.. method:: I2C.start() - - Generate a START condition on the bus (SDA transitions to low while SCL is high). - - Availability: ESP8266. - -.. method:: I2C.stop() - - Generate a STOP condition on the bus (SDA transitions to high while SCL is high). - - Availability: ESP8266. - -.. method:: I2C.readinto(buf, nack=True) - - Reads bytes from the bus and stores them into *buf*. The number of bytes - read is the length of *buf*. An ACK will be sent on the bus after - receiving all but the last byte. After the last byte is received, if *nack* - is true then a NACK will be sent, otherwise an ACK will be sent (and in this - case the slave assumes more bytes are going to be read in a later call). - - Availability: ESP8266. - -.. method:: I2C.write(buf) - - Write the bytes from *buf* to the bus. Checks that an ACK is received - after each byte and stops transmitting the remaining bytes if a NACK is - received. The function returns the number of ACKs that were received. - - Availability: ESP8266. - -Standard bus operations ------------------------ - -The following methods implement the standard I2C master read and write -operations that target a given slave device. - -.. method:: I2C.readfrom(addr, nbytes, stop=True) - - Read *nbytes* from the slave specified by *addr*. - If *stop* is true then a STOP condition is generated at the end of the transfer. - Returns a `bytes` object with the data read. - -.. method:: I2C.readfrom_into(addr, buf, stop=True) - - Read into *buf* from the slave specified by *addr*. - The number of bytes read will be the length of *buf*. - If *stop* is true then a STOP condition is generated at the end of the transfer. - - The method returns ``None``. - -.. method:: I2C.writeto(addr, buf, stop=True) - - Write the bytes from *buf* to the slave specified by *addr*. If a - NACK is received following the write of a byte from *buf* then the - remaining bytes are not sent. If *stop* is true then a STOP condition is - generated at the end of the transfer, even if a NACK is received. - The function returns the number of ACKs that were received. - -Memory operations ------------------ - -Some I2C devices act as a memory device (or set of registers) that can be read -from and written to. In this case there are two addresses associated with an -I2C transaction: the slave address and the memory address. The following -methods are convenience functions to communicate with such devices. - -.. method:: I2C.readfrom_mem(addr, memaddr, nbytes, \*, addrsize=8) - - Read *nbytes* from the slave specified by *addr* starting from the memory - address specified by *memaddr*. - The argument *addrsize* specifies the address size in bits. - Returns a `bytes` object with the data read. - -.. method:: I2C.readfrom_mem_into(addr, memaddr, buf, \*, addrsize=8) - - Read into *buf* from the slave specified by *addr* starting from the - memory address specified by *memaddr*. The number of bytes read is the - length of *buf*. - The argument *addrsize* specifies the address size in bits (on ESP8266 - this argument is not recognised and the address size is always 8 bits). - - The method returns ``None``. - -.. method:: I2C.writeto_mem(addr, memaddr, buf, \*, addrsize=8) - - Write *buf* to the slave specified by *addr* starting from the - memory address specified by *memaddr*. - The argument *addrsize* specifies the address size in bits (on ESP8266 - this argument is not recognised and the address size is always 8 bits). - - The method returns ``None``. diff --git a/docs/library/machine.Pin.rst b/docs/library/machine.Pin.rst deleted file mode 100644 index 05ceb4ad338..00000000000 --- a/docs/library/machine.Pin.rst +++ /dev/null @@ -1,248 +0,0 @@ -.. currentmodule:: machine -.. _machine.Pin: - -class Pin -- control I/O pins -============================= - -A pin object is used to control I/O pins (also known as GPIO - general-purpose -input/output). Pin objects are commonly associated with a physical pin that can -drive an output voltage and read input voltages. The pin class has methods to set the mode of -the pin (IN, OUT, etc) and methods to get and set the digital logic level. -For analog control of a pin, see the :class:`ADC` class. - -A pin object is constructed by using an identifier which unambiguously -specifies a certain I/O pin. The allowed forms of the identifier and the -physical pin that the identifier maps to are port-specific. Possibilities -for the identifier are an integer, a string or a tuple with port and pin -number. - -Usage Model:: - - from machine import Pin - - # create an output pin on pin #0 - p0 = Pin(0, Pin.OUT) - - # set the value low then high - p0.value(0) - p0.value(1) - - # create an input pin on pin #2, with a pull up resistor - p2 = Pin(2, Pin.IN, Pin.PULL_UP) - - # read and print the pin value - print(p2.value()) - - # reconfigure pin #0 in input mode - p0.mode(p0.IN) - - # configure an irq callback - p0.irq(lambda p:print(p)) - -Constructors ------------- - -.. class:: Pin(id, mode=-1, pull=-1, \*, value, drive, alt) - - Access the pin peripheral (GPIO pin) associated with the given ``id``. If - additional arguments are given in the constructor then they are used to initialise - the pin. Any settings that are not specified will remain in their previous state. - - The arguments are: - - - ``id`` is mandatory and can be an arbitrary object. Among possible value - types are: int (an internal Pin identifier), str (a Pin name), and tuple - (pair of [port, pin]). - - - ``mode`` specifies the pin mode, which can be one of: - - - ``Pin.IN`` - Pin is configured for input. If viewed as an output the pin - is in high-impedance state. - - - ``Pin.OUT`` - Pin is configured for (normal) output. - - - ``Pin.OPEN_DRAIN`` - Pin is configured for open-drain output. Open-drain - output works in the following way: if the output value is set to 0 the pin - is active at a low level; if the output value is 1 the pin is in a high-impedance - state. Not all ports implement this mode, or some might only on certain pins. - - - ``Pin.ALT`` - Pin is configured to perform an alternative function, which is - port specific. For a pin configured in such a way any other Pin methods - (except :meth:`Pin.init`) are not applicable (calling them will lead to undefined, - or a hardware-specific, result). Not all ports implement this mode. - - - ``Pin.ALT_OPEN_DRAIN`` - The Same as ``Pin.ALT``, but the pin is configured as - open-drain. Not all ports implement this mode. - - - ``pull`` specifies if the pin has a (weak) pull resistor attached, and can be - one of: - - - ``None`` - No pull up or down resistor. - - ``Pin.PULL_UP`` - Pull up resistor enabled. - - ``Pin.PULL_DOWN`` - Pull down resistor enabled. - - - ``value`` is valid only for Pin.OUT and Pin.OPEN_DRAIN modes and specifies initial - output pin value if given, otherwise the state of the pin peripheral remains - unchanged. - - - ``drive`` specifies the output power of the pin and can be one of: ``Pin.LOW_POWER``, - ``Pin.MED_POWER`` or ``Pin.HIGH_POWER``. The actual current driving capabilities - are port dependent. Not all ports implement this argument. - - - ``alt`` specifies an alternate function for the pin and the values it can take are - port dependent. This argument is valid only for ``Pin.ALT`` and ``Pin.ALT_OPEN_DRAIN`` - modes. It may be used when a pin supports more than one alternate function. If only - one pin alternate function is supported the this argument is not required. Not all - ports implement this argument. - - As specified above, the Pin class allows to set an alternate function for a particular - pin, but it does not specify any further operations on such a pin. Pins configured in - alternate-function mode are usually not used as GPIO but are instead driven by other - hardware peripherals. The only operation supported on such a pin is re-initialising, - by calling the constructor or :meth:`Pin.init` method. If a pin that is configured in - alternate-function mode is re-initialised with ``Pin.IN``, ``Pin.OUT``, or - ``Pin.OPEN_DRAIN``, the alternate function will be removed from the pin. - -Methods -------- - -.. method:: Pin.init(mode=-1, pull=-1, \*, value, drive, alt) - - Re-initialise the pin using the given parameters. Only those arguments that - are specified will be set. The rest of the pin peripheral state will remain - unchanged. See the constructor documentation for details of the arguments. - - Returns ``None``. - -.. method:: Pin.value([x]) - - This method allows to set and get the value of the pin, depending on whether - the argument ``x`` is supplied or not. - - If the argument is omitted then this method gets the digital logic level of - the pin, returning 0 or 1 corresponding to low and high voltage signals - respectively. The behaviour of this method depends on the mode of the pin: - - - ``Pin.IN`` - The method returns the actual input value currently present - on the pin. - - ``Pin.OUT`` - The behaviour and return value of the method is undefined. - - ``Pin.OPEN_DRAIN`` - If the pin is in state '0' then the behaviour and - return value of the method is undefined. Otherwise, if the pin is in - state '1', the method returns the actual input value currently present - on the pin. - - If the argument is supplied then this method sets the digital logic level of - the pin. The argument ``x`` can be anything that converts to a boolean. - If it converts to ``True``, the pin is set to state '1', otherwise it is set - to state '0'. The behaviour of this method depends on the mode of the pin: - - - ``Pin.IN`` - The value is stored in the output buffer for the pin. The - pin state does not change, it remains in the high-impedance state. The - stored value will become active on the pin as soon as it is changed to - ``Pin.OUT`` or ``Pin.OPEN_DRAIN`` mode. - - ``Pin.OUT`` - The output buffer is set to the given value immediately. - - ``Pin.OPEN_DRAIN`` - If the value is '0' the pin is set to a low voltage - state. Otherwise the pin is set to high-impedance state. - - When setting the value this method returns ``None``. - -.. method:: Pin.__call__([x]) - - Pin objects are callable. The call method provides a (fast) shortcut to set - and get the value of the pin. It is equivalent to Pin.value([x]). - See :meth:`Pin.value` for more details. - -.. method:: Pin.on() - - Set pin to "1" output level. - -.. method:: Pin.off() - - Set pin to "0" output level. - -.. method:: Pin.mode([mode]) - - Get or set the pin mode. - See the constructor documentation for details of the ``mode`` argument. - -.. method:: Pin.pull([pull]) - - Get or set the pin pull state. - See the constructor documentation for details of the ``pull`` argument. - -.. method:: Pin.drive([drive]) - - Get or set the pin drive strength. - See the constructor documentation for details of the ``drive`` argument. - - Not all ports implement this method. - - Availability: WiPy. - -.. method:: Pin.irq(handler=None, trigger=(Pin.IRQ_FALLING | Pin.IRQ_RISING), \*, priority=1, wake=None) - - Configure an interrupt handler to be called when the trigger source of the - pin is active. If the pin mode is ``Pin.IN`` then the trigger source is - the external value on the pin. If the pin mode is ``Pin.OUT`` then the - trigger source is the output buffer of the pin. Otherwise, if the pin mode - is ``Pin.OPEN_DRAIN`` then the trigger source is the output buffer for - state '0' and the external pin value for state '1'. - - The arguments are: - - - ``handler`` is an optional function to be called when the interrupt - triggers. - - - ``trigger`` configures the event which can generate an interrupt. - Possible values are: - - - ``Pin.IRQ_FALLING`` interrupt on falling edge. - - ``Pin.IRQ_RISING`` interrupt on rising edge. - - ``Pin.IRQ_LOW_LEVEL`` interrupt on low level. - - ``Pin.IRQ_HIGH_LEVEL`` interrupt on high level. - - These values can be OR'ed together to trigger on multiple events. - - - ``priority`` sets the priority level of the interrupt. The values it - can take are port-specific, but higher values always represent higher - priorities. - - - ``wake`` selects the power mode in which this interrupt can wake up the - system. It can be ``machine.IDLE``, ``machine.SLEEP`` or ``machine.DEEPSLEEP``. - These values can also be OR'ed together to make a pin generate interrupts in - more than one power mode. - - This method returns a callback object. - -Constants ---------- - -The following constants are used to configure the pin objects. Note that -not all constants are available on all ports. - -.. data:: Pin.IN - Pin.OUT - Pin.OPEN_DRAIN - Pin.ALT - Pin.ALT_OPEN_DRAIN - - Selects the pin mode. - -.. data:: Pin.PULL_UP - Pin.PULL_DOWN - - Selects whether there is a pull up/down resistor. Use the value - ``None`` for no pull. - -.. data:: Pin.LOW_POWER - Pin.MED_POWER - Pin.HIGH_POWER - - Selects the pin drive strength. - -.. data:: Pin.IRQ_FALLING - Pin.IRQ_RISING - Pin.IRQ_LOW_LEVEL - Pin.IRQ_HIGH_LEVEL - - Selects the IRQ trigger type. diff --git a/docs/library/machine.RTC.rst b/docs/library/machine.RTC.rst deleted file mode 100644 index 95fa2b4ce60..00000000000 --- a/docs/library/machine.RTC.rst +++ /dev/null @@ -1,69 +0,0 @@ -.. currentmodule:: machine -.. _machine.RTC: - -class RTC -- real time clock -============================ - -The RTC is and independent clock that keeps track of the date -and time. - -Example usage:: - - rtc = machine.RTC() - rtc.init((2014, 5, 1, 4, 13, 0, 0, 0)) - print(rtc.now()) - - -Constructors ------------- - -.. class:: RTC(id=0, ...) - - Create an RTC object. See init for parameters of initialization. - -Methods -------- - -.. method:: RTC.init(datetime) - - Initialise the RTC. Datetime is a tuple of the form: - - ``(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])`` - -.. method:: RTC.now() - - Get get the current datetime tuple. - -.. method:: RTC.deinit() - - Resets the RTC to the time of January 1, 2015 and starts running it again. - -.. method:: RTC.alarm(id, time, \*, repeat=False) - - Set the RTC alarm. Time might be either a millisecond value to program the alarm to - current time + time_in_ms in the future, or a datetimetuple. If the time passed is in - milliseconds, repeat can be set to ``True`` to make the alarm periodic. - -.. method:: RTC.alarm_left(alarm_id=0) - - Get the number of milliseconds left before the alarm expires. - -.. method:: RTC.cancel(alarm_id=0) - - Cancel a running alarm. - -.. method:: RTC.irq(\*, trigger, handler=None, wake=machine.IDLE) - - Create an irq object triggered by a real time clock alarm. - - - ``trigger`` must be ``RTC.ALARM0`` - - ``handler`` is the function to be called when the callback is triggered. - - ``wake`` specifies the sleep mode from where this interrupt can wake - up the system. - -Constants ---------- - -.. data:: RTC.ALARM0 - - irq trigger source diff --git a/docs/library/machine.SD.rst b/docs/library/machine.SD.rst deleted file mode 100644 index 608e958317d..00000000000 --- a/docs/library/machine.SD.rst +++ /dev/null @@ -1,42 +0,0 @@ -.. currentmodule:: machine -.. _machine.SD: - -class SD -- secure digital memory card -====================================== - -The SD card class allows to configure and enable the memory card -module of the WiPy and automatically mount it as ``/sd`` as part -of the file system. There are several pin combinations that can be -used to wire the SD card socket to the WiPy and the pins used can -be specified in the constructor. Please check the `pinout and alternate functions -table. `_ for -more info regarding the pins which can be remapped to be used with a SD card. - -Example usage:: - - from machine import SD - import os - # clk cmd and dat0 pins must be passed along with - # their respective alternate functions - sd = machine.SD(pins=('GP10', 'GP11', 'GP15')) - os.mount(sd, '/sd') - # do normal file operations - -Constructors ------------- - -.. class:: SD(id,... ) - - Create a SD card object. See ``init()`` for parameters if initialization. - -Methods -------- - -.. method:: SD.init(id=0, pins=('GP10', 'GP11', 'GP15')) - - Enable the SD card. In order to initialize the card, give it a 3-tuple: - ``(clk_pin, cmd_pin, dat0_pin)``. - -.. method:: SD.deinit() - - Disable the SD card. diff --git a/docs/library/machine.SPI.rst b/docs/library/machine.SPI.rst deleted file mode 100644 index 080f6fdfb21..00000000000 --- a/docs/library/machine.SPI.rst +++ /dev/null @@ -1,97 +0,0 @@ -.. currentmodule:: machine -.. _machine.SPI: - -class SPI -- a Serial Peripheral Interface bus protocol (master side) -===================================================================== - -SPI is a synchronous serial protocol that is driven by a master. At the -physical level, a bus consists of 3 lines: SCK, MOSI, MISO. Multiple devices -can share the same bus. Each device should have a separate, 4th signal, -SS (Slave Select), to select a particular device on a bus with which -communication takes place. Management of an SS signal should happen in -user code (via machine.Pin class). - -Constructors ------------- - -.. class:: SPI(id, ...) - - Construct an SPI object on the given bus, ``id``. Values of ``id`` depend - on a particular port and its hardware. Values 0, 1, etc. are commonly used - to select hardware SPI block #0, #1, etc. Value -1 can be used for - bitbanging (software) implementation of SPI (if supported by a port). - - With no additional parameters, the SPI object is created but not - initialised (it has the settings from the last initialisation of - the bus, if any). If extra arguments are given, the bus is initialised. - See ``init`` for parameters of initialisation. - -Methods -------- - -.. method:: SPI.init(baudrate=1000000, \*, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=None, mosi=None, miso=None, pins=(SCK, MOSI, MISO)) - - Initialise the SPI bus with the given parameters: - - - ``baudrate`` is the SCK clock rate. - - ``polarity`` can be 0 or 1, and is the level the idle clock line sits at. - - ``phase`` can be 0 or 1 to sample data on the first or second clock edge - respectively. - - ``bits`` is the width in bits of each transfer. Only 8 is guaranteed to be supported by all hardware. - - ``firstbit`` can be ``SPI.MSB`` or ``SPI.LSB``. - - ``sck``, ``mosi``, ``miso`` are pins (machine.Pin) objects to use for bus signals. For most - hardware SPI blocks (as selected by ``id`` parameter to the constructor), pins are fixed - and cannot be changed. In some cases, hardware blocks allow 2-3 alternative pin sets for - a hardware SPI block. Arbitrary pin assignments are possible only for a bitbanging SPI driver - (``id`` = -1). - - ``pins`` - WiPy port doesn't ``sck``, ``mosi``, ``miso`` arguments, and instead allows to - specify them as a tuple of ``pins`` parameter. - -.. method:: SPI.deinit() - - Turn off the SPI bus. - -.. method:: SPI.read(nbytes, write=0x00) - - Read a number of bytes specified by ``nbytes`` while continuously writing - the single byte given by ``write``. - Returns a ``bytes`` object with the data that was read. - -.. method:: SPI.readinto(buf, write=0x00) - - Read into the buffer specified by ``buf`` while continuously writing the - single byte given by ``write``. - Returns ``None``. - - Note: on WiPy this function returns the number of bytes read. - -.. method:: SPI.write(buf) - - Write the bytes contained in ``buf``. - Returns ``None``. - - Note: on WiPy this function returns the number of bytes written. - -.. method:: SPI.write_readinto(write_buf, read_buf) - - Write the bytes from ``write_buf`` while reading into ``read_buf``. The - buffers can be the same or different, but both buffers must have the - same length. - Returns ``None``. - - Note: on WiPy this function returns the number of bytes written. - -Constants ---------- - -.. data:: SPI.MASTER - - for initialising the SPI bus to master; this is only used for the WiPy - -.. data:: SPI.MSB - - set the first bit to be the most significant bit - -.. data:: SPI.LSB - - set the first bit to be the least significant bit diff --git a/docs/library/machine.Signal.rst b/docs/library/machine.Signal.rst deleted file mode 100644 index a1a29164b2c..00000000000 --- a/docs/library/machine.Signal.rst +++ /dev/null @@ -1,123 +0,0 @@ -.. currentmodule:: machine -.. _machine.Signal: - -class Signal -- control and sense external I/O devices -====================================================== - -The Signal class is a simple extension of the `Pin` class. Unlike Pin, which -can be only in "absolute" 0 and 1 states, a Signal can be in "asserted" -(on) or "deasserted" (off) states, while being inverted (active-low) or -not. In other words, it adds logical inversion support to Pin functionality. -While this may seem a simple addition, it is exactly what is needed to -support wide array of simple digital devices in a way portable across -different boards, which is one of the major MicroPython goals. Regardless -of whether different users have an active-high or active-low LED, a normally -open or normally closed relay - you can develop a single, nicely looking -application which works with each of them, and capture hardware -configuration differences in few lines in the config file of your app. - -Example:: - - from machine import Pin, Signal - - # Suppose you have an active-high LED on pin 0 - led1_pin = Pin(0, Pin.OUT) - # ... and active-low LED on pin 1 - led2_pin = Pin(1, Pin.OUT) - - # Now to light up both of them using Pin class, you'll need to set - # them to different values - led1_pin.value(1) - led2_pin.value(0) - - # Signal class allows to abstract away active-high/active-low - # difference - led1 = Signal(led1_pin, invert=False) - led2 = Signal(led2_pin, invert=True) - - # Now lighting up them looks the same - led1.value(1) - led2.value(1) - - # Even better: - led1.on() - led2.on() - -Following is the guide when Signal vs Pin should be used: - -* Use Signal: If you want to control a simple on/off (including software - PWM!) devices like LEDs, multi-segment indicators, relays, buzzers, or - read simple binary sensors, like normally open or normally closed buttons, - pulled high or low, Reed switches, moisture/flame detectors, etc. etc. - Summing up, if you have a real physical device/sensor requiring GPIO - access, you likely should use a Signal. - -* Use Pin: If you implement a higher-level protocol or bus to communicate - with more complex devices. - -The split between Pin and Signal come from the usecases above and the -architecture of MicroPython: Pin offers the lowest overhead, which may -be important when bit-banging protocols. But Signal adds additional -flexibility on top of Pin, at the cost of minor overhead (much smaller -than if you implemented active-high vs active-low device differences in -Python manually!). Also, Pin is a low-level object which needs to be -implemented for each support board, while Signal is a high-level object -which comes for free once Pin is implemented. - -If in doubt, give the Signal a try! Once again, it is offered to save -developers from the need to handle unexciting differences like active-low -vs active-high signals, and allow other users to share and enjoy your -application, instead of being frustrated by the fact that it doesn't -work for them simply because their LEDs or relays are wired in a slightly -different way. - -Constructors ------------- - -.. class:: Signal(pin_obj, invert=False) - Signal(pin_arguments..., \*, invert=False) - - Create a Signal object. There're two ways to create it: - - * By wrapping existing Pin object - universal method which works for - any board. - * By passing required Pin parameters directly to Signal constructor, - skipping the need to create intermediate Pin object. Available on - many, but not all boards. - - The arguments are: - - - ``pin_obj`` is existing Pin object. - - - ``pin_arguments`` are the same arguments as can be passed to Pin constructor. - - - ``invert`` - if True, the signal will be inverted (active low). - -Methods -------- - -.. method:: Signal.value([x]) - - This method allows to set and get the value of the signal, depending on whether - the argument ``x`` is supplied or not. - - If the argument is omitted then this method gets the signal level, 1 meaning - signal is asserted (active) and 0 - signal inactive. - - If the argument is supplied then this method sets the signal level. The - argument ``x`` can be anything that converts to a boolean. If it converts - to ``True``, the signal is active, otherwise it is inactive. - - Correspondence between signal being active and actual logic level on the - underlying pin depends on whether signal is inverted (active-low) or not. - For non-inverted signal, active status corresponds to logical 1, inactive - - to logical 0. For inverted/active-low signal, active status corresponds - to logical 0, while inactive - to logical 1. - -.. method:: Signal.on() - - Activate signal. - -.. method:: Signal.off() - - Deactivate signal. diff --git a/docs/library/machine.Timer.rst b/docs/library/machine.Timer.rst deleted file mode 100644 index ef46f9dd7c6..00000000000 --- a/docs/library/machine.Timer.rst +++ /dev/null @@ -1,160 +0,0 @@ -.. currentmodule:: machine -.. _machine.Timer: - -class Timer -- control hardware timers -====================================== - -Hardware timers deal with timing of periods and events. Timers are perhaps -the most flexible and heterogeneous kind of hardware in MCUs and SoCs, -differently greatly from a model to a model. MicroPython's Timer class -defines a baseline operation of executing a callback with a given period -(or once after some delay), and allow specific boards to define more -non-standard behavior (which thus won't be portable to other boards). - -See discussion of :ref:`important constraints ` on -Timer callbacks. - -.. note:: - - Memory can't be allocated inside irq handlers (an interrupt) and so - exceptions raised within a handler don't give much information. See - :func:`micropython.alloc_emergency_exception_buf` for how to get around this - limitation. - -Constructors ------------- - -.. class:: Timer(id, ...) - - Construct a new timer object of the given id. Id of -1 constructs a - virtual timer (if supported by a board). - -Methods -------- - -.. only:: port_wipy - - .. method:: Timer.init(mode, \*, width=16) - - Initialise the timer. Example:: - - tim.init(Timer.PERIODIC) # periodic 16-bit timer - tim.init(Timer.ONE_SHOT, width=32) # one shot 32-bit timer - - Keyword arguments: - - - ``mode`` can be one of: - - - ``Timer.ONE_SHOT`` - The timer runs once until the configured - period of the channel expires. - - ``Timer.PERIODIC`` - The timer runs periodically at the configured - frequency of the channel. - - ``Timer.PWM`` - Output a PWM signal on a pin. - - - ``width`` must be either 16 or 32 (bits). For really low frequencies < 5Hz - (or large periods), 32-bit timers should be used. 32-bit mode is only available - for ``ONE_SHOT`` AND ``PERIODIC`` modes. - -.. method:: Timer.deinit() - - Deinitialises the timer. Stops the timer, and disables the timer peripheral. - -.. only:: port_wipy - - .. method:: Timer.channel(channel, \**, freq, period, polarity=Timer.POSITIVE, duty_cycle=0) - - If only a channel identifier passed, then a previously initialized channel - object is returned (or ``None`` if there is no previous channel). - - Otherwise, a TimerChannel object is initialized and returned. - - The operating mode is is the one configured to the Timer object that was used to - create the channel. - - - ``channel`` if the width of the timer is 16-bit, then must be either ``TIMER.A``, ``TIMER.B``. - If the width is 32-bit then it **must be** ``TIMER.A | TIMER.B``. - - Keyword only arguments: - - - ``freq`` sets the frequency in Hz. - - ``period`` sets the period in microseconds. - - .. note:: - - Either ``freq`` or ``period`` must be given, never both. - - - ``polarity`` this is applicable for ``PWM``, and defines the polarity of the duty cycle - - ``duty_cycle`` only applicable to ``PWM``. It's a percentage (0.00-100.00). Since the WiPy - doesn't support floating point numbers the duty cycle must be specified in the range 0-10000, - where 10000 would represent 100.00, 5050 represents 50.50, and so on. - - .. note:: - - When the channel is in PWM mode, the corresponding pin is assigned automatically, therefore - there's no need to assign the alternate function of the pin via the ``Pin`` class. The pins which - support PWM functionality are the following: - - - ``GP24`` on Timer 0 channel A. - - ``GP25`` on Timer 1 channel A. - - ``GP9`` on Timer 2 channel B. - - ``GP10`` on Timer 3 channel A. - - ``GP11`` on Timer 3 channel B. - -.. only:: port_wipy - - class TimerChannel --- setup a channel for a timer - ================================================== - - Timer channels are used to generate/capture a signal using a timer. - - TimerChannel objects are created using the Timer.channel() method. - - Methods - ------- - - .. method:: timerchannel.irq(\*, trigger, priority=1, handler=None) - - The behavior of this callback is heavily dependent on the operating - mode of the timer channel: - - - If mode is ``Timer.PERIODIC`` the callback is executed periodically - with the configured frequency or period. - - If mode is ``Timer.ONE_SHOT`` the callback is executed once when - the configured timer expires. - - If mode is ``Timer.PWM`` the callback is executed when reaching the duty - cycle value. - - The accepted params are: - - - ``priority`` level of the interrupt. Can take values in the range 1-7. - Higher values represent higher priorities. - - ``handler`` is an optional function to be called when the interrupt is triggered. - - ``trigger`` must be ``Timer.TIMEOUT`` when the operating mode is either ``Timer.PERIODIC`` or - ``Timer.ONE_SHOT``. In the case that mode is ``Timer.PWM`` then trigger must be equal to - ``Timer.MATCH``. - - Returns a callback object. - -.. only:: port_wipy - - .. method:: timerchannel.freq([value]) - - Get or set the timer channel frequency (in Hz). - - .. method:: timerchannel.period([value]) - - Get or set the timer channel period (in microseconds). - - .. method:: timerchannel.duty_cycle([value]) - - Get or set the duty cycle of the PWM signal. It's a percentage (0.00-100.00). Since the WiPy - doesn't support floating point numbers the duty cycle must be specified in the range 0-10000, - where 10000 would represent 100.00, 5050 represents 50.50, and so on. - -Constants ---------- - -.. data:: Timer.ONE_SHOT -.. data:: Timer.PERIODIC - - Timer operating mode. diff --git a/docs/library/machine.UART.rst b/docs/library/machine.UART.rst deleted file mode 100644 index 1574f17db9a..00000000000 --- a/docs/library/machine.UART.rst +++ /dev/null @@ -1,142 +0,0 @@ -.. currentmodule:: machine -.. _machine.UART: - -class UART -- duplex serial communication bus -============================================= - -UART implements the standard UART/USART duplex serial communications protocol. At -the physical level it consists of 2 lines: RX and TX. The unit of communication -is a character (not to be confused with a string character) which can be 8 or 9 -bits wide. - -UART objects can be created and initialised using:: - - from machine import UART - - uart = UART(1, 9600) # init with given baudrate - uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters - -Supported parameters differ on a board: - -Pyboard: Bits can be 7, 8 or 9. Stop can be 1 or 2. With *parity=None*, -only 8 and 9 bits are supported. With parity enabled, only 7 and 8 bits -are supported. - -WiPy/CC3200: Bits can be 5, 6, 7, 8. Stop can be 1 or 2. - -A UART object acts like a `stream` object and reading and writing is done -using the standard stream methods:: - - uart.read(10) # read 10 characters, returns a bytes object - uart.read() # read all available characters - uart.readline() # read a line - uart.readinto(buf) # read and store into the given buffer - uart.write('abc') # write the 3 characters - -Constructors ------------- - -.. class:: UART(id, ...) - - Construct a UART object of the given id. - -Methods -------- - -.. only:: port_wipy - - .. method:: UART.init(baudrate=9600, bits=8, parity=None, stop=1, \*, pins=(TX, RX, RTS, CTS)) - - Initialise the UART bus with the given parameters: - - - ``baudrate`` is the clock rate. - - ``bits`` is the number of bits per character, 7, 8 or 9. - - ``parity`` is the parity, ``None``, 0 (even) or 1 (odd). - - ``stop`` is the number of stop bits, 1 or 2. - - ``pins`` is a 4 or 2 item list indicating the TX, RX, RTS and CTS pins (in that order). - Any of the pins can be None if one wants the UART to operate with limited functionality. - If the RTS pin is given the the RX pin must be given as well. The same applies to CTS. - When no pins are given, then the default set of TX and RX pins is taken, and hardware - flow control will be disabled. If pins=None, no pin assignment will be made. - -.. method:: UART.deinit() - - Turn off the UART bus. - -.. method:: UART.any() - - Returns an integer counting the number of characters that can be read without - blocking. It will return 0 if there are no characters available and a positive - number if there are characters. The method may return 1 even if there is more - than one character available for reading. - - For more sophisticated querying of available characters use select.poll:: - - poll = select.poll() - poll.register(uart, select.POLLIN) - poll.poll(timeout) - -.. method:: UART.read([nbytes]) - - Read characters. If ``nbytes`` is specified then read at most that many bytes, - otherwise read as much data as possible. - - Return value: a bytes object containing the bytes read in. Returns ``None`` - on timeout. - -.. method:: UART.readinto(buf[, nbytes]) - - Read bytes into the ``buf``. If ``nbytes`` is specified then read at most - that many bytes. Otherwise, read at most ``len(buf)`` bytes. - - Return value: number of bytes read and stored into ``buf`` or ``None`` on - timeout. - -.. method:: UART.readline() - - Read a line, ending in a newline character. - - Return value: the line read or ``None`` on timeout. - -.. method:: UART.write(buf) - - Write the buffer of bytes to the bus. - - Return value: number of bytes written or ``None`` on timeout. - -.. method:: UART.sendbreak() - - Send a break condition on the bus. This drives the bus low for a duration - longer than required for a normal transmission of a character. - -.. only:: port_wipy - - .. method:: UART.irq(trigger, priority=1, handler=None, wake=machine.IDLE) - - Create a callback to be triggered when data is received on the UART. - - - ``trigger`` can only be ``UART.RX_ANY`` - - ``priority`` level of the interrupt. Can take values in the range 1-7. - Higher values represent higher priorities. - - ``handler`` an optional function to be called when new characters arrive. - - ``wake`` can only be ``machine.IDLE``. - - .. note:: - - The handler will be called whenever any of the following two conditions are met: - - - 8 new characters have been received. - - At least 1 new character is waiting in the Rx buffer and the Rx line has been - silent for the duration of 1 complete frame. - - This means that when the handler function is called there will be between 1 to 8 - characters waiting. - - Returns an irq object. - - Constants - --------- - - .. data:: UART.RX_ANY - - IRQ trigger sources diff --git a/docs/library/machine.WDT.rst b/docs/library/machine.WDT.rst deleted file mode 100644 index 5ca6dce45d5..00000000000 --- a/docs/library/machine.WDT.rst +++ /dev/null @@ -1,36 +0,0 @@ -.. currentmodule:: machine -.. _machine.WDT: - -class WDT -- watchdog timer -=========================== - -The WDT is used to restart the system when the application crashes and ends -up into a non recoverable state. Once started it cannot be stopped or -reconfigured in any way. After enabling, the application must "feed" the -watchdog periodically to prevent it from expiring and resetting the system. - -Example usage:: - - from machine import WDT - wdt = WDT(timeout=2000) # enable it with a timeout of 2s - wdt.feed() - -Availability of this class: pyboard, WiPy. - -Constructors ------------- - -.. class:: WDT(id=0, timeout=5000) - - Create a WDT object and start it. The timeout must be given in seconds and - the minimum value that is accepted is 1 second. Once it is running the timeout - cannot be changed and the WDT cannot be stopped either. - -Methods -------- - -.. method:: wdt.feed() - - Feed the WDT to prevent it from resetting the system. The application - should place this call in a sensible place ensuring that the WDT is - only fed after verifying that everything is functioning correctly. diff --git a/docs/library/machine.rst b/docs/library/machine.rst deleted file mode 100644 index 087f19cc6c2..00000000000 --- a/docs/library/machine.rst +++ /dev/null @@ -1,170 +0,0 @@ -:mod:`machine` --- functions related to the hardware -==================================================== - -.. module:: machine - :synopsis: functions related to the hardware - -The ``machine`` module contains specific functions related to the hardware -on a particular board. Most functions in this module allow to achieve direct -and unrestricted access to and control of hardware blocks on a system -(like CPU, timers, buses, etc.). Used incorrectly, this can lead to -malfunction, lockups, crashes of your board, and in extreme cases, hardware -damage. - -.. _machine_callbacks: - -A note of callbacks used by functions and class methods of :mod:`machine` module: -all these callbacks should be considered as executing in an interrupt context. -This is true for both physical devices with IDs >= 0 and "virtual" devices -with negative IDs like -1 (these "virtual" devices are still thin shims on -top of real hardware and real hardware interrupts). See :ref:`isr_rules`. - -Reset related functions ------------------------ - -.. function:: reset() - - Resets the device in a manner similar to pushing the external RESET - button. - -.. function:: reset_cause() - - Get the reset cause. See :ref:`constants ` for the possible return values. - -Interrupt related functions ---------------------------- - -.. function:: disable_irq() - - Disable interrupt requests. - Returns the previous IRQ state which should be considered an opaque value. - This return value should be passed to the `enable_irq()` function to restore - interrupts to their original state, before `disable_irq()` was called. - -.. function:: enable_irq(state) - - Re-enable interrupt requests. - The *state* parameter should be the value that was returned from the most - recent call to the `disable_irq()` function. - -Power related functions ------------------------ - -.. function:: freq() - - Returns CPU frequency in hertz. - -.. function:: idle() - - Gates the clock to the CPU, useful to reduce power consumption at any time during - short or long periods. Peripherals continue working and execution resumes as soon - as any interrupt is triggered (on many ports this includes system timer - interrupt occurring at regular intervals on the order of millisecond). - -.. function:: sleep() - - Stops the CPU and disables all peripherals except for WLAN. Execution is resumed from - the point where the sleep was requested. For wake up to actually happen, wake sources - should be configured first. - -.. function:: deepsleep() - - Stops the CPU and all peripherals (including networking interfaces, if any). Execution - is resumed from the main script, just as with a reset. The reset cause can be checked - to know that we are coming from `machine.DEEPSLEEP`. For wake up to actually happen, - wake sources should be configured first, like `Pin` change or `RTC` timeout. - -.. only:: port_wipy - - .. function:: wake_reason() - - Get the wake reason. See :ref:`constants ` for the possible return values. - -Miscellaneous functions ------------------------ - -.. only:: port_wipy - - .. function:: rng() - - Return a 24-bit software generated random number. - -.. function:: unique_id() - - Returns a byte string with a unique identifier of a board/SoC. It will vary - from a board/SoC instance to another, if underlying hardware allows. Length - varies by hardware (so use substring of a full value if you expect a short - ID). In some MicroPython ports, ID corresponds to the network MAC address. - -.. function:: time_pulse_us(pin, pulse_level, timeout_us=1000000) - - Time a pulse on the given *pin*, and return the duration of the pulse in - microseconds. The *pulse_level* argument should be 0 to time a low pulse - or 1 to time a high pulse. - - If the current input value of the pin is different to *pulse_level*, - the function first (*) waits until the pin input becomes equal to *pulse_level*, - then (**) times the duration that the pin is equal to *pulse_level*. - If the pin is already equal to *pulse_level* then timing starts straight away. - - The function will return -2 if there was timeout waiting for condition marked - (*) above, and -1 if there was timeout during the main measurement, marked (**) - above. The timeout is the same for both cases and given by *timeout_us* (which - is in microseconds). - -.. _machine_constants: - -Constants ---------- - -.. data:: machine.IDLE - machine.SLEEP - machine.DEEPSLEEP - - IRQ wake values. - -.. data:: machine.PWRON_RESET - machine.HARD_RESET - machine.WDT_RESET - machine.DEEPSLEEP_RESET - machine.SOFT_RESET - - Reset causes. - -.. data:: machine.WLAN_WAKE - machine.PIN_WAKE - machine.RTC_WAKE - - Wake-up reasons. - -Classes -------- - -.. only:: not port_wipy - - .. toctree:: - :maxdepth: 1 - - machine.Pin.rst - machine.Signal.rst - machine.UART.rst - machine.SPI.rst - machine.I2C.rst - machine.RTC.rst - machine.Timer.rst - machine.WDT.rst - -.. only:: port_wipy - - .. toctree:: - :maxdepth: 1 - - machine.Pin.rst - machine.UART.rst - machine.SPI.rst - machine.I2C.rst - machine.RTC.rst - machine.Timer.rst - machine.WDT.rst - machine.ADC.rst - machine.SD.rst diff --git a/docs/library/math.rst b/docs/library/math.rst deleted file mode 100644 index a6f13d48c18..00000000000 --- a/docs/library/math.rst +++ /dev/null @@ -1,185 +0,0 @@ -:mod:`math` -- mathematical functions -===================================== - -.. module:: math - :synopsis: mathematical functions - -|see_cpython_module| :mod:`python:math`. - -The ``math`` module provides some basic mathematical functions for -working with floating-point numbers. - -*Note:* On the pyboard, floating-point numbers have 32-bit precision. - -Availability: not available on WiPy. Floating point support required -for this module. - -Functions ---------- - -.. function:: acos(x) - - Return the inverse cosine of ``x``. - -.. function:: acosh(x) - - Return the inverse hyperbolic cosine of ``x``. - -.. function:: asin(x) - - Return the inverse sine of ``x``. - -.. function:: asinh(x) - - Return the inverse hyperbolic sine of ``x``. - -.. function:: atan(x) - - Return the inverse tangent of ``x``. - -.. function:: atan2(y, x) - - Return the principal value of the inverse tangent of ``y/x``. - -.. function:: atanh(x) - - Return the inverse hyperbolic tangent of ``x``. - -.. function:: ceil(x) - - Return an integer, being ``x`` rounded towards positive infinity. - -.. function:: copysign(x, y) - - Return ``x`` with the sign of ``y``. - -.. function:: cos(x) - - Return the cosine of ``x``. - -.. function:: cosh(x) - - Return the hyperbolic cosine of ``x``. - -.. function:: degrees(x) - - Return radians ``x`` converted to degrees. - -.. function:: erf(x) - - Return the error function of ``x``. - -.. function:: erfc(x) - - Return the complementary error function of ``x``. - -.. function:: exp(x) - - Return the exponential of ``x``. - -.. function:: expm1(x) - - Return ``exp(x) - 1``. - -.. function:: fabs(x) - - Return the absolute value of ``x``. - -.. function:: floor(x) - - Return an integer, being ``x`` rounded towards negative infinity. - -.. function:: fmod(x, y) - - Return the remainder of ``x/y``. - -.. function:: frexp(x) - - Decomposes a floating-point number into its mantissa and exponent. - The returned value is the tuple ``(m, e)`` such that ``x == m * 2**e`` - exactly. If ``x == 0`` then the function returns ``(0.0, 0)``, otherwise - the relation ``0.5 <= abs(m) < 1`` holds. - -.. function:: gamma(x) - - Return the gamma function of ``x``. - -.. function:: isfinite(x) - - Return ``True`` if ``x`` is finite. - -.. function:: isinf(x) - - Return ``True`` if ``x`` is infinite. - -.. function:: isnan(x) - - Return ``True`` if ``x`` is not-a-number - -.. function:: ldexp(x, exp) - - Return ``x * (2**exp)``. - -.. function:: lgamma(x) - - Return the natural logarithm of the gamma function of ``x``. - -.. function:: log(x) - - Return the natural logarithm of ``x``. - -.. function:: log10(x) - - Return the base-10 logarithm of ``x``. - -.. function:: log2(x) - - Return the base-2 logarithm of ``x``. - -.. function:: modf(x) - - Return a tuple of two floats, being the fractional and integral parts of - ``x``. Both return values have the same sign as ``x``. - -.. function:: pow(x, y) - - Returns ``x`` to the power of ``y``. - -.. function:: radians(x) - - Return degrees ``x`` converted to radians. - -.. function:: sin(x) - - Return the sine of ``x``. - -.. function:: sinh(x) - - Return the hyperbolic sine of ``x``. - -.. function:: sqrt(x) - - Return the square root of ``x``. - -.. function:: tan(x) - - Return the tangent of ``x``. - -.. function:: tanh(x) - - Return the hyperbolic tangent of ``x``. - -.. function:: trunc(x) - - Return an integer, being ``x`` rounded towards 0. - -Constants ---------- - -.. data:: e - - base of the natural logarithm - -.. data:: pi - - the ratio of a circle's circumference to its diameter diff --git a/docs/library/micropython.rst b/docs/library/micropython.rst index a6ea738ed5f..31065fbe55a 100644 --- a/docs/library/micropython.rst +++ b/docs/library/micropython.rst @@ -1,6 +1,8 @@ :mod:`micropython` -- access and control MicroPython internals ============================================================== +.. include:: ../templates/unsupported_in_circuitpython.inc + .. module:: micropython :synopsis: access and control MicroPython internals @@ -45,17 +47,6 @@ Functions The default optimisation level is usually level 0. -.. function:: alloc_emergency_exception_buf(size) - - Allocate *size* bytes of RAM for the emergency exception buffer (a good - size is around 100 bytes). The buffer is used to create exceptions in cases - when normal RAM allocation would fail (eg within an interrupt handler) and - therefore give useful traceback information in these situations. - - A good way to use this function is to put it at the start of your main script - (eg ``boot.py`` or ``main.py``) and then the emergency exception buffer will be active - for all the code following it. - .. function:: mem_info([verbose]) Print information about currently used memory. If the *verbose* argument @@ -100,38 +91,3 @@ Functions This function can be used to prevent the capturing of Ctrl-C on the incoming stream of characters that is usually used for the REPL, in case that stream is used for other purposes. - -.. function:: schedule(func, arg) - - Schedule the function *func* to be executed "very soon". The function - is passed the value *arg* as its single argument. "Very soon" means that - the MicroPython runtime will do its best to execute the function at the - earliest possible time, given that it is also trying to be efficient, and - that the following conditions hold: - - - A scheduled function will never preempt another scheduled function. - - Scheduled functions are always executed "between opcodes" which means - that all fundamental Python operations (such as appending to a list) - are guaranteed to be atomic. - - A given port may define "critical regions" within which scheduled - functions will never be executed. Functions may be scheduled within - a critical region but they will not be executed until that region - is exited. An example of a critical region is a preempting interrupt - handler (an IRQ). - - A use for this function is to schedule a callback from a preempting IRQ. - Such an IRQ puts restrictions on the code that runs in the IRQ (for example - the heap may be locked) and scheduling a function to call later will lift - those restrictions. - - Note: If `schedule()` is called from a preempting IRQ, when memory - allocation is not allowed and the callback to be passed to `schedule()` is - a bound method, passing this directly will fail. This is because creating a - reference to a bound method causes memory allocation. A solution is to - create a reference to the method in the class constructor and to pass that - reference to `schedule()`. This is discussed in detail here - :ref:`reference documentation ` under "Creation of Python - objects". - - There is a finite stack to hold the scheduled functions and `schedule()` - will raise a `RuntimeError` if the stack is full. diff --git a/docs/library/network.rst b/docs/library/network.rst index a113209e0ea..cdcc5f32328 100644 --- a/docs/library/network.rst +++ b/docs/library/network.rst @@ -2,7 +2,10 @@ :mod:`network` --- network configuration **************************************** +.. include:: ../templates/unsupported_in_circuitpython.inc + .. module:: network + :noindex: :synopsis: network configuration This module provides network drivers and routing configuration. To use this @@ -39,7 +42,7 @@ Common network adapter interface ================================ This section describes an (implied) abstract base class for all network -interface classes implemented by `MicroPython ports ` +interface classes implemented by ``MicroPython ports `` for different hardware. This means that MicroPython does not actually provide ``AbstractNIC`` class, but any actual NIC class, as described in the following sections, implements methods as described here. @@ -98,20 +101,10 @@ parameter should be `id`. duration and other parameters. Where possible, parameter names should match those in connect(). - .. method:: status([param]) - - Query dynamic status information of the interface. When called with no - argument the return value describes the network link status. Otherwise - *param* should be a string naming the particular status parameter to - retrieve. - - The return types and values are dependent on the network - medium/technology. Some of the parameters that may be supported are: + .. method:: status() - * WiFi STA: use ``'rssi'`` to retrieve the RSSI of the AP signal - * WiFi AP: use ``'stations'`` to retrieve a list of all the STAs - connected to the AP. The list contains tuples of the form - (MAC, RSSI). + Return detailed status of the interface, values are dependent + on the network medium/technology. .. method:: ifconfig([(ip, subnet, gateway, dns)]) @@ -128,7 +121,7 @@ parameter should be `id`. Get or set general network interface parameters. These methods allow to work with additional parameters beyond standard IP configuration (as dealt with by `ifconfig()`). These include network-specific and hardware-specific - parameters. For setting parameters, the keyword argument + parameters and status values. For setting parameters, the keyword argument syntax should be used, and multiple parameters can be set at once. For querying, a parameter name should be quoted as a string, and only one parameter can be queried at a time:: @@ -138,466 +131,148 @@ parameter should be `id`. # Query params one by one print(ap.config('essid')) print(ap.config('channel')) - -.. only:: port_pyboard - - class CC3K - ========== - - This class provides a driver for CC3000 WiFi modules. Example usage:: - - import network - nic = network.CC3K(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3) - nic.connect('your-ssid', 'your-password') - while not nic.isconnected(): - pyb.delay(50) - print(nic.ifconfig()) - - # now use socket as usual - ... - - For this example to work the CC3000 module must have the following connections: - - - MOSI connected to Y8 - - MISO connected to Y7 - - CLK connected to Y6 - - CS connected to Y5 - - VBEN connected to Y4 - - IRQ connected to Y3 - - It is possible to use other SPI busses and other pins for CS, VBEN and IRQ. - - Constructors - ------------ - - .. class:: CC3K(spi, pin_cs, pin_en, pin_irq) - - Create a CC3K driver object, initialise the CC3000 module using the given SPI bus - and pins, and return the CC3K object. - - Arguments are: - - - *spi* is an :ref:`SPI object ` which is the SPI bus that the CC3000 is - connected to (the MOSI, MISO and CLK pins). - - *pin_cs* is a :ref:`Pin object ` which is connected to the CC3000 CS pin. - - *pin_en* is a :ref:`Pin object ` which is connected to the CC3000 VBEN pin. - - *pin_irq* is a :ref:`Pin object ` which is connected to the CC3000 IRQ pin. - - All of these objects will be initialised by the driver, so there is no need to - initialise them yourself. For example, you can use:: - - nic = network.CC3K(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3) - - Methods - ------- - - .. method:: cc3k.connect(ssid, key=None, \*, security=WPA2, bssid=None) - - Connect to a WiFi access point using the given SSID, and other security - parameters. - - .. method:: cc3k.disconnect() - - Disconnect from the WiFi access point. - - .. method:: cc3k.isconnected() - - Returns True if connected to a WiFi access point and has a valid IP address, - False otherwise. - - .. method:: cc3k.ifconfig() - - Returns a 7-tuple with (ip, subnet mask, gateway, DNS server, DHCP server, - MAC address, SSID). - - .. method:: cc3k.patch_version() - - Return the version of the patch program (firmware) on the CC3000. - - .. method:: cc3k.patch_program('pgm') - - Upload the current firmware to the CC3000. You must pass 'pgm' as the first - argument in order for the upload to proceed. - - Constants - --------- - - .. data:: CC3K.WEP - .. data:: CC3K.WPA - .. data:: CC3K.WPA2 - - security type to use - - class WIZNET5K - ============== - - This class allows you to control WIZnet5x00 Ethernet adaptors based on - the W5200 and W5500 chipsets. The particular chipset that is supported - by the firmware is selected at compile-time via the MICROPY_PY_WIZNET5K - option. - - Example usage:: - - import network - nic = network.WIZNET5K(pyb.SPI(1), pyb.Pin.board.X5, pyb.Pin.board.X4) - print(nic.ifconfig()) - - # now use socket as usual - ... - - For this example to work the WIZnet5x00 module must have the following connections: - - - MOSI connected to X8 - - MISO connected to X7 - - SCLK connected to X6 - - nSS connected to X5 - - nRESET connected to X4 - - It is possible to use other SPI busses and other pins for nSS and nRESET. - - Constructors - ------------ - - .. class:: WIZNET5K(spi, pin_cs, pin_rst) - - Create a WIZNET5K driver object, initialise the WIZnet5x00 module using the given - SPI bus and pins, and return the WIZNET5K object. - - Arguments are: - - - *spi* is an :ref:`SPI object ` which is the SPI bus that the WIZnet5x00 is - connected to (the MOSI, MISO and SCLK pins). - - *pin_cs* is a :ref:`Pin object ` which is connected to the WIZnet5x00 nSS pin. - - *pin_rst* is a :ref:`Pin object ` which is connected to the WIZnet5x00 nRESET pin. - - All of these objects will be initialised by the driver, so there is no need to - initialise them yourself. For example, you can use:: - - nic = network.WIZNET5K(pyb.SPI(1), pyb.Pin.board.X5, pyb.Pin.board.X4) - - Methods - ------- - - .. method:: wiznet5k.isconnected() - - Returns ``True`` if the physical Ethernet link is connected and up. - Returns ``False`` otherwise. - - .. method:: wiznet5k.ifconfig([(ip, subnet, gateway, dns)]) - - Get/set IP address, subnet mask, gateway and DNS. - - When called with no arguments, this method returns a 4-tuple with the above information. - - To set the above values, pass a 4-tuple with the required information. For example:: - - nic.ifconfig(('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8')) - - .. method:: wiznet5k.regs() - - Dump the WIZnet5x00 registers. Useful for debugging. + # Extended status information also available this way + print(sta.config('rssi')) .. _network.WLAN: -.. only:: port_esp8266 - - Functions - ========= - - .. function:: phy_mode([mode]) - - Get or set the PHY mode. - - If the *mode* parameter is provided, sets the mode to its value. If - the function is called without parameters, returns the current mode. - - The possible modes are defined as constants: - * ``MODE_11B`` -- IEEE 802.11b, - * ``MODE_11G`` -- IEEE 802.11g, - * ``MODE_11N`` -- IEEE 802.11n. - - class WLAN - ========== - - This class provides a driver for WiFi network processor in the ESP8266. Example usage:: - - import network - # enable station interface and connect to WiFi access point - nic = network.WLAN(network.STA_IF) - nic.active(True) - nic.connect('your-ssid', 'your-password') - # now use sockets as usual - - Constructors - ------------ - .. class:: WLAN(interface_id) - - Create a WLAN network interface object. Supported interfaces are - ``network.STA_IF`` (station aka client, connects to upstream WiFi access - points) and ``network.AP_IF`` (access point, allows other WiFi clients to - connect). Availability of the methods below depends on interface type. - For example, only STA interface may `connect()` to an access point. - - Methods - ------- - - .. method:: wlan.active([is_active]) +Functions +========= - Activate ("up") or deactivate ("down") network interface, if boolean - argument is passed. Otherwise, query current state if no argument is - provided. Most other methods require active interface. +.. function:: phy_mode([mode]) - .. method:: wlan.connect(ssid=None, password=None, \*, bssid=None) + Get or set the PHY mode. - Connect to the specified wireless network, using the specified password. - If *bssid* is given then the connection will be restricted to the - access-point with that MAC address (the *ssid* must also be specified - in this case). + If the *mode* parameter is provided, sets the mode to its value. If + the function is called without parameters, returns the current mode. - .. method:: wlan.disconnect() + The possible modes are defined as constants: + * ``MODE_11B`` -- IEEE 802.11b, + * ``MODE_11G`` -- IEEE 802.11g, + * ``MODE_11N`` -- IEEE 802.11n. - Disconnect from the currently connected wireless network. +class WLAN +========== - .. method:: wlan.scan() +This class provides a driver for WiFi network processor in the ESP8266. Example usage:: - Scan for the available wireless networks. - - Scanning is only possible on STA interface. Returns list of tuples with - the information about WiFi access points: - - (ssid, bssid, channel, RSSI, authmode, hidden) - - *bssid* is hardware address of an access point, in binary form, returned as - bytes object. You can use `ubinascii.hexlify()` to convert it to ASCII form. - - There are five values for authmode: - - * 0 -- open - * 1 -- WEP - * 2 -- WPA-PSK - * 3 -- WPA2-PSK - * 4 -- WPA/WPA2-PSK - - and two for hidden: - - * 0 -- visible - * 1 -- hidden - - .. method:: wlan.status([param]) - - Return the current status of the wireless connection. - - When called with no argument the return value describes the network link status. - The possible statuses are defined as constants: - - * ``STAT_IDLE`` -- no connection and no activity, - * ``STAT_CONNECTING`` -- connecting in progress, - * ``STAT_WRONG_PASSWORD`` -- failed due to incorrect password, - * ``STAT_NO_AP_FOUND`` -- failed because no access point replied, - * ``STAT_CONNECT_FAIL`` -- failed due to other problems, - * ``STAT_GOT_IP`` -- connection successful. - - When called with one argument *param* should be a string naming the status - parameter to retrieve. Supported parameters in WiFI STA mode are: ``'rssi'``. - - .. method:: wlan.isconnected() - - In case of STA mode, returns ``True`` if connected to a WiFi access - point and has a valid IP address. In AP mode returns ``True`` when a - station is connected. Returns ``False`` otherwise. - - .. method:: wlan.ifconfig([(ip, subnet, gateway, dns)]) - - Get/set IP-level network interface parameters: IP address, subnet mask, - gateway and DNS server. When called with no arguments, this method returns - a 4-tuple with the above information. To set the above values, pass a - 4-tuple with the required information. For example:: - - nic.ifconfig(('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8')) - - .. method:: wlan.config('param') - .. method:: wlan.config(param=value, ...) - - Get or set general network interface parameters. These methods allow to work - with additional parameters beyond standard IP configuration (as dealt with by - `wlan.ifconfig()`). These include network-specific and hardware-specific - parameters. For setting parameters, keyword argument syntax should be used, - multiple parameters can be set at once. For querying, parameters name should - be quoted as a string, and only one parameter can be queries at time:: - - # Set WiFi access point name (formally known as ESSID) and WiFi channel - ap.config(essid='My AP', channel=11) - # Query params one by one - print(ap.config('essid')) - print(ap.config('channel')) - - Following are commonly supported parameters (availability of a specific parameter - depends on network technology type, driver, and `MicroPython port`). - - ============= =========== - Parameter Description - ============= =========== - mac MAC address (bytes) - essid WiFi access point name (string) - channel WiFi channel (integer) - hidden Whether ESSID is hidden (boolean) - authmode Authentication mode supported (enumeration, see module constants) - password Access password (string) - dhcp_hostname The DHCP hostname to use - ============= =========== - - - -.. only:: port_wipy - - class WLAN - ========== - - This class provides a driver for the WiFi network processor in the WiPy. Example usage:: - - import network - import time - # setup as a station - wlan = network.WLAN(mode=WLAN.STA) - wlan.connect('your-ssid', auth=(WLAN.WPA2, 'your-key')) - while not wlan.isconnected(): - time.sleep_ms(50) - print(wlan.ifconfig()) - - # now use socket as usual - ... - - Constructors - ------------ - - .. class:: WLAN(id=0, ...) - - Create a WLAN object, and optionally configure it. See `init()` for params of configuration. - - .. note:: - - The ``WLAN`` constructor is special in the sense that if no arguments besides the id are given, - it will return the already existing ``WLAN`` instance without re-configuring it. This is - because ``WLAN`` is a system feature of the WiPy. If the already existing instance is not - initialized it will do the same as the other constructors an will initialize it with default - values. - - Methods - ------- - - .. method:: wlan.init(mode, \*, ssid, auth, channel, antenna) - - Set or get the WiFi network processor configuration. - - Arguments are: - - - *mode* can be either ``WLAN.STA`` or ``WLAN.AP``. - - *ssid* is a string with the ssid name. Only needed when mode is ``WLAN.AP``. - - *auth* is a tuple with (sec, key). Security can be ``None``, ``WLAN.WEP``, - ``WLAN.WPA`` or ``WLAN.WPA2``. The key is a string with the network password. - If ``sec`` is ``WLAN.WEP`` the key must be a string representing hexadecimal - values (e.g. 'ABC1DE45BF'). Only needed when mode is ``WLAN.AP``. - - *channel* a number in the range 1-11. Only needed when mode is ``WLAN.AP``. - - *antenna* selects between the internal and the external antenna. Can be either - ``WLAN.INT_ANT`` or ``WLAN.EXT_ANT``. - - For example, you can do:: - - # create and configure as an access point - wlan.init(mode=WLAN.AP, ssid='wipy-wlan', auth=(WLAN.WPA2,'www.wipy.io'), channel=7, antenna=WLAN.INT_ANT) - - or:: - - # configure as an station - wlan.init(mode=WLAN.STA) - - .. method:: wlan.connect(ssid, \*, auth=None, bssid=None, timeout=None) - - Connect to a WiFi access point using the given SSID, and other security - parameters. - - - *auth* is a tuple with (sec, key). Security can be ``None``, ``WLAN.WEP``, - ``WLAN.WPA`` or ``WLAN.WPA2``. The key is a string with the network password. - If ``sec`` is ``WLAN.WEP`` the key must be a string representing hexadecimal - values (e.g. 'ABC1DE45BF'). - - *bssid* is the MAC address of the AP to connect to. Useful when there are several - APs with the same ssid. - - *timeout* is the maximum time in milliseconds to wait for the connection to succeed. - - .. method:: wlan.scan() - - Performs a network scan and returns a list of named tuples with (ssid, bssid, sec, channel, rssi). - Note that channel is always ``None`` since this info is not provided by the WiPy. + import network + # enable station interface and connect to WiFi access point + nic = network.WLAN(network.STA_IF) + nic.active(True) + nic.connect('your-ssid', 'your-password') + # now use sockets as usual - .. method:: wlan.disconnect() +Constructors +------------ +.. class:: WLAN(interface_id) - Disconnect from the WiFi access point. +Create a WLAN network interface object. Supported interfaces are +``network.STA_IF`` (station aka client, connects to upstream WiFi access +points) and ``network.AP_IF`` (access point, allows other WiFi clients to +connect). Availability of the methods below depends on interface type. +For example, only STA interface may `connect()` to an access point. - .. method:: wlan.isconnected() +Methods +------- - In case of STA mode, returns ``True`` if connected to a WiFi access point and has a valid IP address. - In AP mode returns ``True`` when a station is connected, ``False`` otherwise. +.. method:: wlan.active([is_active]) - .. method:: wlan.ifconfig(if_id=0, config=['dhcp' or configtuple]) + Activate ("up") or deactivate ("down") network interface, if boolean + argument is passed. Otherwise, query current state if no argument is + provided. Most other methods require active interface. - With no parameters given returns a 4-tuple of *(ip, subnet_mask, gateway, DNS_server)*. +.. method:: wlan.connect(ssid=None, password=None, \*, bssid=None) - if ``'dhcp'`` is passed as a parameter then the DHCP client is enabled and the IP params - are negotiated with the AP. + Connect to the specified wireless network, using the specified password. + If *bssid* is given then the connection will be restricted to the + access-point with that MAC address (the *ssid* must also be specified + in this case). - If the 4-tuple config is given then a static IP is configured. For instance:: +.. method:: wlan.disconnect() - wlan.ifconfig(config=('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8')) + Disconnect from the currently connected wireless network. - .. method:: wlan.mode([mode]) +.. method:: wlan.scan() - Get or set the WLAN mode. + Scan for the available wireless networks. - .. method:: wlan.ssid([ssid]) + Scanning is only possible on STA interface. Returns list of tuples with + the information about WiFi access points: - Get or set the SSID when in AP mode. + (ssid, bssid, channel, RSSI, authmode, hidden) - .. method:: wlan.auth([auth]) + *bssid* is hardware address of an access point, in binary form, returned as + bytes object. You can use `binascii.hexlify()` to convert it to ASCII form. - Get or set the authentication type when in AP mode. + There are five values for authmode: - .. method:: wlan.channel([channel]) + * 0 -- open + * 1 -- WEP + * 2 -- WPA-PSK + * 3 -- WPA2-PSK + * 4 -- WPA/WPA2-PSK - Get or set the channel (only applicable in AP mode). + and two for hidden: - .. method:: wlan.antenna([antenna]) + * 0 -- visible + * 1 -- hidden - Get or set the antenna type (external or internal). +.. method:: wlan.status() - .. method:: wlan.mac([mac_addr]) + Return the current status of the wireless connection. - Get or set a 6-byte long bytes object with the MAC address. + The possible statuses are defined as constants: - .. method:: wlan.irq(\*, handler, wake) + * ``STAT_IDLE`` -- no connection and no activity, + * ``STAT_CONNECTING`` -- connecting in progress, + * ``STAT_WRONG_PASSWORD`` -- failed due to incorrect password, + * ``STAT_NO_AP_FOUND`` -- failed because no access point replied, + * ``STAT_CONNECT_FAIL`` -- failed due to other problems, + * ``STAT_GOT_IP`` -- connection successful. - Create a callback to be triggered when a WLAN event occurs during ``machine.SLEEP`` - mode. Events are triggered by socket activity or by WLAN connection/disconnection. +.. method:: wlan.isconnected() - - *handler* is the function that gets called when the IRQ is triggered. - - *wake* must be ``machine.SLEEP``. + In case of STA mode, returns ``True`` if connected to a WiFi access + point and has a valid IP address. In AP mode returns ``True`` when a + station is connected. Returns ``False`` otherwise. - Returns an IRQ object. +.. method:: wlan.ifconfig([(ip, subnet, gateway, dns)]) - Constants - --------- + Get/set IP-level network interface parameters: IP address, subnet mask, + gateway and DNS server. When called with no arguments, this method returns + a 4-tuple with the above information. To set the above values, pass a + 4-tuple with the required information. For example:: - .. data:: WLAN.STA - .. data:: WLAN.AP + nic.ifconfig(('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8')) - selects the WLAN mode +.. method:: wlan.config('param') +.. method:: wlan.config(param=value, ...) - .. data:: WLAN.WEP - .. data:: WLAN.WPA - .. data:: WLAN.WPA2 + Get or set general network interface parameters. These methods allow to work + with additional parameters beyond standard IP configuration (as dealt with by + `wlan.ifconfig()`). These include network-specific and hardware-specific + parameters. For setting parameters, keyword argument syntax should be used, + multiple parameters can be set at once. For querying, parameters name should + be quoted as a string, and only one parameter can be queries at time:: - selects the network security + # Set WiFi access point name (formally known as ESSID) and WiFi channel + ap.config(essid='My AP', channel=11) + # Query params one by one + print(ap.config('essid')) + print(ap.config('channel')) - .. data:: WLAN.INT_ANT - .. data:: WLAN.EXT_ANT + Following are commonly supported parameters (availability of a specific parameter + depends on network technology type, driver, and ``MicroPython port``). - selects the antenna type + ============= =========== + Parameter Description + ============= =========== + mac MAC address (bytes) + essid WiFi access point name (string) + channel WiFi channel (integer) + hidden Whether ESSID is hidden (boolean) + authmode Authentication mode supported (enumeration, see module constants) + password Access password (string) + dhcp_hostname The DHCP hostname to use + ============= =========== diff --git a/docs/library/pyb.ADC.rst b/docs/library/pyb.ADC.rst deleted file mode 100644 index 05aaa501509..00000000000 --- a/docs/library/pyb.ADC.rst +++ /dev/null @@ -1,176 +0,0 @@ -.. currentmodule:: pyb -.. _pyb.ADC: - -class ADC -- analog to digital conversion -========================================= - -.. only:: port_pyboard - - Usage:: - - import pyb - - adc = pyb.ADC(pin) # create an analog object from a pin - val = adc.read() # read an analog value - - adc = pyb.ADCAll(resolution) # create an ADCAll object - adc = pyb.ADCAll(resolution, mask) # create an ADCAll object for selected analog channels - val = adc.read_channel(channel) # read the given channel - val = adc.read_core_temp() # read MCU temperature - val = adc.read_core_vbat() # read MCU VBAT - val = adc.read_core_vref() # read MCU VREF - val = adc.read_vref() # read MCU supply voltage - - -Constructors ------------- - - -.. only:: port_pyboard - - .. class:: pyb.ADC(pin) - - Create an ADC object associated with the given pin. - This allows you to then read analog values on that pin. - -Methods -------- - -.. only:: port_pyboard - - .. method:: ADC.read() - - Read the value on the analog pin and return it. The returned value - will be between 0 and 4095. - - .. method:: ADC.read_timed(buf, timer) - - Read analog values into ``buf`` at a rate set by the ``timer`` object. - - ``buf`` can be bytearray or array.array for example. The ADC values have - 12-bit resolution and are stored directly into ``buf`` if its element size is - 16 bits or greater. If ``buf`` has only 8-bit elements (eg a bytearray) then - the sample resolution will be reduced to 8 bits. - - ``timer`` should be a Timer object, and a sample is read each time the timer - triggers. The timer must already be initialised and running at the desired - sampling frequency. - - To support previous behaviour of this function, ``timer`` can also be an - integer which specifies the frequency (in Hz) to sample at. In this case - Timer(6) will be automatically configured to run at the given frequency. - - Example using a Timer object (preferred way):: - - adc = pyb.ADC(pyb.Pin.board.X19) # create an ADC on pin X19 - tim = pyb.Timer(6, freq=10) # create a timer running at 10Hz - buf = bytearray(100) # creat a buffer to store the samples - adc.read_timed(buf, tim) # sample 100 values, taking 10s - - Example using an integer for the frequency:: - - adc = pyb.ADC(pyb.Pin.board.X19) # create an ADC on pin X19 - buf = bytearray(100) # create a buffer of 100 bytes - adc.read_timed(buf, 10) # read analog values into buf at 10Hz - # this will take 10 seconds to finish - for val in buf: # loop over all values - print(val) # print the value out - - This function does not allocate any heap memory. It has blocking behaviour: - it does not return to the calling program until the buffer is full. - - .. method:: ADC.read_timed_multi((adcx, adcy, ...), (bufx, bufy, ...), timer) - - This is a static method. It can be used to extract relative timing or - phase data from multiple ADC's. - - It reads analog values from multiple ADC's into buffers at a rate set by - the *timer* object. Each time the timer triggers a sample is rapidly - read from each ADC in turn. - - ADC and buffer instances are passed in tuples with each ADC having an - associated buffer. All buffers must be of the same type and length and - the number of buffers must equal the number of ADC's. - - Buffers can be ``bytearray`` or ``array.array`` for example. The ADC values - have 12-bit resolution and are stored directly into the buffer if its element - size is 16 bits or greater. If buffers have only 8-bit elements (eg a - ``bytearray``) then the sample resolution will be reduced to 8 bits. - - *timer* must be a Timer object. The timer must already be initialised - and running at the desired sampling frequency. - - Example reading 3 ADC's:: - - adc0 = pyb.ADC(pyb.Pin.board.X1) # Create ADC's - adc1 = pyb.ADC(pyb.Pin.board.X2) - adc2 = pyb.ADC(pyb.Pin.board.X3) - tim = pyb.Timer(8, freq=100) # Create timer - rx0 = array.array('H', (0 for i in range(100))) # ADC buffers of - rx1 = array.array('H', (0 for i in range(100))) # 100 16-bit words - rx2 = array.array('H', (0 for i in range(100))) - # read analog values into buffers at 100Hz (takes one second) - pyb.ADC.read_timed_multi((adc0, adc1, adc2), (rx0, rx1, rx2), tim) - for n in range(len(rx0)): - print(rx0[n], rx1[n], rx2[n]) - - This function does not allocate any heap memory. It has blocking behaviour: - it does not return to the calling program until the buffers are full. - - The function returns ``True`` if all samples were acquired with correct - timing. At high sample rates the time taken to acquire a set of samples - can exceed the timer period. In this case the function returns ``False``, - indicating a loss of precision in the sample interval. In extreme cases - samples may be missed. - - The maximum rate depends on factors including the data width and the - number of ADC's being read. In testing two ADC's were sampled at a timer - rate of 210kHz without overrun. Samples were missed at 215kHz. For three - ADC's the limit is around 140kHz, and for four it is around 110kHz. - At high sample rates disabling interrupts for the duration can reduce the - risk of sporadic data loss. - -The ADCAll Object ------------------ - -.. only:: port_pyboard - - Instantiating this changes all masked ADC pins to analog inputs. The preprocessed MCU temperature, - VREF and VBAT data can be accessed on ADC channels 16, 17 and 18 respectively. - Appropriate scaling is handled according to reference voltage used (usually 3.3V). - The temperature sensor on the chip is factory calibrated and allows to read the die temperature - to +/- 1 degree centigrade. Although this sounds pretty accurate, don't forget that the MCU's internal - temperature is measured. Depending on processing loads and I/O subsystems active the die temperature - may easily be tens of degrees above ambient temperature. On the other hand a pyboard woken up after a - long standby period will show correct ambient temperature within limits mentioned above. - - The ``ADCAll`` ``read_core_vbat()``, ``read_vref()`` and ``read_core_vref()`` methods read - the backup battery voltage, reference voltage and the (1.21V nominal) reference voltage using the - actual supply as a reference. All results are floating point numbers giving direct voltage values. - - ``read_core_vbat()`` returns the voltage of the backup battery. This voltage is also adjusted according - to the actual supply voltage. To avoid analog input overload the battery voltage is measured - via a voltage divider and scaled according to the divider value. To prevent excessive loads - to the backup battery, the voltage divider is only active during ADC conversion. - - ``read_vref()`` is evaluated by measuring the internal voltage reference and backscale it using - factory calibration value of the internal voltage reference. In most cases the reading would be close - to 3.3V. If the pyboard is operated from a battery, the supply voltage may drop to values below 3.3V. - The pyboard will still operate fine as long as the operating conditions are met. With proper settings - of MCU clock, flash access speed and programming mode it is possible to run the pyboard down to - 2 V and still get useful ADC conversion. - - It is very important to make sure analog input voltages never exceed actual supply voltage. - - Other analog input channels (0..15) will return unscaled integer values according to the selected - precision. - - To avoid unwanted activation of analog inputs (channel 0..15) a second parameter can be specified. - This parameter is a binary pattern where each requested analog input has the corresponding bit set. - The default value is 0xffffffff which means all analog inputs are active. If just the internal - channels (16..18) are required, the mask value should be 0x70000. - - Example:: - - adcall = pyb.ADCAll(12, 0x70000) # 12 bit resolution, internal channels - temp = adcall.read_core_temp() diff --git a/docs/library/pyb.Accel.rst b/docs/library/pyb.Accel.rst deleted file mode 100644 index 9ade5c5c815..00000000000 --- a/docs/library/pyb.Accel.rst +++ /dev/null @@ -1,57 +0,0 @@ -.. currentmodule:: pyb -.. _pyb.Accel: - -class Accel -- accelerometer control -==================================== - -Accel is an object that controls the accelerometer. Example usage:: - - accel = pyb.Accel() - for i in range(10): - print(accel.x(), accel.y(), accel.z()) - -Raw values are between -32 and 31. - - -Constructors ------------- - -.. class:: pyb.Accel() - - Create and return an accelerometer object. - -Methods -------- - -.. method:: Accel.filtered_xyz() - - Get a 3-tuple of filtered x, y and z values. - - Implementation note: this method is currently implemented as taking the - sum of 4 samples, sampled from the 3 previous calls to this function along - with the sample from the current call. Returned values are therefore 4 - times the size of what they would be from the raw x(), y() and z() calls. - -.. method:: Accel.tilt() - - Get the tilt register. - -.. method:: Accel.x() - - Get the x-axis value. - -.. method:: Accel.y() - - Get the y-axis value. - -.. method:: Accel.z() - - Get the z-axis value. - -Hardware Note -------------- - -The accelerometer uses I2C bus 1 to communicate with the processor. Consequently -when readings are being taken pins X9 and X10 should be unused (other than for -I2C). Other devices using those pins, and which therefore cannot be used -concurrently, are UART 1 and Timer 4 channels 1 and 2. diff --git a/docs/library/pyb.CAN.rst b/docs/library/pyb.CAN.rst deleted file mode 100644 index 09b97a187c6..00000000000 --- a/docs/library/pyb.CAN.rst +++ /dev/null @@ -1,300 +0,0 @@ -.. currentmodule:: pyb -.. _pyb.CAN: - -class CAN -- controller area network communication bus -====================================================== - -CAN implements the standard CAN communications protocol. At -the physical level it consists of 2 lines: RX and TX. Note that -to connect the pyboard to a CAN bus you must use a CAN transceiver -to convert the CAN logic signals from the pyboard to the correct -voltage levels on the bus. - -Example usage (works without anything connected):: - - from pyb import CAN - can = CAN(1, CAN.LOOPBACK) - can.setfilter(0, CAN.LIST16, 0, (123, 124, 125, 126)) # set a filter to receive messages with id=123, 124, 125 and 126 - can.send('message!', 123) # send a message with id 123 - can.recv(0) # receive message on FIFO 0 - - -Constructors ------------- - -.. class:: pyb.CAN(bus, ...) - - Construct a CAN object on the given bus. *bus* can be 1-2, or ``'YA'`` or ``'YB'``. - With no additional parameters, the CAN object is created but not - initialised (it has the settings from the last initialisation of - the bus, if any). If extra arguments are given, the bus is initialised. - See :meth:`CAN.init` for parameters of initialisation. - - The physical pins of the CAN busses are: - - - ``CAN(1)`` is on ``YA``: ``(RX, TX) = (Y3, Y4) = (PB8, PB9)`` - - ``CAN(2)`` is on ``YB``: ``(RX, TX) = (Y5, Y6) = (PB12, PB13)`` - -Class Methods -------------- -.. classmethod:: CAN.initfilterbanks(nr) - - Reset and disable all filter banks and assign how many banks should be available for CAN(1). - - STM32F405 has 28 filter banks that are shared between the two available CAN bus controllers. - This function configures how many filter banks should be assigned to each. *nr* is the number of banks - that will be assigned to CAN(1), the rest of the 28 are assigned to CAN(2). - At boot, 14 banks are assigned to each controller. - -Methods -------- - -.. method:: CAN.init(mode, extframe=False, prescaler=100, \*, sjw=1, bs1=6, bs2=8, auto_restart=False) - - Initialise the CAN bus with the given parameters: - - - *mode* is one of: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK - - if *extframe* is True then the bus uses extended identifiers in the frames - (29 bits); otherwise it uses standard 11 bit identifiers - - *prescaler* is used to set the duration of 1 time quanta; the time quanta - will be the input clock (PCLK1, see :meth:`pyb.freq()`) divided by the prescaler - - *sjw* is the resynchronisation jump width in units of the time quanta; - it can be 1, 2, 3, 4 - - *bs1* defines the location of the sample point in units of the time quanta; - it can be between 1 and 1024 inclusive - - *bs2* defines the location of the transmit point in units of the time quanta; - it can be between 1 and 16 inclusive - - *auto_restart* sets whether the controller will automatically try and restart - communications after entering the bus-off state; if this is disabled then - :meth:`~CAN.restart()` can be used to leave the bus-off state - - The time quanta tq is the basic unit of time for the CAN bus. tq is the CAN - prescaler value divided by PCLK1 (the frequency of internal peripheral bus 1); - see :meth:`pyb.freq()` to determine PCLK1. - - A single bit is made up of the synchronisation segment, which is always 1 tq. - Then follows bit segment 1, then bit segment 2. The sample point is after bit - segment 1 finishes. The transmit point is after bit segment 2 finishes. - The baud rate will be 1/bittime, where the bittime is 1 + BS1 + BS2 multiplied - by the time quanta tq. - - For example, with PCLK1=42MHz, prescaler=100, sjw=1, bs1=6, bs2=8, the value of - tq is 2.38 microseconds. The bittime is 35.7 microseconds, and the baudrate - is 28kHz. - - See page 680 of the STM32F405 datasheet for more details. - -.. method:: CAN.deinit() - - Turn off the CAN bus. - -.. method:: CAN.restart() - - Force a software restart of the CAN controller without resetting its - configuration. - - If the controller enters the bus-off state then it will no longer participate - in bus activity. If the controller is not configured to automatically restart - (see :meth:`~CAN.init()`) then this method can be used to trigger a restart, - and the controller will follow the CAN protocol to leave the bus-off state and - go into the error active state. - -.. method:: CAN.state() - - Return the state of the controller. The return value can be one of: - - - ``CAN.STOPPED`` -- the controller is completely off and reset; - - ``CAN.ERROR_ACTIVE`` -- the controller is on and in the Error Active state - (both TEC and REC are less than 96); - - ``CAN.ERROR_WARNING`` -- the controller is on and in the Error Warning state - (at least one of TEC or REC is 96 or greater); - - ``CAN.ERROR_PASSIVE`` -- the controller is on and in the Error Passive state - (at least one of TEC or REC is 128 or greater); - - ``CAN.BUS_OFF`` -- the controller is on but not participating in bus activity - (TEC overflowed beyond 255). - -.. method:: CAN.info([list]) - - Get information about the controller's error states and TX and RX buffers. - If *list* is provided then it should be a list object with at least 8 entries, - which will be filled in with the information. Otherwise a new list will be - created and filled in. In both cases the return value of the method is the - populated list. - - The values in the list are: - - - TEC value - - REC value - - number of times the controller enterted the Error Warning state (wrapped - around to 0 after 65535) - - number of times the controller enterted the Error Passive state (wrapped - around to 0 after 65535) - - number of times the controller enterted the Bus Off state (wrapped - around to 0 after 65535) - - number of pending TX messages - - number of pending RX messages on fifo 0 - - number of pending RX messages on fifo 1 - -.. method:: CAN.setfilter(bank, mode, fifo, params, \*, rtr) - - Configure a filter bank: - - - *bank* is the filter bank that is to be configured. - - *mode* is the mode the filter should operate in. - - *fifo* is which fifo (0 or 1) a message should be stored in, if it is accepted by this filter. - - *params* is an array of values the defines the filter. The contents of the array depends on the *mode* argument. - - +-----------+---------------------------------------------------------+ - |*mode* |contents of *params* array | - +===========+=========================================================+ - |CAN.LIST16 |Four 16 bit ids that will be accepted | - +-----------+---------------------------------------------------------+ - |CAN.LIST32 |Two 32 bit ids that will be accepted | - +-----------+---------------------------------------------------------+ - |CAN.MASK16 |Two 16 bit id/mask pairs. E.g. (1, 3, 4, 4) | - | | | The first pair, 1 and 3 will accept all ids | - | | | that have bit 0 = 1 and bit 1 = 0. | - | | | The second pair, 4 and 4, will accept all ids | - | | | that have bit 2 = 1. | - +-----------+---------------------------------------------------------+ - |CAN.MASK32 |As with CAN.MASK16 but with only one 32 bit id/mask pair.| - +-----------+---------------------------------------------------------+ - - - *rtr* is an array of booleans that states if a filter should accept a - remote transmission request message. If this argument is not given - then it defaults to ``False`` for all entries. The length of the array - depends on the *mode* argument. - - +-----------+----------------------+ - |*mode* |length of *rtr* array | - +===========+======================+ - |CAN.LIST16 |4 | - +-----------+----------------------+ - |CAN.LIST32 |2 | - +-----------+----------------------+ - |CAN.MASK16 |2 | - +-----------+----------------------+ - |CAN.MASK32 |1 | - +-----------+----------------------+ - -.. method:: CAN.clearfilter(bank) - - Clear and disables a filter bank: - - - *bank* is the filter bank that is to be cleared. - -.. method:: CAN.any(fifo) - - Return ``True`` if any message waiting on the FIFO, else ``False``. - -.. method:: CAN.recv(fifo, list=None, \*, timeout=5000) - - Receive data on the bus: - - - *fifo* is an integer, which is the FIFO to receive on - - *list* is an optional list object to be used as the return value - - *timeout* is the timeout in milliseconds to wait for the receive. - - Return value: A tuple containing four values. - - - The id of the message. - - A boolean that indicates if the message is an RTR message. - - The FMI (Filter Match Index) value. - - An array containing the data. - - If *list* is ``None`` then a new tuple will be allocated, as well as a new - bytes object to contain the data (as the fourth element in the tuple). - - If *list* is not ``None`` then it should be a list object with a least four - elements. The fourth element should be a memoryview object which is created - from either a bytearray or an array of type 'B' or 'b', and this array must - have enough room for at least 8 bytes. The list object will then be - populated with the first three return values above, and the memoryview object - will be resized inplace to the size of the data and filled in with that data. - The same list and memoryview objects can be reused in subsequent calls to - this method, providing a way of receiving data without using the heap. - For example:: - - buf = bytearray(8) - lst = [0, 0, 0, memoryview(buf)] - # No heap memory is allocated in the following call - can.recv(0, lst) - -.. method:: CAN.send(data, id, \*, timeout=0, rtr=False) - - Send a message on the bus: - - - *data* is the data to send (an integer to send, or a buffer object). - - *id* is the id of the message to be sent. - - *timeout* is the timeout in milliseconds to wait for the send. - - *rtr* is a boolean that specifies if the message shall be sent as - a remote transmission request. If *rtr* is True then only the length - of *data* is used to fill in the DLC slot of the frame; the actual - bytes in *data* are unused. - - If timeout is 0 the message is placed in a buffer in one of three hardware - buffers and the method returns immediately. If all three buffers are in use - an exception is thrown. If timeout is not 0, the method waits until the - message is transmitted. If the message can't be transmitted within the - specified time an exception is thrown. - - Return value: ``None``. - -.. method:: CAN.rxcallback(fifo, fun) - - Register a function to be called when a message is accepted into a empty fifo: - - - *fifo* is the receiving fifo. - - *fun* is the function to be called when the fifo becomes non empty. - - The callback function takes two arguments the first is the can object it self the second is - a integer that indicates the reason for the callback. - - +--------+------------------------------------------------+ - | Reason | | - +========+================================================+ - | 0 | A message has been accepted into a empty FIFO. | - +--------+------------------------------------------------+ - | 1 | The FIFO is full | - +--------+------------------------------------------------+ - | 2 | A message has been lost due to a full FIFO | - +--------+------------------------------------------------+ - - Example use of rxcallback:: - - def cb0(bus, reason): - print('cb0') - if reason == 0: - print('pending') - if reason == 1: - print('full') - if reason == 2: - print('overflow') - - can = CAN(1, CAN.LOOPBACK) - can.rxcallback(0, cb0) - -Constants ---------- - -.. data:: CAN.NORMAL - CAN.LOOPBACK - CAN.SILENT - CAN.SILENT_LOOPBACK - - The mode of the CAN bus used in :meth:`~CAN.init()`. - -.. data:: CAN.STOPPED - CAN.ERROR_ACTIVE - CAN.ERROR_WARNING - CAN.ERROR_PASSIVE - CAN.BUS_OFF - - Possible states of the CAN controller returned from :meth:`~CAN.state()`. - -.. data:: CAN.LIST16 - CAN.MASK16 - CAN.LIST32 - CAN.MASK32 - - The operation mode of a filter used in :meth:`~CAN.setfilter()`. diff --git a/docs/library/pyb.DAC.rst b/docs/library/pyb.DAC.rst deleted file mode 100644 index 3e236a3da9d..00000000000 --- a/docs/library/pyb.DAC.rst +++ /dev/null @@ -1,124 +0,0 @@ -.. currentmodule:: pyb -.. _pyb.DAC: - -class DAC -- digital to analog conversion -========================================= - -The DAC is used to output analog values (a specific voltage) on pin X5 or pin X6. -The voltage will be between 0 and 3.3V. - -*This module will undergo changes to the API.* - -Example usage:: - - from pyb import DAC - - dac = DAC(1) # create DAC 1 on pin X5 - dac.write(128) # write a value to the DAC (makes X5 1.65V) - - dac = DAC(1, bits=12) # use 12 bit resolution - dac.write(4095) # output maximum value, 3.3V - -To output a continuous sine-wave:: - - import math - from pyb import DAC - - # create a buffer containing a sine-wave - buf = bytearray(100) - for i in range(len(buf)): - buf[i] = 128 + int(127 * math.sin(2 * math.pi * i / len(buf))) - - # output the sine-wave at 400Hz - dac = DAC(1) - dac.write_timed(buf, 400 * len(buf), mode=DAC.CIRCULAR) - -To output a continuous sine-wave at 12-bit resolution:: - - import math - from array import array - from pyb import DAC - - # create a buffer containing a sine-wave, using half-word samples - buf = array('H', 2048 + int(2047 * math.sin(2 * math.pi * i / 128)) for i in range(128)) - - # output the sine-wave at 400Hz - dac = DAC(1, bits=12) - dac.write_timed(buf, 400 * len(buf), mode=DAC.CIRCULAR) - -Constructors ------------- - -.. class:: pyb.DAC(port, bits=8, \*, buffering=None) - - Construct a new DAC object. - - ``port`` can be a pin object, or an integer (1 or 2). - DAC(1) is on pin X5 and DAC(2) is on pin X6. - - ``bits`` is an integer specifying the resolution, and can be 8 or 12. - The maximum value for the write and write_timed methods will be - 2\*\*``bits``-1. - - The *buffering* parameter selects the behaviour of the DAC op-amp output - buffer, whose purpose is to reduce the output impedance. It can be - ``None`` to select the default (buffering enabled for :meth:`DAC.noise`, - :meth:`DAC.triangle` and :meth:`DAC.write_timed`, and disabled for - :meth:`DAC.write`), ``False`` to disable buffering completely, or ``True`` - to enable output buffering. - - When buffering is enabled the DAC pin can drive loads down to 5KΩ. - Otherwise it has an output impedance of 15KΩ maximum: consequently - to achieve a 1% accuracy without buffering requires the applied load - to be less than 1.5MΩ. Using the buffer incurs a penalty in accuracy, - especially near the extremes of range. - -Methods -------- - -.. method:: DAC.init(bits=8, \*, buffering=None) - - Reinitialise the DAC. *bits* can be 8 or 12. *buffering* can be - ``None``, ``False`` or ``True`; see above constructor for the meaning - of this parameter. - -.. method:: DAC.deinit() - - De-initialise the DAC making its pin available for other uses. - -.. method:: DAC.noise(freq) - - Generate a pseudo-random noise signal. A new random sample is written - to the DAC output at the given frequency. - -.. method:: DAC.triangle(freq) - - Generate a triangle wave. The value on the DAC output changes at - the given frequency, and the frequency of the repeating triangle wave - itself is 2048 times smaller. - -.. method:: DAC.write(value) - - Direct access to the DAC output. The minimum value is 0. The maximum - value is 2\*\*``bits``-1, where ``bits`` is set when creating the DAC - object or by using the ``init`` method. - -.. method:: DAC.write_timed(data, freq, \*, mode=DAC.NORMAL) - - Initiates a burst of RAM to DAC using a DMA transfer. - The input data is treated as an array of bytes in 8-bit mode, and - an array of unsigned half-words (array typecode 'H') in 12-bit mode. - - ``freq`` can be an integer specifying the frequency to write the DAC - samples at, using Timer(6). Or it can be an already-initialised - Timer object which is used to trigger the DAC sample. Valid timers - are 2, 4, 5, 6, 7 and 8. - - ``mode`` can be ``DAC.NORMAL`` or ``DAC.CIRCULAR``. - - Example using both DACs at the same time:: - - dac1 = DAC(1) - dac2 = DAC(2) - dac1.write_timed(buf1, pyb.Timer(6, freq=100), mode=DAC.CIRCULAR) - dac2.write_timed(buf2, pyb.Timer(7, freq=200), mode=DAC.CIRCULAR) diff --git a/docs/library/pyb.ExtInt.rst b/docs/library/pyb.ExtInt.rst deleted file mode 100644 index 814217cef08..00000000000 --- a/docs/library/pyb.ExtInt.rst +++ /dev/null @@ -1,114 +0,0 @@ -.. currentmodule:: pyb -.. _pyb.ExtInt: - -class ExtInt -- configure I/O pins to interrupt on external events -================================================================== - -There are a total of 22 interrupt lines. 16 of these can come from GPIO pins -and the remaining 6 are from internal sources. - -For lines 0 through 15, a given line can map to the corresponding line from an -arbitrary port. So line 0 can map to Px0 where x is A, B, C, ... and -line 1 can map to Px1 where x is A, B, C, ... :: - - def callback(line): - print("line =", line) - -Note: ExtInt will automatically configure the gpio line as an input. :: - - extint = pyb.ExtInt(pin, pyb.ExtInt.IRQ_FALLING, pyb.Pin.PULL_UP, callback) - -Now every time a falling edge is seen on the X1 pin, the callback will be -called. Caution: mechanical pushbuttons have "bounce" and pushing or -releasing a switch will often generate multiple edges. -See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed -explanation, along with various techniques for debouncing. - -Trying to register 2 callbacks onto the same pin will throw an exception. - -If pin is passed as an integer, then it is assumed to map to one of the -internal interrupt sources, and must be in the range 16 through 22. - -All other pin objects go through the pin mapper to come up with one of the -gpio pins. :: - - extint = pyb.ExtInt(pin, mode, pull, callback) - -Valid modes are pyb.ExtInt.IRQ_RISING, pyb.ExtInt.IRQ_FALLING, -pyb.ExtInt.IRQ_RISING_FALLING, pyb.ExtInt.EVT_RISING, -pyb.ExtInt.EVT_FALLING, and pyb.ExtInt.EVT_RISING_FALLING. - -Only the IRQ_xxx modes have been tested. The EVT_xxx modes have -something to do with sleep mode and the WFE instruction. - -Valid pull values are pyb.Pin.PULL_UP, pyb.Pin.PULL_DOWN, pyb.Pin.PULL_NONE. - -There is also a C API, so that drivers which require EXTI interrupt lines -can also use this code. See extint.h for the available functions and -usrsw.h for an example of using this. - - -Constructors ------------- - -.. class:: pyb.ExtInt(pin, mode, pull, callback) - - Create an ExtInt object: - - - ``pin`` is the pin on which to enable the interrupt (can be a pin object or any valid pin name). - - ``mode`` can be one of: - - ``ExtInt.IRQ_RISING`` - trigger on a rising edge; - - ``ExtInt.IRQ_FALLING`` - trigger on a falling edge; - - ``ExtInt.IRQ_RISING_FALLING`` - trigger on a rising or falling edge. - - ``pull`` can be one of: - - ``pyb.Pin.PULL_NONE`` - no pull up or down resistors; - - ``pyb.Pin.PULL_UP`` - enable the pull-up resistor; - - ``pyb.Pin.PULL_DOWN`` - enable the pull-down resistor. - - ``callback`` is the function to call when the interrupt triggers. The - callback function must accept exactly 1 argument, which is the line that - triggered the interrupt. - - -Class methods -------------- - -.. classmethod:: ExtInt.regs() - - Dump the values of the EXTI registers. - - -Methods -------- - -.. method:: ExtInt.disable() - - Disable the interrupt associated with the ExtInt object. - This could be useful for debouncing. - -.. method:: ExtInt.enable() - - Enable a disabled interrupt. - -.. method:: ExtInt.line() - - Return the line number that the pin is mapped to. - -.. method:: ExtInt.swint() - - Trigger the callback from software. - - -Constants ---------- - -.. data:: ExtInt.IRQ_FALLING - - interrupt on a falling edge - -.. data:: ExtInt.IRQ_RISING - - interrupt on a rising edge - -.. data:: ExtInt.IRQ_RISING_FALLING - - interrupt on a rising or falling edge diff --git a/docs/library/pyb.I2C.rst b/docs/library/pyb.I2C.rst deleted file mode 100644 index 7400318902c..00000000000 --- a/docs/library/pyb.I2C.rst +++ /dev/null @@ -1,175 +0,0 @@ -.. currentmodule:: pyb -.. _pyb.I2C: - -class I2C -- a two-wire serial protocol -======================================= - -I2C is a two-wire protocol for communicating between devices. At the physical -level it consists of 2 wires: SCL and SDA, the clock and data lines respectively. - -I2C objects are created attached to a specific bus. They can be initialised -when created, or initialised later on. - -.. only:: port_pyboard - - Example:: - - from pyb import I2C - - i2c = I2C(1) # create on bus 1 - i2c = I2C(1, I2C.MASTER) # create and init as a master - i2c.init(I2C.MASTER, baudrate=20000) # init as a master - i2c.init(I2C.SLAVE, addr=0x42) # init as a slave with given address - i2c.deinit() # turn off the peripheral - -Printing the i2c object gives you information about its configuration. - -.. only:: port_pyboard - - The basic methods are send and recv:: - - i2c.send('abc') # send 3 bytes - i2c.send(0x42) # send a single byte, given by the number - data = i2c.recv(3) # receive 3 bytes - - To receive inplace, first create a bytearray:: - - data = bytearray(3) # create a buffer - i2c.recv(data) # receive 3 bytes, writing them into data - - You can specify a timeout (in ms):: - - i2c.send(b'123', timeout=2000) # timeout after 2 seconds - - A master must specify the recipient's address:: - - i2c.init(I2C.MASTER) - i2c.send('123', 0x42) # send 3 bytes to slave with address 0x42 - i2c.send(b'456', addr=0x42) # keyword for address - - Master also has other methods:: - - i2c.is_ready(0x42) # check if slave 0x42 is ready - i2c.scan() # scan for slaves on the bus, returning - # a list of valid addresses - i2c.mem_read(3, 0x42, 2) # read 3 bytes from memory of slave 0x42, - # starting at address 2 in the slave - i2c.mem_write('abc', 0x42, 2, timeout=1000) # write 'abc' (3 bytes) to memory of slave 0x42 - # starting at address 2 in the slave, timeout after 1 second - -Constructors ------------- - -.. only:: port_pyboard - - .. class:: pyb.I2C(bus, ...) - - Construct an I2C object on the given bus. ``bus`` can be 1 or 2, 'X' or - 'Y'. With no additional parameters, the I2C object is created but not - initialised (it has the settings from the last initialisation of - the bus, if any). If extra arguments are given, the bus is initialised. - See ``init`` for parameters of initialisation. - - The physical pins of the I2C busses on Pyboards V1.0 and V1.1 are: - - - ``I2C(1)`` is on the X position: ``(SCL, SDA) = (X9, X10) = (PB6, PB7)`` - - ``I2C(2)`` is on the Y position: ``(SCL, SDA) = (Y9, Y10) = (PB10, PB11)`` - - On the Pyboard Lite: - - - ``I2C(1)`` is on the X position: ``(SCL, SDA) = (X9, X10) = (PB6, PB7)`` - - ``I2C(3)`` is on the Y position: ``(SCL, SDA) = (Y9, Y10) = (PA8, PB8)`` - - Calling the constructor with 'X' or 'Y' enables portability between Pyboard - types. - -Methods -------- - -.. method:: I2C.deinit() - - Turn off the I2C bus. - -.. only:: port_pyboard - - .. method:: I2C.init(mode, \*, addr=0x12, baudrate=400000, gencall=False, dma=False) - - Initialise the I2C bus with the given parameters: - - - ``mode`` must be either ``I2C.MASTER`` or ``I2C.SLAVE`` - - ``addr`` is the 7-bit address (only sensible for a slave) - - ``baudrate`` is the SCL clock rate (only sensible for a master) - - ``gencall`` is whether to support general call mode - - ``dma`` is whether to allow the use of DMA for the I2C transfers (note - that DMA transfers have more precise timing but currently do not handle bus - errors properly) - - .. method:: I2C.is_ready(addr) - - Check if an I2C device responds to the given address. Only valid when in master mode. - - .. method:: I2C.mem_read(data, addr, memaddr, \*, timeout=5000, addr_size=8) - - Read from the memory of an I2C device: - - - ``data`` can be an integer (number of bytes to read) or a buffer to read into - - ``addr`` is the I2C device address - - ``memaddr`` is the memory location within the I2C device - - ``timeout`` is the timeout in milliseconds to wait for the read - - ``addr_size`` selects width of memaddr: 8 or 16 bits - - Returns the read data. - This is only valid in master mode. - - .. method:: I2C.mem_write(data, addr, memaddr, \*, timeout=5000, addr_size=8) - - Write to the memory of an I2C device: - - - ``data`` can be an integer or a buffer to write from - - ``addr`` is the I2C device address - - ``memaddr`` is the memory location within the I2C device - - ``timeout`` is the timeout in milliseconds to wait for the write - - ``addr_size`` selects width of memaddr: 8 or 16 bits - - Returns ``None``. - This is only valid in master mode. - - .. method:: I2C.recv(recv, addr=0x00, \*, timeout=5000) - - Receive data on the bus: - - - ``recv`` can be an integer, which is the number of bytes to receive, - or a mutable buffer, which will be filled with received bytes - - ``addr`` is the address to receive from (only required in master mode) - - ``timeout`` is the timeout in milliseconds to wait for the receive - - Return value: if ``recv`` is an integer then a new buffer of the bytes received, - otherwise the same buffer that was passed in to ``recv``. - - .. method:: I2C.send(send, addr=0x00, \*, timeout=5000) - - Send data on the bus: - - - ``send`` is the data to send (an integer to send, or a buffer object) - - ``addr`` is the address to send to (only required in master mode) - - ``timeout`` is the timeout in milliseconds to wait for the send - - Return value: ``None``. - -.. method:: I2C.scan() - - Scan all I2C addresses from 0x01 to 0x7f and return a list of those that respond. - Only valid when in master mode. - -Constants ---------- - -.. data:: I2C.MASTER - - for initialising the bus to master mode - -.. only:: port_pyboard - - .. data:: I2C.SLAVE - - for initialising the bus to slave mode diff --git a/docs/library/pyb.LCD.rst b/docs/library/pyb.LCD.rst deleted file mode 100644 index 5ab127edcda..00000000000 --- a/docs/library/pyb.LCD.rst +++ /dev/null @@ -1,97 +0,0 @@ -.. currentmodule:: pyb -.. _pyb.LCD: - -class LCD -- LCD control for the LCD touch-sensor pyskin -======================================================== - -The LCD class is used to control the LCD on the LCD touch-sensor pyskin, -LCD32MKv1.0. The LCD is a 128x32 pixel monochrome screen, part NHD-C12832A1Z. - -The pyskin must be connected in either the X or Y positions, and then -an LCD object is made using:: - - lcd = pyb.LCD('X') # if pyskin is in the X position - lcd = pyb.LCD('Y') # if pyskin is in the Y position - -Then you can use:: - - lcd.light(True) # turn the backlight on - lcd.write('Hello world!\n') # print text to the screen - -This driver implements a double buffer for setting/getting pixels. -For example, to make a bouncing dot, try:: - - x = y = 0 - dx = dy = 1 - while True: - # update the dot's position - x += dx - y += dy - - # make the dot bounce of the edges of the screen - if x <= 0 or x >= 127: dx = -dx - if y <= 0 or y >= 31: dy = -dy - - lcd.fill(0) # clear the buffer - lcd.pixel(x, y, 1) # draw the dot - lcd.show() # show the buffer - pyb.delay(50) # pause for 50ms - - -Constructors ------------- - -.. class:: pyb.LCD(skin_position) - - Construct an LCD object in the given skin position. ``skin_position`` can be 'X' or 'Y', and - should match the position where the LCD pyskin is plugged in. - - -Methods -------- - -.. method:: LCD.command(instr_data, buf) - - Send an arbitrary command to the LCD. Pass 0 for ``instr_data`` to send an - instruction, otherwise pass 1 to send data. ``buf`` is a buffer with the - instructions/data to send. - -.. method:: LCD.contrast(value) - - Set the contrast of the LCD. Valid values are between 0 and 47. - -.. method:: LCD.fill(colour) - - Fill the screen with the given colour (0 or 1 for white or black). - - This method writes to the hidden buffer. Use ``show()`` to show the buffer. - -.. method:: LCD.get(x, y) - - Get the pixel at the position ``(x, y)``. Returns 0 or 1. - - This method reads from the visible buffer. - -.. method:: LCD.light(value) - - Turn the backlight on/off. True or 1 turns it on, False or 0 turns it off. - -.. method:: LCD.pixel(x, y, colour) - - Set the pixel at ``(x, y)`` to the given colour (0 or 1). - - This method writes to the hidden buffer. Use ``show()`` to show the buffer. - -.. method:: LCD.show() - - Show the hidden buffer on the screen. - -.. method:: LCD.text(str, x, y, colour) - - Draw the given text to the position ``(x, y)`` using the given colour (0 or 1). - - This method writes to the hidden buffer. Use ``show()`` to show the buffer. - -.. method:: LCD.write(str) - - Write the string ``str`` to the screen. It will appear immediately. diff --git a/docs/library/pyb.LED.rst b/docs/library/pyb.LED.rst deleted file mode 100644 index 1ab73a69c9a..00000000000 --- a/docs/library/pyb.LED.rst +++ /dev/null @@ -1,46 +0,0 @@ -.. currentmodule:: pyb -.. _pyb.LED: - -class LED -- LED object -======================= - -The LED object controls an individual LED (Light Emitting Diode). - - -Constructors ------------- - -.. class:: pyb.LED(id) - - Create an LED object associated with the given LED: - - - ``id`` is the LED number, 1-4. - - -Methods -------- - -.. method:: LED.intensity([value]) - - Get or set the LED intensity. Intensity ranges between 0 (off) and 255 (full on). - If no argument is given, return the LED intensity. - If an argument is given, set the LED intensity and return ``None``. - - *Note:* Only LED(3) and LED(4) can have a smoothly varying intensity, and - they use timer PWM to implement it. LED(3) uses Timer(2) and LED(4) uses - Timer(3). These timers are only configured for PWM if the intensity of the - relevant LED is set to a value between 1 and 254. Otherwise the timers are - free for general purpose use. - -.. method:: LED.off() - - Turn the LED off. - -.. method:: LED.on() - - Turn the LED on, to maximum intensity. - -.. method:: LED.toggle() - - Toggle the LED between on (maximum intensity) and off. If the LED is at - non-zero intensity then it is considered "on" and toggle will turn it off. diff --git a/docs/library/pyb.Pin.rst b/docs/library/pyb.Pin.rst deleted file mode 100644 index b766c5280c3..00000000000 --- a/docs/library/pyb.Pin.rst +++ /dev/null @@ -1,280 +0,0 @@ -.. currentmodule:: pyb -.. _pyb.Pin: - -class Pin -- control I/O pins -============================= - -A pin is the basic object to control I/O pins. It has methods to set -the mode of the pin (input, output, etc) and methods to get and set the -digital logic level. For analog control of a pin, see the ADC class. - -Usage Model: - -.. only:: port_pyboard - - All Board Pins are predefined as pyb.Pin.board.Name:: - - x1_pin = pyb.Pin.board.X1 - - g = pyb.Pin(pyb.Pin.board.X1, pyb.Pin.IN) - - CPU pins which correspond to the board pins are available - as ``pyb.cpu.Name``. For the CPU pins, the names are the port letter - followed by the pin number. On the PYBv1.0, ``pyb.Pin.board.X1`` and - ``pyb.Pin.cpu.A0`` are the same pin. - - You can also use strings:: - - g = pyb.Pin('X1', pyb.Pin.OUT_PP) - - Users can add their own names:: - - MyMapperDict = { 'LeftMotorDir' : pyb.Pin.cpu.C12 } - pyb.Pin.dict(MyMapperDict) - g = pyb.Pin("LeftMotorDir", pyb.Pin.OUT_OD) - - and can query mappings:: - - pin = pyb.Pin("LeftMotorDir") - - Users can also add their own mapping function:: - - def MyMapper(pin_name): - if pin_name == "LeftMotorDir": - return pyb.Pin.cpu.A0 - - pyb.Pin.mapper(MyMapper) - - So, if you were to call: ``pyb.Pin("LeftMotorDir", pyb.Pin.OUT_PP)`` - then ``"LeftMotorDir"`` is passed directly to the mapper function. - - To summarise, the following order determines how things get mapped into - an ordinal pin number: - - 1. Directly specify a pin object - 2. User supplied mapping function - 3. User supplied mapping (object must be usable as a dictionary key) - 4. Supply a string which matches a board pin - 5. Supply a string which matches a CPU port/pin - - You can set ``pyb.Pin.debug(True)`` to get some debug information about - how a particular object gets mapped to a pin. - - When a pin has the ``Pin.PULL_UP`` or ``Pin.PULL_DOWN`` pull-mode enabled, - that pin has an effective 40k Ohm resistor pulling it to 3V3 or GND - respectively (except pin Y5 which has 11k Ohm resistors). - - Now every time a falling edge is seen on the gpio pin, the callback will be - executed. Caution: mechanical push buttons have "bounce" and pushing or - releasing a switch will often generate multiple edges. - See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed - explanation, along with various techniques for debouncing. - - All pin objects go through the pin mapper to come up with one of the - gpio pins. - -Constructors ------------- - -.. class:: pyb.Pin(id, ...) - - Create a new Pin object associated with the id. If additional arguments are given, - they are used to initialise the pin. See :meth:`pin.init`. - -.. only:: port_pyboard - - Class methods - ------------- - - .. classmethod:: Pin.debug([state]) - - Get or set the debugging state (``True`` or ``False`` for on or off). - - .. classmethod:: Pin.dict([dict]) - - Get or set the pin mapper dictionary. - - .. classmethod:: Pin.mapper([fun]) - - Get or set the pin mapper function. - - -Methods -------- - -.. only:: port_pyboard - - .. method:: Pin.init(mode, pull=Pin.PULL_NONE, af=-1) - - Initialise the pin: - - - ``mode`` can be one of: - - - ``Pin.IN`` - configure the pin for input; - - ``Pin.OUT_PP`` - configure the pin for output, with push-pull control; - - ``Pin.OUT_OD`` - configure the pin for output, with open-drain control; - - ``Pin.AF_PP`` - configure the pin for alternate function, pull-pull; - - ``Pin.AF_OD`` - configure the pin for alternate function, open-drain; - - ``Pin.ANALOG`` - configure the pin for analog. - - - ``pull`` can be one of: - - - ``Pin.PULL_NONE`` - no pull up or down resistors; - - ``Pin.PULL_UP`` - enable the pull-up resistor; - - ``Pin.PULL_DOWN`` - enable the pull-down resistor. - - - when mode is ``Pin.AF_PP`` or ``Pin.AF_OD``, then af can be the index or name - of one of the alternate functions associated with a pin. - - Returns: ``None``. - -.. method:: Pin.value([value]) - - Get or set the digital logic level of the pin: - - - With no argument, return 0 or 1 depending on the logic level of the pin. - - With ``value`` given, set the logic level of the pin. ``value`` can be - anything that converts to a boolean. If it converts to ``True``, the pin - is set high, otherwise it is set low. - -.. only:: port_pyboard - - .. method:: Pin.__str__() - - Return a string describing the pin object. - - .. method:: Pin.af() - - Returns the currently configured alternate-function of the pin. The - integer returned will match one of the allowed constants for the af - argument to the init function. - - .. method:: Pin.af_list() - - Returns an array of alternate functions available for this pin. - - .. method:: Pin.gpio() - - Returns the base address of the GPIO block associated with this pin. - - .. method:: Pin.mode() - - Returns the currently configured mode of the pin. The integer returned - will match one of the allowed constants for the mode argument to the init - function. - - .. method:: Pin.name() - - Get the pin name. - - .. method:: Pin.names() - - Returns the cpu and board names for this pin. - - .. method:: Pin.pin() - - Get the pin number. - - .. method:: Pin.port() - - Get the pin port. - -.. method:: Pin.pull() - - Returns the currently configured pull of the pin. The integer returned - will match one of the allowed constants for the pull argument to the init - function. - -Constants ---------- - -.. only:: port_pyboard - - .. data:: Pin.AF_OD - - initialise the pin to alternate-function mode with an open-drain drive - - .. data:: Pin.AF_PP - - initialise the pin to alternate-function mode with a push-pull drive - - .. data:: Pin.ANALOG - - initialise the pin to analog mode - - .. data:: Pin.IN - - initialise the pin to input mode - - .. data:: Pin.OUT_OD - - initialise the pin to output mode with an open-drain drive - - .. data:: Pin.OUT_PP - - initialise the pin to output mode with a push-pull drive - - .. data:: Pin.PULL_DOWN - - enable the pull-down resistor on the pin - - .. data:: Pin.PULL_NONE - - don't enable any pull up or down resistors on the pin - - .. data:: Pin.PULL_UP - - enable the pull-up resistor on the pin - -.. only:: port_pyboard - - class PinAF -- Pin Alternate Functions - ====================================== - - A Pin represents a physical pin on the microprocessor. Each pin - can have a variety of functions (GPIO, I2C SDA, etc). Each PinAF - object represents a particular function for a pin. - - Usage Model:: - - x3 = pyb.Pin.board.X3 - x3_af = x3.af_list() - - x3_af will now contain an array of PinAF objects which are available on - pin X3. - - For the pyboard, x3_af would contain: - [Pin.AF1_TIM2, Pin.AF2_TIM5, Pin.AF3_TIM9, Pin.AF7_USART2] - - Normally, each peripheral would configure the af automatically, but sometimes - the same function is available on multiple pins, and having more control - is desired. - - To configure X3 to expose TIM2_CH3, you could use:: - - pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.AF_PP, af=pyb.Pin.AF1_TIM2) - - or:: - - pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.AF_PP, af=1) - - Methods - ------- - - .. method:: pinaf.__str__() - - Return a string describing the alternate function. - - .. method:: pinaf.index() - - Return the alternate function index. - - .. method:: pinaf.name() - - Return the name of the alternate function. - - .. method:: pinaf.reg() - - Return the base register associated with the peripheral assigned to this - alternate function. For example, if the alternate function were TIM2_CH3 - this would return stm.TIM2 diff --git a/docs/library/pyb.RTC.rst b/docs/library/pyb.RTC.rst deleted file mode 100644 index 1a1df909517..00000000000 --- a/docs/library/pyb.RTC.rst +++ /dev/null @@ -1,83 +0,0 @@ -.. currentmodule:: pyb -.. _pyb.RTC: - -class RTC -- real time clock -============================ - -The RTC is and independent clock that keeps track of the date -and time. - -Example usage:: - - rtc = pyb.RTC() - rtc.datetime((2014, 5, 1, 4, 13, 0, 0, 0)) - print(rtc.datetime()) - - -Constructors ------------- - -.. class:: pyb.RTC() - - Create an RTC object. - - -Methods -------- - -.. method:: RTC.datetime([datetimetuple]) - - Get or set the date and time of the RTC. - - With no arguments, this method returns an 8-tuple with the current - date and time. With 1 argument (being an 8-tuple) it sets the date - and time (and ``subseconds`` is reset to 255). - - .. only:: port_pyboard - - The 8-tuple has the following format: - - (year, month, day, weekday, hours, minutes, seconds, subseconds) - - ``weekday`` is 1-7 for Monday through Sunday. - - ``subseconds`` counts down from 255 to 0 - -.. only:: port_pyboard - - .. method:: RTC.wakeup(timeout, callback=None) - - Set the RTC wakeup timer to trigger repeatedly at every ``timeout`` - milliseconds. This trigger can wake the pyboard from both the sleep - states: :meth:`pyb.stop` and :meth:`pyb.standby`. - - If ``timeout`` is ``None`` then the wakeup timer is disabled. - - If ``callback`` is given then it is executed at every trigger of the - wakeup timer. ``callback`` must take exactly one argument. - - .. method:: RTC.info() - - Get information about the startup time and reset source. - - - The lower 0xffff are the number of milliseconds the RTC took to - start up. - - Bit 0x10000 is set if a power-on reset occurred. - - Bit 0x20000 is set if an external reset occurred - - .. method:: RTC.calibration(cal) - - Get or set RTC calibration. - - With no arguments, ``calibration()`` returns the current calibration - value, which is an integer in the range [-511 : 512]. With one - argument it sets the RTC calibration. - - The RTC Smooth Calibration mechanism adjusts the RTC clock rate by - adding or subtracting the given number of ticks from the 32768 Hz - clock over a 32 second period (corresponding to 2^20 clock ticks.) - Each tick added will speed up the clock by 1 part in 2^20, or 0.954 - ppm; likewise the RTC clock it slowed by negative values. The - usable calibration range is: - (-511 * 0.954) ~= -487.5 ppm up to (512 * 0.954) ~= 488.5 ppm - diff --git a/docs/library/pyb.SPI.rst b/docs/library/pyb.SPI.rst deleted file mode 100644 index fd110be190c..00000000000 --- a/docs/library/pyb.SPI.rst +++ /dev/null @@ -1,132 +0,0 @@ -.. currentmodule:: pyb -.. _pyb.SPI: - -class SPI -- a master-driven serial protocol -============================================ - -SPI is a serial protocol that is driven by a master. At the physical level -there are 3 lines: SCK, MOSI, MISO. - -.. only:: port_pyboard - - See usage model of I2C; SPI is very similar. Main difference is - parameters to init the SPI bus:: - - from pyb import SPI - spi = SPI(1, SPI.MASTER, baudrate=600000, polarity=1, phase=0, crc=0x7) - - Only required parameter is mode, SPI.MASTER or SPI.SLAVE. Polarity can be - 0 or 1, and is the level the idle clock line sits at. Phase can be 0 or 1 - to sample data on the first or second clock edge respectively. Crc can be - None for no CRC, or a polynomial specifier. - - Additional methods for SPI:: - - data = spi.send_recv(b'1234') # send 4 bytes and receive 4 bytes - buf = bytearray(4) - spi.send_recv(b'1234', buf) # send 4 bytes and receive 4 into buf - spi.send_recv(buf, buf) # send/recv 4 bytes from/to buf - -Constructors ------------- - -.. only:: port_pyboard - - .. class:: pyb.SPI(bus, ...) - - Construct an SPI object on the given bus. ``bus`` can be 1 or 2, or - 'X' or 'Y'. With no additional parameters, the SPI object is created but - not initialised (it has the settings from the last initialisation of - the bus, if any). If extra arguments are given, the bus is initialised. - See ``init`` for parameters of initialisation. - - The physical pins of the SPI busses are: - - - ``SPI(1)`` is on the X position: ``(NSS, SCK, MISO, MOSI) = (X5, X6, X7, X8) = (PA4, PA5, PA6, PA7)`` - - ``SPI(2)`` is on the Y position: ``(NSS, SCK, MISO, MOSI) = (Y5, Y6, Y7, Y8) = (PB12, PB13, PB14, PB15)`` - - At the moment, the NSS pin is not used by the SPI driver and is free - for other use. - -Methods -------- - -.. method:: SPI.deinit() - - Turn off the SPI bus. - -.. only:: port_pyboard - - .. method:: SPI.init(mode, baudrate=328125, \*, prescaler, polarity=1, phase=0, bits=8, firstbit=SPI.MSB, ti=False, crc=None) - - Initialise the SPI bus with the given parameters: - - - ``mode`` must be either ``SPI.MASTER`` or ``SPI.SLAVE``. - - ``baudrate`` is the SCK clock rate (only sensible for a master). - - ``prescaler`` is the prescaler to use to derive SCK from the APB bus frequency; - use of ``prescaler`` overrides ``baudrate``. - - ``polarity`` can be 0 or 1, and is the level the idle clock line sits at. - - ``phase`` can be 0 or 1 to sample data on the first or second clock edge - respectively. - - ``bits`` can be 8 or 16, and is the number of bits in each transferred word. - - ``firstbit`` can be ``SPI.MSB`` or ``SPI.LSB``. - - ``crc`` can be None for no CRC, or a polynomial specifier. - - Note that the SPI clock frequency will not always be the requested baudrate. - The hardware only supports baudrates that are the APB bus frequency - (see :meth:`pyb.freq`) divided by a prescaler, which can be 2, 4, 8, 16, 32, - 64, 128 or 256. SPI(1) is on AHB2, and SPI(2) is on AHB1. For precise - control over the SPI clock frequency, specify ``prescaler`` instead of - ``baudrate``. - - Printing the SPI object will show you the computed baudrate and the chosen - prescaler. - -.. only:: port_pyboard - - .. method:: SPI.recv(recv, \*, timeout=5000) - - Receive data on the bus: - - - ``recv`` can be an integer, which is the number of bytes to receive, - or a mutable buffer, which will be filled with received bytes. - - ``timeout`` is the timeout in milliseconds to wait for the receive. - - Return value: if ``recv`` is an integer then a new buffer of the bytes received, - otherwise the same buffer that was passed in to ``recv``. - - .. method:: SPI.send(send, \*, timeout=5000) - - Send data on the bus: - - - ``send`` is the data to send (an integer to send, or a buffer object). - - ``timeout`` is the timeout in milliseconds to wait for the send. - - Return value: ``None``. - - .. method:: SPI.send_recv(send, recv=None, \*, timeout=5000) - - Send and receive data on the bus at the same time: - - - ``send`` is the data to send (an integer to send, or a buffer object). - - ``recv`` is a mutable buffer which will be filled with received bytes. - It can be the same as ``send``, or omitted. If omitted, a new buffer will - be created. - - ``timeout`` is the timeout in milliseconds to wait for the receive. - - Return value: the buffer with the received bytes. - -Constants ---------- - -.. only:: port_pyboard - - .. data:: SPI.MASTER - .. data:: SPI.SLAVE - - for initialising the SPI bus to master or slave mode - - .. data:: SPI.LSB - .. data:: SPI.MSB - - set the first bit to be the least or most significant bit diff --git a/docs/library/pyb.Servo.rst b/docs/library/pyb.Servo.rst deleted file mode 100644 index b3ce71d11ac..00000000000 --- a/docs/library/pyb.Servo.rst +++ /dev/null @@ -1,80 +0,0 @@ -.. currentmodule:: pyb -.. _pyb.Servo: - -class Servo -- 3-wire hobby servo driver -======================================== - -Servo objects control standard hobby servo motors with 3-wires (ground, power, -signal). There are 4 positions on the pyboard where these motors can be plugged -in: pins X1 through X4 are the signal pins, and next to them are 4 sets of power -and ground pins. - -Example usage:: - - import pyb - - s1 = pyb.Servo(1) # create a servo object on position X1 - s2 = pyb.Servo(2) # create a servo object on position X2 - - s1.angle(45) # move servo 1 to 45 degrees - s2.angle(0) # move servo 2 to 0 degrees - - # move servo1 and servo2 synchronously, taking 1500ms - s1.angle(-60, 1500) - s2.angle(30, 1500) - -.. note:: The Servo objects use Timer(5) to produce the PWM output. You can - use Timer(5) for Servo control, or your own purposes, but not both at the - same time. - -Constructors ------------- - -.. class:: pyb.Servo(id) - - Create a servo object. ``id`` is 1-4, and corresponds to pins X1 through X4. - - -Methods -------- - -.. method:: Servo.angle([angle, time=0]) - - If no arguments are given, this function returns the current angle. - - If arguments are given, this function sets the angle of the servo: - - - ``angle`` is the angle to move to in degrees. - - ``time`` is the number of milliseconds to take to get to the specified - angle. If omitted, then the servo moves as quickly as possible to its - new position. - -.. method:: Servo.speed([speed, time=0]) - - If no arguments are given, this function returns the current speed. - - If arguments are given, this function sets the speed of the servo: - - - ``speed`` is the speed to change to, between -100 and 100. - - ``time`` is the number of milliseconds to take to get to the specified - speed. If omitted, then the servo accelerates as quickly as possible. - -.. method:: Servo.pulse_width([value]) - - If no arguments are given, this function returns the current raw pulse-width - value. - - If an argument is given, this function sets the raw pulse-width value. - -.. method:: Servo.calibration([pulse_min, pulse_max, pulse_centre, [pulse_angle_90, pulse_speed_100]]) - - If no arguments are given, this function returns the current calibration - data, as a 5-tuple. - - If arguments are given, this function sets the timing calibration: - - - ``pulse_min`` is the minimum allowed pulse width. - - ``pulse_max`` is the maximum allowed pulse width. - - ``pulse_centre`` is the pulse width corresponding to the centre/zero position. - - ``pulse_angle_90`` is the pulse width corresponding to 90 degrees. - - ``pulse_speed_100`` is the pulse width corresponding to a speed of 100. diff --git a/docs/library/pyb.Switch.rst b/docs/library/pyb.Switch.rst deleted file mode 100644 index 1edcbf8488a..00000000000 --- a/docs/library/pyb.Switch.rst +++ /dev/null @@ -1,46 +0,0 @@ -.. currentmodule:: pyb -.. _pyb.Switch: - -class Switch -- switch object -============================= - -A Switch object is used to control a push-button switch. - -Usage:: - - sw = pyb.Switch() # create a switch object - sw.value() # get state (True if pressed, False otherwise) - sw() # shorthand notation to get the switch state - sw.callback(f) # register a callback to be called when the - # switch is pressed down - sw.callback(None) # remove the callback - -Example:: - - pyb.Switch().callback(lambda: pyb.LED(1).toggle()) - - -Constructors ------------- - -.. class:: pyb.Switch() - - Create and return a switch object. - - -Methods -------- - -.. method:: Switch.__call__() - - Call switch object directly to get its state: ``True`` if pressed down, - ``False`` otherwise. - -.. method:: Switch.value() - - Get the switch state. Returns ``True`` if pressed down, otherwise ``False``. - -.. method:: Switch.callback(fun) - - Register the given function to be called when the switch is pressed down. - If ``fun`` is ``None``, then it disables the callback. diff --git a/docs/library/pyb.Timer.rst b/docs/library/pyb.Timer.rst deleted file mode 100644 index 052bce2efd6..00000000000 --- a/docs/library/pyb.Timer.rst +++ /dev/null @@ -1,286 +0,0 @@ -.. currentmodule:: pyb -.. _pyb.Timer: - -class Timer -- control internal timers -====================================== - -.. only:: port_pyboard - - Timers can be used for a great variety of tasks. At the moment, only - the simplest case is implemented: that of calling a function periodically. - - Each timer consists of a counter that counts up at a certain rate. The rate - at which it counts is the peripheral clock frequency (in Hz) divided by the - timer prescaler. When the counter reaches the timer period it triggers an - event, and the counter resets back to zero. By using the callback method, - the timer event can call a Python function. - - Example usage to toggle an LED at a fixed frequency:: - - tim = pyb.Timer(4) # create a timer object using timer 4 - tim.init(freq=2) # trigger at 2Hz - tim.callback(lambda t:pyb.LED(1).toggle()) - - Example using named function for the callback:: - - def tick(timer): # we will receive the timer object when being called - print(timer.counter()) # show current timer's counter value - tim = pyb.Timer(4, freq=1) # create a timer object using timer 4 - trigger at 1Hz - tim.callback(tick) # set the callback to our tick function - - Further examples:: - - tim = pyb.Timer(4, freq=100) # freq in Hz - tim = pyb.Timer(4, prescaler=0, period=99) - tim.counter() # get counter (can also set) - tim.prescaler(2) # set prescaler (can also get) - tim.period(199) # set period (can also get) - tim.callback(lambda t: ...) # set callback for update interrupt (t=tim instance) - tim.callback(None) # clear callback - - *Note:* Timer(2) and Timer(3) are used for PWM to set the intensity of LED(3) - and LED(4) respectively. But these timers are only configured for PWM if - the intensity of the relevant LED is set to a value between 1 and 254. If - the intensity feature of the LEDs is not used then these timers are free for - general purpose use. Similarly, Timer(5) controls the servo driver, and - Timer(6) is used for timed ADC/DAC reading/writing. It is recommended to - use the other timers in your programs. - -*Note:* Memory can't be allocated during a callback (an interrupt) and so -exceptions raised within a callback don't give much information. See -:func:`micropython.alloc_emergency_exception_buf` for how to get around this -limitation. - - -Constructors ------------- - -.. class:: pyb.Timer(id, ...) - - .. only:: port_pyboard - - Construct a new timer object of the given id. If additional - arguments are given, then the timer is initialised by ``init(...)``. - ``id`` can be 1 to 14. - -Methods -------- - -.. only:: port_pyboard - - .. method:: Timer.init(\*, freq, prescaler, period) - - Initialise the timer. Initialisation must be either by frequency (in Hz) - or by prescaler and period:: - - tim.init(freq=100) # set the timer to trigger at 100Hz - tim.init(prescaler=83, period=999) # set the prescaler and period directly - - Keyword arguments: - - - ``freq`` --- specifies the periodic frequency of the timer. You might also - view this as the frequency with which the timer goes through one complete cycle. - - - ``prescaler`` [0-0xffff] - specifies the value to be loaded into the - timer's Prescaler Register (PSC). The timer clock source is divided by - (``prescaler + 1``) to arrive at the timer clock. Timers 2-7 and 12-14 - have a clock source of 84 MHz (pyb.freq()[2] \* 2), and Timers 1, and 8-11 - have a clock source of 168 MHz (pyb.freq()[3] \* 2). - - - ``period`` [0-0xffff] for timers 1, 3, 4, and 6-15. [0-0x3fffffff] for timers 2 & 5. - Specifies the value to be loaded into the timer's AutoReload - Register (ARR). This determines the period of the timer (i.e. when the - counter cycles). The timer counter will roll-over after ``period + 1`` - timer clock cycles. - - - ``mode`` can be one of: - - - ``Timer.UP`` - configures the timer to count from 0 to ARR (default) - - ``Timer.DOWN`` - configures the timer to count from ARR down to 0. - - ``Timer.CENTER`` - configures the timer to count from 0 to ARR and - then back down to 0. - - - ``div`` can be one of 1, 2, or 4. Divides the timer clock to determine - the sampling clock used by the digital filters. - - - ``callback`` - as per Timer.callback() - - - ``deadtime`` - specifies the amount of "dead" or inactive time between - transitions on complimentary channels (both channels will be inactive) - for this time). ``deadtime`` may be an integer between 0 and 1008, with - the following restrictions: 0-128 in steps of 1. 128-256 in steps of - 2, 256-512 in steps of 8, and 512-1008 in steps of 16. ``deadtime`` - measures ticks of ``source_freq`` divided by ``div`` clock ticks. - ``deadtime`` is only available on timers 1 and 8. - - You must either specify freq or both of period and prescaler. - -.. method:: Timer.deinit() - - Deinitialises the timer. - - .. only:: port_pyboard - - Disables the callback (and the associated irq). - - Disables any channel callbacks (and the associated irq). - Stops the timer, and disables the timer peripheral. - -.. only:: port_pyboard - - .. method:: Timer.callback(fun) - - Set the function to be called when the timer triggers. - ``fun`` is passed 1 argument, the timer object. - If ``fun`` is ``None`` then the callback will be disabled. - -.. only:: port_pyboard - - .. method:: Timer.channel(channel, mode, ...) - - If only a channel number is passed, then a previously initialized channel - object is returned (or ``None`` if there is no previous channel). - - Otherwise, a TimerChannel object is initialized and returned. - - Each channel can be configured to perform pwm, output compare, or - input capture. All channels share the same underlying timer, which means - that they share the same timer clock. - - Keyword arguments: - - - ``mode`` can be one of: - - - ``Timer.PWM`` --- configure the timer in PWM mode (active high). - - ``Timer.PWM_INVERTED`` --- configure the timer in PWM mode (active low). - - ``Timer.OC_TIMING`` --- indicates that no pin is driven. - - ``Timer.OC_ACTIVE`` --- the pin will be made active when a compare match occurs (active is determined by polarity) - - ``Timer.OC_INACTIVE`` --- the pin will be made inactive when a compare match occurs. - - ``Timer.OC_TOGGLE`` --- the pin will be toggled when an compare match occurs. - - ``Timer.OC_FORCED_ACTIVE`` --- the pin is forced active (compare match is ignored). - - ``Timer.OC_FORCED_INACTIVE`` --- the pin is forced inactive (compare match is ignored). - - ``Timer.IC`` --- configure the timer in Input Capture mode. - - ``Timer.ENC_A`` --- configure the timer in Encoder mode. The counter only changes when CH1 changes. - - ``Timer.ENC_B`` --- configure the timer in Encoder mode. The counter only changes when CH2 changes. - - ``Timer.ENC_AB`` --- configure the timer in Encoder mode. The counter changes when CH1 or CH2 changes. - - - ``callback`` - as per TimerChannel.callback() - - - ``pin`` None (the default) or a Pin object. If specified (and not None) - this will cause the alternate function of the the indicated pin - to be configured for this timer channel. An error will be raised if - the pin doesn't support any alternate functions for this timer channel. - - Keyword arguments for Timer.PWM modes: - - - ``pulse_width`` - determines the initial pulse width value to use. - - ``pulse_width_percent`` - determines the initial pulse width percentage to use. - - Keyword arguments for Timer.OC modes: - - - ``compare`` - determines the initial value of the compare register. - - - ``polarity`` can be one of: - - - ``Timer.HIGH`` - output is active high - - ``Timer.LOW`` - output is active low - - Optional keyword arguments for Timer.IC modes: - - - ``polarity`` can be one of: - - - ``Timer.RISING`` - captures on rising edge. - - ``Timer.FALLING`` - captures on falling edge. - - ``Timer.BOTH`` - captures on both edges. - - Note that capture only works on the primary channel, and not on the - complimentary channels. - - Notes for Timer.ENC modes: - - - Requires 2 pins, so one or both pins will need to be configured to use - the appropriate timer AF using the Pin API. - - Read the encoder value using the timer.counter() method. - - Only works on CH1 and CH2 (and not on CH1N or CH2N) - - The channel number is ignored when setting the encoder mode. - - PWM Example:: - - timer = pyb.Timer(2, freq=1000) - ch2 = timer.channel(2, pyb.Timer.PWM, pin=pyb.Pin.board.X2, pulse_width=8000) - ch3 = timer.channel(3, pyb.Timer.PWM, pin=pyb.Pin.board.X3, pulse_width=16000) - -.. only:: port_pyboard - - .. method:: Timer.counter([value]) - - Get or set the timer counter. - -.. only:: port_pyboard - - .. method:: Timer.freq([value]) - - Get or set the frequency for the timer (changes prescaler and period if set). - -.. only:: port_pyboard - - .. method:: Timer.period([value]) - - Get or set the period of the timer. - - .. method:: Timer.prescaler([value]) - - Get or set the prescaler for the timer. - - .. method:: Timer.source_freq() - - Get the frequency of the source of the timer. - -class TimerChannel --- setup a channel for a timer -================================================== - -Timer channels are used to generate/capture a signal using a timer. - -TimerChannel objects are created using the Timer.channel() method. - -Methods -------- - -.. only:: port_pyboard - - .. method:: timerchannel.callback(fun) - - Set the function to be called when the timer channel triggers. - ``fun`` is passed 1 argument, the timer object. - If ``fun`` is ``None`` then the callback will be disabled. - -.. only:: port_pyboard - - .. method:: timerchannel.capture([value]) - - Get or set the capture value associated with a channel. - capture, compare, and pulse_width are all aliases for the same function. - capture is the logical name to use when the channel is in input capture mode. - - .. method:: timerchannel.compare([value]) - - Get or set the compare value associated with a channel. - capture, compare, and pulse_width are all aliases for the same function. - compare is the logical name to use when the channel is in output compare mode. - - .. method:: timerchannel.pulse_width([value]) - - Get or set the pulse width value associated with a channel. - capture, compare, and pulse_width are all aliases for the same function. - pulse_width is the logical name to use when the channel is in PWM mode. - - In edge aligned mode, a pulse_width of ``period + 1`` corresponds to a duty cycle of 100% - In center aligned mode, a pulse width of ``period`` corresponds to a duty cycle of 100% - - .. method:: timerchannel.pulse_width_percent([value]) - - Get or set the pulse width percentage associated with a channel. The value - is a number between 0 and 100 and sets the percentage of the timer period - for which the pulse is active. The value can be an integer or - floating-point number for more accuracy. For example, a value of 25 gives - a duty cycle of 25%. diff --git a/docs/library/pyb.UART.rst b/docs/library/pyb.UART.rst deleted file mode 100644 index c299c838e7c..00000000000 --- a/docs/library/pyb.UART.rst +++ /dev/null @@ -1,245 +0,0 @@ -.. currentmodule:: pyb -.. _pyb.UART: - -class UART -- duplex serial communication bus -============================================= - -UART implements the standard UART/USART duplex serial communications protocol. At -the physical level it consists of 2 lines: RX and TX. The unit of communication -is a character (not to be confused with a string character) which can be 8 or 9 -bits wide. - -UART objects can be created and initialised using:: - - from pyb import UART - - uart = UART(1, 9600) # init with given baudrate - uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters - -.. only:: port_pyboard - - Bits can be 7, 8 or 9. Parity can be None, 0 (even) or 1 (odd). Stop can be 1 or 2. - - *Note:* with parity=None, only 8 and 9 bits are supported. With parity enabled, - only 7 and 8 bits are supported. - -A UART object acts like a `stream` object and reading and writing is done -using the standard stream methods:: - - uart.read(10) # read 10 characters, returns a bytes object - uart.read() # read all available characters - uart.readline() # read a line - uart.readinto(buf) # read and store into the given buffer - uart.write('abc') # write the 3 characters - -.. only:: port_pyboard - - Individual characters can be read/written using:: - - uart.readchar() # read 1 character and returns it as an integer - uart.writechar(42) # write 1 character - - To check if there is anything to be read, use:: - - uart.any() # returns the number of characters waiting - - - *Note:* The stream functions ``read``, ``write``, etc. are new in MicroPython v1.3.4. - Earlier versions use ``uart.send`` and ``uart.recv``. - -Constructors ------------- - -.. only:: port_pyboard - - .. class:: pyb.UART(bus, ...) - - Construct a UART object on the given bus. ``bus`` can be 1-6, or 'XA', 'XB', 'YA', or 'YB'. - With no additional parameters, the UART object is created but not - initialised (it has the settings from the last initialisation of - the bus, if any). If extra arguments are given, the bus is initialised. - See ``init`` for parameters of initialisation. - - The physical pins of the UART busses are: - - - ``UART(4)`` is on ``XA``: ``(TX, RX) = (X1, X2) = (PA0, PA1)`` - - ``UART(1)`` is on ``XB``: ``(TX, RX) = (X9, X10) = (PB6, PB7)`` - - ``UART(6)`` is on ``YA``: ``(TX, RX) = (Y1, Y2) = (PC6, PC7)`` - - ``UART(3)`` is on ``YB``: ``(TX, RX) = (Y9, Y10) = (PB10, PB11)`` - - ``UART(2)`` is on: ``(TX, RX) = (X3, X4) = (PA2, PA3)`` - - The Pyboard Lite supports UART(1), UART(2) and UART(6) only. Pins are as above except: - - - ``UART(2)`` is on: ``(TX, RX) = (X1, X2) = (PA2, PA3)`` - -Methods -------- - -.. only:: port_pyboard - - .. method:: UART.init(baudrate, bits=8, parity=None, stop=1, \*, timeout=1000, flow=0, timeout_char=0, read_buf_len=64) - - Initialise the UART bus with the given parameters: - - - ``baudrate`` is the clock rate. - - ``bits`` is the number of bits per character, 7, 8 or 9. - - ``parity`` is the parity, ``None``, 0 (even) or 1 (odd). - - ``stop`` is the number of stop bits, 1 or 2. - - ``flow`` sets the flow control type. Can be 0, ``UART.RTS``, ``UART.CTS`` - or ``UART.RTS | UART.CTS``. - - ``timeout`` is the timeout in milliseconds to wait for writing/reading the first character. - - ``timeout_char`` is the timeout in milliseconds to wait between characters while writing or reading. - - ``read_buf_len`` is the character length of the read buffer (0 to disable). - - This method will raise an exception if the baudrate could not be set within - 5% of the desired value. The minimum baudrate is dictated by the frequency - of the bus that the UART is on; UART(1) and UART(6) are APB2, the rest are on - APB1. The default bus frequencies give a minimum baudrate of 1300 for - UART(1) and UART(6) and 650 for the others. Use :func:`pyb.freq ` - to reduce the bus frequencies to get lower baudrates. - - *Note:* with parity=None, only 8 and 9 bits are supported. With parity enabled, - only 7 and 8 bits are supported. - -.. method:: UART.deinit() - - Turn off the UART bus. - -.. only:: port_pyboard - - .. method:: UART.any() - - Returns the number of bytes waiting (may be 0). - -.. method:: UART.read([nbytes]) - - Read characters. If ``nbytes`` is specified then read at most that many bytes. - If ``nbytes`` are available in the buffer, returns immediately, otherwise returns - when sufficient characters arrive or the timeout elapses. - - If ``nbytes`` is not given then the method reads as much data as possible. It - returns after the timeout has elapsed. - - .. only:: port_pyboard - - *Note:* for 9 bit characters each character takes two bytes, ``nbytes`` must - be even, and the number of characters is ``nbytes/2``. - - Return value: a bytes object containing the bytes read in. Returns ``None`` - on timeout. - -.. method:: UART.readchar() - - Receive a single character on the bus. - - Return value: The character read, as an integer. Returns -1 on timeout. - -.. method:: UART.readinto(buf[, nbytes]) - - Read bytes into the ``buf``. If ``nbytes`` is specified then read at most - that many bytes. Otherwise, read at most ``len(buf)`` bytes. - - Return value: number of bytes read and stored into ``buf`` or ``None`` on - timeout. - -.. method:: UART.readline() - - Read a line, ending in a newline character. If such a line exists, return is - immediate. If the timeout elapses, all available data is returned regardless - of whether a newline exists. - - Return value: the line read or ``None`` on timeout if no data is available. - -.. method:: UART.write(buf) - - .. only:: port_pyboard - - Write the buffer of bytes to the bus. If characters are 7 or 8 bits wide - then each byte is one character. If characters are 9 bits wide then two - bytes are used for each character (little endian), and ``buf`` must contain - an even number of bytes. - - Return value: number of bytes written. If a timeout occurs and no bytes - were written returns ``None``. - -.. only:: port_pyboard - - .. method:: UART.writechar(char) - - Write a single character on the bus. ``char`` is an integer to write. - Return value: ``None``. See note below if CTS flow control is used. - -.. method:: UART.sendbreak() - - Send a break condition on the bus. This drives the bus low for a duration - of 13 bits. - Return value: ``None``. - -Constants ---------- - -.. only:: port_pyboard - - .. data:: UART.RTS - .. data:: UART.CTS - - to select the flow control type. - -Flow Control ------------- - -.. only:: port_pyboard - - On Pyboards V1 and V1.1 ``UART(2)`` and ``UART(3)`` support RTS/CTS hardware flow control - using the following pins: - - - ``UART(2)`` is on: ``(TX, RX, nRTS, nCTS) = (X3, X4, X2, X1) = (PA2, PA3, PA1, PA0)`` - - ``UART(3)`` is on :``(TX, RX, nRTS, nCTS) = (Y9, Y10, Y7, Y6) = (PB10, PB11, PB14, PB13)`` - - On the Pyboard Lite only ``UART(2)`` supports flow control on these pins: - - ``(TX, RX, nRTS, nCTS) = (X1, X2, X4, X3) = (PA2, PA3, PA1, PA0)`` - - In the following paragraphs the term "target" refers to the device connected to - the UART. - - When the UART's ``init()`` method is called with ``flow`` set to one or both of - ``UART.RTS`` and ``UART.CTS`` the relevant flow control pins are configured. - ``nRTS`` is an active low output, ``nCTS`` is an active low input with pullup - enabled. To achieve flow control the Pyboard's ``nCTS`` signal should be connected - to the target's ``nRTS`` and the Pyboard's ``nRTS`` to the target's ``nCTS``. - - CTS: target controls Pyboard transmitter - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - If CTS flow control is enabled the write behaviour is as follows: - - If the Pyboard's ``UART.write(buf)`` method is called, transmission will stall for - any periods when ``nCTS`` is ``False``. This will result in a timeout if the entire - buffer was not transmitted in the timeout period. The method returns the number of - bytes written, enabling the user to write the remainder of the data if required. In - the event of a timeout, a character will remain in the UART pending ``nCTS``. The - number of bytes composing this character will be included in the return value. - - If ``UART.writechar()`` is called when ``nCTS`` is ``False`` the method will time - out unless the target asserts ``nCTS`` in time. If it times out ``OSError 116`` - will be raised. The character will be transmitted as soon as the target asserts ``nCTS``. - - RTS: Pyboard controls target's transmitter - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - If RTS flow control is enabled, behaviour is as follows: - - If buffered input is used (``read_buf_len`` > 0), incoming characters are buffered. - If the buffer becomes full, the next character to arrive will cause ``nRTS`` to go - ``False``: the target should cease transmission. ``nRTS`` will go ``True`` when - characters are read from the buffer. - - Note that the ``any()`` method returns the number of bytes in the buffer. Assume a - buffer length of ``N`` bytes. If the buffer becomes full, and another character arrives, - ``nRTS`` will be set False, and ``any()`` will return the count ``N``. When - characters are read the additional character will be placed in the buffer and will - be included in the result of a subsequent ``any()`` call. - - If buffered input is not used (``read_buf_len`` == 0) the arrival of a character will - cause ``nRTS`` to go ``False`` until the character is read. diff --git a/docs/library/pyb.USB_HID.rst b/docs/library/pyb.USB_HID.rst deleted file mode 100644 index 70270443548..00000000000 --- a/docs/library/pyb.USB_HID.rst +++ /dev/null @@ -1,40 +0,0 @@ -.. currentmodule:: pyb -.. _pyb.USB_HID: - -class USB_HID -- USB Human Interface Device (HID) -================================================= - -The USB_HID class allows creation of an object representing the USB -Human Interface Device (HID) interface. It can be used to emulate -a peripheral such as a mouse or keyboard. - -Before you can use this class, you need to use :meth:`pyb.usb_mode()` to set the USB mode to include the HID interface. - -Constructors ------------- - -.. class:: pyb.USB_HID() - - Create a new USB_HID object. - - -Methods -------- - -.. method:: USB_HID.recv(data, \*, timeout=5000) - - Receive data on the bus: - - - ``data`` can be an integer, which is the number of bytes to receive, - or a mutable buffer, which will be filled with received bytes. - - ``timeout`` is the timeout in milliseconds to wait for the receive. - - Return value: if ``data`` is an integer then a new buffer of the bytes received, - otherwise the number of bytes read into ``data`` is returned. - -.. method:: USB_HID.send(data) - - Send data over the USB HID interface: - - - ``data`` is the data to send (a tuple/list of integers, or a - bytearray). diff --git a/docs/library/pyb.USB_VCP.rst b/docs/library/pyb.USB_VCP.rst deleted file mode 100644 index 3bc6c749ced..00000000000 --- a/docs/library/pyb.USB_VCP.rst +++ /dev/null @@ -1,103 +0,0 @@ -.. currentmodule:: pyb -.. _pyb.USB_VCP: - -class USB_VCP -- USB virtual comm port -====================================== - -The USB_VCP class allows creation of a `stream`-like object representing the USB -virtual comm port. It can be used to read and write data over USB to -the connected host. - - -Constructors ------------- - -.. class:: pyb.USB_VCP() - - Create a new USB_VCP object. - - -Methods -------- - -.. method:: USB_VCP.setinterrupt(chr) - - Set the character which interrupts running Python code. This is set - to 3 (CTRL-C) by default, and when a CTRL-C character is received over - the USB VCP port, a KeyboardInterrupt exception is raised. - - Set to -1 to disable this interrupt feature. This is useful when you - want to send raw bytes over the USB VCP port. - -.. method:: USB_VCP.isconnected() - - Return ``True`` if USB is connected as a serial device, else ``False``. - -.. method:: USB_VCP.any() - - Return ``True`` if any characters waiting, else ``False``. - -.. method:: USB_VCP.close() - - This method does nothing. It exists so the USB_VCP object can act as - a file. - -.. method:: USB_VCP.read([nbytes]) - - Read at most ``nbytes`` from the serial device and return them as a - bytes object. If ``nbytes`` is not specified then the method reads - all available bytes from the serial device. - USB_VCP `stream` implicitly works in non-blocking mode, - so if no pending data available, this method will return immediately - with ``None`` value. - -.. method:: USB_VCP.readinto(buf, [maxlen]) - - Read bytes from the serial device and store them into ``buf``, which - should be a buffer-like object. At most ``len(buf)`` bytes are read. - If ``maxlen`` is given and then at most ``min(maxlen, len(buf))`` bytes - are read. - - Returns the number of bytes read and stored into ``buf`` or ``None`` - if no pending data available. - -.. method:: USB_VCP.readline() - - Read a whole line from the serial device. - - Returns a bytes object containing the data, including the trailing - newline character or ``None`` if no pending data available. - -.. method:: USB_VCP.readlines() - - Read as much data as possible from the serial device, breaking it into - lines. - - Returns a list of bytes objects, each object being one of the lines. - Each line will include the newline character. - -.. method:: USB_VCP.write(buf) - - Write the bytes from ``buf`` to the serial device. - - Returns the number of bytes written. - -.. method:: USB_VCP.recv(data, \*, timeout=5000) - - Receive data on the bus: - - - ``data`` can be an integer, which is the number of bytes to receive, - or a mutable buffer, which will be filled with received bytes. - - ``timeout`` is the timeout in milliseconds to wait for the receive. - - Return value: if ``data`` is an integer then a new buffer of the bytes received, - otherwise the number of bytes read into ``data`` is returned. - -.. method:: USB_VCP.send(data, \*, timeout=5000) - - Send data over the USB VCP: - - - ``data`` is the data to send (an integer to send, or a buffer object). - - ``timeout`` is the timeout in milliseconds to wait for the send. - - Return value: number of bytes sent. diff --git a/docs/library/pyb.rst b/docs/library/pyb.rst deleted file mode 100644 index 141c270b31e..00000000000 --- a/docs/library/pyb.rst +++ /dev/null @@ -1,322 +0,0 @@ -:mod:`pyb` --- functions related to the board -============================================= - -.. module:: pyb - :synopsis: functions related to the board - -The ``pyb`` module contains specific functions related to the board. - -Time related functions ----------------------- - -.. function:: delay(ms) - - Delay for the given number of milliseconds. - -.. function:: udelay(us) - - Delay for the given number of microseconds. - -.. function:: millis() - - Returns the number of milliseconds since the board was last reset. - - The result is always a MicroPython smallint (31-bit signed number), so - after 2^30 milliseconds (about 12.4 days) this will start to return - negative numbers. - - Note that if :meth:`pyb.stop()` is issued the hardware counter supporting this - function will pause for the duration of the "sleeping" state. This - will affect the outcome of :meth:`pyb.elapsed_millis()`. - -.. function:: micros() - - Returns the number of microseconds since the board was last reset. - - The result is always a MicroPython smallint (31-bit signed number), so - after 2^30 microseconds (about 17.8 minutes) this will start to return - negative numbers. - - Note that if :meth:`pyb.stop()` is issued the hardware counter supporting this - function will pause for the duration of the "sleeping" state. This - will affect the outcome of :meth:`pyb.elapsed_micros()`. - -.. function:: elapsed_millis(start) - - Returns the number of milliseconds which have elapsed since ``start``. - - This function takes care of counter wrap, and always returns a positive - number. This means it can be used to measure periods up to about 12.4 days. - - Example:: - - start = pyb.millis() - while pyb.elapsed_millis(start) < 1000: - # Perform some operation - -.. function:: elapsed_micros(start) - - Returns the number of microseconds which have elapsed since ``start``. - - This function takes care of counter wrap, and always returns a positive - number. This means it can be used to measure periods up to about 17.8 minutes. - - Example:: - - start = pyb.micros() - while pyb.elapsed_micros(start) < 1000: - # Perform some operation - pass - -Reset related functions ------------------------ - -.. function:: hard_reset() - - Resets the pyboard in a manner similar to pushing the external RESET - button. - -.. function:: bootloader() - - Activate the bootloader without BOOT\* pins. - -.. function:: fault_debug(value) - - Enable or disable hard-fault debugging. A hard-fault is when there is a fatal - error in the underlying system, like an invalid memory access. - - If the *value* argument is ``False`` then the board will automatically reset if - there is a hard fault. - - If *value* is ``True`` then, when the board has a hard fault, it will print the - registers and the stack trace, and then cycle the LEDs indefinitely. - - The default value is disabled, i.e. to automatically reset. - -Interrupt related functions ---------------------------- - -.. function:: disable_irq() - - Disable interrupt requests. - Returns the previous IRQ state: ``False``/``True`` for disabled/enabled IRQs - respectively. This return value can be passed to enable_irq to restore - the IRQ to its original state. - -.. function:: enable_irq(state=True) - - Enable interrupt requests. - If ``state`` is ``True`` (the default value) then IRQs are enabled. - If ``state`` is ``False`` then IRQs are disabled. The most common use of - this function is to pass it the value returned by ``disable_irq`` to - exit a critical section. - -Power related functions ------------------------ - -.. only:: port_pyboard - - .. function:: freq([sysclk[, hclk[, pclk1[, pclk2]]]]) - - If given no arguments, returns a tuple of clock frequencies: - (sysclk, hclk, pclk1, pclk2). - These correspond to: - - - sysclk: frequency of the CPU - - hclk: frequency of the AHB bus, core memory and DMA - - pclk1: frequency of the APB1 bus - - pclk2: frequency of the APB2 bus - - If given any arguments then the function sets the frequency of the CPU, - and the busses if additional arguments are given. Frequencies are given in - Hz. Eg freq(120000000) sets sysclk (the CPU frequency) to 120MHz. Note that - not all values are supported and the largest supported frequency not greater - than the given value will be selected. - - Supported sysclk frequencies are (in MHz): 8, 16, 24, 30, 32, 36, 40, 42, 48, - 54, 56, 60, 64, 72, 84, 96, 108, 120, 144, 168. - - The maximum frequency of hclk is 168MHz, of pclk1 is 42MHz, and of pclk2 is - 84MHz. Be sure not to set frequencies above these values. - - The hclk, pclk1 and pclk2 frequencies are derived from the sysclk frequency - using a prescaler (divider). Supported prescalers for hclk are: 1, 2, 4, 8, - 16, 64, 128, 256, 512. Supported prescalers for pclk1 and pclk2 are: 1, 2, - 4, 8. A prescaler will be chosen to best match the requested frequency. - - A sysclk frequency of - 8MHz uses the HSE (external crystal) directly and 16MHz uses the HSI - (internal oscillator) directly. The higher frequencies use the HSE to - drive the PLL (phase locked loop), and then use the output of the PLL. - - Note that if you change the frequency while the USB is enabled then - the USB may become unreliable. It is best to change the frequency - in boot.py, before the USB peripheral is started. Also note that sysclk - frequencies below 36MHz do not allow the USB to function correctly. - - .. function:: wfi() - - Wait for an internal or external interrupt. - - This executes a ``wfi`` instruction which reduces power consumption - of the MCU until any interrupt occurs (be it internal or external), - at which point execution continues. Note that the system-tick interrupt - occurs once every millisecond (1000Hz) so this function will block for - at most 1ms. - - .. function:: stop() - - Put the pyboard in a "sleeping" state. - - This reduces power consumption to less than 500 uA. To wake from this - sleep state requires an external interrupt or a real-time-clock event. - Upon waking execution continues where it left off. - - See :meth:`rtc.wakeup` to configure a real-time-clock wakeup event. - - .. function:: standby() - - Put the pyboard into a "deep sleep" state. - - This reduces power consumption to less than 50 uA. To wake from this - sleep state requires a real-time-clock event, or an external interrupt - on X1 (PA0=WKUP) or X18 (PC13=TAMP1). - Upon waking the system undergoes a hard reset. - - See :meth:`rtc.wakeup` to configure a real-time-clock wakeup event. - -Miscellaneous functions ------------------------ - -.. only:: port_pyboard - - .. function:: have_cdc() - - Return True if USB is connected as a serial device, False otherwise. - - .. note:: This function is deprecated. Use pyb.USB_VCP().isconnected() instead. - - .. function:: hid((buttons, x, y, z)) - - Takes a 4-tuple (or list) and sends it to the USB host (the PC) to - signal a HID mouse-motion event. - - .. note:: This function is deprecated. Use :meth:`pyb.USB_HID.send()` instead. - - .. function:: info([dump_alloc_table]) - - Print out lots of information about the board. - -.. function:: main(filename) - - Set the filename of the main script to run after boot.py is finished. If - this function is not called then the default file main.py will be executed. - - It only makes sense to call this function from within boot.py. - -.. only:: port_pyboard - - .. function:: mount(device, mountpoint, \*, readonly=False, mkfs=False) - - Mount a block device and make it available as part of the filesystem. - ``device`` must be an object that provides the block protocol: - - - ``readblocks(self, blocknum, buf)`` - - ``writeblocks(self, blocknum, buf)`` (optional) - - ``count(self)`` - - ``sync(self)`` (optional) - - ``readblocks`` and ``writeblocks`` should copy data between ``buf`` and - the block device, starting from block number ``blocknum`` on the device. - ``buf`` will be a bytearray with length a multiple of 512. If - ``writeblocks`` is not defined then the device is mounted read-only. - The return value of these two functions is ignored. - - ``count`` should return the number of blocks available on the device. - ``sync``, if implemented, should sync the data on the device. - - The parameter ``mountpoint`` is the location in the root of the filesystem - to mount the device. It must begin with a forward-slash. - - If ``readonly`` is ``True``, then the device is mounted read-only, - otherwise it is mounted read-write. - - If ``mkfs`` is ``True``, then a new filesystem is created if one does not - already exist. - - To unmount a device, pass ``None`` as the device and the mount location - as ``mountpoint``. - -.. function:: repl_uart(uart) - - Get or set the UART object where the REPL is repeated on. - -.. only:: port_pyboard - - .. function:: rng() - - Return a 30-bit hardware generated random number. - -.. function:: sync() - - Sync all file systems. - -.. only:: port_pyboard - - .. function:: unique_id() - - Returns a string of 12 bytes (96 bits), which is the unique ID of the MCU. - -.. function:: usb_mode([modestr], vid=0xf055, pid=0x9801, hid=pyb.hid_mouse) - - If called with no arguments, return the current USB mode as a string. - - If called with ``modestr`` provided, attempts to set USB mode. - This can only be done when called from ``boot.py`` before - :meth:`pyb.main()` has been called. The following values of - ``modestr`` are understood: - - - ``None``: disables USB - - ``'VCP'``: enable with VCP (Virtual COM Port) interface - - ``'MSC'``: enable with MSC (mass storage device class) interface - - ``'VCP+MSC'``: enable with VCP and MSC - - ``'VCP+HID'``: enable with VCP and HID (human interface device) - - For backwards compatibility, ``'CDC'`` is understood to mean - ``'VCP'`` (and similarly for ``'CDC+MSC'`` and ``'CDC+HID'``). - - The ``vid`` and ``pid`` parameters allow you to specify the VID - (vendor id) and PID (product id). - - If enabling HID mode, you may also specify the HID details by - passing the ``hid`` keyword parameter. It takes a tuple of - (subclass, protocol, max packet length, polling interval, report - descriptor). By default it will set appropriate values for a USB - mouse. There is also a ``pyb.hid_keyboard`` constant, which is an - appropriate tuple for a USB keyboard. - -Classes -------- - -.. only:: port_pyboard - - .. toctree:: - :maxdepth: 1 - - pyb.Accel.rst - pyb.ADC.rst - pyb.CAN.rst - pyb.DAC.rst - pyb.ExtInt.rst - pyb.I2C.rst - pyb.LCD.rst - pyb.LED.rst - pyb.Pin.rst - pyb.RTC.rst - pyb.Servo.rst - pyb.SPI.rst - pyb.Switch.rst - pyb.Timer.rst - pyb.UART.rst - pyb.USB_HID.rst - pyb.USB_VCP.rst diff --git a/docs/library/sys.rst b/docs/library/sys.rst index f2d96cb8cc8..2aa15531a31 100644 --- a/docs/library/sys.rst +++ b/docs/library/sys.rst @@ -1,10 +1,12 @@ :mod:`sys` -- system specific functions ======================================= +.. include:: ../templates/unsupported_in_circuitpython.inc + .. module:: sys :synopsis: system specific functions -|see_cpython_module| :mod:`python:sys`. +|see_cpython_module| :mod:`cpython:sys`. Functions --------- @@ -27,8 +29,7 @@ Functions ``traceback`` module in CPython. Unlike ``traceback.print_exception()``, this function takes just exception value instead of exception type, exception value, and traceback object; *file* argument should be - positional; further arguments are not supported. CPython-compatible - ``traceback`` module can be found in `micropython-lib`. + positional; further arguments are not supported. Constants --------- @@ -44,12 +45,12 @@ Constants .. data:: implementation Object with information about the current Python implementation. For - MicroPython, it has following attributes: + CircuitPython, it has following attributes: - * *name* - string "micropython" + * *name* - string "circuitpython" * *version* - tuple (major, minor, micro), e.g. (1, 7, 0) - This object is the recommended way to distinguish MicroPython from other + This object is the recommended way to distinguish CircuitPython from other Python implementations (note that it still may not exist in the very minimal ports). @@ -57,13 +58,13 @@ Constants :class: attention CPython mandates more attributes for this object, but the actual useful - bare minimum is implemented in MicroPython. + bare minimum is implemented in CircuitPython. .. data:: maxsize Maximum value which a native integer type can hold on the current platform, - or maximum value representable by MicroPython integer type, if it's smaller - than platform max value (that is the case for MicroPython ports without + or maximum value representable by CircuitPython integer type, if it's smaller + than platform max value (that is the case for CircuitPython ports without long int support). This attribute is useful for detecting "bitness" of a platform (32-bit vs @@ -95,24 +96,24 @@ Constants .. data:: platform - The platform that MicroPython is running on. For OS/RTOS ports, this is + The platform that CircuitPython is running on. For OS/RTOS ports, this is usually an identifier of the OS, e.g. ``"linux"``. For baremetal ports it - is an identifier of a board, e.g. ``"pyboard"`` for the original MicroPython - reference board. It thus can be used to distinguish one board from another. - If you need to check whether your program runs on MicroPython (vs other + is an identifier of the chip on a board, e.g. ``"MicroChip SAMD51"``. + It thus can be used to distinguish one board from another. + If you need to check whether your program runs on CircuitPython (vs other Python implementation), use `sys.implementation` instead. .. data:: stderr - Standard error `stream`. + Standard error ``stream``. .. data:: stdin - Standard input `stream`. + Standard input ``stream``. .. data:: stdout - Standard output `stream`. + Standard output ``stream``. .. data:: version diff --git a/docs/library/ubinascii.rst b/docs/library/ubinascii.rst deleted file mode 100644 index 192d34514b3..00000000000 --- a/docs/library/ubinascii.rst +++ /dev/null @@ -1,40 +0,0 @@ -:mod:`ubinascii` -- binary/ASCII conversions -============================================ - -.. module:: ubinascii - :synopsis: binary/ASCII conversions - -|see_cpython_module| :mod:`python:binascii`. - -This module implements conversions between binary data and various -encodings of it in ASCII form (in both directions). - -Functions ---------- - -.. function:: hexlify(data, [sep]) - - Convert binary data to hexadecimal representation. Returns bytes string. - - .. admonition:: Difference to CPython - :class: attention - - If additional argument, *sep* is supplied, it is used as a separator - between hexadecimal values. - -.. function:: unhexlify(data) - - Convert hexadecimal data to binary representation. Returns bytes string. - (i.e. inverse of hexlify) - -.. function:: a2b_base64(data) - - Decode base64-encoded data, ignoring invalid characters in the input. - Conforms to `RFC 2045 s.6.8 `_. - Returns a bytes object. - -.. function:: b2a_base64(data) - - Encode binary data in base64 format, as in `RFC 3548 - `_. Returns the encoded data - followed by a newline character, as a bytes object. diff --git a/docs/library/ucollections.rst b/docs/library/ucollections.rst deleted file mode 100644 index 96de67acc47..00000000000 --- a/docs/library/ucollections.rst +++ /dev/null @@ -1,55 +0,0 @@ -:mod:`ucollections` -- collection and container types -===================================================== - -.. module:: ucollections - :synopsis: collection and container types - -|see_cpython_module| :mod:`python:collections`. - -This module implements advanced collection and container types to -hold/accumulate various objects. - -Classes -------- - -.. function:: namedtuple(name, fields) - - This is factory function to create a new namedtuple type with a specific - name and set of fields. A namedtuple is a subclass of tuple which allows - to access its fields not just by numeric index, but also with an attribute - access syntax using symbolic field names. Fields is a sequence of strings - specifying field names. For compatibility with CPython it can also be a - a string with space-separated field named (but this is less efficient). - Example of use:: - - from ucollections import namedtuple - - MyTuple = namedtuple("MyTuple", ("id", "name")) - t1 = MyTuple(1, "foo") - t2 = MyTuple(2, "bar") - print(t1.name) - assert t2.name == t2[1] - -.. function:: OrderedDict(...) - - ``dict`` type subclass which remembers and preserves the order of keys - added. When ordered dict is iterated over, keys/items are returned in - the order they were added:: - - from ucollections import OrderedDict - - # To make benefit of ordered keys, OrderedDict should be initialized - # from sequence of (key, value) pairs. - d = OrderedDict([("z", 1), ("a", 2)]) - # More items can be added as usual - d["w"] = 5 - d["b"] = 3 - for k, v in d.items(): - print(k, v) - - Output:: - - z 1 - a 2 - w 5 - b 3 diff --git a/docs/library/uctypes.rst b/docs/library/uctypes.rst index c938d74a8ef..f71b00c1e46 100644 --- a/docs/library/uctypes.rst +++ b/docs/library/uctypes.rst @@ -1,6 +1,8 @@ :mod:`uctypes` -- access binary data in a structured way ======================================================== +.. include:: ../templates/unsupported_in_circuitpython.inc + .. module:: uctypes :synopsis: access binary data in a structured way @@ -13,7 +15,7 @@ sub-fields. .. seealso:: - Module :mod:`ustruct` + Module :mod:`struct` Standard Python way to access binary data structures (doesn't scale well to large and complex structures). diff --git a/docs/library/uerrno.rst b/docs/library/uerrno.rst index e336eb5c5c8..72f71f0aacd 100644 --- a/docs/library/uerrno.rst +++ b/docs/library/uerrno.rst @@ -1,13 +1,14 @@ :mod:`uerrno` -- system error codes =================================== +.. include:: ../templates/unsupported_in_circuitpython.inc + .. module:: uerrno :synopsis: system error codes -|see_cpython_module| :mod:`python:errno`. +|see_cpython_module| :mod:`cpython:errno`. This module provides access to symbolic error codes for `OSError` exception. -A particular inventory of codes depends on `MicroPython port`. Constants --------- @@ -15,12 +16,11 @@ Constants .. data:: EEXIST, EAGAIN, etc. Error codes, based on ANSI C/POSIX standard. All error codes start with - "E". As mentioned above, inventory of the codes depends on - `MicroPython port`. Errors are usually accessible as ``exc.args[0]`` + "E". Errors are usually accessible as ``exc.args[0]`` where ``exc`` is an instance of `OSError`. Usage example:: try: - uos.mkdir("my_dir") + os.mkdir("my_dir") except OSError as exc: if exc.args[0] == uerrno.EEXIST: print("Directory already exists") diff --git a/docs/library/uhashlib.rst b/docs/library/uhashlib.rst deleted file mode 100644 index 50ed658cc10..00000000000 --- a/docs/library/uhashlib.rst +++ /dev/null @@ -1,57 +0,0 @@ -:mod:`uhashlib` -- hashing algorithms -===================================== - -.. module:: uhashlib - :synopsis: hashing algorithms - -|see_cpython_module| :mod:`python:hashlib`. - -This module implements binary data hashing algorithms. The exact inventory -of available algorithms depends on a board. Among the algorithms which may -be implemented: - -* SHA256 - The current generation, modern hashing algorithm (of SHA2 series). - It is suitable for cryptographically-secure purposes. Included in the - MicroPython core and any board is recommended to provide this, unless - it has particular code size constraints. - -* SHA1 - A previous generation algorithm. Not recommended for new usages, - but SHA1 is a part of number of Internet standards and existing - applications, so boards targeting network connectivity and - interoperatiability will try to provide this. - -* MD5 - A legacy algorithm, not considered cryptographically secure. Only - selected boards, targeting interoperatibility with legacy applications, - will offer this. - -Constructors ------------- - -.. class:: uhashlib.sha256([data]) - - Create an SHA256 hasher object and optionally feed ``data`` into it. - -.. class:: uhashlib.sha1([data]) - - Create an SHA1 hasher object and optionally feed ``data`` into it. - -.. class:: uhashlib.md5([data]) - - Create an MD5 hasher object and optionally feed ``data`` into it. - -Methods -------- - -.. method:: hash.update(data) - - Feed more binary data into hash. - -.. method:: hash.digest() - - Return hash for all data passed through hash, as a bytes object. After this - method is called, more data cannot be fed into the hash any longer. - -.. method:: hash.hexdigest() - - This method is NOT implemented. Use ``ubinascii.hexlify(hash.digest())`` - to achieve a similar effect. diff --git a/docs/library/uheapq.rst b/docs/library/uheapq.rst index f822f1e7f32..67da5f73805 100644 --- a/docs/library/uheapq.rst +++ b/docs/library/uheapq.rst @@ -1,10 +1,12 @@ :mod:`uheapq` -- heap queue algorithm ===================================== +.. include:: ../templates/unsupported_in_circuitpython.inc + .. module:: uheapq :synopsis: heap queue algorithm -|see_cpython_module| :mod:`python:heapq`. +|see_cpython_module| :mod:`cpython:heapq`. This module implements the heap queue algorithm. diff --git a/docs/library/uio.rst b/docs/library/uio.rst index 81420702dcb..d1f7c111fa5 100644 --- a/docs/library/uio.rst +++ b/docs/library/uio.rst @@ -1,12 +1,14 @@ :mod:`uio` -- input/output streams ================================== +.. include:: ../templates/unsupported_in_circuitpython.inc + .. module:: uio :synopsis: input/output streams -|see_cpython_module| :mod:`python:io`. +|see_cpython_module| :mod:`cpython:io`. -This module contains additional types of `stream` (file-like) objects +This module contains additional types of ``stream`` (file-like) objects and helper functions. Conceptual hierarchy @@ -81,7 +83,7 @@ Functions Open a file. Builtin ``open()`` function is aliased to this function. All ports (which provide access to file system) are required to support - *mode* parameter, but support for other arguments vary by port. + ``mode`` parameter, but support for other arguments vary by port. Classes ------- @@ -103,7 +105,7 @@ Classes text-mode I/O (similar to a normal file opened with "t" modifier). `BytesIO` is used for binary-mode I/O (similar to a normal file opened with "b" modifier). Initial contents of file-like objects - can be specified with *string* parameter (should be normal string + can be specified with `string` parameter (should be normal string for `StringIO` or bytes object for `BytesIO`). All the usual file methods like ``read()``, ``write()``, ``seek()``, ``flush()``, ``close()`` are available on these objects, and additionally, a diff --git a/docs/library/ujson.rst b/docs/library/ujson.rst index 5668eb21a80..4ed91f053a1 100644 --- a/docs/library/ujson.rst +++ b/docs/library/ujson.rst @@ -1,10 +1,12 @@ :mod:`ujson` -- JSON encoding and decoding ========================================== +.. include:: ../templates/unsupported_in_circuitpython.inc + .. module:: ujson :synopsis: JSON encoding and decoding -|see_cpython_module| :mod:`python:json`. +|see_cpython_module| :mod:`cpython:json`. This modules allows to convert between Python objects and the JSON data format. @@ -14,20 +16,20 @@ Functions .. function:: dump(obj, stream) - Serialise *obj* to a JSON string, writing it to the given *stream*. + Serialise ``obj`` to a JSON string, writing it to the given *stream*. .. function:: dumps(obj) - Return *obj* represented as a JSON string. + Return ``obj`` represented as a JSON string. .. function:: load(stream) - Parse the given *stream*, interpreting it as a JSON string and + Parse the given ``stream``, interpreting it as a JSON string and deserialising the data to a Python object. The resulting object is returned. Parsing continues until end-of-file is encountered. - A :exc:`ValueError` is raised if the data in *stream* is not correctly formed. + A :exc:`ValueError` is raised if the data in ``stream`` is not correctly formed. .. function:: loads(str) diff --git a/docs/library/uos.rst b/docs/library/uos.rst deleted file mode 100644 index 27f339bb16f..00000000000 --- a/docs/library/uos.rst +++ /dev/null @@ -1,249 +0,0 @@ -:mod:`uos` -- basic "operating system" services -=============================================== - -.. module:: uos - :synopsis: basic "operating system" services - -|see_cpython_module| :mod:`python:os`. - -The ``uos`` module contains functions for filesystem access and mounting, -terminal redirection and duplication, and the ``uname`` and ``urandom`` -functions. - -General functions ------------------ - -.. function:: uname() - - Return a tuple (possibly a named tuple) containing information about the - underlying machine and/or its operating system. The tuple has five fields - in the following order, each of them being a string: - - * ``sysname`` -- the name of the underlying system - * ``nodename`` -- the network name (can be the same as ``sysname``) - * ``release`` -- the version of the underlying system - * ``version`` -- the MicroPython version and build date - * ``machine`` -- an identifier for the underlying hardware (eg board, CPU) - -.. function:: urandom(n) - - Return a bytes object with *n* random bytes. Whenever possible, it is - generated by the hardware random number generator. - -Filesystem access ------------------ - -.. function:: chdir(path) - - Change current directory. - -.. function:: getcwd() - - Get the current directory. - -.. function:: ilistdir([dir]) - - This function returns an iterator which then yields tuples corresponding to - the entries in the directory that it is listing. With no argument it lists the - current directory, otherwise it lists the directory given by *dir*. - - The tuples have the form *(name, type, inode[, size])*: - - - *name* is a string (or bytes if *dir* is a bytes object) and is the name of - the entry; - - *type* is an integer that specifies the type of the entry, with 0x4000 for - directories and 0x8000 for regular files; - - *inode* is an integer corresponding to the inode of the file, and may be 0 - for filesystems that don't have such a notion. - - Some platforms may return a 4-tuple that includes the entry's *size*. For - file entries, *size* is an integer representing the size of the file - or -1 if unknown. Its meaning is currently undefined for directory - entries. - -.. function:: listdir([dir]) - - With no argument, list the current directory. Otherwise list the given directory. - -.. function:: mkdir(path) - - Create a new directory. - -.. function:: remove(path) - - Remove a file. - -.. function:: rmdir(path) - - Remove a directory. - -.. function:: rename(old_path, new_path) - - Rename a file. - -.. function:: stat(path) - - Get the status of a file or directory. - -.. function:: statvfs(path) - - Get the status of a fileystem. - - Returns a tuple with the filesystem information in the following order: - - * ``f_bsize`` -- file system block size - * ``f_frsize`` -- fragment size - * ``f_blocks`` -- size of fs in f_frsize units - * ``f_bfree`` -- number of free blocks - * ``f_bavail`` -- number of free blocks for unpriviliged users - * ``f_files`` -- number of inodes - * ``f_ffree`` -- number of free inodes - * ``f_favail`` -- number of free inodes for unpriviliged users - * ``f_flag`` -- mount flags - * ``f_namemax`` -- maximum filename length - - Parameters related to inodes: ``f_files``, ``f_ffree``, ``f_avail`` - and the ``f_flags`` parameter may return ``0`` as they can be unavailable - in a port-specific implementation. - -.. function:: sync() - - Sync all filesystems. - -Terminal redirection and duplication ------------------------------------- - -.. function:: dupterm(stream_object, index=0) - - Duplicate or switch the MicroPython terminal (the REPL) on the given `stream`-like - object. The *stream_object* argument must implement the ``readinto()`` and - ``write()`` methods. The stream should be in non-blocking mode and - ``readinto()`` should return ``None`` if there is no data available for reading. - - After calling this function all terminal output is repeated on this stream, - and any input that is available on the stream is passed on to the terminal input. - - The *index* parameter should be a non-negative integer and specifies which - duplication slot is set. A given port may implement more than one slot (slot 0 - will always be available) and in that case terminal input and output is - duplicated on all the slots that are set. - - If ``None`` is passed as the *stream_object* then duplication is cancelled on - the slot given by *index*. - - The function returns the previous stream-like object in the given slot. - -Filesystem mounting -------------------- - -Some ports provide a Virtual Filesystem (VFS) and the ability to mount multiple -"real" filesystems within this VFS. Filesystem objects can be mounted at either -the root of the VFS, or at a subdirectory that lives in the root. This allows -dynamic and flexible configuration of the filesystem that is seen by Python -programs. Ports that have this functionality provide the :func:`mount` and -:func:`umount` functions, and possibly various filesystem implementations -represented by VFS classes. - -.. function:: mount(fsobj, mount_point, \*, readonly) - - Mount the filesystem object *fsobj* at the location in the VFS given by the - *mount_point* string. *fsobj* can be a a VFS object that has a ``mount()`` - method, or a block device. If it's a block device then the filesystem type - is automatically detected (an exception is raised if no filesystem was - recognised). *mount_point* may be ``'/'`` to mount *fsobj* at the root, - or ``'/'`` to mount it at a subdirectory under the root. - - If *readonly* is ``True`` then the filesystem is mounted read-only. - - During the mount process the method ``mount()`` is called on the filesystem - object. - - Will raise ``OSError(EPERM)`` if *mount_point* is already mounted. - -.. function:: umount(mount_point) - - Unmount a filesystem. *mount_point* can be a string naming the mount location, - or a previously-mounted filesystem object. During the unmount process the - method ``umount()`` is called on the filesystem object. - - Will raise ``OSError(EINVAL)`` if *mount_point* is not found. - -.. class:: VfsFat(block_dev) - - Create a filesystem object that uses the FAT filesystem format. Storage of - the FAT filesystem is provided by *block_dev*. - Objects created by this constructor can be mounted using :func:`mount`. - - .. staticmethod:: mkfs(block_dev) - - Build a FAT filesystem on *block_dev*. - -Block devices -------------- - -A block device is an object which implements the block protocol, which is a set -of methods described below by the :class:`AbstractBlockDev` class. A concrete -implementation of this class will usually allow access to the memory-like -functionality a piece of hardware (like flash memory). A block device can be -used by a particular filesystem driver to store the data for its filesystem. - -.. class:: AbstractBlockDev(...) - - Construct a block device object. The parameters to the constructor are - dependent on the specific block device. - - .. method:: readblocks(block_num, buf) - - Starting at *block_num*, read blocks from the device into *buf* (an array - of bytes). The number of blocks to read is given by the length of *buf*, - which will be a multiple of the block size. - - .. method:: writeblocks(block_num, buf) - - Starting at *block_num*, write blocks from *buf* (an array of bytes) to - the device. The number of blocks to write is given by the length of *buf*, - which will be a multiple of the block size. - - .. method:: ioctl(op, arg) - - Control the block device and query its parameters. The operation to - perform is given by *op* which is one of the following integers: - - - 1 -- initialise the device (*arg* is unused) - - 2 -- shutdown the device (*arg* is unused) - - 3 -- sync the device (*arg* is unused) - - 4 -- get a count of the number of blocks, should return an integer - (*arg* is unused) - - 5 -- get the number of bytes in a block, should return an integer, - or ``None`` in which case the default value of 512 is used - (*arg* is unused) - -By way of example, the following class will implement a block device that stores -its data in RAM using a ``bytearray``:: - - class RAMBlockDev: - def __init__(self, block_size, num_blocks): - self.block_size = block_size - self.data = bytearray(block_size * num_blocks) - - def readblocks(self, block_num, buf): - for i in range(len(buf)): - buf[i] = self.data[block_num * self.block_size + i] - - def writeblocks(self, block_num, buf): - for i in range(len(buf)): - self.data[block_num * self.block_size + i] = buf[i] - - def ioctl(self, op, arg): - if op == 4: # get number of blocks - return len(self.data) // self.block_size - if op == 5: # get block size - return self.block_size - -It can be used as follows:: - - import uos - - bdev = RAMBlockDev(512, 50) - uos.VfsFat.mkfs(bdev) - vfs = uos.VfsFat(bdev) - uos.mount(vfs, '/ramdisk') diff --git a/docs/library/ure.rst b/docs/library/ure.rst index f54614f0481..4af182b0168 100644 --- a/docs/library/ure.rst +++ b/docs/library/ure.rst @@ -1,10 +1,12 @@ :mod:`ure` -- simple regular expressions ======================================== +.. include:: ../templates/unsupported_in_circuitpython.inc + .. module:: ure :synopsis: regular expressions -|see_cpython_module| :mod:`python:re`. +|see_cpython_module| :mod:`cpython:re`. This module implements regular expression operations. Regular expression syntax supported is a subset of CPython ``re`` module (and actually is @@ -67,7 +69,6 @@ Functions .. data:: DEBUG Flag value, display debug information about compiled expression. - (Availability depends on `MicroPython port`.) .. _regex: diff --git a/docs/library/uselect.rst b/docs/library/uselect.rst index 77d4584731a..a2b408b2060 100644 --- a/docs/library/uselect.rst +++ b/docs/library/uselect.rst @@ -1,13 +1,15 @@ :mod:`uselect` -- wait for events on a set of streams ======================================================================== +.. include:: ../templates/unsupported_in_circuitpython.inc + .. module:: uselect :synopsis: wait for events on a set of streams -|see_cpython_module| :mod:`python:select`. +|see_cpython_module| :mod:`cpython:select`. This module provides functions to efficiently wait for events on multiple -`streams ` (select streams which are ready for operations). +``stream`` objects (select streams which are ready for operations). Functions --------- @@ -33,7 +35,7 @@ Methods .. method:: poll.register(obj[, eventmask]) - Register `stream` *obj* for polling. *eventmask* is logical OR of: + Register ``stream`` *obj* for polling. *eventmask* is logical OR of: * ``uselect.POLLIN`` - data available for reading * ``uselect.POLLOUT`` - more data can be written @@ -79,7 +81,7 @@ Methods .. method:: poll.ipoll(timeout=-1, flags=0) Like :meth:`poll.poll`, but instead returns an iterator which yields a - `callee-owned tuple`. This function provides an efficient, allocation-free + ``callee-owned tuples``. This function provides efficient, allocation-free way to poll on streams. If *flags* is 1, one-shot behavior for events is employed: streams for diff --git a/docs/library/usocket.rst b/docs/library/usocket.rst index 3ae477a9ac5..2115085a311 100644 --- a/docs/library/usocket.rst +++ b/docs/library/usocket.rst @@ -2,17 +2,19 @@ :mod:`usocket` -- socket module ******************************* +.. include:: ../templates/unsupported_in_circuitpython.inc + .. module:: usocket :synopsis: socket module -|see_cpython_module| :mod:`python:socket`. +|see_cpython_module| :mod:`cpython:socket`. This module provides access to the BSD socket interface. .. admonition:: Difference to CPython :class: attention - For efficiency and consistency, socket objects in MicroPython implement a `stream` + For efficiency and consistency, socket objects in MicroPython implement a ``stream`` (file-like) interface directly. In CPython, you need to convert a socket to a file-like object using `makefile()` method. This method is still supported by MicroPython (but is a no-op), so where compatibility with CPython matters, @@ -36,11 +38,7 @@ power) and portable way to work with addresses. However, ``socket`` module (note the difference with native MicroPython ``usocket`` module described here) provides CPython-compatible way to specify -addresses using tuples, as described below. Note that depending on a -`MicroPython port`, ``socket`` module can be builtin or need to be -installed from `micropython-lib` (as in the case of `MicroPython Unix port`), -and some ports still accept only numeric addresses in the tuple format, -and require to use `getaddrinfo` function to resolve domain names. +addresses using tuples, as described below. Summing up: @@ -60,8 +58,7 @@ Tuple address format for ``socket`` module: and *port* is an integer port number in the range 1-65535. *flowinfo* must be 0. *scopeid* is the interface scope identifier for link-local addresses. Note the domain names are not accepted as *ipv6_address*, - they should be resolved first using `usocket.getaddrinfo()`. Availability - of IPv6 support depends on a `MicroPython port`. + they should be resolved first using `usocket.getaddrinfo()`. Functions --------- @@ -81,8 +78,8 @@ Functions .. function:: getaddrinfo(host, port) - Translate the host/port argument into a sequence of 5-tuples that contain all the - necessary arguments for creating a socket connected to that service. The list of + Translate the host/port argument into a sequence of 5-tuples that contain all the + necessary arguments for creating a socket connected to that service. The list of 5-tuples has following structure:: (family, type, proto, canonname, sockaddr) @@ -99,7 +96,7 @@ Functions of error in this function. MicroPython doesn't have ``socket.gaierror`` and raises OSError directly. Note that error numbers of `getaddrinfo()` form a separate namespace and may not match error numbers from - the :mod:`uerrno` module. To distinguish `getaddrinfo()` errors, they are + :py:mod:`uerrno` module. To distinguish `getaddrinfo()` errors, they are represented by negative numbers, whereas standard system errors are positive numbers (error numbers are accessible using ``e.args[0]`` property from an exception object). The use of negative values is a provisional @@ -127,7 +124,7 @@ Constants .. data:: AF_INET AF_INET6 - Address family types. Availability depends on a particular `MicroPython port`. + Address family types. Availability depends on a particular ``MicroPython port``. .. data:: SOCK_STREAM SOCK_DGRAM @@ -137,21 +134,21 @@ Constants .. data:: IPPROTO_UDP IPPROTO_TCP - IP protocol numbers. Availability depends on a particular `MicroPython port`. + IP protocol numbers. Availability depends on a particular ``MicroPython port``. Note that you don't need to specify these in a call to `usocket.socket()`, because `SOCK_STREAM` socket type automatically selects `IPPROTO_TCP`, and `SOCK_DGRAM` - `IPPROTO_UDP`. Thus, the only real use of these constants - is as an argument to `setsockopt()`. + is as an argument to `usocket.socket.setsockopt()`. .. data:: usocket.SOL_* - Socket option levels (an argument to `setsockopt()`). The exact - inventory depends on a `MicroPython port`. + Socket option levels (an argument to `usocket.socket.setsockopt()`). The exact + inventory depends on a ``MicroPython port``. .. data:: usocket.SO_* - Socket options (an argument to `setsockopt()`). The exact - inventory depends on a `MicroPython port`. + Socket options (an argument to `usocket.socket.setsockopt()`). The exact + inventory depends on a ``MicroPython port``. Constants specific to WiPy: @@ -171,7 +168,7 @@ Methods on the socket object will fail. The remote end will receive EOF indication if supported by protocol. - Sockets are automatically closed when they are garbage-collected, but it is recommended + Sockets are automatically closed when they are garbage-collected, but it is recommended to `close()` them explicitly as soon you finished working with them. .. method:: socket.bind(address) @@ -245,10 +242,10 @@ Methods completed. If zero is given, the socket is put in non-blocking mode. If None is given, the socket is put in blocking mode. - Not every `MicroPython port` supports this method. A more portable and + Not every ``MicroPython port`` supports this method. A more portable and generic solution is to use `uselect.poll` object. This allows to wait on multiple objects at the same time (and not just on sockets, but on generic - `stream` objects which support polling). Example:: + ``stream`` objects which support polling). Example:: # Instead of: s.settimeout(1.0) # time in seconds diff --git a/docs/library/ussl.rst b/docs/library/ussl.rst index be84dc05450..91a64b025fc 100644 --- a/docs/library/ussl.rst +++ b/docs/library/ussl.rst @@ -1,10 +1,12 @@ :mod:`ussl` -- SSL/TLS module ============================= +.. include:: ../templates/unsupported_in_circuitpython.inc + .. module:: ussl :synopsis: TLS/SSL wrapper for socket objects -|see_cpython_module| :mod:`python:ssl`. +|see_cpython_module| :mod:`cpython:ssl`. This module provides access to Transport Layer Security (previously and widely known as “Secure Sockets Layerâ€) encryption and peer authentication @@ -15,16 +17,16 @@ Functions .. function:: ussl.wrap_socket(sock, server_side=False, keyfile=None, certfile=None, cert_reqs=CERT_NONE, ca_certs=None) - Takes a `stream` *sock* (usually usocket.socket instance of ``SOCK_STREAM`` type), + Takes a ``stream`` *sock* (usually usocket.socket instance of ``SOCK_STREAM`` type), and returns an instance of ssl.SSLSocket, which wraps the underlying stream in - an SSL context. Returned object has the usual `stream` interface methods like + an SSL context. Returned object has the usual ``stream`` interface methods like ``read()``, ``write()``, etc. In MicroPython, the returned object does not expose socket interface and methods like ``recv()``, ``send()``. In particular, a server-side SSL socket should be created from a normal socket returned from :meth:`~usocket.socket.accept()` on a non-SSL listening server socket. Depending on the underlying module implementation in a particular - `MicroPython port`, some or all keyword arguments above may be not supported. + ``MicroPython port``, some or all keyword arguments above may be not supported. .. warning:: diff --git a/docs/library/ustruct.rst b/docs/library/ustruct.rst deleted file mode 100644 index 81915d0a8d0..00000000000 --- a/docs/library/ustruct.rst +++ /dev/null @@ -1,42 +0,0 @@ -:mod:`ustruct` -- pack and unpack primitive data types -====================================================== - -.. module:: ustruct - :synopsis: pack and unpack primitive data types - -|see_cpython_module| :mod:`python:struct`. - -Supported size/byte order prefixes: ``@``, ``<``, ``>``, ``!``. - -Supported format codes: ``b``, ``B``, ``h``, ``H``, ``i``, ``I``, ``l``, -``L``, ``q``, ``Q``, ``s``, ``P``, ``f``, ``d`` (the latter 2 depending -on the floating-point support). - -Functions ---------- - -.. function:: calcsize(fmt) - - Return the number of bytes needed to store the given *fmt*. - -.. function:: pack(fmt, v1, v2, ...) - - Pack the values *v1*, *v2*, ... according to the format string *fmt*. - The return value is a bytes object encoding the values. - -.. function:: pack_into(fmt, buffer, offset, v1, v2, ...) - - Pack the values *v1*, *v2*, ... according to the format string *fmt* - into a *buffer* starting at *offset*. *offset* may be negative to count - from the end of *buffer*. - -.. function:: unpack(fmt, data) - - Unpack from the *data* according to the format string *fmt*. - The return value is a tuple of the unpacked values. - -.. function:: unpack_from(fmt, data, offset=0) - - Unpack from the *data* starting at *offset* according to the format string - *fmt*. *offset* may be negative to count from the end of *buffer*. The return - value is a tuple of the unpacked values. diff --git a/docs/library/utime.rst b/docs/library/utime.rst deleted file mode 100644 index 7fe83f5abe0..00000000000 --- a/docs/library/utime.rst +++ /dev/null @@ -1,229 +0,0 @@ -:mod:`utime` -- time related functions -====================================== - -.. module:: utime - :synopsis: time related functions - -|see_cpython_module| :mod:`python:time`. - -The ``utime`` module provides functions for getting the current time and date, -measuring time intervals, and for delays. - -**Time Epoch**: Unix port uses standard for POSIX systems epoch of -1970-01-01 00:00:00 UTC. However, embedded ports use epoch of -2000-01-01 00:00:00 UTC. - -**Maintaining actual calendar date/time**: This requires a -Real Time Clock (RTC). On systems with underlying OS (including some -RTOS), an RTC may be implicit. Setting and maintaining actual calendar -time is responsibility of OS/RTOS and is done outside of MicroPython, -it just uses OS API to query date/time. On baremetal ports however -system time depends on ``machine.RTC()`` object. The current calendar time -may be set using ``machine.RTC().datetime(tuple)`` function, and maintained -by following means: - -* By a backup battery (which may be an additional, optional component for - a particular board). -* Using networked time protocol (requires setup by a port/user). -* Set manually by a user on each power-up (many boards then maintain - RTC time across hard resets, though some may require setting it again - in such case). - -If actual calendar time is not maintained with a system/MicroPython RTC, -functions below which require reference to current absolute time may -behave not as expected. - -Functions ---------- - -.. function:: localtime([secs]) - - Convert a time expressed in seconds since the Epoch (see above) into an 8-tuple which - contains: (year, month, mday, hour, minute, second, weekday, yearday) - If secs is not provided or None, then the current time from the RTC is used. - - * year includes the century (for example 2014). - * month is 1-12 - * mday is 1-31 - * hour is 0-23 - * minute is 0-59 - * second is 0-59 - * weekday is 0-6 for Mon-Sun - * yearday is 1-366 - -.. function:: mktime() - - This is inverse function of localtime. It's argument is a full 8-tuple - which expresses a time as per localtime. It returns an integer which is - the number of seconds since Jan 1, 2000. - -.. function:: sleep(seconds) - - Sleep for the given number of seconds. Some boards may accept *seconds* as a - floating-point number to sleep for a fractional number of seconds. Note that - other boards may not accept a floating-point argument, for compatibility with - them use `sleep_ms()` and `sleep_us()` functions. - -.. function:: sleep_ms(ms) - - Delay for given number of milliseconds, should be positive or 0. - -.. function:: sleep_us(us) - - Delay for given number of microseconds, should be positive or 0. - -.. function:: ticks_ms() - - Returns an increasing millisecond counter with an arbitrary reference point, that - wraps around after some value. - - The wrap-around value is not explicitly exposed, but we will - refer to it as *TICKS_MAX* to simplify discussion. Period of the values is - *TICKS_PERIOD = TICKS_MAX + 1*. *TICKS_PERIOD* is guaranteed to be a power of - two, but otherwise may differ from port to port. The same period value is used - for all of `ticks_ms()`, `ticks_us()`, `ticks_cpu()` functions (for - simplicity). Thus, these functions will return a value in range [*0* .. - *TICKS_MAX*], inclusive, total *TICKS_PERIOD* values. Note that only - non-negative values are used. For the most part, you should treat values returned - by these functions as opaque. The only operations available for them are - `ticks_diff()` and `ticks_add()` functions described below. - - Note: Performing standard mathematical operations (+, -) or relational - operators (<, <=, >, >=) directly on these value will lead to invalid - result. Performing mathematical operations and then passing their results - as arguments to `ticks_diff()` or `ticks_add()` will also lead to - invalid results from the latter functions. - -.. function:: ticks_us() - - Just like `ticks_ms()` above, but in microseconds. - -.. function:: ticks_cpu() - - Similar to `ticks_ms()` and `ticks_us()`, but with the highest possible resolution - in the system. This is usually CPU clocks, and that's why the function is named that - way. But it doesn't have to be a CPU clock, some other timing source available in a - system (e.g. high-resolution timer) can be used instead. The exact timing unit - (resolution) of this function is not specified on ``utime`` module level, but - documentation for a specific port may provide more specific information. This - function is intended for very fine benchmarking or very tight real-time loops. - Avoid using it in portable code. - - Availability: Not every port implements this function. - - -.. function:: ticks_add(ticks, delta) - - Offset ticks value by a given number, which can be either positive or negative. - Given a *ticks* value, this function allows to calculate ticks value *delta* - ticks before or after it, following modular-arithmetic definition of tick values - (see `ticks_ms()` above). *ticks* parameter must be a direct result of call - to `ticks_ms()`, `ticks_us()`, or `ticks_cpu()` functions (or from previous - call to `ticks_add()`). However, *delta* can be an arbitrary integer number - or numeric expression. `ticks_add()` is useful for calculating deadlines for - events/tasks. (Note: you must use `ticks_diff()` function to work with - deadlines.) - - Examples:: - - # Find out what ticks value there was 100ms ago - print(ticks_add(time.ticks_ms(), -100)) - - # Calculate deadline for operation and test for it - deadline = ticks_add(time.ticks_ms(), 200) - while ticks_diff(deadline, time.ticks_ms()) > 0: - do_a_little_of_something() - - # Find out TICKS_MAX used by this port - print(ticks_add(0, -1)) - - -.. function:: ticks_diff(ticks1, ticks2) - - Measure ticks difference between values returned from `ticks_ms()`, `ticks_us()`, - or `ticks_cpu()` functions, as a signed value which may wrap around. - - The argument order is the same as for subtraction - operator, ``ticks_diff(ticks1, ticks2)`` has the same meaning as ``ticks1 - ticks2``. - However, values returned by `ticks_ms()`, etc. functions may wrap around, so - directly using subtraction on them will produce incorrect result. That is why - `ticks_diff()` is needed, it implements modular (or more specifically, ring) - arithmetics to produce correct result even for wrap-around values (as long as they not - too distant inbetween, see below). The function returns **signed** value in the range - [*-TICKS_PERIOD/2* .. *TICKS_PERIOD/2-1*] (that's a typical range definition for - two's-complement signed binary integers). If the result is negative, it means that - *ticks1* occurred earlier in time than *ticks2*. Otherwise, it means that - *ticks1* occurred after *ticks2*. This holds **only** if *ticks1* and *ticks2* - are apart from each other for no more than *TICKS_PERIOD/2-1* ticks. If that does - not hold, incorrect result will be returned. Specifically, if two tick values are - apart for *TICKS_PERIOD/2-1* ticks, that value will be returned by the function. - However, if *TICKS_PERIOD/2* of real-time ticks has passed between them, the - function will return *-TICKS_PERIOD/2* instead, i.e. result value will wrap around - to the negative range of possible values. - - Informal rationale of the constraints above: Suppose you are locked in a room with no - means to monitor passing of time except a standard 12-notch clock. Then if you look at - dial-plate now, and don't look again for another 13 hours (e.g., if you fall for a - long sleep), then once you finally look again, it may seem to you that only 1 hour - has passed. To avoid this mistake, just look at the clock regularly. Your application - should do the same. "Too long sleep" metaphor also maps directly to application - behavior: don't let your application run any single task for too long. Run tasks - in steps, and do time-keeping inbetween. - - `ticks_diff()` is designed to accommodate various usage patterns, among them: - - * Polling with timeout. In this case, the order of events is known, and you will deal - only with positive results of `ticks_diff()`:: - - # Wait for GPIO pin to be asserted, but at most 500us - start = time.ticks_us() - while pin.value() == 0: - if time.ticks_diff(time.ticks_us(), start) > 500: - raise TimeoutError - - * Scheduling events. In this case, `ticks_diff()` result may be negative - if an event is overdue:: - - # This code snippet is not optimized - now = time.ticks_ms() - scheduled_time = task.scheduled_time() - if ticks_diff(scheduled_time, now) > 0: - print("Too early, let's nap") - sleep_ms(ticks_diff(scheduled_time, now)) - task.run() - elif ticks_diff(scheduled_time, now) == 0: - print("Right at time!") - task.run() - elif ticks_diff(scheduled_time, now) < 0: - print("Oops, running late, tell task to run faster!") - task.run(run_faster=true) - - Note: Do not pass `time()` values to `ticks_diff()`, you should use - normal mathematical operations on them. But note that `time()` may (and will) - also overflow. This is known as https://en.wikipedia.org/wiki/Year_2038_problem . - - -.. function:: time() - - Returns the number of seconds, as an integer, since the Epoch, assuming that - underlying RTC is set and maintained as described above. If an RTC is not set, this - function returns number of seconds since a port-specific reference point in time (for - embedded boards without a battery-backed RTC, usually since power up or reset). If you - want to develop portable MicroPython application, you should not rely on this function - to provide higher than second precision. If you need higher precision, use - `ticks_ms()` and `ticks_us()` functions, if you need calendar time, - `localtime()` without an argument is a better choice. - - .. admonition:: Difference to CPython - :class: attention - - In CPython, this function returns number of - seconds since Unix epoch, 1970-01-01 00:00 UTC, as a floating-point, - usually having microsecond precision. With MicroPython, only Unix port - uses the same Epoch, and if floating-point precision allows, - returns sub-second precision. Embedded hardware usually doesn't have - floating-point precision to represent both long time ranges and subsecond - precision, so they use integer value with second precision. Some embedded - hardware also lacks battery-powered RTC, so returns number of seconds - since last power-up or from other relative, hardware-specific point - (e.g. reset). diff --git a/docs/library/uzlib.rst b/docs/library/uzlib.rst index 0b399f228ac..ba08b535cf2 100644 --- a/docs/library/uzlib.rst +++ b/docs/library/uzlib.rst @@ -1,10 +1,12 @@ :mod:`uzlib` -- zlib decompression ================================== +.. include:: ../templates/unsupported_in_circuitpython.inc + .. module:: uzlib :synopsis: zlib decompression -|see_cpython_module| :mod:`python:zlib`. +|see_cpython_module| :mod:`cpython:zlib`. This module allows to decompress binary data compressed with `DEFLATE algorithm `_ @@ -25,7 +27,7 @@ Functions .. class:: DecompIO(stream, wbits=0) - Create a `stream` wrapper which allows transparent decompression of + Create a ``stream`` wrapper which allows transparent decompression of compressed data in another *stream*. This allows to process compressed streams with data larger than available heap size. In addition to values described in :func:`decompress`, *wbits* may take values diff --git a/docs/library/wipy.rst b/docs/library/wipy.rst deleted file mode 100644 index cdece7b82b5..00000000000 --- a/docs/library/wipy.rst +++ /dev/null @@ -1,17 +0,0 @@ -************************************* -:mod:`wipy` -- WiPy specific features -************************************* - -.. module:: wipy - :synopsis: WiPy specific features - -The ``wipy`` module contains functions to control specific features of the -WiPy, such as the heartbeat LED. - -Functions ---------- - -.. function:: heartbeat([enable]) - - Get or set the state (enabled or disabled) of the heartbeat LED. Accepts and - returns boolean values (``True`` or ``False``). diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 44f9682790e..00000000000 --- a/docs/make.bat +++ /dev/null @@ -1,242 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set BUILDDIR=_build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . -set I18NSPHINXOPTS=%SPHINXOPTS% . -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% - set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. texinfo to make Texinfo files - echo. gettext to make PO message catalogs - echo. changes to make an overview over all changed/added/deprecated items - echo. xml to make Docutils-native XML files - echo. pseudoxml to make pseudoxml-XML files for display purposes - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - - -%SPHINXBUILD% 2> nul -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\MicroPython.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\MicroPython.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdf" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf - cd %BUILDDIR%/.. - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdfja" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf-ja - cd %BUILDDIR%/.. - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "texinfo" ( - %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. - goto end -) - -if "%1" == "gettext" ( - %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The message catalogs are in %BUILDDIR%/locale. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -if "%1" == "xml" ( - %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The XML files are in %BUILDDIR%/xml. - goto end -) - -if "%1" == "pseudoxml" ( - %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. - goto end -) - -:end diff --git a/docs/porting.rst b/docs/porting.rst new file mode 100644 index 00000000000..6bb5144588e --- /dev/null +++ b/docs/porting.rst @@ -0,0 +1,68 @@ +We love CircuitPython and would love to see it come to more microcontroller +platforms. With 3.0 we've reworked CircuitPython to make it easier than ever to +add support. While there are some major differences between ports, this page +covers the similarities that make CircuitPython what it is and how that core +fits into a variety of microcontrollers. + +Architecture +============ + +There are three core pieces to CircuitPython: + +The first is the Python VM that the awesome MicroPython devs have created. +These VMs are written to be portable so there is not much needed when moving to +a different microcontroller, especially if it is ARM based. + +The second is the infrastructure around those VMs which provides super basic +operating system functionality such as initializing hardware, running USB, +prepping file systems and automatically running user code on boot. In +CircuitPython we've dubbed this component the supervisor because it monitors +and facilitates the VMs which run user Python code. Porting involves the +supervisor because many of the tasks it does while interfacing with the +hardware. Once its going though, the REPL works and debugging can migrate to a +Python based approach rather than C. + +The third core piece is the plethora of low level APIs that CircuitPython +provides as the foundation for higher level libraries including device drivers. +These APIs are called from within the running VMs through the Python interfaces +defined in ``shared-bindings``. These bindings rely on the underlying +``common_hal`` C API to implement the functionality needed for the Python API. +By splitting the two, we work to ensure standard functionality across which +means that libraries and examples apply across ports with minimal changes. + +Porting +======= + +Step 1: Getting building +------------------------ +The first step to porting to a new microcontroller is getting a build running. +The primary goal of it should be to get ``main.c`` compiling with the assistance +of the ``supervisor/supervisor.mk`` file. Port specific code should be isolated +to the port's directory (in the top level until the ``ports`` directory is +present). This includes the Makefile and any C library resources. Make sure +these resources are compatible with the MIT License of the rest of the code! + +Step 2: Init +-------------- +Once your build is setup, the next step should be to get your clocks going as +you expect from the supervisor. The supervisor calls ``port_init`` to allow for +initialization at the beginning of main. This function also has the ability to +request a safe mode state which prevents the supervisor from running user code +while still allowing access to the REPL and other resources. + +The core port initialization and reset methods are defined in +``supervisor/port.c`` and should be the first to be implemented. Its required +that they be implemented in the ``supervisor`` directory within the port +directory. That way, they are always in the expected place. + +The supervisor also uses three linker variables, ``_ezero``, ``_estack`` and +``_ebss`` to determine memory layout for stack overflow checking. + +Step 3: REPL +------------ +Getting the REPL going is a huge step. It involves a bunch of initialization to +be done correctly and is a good sign you are well on your porting way. To get +the REPL going you must implement the functions and definitions from +``supervisor/serial.h`` with a corresponding ``supervisor/serial.c`` in the port +directory. This involves sending and receiving characters over some sort of +serial connection. It could be UART or USB for example. diff --git a/docs/pyboard/general.rst b/docs/pyboard/general.rst deleted file mode 100644 index 97e9aabc0bc..00000000000 --- a/docs/pyboard/general.rst +++ /dev/null @@ -1,80 +0,0 @@ -General information about the pyboard -===================================== - -.. contents:: - -Local filesystem and SD card ----------------------------- - -There is a small internal filesystem (a drive) on the pyboard, called ``/flash``, -which is stored within the microcontroller's flash memory. If a micro SD card -is inserted into the slot, it is available as ``/sd``. - -When the pyboard boots up, it needs to choose a filesystem to boot from. If -there is no SD card, then it uses the internal filesystem ``/flash`` as the boot -filesystem, otherwise, it uses the SD card ``/sd``. After the boot, the current -directory is set to one of the directories above. - -If needed, you can prevent the use of the SD card by creating an empty file -called ``/flash/SKIPSD``. If this file exists when the pyboard boots -up then the SD card will be skipped and the pyboard will always boot from the -internal filesystem (in this case the SD card won't be mounted but you can still -mount and use it later in your program using ``os.mount``). - -(Note that on older versions of the board, ``/flash`` is called ``0:/`` and ``/sd`` -is called ``1:/``). - -The boot filesystem is used for 2 things: it is the filesystem from which -the ``boot.py`` and ``main.py`` files are searched for, and it is the filesystem -which is made available on your PC over the USB cable. - -The filesystem will be available as a USB flash drive on your PC. You can -save files to the drive, and edit ``boot.py`` and ``main.py``. - -*Remember to eject (on Linux, unmount) the USB drive before you reset your -pyboard.* - -Boot modes ----------- - -If you power up normally, or press the reset button, the pyboard will boot -into standard mode: the ``boot.py`` file will be executed first, then the -USB will be configured, then ``main.py`` will run. - -You can override this boot sequence by holding down the user switch as -the board is booting up. Hold down user switch and press reset, and then -as you continue to hold the user switch, the LEDs will count in binary. -When the LEDs have reached the mode you want, let go of the user switch, -the LEDs for the selected mode will flash quickly, and the board will boot. - -The modes are: - -1. Green LED only, *standard boot*: run ``boot.py`` then ``main.py``. -2. Orange LED only, *safe boot*: don't run any scripts on boot-up. -3. Green and orange LED together, *filesystem reset*: resets the flash - filesystem to its factory state, then boots in safe mode. - -If your filesystem becomes corrupt, boot into mode 3 to fix it. -If resetting the filesystem while plugged into your compute doesn't work, -you can try doing the same procedure while the board is plugged into a USB -charger, or other USB power supply without data connection. - -Errors: flashing LEDs ---------------------- - -There are currently 2 kinds of errors that you might see: - -1. If the red and green LEDs flash alternatively, then a Python script - (eg ``main.py``) has an error. Use the REPL to debug it. -2. If all 4 LEDs cycle on and off slowly, then there was a hard fault. - This cannot be recovered from and you need to do a hard reset. - -Guide for using the pyboard with Windows ----------------------------------------- - -The following PDF guide gives information about using the pyboard with Windows, -including setting up the serial prompt and downloading new firmware using -DFU programming: -`PDF guide `__. - -.. include:: hardware/index.rst diff --git a/docs/pyboard/hardware/index.rst b/docs/pyboard/hardware/index.rst deleted file mode 100644 index 91fea24e7af..00000000000 --- a/docs/pyboard/hardware/index.rst +++ /dev/null @@ -1,30 +0,0 @@ -.. _hardware_index: - -The pyboard hardware --------------------- - -For the pyboard: - -* `PYBv1.0 schematics and layout `_ (2.4MiB PDF) -* `PYBv1.0 metric dimensions `_ (360KiB PDF) -* `PYBv1.0 imperial dimensions `_ (360KiB PDF) - -For the official skin modules: - -* `LCD32MKv1.0 schematics `_ (194KiB PDF) -* `AMPv1.0 schematics `_ (209KiB PDF) -* LCD160CRv1.0: see :mod:`lcd160cr` - -Datasheets for the components on the pyboard --------------------------------------------- - -* The microcontroller: `STM32F405RGT6 `_ (link to manufacturer's site) -* The accelerometer: `Freescale MMA7660 `_ (800kiB PDF) -* The LDO voltage regulator: `Microchip MCP1802 `_ (400kiB PDF) - -Datasheets for other components -------------------------------- - -* The LCD display on the LCD touch-sensor skin: `Newhaven Display NHD-C12832A1Z-FSW-FBW-3V3 `_ (460KiB PDF) -* The touch sensor chip on the LCD touch-sensor skin: `Freescale MPR121 `_ (280KiB PDF) -* The digital potentiometer on the audio skin: `Microchip MCP4541 `_ (2.7MiB PDF) diff --git a/docs/pyboard/quickref.rst b/docs/pyboard/quickref.rst deleted file mode 100644 index 48798aad3e5..00000000000 --- a/docs/pyboard/quickref.rst +++ /dev/null @@ -1,217 +0,0 @@ -.. _quickref: - -Quick reference for the pyboard -=============================== - -The below pinout is for PYBv1.0. You can also view pinouts for -other versions of the pyboard: -`PYBv1.1 `__ -or `PYBLITEv1.0-AC `__ -or `PYBLITEv1.0 `__. - -.. image:: http://micropython.org/resources/pybv10-pinout.jpg - :alt: PYBv1.0 pinout - :width: 700px - -General board control ---------------------- - -See :mod:`pyb`. :: - - import pyb - - pyb.repl_uart(pyb.UART(1, 9600)) # duplicate REPL on UART(1) - pyb.wfi() # pause CPU, waiting for interrupt - pyb.freq() # get CPU and bus frequencies - pyb.freq(60000000) # set CPU freq to 60MHz - pyb.stop() # stop CPU, waiting for external interrupt - -Delay and timing ----------------- - -Use the :mod:`time ` module:: - - import time - - time.sleep(1) # sleep for 1 second - time.sleep_ms(500) # sleep for 500 milliseconds - time.sleep_us(10) # sleep for 10 microseconds - start = time.ticks_ms() # get value of millisecond counter - delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference - -Internal LEDs -------------- - -See :ref:`pyb.LED `. :: - - from pyb import LED - - led = LED(1) # 1=red, 2=green, 3=yellow, 4=blue - led.toggle() - led.on() - led.off() - - # LEDs 3 and 4 support PWM intensity (0-255) - LED(4).intensity() # get intensity - LED(4).intensity(128) # set intensity to half - -Internal switch ---------------- - -See :ref:`pyb.Switch `. :: - - from pyb import Switch - - sw = Switch() - sw.value() # returns True or False - sw.callback(lambda: pyb.LED(1).toggle()) - -Pins and GPIO -------------- - -See :ref:`pyb.Pin `. :: - - from pyb import Pin - - p_out = Pin('X1', Pin.OUT_PP) - p_out.high() - p_out.low() - - p_in = Pin('X2', Pin.IN, Pin.PULL_UP) - p_in.value() # get value, 0 or 1 - -Servo control -------------- - -See :ref:`pyb.Servo `. :: - - from pyb import Servo - - s1 = Servo(1) # servo on position 1 (X1, VIN, GND) - s1.angle(45) # move to 45 degrees - s1.angle(-60, 1500) # move to -60 degrees in 1500ms - s1.speed(50) # for continuous rotation servos - -External interrupts -------------------- - -See :ref:`pyb.ExtInt `. :: - - from pyb import Pin, ExtInt - - callback = lambda e: print("intr") - ext = ExtInt(Pin('Y1'), ExtInt.IRQ_RISING, Pin.PULL_NONE, callback) - -Timers ------- - -See :ref:`pyb.Timer `. :: - - from pyb import Timer - - tim = Timer(1, freq=1000) - tim.counter() # get counter value - tim.freq(0.5) # 0.5 Hz - tim.callback(lambda t: pyb.LED(1).toggle()) - -RTC (real time clock) ---------------------- - -See :ref:`pyb.RTC ` :: - - from pyb import RTC - - rtc = RTC() - rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time - rtc.datetime() # get date and time - -PWM (pulse width modulation) ----------------------------- - -See :ref:`pyb.Pin ` and :ref:`pyb.Timer `. :: - - from pyb import Pin, Timer - - p = Pin('X1') # X1 has TIM2, CH1 - tim = Timer(2, freq=1000) - ch = tim.channel(1, Timer.PWM, pin=p) - ch.pulse_width_percent(50) - -ADC (analog to digital conversion) ----------------------------------- - -See :ref:`pyb.Pin ` and :ref:`pyb.ADC `. :: - - from pyb import Pin, ADC - - adc = ADC(Pin('X19')) - adc.read() # read value, 0-4095 - -DAC (digital to analog conversion) ----------------------------------- - -See :ref:`pyb.Pin ` and :ref:`pyb.DAC `. :: - - from pyb import Pin, DAC - - dac = DAC(Pin('X5')) - dac.write(120) # output between 0 and 255 - -UART (serial bus) ------------------ - -See :ref:`pyb.UART `. :: - - from pyb import UART - - uart = UART(1, 9600) - uart.write('hello') - uart.read(5) # read up to 5 bytes - -SPI bus -------- - -See :ref:`pyb.SPI `. :: - - from pyb import SPI - - spi = SPI(1, SPI.MASTER, baudrate=200000, polarity=1, phase=0) - spi.send('hello') - spi.recv(5) # receive 5 bytes on the bus - spi.send_recv('hello') # send and receive 5 bytes - -I2C bus -------- - -See :ref:`pyb.I2C `. :: - - from pyb import I2C - - i2c = I2C(1, I2C.MASTER, baudrate=100000) - i2c.scan() # returns list of slave addresses - i2c.send('hello', 0x42) # send 5 bytes to slave with address 0x42 - i2c.recv(5, 0x42) # receive 5 bytes from slave - i2c.mem_read(2, 0x42, 0x10) # read 2 bytes from slave 0x42, slave memory 0x10 - i2c.mem_write('xy', 0x42, 0x10) # write 2 bytes to slave 0x42, slave memory 0x10 - -CAN bus (controller area network) ---------------------------------- - -See :ref:`pyb.CAN `. :: - - from pyb import CAN - - can = CAN(1, CAN.LOOPBACK) - can.setfilter(0, CAN.LIST16, 0, (123, 124, 125, 126)) - can.send('message!', 123) # send a message with id 123 - can.recv(0) # receive message on FIFO 0 - -Internal accelerometer ----------------------- - -See :ref:`pyb.Accel `. :: - - from pyb import Accel - - accel = Accel() - print(accel.x(), accel.y(), accel.z(), accel.tilt()) diff --git a/docs/pyboard/tutorial/accel.rst b/docs/pyboard/tutorial/accel.rst deleted file mode 100644 index 58170e74ff3..00000000000 --- a/docs/pyboard/tutorial/accel.rst +++ /dev/null @@ -1,92 +0,0 @@ -The accelerometer -================= - -Here you will learn how to read the accelerometer and signal using LEDs states like tilt left and tilt right. - -Using the accelerometer ------------------------ - -The pyboard has an accelerometer (a tiny mass on a tiny spring) that can be used -to detect the angle of the board and motion. There is a different sensor for -each of the x, y, z directions. To get the value of the accelerometer, create a -pyb.Accel() object and then call the x() method. :: - - >>> accel = pyb.Accel() - >>> accel.x() - 7 - -This returns a signed integer with a value between around -30 and 30. Note that -the measurement is very noisy, this means that even if you keep the board -perfectly still there will be some variation in the number that you measure. -Because of this, you shouldn't use the exact value of the x() method but see if -it is in a certain range. - -We will start by using the accelerometer to turn on a light if it is not flat. :: - - accel = pyb.Accel() - light = pyb.LED(3) - SENSITIVITY = 3 - - while True: - x = accel.x() - if abs(x) > SENSITIVITY: - light.on() - else: - light.off() - - pyb.delay(100) - -We create Accel and LED objects, then get the value of the x direction of the -accelerometer. If the magnitude of x is bigger than a certain value ``SENSITIVITY``, -then the LED turns on, otherwise it turns off. The loop has a small ``pyb.delay()`` -otherwise the LED flashes annoyingly when the value of x is close to -``SENSITIVITY``. Try running this on the pyboard and tilt the board left and right -to make the LED turn on and off. - -**Exercise: Change the above script so that the blue LED gets brighter the more -you tilt the pyboard. HINT: You will need to rescale the values, intensity goes -from 0-255.** - -Making a spirit level ---------------------- - -The example above is only sensitive to the angle in the x direction but if we -use the ``y()`` value and more LEDs we can turn the pyboard into a spirit level. :: - - xlights = (pyb.LED(2), pyb.LED(3)) - ylights = (pyb.LED(1), pyb.LED(4)) - - accel = pyb.Accel() - SENSITIVITY = 3 - - while True: - x = accel.x() - if x > SENSITIVITY: - xlights[0].on() - xlights[1].off() - elif x < -SENSITIVITY: - xlights[1].on() - xlights[0].off() - else: - xlights[0].off() - xlights[1].off() - - y = accel.y() - if y > SENSITIVITY: - ylights[0].on() - ylights[1].off() - elif y < -SENSITIVITY: - ylights[1].on() - ylights[0].off() - else: - ylights[0].off() - ylights[1].off() - - pyb.delay(100) - -We start by creating a tuple of LED objects for the x and y directions. Tuples -are immutable objects in python which means they can't be modified once they are -created. We then proceed as before but turn on a different LED for positive and -negative x values. We then do the same for the y direction. This isn't -particularly sophisticated but it does the job. Run this on your pyboard and you -should see different LEDs turning on depending on how you tilt the board. diff --git a/docs/pyboard/tutorial/amp_skin.rst b/docs/pyboard/tutorial/amp_skin.rst deleted file mode 100644 index 697637f9d2b..00000000000 --- a/docs/pyboard/tutorial/amp_skin.rst +++ /dev/null @@ -1,98 +0,0 @@ -The AMP audio skin -================== - -Soldering and using the AMP audio skin. - -.. image:: img/skin_amp_1.jpg - :alt: AMP skin - :width: 250px - -.. image:: img/skin_amp_2.jpg - :alt: AMP skin - :width: 250px - -The following video shows how to solder the headers, microphone and speaker onto the AMP skin. - -.. raw:: html - - - -For circuit schematics and datasheets for the components on the skin see :ref:`hardware_index`. - -Example code ------------- - -The AMP skin has a speaker which is connected to ``DAC(1)`` via a small -power amplifier. The volume of the amplifier is controlled by a digital -potentiometer, which is an I2C device with address 46 on the ``IC2(1)`` bus. - -To set the volume, define the following function:: - - import pyb - def volume(val): - pyb.I2C(1, pyb.I2C.MASTER).mem_write(val, 46, 0) - -Then you can do:: - - >>> volume(0) # minimum volume - >>> volume(127) # maximum volume - -To play a sound, use the ``write_timed`` method of the ``DAC`` object. -For example:: - - import math - from pyb import DAC - - # create a buffer containing a sine-wave - buf = bytearray(100) - for i in range(len(buf)): - buf[i] = 128 + int(127 * math.sin(2 * math.pi * i / len(buf))) - - # output the sine-wave at 400Hz - dac = DAC(1) - dac.write_timed(buf, 400 * len(buf), mode=DAC.CIRCULAR) - -You can also play WAV files using the Python ``wave`` module. You can get -the wave module `here `__ and you will also need -the chunk module available `here `__. Put these -on your pyboard (either on the flash or the SD card in the top-level directory). You will need an -8-bit WAV file to play, such as `this one `_, -or to convert any file you have with the command:: - - avconv -i original.wav -ar 22050 -codec pcm_u8 test.wav - -Then you can do:: - - >>> import wave - >>> from pyb import DAC - >>> dac = DAC(1) - >>> f = wave.open('test.wav') - >>> dac.write_timed(f.readframes(f.getnframes()), f.getframerate()) - -This should play the WAV file. Note that this will read the whole file into RAM -so it has to be small enough to fit in it. - -To play larger wave files you will have to use the micro-SD card to store it. -Also the file must be read and sent to the DAC in small chunks that will fit -the RAM limit of the microcontroller. Here is an example function that can -play 8-bit wave files with up to 16kHz sampling:: - - import wave - from pyb import DAC - from pyb import delay - dac = DAC(1) - - def play(filename): - f = wave.open(filename, 'r') - total_frames = f.getnframes() - framerate = f.getframerate() - - for position in range(0, total_frames, framerate): - f.setpos(position) - dac.write_timed(f.readframes(framerate), framerate) - delay(1000) - -This function reads one second worth of data and sends it to DAC. It then waits -one second and moves the file cursor to the new position to read the next second -of data in the next iteration of the for-loop. It plays one second of audio at -a time every one second. diff --git a/docs/pyboard/tutorial/assembler.rst b/docs/pyboard/tutorial/assembler.rst deleted file mode 100644 index 1fe2bc4b079..00000000000 --- a/docs/pyboard/tutorial/assembler.rst +++ /dev/null @@ -1,131 +0,0 @@ -.. _pyboard_tutorial_assembler: - -Inline assembler -================ - -Here you will learn how to write inline assembler in MicroPython. - -**Note**: this is an advanced tutorial, intended for those who already -know a bit about microcontrollers and assembly language. - -MicroPython includes an inline assembler. It allows you to write -assembly routines as a Python function, and you can call them as you would -a normal Python function. - -Returning a value ------------------ - -Inline assembler functions are denoted by a special function decorator. -Let's start with the simplest example:: - - @micropython.asm_thumb - def fun(): - movw(r0, 42) - -You can enter this in a script or at the REPL. This function takes no -arguments and returns the number 42. ``r0`` is a register, and the value -in this register when the function returns is the value that is returned. -MicroPython always interprets the ``r0`` as an integer, and converts it to an -integer object for the caller. - -If you run ``print(fun())`` you will see it print out 42. - -Accessing peripherals ---------------------- - -For something a bit more complicated, let's turn on an LED:: - - @micropython.asm_thumb - def led_on(): - movwt(r0, stm.GPIOA) - movw(r1, 1 << 13) - strh(r1, [r0, stm.GPIO_BSRRL]) - -This code uses a few new concepts: - - - ``stm`` is a module which provides a set of constants for easy - access to the registers of the pyboard's microcontroller. Try - running ``import stm`` and then ``help(stm)`` at the REPL. It will - give you a list of all the available constants. - - - ``stm.GPIOA`` is the address in memory of the GPIOA peripheral. - On the pyboard, the red LED is on port A, pin PA13. - - - ``movwt`` moves a 32-bit number into a register. It is a convenience - function that turns into 2 thumb instructions: ``movw`` followed by ``movt``. - The ``movt`` also shifts the immediate value right by 16 bits. - - - ``strh`` stores a half-word (16 bits). The instruction above stores - the lower 16-bits of ``r1`` into the memory location ``r0 + stm.GPIO_BSRRL``. - This has the effect of setting high all those pins on port A for which - the corresponding bit in ``r0`` is set. In our example above, the 13th - bit in ``r0`` is set, so PA13 is pulled high. This turns on the red LED. - -Accepting arguments -------------------- - -Inline assembler functions can accept up to 4 arguments. If they are -used, they must be named ``r0``, ``r1``, ``r2`` and ``r3`` to reflect the registers -and the calling conventions. - -Here is a function that adds its arguments:: - - @micropython.asm_thumb - def asm_add(r0, r1): - add(r0, r0, r1) - -This performs the computation ``r0 = r0 + r1``. Since the result is put -in ``r0``, that is what is returned. Try ``asm_add(1, 2)``, it should return -3. - -Loops ------ - -We can assign labels with ``label(my_label)``, and branch to them using -``b(my_label)``, or a conditional branch like ``bgt(my_label)``. - -The following example flashes the green LED. It flashes it ``r0`` times. :: - - @micropython.asm_thumb - def flash_led(r0): - # get the GPIOA address in r1 - movwt(r1, stm.GPIOA) - - # get the bit mask for PA14 (the pin LED #2 is on) - movw(r2, 1 << 14) - - b(loop_entry) - - label(loop1) - - # turn LED on - strh(r2, [r1, stm.GPIO_BSRRL]) - - # delay for a bit - movwt(r4, 5599900) - label(delay_on) - sub(r4, r4, 1) - cmp(r4, 0) - bgt(delay_on) - - # turn LED off - strh(r2, [r1, stm.GPIO_BSRRH]) - - # delay for a bit - movwt(r4, 5599900) - label(delay_off) - sub(r4, r4, 1) - cmp(r4, 0) - bgt(delay_off) - - # loop r0 times - sub(r0, r0, 1) - label(loop_entry) - cmp(r0, 0) - bgt(loop1) - -Further reading ---------------- - -For further information about supported instructions of the inline assembler, -see the :ref:`reference documentation `. diff --git a/docs/pyboard/tutorial/debounce.rst b/docs/pyboard/tutorial/debounce.rst deleted file mode 100644 index f730e1d340e..00000000000 --- a/docs/pyboard/tutorial/debounce.rst +++ /dev/null @@ -1,37 +0,0 @@ -Debouncing a pin input -====================== - -A pin used as input from a switch or other mechanical device can have a lot -of noise on it, rapidly changing from low to high when the switch is first -pressed or released. This noise can be eliminated using a capacitor (a -debouncing circuit). It can also be eliminated using a simple function that -makes sure the value on the pin is stable. - -The following function does just this. It gets the current value of the given -pin, and then waits for the value to change. The new pin value must be stable -for a continuous 20ms for it to register the change. You can adjust this time -(to say 50ms) if you still have noise. :: - - import pyb - - def wait_pin_change(pin): - # wait for pin to change value - # it needs to be stable for a continuous 20ms - cur_value = pin.value() - active = 0 - while active < 20: - if pin.value() != cur_value: - active += 1 - else: - active = 0 - pyb.delay(1) - - -Use it something like this:: - - import pyb - - pin_x1 = pyb.Pin('X1', pyb.Pin.IN, pyb.Pin.PULL_DOWN) - while True: - wait_pin_change(pin_x1) - pyb.LED(4).toggle() diff --git a/docs/pyboard/tutorial/fading_led.rst b/docs/pyboard/tutorial/fading_led.rst deleted file mode 100644 index 0a4b5c50396..00000000000 --- a/docs/pyboard/tutorial/fading_led.rst +++ /dev/null @@ -1,89 +0,0 @@ -Fading LEDs -=========== - -In addition to turning LEDs on and off, it is also possible to control the brightness of an LED using `Pulse-Width Modulation (PWM) `_, a common technique for obtaining variable output from a digital pin. This allows us to fade an LED: - -.. image:: http://upload.wikimedia.org/wikipedia/commons/a/a9/Fade.gif - -Components ----------- - -You will need: - -- Standard 5 or 3 mm LED -- 100 Ohm resistor -- Wires -- `Breadboard `_ (optional, but makes things easier) - -Connecting Things Up --------------------- - -For this tutorial, we will use the ``X1`` pin. Connect one end of the resistor to ``X1``, and the other end to the **anode** of the LED, which is the longer leg. Connect the **cathode** of the LED to ground. - -.. image:: img/fading_leds_breadboard_fritzing.png - -Code ----- -By examining the :ref:`quickref`, we see that ``X1`` is connected to channel 1 of timer 5 (``TIM5 CH1``). Therefore we will first create a ``Timer`` object for timer 5, then create a ``TimerChannel`` object for channel 1:: - - from pyb import Timer - from time import sleep - - # timer 5 will be created with a frequency of 100 Hz - tim = pyb.Timer(5, freq=100) - tchannel = tim.channel(1, Timer.PWM, pin=pyb.Pin.board.X1, pulse_width=0) - -Brightness of the LED in PWM is controlled by controlling the pulse-width, that is the amount of time the LED is on every cycle. With a timer frequency of 100 Hz, each cycle takes 0.01 second, or 10 ms. - -To achieve the fading effect shown at the beginning of this tutorial, we want to set the pulse-width to a small value, then slowly increase the pulse-width to brighten the LED, and start over when we reach some maximum brightness:: - - # maximum and minimum pulse-width, which corresponds to maximum - # and minimum brightness - max_width = 200000 - min_width = 20000 - - # how much to change the pulse-width by each step - wstep = 1500 - cur_width = min_width - - while True: - tchannel.pulse_width(cur_width) - - # this determines how often we change the pulse-width. It is - # analogous to frames-per-second - sleep(0.01) - - cur_width += wstep - - if cur_width > max_width: - cur_width = min_width - -Breathing Effect ----------------- - -If we want to have a breathing effect, where the LED fades from dim to bright then bright to dim, then we simply need to reverse the sign of ``wstep`` when we reach maximum brightness, and reverse it again at minimum brightness. To do this we modify the ``while`` loop to be:: - - while True: - tchannel.pulse_width(cur_width) - - sleep(0.01) - - cur_width += wstep - - if cur_width > max_width: - cur_width = max_width - wstep *= -1 - elif cur_width < min_width: - cur_width = min_width - wstep *= -1 - -Advanced Exercise ------------------ - -You may have noticed that the LED brightness seems to fade slowly, but increases quickly. This is because our eyes interprets brightness logarithmically (`Weber's Law `_ -), while the LED's brightness changes linearly, that is by the same amount each time. How do you solve this problem? (Hint: what is the opposite of the logarithmic function?) - -Addendum --------- - -We could have also used the digital-to-analog converter (DAC) to achieve the same effect. The PWM method has the advantage that it drives the LED with the same current each time, but for different lengths of time. This allows better control over the brightness, because LEDs do not necessarily exhibit a linear relationship between the driving current and brightness. diff --git a/docs/pyboard/tutorial/img/fading_leds_breadboard_fritzing.png b/docs/pyboard/tutorial/img/fading_leds_breadboard_fritzing.png deleted file mode 100644 index a8eec4eb620..00000000000 Binary files a/docs/pyboard/tutorial/img/fading_leds_breadboard_fritzing.png and /dev/null differ diff --git a/docs/pyboard/tutorial/img/pyboard_servo.jpg b/docs/pyboard/tutorial/img/pyboard_servo.jpg deleted file mode 100644 index 0d64e46c428..00000000000 Binary files a/docs/pyboard/tutorial/img/pyboard_servo.jpg and /dev/null differ diff --git a/docs/pyboard/tutorial/img/pyboard_usb_micro.jpg b/docs/pyboard/tutorial/img/pyboard_usb_micro.jpg deleted file mode 100644 index bc1c2b83233..00000000000 Binary files a/docs/pyboard/tutorial/img/pyboard_usb_micro.jpg and /dev/null differ diff --git a/docs/pyboard/tutorial/img/skin_amp_1.jpg b/docs/pyboard/tutorial/img/skin_amp_1.jpg deleted file mode 100644 index df444600803..00000000000 Binary files a/docs/pyboard/tutorial/img/skin_amp_1.jpg and /dev/null differ diff --git a/docs/pyboard/tutorial/img/skin_amp_2.jpg b/docs/pyboard/tutorial/img/skin_amp_2.jpg deleted file mode 100644 index 7631b3b6334..00000000000 Binary files a/docs/pyboard/tutorial/img/skin_amp_2.jpg and /dev/null differ diff --git a/docs/pyboard/tutorial/img/skin_lcd_1.jpg b/docs/pyboard/tutorial/img/skin_lcd_1.jpg deleted file mode 100644 index 1dda73ffd53..00000000000 Binary files a/docs/pyboard/tutorial/img/skin_lcd_1.jpg and /dev/null differ diff --git a/docs/pyboard/tutorial/img/skin_lcd_2.jpg b/docs/pyboard/tutorial/img/skin_lcd_2.jpg deleted file mode 100644 index 6e3e1033efc..00000000000 Binary files a/docs/pyboard/tutorial/img/skin_lcd_2.jpg and /dev/null differ diff --git a/docs/pyboard/tutorial/index.rst b/docs/pyboard/tutorial/index.rst deleted file mode 100644 index 1dc155f1493..00000000000 --- a/docs/pyboard/tutorial/index.rst +++ /dev/null @@ -1,48 +0,0 @@ -.. _tutorial-index: - -MicroPython tutorial for the pyboard -==================================== - -This tutorial is intended to get you started with your pyboard. -All you need is a pyboard and a micro-USB cable to connect it to -your PC. If it is your first time, it is recommended to follow -the tutorial through in the order below. - -.. toctree:: - :maxdepth: 1 - :numbered: - - intro.rst - script.rst - repl.rst - leds.rst - switch.rst - accel.rst - reset.rst - usb_mouse.rst - timer.rst - assembler.rst - power_ctrl.rst - -Tutorials requiring extra components ------------------------------------- - -.. toctree:: - :maxdepth: 1 - :numbered: - - servo.rst - fading_led.rst - lcd_skin.rst - amp_skin.rst - lcd160cr_skin.rst - -Tips, tricks and useful things to know --------------------------------------- - -.. toctree:: - :maxdepth: 1 - :numbered: - - debounce.rst - pass_through.rst diff --git a/docs/pyboard/tutorial/intro.rst b/docs/pyboard/tutorial/intro.rst deleted file mode 100644 index 78343db59a8..00000000000 --- a/docs/pyboard/tutorial/intro.rst +++ /dev/null @@ -1,54 +0,0 @@ -Introduction to the pyboard -=========================== - -To get the most out of your pyboard, there are a few basic things to -understand about how it works. - -Caring for your pyboard ------------------------ - -Because the pyboard does not have a housing it needs a bit of care: - - - Be gentle when plugging/unplugging the USB cable. Whilst the USB connector - is soldered through the board and is relatively strong, if it breaks off - it can be very difficult to fix. - - - Static electricity can shock the components on the pyboard and destroy them. - If you experience a lot of static electricity in your area (eg dry and cold - climates), take extra care not to shock the pyboard. If your pyboard came - in a black plastic box, then this box is the best way to store and carry the - pyboard as it is an anti-static box (it is made of a conductive plastic, with - conductive foam inside). - -As long as you take care of the hardware, you should be okay. It's almost -impossible to break the software on the pyboard, so feel free to play around -with writing code as much as you like. If the filesystem gets corrupt, see -below on how to reset it. In the worst case you might need to reflash the -MicroPython software, but that can be done over USB. - -Layout of the pyboard ---------------------- - -The micro USB connector is on the top right, the micro SD card slot on -the top left of the board. There are 4 LEDs between the SD slot and -USB connector. The colours are: red on the bottom, then green, orange, -and blue on the top. There are 2 switches: the right one is the reset -switch, the left is the user switch. - -Plugging in and powering on ---------------------------- - -The pyboard can be powered via USB. Connect it to your PC via a micro USB -cable. There is only one way that the cable will fit. Once connected, -the green LED on the board should flash quickly. - -Powering by an external power source ------------------------------------- - -The pyboard can be powered by a battery or other external power source. - -**Be sure to connect the positive lead of the power supply to VIN, and -ground to GND. There is no polarity protection on the pyboard so you -must be careful when connecting anything to VIN.** - -**The input voltage must be between 3.6V and 10V.** diff --git a/docs/pyboard/tutorial/lcd160cr_skin.rst b/docs/pyboard/tutorial/lcd160cr_skin.rst deleted file mode 100644 index fc9d6353826..00000000000 --- a/docs/pyboard/tutorial/lcd160cr_skin.rst +++ /dev/null @@ -1,134 +0,0 @@ -The LCD160CR skin -================= - -This tutorial shows how to get started using the LCD160CR skin. - -.. image:: http://micropython.org/resources/LCD160CRv10-positions.jpg - :alt: LCD160CRv1.0 picture - :width: 800px - -For detailed documentation of the driver for the display see the -:mod:`lcd160cr` module. - -Plugging in the display ------------------------ - -The display can be plugged directly into a pyboard (all pyboard versions -are supported). You plug the display onto the top of the pyboard either -in the X or Y positions. The display should cover half of the pyboard. -See the picture above for how to achieve this; the left half of the picture -shows the X position, and the right half shows the Y position. - -Getting the driver ------------------- - -You can control the display directly using a power/enable pin and an I2C -bus, but it is much more convenient to use the driver provided by the -:mod:`lcd160cr` module. This driver is included in recent version of the -pyboard firmware (see `here `__). You -can also find the driver in the GitHub repository -`here `__, and to use this version you will need to copy the file to your -board, into a directory that is searched by import (usually the lib/ -directory). - -Once you have the driver installed you need to import it to use it:: - - import lcd160cr - -Testing the display -------------------- - -There is a test program which you can use to test the features of the display, -and which also serves as a basis to start creating your own code that uses the -LCD. This test program is included in recent versions of the pyboard firmware -and is also available on GitHub -`here `__. - -To run the test from the MicroPython prompt do:: - - >>> import lcd160cr_test - -It will then print some brief instructions. You will need to know which -position your display is connected to (X or Y) and then you can run (assuming -you have the display on position X):: - - >>> test_all('X') - -Drawing some graphics ---------------------- - -You must first create an LCD160CR object which will control the display. Do this -using:: - - >>> import lcd160cr - >>> lcd = lcd160cr.LCD160CR('X') - -This assumes your display is connected in the X position. If it's in the Y -position then use ``lcd = lcd160cr.LCD160CR('Y')`` instead. - -To erase the screen and draw a line, try:: - - >>> lcd.set_pen(lcd.rgb(255, 0, 0), lcd.rgb(64, 64, 128)) - >>> lcd.erase() - >>> lcd.line(10, 10, 50, 80) - -The next example draws random rectangles on the screen. You can copy-and-paste it -into the MicroPython prompt by first pressing "Ctrl-E" at the prompt, then "Ctrl-D" -once you have pasted the text. :: - - from random import randint - for i in range(1000): - fg = lcd.rgb(randint(128, 255), randint(128, 255), randint(128, 255)) - bg = lcd.rgb(randint(0, 128), randint(0, 128), randint(0, 128)) - lcd.set_pen(fg, bg) - lcd.rect(randint(0, lcd.w), randint(0, lcd.h), randint(10, 40), randint(10, 40)) - -Using the touch sensor ----------------------- - -The display includes a resistive touch sensor that can report the position (in -pixels) of a single force-based touch on the screen. To see if there is a touch -on the screen use:: - - >>> lcd.is_touched() - -This will return either ``False`` or ``True``. Run the above command while touching -the screen to see the result. - -To get the location of the touch you can use the method:: - - >>> lcd.get_touch() - -This will return a 3-tuple, with the first entry being 0 or 1 depending on whether -there is currently anything touching the screen (1 if there is), and the second and -third entries in the tuple being the x and y coordinates of the current (or most -recent) touch. - -Directing the MicroPython output to the display ------------------------------------------------ - -The display supports input from a UART and implements basic VT100 commands, which -means it can be used as a simple, general purpose terminal. Let's set up the -pyboard to redirect its output to the display. - -First you need to create a UART object:: - - >>> import pyb - >>> uart = pyb.UART('XA', 115200) - -This assumes your display is connected to position X. If it's on position Y then -use ``uart = pyb.UART('YA', 115200)`` instead. - -Now, connect the REPL output to this UART:: - - >>> pyb.repl_uart(uart) - -From now on anything you type at the MicroPython prompt, and any output you -receive, will appear on the display. - -No set-up commands are required for this mode to work and you can use the display -to monitor the output of any UART, not just from the pyboard. All that is needed -is for the display to have power, ground and the power/enable pin driven high. -Then any characters on the display's UART input will be printed to the screen. -You can adjust the UART baudrate from the default of 115200 using the -`set_uart_baudrate` method. diff --git a/docs/pyboard/tutorial/lcd_skin.rst b/docs/pyboard/tutorial/lcd_skin.rst deleted file mode 100644 index 288ac1bf08b..00000000000 --- a/docs/pyboard/tutorial/lcd_skin.rst +++ /dev/null @@ -1,86 +0,0 @@ -The LCD and touch-sensor skin -============================= - -Soldering and using the LCD and touch-sensor skin. - -.. image:: img/skin_lcd_1.jpg - :alt: pyboard with LCD skin - :width: 250px - -.. image:: img/skin_lcd_2.jpg - :alt: pyboard with LCD skin - :width: 250px - -The following video shows how to solder the headers onto the LCD skin. -At the end of the video, it shows you how to correctly connect the LCD skin to the pyboard. - -.. raw:: html - - - -For circuit schematics and datasheets for the components on the skin see :ref:`hardware_index`. - -Using the LCD -------------- - -To get started using the LCD, try the following at the MicroPython prompt. -Make sure the LCD skin is attached to the pyboard as pictured at the top of this page. :: - - >>> import pyb - >>> lcd = pyb.LCD('X') - >>> lcd.light(True) - >>> lcd.write('Hello uPy!\n') - -You can make a simple animation using the code:: - - import pyb - lcd = pyb.LCD('X') - lcd.light(True) - for x in range(-80, 128): - lcd.fill(0) - lcd.text('Hello uPy!', x, 10, 1) - lcd.show() - pyb.delay(25) - -Using the touch sensor ----------------------- - -To read the touch-sensor data you need to use the I2C bus. The -MPR121 capacitive touch sensor has address 90. - -To get started, try:: - - >>> import pyb - >>> i2c = pyb.I2C(1, pyb.I2C.MASTER) - >>> i2c.mem_write(4, 90, 0x5e) - >>> touch = i2c.mem_read(1, 90, 0)[0] - -The first line above makes an I2C object, and the second line -enables the 4 touch sensors. The third line reads the touch -status and the ``touch`` variable holds the state of the 4 touch -buttons (A, B, X, Y). - -There is a simple driver `here `__ -which allows you to set the threshold and debounce parameters, and -easily read the touch status and electrode voltage levels. Copy -this script to your pyboard (either flash or SD card, in the top -directory or ``lib/`` directory) and then try:: - - >>> import pyb - >>> import mpr121 - >>> m = mpr121.MPR121(pyb.I2C(1, pyb.I2C.MASTER)) - >>> for i in range(100): - ... print(m.touch_status()) - ... pyb.delay(100) - ... - -This will continuously print out the touch status of all electrodes. -Try touching each one in turn. - -Note that if you put the LCD skin in the Y-position, then you need to -initialise the I2C bus using:: - - >>> m = mpr121.MPR121(pyb.I2C(2, pyb.I2C.MASTER)) - -There is also a demo which uses the LCD and the touch sensors together, -and can be found `here `__. diff --git a/docs/pyboard/tutorial/leds.rst b/docs/pyboard/tutorial/leds.rst deleted file mode 100644 index 6b05f5db050..00000000000 --- a/docs/pyboard/tutorial/leds.rst +++ /dev/null @@ -1,75 +0,0 @@ -Turning on LEDs and basic Python concepts -========================================= - -The easiest thing to do on the pyboard is to turn on the LEDs attached to the board. Connect the board, and log in as described in tutorial 1. We will start by turning and LED on in the interpreter, type the following :: - - >>> myled = pyb.LED(1) - >>> myled.on() - >>> myled.off() - -These commands turn the LED on and off. - -This is all very well but we would like this process to be automated. Open the file MAIN.PY on the pyboard in your favourite text editor. Write or paste the following lines into the file. If you are new to python, then make sure you get the indentation correct since this matters! :: - - led = pyb.LED(2) - while True: - led.toggle() - pyb.delay(1000) - -When you save, the red light on the pyboard should turn on for about a second. To run the script, do a soft reset (CTRL-D). The pyboard will then restart and you should see a green light continuously flashing on and off. Success, the first step on your path to building an army of evil robots! When you are bored of the annoying flashing light then press CTRL-C at your terminal to stop it running. - -So what does this code do? First we need some terminology. Python is an object-oriented language, almost everything in python is a *class* and when you create an instance of a class you get an *object*. Classes have *methods* associated to them. A method (also called a member function) is used to interact with or control the object. - -The first line of code creates an LED object which we have then called led. When we create the object, it takes a single parameter which must be between 1 and 4, corresponding to the 4 LEDs on the board. The pyb.LED class has three important member functions that we will use: on(), off() and toggle(). The other function that we use is pyb.delay() this simply waits for a given time in miliseconds. Once we have created the LED object, the statement while True: creates an infinite loop which toggles the led between on and off and waits for 1 second. - -**Exercise: Try changing the time between toggling the led and turning on a different LED.** - -**Exercise: Connect to the pyboard directly, create a pyb.LED object and turn it on using the on() method.** - -A Disco on your pyboard ------------------------ - -So far we have only used a single LED but the pyboard has 4 available. Let's start by creating an object for each LED so we can control each of them. We do that by creating a list of LEDS with a list comprehension. :: - - leds = [pyb.LED(i) for i in range(1,5)] - -If you call pyb.LED() with a number that isn't 1,2,3,4 you will get an error message. -Next we will set up an infinite loop that cycles through each of the LEDs turning them on and off. :: - - n = 0 - while True: - n = (n + 1) % 4 - leds[n].toggle() - pyb.delay(50) - -Here, n keeps track of the current LED and every time the loop is executed we cycle to the next n (the % sign is a modulus operator that keeps n between 0 and 3.) Then we access the nth LED and toggle it. If you run this you should see each of the LEDs turning on then all turning off again in sequence. - -One problem you might find is that if you stop the script and then start it again that the LEDs are stuck on from the previous run, ruining our carefully choreographed disco. We can fix this by turning all the LEDs off when we initialise the script and then using a try/finally block. When you press CTRL-C, MicroPython generates a VCPInterrupt exception. Exceptions normally mean something has gone wrong and you can use a try: command to "catch" an exception. In this case it is just the user interrupting the script, so we don't need to catch the error but just tell MicroPython what to do when we exit. The finally block does this, and we use it to make sure all the LEDs are off. The full code is:: - - leds = [pyb.LED(i) for i in range(1,5)] - for l in leds: - l.off() - - n = 0 - try: - while True: - n = (n + 1) % 4 - leds[n].toggle() - pyb.delay(50) - finally: - for l in leds: - l.off() - -The Special LEDs ----------------- - -The yellow and blue LEDs are special. As well as turning them on and off, you can control their intensity using the intensity() method. This takes a number between 0 and 255 that determines how bright it is. The following script makes the blue LED gradually brighter then turns it off again. :: - - led = pyb.LED(4) - intensity = 0 - while True: - intensity = (intensity + 1) % 255 - led.intensity(intensity) - pyb.delay(20) - -You can call intensity() on LEDs 1 and 2 but they can only be off or on. 0 sets them off and any other number up to 255 turns them on. diff --git a/docs/pyboard/tutorial/pass_through.rst b/docs/pyboard/tutorial/pass_through.rst deleted file mode 100644 index 012a907648e..00000000000 --- a/docs/pyboard/tutorial/pass_through.rst +++ /dev/null @@ -1,18 +0,0 @@ -Making a UART - USB pass through -================================ - -It's as simple as:: - - import pyb - import select - - def pass_through(usb, uart): - usb.setinterrupt(-1) - while True: - select.select([usb, uart], [], []) - if usb.any(): - uart.write(usb.read(256)) - if uart.any(): - usb.write(uart.read(256)) - - pass_through(pyb.USB_VCP(), pyb.UART(1, 9600, timeout=0)) diff --git a/docs/pyboard/tutorial/power_ctrl.rst b/docs/pyboard/tutorial/power_ctrl.rst deleted file mode 100644 index 877b7cd7eee..00000000000 --- a/docs/pyboard/tutorial/power_ctrl.rst +++ /dev/null @@ -1,13 +0,0 @@ -Power control -============= - -:meth:`pyb.wfi` is used to reduce power consumption while waiting for an -event such as an interrupt. You would use it in the following situation:: - - while True: - do_some_processing() - pyb.wfi() - -Control the frequency using :meth:`pyb.freq`:: - - pyb.freq(30000000) # set CPU frequency to 30MHz diff --git a/docs/pyboard/tutorial/repl.rst b/docs/pyboard/tutorial/repl.rst deleted file mode 100644 index 646ecbc2373..00000000000 --- a/docs/pyboard/tutorial/repl.rst +++ /dev/null @@ -1,110 +0,0 @@ -Getting a MicroPython REPL prompt -================================= - -REPL stands for Read Evaluate Print Loop, and is the name given to the -interactive MicroPython prompt that you can access on the pyboard. Using -the REPL is by far the easiest way to test out your code and run commands. -You can use the REPL in addition to writing scripts in ``main.py``. - -To use the REPL, you must connect to the serial USB device on the pyboard. -How you do this depends on your operating system. - -Windows -------- - -You need to install the pyboard driver to use the serial USB device. -The driver is on the pyboard's USB flash drive, and is called ``pybcdc.inf``. - -To install this driver you need to go to Device Manager -for your computer, find the pyboard in the list of devices (it should have -a warning sign next to it because it's not working yet), right click on -the pyboard device, select Properties, then Install Driver. You need to -then select the option to find the driver manually (don't use Windows auto update), -navigate to the pyboard's USB drive, and select that. It should then install. -After installing, go back to the Device Manager to find the installed pyboard, -and see which COM port it is (eg COM4). -More comprehensive instructions can be found in the -`Guide for pyboard on Windows (PDF) `_. -Please consult this guide if you are having problems installing the driver. - -You now need to run your terminal program. You can use HyperTerminal if you -have it installed, or download the free program PuTTY: -`putty.exe `_. -Using your serial program you must connect to the COM port that you found in the -previous step. With PuTTY, click on "Session" in the left-hand panel, then click -the "Serial" radio button on the right, then enter you COM port (eg COM4) in the -"Serial Line" box. Finally, click the "Open" button. - -Mac OS X --------- - -Open a terminal and run:: - - screen /dev/tty.usbmodem* - -When you are finished and want to exit screen, type CTRL-A CTRL-\\. - -Linux ------ - -Open a terminal and run:: - - screen /dev/ttyACM0 - -You can also try ``picocom`` or ``minicom`` instead of screen. You may have to -use ``/dev/ttyACM1`` or a higher number for ``ttyACM``. And, you may need to give -yourself the correct permissions to access this devices (eg group ``uucp`` or ``dialout``, -or use sudo). - -Using the REPL prompt ---------------------- - -Now let's try running some MicroPython code directly on the pyboard. - -With your serial program open (PuTTY, screen, picocom, etc) you may see a blank -screen with a flashing cursor. Press Enter and you should be presented with a -MicroPython prompt, i.e. ``>>>``. Let's make sure it is working with the obligatory test:: - - >>> print("hello pyboard!") - hello pyboard! - -In the above, you should not type in the ``>>>`` characters. They are there to -indicate that you should type the text after it at the prompt. In the end, once -you have entered the text ``print("hello pyboard!")`` and pressed Enter, the output -on your screen should look like it does above. - -If you already know some python you can now try some basic commands here. - -If any of this is not working you can try either a hard reset or a soft reset; -see below. - -Go ahead and try typing in some other commands. For example:: - - >>> pyb.LED(1).on() - >>> pyb.LED(2).on() - >>> 1 + 2 - 3 - >>> 1 / 2 - 0.5 - >>> 20 * 'py' - 'pypypypypypypypypypypypypypypypypypypypy' - -Resetting the board -------------------- - -If something goes wrong, you can reset the board in two ways. The first is to press CTRL-D -at the MicroPython prompt, which performs a soft reset. You will see a message something like :: - - >>> - PYB: sync filesystems - PYB: soft reboot - Micro Python v1.0 on 2014-05-03; PYBv1.0 with STM32F405RG - Type "help()" for more information. - >>> - -If that isn't working you can perform a hard reset (turn-it-off-and-on-again) by pressing the RST -switch (the small black button closest to the micro-USB socket on the board). This will end your -session, disconnecting whatever program (PuTTY, screen, etc) that you used to connect to the pyboard. - -If you are going to do a hard-reset, it's recommended to first close your serial program and eject/unmount -the pyboard drive. diff --git a/docs/pyboard/tutorial/reset.rst b/docs/pyboard/tutorial/reset.rst deleted file mode 100644 index 0cd5ac21c8f..00000000000 --- a/docs/pyboard/tutorial/reset.rst +++ /dev/null @@ -1,60 +0,0 @@ -Safe mode and factory reset -=========================== - -If something goes wrong with your pyboard, don't panic! It is almost -impossible for you to break the pyboard by programming the wrong thing. - -The first thing to try is to enter safe mode: this temporarily skips -execution of ``boot.py`` and ``main.py`` and gives default USB settings. - -If you have problems with the filesystem you can do a factory reset, -which restores the filesystem to its original state. - -Safe mode ---------- - -To enter safe mode, do the following steps: - -1. Connect the pyboard to USB so it powers up. -2. Hold down the USR switch. -3. While still holding down USR, press and release the RST switch. -4. The LEDs will then cycle green to orange to green+orange and back again. -5. Keep holding down USR until *only the orange LED is lit*, and then let - go of the USR switch. -6. The orange LED should flash quickly 4 times, and then turn off. -7. You are now in safe mode. - -In safe mode, the ``boot.py`` and ``main.py`` files are not executed, and so -the pyboard boots up with default settings. This means you now have access -to the filesystem (the USB drive should appear), and you can edit ``boot.py`` -and ``main.py`` to fix any problems. - -Entering safe mode is temporary, and does not make any changes to the -files on the pyboard. - -Factory reset the filesystem ----------------------------- - -If you pyboard's filesystem gets corrupted (for example, you forgot to -eject/unmount it), or you have some code in ``boot.py`` or ``main.py`` which -you can't escape from, then you can reset the filesystem. - -Resetting the filesystem deletes all files on the internal pyboard storage -(not the SD card), and restores the files ``boot.py``, ``main.py``, ``README.txt`` -and ``pybcdc.inf`` back to their original state. - -To do a factory reset of the filesystem you follow a similar procedure as -you did to enter safe mode, but release USR on green+orange: - -1. Connect the pyboard to USB so it powers up. -2. Hold down the USR switch. -3. While still holding down USR, press and release the RST switch. -4. The LEDs will then cycle green to orange to green+orange and back again. -5. Keep holding down USR until *both the green and orange LEDs are lit*, and - then let go of the USR switch. -6. The green and orange LEDs should flash quickly 4 times. -7. The red LED will turn on (so red, green and orange are now on). -8. The pyboard is now resetting the filesystem (this takes a few seconds). -9. The LEDs all turn off. -10. You now have a reset filesystem, and are in safe mode. -11. Press and release the RST switch to boot normally. diff --git a/docs/pyboard/tutorial/script.rst b/docs/pyboard/tutorial/script.rst deleted file mode 100644 index 75dd324e3ca..00000000000 --- a/docs/pyboard/tutorial/script.rst +++ /dev/null @@ -1,105 +0,0 @@ -Running your first script -========================= - -Let's jump right in and get a Python script running on the pyboard. After -all, that's what it's all about! - -Connecting your pyboard ------------------------ - -Connect your pyboard to your PC (Windows, Mac or Linux) with a micro USB cable. -There is only one way that the cable will connect, so you can't get it wrong. - -.. image:: img/pyboard_usb_micro.jpg - -When the pyboard is connected to your PC it will power on and enter the start up -process (the boot process). The green LED should light up for half a second or -less, and when it turns off it means the boot process has completed. - -Opening the pyboard USB drive ------------------------------ - -Your PC should now recognise the pyboard. It depends on the type of PC you -have as to what happens next: - - - **Windows**: Your pyboard will appear as a removable USB flash drive. - Windows may automatically pop-up a window, or you may need to go there - using Explorer. - - Windows will also see that the pyboard has a serial device, and it will - try to automatically configure this device. If it does, cancel the process. - We will get the serial device working in the next tutorial. - - - **Mac**: Your pyboard will appear on the desktop as a removable disc. - It will probably be called "NONAME". Click on it to open the pyboard folder. - - - **Linux**: Your pyboard will appear as a removable medium. On Ubuntu - it will mount automatically and pop-up a window with the pyboard folder. - On other Linux distributions, the pyboard may be mounted automatically, - or you may need to do it manually. At a terminal command line, type ``lsblk`` - to see a list of connected drives, and then ``mount /dev/sdb1`` (replace ``sdb1`` - with the appropriate device). You may need to be root to do this. - -Okay, so you should now have the pyboard connected as a USB flash drive, and -a window (or command line) should be showing the files on the pyboard drive. - -The drive you are looking at is known as ``/flash`` by the pyboard, and should contain -the following 4 files: - -* `boot.py `_ -- this script is executed when the pyboard boots up. It sets - up various configuration options for the pyboard. - -* `main.py `_ -- this is the main script that will contain your Python program. - It is executed after ``boot.py``. - -* `README.txt `_ -- this contains some very basic information about getting - started with the pyboard. - -* `pybcdc.inf `_ -- this is a Windows driver file to configure the serial USB - device. More about this in the next tutorial. - -Editing ``main.py`` -------------------- - -Now we are going to write our Python program, so open the ``main.py`` -file in a text editor. On Windows you can use notepad, or any other editor. -On Mac and Linux, use your favourite text editor. With the file open you will -see it contains 1 line:: - - # main.py -- put your code here! - -This line starts with a # character, which means that it is a *comment*. Such -lines will not do anything, and are there for you to write notes about your -program. - -Let's add 2 lines to this ``main.py`` file, to make it look like this:: - - # main.py -- put your code here! - import pyb - pyb.LED(4).on() - -The first line we wrote says that we want to use the ``pyb`` module. -This module contains all the functions and classes to control the features -of the pyboard. - -The second line that we wrote turns the blue LED on: it first gets the ``LED`` -class from the ``pyb`` module, creates LED number 4 (the blue LED), and then -turns it on. - -Resetting the pyboard ---------------------- - -To run this little script, you need to first save and close the ``main.py`` file, -and then eject (or unmount) the pyboard USB drive. Do this like you would a -normal USB flash drive. - -When the drive is safely ejected/unmounted you can get to the fun part: -press the RST switch on the pyboard to reset and run your script. The RST -switch is the small black button just below the USB connector on the board, -on the right edge. - -When you press RST the green LED will flash quickly, and then the blue -LED should turn on and stay on. - -Congratulations! You have written and run your very first MicroPython -program! diff --git a/docs/pyboard/tutorial/servo.rst b/docs/pyboard/tutorial/servo.rst deleted file mode 100644 index 83d1b0cc156..00000000000 --- a/docs/pyboard/tutorial/servo.rst +++ /dev/null @@ -1,146 +0,0 @@ -Controlling hobby servo motors -============================== - -There are 4 dedicated connection points on the pyboard for connecting up -hobby servo motors (see eg -[Wikipedia](http://en.wikipedia.org/wiki/Servo_%28radio_control%29)). -These motors have 3 wires: ground, power and signal. On the pyboard you -can connect them in the bottom right corner, with the signal pin on the -far right. Pins X1, X2, X3 and X4 are the 4 dedicated servo signal pins. - -.. image:: img/pyboard_servo.jpg - -In this picture there are male-male double adaptors to connect the servos -to the header pins on the pyboard. - -The ground wire on a servo is usually the darkest coloured one, either -black or dark brown. The power wire will most likely be red. - -The power pin for the servos (labelled VIN) is connected directly to the -input power source of the pyboard. When powered via USB, VIN is powered -through a diode by the 5V USB power line. Connect to USB, the pyboard can -power at least 4 small to medium sized servo motors. - -If using a battery to power the pyboard and run servo motors, make sure it -is not greater than 6V, since this is the maximum voltage most servo motors -can take. (Some motors take only up to 4.8V, so check what type you are -using.) - -Creating a Servo object ------------------------ - -Plug in a servo to position 1 (the one with pin X1) and create a servo object -using:: - - >>> servo1 = pyb.Servo(1) - -To change the angle of the servo use the ``angle`` method:: - - >>> servo1.angle(45) - >>> servo1.angle(-60) - -The angle here is measured in degrees, and ranges from about -90 to +90, -depending on the motor. Calling ``angle`` without parameters will return -the current angle:: - - >>> servo1.angle() - -60 - -Note that for some angles, the returned angle is not exactly the same as -the angle you set, due to rounding errors in setting the pulse width. - -You can pass a second parameter to the ``angle`` method, which specifies how -long to take (in milliseconds) to reach the desired angle. For example, to -take 1 second (1000 milliseconds) to go from the current position to 50 degrees, -use :: - - >>> servo1.angle(50, 1000) - -This command will return straight away and the servo will continue to move -to the desired angle, and stop when it gets there. You can use this feature -as a speed control, or to synchronise 2 or more servo motors. If we have -another servo motor (``servo2 = pyb.Servo(2)``) then we can do :: - - >>> servo1.angle(-45, 2000); servo2.angle(60, 2000) - -This will move the servos together, making them both take 2 seconds to -reach their final angles. - -Note: the semicolon between the 2 expressions above is used so that they -are executed one after the other when you press enter at the REPL prompt. -In a script you don't need to do this, you can just write them one line -after the other. - -Continuous rotation servos --------------------------- - -So far we have been using standard servos that move to a specific angle -and stay at that angle. These servo motors are useful to create joints -of a robot, or things like pan-tilt mechanisms. Internally, the motor -has a variable resistor (potentiometer) which measures the current angle -and applies power to the motor proportional to how far it is from the -desired angle. The desired angle is set by the width of a high-pulse on -the servo signal wire. A pulse width of 1500 microsecond corresponds -to the centre position (0 degrees). The pulses are sent at 50 Hz, ie -50 pulses per second. - -You can also get **continuous rotation** servo motors which turn -continuously clockwise or counterclockwise. The direction and speed of -rotation is set by the pulse width on the signal wire. A pulse width -of 1500 microseconds corresponds to a stopped motor. A pulse width -smaller or larger than this means rotate one way or the other, at a -given speed. - -On the pyboard, the servo object for a continuous rotation motor is -the same as before. In fact, using ``angle`` you can set the speed. But -to make it easier to understand what is intended, there is another method -called ``speed`` which sets the speed:: - - >>> servo1.speed(30) - -``speed`` has the same functionality as ``angle``: you can get the speed, -set it, and set it with a time to reach the final speed. :: - - >>> servo1.speed() - 30 - >>> servo1.speed(-20) - >>> servo1.speed(0, 2000) - -The final command above will set the motor to stop, but take 2 seconds -to do it. This is essentially a control over the acceleration of the -continuous servo. - -A servo speed of 100 (or -100) is considered maximum speed, but actually -you can go a bit faster than that, depending on the particular motor. - -The only difference between the ``angle`` and ``speed`` methods (apart from -the name) is the way the input numbers (angle or speed) are converted to -a pulse width. - -Calibration ------------ - -The conversion from angle or speed to pulse width is done by the servo -object using its calibration values. To get the current calibration, -use :: - - >>> servo1.calibration() - (640, 2420, 1500, 2470, 2200) - -There are 5 numbers here, which have meaning: - -1. Minimum pulse width; the smallest pulse width that the servo accepts. -2. Maximum pulse width; the largest pulse width that the servo accepts. -3. Centre pulse width; the pulse width that puts the servo at 0 degrees - or 0 speed. -4. The pulse width corresponding to 90 degrees. This sets the conversion - in the method ``angle`` of angle to pulse width. -5. The pulse width corresponding to a speed of 100. This sets the conversion - in the method ``speed`` of speed to pulse width. - -You can recalibrate the servo (change its default values) by using:: - - >>> servo1.calibration(700, 2400, 1510, 2500, 2000) - -Of course, you would change the above values to suit your particular -servo motor. diff --git a/docs/pyboard/tutorial/switch.rst b/docs/pyboard/tutorial/switch.rst deleted file mode 100644 index 91683fba453..00000000000 --- a/docs/pyboard/tutorial/switch.rst +++ /dev/null @@ -1,113 +0,0 @@ -The Switch, callbacks and interrupts -==================================== - -The pyboard has 2 small switches, labelled USR and RST. The RST switch -is a hard-reset switch, and if you press it then it restarts the pyboard -from scratch, equivalent to turning the power off then back on. - -The USR switch is for general use, and is controlled via a Switch object. -To make a switch object do:: - - >>> sw = pyb.Switch() - -Remember that you may need to type ``import pyb`` if you get an error that -the name ``pyb`` does not exist. - -With the switch object you can get its status:: - - >>> sw.value() - False - -This will print ``False`` if the switch is not held, or ``True`` if it is held. -Try holding the USR switch down while running the above command. - -There is also a shorthand notation to get the switch status, by "calling" the -switch object:: - - >>> sw() - False - -Switch callbacks ----------------- - -The switch is a very simple object, but it does have one advanced feature: -the ``sw.callback()`` function. The callback function sets up something to -run when the switch is pressed, and uses an interrupt. It's probably best -to start with an example before understanding how interrupts work. Try -running the following at the prompt:: - - >>> sw.callback(lambda:print('press!')) - -This tells the switch to print ``press!`` each time the switch is pressed -down. Go ahead and try it: press the USR switch and watch the output on -your PC. Note that this print will interrupt anything you are typing, and -is an example of an interrupt routine running asynchronously. - -As another example try:: - - >>> sw.callback(lambda:pyb.LED(1).toggle()) - -This will toggle the red LED each time the switch is pressed. And it will -even work while other code is running. - -To disable the switch callback, pass ``None`` to the callback function:: - - >>> sw.callback(None) - -You can pass any function (that takes zero arguments) to the switch callback. -Above we used the ``lambda`` feature of Python to create an anonymous function -on the fly. But we could equally do:: - - >>> def f(): - ... pyb.LED(1).toggle() - ... - >>> sw.callback(f) - -This creates a function called ``f`` and assigns it to the switch callback. -You can do things this way when your function is more complicated than a -``lambda`` will allow. - -Note that your callback functions must not allocate any memory (for example -they cannot create a tuple or list). Callback functions should be relatively -simple. If you need to make a list, make it beforehand and store it in a -global variable (or make it local and close over it). If you need to do -a long, complicated calculation, then use the callback to set a flag which -some other code then responds to. - -Technical details of interrupts -------------------------------- - -Let's step through the details of what is happening with the switch -callback. When you register a function with ``sw.callback()``, the switch -sets up an external interrupt trigger (falling edge) on the pin that the -switch is connected to. This means that the microcontroller will listen -on the pin for any changes, and the following will occur: - -1. When the switch is pressed a change occurs on the pin (the pin goes - from low to high), and the microcontroller registers this change. -2. The microcontroller finishes executing the current machine instruction, - stops execution, and saves its current state (pushes the registers on - the stack). This has the effect of pausing any code, for example your - running Python script. -3. The microcontroller starts executing the special interrupt handler - associated with the switch's external trigger. This interrupt handler - get the function that you registered with ``sw.callback()`` and executes - it. -4. Your callback function is executed until it finishes, returning control - to the switch interrupt handler. -5. The switch interrupt handler returns, and the microcontroller is - notified that the interrupt has been dealt with. -6. The microcontroller restores the state that it saved in step 2. -7. Execution continues of the code that was running at the beginning. Apart - from the pause, this code does not notice that it was interrupted. - -The above sequence of events gets a bit more complicated when multiple -interrupts occur at the same time. In that case, the interrupt with the -highest priority goes first, then the others in order of their priority. -The switch interrupt is set at the lowest priority. - -Further reading ---------------- - -For further information about using hardware interrupts see -:ref:`writing interrupt handlers `. diff --git a/docs/pyboard/tutorial/timer.rst b/docs/pyboard/tutorial/timer.rst deleted file mode 100644 index aedaaa13c53..00000000000 --- a/docs/pyboard/tutorial/timer.rst +++ /dev/null @@ -1,114 +0,0 @@ -The Timers -========== - -The pyboard has 14 timers which each consist of an independent counter -running at a user-defined frequency. They can be set up to run a function -at specific intervals. -The 14 timers are numbered 1 through 14, but 3 is reserved -for internal use, and 5 and 6 are used for servo and ADC/DAC control. -Avoid using these timers if possible. - -Let's create a timer object:: - - >>> tim = pyb.Timer(4) - -Now let's see what we just created:: - - >>> tim - Timer(4) - -The pyboard is telling us that ``tim`` is attached to timer number 4, but -it's not yet initialised. So let's initialise it to trigger at 10 Hz -(that's 10 times per second):: - - >>> tim.init(freq=10) - -Now that it's initialised, we can see some information about the timer:: - - >>> tim - Timer(4, prescaler=624, period=13439, mode=UP, div=1) - -The information means that this timer is set to run at the peripheral -clock speed divided by 624+1, and it will count from 0 up to 13439, at which -point it triggers an interrupt, and then starts counting again from 0. These -numbers are set to make the timer trigger at 10 Hz: the source frequency -of the timer is 84MHz (found by running ``tim.source_freq()``) so we -get 84MHz / 625 / 13440 = 10Hz. - -Timer counter -------------- - -So what can we do with our timer? The most basic thing is to get the -current value of its counter:: - - >>> tim.counter() - 21504 - -This counter will continuously change, and counts up. - -Timer callbacks ---------------- - -The next thing we can do is register a callback function for the timer to -execute when it triggers (see the [switch tutorial](tut-switch) for an -introduction to callback functions):: - - >>> tim.callback(lambda t:pyb.LED(1).toggle()) - -This should start the red LED flashing right away. It will be flashing -at 5 Hz (2 toggle's are needed for 1 flash, so toggling at 10 Hz makes -it flash at 5 Hz). You can change the frequency by re-initialising the -timer:: - - >>> tim.init(freq=20) - -You can disable the callback by passing it the value ``None``:: - - >>> tim.callback(None) - -The function that you pass to callback must take 1 argument, which is -the timer object that triggered. This allows you to control the timer -from within the callback function. - -We can create 2 timers and run them independently:: - - >>> tim4 = pyb.Timer(4, freq=10) - >>> tim7 = pyb.Timer(7, freq=20) - >>> tim4.callback(lambda t: pyb.LED(1).toggle()) - >>> tim7.callback(lambda t: pyb.LED(2).toggle()) - -Because the callbacks are proper hardware interrupts, we can continue -to use the pyboard for other things while these timers are running. - -Making a microsecond counter ----------------------------- - -You can use a timer to create a microsecond counter, which might be -useful when you are doing something which requires accurate timing. -We will use timer 2 for this, since timer 2 has a 32-bit counter (so -does timer 5, but if you use timer 5 then you can't use the Servo -driver at the same time). - -We set up timer 2 as follows:: - - >>> micros = pyb.Timer(2, prescaler=83, period=0x3fffffff) - -The prescaler is set at 83, which makes this timer count at 1 MHz. -This is because the CPU clock, running at 168 MHz, is divided by -2 and then by prescaler+1, giving a frequency of 168 MHz/2/(83+1)=1 MHz -for timer 2. The period is set to a large number so that the timer -can count up to a large number before wrapping back around to zero. -In this case it will take about 17 minutes before it cycles back to -zero. - -To use this timer, it's best to first reset it to 0:: - - >>> micros.counter(0) - -and then perform your timing:: - - >>> start_micros = micros.counter() - - ... do some stuff ... - - >>> end_micros = micros.counter() diff --git a/docs/pyboard/tutorial/usb_mouse.rst b/docs/pyboard/tutorial/usb_mouse.rst deleted file mode 100644 index 6f8831edb46..00000000000 --- a/docs/pyboard/tutorial/usb_mouse.rst +++ /dev/null @@ -1,131 +0,0 @@ -Making the pyboard act as a USB mouse -===================================== - -The pyboard is a USB device, and can configured to act as a mouse instead -of the default USB flash drive. - -To do this we must first edit the ``boot.py`` file to change the USB -configuration. If you have not yet touched your ``boot.py`` file then it -will look something like this:: - - # boot.py -- run on boot-up - # can run arbitrary Python, but best to keep it minimal - - import pyb - #pyb.main('main.py') # main script to run after this one - #pyb.usb_mode('VCP+MSC') # act as a serial and a storage device - #pyb.usb_mode('VCP+HID') # act as a serial device and a mouse - -To enable the mouse mode, uncomment the last line of the file, to -make it look like:: - - pyb.usb_mode('VCP+HID') # act as a serial device and a mouse - -If you already changed your ``boot.py`` file, then the minimum code it -needs to work is:: - - import pyb - pyb.usb_mode('VCP+HID') - -This tells the pyboard to configure itself as a VCP (Virtual COM Port, -ie serial port) and HID (human interface device, in our case a mouse) -USB device when it boots up. - -Eject/unmount the pyboard drive and reset it using the RST switch. -Your PC should now detect the pyboard as a mouse! - -Sending mouse events by hand ----------------------------- - -To get the py-mouse to do anything we need to send mouse events to the PC. -We will first do this manually using the REPL prompt. Connect to your -pyboard using your serial program and type the following:: - - >>> hid = pyb.USB_HID() - >>> hid.send((0, 10, 0, 0)) - -Your mouse should move 10 pixels to the right! In the command above you -are sending 4 pieces of information: button status, x, y and scroll. The -number 10 is telling the PC that the mouse moved 10 pixels in the x direction. - -Let's make the mouse oscillate left and right:: - - >>> import math - >>> def osc(n, d): - ... for i in range(n): - ... hid.send((0, int(20 * math.sin(i / 10)), 0, 0)) - ... pyb.delay(d) - ... - >>> osc(100, 50) - -The first argument to the function ``osc`` is the number of mouse events to send, -and the second argument is the delay (in milliseconds) between events. Try -playing around with different numbers. - -**Exercise: make the mouse go around in a circle.** - -Making a mouse with the accelerometer -------------------------------------- - -Now lets make the mouse move based on the angle of the pyboard, using the -accelerometer. The following code can be typed directly at the REPL prompt, -or put in the ``main.py`` file. Here, we'll put in in ``main.py`` because to do -that we will learn how to go into safe mode. - -At the moment the pyboard is acting as a serial USB device and an HID (a mouse). -So you cannot access the filesystem to edit your ``main.py`` file. - -You also can't edit your ``boot.py`` to get out of HID-mode and back to normal -mode with a USB drive... - -To get around this we need to go into *safe mode*. This was described in -the [safe mode tutorial](tut-reset), but we repeat the instructions here: - -1. Hold down the USR switch. -2. While still holding down USR, press and release the RST switch. -3. The LEDs will then cycle green to orange to green+orange and back again. -4. Keep holding down USR until *only the orange LED is lit*, and then let - go of the USR switch. -5. The orange LED should flash quickly 4 times, and then turn off. -6. You are now in safe mode. - -In safe mode, the ``boot.py`` and ``main.py`` files are not executed, and so -the pyboard boots up with default settings. This means you now have access -to the filesystem (the USB drive should appear), and you can edit ``main.py``. -(Leave ``boot.py`` as-is, because we still want to go back to HID-mode after -we finish editing ``main.py``.) - -In ``main.py`` put the following code:: - - import pyb - - switch = pyb.Switch() - accel = pyb.Accel() - hid = pyb.USB_HID() - - while not switch(): - hid.send((0, accel.x(), accel.y(), 0)) - pyb.delay(20) - -Save your file, eject/unmount your pyboard drive, and reset it using the RST -switch. It should now act as a mouse, and the angle of the board will move -the mouse around. Try it out, and see if you can make the mouse stand still! - -Press the USR switch to stop the mouse motion. - -You'll note that the y-axis is inverted. That's easy to fix: just put a -minus sign in front of the y-coordinate in the ``hid.send()`` line above. - -Restoring your pyboard to normal --------------------------------- - -If you leave your pyboard as-is, it'll behave as a mouse everytime you plug -it in. You probably want to change it back to normal. To do this you need -to first enter safe mode (see above), and then edit the ``boot.py`` file. -In the ``boot.py`` file, comment out (put a # in front of) the line with the -``VCP+HID`` setting, so it looks like:: - - #pyb.usb_mode('VCP+HID') # act as a serial device and a mouse - -Save your file, eject/unmount the drive, and reset the pyboard. It is now -back to normal operating mode. diff --git a/docs/pyboard_index.rst b/docs/pyboard_index.rst deleted file mode 100644 index 2255a75607a..00000000000 --- a/docs/pyboard_index.rst +++ /dev/null @@ -1,12 +0,0 @@ -MicroPython documentation and references -======================================== - -.. toctree:: - - pyboard/quickref.rst - pyboard/general.rst - pyboard/tutorial/index.rst - library/index.rst - reference/index.rst - genrst/index.rst - license.rst diff --git a/docs/reference/asm_thumb2_arith.rst b/docs/reference/asm_thumb2_arith.rst deleted file mode 100644 index da4a688525a..00000000000 --- a/docs/reference/asm_thumb2_arith.rst +++ /dev/null @@ -1,50 +0,0 @@ -Arithmetic instructions -======================= - -Document conventions --------------------- - -Notation: ``Rd, Rm, Rn`` denote ARM registers R0-R7. ``immN`` denotes an immediate -value having a width of N bits e.g. ``imm8``, ``imm3``. ``carry`` denotes -the carry condition flag, ``not(carry)`` denotes its complement. In the case of instructions -with more than one register argument, it is permissible for some to be identical. For example -the following will add the contents of R0 to itself, placing the result in R0: - -* add(r0, r0, r0) - -Arithmetic instructions affect the condition flags except where stated. - -Addition --------- - -* add(Rdn, imm8) ``Rdn = Rdn + imm8`` -* add(Rd, Rn, imm3) ``Rd = Rn + imm3`` -* add(Rd, Rn, Rm) ``Rd = Rn +Rm`` -* adc(Rd, Rn) ``Rd = Rd + Rn + carry`` - -Subtraction ------------ - -* sub(Rdn, imm8) ``Rdn = Rdn - imm8`` -* sub(Rd, Rn, imm3) ``Rd = Rn - imm3`` -* sub(Rd, Rn, Rm) ``Rd = Rn - Rm`` -* sbc(Rd, Rn) ``Rd = Rd - Rn - not(carry)`` - -Negation --------- - -* neg(Rd, Rn) ``Rd = -Rn`` - -Multiplication and division ---------------------------- - -* mul(Rd, Rn) ``Rd = Rd * Rn`` - -This produces a 32 bit result with overflow lost. The result may be treated as -signed or unsigned according to the definition of the operands. - -* sdiv(Rd, Rn, Rm) ``Rd = Rn / Rm`` -* udiv(Rd, Rn, Rm) ``Rd = Rn / Rm`` - -These functions perform signed and unsigned division respectively. Condition flags -are not affected. diff --git a/docs/reference/asm_thumb2_compare.rst b/docs/reference/asm_thumb2_compare.rst deleted file mode 100644 index 521af69da3b..00000000000 --- a/docs/reference/asm_thumb2_compare.rst +++ /dev/null @@ -1,90 +0,0 @@ -Comparison instructions -======================= - -These perform an arithmetic or logical instruction on two arguments, discarding the result -but setting the condition flags. Typically these are used to test data values without changing -them prior to executing a conditional branch. - -Document conventions --------------------- - -Notation: ``Rd, Rm, Rn`` denote ARM registers R0-R7. ``imm8`` denotes an immediate -value having a width of 8 bits. - -The Application Program Status Register (APSR) ----------------------------------------------- - -This contains four bits which are tested by the conditional branch instructions. Typically a -conditional branch will test multiple bits, for example ``bge(LABEL)``. The meaning of -condition codes can depend on whether the operands of an arithmetic instruction are viewed as -signed or unsigned integers. Thus ``bhi(LABEL)`` assumes unsigned numbers were processed while -``bgt(LABEL)`` assumes signed operands. - -APSR Bits ---------- - -* Z (zero) - -This is set if the result of an operation is zero or the operands of a comparison are equal. - -* N (negative) - -Set if the result is negative. - -* C (carry) - -An addition sets the carry flag when the result overflows out of the MSB, for example adding -0x80000000 and 0x80000000. By the nature of two's complement arithmetic this behaviour is reversed -on subtraction, with a borrow indicated by the carry bit being clear. Thus 0x10 - 0x01 is executed -as 0x10 + 0xffffffff which will set the carry bit. - -* V (overflow) - -The overflow flag is set if the result, viewed as a two's compliment number, has the "wrong" sign -in relation to the operands. For example adding 1 to 0x7fffffff will set the overflow bit because -the result (0x8000000), viewed as a two's complement integer, is negative. Note that in this instance -the carry bit is not set. - -Comparison instructions ------------------------ - -These set the APSR (Application Program Status Register) N (negative), Z (zero), C (carry) and V -(overflow) flags. - -* cmp(Rn, imm8) ``Rn - imm8`` -* cmp(Rn, Rm) ``Rn - Rm`` -* cmn(Rn, Rm) ``Rn + Rm`` -* tst(Rn, Rm) ``Rn & Rm`` - -Conditional execution ---------------------- - -The ``it`` and ``ite`` instructions provide a means of conditionally executing from one to four subsequent -instructions without the need for a label. - -* it() If then - -Execute the next instruction if is true: - -:: - - cmp(r0, r1) - it(eq) - mov(r0, 100) # runs if r0 == r1 - # execution continues here - -* ite() If then else - -If is true, execute the next instruction, otherwise execute the -subsequent one. Thus: - -:: - - cmp(r0, r1) - ite(eq) - mov(r0, 100) # runs if r0 == r1 - mov(r0, 200) # runs if r0 != r1 - # execution continues here - -This may be extended to control the execution of upto four subsequent instructions: it[x[y[z]]] -where x,y,z=t/e; e.g. itt, itee, itete, ittte, itttt, iteee, etc. diff --git a/docs/reference/asm_thumb2_directives.rst b/docs/reference/asm_thumb2_directives.rst deleted file mode 100644 index 95acd7781fd..00000000000 --- a/docs/reference/asm_thumb2_directives.rst +++ /dev/null @@ -1,36 +0,0 @@ -Assembler Directives -==================== - -Labels ------- - -* label(INNER1) - -This defines a label for use in a branch instruction. Thus elsewhere in the code a ``b(INNER1)`` -will cause execution to continue with the instruction after the label directive. - -Defining inline data --------------------- - -The following assembler directives facilitate embedding data in an assembler code block. - -* data(size, d0, d1 .. dn) - -The data directive creates n array of data values in memory. The first argument specifies the -size in bytes of the subsequent arguments. Hence the first statement below will cause the -assembler to put three bytes (with values 2, 3 and 4) into consecutive memory locations -while the second will cause it to emit two four byte words. - -:: - - data(1, 2, 3, 4) - data(4, 2, 100000) - -Data values longer than a single byte are stored in memory in little-endian format. - -* align(nBytes) - -Align the following instruction to an nBytes value. ARM Thumb-2 instructions must be two -byte aligned, hence it's advisable to issue ``align(2)`` after ``data`` directives and -prior to any subsequent code. This ensures that the code will run irrespective of the -size of the data array. diff --git a/docs/reference/asm_thumb2_float.rst b/docs/reference/asm_thumb2_float.rst deleted file mode 100644 index 4acb734eeb4..00000000000 --- a/docs/reference/asm_thumb2_float.rst +++ /dev/null @@ -1,77 +0,0 @@ -Floating Point instructions -============================== - -These instructions support the use of the ARM floating point coprocessor -(on platforms such as the Pyboard which are equipped with one). The FPU -has 32 registers known as ``s0-s31`` each of which can hold a single -precision float. Data can be passed between the FPU registers and the -ARM core registers with the ``vmov`` instruction. - -Note that MicroPython doesn't support passing floats to -assembler functions, nor can you put a float into ``r0`` and expect a -reasonable result. There are two ways to overcome this. The first is to -use arrays, and the second is to pass and/or return integers and convert -to and from floats in code. - -Document conventions --------------------- - -Notation: ``Sd, Sm, Sn`` denote FPU registers, ``Rd, Rm, Rn`` denote ARM core -registers. The latter can be any ARM core register although registers -``R13-R15`` are unlikely to be appropriate in this context. - -Arithmetic ----------- - -* vadd(Sd, Sn, Sm) ``Sd = Sn + Sm`` -* vsub(Sd, Sn, Sm) ``Sd = Sn - Sm`` -* vneg(Sd, Sm) ``Sd = -Sm`` -* vmul(Sd, Sn, Sm) ``Sd = Sn * Sm`` -* vdiv(Sd, Sn, Sm) ``Sd = Sn / Sm`` -* vsqrt(Sd, Sm) ``Sd = sqrt(Sm)`` - -Registers may be identical: ``vmul(S0, S0, S0)`` will execute ``S0 = S0*S0`` - -Move between ARM core and FPU registers ---------------------------------------- - -* vmov(Sd, Rm) ``Sd = Rm`` -* vmov(Rd, Sm) ``Rd = Sm`` - -The FPU has a register known as FPSCR, similar to the ARM core's APSR, which stores condition -codes plus other data. The following instructions provide access to this. - -* vmrs(APSR\_nzcv, FPSCR) - -Move the floating-point N, Z, C, and V flags to the APSR N, Z, C, and V flags. - -This is done after an instruction such as an FPU -comparison to enable the condition codes to be tested by the assembler -code. The following is a more general form of the instruction. - -* vmrs(Rd, FPSCR) ``Rd = FPSCR`` - -Move between FPU register and memory ------------------------------------- - -* vldr(Sd, [Rn, offset]) ``Sd = [Rn + offset]`` -* vstr(Sd, [Rn, offset]) ``[Rn + offset] = Sd`` - -Where ``[Rn + offset]`` denotes the memory address obtained by adding Rn to the offset. This -is specified in bytes. Since each float value occupies a 32 bit word, when accessing arrays of -floats the offset must always be a multiple of four bytes. - -Data Comparison ---------------- - -* vcmp(Sd, Sm) - -Compare the values in Sd and Sm and set the FPU N, Z, -C, and V flags. This would normally be followed by ``vmrs(APSR_nzcv, FPSCR)`` -to enable the results to be tested. - -Convert between integer and float ---------------------------------- - -* vcvt\_f32\_s32(Sd, Sm) ``Sd = float(Sm)`` -* vcvt\_s32\_f32(Sd, Sm) ``Sd = int(Sm)`` diff --git a/docs/reference/asm_thumb2_hints_tips.rst b/docs/reference/asm_thumb2_hints_tips.rst deleted file mode 100644 index 062a3c8448c..00000000000 --- a/docs/reference/asm_thumb2_hints_tips.rst +++ /dev/null @@ -1,244 +0,0 @@ -Hints and tips -============== - -The following are some examples of the use of the inline assembler and some -information on how to work around its limitations. In this document the term -"assembler function" refers to a function declared in Python with the -``@micropython.asm_thumb`` decorator, whereas "subroutine" refers to assembler -code called from within an assembler function. - -Code branches and subroutines ------------------------------ - -It is important to appreciate that labels are local to an assembler function. -There is currently no way for a subroutine defined in one function to be called -from another. - -To call a subroutine the instruction ``bl(LABEL)`` is issued. This transfers -control to the instruction following the ``label(LABEL)`` directive and stores -the return address in the link register (``lr`` or ``r14``). To return the -instruction ``bx(lr)`` is issued which causes execution to continue with -the instruction following the subroutine call. This mechanism implies that, if -a subroutine is to call another, it must save the link register prior to -the call and restore it before terminating. - -The following rather contrived example illustrates a function call. Note that -it's necessary at the start to branch around all subroutine calls: subroutines -end execution with ``bx(lr)`` while the outer function simply "drops off the end" -in the style of Python functions. - -:: - - @micropython.asm_thumb - def quad(r0): - b(START) - label(DOUBLE) - add(r0, r0, r0) - bx(lr) - label(START) - bl(DOUBLE) - bl(DOUBLE) - - print(quad(10)) - -The following code example demonstrates a nested (recursive) call: the classic -Fibonacci sequence. Here, prior to a recursive call, the link register is saved -along with other registers which the program logic requires to be preserved. - -:: - - @micropython.asm_thumb - def fib(r0): - b(START) - label(DOFIB) - push({r1, r2, lr}) - cmp(r0, 1) - ble(FIBDONE) - sub(r0, 1) - mov(r2, r0) # r2 = n -1 - bl(DOFIB) - mov(r1, r0) # r1 = fib(n -1) - sub(r0, r2, 1) - bl(DOFIB) # r0 = fib(n -2) - add(r0, r0, r1) - label(FIBDONE) - pop({r1, r2, lr}) - bx(lr) - label(START) - bl(DOFIB) - - for n in range(10): - print(fib(n)) - -Argument passing and return ---------------------------- - -The tutorial details the fact that assembler functions can support from zero to -three arguments, which must (if used) be named ``r0``, ``r1`` and ``r2``. When -the code executes the registers will be initialised to those values. - -The data types which can be passed in this way are integers and memory -addresses. With current firmware all possible 32 bit values may be passed and -returned. If the return value may have the most significant bit set a Python -type hint should be employed to enable MicroPython to determine whether the -value should be interpreted as a signed or unsigned integer: types are -``int`` or ``uint``. - -:: - - @micropython.asm_thumb - def uadd(r0, r1) -> uint: - add(r0, r0, r1) - -``hex(uadd(0x40000000,0x40000000))`` will return 0x80000000, demonstrating the -passing and return of integers where bits 30 and 31 differ. - -The limitations on the number of arguments and return values can be overcome by means -of the ``array`` module which enables any number of values of any type to be accessed. - -Multiple arguments -~~~~~~~~~~~~~~~~~~ - -If a Python array of integers is passed as an argument to an assembler -function, the function will receive the address of a contiguous set of integers. -Thus multiple arguments can be passed as elements of a single array. Similarly a -function can return multiple values by assigning them to array elements. -Assembler functions have no means of determining the length of an array: -this will need to be passed to the function. - -This use of arrays can be extended to enable more than three arrays to be used. -This is done using indirection: the ``uctypes`` module supports ``addressof()`` -which will return the address of an array passed as its argument. Thus you can -populate an integer array with the addresses of other arrays: - -:: - - from uctypes import addressof - @micropython.asm_thumb - def getindirect(r0): - ldr(r0, [r0, 0]) # Address of array loaded from passed array - ldr(r0, [r0, 4]) # Return element 1 of indirect array (24) - - def testindirect(): - a = array.array('i',[23, 24]) - b = array.array('i',[0,0]) - b[0] = addressof(a) - print(getindirect(b)) - -Non-integer data types -~~~~~~~~~~~~~~~~~~~~~~ - -These may be handled by means of arrays of the appropriate data type. For -example, single precision floating point data may be processed as follows. -This code example takes an array of floats and replaces its contents with -their squares. - -:: - - from array import array - - @micropython.asm_thumb - def square(r0, r1): - label(LOOP) - vldr(s0, [r0, 0]) - vmul(s0, s0, s0) - vstr(s0, [r0, 0]) - add(r0, 4) - sub(r1, 1) - bgt(LOOP) - - a = array('f', (x for x in range(10))) - square(a, len(a)) - print(a) - -The uctypes module supports the use of data structures beyond simple -arrays. It enables a Python data structure to be mapped onto a bytearray -instance which may then be passed to the assembler function. - -Named constants ---------------- - -Assembler code may be made more readable and maintainable by using named -constants rather than littering code with numbers. This may be achieved -thus: - -:: - - MYDATA = const(33) - - @micropython.asm_thumb - def foo(): - mov(r0, MYDATA) - -The const() construct causes MicroPython to replace the variable name -with its value at compile time. If constants are declared in an outer -Python scope they can be shared between multiple assembler functions and -with Python code. - -Assembler code as class methods -------------------------------- - -MicroPython passes the address of the object instance as the first argument -to class methods. This is normally of little use to an assembler function. -It can be avoided by declaring the function as a static method thus: - -:: - - class foo: - @staticmethod - @micropython.asm_thumb - def bar(r0): - add(r0, r0, r0) - -Use of unsupported instructions -------------------------------- - -These can be coded using the data statement as shown below. While -``push()`` and ``pop()`` are supported the example below illustrates the -principle. The necessary machine code may be found in the ARM v7-M -Architecture Reference Manual. Note that the first argument of data -calls such as - -:: - - data(2, 0xe92d, 0x0f00) # push r8,r9,r10,r11 - -indicates that each subsequent argument is a two byte quantity. - -Overcoming MicroPython's integer restriction --------------------------------------------- - -The Pyboard chip includes a CRC generator. Its use presents a problem in -MicroPython because the returned values cover the full gamut of 32 bit -quantities whereas small integers in MicroPython cannot have differing values -in bits 30 and 31. This limitation is overcome with the following code, which -uses assembler to put the result into an array and Python code to -coerce the result into an arbitrary precision unsigned integer. - -:: - - from array import array - import stm - - def enable_crc(): - stm.mem32[stm.RCC + stm.RCC_AHB1ENR] |= 0x1000 - - def reset_crc(): - stm.mem32[stm.CRC+stm.CRC_CR] = 1 - - @micropython.asm_thumb - def getval(r0, r1): - movwt(r3, stm.CRC + stm.CRC_DR) - str(r1, [r3, 0]) - ldr(r2, [r3, 0]) - str(r2, [r0, 0]) - - def getcrc(value): - a = array('i', [0]) - getval(a, value) - return a[0] & 0xffffffff # coerce to arbitrary precision - - enable_crc() - reset_crc() - for x in range(20): - print(hex(getcrc(0))) diff --git a/docs/reference/asm_thumb2_index.rst b/docs/reference/asm_thumb2_index.rst deleted file mode 100644 index f066e6acec5..00000000000 --- a/docs/reference/asm_thumb2_index.rst +++ /dev/null @@ -1,73 +0,0 @@ -.. _asm_thumb2_index: - -Inline Assembler for Thumb2 architectures -========================================= - -This document assumes some familiarity with assembly language programming and should be read after studying -the :ref:`tutorial `. For a detailed description of the instruction set consult the -Architecture Reference Manual detailed below. -The inline assembler supports a subset of the ARM Thumb-2 instruction set described here. The syntax tries -to be as close as possible to that defined in the above ARM manual, converted to Python function calls. - -Instructions operate on 32 bit signed integer data except where stated otherwise. Most supported instructions -operate on registers ``R0-R7`` only: where ``R8-R15`` are supported this is stated. Registers ``R8-R12`` must be -restored to their initial value before return from a function. Registers ``R13-R15`` constitute the Link Register, -Stack Pointer and Program Counter respectively. - -Document conventions --------------------- - -Where possible the behaviour of each instruction is described in Python, for example - -* add(Rd, Rn, Rm) ``Rd = Rn + Rm`` - -This enables the effect of instructions to be demonstrated in Python. In certain case this is impossible -because Python doesn't support concepts such as indirection. The pseudocode employed in such cases is -described on the relevant page. - -Instruction Categories ----------------------- - -The following sections details the subset of the ARM Thumb-2 instruction set supported by MicroPython. - -.. toctree:: - :maxdepth: 1 - :numbered: - - asm_thumb2_mov.rst - asm_thumb2_ldr.rst - asm_thumb2_str.rst - asm_thumb2_logical_bit.rst - asm_thumb2_arith.rst - asm_thumb2_compare.rst - asm_thumb2_label_branch.rst - asm_thumb2_stack.rst - asm_thumb2_misc.rst - asm_thumb2_float.rst - asm_thumb2_directives.rst - -Usage examples --------------- - -These sections provide further code examples and hints on the use of the assembler. - -.. toctree:: - :maxdepth: 1 - :numbered: - - asm_thumb2_hints_tips.rst - -References ----------- - -- :ref:`Assembler Tutorial ` -- `Wiki hints and tips - `__ -- `uPy Inline Assembler source-code, - emitinlinethumb.c `__ -- `ARM Thumb2 Instruction Set Quick Reference - Card `__ -- `RM0090 Reference - Manual `__ -- ARM v7-M Architecture Reference Manual (Available on the - ARM site after a simple registration procedure. Also available on academic sites but beware of out of date versions.) diff --git a/docs/reference/asm_thumb2_label_branch.rst b/docs/reference/asm_thumb2_label_branch.rst deleted file mode 100644 index 8c85e55f0e8..00000000000 --- a/docs/reference/asm_thumb2_label_branch.rst +++ /dev/null @@ -1,85 +0,0 @@ -Branch instructions -=================== - -These cause execution to jump to a target location usually specified by a label (see the ``label`` -assembler directive). Conditional branches and the ``it`` and ``ite`` instructions test -the Application Program Status Register (APSR) N (negative), Z (zero), C (carry) and V -(overflow) flags to determine whether the branch should be executed. - -Most of the exposed assembler instructions (including move operations) set the flags but -there are explicit comparison instructions to enable values to be tested. - -Further detail on the meaning of the condition flags is provided in the section -describing comparison functions. - -Document conventions --------------------- - -Notation: ``Rm`` denotes ARM registers R0-R15. ``LABEL`` denotes a label defined with the -``label()`` assembler directive. ```` indicates one of the following condition -specifiers: - -* eq Equal to (result was zero) -* ne Not equal -* cs Carry set -* cc Carry clear -* mi Minus (negative) -* pl Plus (positive) -* vs Overflow set -* vc Overflow clear -* hi > (unsigned comparison) -* ls <= (unsigned comparison) -* ge >= (signed comparison) -* lt < (signed comparison) -* gt > (signed comparison) -* le <= (signed comparison) - -Branch to label ---------------- - -* b(LABEL) Unconditional branch -* beq(LABEL) branch if equal -* bne(LABEL) branch if not equal -* bge(LABEL) branch if greater than or equal -* bgt(LABEL) branch if greater than -* blt(LABEL) branch if less than (<) (signed) -* ble(LABEL) branch if less than or equal to (<=) (signed) -* bcs(LABEL) branch if carry flag is set -* bcc(LABEL) branch if carry flag is clear -* bmi(LABEL) branch if negative -* bpl(LABEL) branch if positive -* bvs(LABEL) branch if overflow flag set -* bvc(LABEL) branch if overflow flag is clear -* bhi(LABEL) branch if higher (unsigned) -* bls(LABEL) branch if lower or equal (unsigned) - -Long branches -------------- - -The code produced by the branch instructions listed above uses a fixed bit width to specify the -branch destination, which is PC relative. Consequently in long programs where the -branch instruction is remote from its destination the assembler will produce a "branch not in -range" error. This can be overcome with the "wide" variants such as - -* beq\_w(LABEL) long branch if equal - -Wide branches use 4 bytes to encode the instruction (compared with 2 bytes for standard branch instructions). - -Subroutines (functions) ------------------------ - -When entering a subroutine the processor stores the return address in register r14, also -known as the link register (lr). Return to the instruction after the subroutine call is -performed by updating the program counter (r15 or pc) from the link register, This -process is handled by the following instructions. - -* bl(LABEL) - -Transfer execution to the instruction after ``LABEL`` storing the return address in -the link register (r14). - -* bx(Rm) Branch to address specified by Rm. - -Typically ``bx(lr)`` is issued to return from a subroutine. For nested subroutines the -link register of outer scopes must be saved (usually on the stack) before performing -inner subroutine calls. diff --git a/docs/reference/asm_thumb2_ldr.rst b/docs/reference/asm_thumb2_ldr.rst deleted file mode 100644 index 16b77295929..00000000000 --- a/docs/reference/asm_thumb2_ldr.rst +++ /dev/null @@ -1,23 +0,0 @@ -Load register from memory -========================= - -Document conventions --------------------- - -Notation: ``Rt, Rn`` denote ARM registers R0-R7 except where stated. ``immN`` represents an immediate -value having a width of N bits hence ``imm5`` is constrained to the range 0-31. ``[Rn + immN]`` is the contents -of the memory address obtained by adding Rn and the offset ``immN``. Offsets are measured in -bytes. These instructions affect the condition flags. - -Register Load -------------- - -* ldr(Rt, [Rn, imm7]) ``Rt = [Rn + imm7]`` Load a 32 bit word -* ldrb(Rt, [Rn, imm5]) ``Rt = [Rn + imm5]`` Load a byte -* ldrh(Rt, [Rn, imm6]) ``Rt = [Rn + imm6]`` Load a 16 bit half word - -Where a byte or half word is loaded, it is zero-extended to 32 bits. - -The specified immediate offsets are measured in bytes. Hence in the case of ``ldr`` the 7 bit value -enables 32 bit word aligned values to be accessed with a maximum offset of 31 words. In the case of ``ldrh`` the -6 bit value enables 16 bit half-word aligned values to be accessed with a maximum offset of 31 half-words. diff --git a/docs/reference/asm_thumb2_logical_bit.rst b/docs/reference/asm_thumb2_logical_bit.rst deleted file mode 100644 index 8c51feaf45f..00000000000 --- a/docs/reference/asm_thumb2_logical_bit.rst +++ /dev/null @@ -1,53 +0,0 @@ -Logical & Bitwise instructions -============================== - -Document conventions --------------------- - -Notation: ``Rd, Rn`` denote ARM registers R0-R7 except in the case of the -special instructions where R0-R15 may be used. ``Rn`` denotes an ARM register -whose contents must lie in range ``a <= contents <= b``. In the case of instructions -with two register arguments, it is permissible for them to be identical. For example -the following will zero R0 (Python ``R0 ^= R0``) regardless of its initial contents. - -* eor(r0, r0) - -These instructions affect the condition flags except where stated. - -Logical instructions --------------------- - -* and\_(Rd, Rn) ``Rd &= Rn`` -* orr(Rd, Rn) ``Rd |= Rn`` -* eor(Rd, Rn) ``Rd ^= Rn`` -* mvn(Rd, Rn) ``Rd = Rn ^ 0xffffffff`` i.e. Rd = 1's complement of Rn -* bic(Rd, Rn) ``Rd &= ~Rn`` bit clear Rd using mask in Rn - -Note the use of "and\_" instead of "and", because "and" is a reserved keyword in Python. - -Shift and rotation instructions -------------------------------- - -* lsl(Rd, Rn<0-31>) ``Rd <<= Rn`` -* lsr(Rd, Rn<1-32>) ``Rd = (Rd & 0xffffffff) >> Rn`` Logical shift right -* asr(Rd, Rn<1-32>) ``Rd >>= Rn`` arithmetic shift right -* ror(Rd, Rn<1-31>) ``Rd = rotate_right(Rd, Rn)`` Rd is rotated right Rn bits. - -A rotation by (for example) three bits works as follows. If Rd initially -contains bits ``b31 b30..b0`` after rotation it will contain ``b2 b1 b0 b31 b30..b3`` - -Special instructions --------------------- - -Condition codes are unaffected by these instructions. - -* clz(Rd, Rn) ``Rd = count_leading_zeros(Rn)`` - -count_leading_zeros(Rn) returns the number of binary zero bits before the first binary one bit in Rn. - -* rbit(Rd, Rn) ``Rd = bit_reverse(Rn)`` - -bit_reverse(Rn) returns the bit-reversed contents of Rn. If Rn contains bits ``b31 b30..b0`` Rd will be set -to ``b0 b1 b2..b31`` - -Trailing zeros may be counted by performing a bit reverse prior to executing clz. diff --git a/docs/reference/asm_thumb2_misc.rst b/docs/reference/asm_thumb2_misc.rst deleted file mode 100644 index ca3f878cca9..00000000000 --- a/docs/reference/asm_thumb2_misc.rst +++ /dev/null @@ -1,13 +0,0 @@ -Miscellaneous instructions -========================== - -* nop() ``pass`` no operation. -* wfi() Suspend execution in a low power state until an interrupt occurs. -* cpsid(flags) set the Priority Mask Register - disable interrupts. -* cpsie(flags) clear the Priority Mask Register - enable interrupts. -* mrs(Rd, special_reg) ``Rd = special_reg`` copy a special register to a general register. The special register - may be IPSR (Interrupt Status Register) or BASEPRI (Base Priority Register). The IPSR provides a means of determining - the exception number of an interrupt being processed. It contains zero if no interrupt is being processed. - -Currently the ``cpsie()`` and ``cpsid()`` functions are partially implemented. -They require but ignore the flags argument and serve as a means of enabling and disabling interrupts. diff --git a/docs/reference/asm_thumb2_mov.rst b/docs/reference/asm_thumb2_mov.rst deleted file mode 100644 index 900bf957b63..00000000000 --- a/docs/reference/asm_thumb2_mov.rst +++ /dev/null @@ -1,27 +0,0 @@ -Register move instructions -========================== - -Document conventions --------------------- - -Notation: ``Rd, Rn`` denote ARM registers R0-R15. ``immN`` denotes an immediate -value having a width of N bits. These instructions affect the condition flags. - -Register moves --------------- - -Where immediate values are used, these are zero-extended to 32 bits. Thus -``mov(R0, 0xff)`` will set R0 to 255. - -* mov(Rd, imm8) ``Rd = imm8`` -* mov(Rd, Rn) ``Rd = Rn`` -* movw(Rd, imm16) ``Rd = imm16`` -* movt(Rd, imm16) ``Rd = (Rd & 0xffff) | (imm16 << 16)`` - -movt writes an immediate value to the top halfword of the destination register. -It does not affect the contents of the bottom halfword. - -* movwt(Rd, imm32) ``Rd = imm32`` - -movwt is a pseudo-instruction: the MicroPython assembler emits a ``movw`` followed -by a ``movt`` to move a 32-bit value into Rd. diff --git a/docs/reference/asm_thumb2_stack.rst b/docs/reference/asm_thumb2_stack.rst deleted file mode 100644 index bffbab277c2..00000000000 --- a/docs/reference/asm_thumb2_stack.rst +++ /dev/null @@ -1,20 +0,0 @@ -Stack push and pop -================== - -Document conventions --------------------- - -The ``push()`` and ``pop()`` instructions accept as their argument a register set containing -a subset, or possibly all, of the general-purpose registers R0-R12 and the link register (lr or R14). -As with any Python set the order in which the registers are specified is immaterial. Thus the -in the following example the pop() instruction would restore R1, R7 and R8 to their contents prior -to the push(): - -* push({r1, r8, r7}) Save three registers on the stack. -* pop({r7, r1, r8}) Restore them - -Stack operations ----------------- - -* push({regset}) Push a set of registers onto the stack -* pop({regset}) Restore a set of registers from the stack diff --git a/docs/reference/asm_thumb2_str.rst b/docs/reference/asm_thumb2_str.rst deleted file mode 100644 index 5a88b091bd6..00000000000 --- a/docs/reference/asm_thumb2_str.rst +++ /dev/null @@ -1,21 +0,0 @@ -Store register to memory -======================== - -Document conventions --------------------- - -Notation: ``Rt, Rn`` denote ARM registers R0-R7 except where stated. ``immN`` represents an immediate -value having a width of N bits hence ``imm5`` is constrained to the range 0-31. ``[Rn + imm5]`` is the -contents of the memory address obtained by adding Rn and the offset ``imm5``. Offsets are measured in -bytes. These instructions do not affect the condition flags. - -Register Store --------------- - -* str(Rt, [Rn, imm7]) ``[Rn + imm7] = Rt`` Store a 32 bit word -* strb(Rt, [Rn, imm5]) ``[Rn + imm5] = Rt`` Store a byte (b0-b7) -* strh(Rt, [Rn, imm6]) ``[Rn + imm6] = Rt`` Store a 16 bit half word (b0-b15) - -The specified immediate offsets are measured in bytes. Hence in the case of ``str`` the 7 bit value -enables 32 bit word aligned values to be accessed with a maximum offset of 31 words. In the case of ``strh`` the -6 bit value enables 16 bit half-word aligned values to be accessed with a maximum offset of 31 half-words. diff --git a/docs/reference/constrained.rst b/docs/reference/constrained.rst deleted file mode 100644 index edac0ae681b..00000000000 --- a/docs/reference/constrained.rst +++ /dev/null @@ -1,456 +0,0 @@ -.. _constrained: - -MicroPython on Microcontrollers -=============================== - -MicroPython is designed to be capable of running on microcontrollers. These -have hardware limitations which may be unfamiliar to programmers more familiar -with conventional computers. In particular the amount of RAM and nonvolatile -"disk" (flash memory) storage is limited. This tutorial offers ways to make -the most of the limited resources. Because MicroPython runs on controllers -based on a variety of architectures, the methods presented are generic: in some -cases it will be necessary to obtain detailed information from platform specific -documentation. - -Flash Memory ------------- - -On the Pyboard the simple way to address the limited capacity is to fit a micro -SD card. In some cases this is impractical, either because the device does not -have an SD card slot or for reasons of cost or power consumption; hence the -on-chip flash must be used. The firmware including the MicroPython subsystem is -stored in the onboard flash. The remaining capacity is available for use. For -reasons connected with the physical architecture of the flash memory part of -this capacity may be inaccessible as a filesystem. In such cases this space may -be employed by incorporating user modules into a firmware build which is then -flashed to the device. - -There are two ways to achieve this: frozen modules and frozen bytecode. Frozen -modules store the Python source with the firmware. Frozen bytecode uses the -cross compiler to convert the source to bytecode which is then stored with the -firmware. In either case the module may be accessed with an import statement: - -.. code:: - - import mymodule - -The procedure for producing frozen modules and bytecode is platform dependent; -instructions for building the firmware can be found in the README files in the -relevant part of the source tree. - -In general terms the steps are as follows: - -* Clone the MicroPython `repository `_. -* Acquire the (platform specific) toolchain to build the firmware. -* Build the cross compiler. -* Place the modules to be frozen in a specified directory (dependent on whether - the module is to be frozen as source or as bytecode). -* Build the firmware. A specific command may be required to build frozen - code of either type - see the platform documentation. -* Flash the firmware to the device. - -RAM ---- - -When reducing RAM usage there are two phases to consider: compilation and -execution. In addition to memory consumption, there is also an issue known as -heap fragmentation. In general terms it is best to minimise the repeated -creation and destruction of objects. The reason for this is covered in the -section covering the `heap`_. - -Compilation Phase -~~~~~~~~~~~~~~~~~ - -When a module is imported, MicroPython compiles the code to bytecode which is -then executed by the MicroPython virtual machine (VM). The bytecode is stored -in RAM. The compiler itself requires RAM, but this becomes available for use -when the compilation has completed. - -If a number of modules have already been imported the situation can arise where -there is insufficient RAM to run the compiler. In this case the import -statement will produce a memory exception. - -If a module instantiates global objects on import it will consume RAM at the -time of import, which is then unavailable for the compiler to use on subsequent -imports. In general it is best to avoid code which runs on import; a better -approach is to have initialisation code which is run by the application after -all modules have been imported. This maximises the RAM available to the -compiler. - -If RAM is still insufficient to compile all modules one solution is to -precompile modules. MicroPython has a cross compiler capable of compiling Python -modules to bytecode (see the README in the mpy-cross directory). The resulting -bytecode file has a .mpy extension; it may be copied to the filesystem and -imported in the usual way. Alternatively some or all modules may be implemented -as frozen bytecode: on most platforms this saves even more RAM as the bytecode -is run directly from flash rather than being stored in RAM. - -Execution Phase -~~~~~~~~~~~~~~~ - -There are a number of coding techniques for reducing RAM usage. - -**Constants** - -MicroPython provides a ``const`` keyword which may be used as follows: - -.. code:: - - from micropython import const - ROWS = const(33) - _COLS = const(0x10) - a = ROWS - b = _COLS - -In both instances where the constant is assigned to a variable the compiler -will avoid coding a lookup to the name of the constant by substituting its -literal value. This saves bytecode and hence RAM. However the ``ROWS`` value -will occupy at least two machine words, one each for the key and value in the -globals dictionary. The presence in the dictionary is necessary because another -module might import or use it. This RAM can be saved by prepending the name -with an underscore as in ``_COLS``: this symbol is not visible outside the -module so will not occupy RAM. - -The argument to ``const()`` may be anything which, at compile time, evaluates -to an integer e.g. ``0x100`` or ``1 << 8``. It can even include other const -symbols that have already been defined, e.g. ``1 << BIT``. - -**Constant data structures** - -Where there is a substantial volume of constant data and the platform supports -execution from Flash, RAM may be saved as follows. The data should be located in -Python modules and frozen as bytecode. The data must be defined as `bytes` -objects. The compiler 'knows' that `bytes` objects are immutable and ensures -that the objects remain in flash memory rather than being copied to RAM. The -`ustruct` module can assist in converting between `bytes` types and other -Python built-in types. - -When considering the implications of frozen bytecode, note that in Python -strings, floats, bytes, integers and complex numbers are immutable. Accordingly -these will be frozen into flash. Thus, in the line - -.. code:: - - mystring = "The quick brown fox" - -the actual string "The quick brown fox" will reside in flash. At runtime a -reference to the string is assigned to the *variable* ``mystring``. The reference -occupies a single machine word. In principle a long integer could be used to -store constant data: - -.. code:: - - bar = 0xDEADBEEF0000DEADBEEF - -As in the string example, at runtime a reference to the arbitrarily large -integer is assigned to the variable ``bar``. That reference occupies a -single machine word. - -It might be expected that tuples of integers could be employed for the purpose -of storing constant data with minimal RAM use. With the current compiler this -is ineffective (the code works, but RAM is not saved). - -.. code:: - - foo = (1, 2, 3, 4, 5, 6, 100000) - -At runtime the tuple will be located in RAM. This may be subject to future -improvement. - -**Needless object creation** - -There are a number of situations where objects may unwittingly be created and -destroyed. This can reduce the usability of RAM through fragmentation. The -following sections discuss instances of this. - -**String concatenation** - -Consider the following code fragments which aim to produce constant strings: - -.. code:: - - var = "foo" + "bar" - var1 = "foo" "bar" - var2 = """\ - foo\ - bar""" - -Each produces the same outcome, however the first needlessly creates two string -objects at runtime, allocates more RAM for concatenation before producing the -third. The others perform the concatenation at compile time which is more -efficient, reducing fragmentation. - -Where strings must be dynamically created before being fed to a stream such as -a file it will save RAM if this is done in a piecemeal fashion. Rather than -creating a large string object, create a substring and feed it to the stream -before dealing with the next. - -The best way to create dynamic strings is by means of the string ``format()`` -method: - -.. code:: - - var = "Temperature {:5.2f} Pressure {:06d}\n".format(temp, press) - -**Buffers** - -When accessing devices such as instances of UART, I2C and SPI interfaces, using -pre-allocated buffers avoids the creation of needless objects. Consider these -two loops: - -.. code:: - - while True: - var = spi.read(100) - # process data - - buf = bytearray(100) - while True: - spi.readinto(buf) - # process data in buf - -The first creates a buffer on each pass whereas the second re-uses a pre-allocated -buffer; this is both faster and more efficient in terms of memory fragmentation. - -**Bytes are smaller than ints** - -On most platforms an integer consumes four bytes. Consider the two calls to the -function ``foo()``: - -.. code:: - - def foo(bar): - for x in bar: - print(x) - foo((1, 2, 0xff)) - foo(b'\1\2\xff') - -In the first call a tuple of integers is created in RAM. The second efficiently -creates a `bytes` object consuming the minimum amount of RAM. If the module -were frozen as bytecode, the `bytes` object would reside in flash. - -**Strings Versus Bytes** - -Python3 introduced Unicode support. This introduced a distinction between a -string and an array of bytes. MicroPython ensures that Unicode strings take no -additional space so long as all characters in the string are ASCII (i.e. have -a value < 126). If values in the full 8-bit range are required `bytes` and -`bytearray` objects can be used to ensure that no additional space will be -required. Note that most string methods (e.g. :meth:`str.strip()`) apply also to `bytes` -instances so the process of eliminating Unicode can be painless. - -.. code:: - - s = 'the quick brown fox' # A string instance - b = b'the quick brown fox' # A bytes instance - -Where it is necessary to convert between strings and bytes the :meth:`str.encode` -and the :meth:`bytes.decode` methods can be used. Note that both strings and bytes -are immutable. Any operation which takes as input such an object and produces -another implies at least one RAM allocation to produce the result. In the -second line below a new bytes object is allocated. This would also occur if ``foo`` -were a string. - -.. code:: - - foo = b' empty whitespace' - foo = foo.lstrip() - -**Runtime compiler execution** - -The Python funcitons `eval` and `exec` invoke the compiler at runtime, which -requires significant amounts of RAM. Note that the ``pickle`` library from -`micropython-lib` employs `exec`. It may be more RAM efficient to use the -`ujson` library for object serialisation. - -**Storing strings in flash** - -Python strings are immutable hence have the potential to be stored in read only -memory. The compiler can place in flash strings defined in Python code. As with -frozen modules it is necessary to have a copy of the source tree on the PC and -the toolchain to build the firmware. The procedure will work even if the -modules have not been fully debugged, so long as they can be imported and run. - -After importing the modules, execute: - -.. code:: - - micropython.qstr_info(1) - -Then copy and paste all the Q(xxx) lines into a text editor. Check for and -remove lines which are obviously invalid. Open the file qstrdefsport.h which -will be found in ports/stm32 (or the equivalent directory for the architecture in -use). Copy and paste the corrected lines at the end of the file. Save the file, -rebuild and flash the firmware. The outcome can be checked by importing the -modules and again issuing: - -.. code:: - - micropython.qstr_info(1) - -The Q(xxx) lines should be gone. - -.. _heap: - -The Heap --------- - -When a running program instantiates an object the necessary RAM is allocated -from a fixed size pool known as the heap. When the object goes out of scope (in -other words becomes inaccessible to code) the redundant object is known as -"garbage". A process known as "garbage collection" (GC) reclaims that memory, -returning it to the free heap. This process runs automatically, however it can -be invoked directly by issuing `gc.collect()`. - -The discourse on this is somewhat involved. For a 'quick fix' issue the -following periodically: - -.. code:: - - gc.collect() - gc.threshold(gc.mem_free() // 4 + gc.mem_alloc()) - -Fragmentation -~~~~~~~~~~~~~ - -Say a program creates an object ``foo``, then an object ``bar``. Subsequently -``foo`` goes out of scope but ``bar`` remains. The RAM used by ``foo`` will be -reclaimed by GC. However if ``bar`` was allocated to a higher address, the -RAM reclaimed from ``foo`` will only be of use for objects no bigger than -``foo``. In a complex or long running program the heap can become fragmented: -despite there being a substantial amount of RAM available, there is insufficient -contiguous space to allocate a particular object, and the program fails with a -memory error. - -The techniques outlined above aim to minimise this. Where large permanent buffers -or other objects are required it is best to instantiate these early in the -process of program execution before fragmentation can occur. Further improvements -may be made by monitoring the state of the heap and by controlling GC; these are -outlined below. - -Reporting -~~~~~~~~~ - -A number of library functions are available to report on memory allocation and -to control GC. These are to be found in the `gc` and `micropython` modules. -The following example may be pasted at the REPL (``ctrl e`` to enter paste mode, -``ctrl d`` to run it). - -.. code:: - - import gc - import micropython - gc.collect() - micropython.mem_info() - print('-----------------------------') - print('Initial free: {} allocated: {}'.format(gc.mem_free(), gc.mem_alloc())) - def func(): - a = bytearray(10000) - gc.collect() - print('Func definition: {} allocated: {}'.format(gc.mem_free(), gc.mem_alloc())) - func() - print('Func run free: {} allocated: {}'.format(gc.mem_free(), gc.mem_alloc())) - gc.collect() - print('Garbage collect free: {} allocated: {}'.format(gc.mem_free(), gc.mem_alloc())) - print('-----------------------------') - micropython.mem_info(1) - -Methods employed above: - -* `gc.collect()` Force a garbage collection. See footnote. -* `micropython.mem_info()` Print a summary of RAM utilisation. -* `gc.mem_free()` Return the free heap size in bytes. -* `gc.mem_alloc()` Return the number of bytes currently allocated. -* ``micropython.mem_info(1)`` Print a table of heap utilisation (detailed below). - -The numbers produced are dependent on the platform, but it can be seen that -declaring the function uses a small amount of RAM in the form of bytecode -emitted by the compiler (the RAM used by the compiler has been reclaimed). -Running the function uses over 10KiB, but on return ``a`` is garbage because it -is out of scope and cannot be referenced. The final `gc.collect()` recovers -that memory. - -The final output produced by ``micropython.mem_info(1)`` will vary in detail but -may be interpreted as follows: - -====== ================= -Symbol Meaning -====== ================= - . free block - h head block - = tail block - m marked head block - T tuple - L list - D dict - F float - B byte code - M module -====== ================= - -Each letter represents a single block of memory, a block being 16 bytes. So each -line of the heap dump represents 0x400 bytes or 1KiB of RAM. - -Control of Garbage Collection -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -A GC can be demanded at any time by issuing `gc.collect()`. It is advantageous -to do this at intervals, firstly to pre-empt fragmentation and secondly for -performance. A GC can take several milliseconds but is quicker when there is -little work to do (about 1ms on the Pyboard). An explicit call can minimise that -delay while ensuring it occurs at points in the program when it is acceptable. - -Automatic GC is provoked under the following circumstances. When an attempt at -allocation fails, a GC is performed and the allocation re-tried. Only if this -fails is an exception raised. Secondly an automatic GC will be triggered if the -amount of free RAM falls below a threshold. This threshold can be adapted as -execution progresses: - -.. code:: - - gc.collect() - gc.threshold(gc.mem_free() // 4 + gc.mem_alloc()) - -This will provoke a GC when more than 25% of the currently free heap becomes -occupied. - -In general modules should instantiate data objects at runtime using constructors -or other initialisation functions. The reason is that if this occurs on -initialisation the compiler may be starved of RAM when subsequent modules are -imported. If modules do instantiate data on import then `gc.collect()` issued -after the import will ameliorate the problem. - -String Operations ------------------ - -MicroPython handles strings in an efficient manner and understanding this can -help in designing applications to run on microcontrollers. When a module -is compiled, strings which occur multiple times are stored once only, a process -known as string interning. In MicroPython an interned string is known as a ``qstr``. -In a module imported normally that single instance will be located in RAM, but -as described above, in modules frozen as bytecode it will be located in flash. - -String comparisons are also performed efficiently using hashing rather than -character by character. The penalty for using strings rather than integers may -hence be small both in terms of performance and RAM usage - a fact which may -come as a surprise to C programmers. - -Postscript ----------- - -MicroPython passes, returns and (by default) copies objects by reference. A -reference occupies a single machine word so these processes are efficient in -RAM usage and speed. - -Where variables are required whose size is neither a byte nor a machine word -there are standard libraries which can assist in storing these efficiently and -in performing conversions. See the `array`, `ustruct` and `uctypes` -modules. - -Footnote: gc.collect() return value -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -On Unix and Windows platforms the `gc.collect()` method returns an integer -which signifies the number of distinct memory regions that were reclaimed in the -collection (more precisely, the number of heads that were turned into frees). For -efficiency reasons bare metal ports do not return this value. diff --git a/docs/reference/glossary.rst b/docs/reference/glossary.rst deleted file mode 100644 index a6abc8b9da4..00000000000 --- a/docs/reference/glossary.rst +++ /dev/null @@ -1,155 +0,0 @@ -Glossary -======== - -.. glossary:: - - baremetal - A system without a (full-fledged) OS, for example an - :term:`MCU`-based system. When running on a baremetal system, - MicroPython effectively becomes its user-facing OS with a command - interpreter (REPL). - - board - A PCB board. Oftentimes, the term is used to denote a particular - model of an :term:`MCU` system. Sometimes, it is used to actually - refer to :term:`MicroPython port` to a particular board (and then - may also refer to "boardless" ports like - :term:`Unix port `). - - callee-owned tuple - A tuple returned by some builtin function/method, containing data - which is valid for a limited time, usually until next call to the - same function (or a group of related functions). After next call, - data in the tuple may be changed. This leads to the following - restriction on the usage of callee-owned tuples - references to - them cannot be stored. The only valid operation is extracting - values from them (including making a copy). Callee-owned tuples - is a MicroPython-specific construct (not available in the general - Python language), introduced for memory allocation optimization. - The idea is that callee-owned tuple is allocated once and stored - on the callee side. Subsequent calls don't require allocation, - allowing to return multiple values when allocation is not possible - (e.g. in interrupt context) or not desirable (because allocation - inherently leads to memory fragmentation). Note that callee-owned - tuples are effectively mutable tuples, making an exception to - Python's rule that tuples are immutable. (It may be interesting - why tuples were used for such a purpose then, instead of mutable - lists - the reason for that is that lists are mutable from user - application side too, so a user could do things to a callee-owned - list which the callee doesn't expect and could lead to problems; - a tuple is protected from this.) - - CPython - CPython is the reference implementation of Python programming - language, and the most well-known one, which most of the people - run. It is however one of many implementations (among which - Jython, IronPython, PyPy, and many more, including MicroPython). - As there is no formal specification of the Python language, only - CPython documentation, it is not always easy to draw a line - between Python the language and CPython its particular - implementation. This however leaves more freedom for other - implementations. For example, MicroPython does a lot of things - differently than CPython, while still aspiring to be a Python - language implementation. - - GPIO - General-purpose input/output. The simplest means to control - electrical signals. With GPIO, user can configure hardware - signal pin to be either input or output, and set or get - its digital signal value (logical "0" or "1"). MicroPython - abstracts GPIO access using :class:`machine.Pin` and :class:`machine.Signal` - classes. - - GPIO port - A group of :term:`GPIO` pins, usually based on hardware - properties of these pins (e.g. controllable by the same - register). - - interned string - A string referenced by its (unique) identity rather than its - address. Interned strings are thus can be quickly compared just - by their identifiers, instead of comparing by content. The - drawbacks of interned strings are that interning operation takes - time (proportional to the number of existing interned strings, - i.e. becoming slower and slower over time) and that the space - used for interned strings is not reclaimable. String interning - is done automatically by MicroPython compiler and runtimer when - it's either required by the implementation (e.g. function keyword - arguments are represented by interned string id's) or deemed - beneficial (e.g. for short enough strings, which have a chance - to be repeated, and thus interning them would save memory on - copies). Most of string and I/O operations don't produce interned - strings due to drawbacks described above. - - MCU - Microcontroller. Microcontrollers usually have much less resources - than a full-fledged computing system, but smaller, cheaper and - require much less power. MicroPython is designed to be small and - optimized enough to run on an average modern microcontroller. - - micropython-lib - MicroPython is (usually) distributed as a single executable/binary - file with just few builtin modules. There is no extensive standard - library comparable with :term:`CPython`. Instead, there is a related, but - separate project - `micropython-lib `_ - which provides implementations for many modules from CPython's - standard library. However, large subset of these modules require - POSIX-like environment (Linux, FreeBSD, MacOS, etc.; Windows may be - partially supported), and thus would work or make sense only with - `MicroPython Unix port`. Some subset of modules is however usable - for `baremetal` ports too. - - Unlike monolithic :term:`CPython` stdlib, micropython-lib modules - are intended to be installed individually - either using manual - copying or using :term:`upip`. - - MicroPython port - MicroPython supports different :term:`boards `, RTOSes, - and OSes, and can be relatively easily adapted to new systems. - MicroPython with support for a particular system is called a - "port" to that system. Different ports may have widely different - functionality. This documentation is intended to be a reference - of the generic APIs available across different ports ("MicroPython - core"). Note that some ports may still omit some APIs described - here (e.g. due to resource constraints). Any such differences, - and port-specific extensions beyond MicroPython core functionality, - would be described in the separate port-specific documentation. - - MicroPython Unix port - Unix port is one of the major :term:`MicroPython ports `. - It is intended to run on POSIX-compatible operating systems, like - Linux, MacOS, FreeBSD, Solaris, etc. It also serves as the basis - of Windows port. The importance of Unix port lies in the fact - that while there are many different :term:`boards `, so - two random users unlikely have the same board, almost all modern - OSes have some level of POSIX compatibility, so Unix port serves - as a kind of "common ground" to which any user can have access. - So, Unix port is used for initial prototyping, different kinds - of testing, development of machine-independent features, etc. - All users of MicroPython, even those which are interested only - in running MicroPython on :term:`MCU` systems, are recommended - to be familiar with Unix (or Windows) port, as it is important - productivity helper and a part of normal MicroPython workflow. - - port - Either :term:`MicroPython port` or :term:`GPIO port`. If not clear - from context, it's recommended to use full specification like one - of the above. - - stream - Also known as a "file-like object". An object which provides sequential - read-write access to the underlying data. A stream object implements - a corresponding interface, which consists of methods like ``read()``, - ``write()``, ``readinto()``, ``seek()``, ``flush()``, ``close()``, etc. - A stream is an important concept in MicroPython, many I/O objects - implement the stream interface, and thus can be used consistently and - interchangeably in different contexts. For more information on - streams in MicroPython, see `uio` module. - - upip - (Literally, "micro pip"). A package manage for MicroPython, inspired - by :term:`CPython`'s pip, but much smaller and with reduced functionality. - upip runs both on :term:`Unix port ` and on - :term:`baremetal` ports (those which offer filesystem and networking - support). diff --git a/docs/reference/index.rst b/docs/reference/index.rst deleted file mode 100644 index 9c5c164f3f8..00000000000 --- a/docs/reference/index.rst +++ /dev/null @@ -1,34 +0,0 @@ -The MicroPython language -======================== - -MicroPython aims to implement the Python 3.4 standard (with selected -features from later versions) with respect to language syntax, and most -of the features of MicroPython are identical to those described by the -"Language Reference" documentation at -`docs.python.org `_. - -The MicroPython standard library is described in the -:ref:`corresponding chapter `. The :ref:`cpython_diffs` -chapter describes differences between MicroPython and CPython (which -mostly concern standard library and types, but also some language-level -features). - -This chapter describes features and peculiarities of MicroPython -implementation and the best practices to use them. - -.. toctree:: - :maxdepth: 1 - - glossary.rst - repl.rst - isr_rules.rst - speed_python.rst - constrained.rst - packages.rst - -.. only:: port_pyboard - - .. toctree:: - :maxdepth: 1 - - asm_thumb2_index.rst diff --git a/docs/reference/isr_rules.rst b/docs/reference/isr_rules.rst deleted file mode 100644 index dfdee048c13..00000000000 --- a/docs/reference/isr_rules.rst +++ /dev/null @@ -1,382 +0,0 @@ -.. _isr_rules: - -Writing interrupt handlers -========================== - -On suitable hardware MicroPython offers the ability to write interrupt handlers in Python. Interrupt handlers -- also known as interrupt service routines (ISR's) - are defined as callback functions. These are executed -in response to an event such as a timer trigger or a voltage change on a pin. Such events can occur at any point -in the execution of the program code. This carries significant consequences, some specific to the MicroPython -language. Others are common to all systems capable of responding to real time events. This document covers -the language specific issues first, followed by a brief introduction to real time programming for those new to it. - -This introduction uses vague terms like "slow" or "as fast as possible". This is deliberate, as speeds are -application dependent. Acceptable durations for an ISR are dependent on the rate at which interrupts occur, -the nature of the main program, and the presence of other concurrent events. - -Tips and recommended practices ------------------------------- - -This summarises the points detailed below and lists the principal recommendations for interrupt handler code. - -* Keep the code as short and simple as possible. -* Avoid memory allocation: no appending to lists or insertion into dictionaries, no floating point. -* Consider using ``micropython.schedule`` to work around the above constraint. -* Where an ISR returns multiple bytes use a pre-allocated ``bytearray``. If multiple integers are to be - shared between an ISR and the main program consider an array (``array.array``). -* Where data is shared between the main program and an ISR, consider disabling interrupts prior to accessing - the data in the main program and re-enabling them immediately afterwards (see Critical Sections). -* Allocate an emergency exception buffer (see below). - - -MicroPython Issues ------------------- - -The emergency exception buffer -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If an error occurs in an ISR, MicroPython is unable to produce an error report unless a special buffer is created -for the purpose. Debugging is simplified if the following code is included in any program using interrupts. - -.. code:: python - - import micropython - micropython.alloc_emergency_exception_buf(100) - -Simplicity -~~~~~~~~~~ - -For a variety of reasons it is important to keep ISR code as short and simple as possible. It should do only what -has to be done immediately after the event which caused it: operations which can be deferred should be delegated -to the main program loop. Typically an ISR will deal with the hardware device which caused the interrupt, making -it ready for the next interrupt to occur. It will communicate with the main loop by updating shared data to indicate -that the interrupt has occurred, and it will return. An ISR should return control to the main loop as quickly -as possible. This is not a specific MicroPython issue so is covered in more detail :ref:`below `. - -Communication between an ISR and the main program -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Normally an ISR needs to communicate with the main program. The simplest means of doing this is via one or more -shared data objects, either declared as global or shared via a class (see below). There are various restrictions -and hazards around doing this, which are covered in more detail below. Integers, ``bytes`` and ``bytearray`` objects -are commonly used for this purpose along with arrays (from the array module) which can store various data types. - -The use of object methods as callbacks -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -MicroPython supports this powerful technique which enables an ISR to share instance variables with the underlying -code. It also enables a class implementing a device driver to support multiple device instances. The following -example causes two LED's to flash at different rates. - -.. code:: python - - import pyb, micropython - micropython.alloc_emergency_exception_buf(100) - class Foo(object): - def __init__(self, timer, led): - self.led = led - timer.callback(self.cb) - def cb(self, tim): - self.led.toggle() - - red = Foo(pyb.Timer(4, freq=1), pyb.LED(1)) - green = Foo(pyb.Timer(2, freq=0.8), pyb.LED(2)) - -In this example the ``red`` instance associates timer 4 with LED 1: when a timer 4 interrupt occurs ``red.cb()`` -is called causing LED 1 to change state. The ``green`` instance operates similarly: a timer 2 interrupt -results in the execution of ``green.cb()`` and toggles LED 2. The use of instance methods confers two -benefits. Firstly a single class enables code to be shared between multiple hardware instances. Secondly, as -a bound method the callback function's first argument is ``self``. This enables the callback to access instance -data and to save state between successive calls. For example, if the class above had a variable ``self.count`` -set to zero in the constructor, ``cb()`` could increment the counter. The ``red`` and ``green`` instances would -then maintain independent counts of the number of times each LED had changed state. - -Creation of Python objects -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -ISR's cannot create instances of Python objects. This is because MicroPython needs to allocate memory for the -object from a store of free memory block called the heap. This is not permitted in an interrupt handler because -heap allocation is not re-entrant. In other words the interrupt might occur when the main program is part way -through performing an allocation - to maintain the integrity of the heap the interpreter disallows memory -allocations in ISR code. - -A consequence of this is that ISR's can't use floating point arithmetic; this is because floats are Python objects. Similarly -an ISR can't append an item to a list. In practice it can be hard to determine exactly which code constructs will -attempt to perform memory allocation and provoke an error message: another reason for keeping ISR code short and simple. - -One way to avoid this issue is for the ISR to use pre-allocated buffers. For example a class constructor -creates a ``bytearray`` instance and a boolean flag. The ISR method assigns data to locations in the buffer and sets -the flag. The memory allocation occurs in the main program code when the object is instantiated rather than in the ISR. - -The MicroPython library I/O methods usually provide an option to use a pre-allocated buffer. For -example ``pyb.i2c.recv()`` can accept a mutable buffer as its first argument: this enables its use in an ISR. - -A means of creating an object without employing a class or globals is as follows: - -.. code:: python - - def set_volume(t, buf=bytearray(3)): - buf[0] = 0xa5 - buf[1] = t >> 4 - buf[2] = 0x5a - return buf - -The compiler instantiates the default ``buf`` argument when the function is -loaded for the first time (usually when the module it's in is imported). - -An instance of object creation occurs when a reference to a bound method is -created. This means that an ISR cannot pass a bound method to a function. One -solution is to create a reference to the bound method in the class constructor -and to pass that reference in the ISR. For example: - -.. code:: python - - class Foo(): - def __init__(self): - self.bar_ref = self.bar # Allocation occurs here - self.x = 0.1 - tim = pyb.Timer(4) - tim.init(freq=2) - tim.callback(self.cb) - - def bar(self, _): - self.x *= 1.2 - print(self.x) - - def cb(self, t): - # Passing self.bar would cause allocation. - micropython.schedule(self.bar_ref, 0) - -Other techniques are to define and instantiate the method in the constructor -or to pass :meth:`Foo.bar` with the argument *self*. - -Use of Python objects -~~~~~~~~~~~~~~~~~~~~~ - -A further restriction on objects arises because of the way Python works. When an ``import`` statement is executed the -Python code is compiled to bytecode, with one line of code typically mapping to multiple bytecodes. When the code -runs the interpreter reads each bytecode and executes it as a series of machine code instructions. Given that an -interrupt can occur at any time between machine code instructions, the original line of Python code may be only -partially executed. Consequently a Python object such as a set, list or dictionary modified in the main loop -may lack internal consistency at the moment the interrupt occurs. - -A typical outcome is as follows. On rare occasions the ISR will run at the precise moment in time when the object -is partially updated. When the ISR tries to read the object, a crash results. Because such problems typically occur -on rare, random occasions they can be hard to diagnose. There are ways to circumvent this issue, described in -:ref:`Critical Sections ` below. - -It is important to be clear about what constitutes the modification of an object. An alteration to a built-in type -such as a dictionary is problematic. Altering the contents of an array or bytearray is not. This is because bytes -or words are written as a single machine code instruction which is not interruptible: in the parlance of real time -programming the write is atomic. A user defined object might instantiate an integer, array or bytearray. It is valid -for both the main loop and the ISR to alter the contents of these. - -MicroPython supports integers of arbitrary precision. Values between 2**30 -1 and -2**30 will be stored in -a single machine word. Larger values are stored as Python objects. Consequently changes to long integers cannot -be considered atomic. The use of long integers in ISR's is unsafe because memory allocation may be -attempted as the variable's value changes. - -Overcoming the float limitation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In general it is best to avoid using floats in ISR code: hardware devices normally handle integers and conversion -to floats is normally done in the main loop. However there are a few DSP algorithms which require floating point. -On platforms with hardware floating point (such as the Pyboard) the inline ARM Thumb assembler can be used to work -round this limitation. This is because the processor stores float values in a machine word; values can be shared -between the ISR and main program code via an array of floats. - -Using micropython.schedule -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This function enables an ISR to schedule a callback for execution "very soon". The callback is queued for -execution which will take place at a time when the heap is not locked. Hence it can create Python objects -and use floats. The callback is also guaranteed to run at a time when the main program has completed any -update of Python objects, so the callback will not encounter partially updated objects. - -Typical usage is to handle sensor hardware. The ISR acquires data from the hardware and enables it to -issue a further interrupt. It then schedules a callback to process the data. - -Scheduled callbacks should comply with the principles of interrupt handler design outlined below. This is to -avoid problems resulting from I/O activity and the modification of shared data which can arise in any code -which pre-empts the main program loop. - -Execution time needs to be considered in relation to the frequency with which interrupts can occur. If an -interrupt occurs while the previous callback is executing, a further instance of the callback will be queued -for execution; this will run after the current instance has completed. A sustained high interrupt repetition -rate therefore carries a risk of unconstrained queue growth and eventual failure with a ``RuntimeError``. - -If the callback to be passed to `schedule()` is a bound method, consider the -note in "Creation of Python objects". - -Exceptions ----------- - -If an ISR raises an exception it will not propagate to the main loop. The interrupt will be disabled unless the -exception is handled by the ISR code. - -General Issues --------------- - -This is merely a brief introduction to the subject of real time programming. Beginners should note -that design errors in real time programs can lead to faults which are particularly hard to diagnose. This is because -they can occur rarely and at intervals which are essentially random. It is crucial to get the initial design right and -to anticipate issues before they arise. Both interrupt handlers and the main program need to be designed -with an appreciation of the following issues. - -.. _ISR: - -Interrupt Handler Design -~~~~~~~~~~~~~~~~~~~~~~~~ - -As mentioned above, ISR's should be designed to be as simple as possible. They should always return in a short, -predictable period of time. This is important because when the ISR is running, the main loop is not: inevitably -the main loop experiences pauses in its execution at random points in the code. Such pauses can be a source of hard -to diagnose bugs particularly if their duration is long or variable. In order to understand the implications of -ISR run time, a basic grasp of interrupt priorities is required. - -Interrupts are organised according to a priority scheme. ISR code may itself be interrupted by a higher priority -interrupt. This has implications if the two interrupts share data (see Critical Sections below). If such an interrupt -occurs it interposes a delay into the ISR code. If a lower priority interrupt occurs while the ISR is running, it -will be delayed until the ISR is complete: if the delay is too long, the lower priority interrupt may fail. A -further issue with slow ISR's is the case where a second interrupt of the same type occurs during its execution. -The second interrupt will be handled on termination of the first. However if the rate of incoming interrupts -consistently exceeds the capacity of the ISR to service them the outcome will not be a happy one. - -Consequently looping constructs should be avoided or minimised. I/O to devices other than to the interrupting device -should normally be avoided: I/O such as disk access, ``print`` statements and UART access is relatively slow, and -its duration may vary. A further issue here is that filesystem functions are not reentrant: using filesystem I/O -in an ISR and the main program would be hazardous. Crucially ISR code should not wait on an event. I/O is acceptable -if the code can be guaranteed to return in a predictable period, for example toggling a pin or LED. Accessing the -interrupting device via I2C or SPI may be necessary but the time taken for such accesses should be calculated or -measured and its impact on the application assessed. - -There is usually a need to share data between the ISR and the main loop. This may be done either through global -variables or via class or instance variables. Variables are typically integer or boolean types, or integer or byte -arrays (a pre-allocated integer array offers faster access than a list). Where multiple values are modified by -the ISR it is necessary to consider the case where the interrupt occurs at a time when the main program has -accessed some, but not all, of the values. This can lead to inconsistencies. - -Consider the following design. An ISR stores incoming data in a bytearray, then adds the number of bytes -received to an integer representing total bytes ready for processing. The main program reads the number of bytes, -processes the bytes, then clears down the number of bytes ready. This will work until an interrupt occurs just -after the main program has read the number of bytes. The ISR puts the added data into the buffer and updates -the number received, but the main program has already read the number, so processes the data originally received. -The newly arrived bytes are lost. - -There are various ways of avoiding this hazard, the simplest being to use a circular buffer. If it is not possible -to use a structure with inherent thread safety other ways are described below. - -Reentrancy -~~~~~~~~~~ - -A potential hazard may occur if a function or method is shared between the main program and one or more ISR's or -between multiple ISR's. The issue here is that the function may itself be interrupted and a further instance of -that function run. If this is to occur, the function must be designed to be reentrant. How this is done is an -advanced topic beyond the scope of this tutorial. - -.. _Critical: - -Critical Sections -~~~~~~~~~~~~~~~~~ - -An example of a critical section of code is one which accesses more than one variable which can be affected by an ISR. If -the interrupt happens to occur between accesses to the individual variables, their values will be inconsistent. This is -an instance of a hazard known as a race condition: the ISR and the main program loop race to alter the variables. To -avoid inconsistency a means must be employed to ensure that the ISR does not alter the values for the duration of -the critical section. One way to achieve this is to issue ``pyb.disable_irq()`` before the start of the section, and -``pyb.enable_irq()`` at the end. Here is an example of this approach: - -.. code:: python - - import pyb, micropython, array - micropython.alloc_emergency_exception_buf(100) - - class BoundsException(Exception): - pass - - ARRAYSIZE = const(20) - index = 0 - data = array.array('i', 0 for x in range(ARRAYSIZE)) - - def callback1(t): - global data, index - for x in range(5): - data[index] = pyb.rng() # simulate input - index += 1 - if index >= ARRAYSIZE: - raise BoundsException('Array bounds exceeded') - - tim4 = pyb.Timer(4, freq=100, callback=callback1) - - for loop in range(1000): - if index > 0: - irq_state = pyb.disable_irq() # Start of critical section - for x in range(index): - print(data[x]) - index = 0 - pyb.enable_irq(irq_state) # End of critical section - print('loop {}'.format(loop)) - pyb.delay(1) - - tim4.callback(None) - -A critical section can comprise a single line of code and a single variable. Consider the following code fragment. - -.. code:: python - - count = 0 - def cb(): # An interrupt callback - count +=1 - def main(): - # Code to set up the interrupt callback omitted - while True: - count += 1 - -This example illustrates a subtle source of bugs. The line ``count += 1`` in the main loop carries a specific race -condition hazard known as a read-modify-write. This is a classic cause of bugs in real time systems. In the main loop -MicroPython reads the value of ``t.counter``, adds 1 to it, and writes it back. On rare occasions the interrupt occurs -after the read and before the write. The interrupt modifies ``t.counter`` but its change is overwritten by the main -loop when the ISR returns. In a real system this could lead to rare, unpredictable failures. - -As mentioned above, care should be taken if an instance of a Python built in type is modified in the main code and -that instance is accessed in an ISR. The code performing the modification should be regarded as a critical -section to ensure that the instance is in a valid state when the ISR runs. - -Particular care needs to be taken if a dataset is shared between different ISR's. The hazard here is that the higher -priority interrupt may occur when the lower priority one has partially updated the shared data. Dealing with this -situation is an advanced topic beyond the scope of this introduction other than to note that mutex objects described -below can sometimes be used. - -Disabling interrupts for the duration of a critical section is the usual and simplest way to proceed, but it disables -all interrupts rather than merely the one with the potential to cause problems. It is generally undesirable to disable -an interrupt for long. In the case of timer interrupts it introduces variability to the time when a callback occurs. -In the case of device interrupts, it can lead to the device being serviced too late with possible loss of data or -overrun errors in the device hardware. Like ISR's, a critical section in the main code should have a short, predictable -duration. - -An approach to dealing with critical sections which radically reduces the time for which interrupts are disabled is to -use an object termed a mutex (name derived from the notion of mutual exclusion). The main program locks the mutex -before running the critical section and unlocks it at the end. The ISR tests whether the mutex is locked. If it is, -it avoids the critical section and returns. The design challenge is defining what the ISR should do in the event -that access to the critical variables is denied. A simple example of a mutex may be found -`here `_. Note that the mutex code does disable interrupts, -but only for the duration of eight machine instructions: the benefit of this approach is that other interrupts are -virtually unaffected. - -Interrupts and the REPL -~~~~~~~~~~~~~~~~~~~~~~~ - -Interrupt handlers, such as those associated with timers, can continue to run -after a program terminates. This may produce unexpected results where you might -have expected the object raising the callback to have gone out of scope. For -example on the Pyboard: - -.. code:: python - - def bar(): - foo = pyb.Timer(2, freq=4, callback=lambda t: print('.', end='')) - - bar() - -This continues to run until the timer is explicitly disabled or the board is -reset with ``ctrl D``. diff --git a/docs/reference/packages.rst b/docs/reference/packages.rst deleted file mode 100644 index 8be2461c2db..00000000000 --- a/docs/reference/packages.rst +++ /dev/null @@ -1,312 +0,0 @@ -Distribution packages, package management, and deploying applications -===================================================================== - -Just as the "big" Python, MicroPython supports creation of "third party" -packages, distributing them, and easily installing them in each user's -environment. This chapter discusses how these actions are achieved. -Some familiarity with Python packaging is recommended. - -Overview --------- - -Steps below represent a high-level workflow when creating and consuming -packages: - -1. Python modules and packages are turned into distribution package - archives, and published at the Python Package Index (PyPI). -2. `upip` package manager can be used to install a distribution package - on a `MicroPython port` with networking capabilities (for example, - on the Unix port). -3. For ports without networking capabilities, an "installation image" - can be prepared on the Unix port, and transferred to a device by - suitable means. -4. For low-memory ports, the installation image can be frozen as the - bytecode into MicroPython executable, thus minimizing the memory - storage overheads. - -The sections below describe this process in details. - -Distribution packages ---------------------- - -Python modules and packages can be packaged into archives suitable for -transfer between systems, storing at the well-known location (PyPI), -and downloading on demand for deployment. These archives are known as -*distribution packages* (to differentiate them from Python packages -(means to organize Python source code)). - -The MicroPython distribution package format is a well-known tar.gz -format, with some adaptations however. The Gzip compressor, used as -an external wrapper for TAR archives, by default uses 32KB dictionary -size, which means that to uncompress a compressed stream, 32KB of -contguous memory needs to be allocated. This requirement may be not -satisfiable on low-memory devices, which may have total memory available -less than that amount, and even if not, a contiguous block like that -may be hard to allocate due to memory fragmentation. To accommodate -these constraints, MicroPython distribution packages use Gzip compression -with the dictionary size of 4K, which should be a suitable compromise -with still achieving some compression while being able to uncompressed -even by the smallest devices. - -Besides the small compression dictionary size, MicroPython distribution -packages also have other optimizations, like removing any files from -the archive which aren't used by the installation process. In particular, -`upip` package manager doesn't execute ``setup.py`` during installation -(see below), and thus that file is not included in the archive. - -At the same time, these optimizations make MicroPython distribution -packages not compatible with `CPython`'s package manager, ``pip``. -This isn't considered a big problem, because: - -1. Packages can be installed with `upip`, and then can be used with - CPython (if they are compatible with it). -2. In the other direction, majority of CPython packages would be - incompatible with MicroPython by various reasons, first of all, - the reliance on features not implemented by MicroPython. - -Summing up, the MicroPython distribution package archives are highly -optimized for MicroPython's target environments, which are highly -resource constrained devices. - - -``upip`` package manager ------------------------- - -MicroPython distribution packages are intended to be installed using -the `upip` package manager. `upip` is a Python application which is -usually distributed (as frozen bytecode) with network-enabled -`MicroPython ports `. At the very least, -`upip` is available in the `MicroPython Unix port`. - -On any `MicroPython port` providing `upip`, it can be accessed as -following:: - - import upip - upip.help() - upip.install(package_or_package_list, [path]) - -Where *package_or_package_list* is the name of a distribution -package to install, or a list of such names to install multiple -packages. Optional *path* parameter specifies filesystem -location to install under and defaults to the standard library -location (see below). - -An example of installing a specific package and then using it:: - - >>> import upip - >>> upip.install("micropython-pystone_lowmem") - [...] - >>> import pystone_lowmem - >>> pystone_lowmem.main() - -Note that the name of Python package and the name of distribution -package for it in general don't have to match, and oftentimes they -don't. This is because PyPI provides a central package repository -for all different Python implementations and versions, and thus -distribution package names may need to be namespaced for a particular -implementation. For example, all packages from `micropython-lib` -follow this naming convention: for a Python module or package named -``foo``, the distribution package name is ``micropython-foo``. - -For the ports which run MicroPython executable from the OS command -prompts (like the Unix port), `upip` can be (and indeed, usually is) -run from the command line instead of MicroPython's own REPL. The -commands which corresponds to the example above are:: - - micropython -m upip -h - micropython -m upip install [-p ] ... - micropython -m upip install micropython-pystone_lowmem - -[TODO: Describe installation path.] - - -Cross-installing packages -------------------------- - -For `MicroPython ports ` without native networking -capabilities, the recommend process is "cross-installing" them into a -"directory image" using the `MicroPython Unix port`, and then -transferring this image to a device by suitable means. - -Installing to a directory image involves using ``-p`` switch to `upip`:: - - micropython -m upip install -p install_dir micropython-pystone_lowmem - -After this command, the package content (and contents of every depenency -packages) will be available in the ``install_dir/`` subdirectory. You -would need to transfer contents of this directory (without the -``install_dir/`` prefix) to the device, at the suitable location, where -it can be found by the Python ``import`` statement (see discussion of -the `upip` installation path above). - - -Cross-installing packages with freezing ---------------------------------------- - -For the low-memory `MicroPython ports `, the process -described in the previous section does not provide the most efficient -resource usage,because the packages are installed in the source form, -so need to be compiled to the bytecome on each import. This compilation -requires RAM, and the resulting bytecode is also stored in RAM, reducing -its amount available for storing application data. Moreover, the process -above requires presence of the filesystem on a device, and the most -resource-constrained devices may not even have it. - -The bytecode freezing is a process which resolves all the issues -mentioned above: - -* The source code is pre-compiled into bytecode and store as such. -* The bytecode is stored in ROM, not RAM. -* Filesystem is not required for frozen packages. - -Using frozen bytecode requires building the executable (firmware) -for a given `MicroPython port` from the C source code. Consequently, -the process is: - -1. Follow the instructions for a particular port on setting up a - toolchain and building the port. For example, for ESP8266 port, - study instructions in ``ports/esp8266/README.md`` and follow them. - Make sure you can build the port and deploy the resulting - executable/firmware successfully before proceeding to the next steps. -2. Build `MicroPython Unix port` and make sure it is in your PATH and - you can execute ``micropython``. -3. Change to port's directory (e.g. ``ports/esp8266/`` for ESP8266). -4. Run ``make clean-frozen``. This step cleans up any previous - modules which were installed for freezing (consequently, you need - to skip this step to add additional modules, instead of starting - from scratch). -5. Run ``micropython -m upip install -p modules ...`` to - install packages you want to freeze. -6. Run ``make clean``. -7. Run ``make``. - -After this, you should have the executable/firmware with modules as -the bytecode inside, which you can deploy the usual way. - -Few notes: - -1. Step 5 in the sequence above assumes that the distribution package - is available from PyPI. If that is not the case, you would need - to copy Python source files manually to ``modules/`` subdirectory - of the port port directory. (Note that upip does not support - installing from e.g. version control repositories). -2. The firmware for baremetal devices usually has size restrictions, - so adding too many frozen modules may overflow it. Usually, you - would get a linking error if this happens. However, in some cases, - an image may be produced, which is not runnable on a device. Such - cases are in general bugs, and should be reported and further - investigated. If you face such a situation, as an initial step, - you may want to decrease the amount of frozen modules included. - - -Creating distribution packages ------------------------------- - -Distribution packages for MicroPython are created in the same manner -as for CPython or any other Python implementation, see references at -the end of chapter. Setuptools (instead of distutils) should be used, -because distutils do not support dependencies and other features. "Source -distribution" (``sdist``) format is used for packaging. The post-processing -discussed above, (and pre-processing discussed in the following section) -is achieved by using custom ``sdist`` command for setuptools. Thus, packaging -steps remain the same as for the standard setuptools, the user just -needs to override ``sdist`` command implementation by passing the -appropriate argument to ``setup()`` call:: - - from setuptools import setup - import sdist_upip - - setup( - ..., - cmdclass={'sdist': sdist_upip.sdist} - ) - -The sdist_upip.py module as referenced above can be found in -`micropython-lib`: -https://github.com/micropython/micropython-lib/blob/master/sdist_upip.py - - -Application resources ---------------------- - -A complete application, besides the source code, oftentimes also consists -of data files, e.g. web page templates, game images, etc. It's clear how -to deal with those when application is installed manually - you just put -those data files in the filesystem at some location and use the normal -file access functions. - -The situation is different when deploying applications from packages - this -is more advanced, streamlined and flexible way, but also requires more -advanced approach to accessing data files. This approach is treating -the data files as "resources", and abstracting away access to them. - -Python supports resource access using its "setuptools" library, using -``pkg_resources`` module. MicroPython, following its usual approach, -implements subset of the functionality of that module, specifically -``pkg_resources.resource_stream(package, resource)`` function. -The idea is that an application calls this function, passing a -resource identifier, which is a relative path to data file within -the specified package (usually top-level application package). It -returns a stream object which can be used to access resource contents. -Thus, the ``resource_stream()`` emulates interface of the standard -`open()` function. - -Implementation-wise, ``resource_stream()`` uses file operations -underlyingly, if distribution package is install in the filesystem. -However, it also supports functioning without the underlying filesystem, -e.g. if the package is frozen as the bytecode. This however requires -an extra intermediate step when packaging application - creation of -"Python resource module". - -The idea of this module is to convert binary data to a Python bytes -object, and put it into the dictionary, indexed by the resource name. -This conversion is done automatically using overridden ``sdist`` command -described in the previous section. - -Let's trace the complete process using the following example. Suppose -your application has the following structure:: - - my_app/ - __main__.py - utils.py - data/ - page.html - image.png - -``__main__.py`` and ``utils.py`` should access resources using the -following calls:: - - import pkg_resources - - pkg_resources.resource_stream(__name__, "data/page.html") - pkg_resources.resource_stream(__name__, "data/image.png") - -You can develop and debug using the `MicroPython Unix port` as usual. -When time comes to make a distribution package out of it, just use -overridden "sdist" command from sdist_upip.py module as described in -the previous section. - -This will create a Python resource module named ``R.py``, based on the -files declared in ``MANIFEST`` or ``MANIFEST.in`` files (any non-``.py`` -file will be considered a resource and added to ``R.py``) - before -proceeding with the normal packaging steps. - -Prepared like this, your application will work both when deployed to -filesystem and as frozen bytecode. - -If you would like to debug ``R.py`` creation, you can run:: - - python3 setup.py sdist --manifest-only - -Alternatively, you can use tools/mpy_bin2res.py script from the -MicroPython distribution, in which can you will need to pass paths -to all resource files:: - - mpy_bin2res.py data/page.html data/image.png - -References ----------- - -* Python Packaging User Guide: https://packaging.python.org/ -* Setuptools documentation: https://setuptools.readthedocs.io/ -* Distutils documentation: https://docs.python.org/3/library/distutils.html diff --git a/docs/reference/repl.rst b/docs/reference/repl.rst deleted file mode 100644 index 1eccb9a88a1..00000000000 --- a/docs/reference/repl.rst +++ /dev/null @@ -1,212 +0,0 @@ -The MicroPython Interactive Interpreter Mode (aka REPL) -======================================================= - -This section covers some characteristics of the MicroPython Interactive -Interpreter Mode. A commonly used term for this is REPL (read-eval-print-loop) -which will be used to refer to this interactive prompt. - -Auto-indent ------------ - -When typing python statements which end in a colon (for example if, for, while) -then the prompt will change to three dots (...) and the cursor will be indented -by 4 spaces. When you press return, the next line will continue at the same -level of indentation for regular statements or an additional level of indentation -where appropriate. If you press the backspace key then it will undo one -level of indentation. - -If your cursor is all the way back at the beginning, pressing RETURN will then -execute the code that you've entered. The following shows what you'd see -after entering a for statement (the underscore shows where the cursor winds up): - - >>> for i in range(30): - ... _ - -If you then enter an if statement, an additional level of indentation will be -provided: - - >>> for i in range(30): - ... if i > 3: - ... _ - -Now enter ``break`` followed by RETURN and press BACKSPACE: - - >>> for i in range(30): - ... if i > 3: - ... break - ... _ - -Finally type ``print(i)``, press RETURN, press BACKSPACE and press RETURN again: - - >>> for i in range(30): - ... if i > 3: - ... break - ... print(i) - ... - 0 - 1 - 2 - 3 - >>> - -Auto-indent won't be applied if the previous two lines were all spaces. This -means that you can finish entering a compound statement by pressing RETURN -twice, and then a third press will finish and execute. - -Auto-completion ---------------- - -While typing a command at the REPL, if the line typed so far corresponds to -the beginning of the name of something, then pressing TAB will show -possible things that could be entered. For example, first import the machine -module by entering ``import machine`` and pressing RETURN. -Then type ``m`` and press TAB and it should expand to ``machine``. -Enter a dot ``.`` and press TAB again. You should see something like: - - >>> machine. - __name__ info unique_id reset - bootloader freq rng idle - sleep deepsleep disable_irq enable_irq - Pin - -The word will be expanded as much as possible until multiple possibilities exist. -For example, type ``machine.Pin.AF3`` and press TAB and it will expand to -``machine.Pin.AF3_TIM``. Pressing TAB a second time will show the possible -expansions: - - >>> machine.Pin.AF3_TIM - AF3_TIM10 AF3_TIM11 AF3_TIM8 AF3_TIM9 - >>> machine.Pin.AF3_TIM - -Interrupting a running program ------------------------------- - -You can interrupt a running program by pressing Ctrl-C. This will raise a KeyboardInterrupt -which will bring you back to the REPL, providing your program doesn't intercept the -KeyboardInterrupt exception. - -For example: - - >>> for i in range(1000000): - ... print(i) - ... - 0 - 1 - 2 - 3 - ... - 6466 - 6467 - 6468 - Traceback (most recent call last): - File "", line 2, in - KeyboardInterrupt: - >>> - -Paste Mode ----------- - -If you want to paste some code into your terminal window, the auto-indent feature -will mess things up. For example, if you had the following python code: :: - - def foo(): - print('This is a test to show paste mode') - print('Here is a second line') - foo() - -and you try to paste this into the normal REPL, then you will see something like -this: - - >>> def foo(): - ... print('This is a test to show paste mode') - ... print('Here is a second line') - ... foo() - ... - Traceback (most recent call last): - File "", line 3 - IndentationError: unexpected indent - -If you press Ctrl-E, then you will enter paste mode, which essentially turns off -the auto-indent feature, and changes the prompt from ``>>>`` to ``===``. For example: - - >>> - paste mode; Ctrl-C to cancel, Ctrl-D to finish - === def foo(): - === print('This is a test to show paste mode') - === print('Here is a second line') - === foo() - === - This is a test to show paste mode - Here is a second line - >>> - -Paste Mode allows blank lines to be pasted. The pasted text is compiled as if -it were a file. Pressing Ctrl-D exits paste mode and initiates the compilation. - -Soft Reset ----------- - -A soft reset will reset the python interpreter, but tries not to reset the -method by which you're connected to the MicroPython board (USB-serial, or Wifi). - -You can perform a soft reset from the REPL by pressing Ctrl-D, or from your python -code by executing: :: - - machine.soft_reset() - -For example, if you reset your MicroPython board, and you execute a dir() -command, you'd see something like this: - - >>> dir() - ['__name__', 'pyb'] - -Now create some variables and repeat the dir() command: - - >>> i = 1 - >>> j = 23 - >>> x = 'abc' - >>> dir() - ['j', 'x', '__name__', 'pyb', 'i'] - >>> - -Now if you enter Ctrl-D, and repeat the dir() command, you'll see that your -variables no longer exist: - -.. code-block:: python - - PYB: sync filesystems - PYB: soft reboot - MicroPython v1.5-51-g6f70283-dirty on 2015-10-30; PYBv1.0 with STM32F405RG - Type "help()" for more information. - >>> dir() - ['__name__', 'pyb'] - >>> - -The special variable _ (underscore) ------------------------------------ - -When you use the REPL, you may perform computations and see the results. -MicroPython stores the results of the previous statement in the variable _ (underscore). -So you can use the underscore to save the result in a variable. For example: - - >>> 1 + 2 + 3 + 4 + 5 - 15 - >>> x = _ - >>> x - 15 - >>> - -Raw Mode --------- - -Raw mode is not something that a person would normally use. It is intended for -programmatic use. It essentially behaves like paste mode with echo turned off. - -Raw mode is entered using Ctrl-A. You then send your python code, followed by -a Ctrl-D. The Ctrl-D will be acknowledged by 'OK' and then the python code will -be compiled and executed. Any output (or errors) will be sent back. Entering -Ctrl-B will leave raw mode and return the the regular (aka friendly) REPL. - -The ``tools/pyboard.py`` program uses the raw REPL to execute python files on the -MicroPython board. - diff --git a/docs/reference/speed_python.rst b/docs/reference/speed_python.rst deleted file mode 100644 index 4db60ec14d6..00000000000 --- a/docs/reference/speed_python.rst +++ /dev/null @@ -1,342 +0,0 @@ -Maximising MicroPython Speed -============================ - -.. contents:: - -This tutorial describes ways of improving the performance of MicroPython code. -Optimisations involving other languages are covered elsewhere, namely the use -of modules written in C and the MicroPython inline assembler. - -The process of developing high performance code comprises the following stages -which should be performed in the order listed. - -* Design for speed. -* Code and debug. - -Optimisation steps: - -* Identify the slowest section of code. -* Improve the efficiency of the Python code. -* Use the native code emitter. -* Use the viper code emitter. -* Use hardware-specific optimisations. - -Designing for speed -------------------- - -Performance issues should be considered at the outset. This involves taking a view -on the sections of code which are most performance critical and devoting particular -attention to their design. The process of optimisation begins when the code has -been tested: if the design is correct at the outset optimisation will be -straightforward and may actually be unnecessary. - -Algorithms -~~~~~~~~~~ - -The most important aspect of designing any routine for performance is ensuring that -the best algorithm is employed. This is a topic for textbooks rather than for a -MicroPython guide but spectacular performance gains can sometimes be achieved -by adopting algorithms known for their efficiency. - -RAM Allocation -~~~~~~~~~~~~~~ - -To design efficient MicroPython code it is necessary to have an understanding of the -way the interpreter allocates RAM. When an object is created or grows in size -(for example where an item is appended to a list) the necessary RAM is allocated -from a block known as the heap. This takes a significant amount of time; -further it will on occasion trigger a process known as garbage collection which -can take several milliseconds. - -Consequently the performance of a function or method can be improved if an object is created -once only and not permitted to grow in size. This implies that the object persists -for the duration of its use: typically it will be instantiated in a class constructor -and used in various methods. - -This is covered in further detail :ref:`Controlling garbage collection ` below. - -Buffers -~~~~~~~ - -An example of the above is the common case where a buffer is required, such as one -used for communication with a device. A typical driver will create the buffer in the -constructor and use it in its I/O methods which will be called repeatedly. - -The MicroPython libraries typically provide support for pre-allocated buffers. For -example, objects which support stream interface (e.g., file or UART) provide ``read()`` -method which allocates new buffer for read data, but also a ``readinto()`` method -to read data into an existing buffer. - -Floating Point -~~~~~~~~~~~~~~ - -Some MicroPython ports allocate floating point numbers on heap. Some other ports -may lack dedicated floating-point coprocessor, and perform arithmetic operations -on them in "software" at considerably lower speed than on integers. Where -performance is important, use integer operations and restrict the use of floating -point to sections of the code where performance is not paramount. For example, -capture ADC readings as integers values to an array in one quick go, and only then -convert them to floating-point numbers for signal processing. - -Arrays -~~~~~~ - -Consider the use of the various types of array classes as an alternative to lists. -The `array` module supports various element types with 8-bit elements supported -by Python's built in `bytes` and `bytearray` classes. These data structures all store -elements in contiguous memory locations. Once again to avoid memory allocation in critical -code these should be pre-allocated and passed as arguments or as bound objects. - -When passing slices of objects such as `bytearray` instances, Python creates -a copy which involves allocation of the size proportional to the size of slice. -This can be alleviated using a `memoryview` object. `memoryview` itself -is allocated on heap, but is a small, fixed-size object, regardless of the size -of slice it points too. - -.. code:: python - - ba = bytearray(10000) # big array - func(ba[30:2000]) # a copy is passed, ~2K new allocation - mv = memoryview(ba) # small object is allocated - func(mv[30:2000]) # a pointer to memory is passed - -A `memoryview` can only be applied to objects supporting the buffer protocol - this -includes arrays but not lists. Small caveat is that while memoryview object is live, -it also keeps alive the original buffer object. So, a memoryview isn't a universal -panacea. For instance, in the example above, if you are done with 10K buffer and -just need those bytes 30:2000 from it, it may be better to make a slice, and let -the 10K buffer go (be ready for garbage collection), instead of making a -long-living memoryview and keeping 10K blocked for GC. - -Nonetheless, `memoryview` is indispensable for advanced preallocated buffer -management. ``readinto()`` method discussed above puts data at the beginning -of buffer and fills in entire buffer. What if you need to put data in the -middle of existing buffer? Just create a memoryview into the needed section -of buffer and pass it to ``readinto()``. - -Identifying the slowest section of code ---------------------------------------- - -This is a process known as profiling and is covered in textbooks and -(for standard Python) supported by various software tools. For the type of -smaller embedded application likely to be running on MicroPython platforms -the slowest function or method can usually be established by judicious use -of the timing ``ticks`` group of functions documented in `utime`. -Code execution time can be measured in ms, us, or CPU cycles. - -The following enables any function or method to be timed by adding an -``@timed_function`` decorator: - -.. code:: python - - def timed_function(f, *args, **kwargs): - myname = str(f).split(' ')[1] - def new_func(*args, **kwargs): - t = utime.ticks_us() - result = f(*args, **kwargs) - delta = utime.ticks_diff(utime.ticks_us(), t) - print('Function {} Time = {:6.3f}ms'.format(myname, delta/1000)) - return result - return new_func - -MicroPython code improvements ------------------------------ - -The const() declaration -~~~~~~~~~~~~~~~~~~~~~~~ - -MicroPython provides a ``const()`` declaration. This works in a similar way -to ``#define`` in C in that when the code is compiled to bytecode the compiler -substitutes the numeric value for the identifier. This avoids a dictionary -lookup at runtime. The argument to ``const()`` may be anything which, at -compile time, evaluates to an integer e.g. ``0x100`` or ``1 << 8``. - -.. _Caching: - -Caching object references -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Where a function or method repeatedly accesses objects performance is improved -by caching the object in a local variable: - -.. code:: python - - class foo(object): - def __init__(self): - ba = bytearray(100) - def bar(self, obj_display): - ba_ref = self.ba - fb = obj_display.framebuffer - # iterative code using these two objects - -This avoids the need repeatedly to look up ``self.ba`` and ``obj_display.framebuffer`` -in the body of the method ``bar()``. - -.. _controlling_gc: - -Controlling garbage collection -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -When memory allocation is required, MicroPython attempts to locate an adequately -sized block on the heap. This may fail, usually because the heap is cluttered -with objects which are no longer referenced by code. If a failure occurs, the -process known as garbage collection reclaims the memory used by these redundant -objects and the allocation is then tried again - a process which can take several -milliseconds. - -There may be benefits in pre-empting this by periodically issuing `gc.collect()`. -Firstly doing a collection before it is actually required is quicker - typically on the -order of 1ms if done frequently. Secondly you can determine the point in code -where this time is used rather than have a longer delay occur at random points, -possibly in a speed critical section. Finally performing collections regularly -can reduce fragmentation in the heap. Severe fragmentation can lead to -non-recoverable allocation failures. - -The Native code emitter ------------------------ - -This causes the MicroPython compiler to emit native CPU opcodes rather than -bytecode. It covers the bulk of the MicroPython functionality, so most functions will require -no adaptation (but see below). It is invoked by means of a function decorator: - -.. code:: python - - @micropython.native - def foo(self, arg): - buf = self.linebuf # Cached object - # code - -There are certain limitations in the current implementation of the native code emitter. - -* Context managers are not supported (the ``with`` statement). -* Generators are not supported. -* If ``raise`` is used an argument must be supplied. - -The trade-off for the improved performance (roughly twices as fast as bytecode) is an -increase in compiled code size. - -The Viper code emitter ----------------------- - -The optimisations discussed above involve standards-compliant Python code. The -Viper code emitter is not fully compliant. It supports special Viper native data types -in pursuit of performance. Integer processing is non-compliant because it uses machine -words: arithmetic on 32 bit hardware is performed modulo 2**32. - -Like the Native emitter Viper produces machine instructions but further optimisations -are performed, substantially increasing performance especially for integer arithmetic and -bit manipulations. It is invoked using a decorator: - -.. code:: python - - @micropython.viper - def foo(self, arg: int) -> int: - # code - -As the above fragment illustrates it is beneficial to use Python type hints to assist the Viper optimiser. -Type hints provide information on the data types of arguments and of the return value; these -are a standard Python language feature formally defined here `PEP0484 `_. -Viper supports its own set of types namely ``int``, ``uint`` (unsigned integer), ``ptr``, ``ptr8``, -``ptr16`` and ``ptr32``. The ``ptrX`` types are discussed below. Currently the ``uint`` type serves -a single purpose: as a type hint for a function return value. If such a function returns ``0xffffffff`` -Python will interpret the result as 2**32 -1 rather than as -1. - -In addition to the restrictions imposed by the native emitter the following constraints apply: - -* Functions may have up to four arguments. -* Default argument values are not permitted. -* Floating point may be used but is not optimised. - -Viper provides pointer types to assist the optimiser. These comprise - -* ``ptr`` Pointer to an object. -* ``ptr8`` Points to a byte. -* ``ptr16`` Points to a 16 bit half-word. -* ``ptr32`` Points to a 32 bit machine word. - -The concept of a pointer may be unfamiliar to Python programmers. It has similarities -to a Python `memoryview` object in that it provides direct access to data stored in memory. -Items are accessed using subscript notation, but slices are not supported: a pointer can return -a single item only. Its purpose is to provide fast random access to data stored in contiguous -memory locations - such as data stored in objects which support the buffer protocol, and -memory-mapped peripheral registers in a microcontroller. It should be noted that programming -using pointers is hazardous: bounds checking is not performed and the compiler does nothing to -prevent buffer overrun errors. - -Typical usage is to cache variables: - -.. code:: python - - @micropython.viper - def foo(self, arg: int) -> int: - buf = ptr8(self.linebuf) # self.linebuf is a bytearray or bytes object - for x in range(20, 30): - bar = buf[x] # Access a data item through the pointer - # code omitted - -In this instance the compiler "knows" that ``buf`` is the address of an array of bytes; -it can emit code to rapidly compute the address of ``buf[x]`` at runtime. Where casts are -used to convert objects to Viper native types these should be performed at the start of -the function rather than in critical timing loops as the cast operation can take several -microseconds. The rules for casting are as follows: - -* Casting operators are currently: ``int``, ``bool``, ``uint``, ``ptr``, ``ptr8``, ``ptr16`` and ``ptr32``. -* The result of a cast will be a native Viper variable. -* Arguments to a cast can be a Python object or a native Viper variable. -* If argument is a native Viper variable, then cast is a no-op (i.e. costs nothing at runtime) - that just changes the type (e.g. from ``uint`` to ``ptr8``) so that you can then store/load - using this pointer. -* If the argument is a Python object and the cast is ``int`` or ``uint``, then the Python object - must be of integral type and the value of that integral object is returned. -* The argument to a bool cast must be integral type (boolean or integer); when used as a return - type the viper function will return True or False objects. -* If the argument is a Python object and the cast is ``ptr``, ``ptr``, ``ptr16`` or ``ptr32``, - then the Python object must either have the buffer protocol with read-write capabilities - (in which case a pointer to the start of the buffer is returned) or it must be of integral - type (in which case the value of that integral object is returned). - -The following example illustrates the use of a ``ptr16`` cast to toggle pin X1 ``n`` times: - -.. code:: python - - BIT0 = const(1) - @micropython.viper - def toggle_n(n: int): - odr = ptr16(stm.GPIOA + stm.GPIO_ODR) - for _ in range(n): - odr[0] ^= BIT0 - -A detailed technical description of the three code emitters may be found -on Kickstarter here `Note 1 `_ -and here `Note 2 `_ - -Accessing hardware directly ---------------------------- - -.. note:: - - Code examples in this section are given for the Pyboard. The techniques - described however may be applied to other MicroPython ports too. - -This comes into the category of more advanced programming and involves some knowledge -of the target MCU. Consider the example of toggling an output pin on the Pyboard. The -standard approach would be to write - -.. code:: python - - mypin.value(mypin.value() ^ 1) # mypin was instantiated as an output pin - -This involves the overhead of two calls to the :class:`~machine.Pin` instance's :meth:`~machine.Pin.value()` -method. This overhead can be eliminated by performing a read/write to the relevant bit -of the chip's GPIO port output data register (odr). To facilitate this the ``stm`` -module provides a set of constants providing the addresses of the relevant registers. -A fast toggle of pin ``P4`` (CPU pin ``A14``) - corresponding to the green LED - -can be performed as follows: - -.. code:: python - - import machine - import stm - - BIT14 = const(1 << 14) - machine.mem16[stm.GPIOA + stm.GPIO_ODR] ^= BIT14 diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000000..9edf6d328d8 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,3 @@ +sphinx==1.8.5 +recommonmark==0.5.0 +sphinxcontrib-svg2pdfconverter==0.1.0 diff --git a/docs/rstjinja.py b/docs/rstjinja.py new file mode 100644 index 00000000000..3a08b259977 --- /dev/null +++ b/docs/rstjinja.py @@ -0,0 +1,24 @@ +# Derived from code on Eric Holscher's blog, found at: +# https://www.ericholscher.com/blog/2016/jul/25/integrating-jinja-rst-sphinx/ + +def rstjinja(app, docname, source): + """ + Render our pages as a jinja template for fancy templating goodness. + """ + # Make sure we're outputting HTML + if app.builder.format != 'html': + return + + # we only want our one jinja template to run through this func + if "shared-bindings/support_matrix" not in docname: + return + + src = source[0] + print(docname) + rendered = app.builder.templates.render_string( + src, app.config.html_context + ) + source[0] = rendered + +def setup(app): + app.connect("source-read", rstjinja) diff --git a/docs/shared_bindings_matrix.py b/docs/shared_bindings_matrix.py new file mode 100644 index 00000000000..ed88efc75e8 --- /dev/null +++ b/docs/shared_bindings_matrix.py @@ -0,0 +1,244 @@ +# The MIT License (MIT) +# +# Copyright (c) 2019 Michael Schroeder +# +# 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. +# + +import json +import os +import re + + +SUPPORTED_PORTS = ["atmel-samd", "nrf"] + + +def parse_port_config(contents, chip_keyword=None): + """ Compile a dictionary of port-wide module configs, which may + be categorized by chipset. + """ + chip_fam = "all" + ifeq_found = False + port_config_results = {"all": []} + + chip_pattern = "" + if chip_keyword: + chip_pattern = ( + re.compile("(?<=ifeq\s\(\$\({}\)\,)(\w+)".format(chip_keyword)) + ) + + for line in contents: + if chip_keyword: + if not ifeq_found: + check_ifeq = chip_pattern.search(line) + if check_ifeq: + ifeq_found = True + chip_fam = check_ifeq.group(1) + #print("found chip:", chip_fam) + else: + ifeq_found = False + chip_fam = "all" + else: + if "endif" in line: + ifeq_found = False + chip_fam = "all" + + if "CIRCUITPY_" in line: + if chip_fam in port_config_results: + port_config_results[chip_fam].append(line.rstrip("\n")) + else: + port_config_results[chip_fam] = [line.rstrip("\n")] + + #print(port_config_results) + return port_config_results + +def get_shared_bindings(): + """ Get a list of modules in shared-bindings based on folder names + """ + return [item for item in os.listdir("./shared-bindings")] + + +def read_mpconfig(): + """ Open 'circuitpy_mpconfig.mk' and return the contents. + """ + configs = [] + with open("py/circuitpy_mpconfig.mk") as mpconfig: + configs = mpconfig.read() + + return configs + + +def build_module_map(): + """ Establish the base of the JSON file, based on the contents from + `configs`. Base will contain module names, if they're part of + the `FULL_BUILD`, or their default value (0 | 1). + + """ + base = dict() + modules = get_shared_bindings() + configs = read_mpconfig() + full_build = False + for module in modules: + full_name = module + search_name = module.lstrip("_") + re_pattern = "CIRCUITPY_{}\s=\s(.+)".format(search_name.upper()) + find_config = re.search(re_pattern, configs) + #print(module, "|", find_config) + if not find_config: + continue + full_build = int("FULL_BUILD" in find_config.group(0)) + #print(find_config[1]) + if not full_build: + default_val = find_config.group(1) + else: + default_val = "None" + base[search_name] = { + "name": full_name, + "full_build": str(full_build), + "default_value": default_val, + "excluded": {} + } + + return base + + +def get_excluded_boards(base): + """ Cycles through each board's `mpconfigboard.mk` file to determine + if each module is included or not. Boards are selected by existence + in a port listed in `SUPPORTED_PORTS` (e.g. `/port/nrf/feather_52840`) + + Boards are further categorized by their respective chipset (SAMD21, + SAMD51, nRF52840, etc.) + """ + modules = list(base.keys()) + + re_board_chip = None + chip_keyword = None + for port in SUPPORTED_PORTS: + # each port appears to use its own define for the chipset + if port in ["atmel-samd"]: + re_board_chip = re.compile("CHIP_FAMILY\s=\s(\w+)") + chip_keyword = "CHIP_FAMILY" + elif port in ["nrf"]: + re_board_chip = re.compile("MCU_VARIANT\s=\s(\w+)") + + port_dir = "ports/{}".format(port) + + port_config_contents = "" + with open(os.path.join(port_dir, "mpconfigport.mk")) as port_config: + port_config_contents = port_config.readlines() + port_config = parse_port_config(port_config_contents, chip_keyword) + + for entry in os.scandir(os.path.join(port_dir, "boards")): + if not entry.is_dir(): + continue + + contents = "" + board_dir = os.path.join(entry.path, "mpconfigboard.mk") + with open(board_dir) as board: + contents = board.read() + + board_chip = re_board_chip.search(contents) + #print(entry.name, board_chip.group(1)) + if not board_chip: + board_chip = "Unknown Chip" + else: + board_chip = board_chip.group(1) + + # add port_config results to contents + contents += "\n" + "\n".join(port_config["all"]) + if board_chip in port_config: + contents += "\n" + "\n".join(port_config[board_chip]) + + for module in modules: + board_is_excluded = False + # check if board uses `SMALL_BUILD`. if yes, and current + # module is marked as `FULL_BUILD`, board is excluded + small_build = re.search("CIRCUITPY_SMALL_BUILD = 1", contents) + if small_build and base[module]["full_build"] == "1": + board_is_excluded = True + # check if module is specifically disabled for this board + re_pattern = "CIRCUITPY_{}\s=\s(\w)".format(module.upper()) + find_module = re.search(re_pattern, contents) + if not find_module: + # check if default inclusion is off ('0'). if the board doesn't + # have it explicitly enabled, its excluded. + if base[module]["default_value"] == "0": + board_is_excluded = True + else: + if (find_module.group(1) == "0" and + find_module.group(1) != base[module]["default_value"]): + board_is_excluded = True + + if board_is_excluded: + if board_chip in base[module]["excluded"]: + base[module]["excluded"][board_chip].append(entry.name) + else: + base[module]["excluded"][board_chip] = [entry.name] + #print(json.dumps(base, indent=2)) + return base + + +def support_matrix_excluded_boards(): + """ Compiles a list of available modules, and which board definitions + do not include them. + """ + base = build_module_map() + + return get_excluded_boards(base) + +def support_matrix_by_board(): + """ Compiles a list of the available core modules available for each + board. + """ + base = build_module_map() + base_with_exclusions = get_excluded_boards(base) + + boards = dict() + for port in SUPPORTED_PORTS: + port_dir = "ports/{}/boards".format(port) + for entry in os.scandir(port_dir): + if not entry.is_dir(): + continue + board_modules = [] + + board_name = entry.name + board_contents = "" + with open(os.path.join(entry.path, "mpconfigboard.h")) as get_name: + board_contents = get_name.read() + board_name_re = re.search("(?<=MICROPY_HW_BOARD_NAME)\s+(.+)", + board_contents) + if board_name_re: + board_name = board_name_re.group(1).strip('"') + + for module in base_with_exclusions.keys(): + #print(module) + board_has_module = True + if base_with_exclusions[module]["excluded"]: + for port in base_with_exclusions[module]["excluded"].values(): + #print(port) + if entry.name in port: + board_has_module = False + + if board_has_module: + board_modules.append(base_with_exclusions[module]["name"]) + boards[board_name] = sorted(board_modules) + + #print(json.dumps(boards, indent=2)) + return boards diff --git a/docs/sphinx_selective_exclude/LICENSE b/docs/sphinx_selective_exclude/LICENSE deleted file mode 100644 index 0b47ced8a15..00000000000 --- a/docs/sphinx_selective_exclude/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2016 by the sphinx_selective_exclude authors. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/docs/sphinx_selective_exclude/README.md b/docs/sphinx_selective_exclude/README.md deleted file mode 100644 index dab1407392f..00000000000 --- a/docs/sphinx_selective_exclude/README.md +++ /dev/null @@ -1,138 +0,0 @@ -Sphinx eager ".. only::" directive and other selective rendition extensions -=========================================================================== - -Project home page: https://github.com/pfalcon/sphinx_selective_exclude - -The implementation of ".. only::" directive in Sphinx documentation -generation tool is known to violate principles of least user surprise -and user expectations in general. Instead of excluding content early -in the pipeline (pre-processor style), Sphinx defers exclusion until -output phase, and what's the worst, various stages processing ignore -"only" blocks and their exclusion status, so they may leak unexpected -information into ToC, indexes, etc. - -There's multiple issues submitted upstream on this matter: - -* https://github.com/sphinx-doc/sphinx/issues/2150 -* https://github.com/sphinx-doc/sphinx/issues/1717 -* https://github.com/sphinx-doc/sphinx/issues/1488 -* etc. - -They are largely ignored by Sphinx maintainers. - -This projects tries to rectify situation on users' side. It actually -changes the way Sphinx processes "only" directive, but does this -without forking the project, and instead is made as a standard -Sphinx extension, which a user may add to their documentation config. -Unlike normal extensions, extensions provided in this package -monkey-patch Sphinx core to work in a way expected by users. - -eager_only ----------- - -The core extension provided by the package is called `eager_only` and -is based on the idea by Andrea Cassioli (see bugreports above) to -process "only" directive as soon as possible during parsing phase. -This approach has some drawbacks, like producing warnings like -"WARNING: document isn't included in any toctree" if "only" is used -to shape up a toctree, or the fact that changing a documentation -builder (html/latex/etc.) will almost certainly require complete -rebuild of documentation. But these are relatively minor issues -comparing to completely broken way "only" works in upstream Sphinx. - -modindex_exclude ----------------- - -"only" directive allows for fine-grained conditional exclusion, but -sometimes you may want to exclude entire module(s) at once. Even if -you wrap an entire module description in "only" directive, like: - - .. only: option1 - .. module:: my_module - - ... - -You will still have an HTML page generated, albeit empty. It may also -go into indexes, so will be discoverable by users, leading to less -than ideal experience. `modindex_exclude` extension is design to -resolve this issue, by making sure that any reference of a module -is excluded from Python module index ("modindex"), as well as -general cross-reference index ("genindex"). In the latter case, -any symbol belong to a module will be excluded. Unlike `eager_only` -extension which appear to have issued with "latexpdf" builder, -`modindex_exclude` is useful for PDF, and allows to get cleaner -index for PDF, just the same as for HTML. - -search_auto_exclude -------------------- - -Even if you exclude some documents from toctree:: using only:: -directive, they will be indexed for full-text search, so user may -find them and get confused. This plugin follows very simple idea -that if you didn't include some documents in the toctree, then -you didn't want them to be accessible (e.g. for a particular -configuration), and so will make sure they aren't indexed either. - -This extension depends on `eager_only` and won't work without it. -Note that Sphinx will issue warnings, as usual, for any documents -not included in a toctree. This is considered a feature, and gives -you a chance to check that document exclusions are indeed right -for a particular configuration you build (and not that you forgot -to add something to a toctree). - -Summary -------- - -Based on the above, sphinx_selective_exclude offers extension to let -you: - -* Make "only::" directive work in an expected, intuitive manner, using - `eager_only` extension. -* However, if you apply only:: to toctree::, excluded documents will - still be available via full-text search, so you need to use - `search_auto_exclude` for that to work as expected. -* Similar to search, indexes may also require special treatment, hence - there's the `modindex_exclude` extension. - -Most likely, you will want to use all 3 extensions together - if you -really want build subsets of docimentation covering sufficiently different -configurations from a single doctree. However, if one of them is enough -to cover your usecase, that's OK to (and why they were separated into -3 extensions, to follow KISS and "least surprise" principles and to -not make people deal with things they aren't interested in). In this case, -however remember there're other extensions, if you later hit a usecase -when they're needed. - -Usage ------ - -To use these extensions, add https://github.com/pfalcon/sphinx_selective_exclude -as a git submodule to your project, in documentation folder (where -Sphinx conf.py is located). Alternatively, commit sphinx_selective_exclude -directory instead of making it a submodule (you will need to pick up -any project updates manually then). - -Add following lines to "extensions" settings in your conf.py (you -likely already have some standard Sphinx extensions enabled): - - extensions = [ - ... - 'sphinx_selective_exclude.eager_only', - 'sphinx_selective_exclude.search_auto_exclude', - 'sphinx_selective_exclude.modindex_exclude', - ] - -As discussed above, you may enable all extensions, or one by one. - -Please note that to make sure these extensions work well and avoid producing -output docs with artifacts, it is IMPERATIVE to remove cached doctree if -you rebuild documentation with another builder (i.e. with different output -format). Also, to stay on safe side, it's recommended to remove old doctree -anyway before generating production-ready documentation for publishing. To -do that, run something like: - - rm -rf _build/doctrees/ - -A typical artificat when not following these simple rules is that content -of some sections may be missing. If you face anything like that, just -remember what's written above and remove cached doctrees. diff --git a/docs/sphinx_selective_exclude/eager_only.py b/docs/sphinx_selective_exclude/eager_only.py deleted file mode 100644 index 82766c2e64c..00000000000 --- a/docs/sphinx_selective_exclude/eager_only.py +++ /dev/null @@ -1,45 +0,0 @@ -# -# This is a Sphinx documentation tool extension which makes .only:: -# directives be eagerly processed early in the parsing stage. This -# makes sure that content in .only:: blocks gets actually excluded -# as a typical user expects, instead of bits of information in -# these blocks leaking to documentation in various ways (e.g., -# indexes containing entries for functions which are actually in -# .only:: blocks and thus excluded from documentation, etc.) -# Note that with this extension, you may need to completely -# rebuild a doctree when switching builders (i.e. completely -# remove _build/doctree dir between generation of HTML vs PDF -# documentation). -# -# This extension works by monkey-patching Sphinx core, so potentially -# may not work with untested Sphinx versions. It tested to work with -# 1.2.2 and 1.4.2 -# -# Copyright (c) 2016 Paul Sokolovsky -# Based on idea by Andrea Cassioli: -# https://github.com/sphinx-doc/sphinx/issues/2150#issuecomment-171912290 -# Licensed under the terms of BSD license, see LICENSE file. -# -import sphinx -from docutils.parsers.rst import directives - - -class EagerOnly(sphinx.directives.other.Only): - - def run(self, *args): - # Evaluate the condition eagerly, and if false return no nodes right away - env = self.state.document.settings.env - env.app.builder.tags.add('TRUE') - #print(repr(self.arguments[0])) - if not env.app.builder.tags.eval_condition(self.arguments[0]): - return [] - - # Otherwise, do the usual processing - nodes = super(EagerOnly, self).run() - if len(nodes) == 1: - nodes[0]['expr'] = 'TRUE' - return nodes - - -def setup(app): - directives.register_directive('only', EagerOnly) diff --git a/docs/sphinx_selective_exclude/modindex_exclude.py b/docs/sphinx_selective_exclude/modindex_exclude.py deleted file mode 100644 index bf8db795e6f..00000000000 --- a/docs/sphinx_selective_exclude/modindex_exclude.py +++ /dev/null @@ -1,75 +0,0 @@ -# -# This is a Sphinx documentation tool extension which allows to -# exclude some Python modules from the generated indexes. Modules -# are excluded both from "modindex" and "genindex" index tables -# (in the latter case, all members of a module are excluded). -# To control exclusion, set "modindex_exclude" variable in Sphinx -# conf.py to the list of modules to exclude. Note: these should be -# modules (as defined by py:module directive, not just raw filenames). -# This extension works by monkey-patching Sphinx core, so potentially -# may not work with untested Sphinx versions. It tested to work with -# 1.2.2 and 1.4.2 -# -# Copyright (c) 2016 Paul Sokolovsky -# Licensed under the terms of BSD license, see LICENSE file. -# -import sphinx - - -#org_PythonModuleIndex_generate = None -org_PyObject_add_target_and_index = None -org_PyModule_run = None - -EXCLUDES = {} - -# No longer used, PyModule_run() monkey-patch does all the job -def PythonModuleIndex_generate(self, docnames=None): - docnames = [] - excludes = self.domain.env.config['modindex_exclude'] - for modname, (docname, synopsis, platforms, deprecated) in self.domain.data['modules'].items(): - #print(docname) - if modname not in excludes: - docnames.append(docname) - - return org_PythonModuleIndex_generate(self, docnames) - - -def PyObject_add_target_and_index(self, name_cls, sig, signode): - if hasattr(self.env, "ref_context"): - # Sphinx 1.4 - ref_context = self.env.ref_context - else: - # Sphinx 1.2 - ref_context = self.env.temp_data - modname = self.options.get( - 'module', ref_context.get('py:module')) - #print("*", modname, name_cls) - if modname in self.env.config['modindex_exclude']: - return None - return org_PyObject_add_target_and_index(self, name_cls, sig, signode) - - -def PyModule_run(self): - env = self.state.document.settings.env - modname = self.arguments[0].strip() - excl = env.config['modindex_exclude'] - if modname in excl: - self.options['noindex'] = True - EXCLUDES.setdefault(modname, []).append(env.docname) - return org_PyModule_run(self) - - -def setup(app): - app.add_config_value('modindex_exclude', [], 'html') - -# global org_PythonModuleIndex_generate -# org_PythonModuleIndex_generate = sphinx.domains.python.PythonModuleIndex.generate -# sphinx.domains.python.PythonModuleIndex.generate = PythonModuleIndex_generate - - global org_PyObject_add_target_and_index - org_PyObject_add_target_and_index = sphinx.domains.python.PyObject.add_target_and_index - sphinx.domains.python.PyObject.add_target_and_index = PyObject_add_target_and_index - - global org_PyModule_run - org_PyModule_run = sphinx.domains.python.PyModule.run - sphinx.domains.python.PyModule.run = PyModule_run diff --git a/docs/sphinx_selective_exclude/search_auto_exclude.py b/docs/sphinx_selective_exclude/search_auto_exclude.py deleted file mode 100644 index b8b326dd2c3..00000000000 --- a/docs/sphinx_selective_exclude/search_auto_exclude.py +++ /dev/null @@ -1,34 +0,0 @@ -# -# This is a Sphinx documentation tool extension which allows to -# automatically exclude from full-text search index document -# which are not referenced via toctree::. It's intended to be -# used with toctrees conditional on only:: directive, with the -# idea being that if you didn't include it in the ToC, you don't -# want the docs being findable by search either (for example, -# because these docs contain information not pertinent to a -# particular product configuration). -# -# This extension depends on "eager_only" extension and won't work -# without it. -# -# Copyright (c) 2016 Paul Sokolovsky -# Licensed under the terms of BSD license, see LICENSE file. -# -import sphinx - - -org_StandaloneHTMLBuilder_index_page = None - - -def StandaloneHTMLBuilder_index_page(self, pagename, doctree, title): - if pagename not in self.env.files_to_rebuild: - if pagename != self.env.config.master_doc and 'orphan' not in self.env.metadata[pagename]: - print("Excluding %s from full-text index because it's not referenced in ToC" % pagename) - return - return org_StandaloneHTMLBuilder_index_page(self, pagename, doctree, title) - - -def setup(app): - global org_StandaloneHTMLBuilder_index_page - org_StandaloneHTMLBuilder_index_page = sphinx.builders.html.StandaloneHTMLBuilder.index_page - sphinx.builders.html.StandaloneHTMLBuilder.index_page = StandaloneHTMLBuilder_index_page diff --git a/docs/static/customstyle.css b/docs/static/customstyle.css index 74eff4e051e..6c964b762c3 100644 --- a/docs/static/customstyle.css +++ b/docs/static/customstyle.css @@ -8,3 +8,19 @@ .admonition-difference-to-cpython .admonition-title { margin: 4px; } + + + +/* override table width restrictions */ +@media screen and (min-width: 767px) { + + .wy-table-responsive table td { + /* !important prevents the common CSS stylesheets from overriding + this as on RTD they are loaded after this stylesheet */ + white-space: normal !important; + } + + .wy-table-responsive { + overflow: visible !important; + } +} diff --git a/docs/static/favicon.ico b/docs/static/favicon.ico index 49c6154140a..5aca98376a1 100644 Binary files a/docs/static/favicon.ico and b/docs/static/favicon.ico differ diff --git a/docs/supported_ports.rst b/docs/supported_ports.rst new file mode 100644 index 00000000000..039ddea68bd --- /dev/null +++ b/docs/supported_ports.rst @@ -0,0 +1,12 @@ +Supported Ports +============================== + +Adafruit's CircuitPython currently has limited support with a focus on supporting the Atmel SAMD +and ESP8266. + +.. toctree:: + :maxdepth: 2 + + ../ports/atmel-samd/README + ../ports/esp8266/README + ../ports/nrf/README diff --git a/docs/templates/layout.html b/docs/templates/layout.html deleted file mode 100644 index a6caa0bc5a1..00000000000 --- a/docs/templates/layout.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "!layout.html" %} -{% set css_files = css_files + ["_static/customstyle.css"] %} - -{# we change the master_doc variable so that links to the index - page are to index.html instead of _index.html #} -{% set master_doc = "index" %} diff --git a/docs/templates/replace.inc b/docs/templates/replace.inc index 319c53735fc..2636045f6e6 100644 --- a/docs/templates/replace.inc +++ b/docs/templates/replace.inc @@ -4,6 +4,6 @@ .. |see_cpython_module| replace:: - *This module implements a subset of the corresponding* `CPython` *module, - as described below. For more information, refer to the original - CPython documentation:* + *This module implements a subset of the corresponding* ``CPython`` *module, + as described below. For more information, refer to the original* + ``CPython`` *documentation:* diff --git a/docs/templates/topindex.html b/docs/templates/topindex.html deleted file mode 100644 index 76e5e18d722..00000000000 --- a/docs/templates/topindex.html +++ /dev/null @@ -1,112 +0,0 @@ -{% extends "defindex.html" %} -{% block body %} - -

MicroPython documentation

- -

- {{ _('Welcome! This is the documentation for MicroPython') }} - v{{ release|e }}{% if last_updated %}, {{ _('last updated') }} {{ last_updated|e }}{% endif %}. -

- -

- MicroPython runs on a variety of systems and each has their own specific - documentation. You are currently viewing the documentation for - {{ port_name }}. -

- - - -

Documentation for MicroPython and {{ port_name }}:

- - - - -
- {% if port in ("pyboard", "wipy", "esp8266") %} - - - - {% endif %} - - - - - -
- -

Indices and tables:

- - - -
- - - - - -
- -

External links:

- - - - -
- - - - -
- -{% endblock %} diff --git a/docs/templates/unsupported_in_circuitpython.inc b/docs/templates/unsupported_in_circuitpython.inc new file mode 100644 index 00000000000..582bd9dd0d3 --- /dev/null +++ b/docs/templates/unsupported_in_circuitpython.inc @@ -0,0 +1,9 @@ +.. warning:: + + Though this MicroPython-based library may be available for use + in some builds of CircuitPython, it is unsupported and its functionality + may change in the future, perhaps significantly. + As CircuitPython continues to develop, it may be changed + to comply more closely with the corresponding standard Python library. + You will likely need to change your code later if you rely + on any non-standard functionality it currently provides. diff --git a/docs/templates/versions.html b/docs/templates/versions.html deleted file mode 100644 index 198630dd778..00000000000 --- a/docs/templates/versions.html +++ /dev/null @@ -1,37 +0,0 @@ -
- - Ports and Versions - {{ port }} ({{ port_version }}) - - -
-
-
Ports
- {% for slug, url in all_ports %} -
{{ slug }}
- {% endfor %} -
-
-
Versions
- {% for slug, url in all_versions %} -
{{ slug }}
- {% endfor %} -
-
-
Downloads
- {% for type, url in downloads %} -
{{ type }}
- {% endfor %} -
-
-
-
External links
-
- micropython.org -
-
- GitHub -
-
-
-
diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst new file mode 100644 index 00000000000..66bcc2764cb --- /dev/null +++ b/docs/troubleshooting.rst @@ -0,0 +1,55 @@ +Troubleshooting +=============== + +From time to time, an error occurs when working with CircuitPython. Here are a +variety of errors that can happen, what they mean and how to fix them. + +File system issues +------------------ + +If your host computer starts complaining that your ``CIRCUITPY`` drive is corrupted +or files cannot be overwritten or deleted, then you will have to erase it completely. +When CircuitPython restarts it will create a fresh empty ``CIRCUITPY`` filesystem. + +This often happens on Windows when the ``CIRCUITPY`` disk is not safely ejected +before being reset by the button or being disconnected from USB. This can also +happen on Linux and Mac OSX but its less likely. + +.. caution:: To erase and re-create ``CIRCUITPY`` (for example, to correct a corrupted filesystem), + follow one of the procedures below. It's important to note that **any files stored on the** + ``CIRCUITPY`` **drive will be erased**. + +**For boards with** ``CIRCUITPY`` **stored on a separate SPI flash chip, +such as Feather M0 Express, Metro M0 Express and Circuit Playground Express:** + + +#. Download the appropriate flash .erase uf2 from `the Adafruit_SPIFlash repo `_. +#. Double-click the reset button. +#. Copy the appropriate .uf2 to the xxxBOOT drive. +#. The on-board NeoPixel will turn blue, indicating the erase has started. +#. After about 15 seconds, the NexoPixel will start flashing green. If it flashes red, the erase failed. +#. Double-click again and load the appropriate `CircuitPython .uf2 `_. + +**For boards without SPI flash, such as Feather M0 Proto, Gemma M0 and, Trinket M0:** + +#. Download the appropriate erase .uf2 from `the Learn repo `_. +#. Double-click the reset button. +#. Copy the appropriate .uf2 to the xxxBOOT drive. +#. The boot LED will start pulsing again, and the xxxBOOT drive will appear again. +#. Load the appropriate `CircuitPython .uf2 `_. + +ValueError: Incompatible ``.mpy`` file. +--------------------------------------- + +This error occurs when importing a module that is stored as a ``mpy`` binary file +(rather than a ``py`` text file) that was generated by a different version of +CircuitPython than the one its being loaded into. Most versions are compatible +but, rarely they aren't. In particular, the ``mpy`` binary format changed between +CircuitPython versions 1.x and 2.x, and will change again between 2.x and 3.x. + +So, for instance, if you just upgraded to CircuitPython 2.x from 1.x you'll need to download a +newer version of the library that triggered the error on ``import``. They are +all available in the +`Adafruit bundle `_ +and the `Community bundle `_. +Make sure to download a version with 2.0.0 or higher in the filename. diff --git a/docs/unix_index.rst b/docs/unix_index.rst deleted file mode 100644 index 1bfeb0bdac3..00000000000 --- a/docs/unix_index.rst +++ /dev/null @@ -1,9 +0,0 @@ -MicroPython documentation and references -======================================== - -.. toctree:: - - library/index.rst - reference/index.rst - genrst/index.rst - license.rst diff --git a/docs/wipy/general.rst b/docs/wipy/general.rst deleted file mode 100644 index f28edb4e4b9..00000000000 --- a/docs/wipy/general.rst +++ /dev/null @@ -1,385 +0,0 @@ -General information about the WiPy -================================== - -No floating point support -------------------------- - -Due to space reasons, there's no floating point support, and no math module. This -means that floating point numbers cannot be used anywhere in the code, and that -all divisions must be performed using '//' instead of '/'. Example:: - - >>> r = 4 // 2 # this will work - >>> r = 4 / 2 # this WON'T - -Before applying power ---------------------- - -.. warning:: - - The GPIO pins of the WiPy are NOT 5V tolerant, connecting them to voltages higher - than 3.6V will cause irreparable damage to the board. ADC pins, when configured - in analog mode cannot withstand voltages above 1.8V. Keep these considerations in - mind when wiring your electronics. - -WLAN default behaviour ----------------------- - -When the WiPy boots with the default factory configuration starts in Access Point -mode with ``ssid`` that starts with: ``wipy-wlan`` and ``key: www.wipy.io``. -Connect to this network and the WiPy will be reachable at ``192.168.1.1``. In order -to gain access to the interactive prompt, open a telnet session to that IP address on -the default port (23). You will be asked for credentials: -``login: micro`` and ``password: python`` - -.. _wipy_telnet: - -Telnet REPL ------------ - -Linux stock telnet works like a charm (also on OSX), but other tools like putty -work quite well too. The default credentials are: **user:** ``micro``, **password:** ``python``. -See :ref:`network.server ` for info on how to change the defaults. -For instance, on a linux shell (when connected to the WiPy in AP mode):: - - $ telnet 192.168.1.1 - -.. _wipy_filesystem: - -Local file system and FTP access --------------------------------- - -There is a small internal file system (a drive) on the WiPy, called ``/flash``, -which is stored within the external serial flash memory. If a micro SD card -is hooked-up and mounted, it will be available as well. - -When the WiPy starts up, it always boots from the ``boot.py`` located in the -``/flash`` file system. On boot up, the current directory is ``/flash``. - -The file system is accessible via the native FTP server running in the WiPy. -Open your FTP client of choice and connect to: - -**url:** ``ftp://192.168.1.1``, **user:** ``micro``, **password:** ``python`` - -See :ref:`network.server ` for info on how to change the defaults. -The recommended clients are: Linux stock FTP (also in OSX), Filezilla and FireFTP. -For example, on a linux shell:: - - $ ftp 192.168.1.1 - -The FTP server on the WiPy doesn't support active mode, only passive, therefore, -if using the native unix ftp client, just after logging in do:: - - ftp> passive - -Besides that, the FTP server only supports one data connection at a time. Check out -the Filezilla settings section below for more info. - -FileZilla settings ------------------- -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. Other FTP clients might behave in a similar way. - -.. _wipy_firmware_upgrade: - -Upgrading the firmware Over The Air ------------------------------------ - -OTA software updates can be performed through the FTP server. Upload the ``mcuimg.bin`` file -to: ``/flash/sys/mcuimg.bin`` it will take around 6s. You won't see the file being stored -inside ``/flash/sys/`` because it's actually saved bypassing the user file system, so it -ends up inside the internal **hidden** file system, but rest assured that it was successfully -transferred, and it has been signed with a MD5 checksum to verify its integrity. Now, reset -the WiPy by pressing the switch on the board, or by typing:: - - >>> import machine - >>> machine.reset() - -Software updates can be found in: https://github.com/wipy/wipy/releases (**Binaries.zip**). -It's always recommended to update to the latest software, but make sure to -read the **release notes** before. - -.. note:: - - The ``bootloader.bin`` found inside ``Binaries.zip`` is there only for reference, it's not - needed for the Over The Air update. - -In order to check your software version, do:: - - >>> import os - >>> os.uname().release - -If the version number is lower than the latest release found in -`the releases `_, go ahead and update your WiPy! - - -.. _wipy_boot_modes: - -Boot modes and safe boot ------------------------- - -If you power up normally, or press the reset button, the WiPy will boot -into standard mode; the ``boot.py`` file will be executed first, then -``main.py`` will run. - -You can override this boot sequence by pulling ``GP28`` **up** (connect -it to the 3v3 output pin) during reset. This procedure also allows going -back in time to old firmware versions. The WiPy can hold up to 3 different -firmware versions, which are: the factory firmware plus 2 user updates. - -After reset, if ``GP28`` is held high, the heartbeat LED will start flashing -slowly, if after 3 seconds the pin is still being held high, the LED will start -blinking a bit faster and the WiPy will select the previous user update to boot. -If the previous user update is the desired firmware image, ``GP28`` must be -released before 3 more seconds elapse. If 3 seconds later the pin is still high, -the factory firmware will be selected, the LED will flash quickly for 1.5 seconds -and the WiPy will proceed to boot. The firmware selection mechanism is as follows: - - -**Safe Boot Pin** ``GP28`` **released during:** - -+-------------------------+-------------------------+----------------------------+ -| 1st 3 secs window | 2nd 3 secs window | Final 1.5 secs window | -+=========================+=========================+============================+ -| | Safe boot, *latest* | | Safe boot, *previous* | | Safe boot, the *factory* | -| | firmware is selected | | user update selected | | firmware is selected | -+-------------------------+-------------------------+----------------------------+ - -On all of the above 3 scenarios, safe boot mode is entered, meaning that -the execution of both ``boot.py`` and ``main.py`` is skipped. This is -useful to recover from crash situations caused by the user scripts. The selection -made during safe boot is not persistent, therefore after the next normal reset -the latest firmware will run again. - -The heartbeat LED ------------------- - -By default the heartbeat LED flashes once every 4s to signal that the system is -alive. This can be overridden through the :mod:`wipy` module:: - - >>> import wipy - >>> wipy.heartbeat(False) - -There are currently 2 kinds of errors that you might see: - -1. If the heartbeat LED flashes quickly, then a Python script (eg ``main.py``) - has an error. Use the REPL to debug it. -2. If the heartbeat LED stays on, then there was a hard fault, you cannot - recover from this, the only way out is to press the reset switch. - -Details on sleep modes ----------------------- - -* ``machine.idle()``: Power consumption: ~12mA (in WLAN STA mode). Wake sources: - any hardware interrupt (including systick with period of 1ms), no special - configuration required. -* ``machine.sleep()``: 950uA (in WLAN STA mode). Wake sources are ``Pin``, ``RTC`` - and ``WLAN`` -* ``machine.deepsleep()``: ~350uA. Wake sources are ``Pin`` and ``RTC``. - -Additional details for machine.Pin ----------------------------------- - -On the WiPy board the pins are identified by their string id:: - - from machine import Pin - g = machine.Pin('GP9', mode=Pin.OUT, pull=None, drive=Pin.MED_POWER, alt=-1) - -You can also configure the Pin to generate interrupts. For instance:: - - from machine import Pin - - def pincb(pin): - print(pin.id()) - - pin_int = Pin('GP10', mode=Pin.IN, pull=Pin.PULL_DOWN) - pin_int.irq(trigger=Pin.IRQ_RISING, handler=pincb) - # the callback can be triggered manually - pin_int.irq()() - # to disable the callback - pin_int.irq().disable() - -Now every time a falling edge is seen on the gpio pin, the callback will be -executed. Caution: mechanical push buttons have "bounce" and pushing or -releasing a switch will often generate multiple edges. -See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed -explanation, along with various techniques for debouncing. - -All pin objects go through the pin mapper to come up with one of the -gpio pins. - -For the ``drive`` parameter the strengths are: - - - ``Pin.LOW_POWER`` - 2mA drive capability. - - ``Pin.MED_POWER`` - 4mA drive capability. - - ``Pin.HIGH_POWER`` - 6mA drive capability. - -For the ``alt`` parameter please refer to the pinout and alternate functions -table at `_ -for the specific alternate functions that each pin supports. - -For interrupts, the ``priority`` can take values in the range 1-7. And the -``wake`` parameter has the following properties: - - - If ``wake_from=machine.Sleep.ACTIVE`` any pin can wake the board. - - If ``wake_from=machine.Sleep.SUSPENDED`` pins ``GP2``, ``GP4``, ``GP10``, - ``GP11``, GP17`` or ``GP24`` can wake the board. Note that only 1 - of this pins can be enabled as a wake source at the same time, so, only - the last enabled pin as a ``machine.Sleep.SUSPENDED`` wake source will have effect. - - If ``wake_from=machine.Sleep.SUSPENDED`` pins ``GP2``, ``GP4``, ``GP10``, - ``GP11``, ``GP17`` and ``GP24`` can wake the board. In this case all of the - 6 pins can be enabled as a ``machine.Sleep.HIBERNATE`` wake source at the same time. - -Additional Pin methods: - -.. method:: machine.Pin.alt_list() - - Returns a list of the alternate functions supported by the pin. List items are - a tuple of the form: ``('ALT_FUN_NAME', ALT_FUN_INDEX)`` - -Additional details for machine.I2C ----------------------------------- - -On the WiPy there is a single hardware I2C peripheral, identified by "0". By -default this is the peripheral that is used when constructing an I2C instance. -The default pins are GP23 for SCL and GP13 for SDA, and one can create the -default I2C peripheral simply by doing:: - - i2c = machine.I2C() - -The pins and frequency can be specified as:: - - i2c = machine.I2C(freq=400000, scl='GP23', sda='GP13') - -Only certain pins can be used as SCL/SDA. Please refer to the pinout for further -information. - -Known issues ------------- - -Incompatible way to create SSL sockets -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -SSL sockets need to be created the following way before wrapping them with. -``ssl.wrap_socket``:: - - import socket - import ssl - s = socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_SEC) - ss = ssl.wrap_socket(s) - -Certificates must be used in order to validate the other side of the connection, and also to -authenticate ourselves with the other end. Such certificates must be stored as files using the -FTP server, and they must be placed in specific paths with specific names. - -- The certificate to validate the other side goes in: **'/flash/cert/ca.pem'** -- The certificate to authenticate ourselves goes in: **'/flash/cert/cert.pem'** -- The key for our own certificate goes in: **'/flash/cert/private.key'** - -.. note:: - - When these files are stored, they are placed inside the internal **hidden** file system - (just like firmware updates), and therefore they are never visible. - -For instance to connect to the Blynk servers using certificates, take the file ``ca.pem`` located -in the `blynk examples folder `_. -and put it in '/flash/cert/'. Then do:: - - import socket - import ssl - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_SEC) - ss = ssl.wrap_socket(s, cert_reqs=ssl.CERT_REQUIRED, ca_certs='/flash/cert/ca.pem') - ss.connect(socket.getaddrinfo('cloud.blynk.cc', 8441)[0][-1]) - -Incompatibilities in uhashlib module -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Due to hardware implementation details of the WiPy, data must be buffered before being -digested, which would make it impossible to calculate the hash of big blocks of data that -do not fit in RAM. In this case, since most likely the total size of the data is known -in advance, the size can be passed to the constructor and hence the HASH hardware engine -of the WiPy can be properly initialized without needing buffering. If ``block_size`` is -to be given, an initial chunk of ``data`` must be passed as well. **When using this extension, -care must be taken to make sure that the length of all intermediate chunks (including the -initial one) is a multiple of 4 bytes.** The last chunk may be of any length. - -Example:: - - hash = uhashlib.sha1('abcd1234', 1001) # length of the initial piece is multiple of 4 bytes - hash.update('1234') # also multiple of 4 bytes - ... - hash.update('12345') # last chunk may be of any length - hash.digest() - -Unrelated function in machine module -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. function:: main(filename) - - Set the filename of the main script to run after boot.py is finished. If - this function is not called then the default file main.py will be executed. - - It only makes sense to call this function from within boot.py. - -Adhoc way to control telnet/FTP server via network module -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The ``Server`` class controls the behaviour and the configuration of the FTP and telnet -services running on the WiPy. Any changes performed using this class' methods will -affect both. - -Example:: - - import network - server = network.Server() - server.deinit() # disable the server - # enable the server again with new settings - server.init(login=('user', 'password'), timeout=600) - -.. class:: network.Server(id, ...) - - Create a server instance, see ``init`` for parameters of initialization. - -.. method:: server.init(\*, login=('micro', 'python'), timeout=300) - - Init (and effectively start the server). Optionally a new ``user``, ``password`` - and ``timeout`` (in seconds) can be passed. - -.. method:: server.deinit() - - Stop the server - -.. method:: server.timeout([timeout_in_seconds]) - - Get or set the server timeout. - -.. method:: server.isrunning() - - Returns ``True`` if the server is running, ``False`` otherwise. - -Adhoc VFS-like support -~~~~~~~~~~~~~~~~~~~~~~ - -WiPy doesn't implement full MicroPython VFS support, instead following -functions are defined in ``uos`` module: - -.. function:: mount(block_device, mount_point, \*, readonly=False) - - Mounts a block device (like an ``SD`` object) in the specified mount - point. Example:: - - os.mount(sd, '/sd') - -.. function:: unmount(path) - - Unmounts a previously mounted block device from the given path. - -.. function:: mkfs(block_device or path) - - Formats the specified path, must be either ``/flash`` or ``/sd``. - A block device can also be passed like an ``SD`` object before - being mounted. - diff --git a/docs/wipy/quickref.rst b/docs/wipy/quickref.rst deleted file mode 100644 index f60c81f5fe3..00000000000 --- a/docs/wipy/quickref.rst +++ /dev/null @@ -1,218 +0,0 @@ -.. _quickref_: - -Quick reference for the WiPy -============================ - -.. image:: https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png - :alt: WiPy pinout and alternate functions table - :width: 800px - -General board control (including sleep modes) ---------------------------------------------- - -See the :mod:`machine` module:: - - import machine - - help(machine) # display all members from the machine module - machine.freq() # get the CPU frequency - machine.unique_id() # return the 6-byte unique id of the board (the WiPy's MAC address) - - machine.idle() # average current decreases to (~12mA), any interrupts wake it up - machine.sleep() # everything except for WLAN is powered down (~950uA avg. current) - # wakes from Pin, RTC or WLAN - machine.deepsleep() # deepest sleep mode, MCU starts from reset. Wakes from Pin and RTC. - -Pins and GPIO -------------- - -See :ref:`machine.Pin `. :: - - from machine import Pin - - # initialize GP2 in gpio mode (alt=0) and make it an output - p_out = Pin('GP2', mode=Pin.OUT) - p_out.value(1) - p_out.value(0) - p_out.toggle() - p_out(True) - - # make GP1 an input with the pull-up enabled - p_in = Pin('GP1', mode=Pin.IN, pull=Pin.PULL_UP) - p_in() # get value, 0 or 1 - -Timers ------- - -See :ref:`machine.Timer ` and :ref:`machine.Pin `. -Timer ``id``'s take values from 0 to 3.:: - - from machine import Timer - from machine import Pin - - tim = Timer(0, mode=Timer.PERIODIC) - tim_a = tim.channel(Timer.A, freq=1000) - tim_a.freq(5) # 5 Hz - - p_out = Pin('GP2', mode=Pin.OUT) - tim_a.irq(trigger=Timer.TIMEOUT, handler=lambda t: p_out.toggle()) - -PWM (pulse width modulation) ----------------------------- - -See :ref:`machine.Pin ` and :ref:`machine.Timer `. :: - - from machine import Timer - - # timer 1 in PWM mode and width must be 16 buts - tim = Timer(1, mode=Timer.PWM, width=16) - - # enable channel A @1KHz with a 50.55% duty cycle - tim_a = tim.channel(Timer.A, freq=1000, duty_cycle=5055) - -ADC (analog to digital conversion) ----------------------------------- - -See :ref:`machine.ADC `. :: - - from machine import ADC - - adc = ADC() - apin = adc.channel(pin='GP3') - apin() # read value, 0-4095 - -UART (serial bus) ------------------ - -See :ref:`machine.UART `. :: - - from machine import UART - uart = UART(0, baudrate=9600) - uart.write('hello') - uart.read(5) # read up to 5 bytes - -SPI bus -------- - -See :ref:`machine.SPI `. :: - - from machine import SPI - - # configure the SPI master @ 2MHz - spi = SPI(0, SPI.MASTER, baudrate=200000, polarity=0, phase=0) - spi.write('hello') - spi.read(5) # receive 5 bytes on the bus - rbuf = bytearray(5) - spi.write_readinto('hello', rbuf) # send and receive 5 bytes - -I2C bus -------- - -See :ref:`machine.I2C `. :: - - from machine import I2C - # configure the I2C bus - i2c = I2C(baudrate=100000) - i2c.scan() # returns list of slave addresses - i2c.writeto(0x42, 'hello') # send 5 bytes to slave with address 0x42 - i2c.readfrom(0x42, 5) # receive 5 bytes from slave - i2c.readfrom_mem(0x42, 0x10, 2) # read 2 bytes from slave 0x42, slave memory 0x10 - i2c.writeto_mem(0x42, 0x10, 'xy') # write 2 bytes to slave 0x42, slave memory 0x10 - -Watchdog timer (WDT) --------------------- - -See :ref:`machine.WDT `. :: - - from machine import WDT - - # enable the WDT with a timeout of 5s (1s is the minimum) - wdt = WDT(timeout=5000) - wdt.feed() - -Real time clock (RTC) ---------------------- - -See :ref:`machine.RTC ` :: - - from machine import RTC - - rtc = RTC() # init with default time and date - rtc = RTC(datetime=(2015, 8, 29, 9, 0, 0, 0, None)) # init with a specific time and date - print(rtc.now()) - - def alarm_handler (rtc_o): - pass - # do some non blocking operations - # warning printing on an irq via telnet is not - # possible, only via UART - - # create a RTC alarm that expires after 5 seconds - rtc.alarm(time=5000, repeat=False) - - # enable RTC interrupts - rtc_i = rtc.irq(trigger=RTC.ALARM0, handler=alarm_handler, wake=machine.SLEEP) - - # go into suspended mode waiting for the RTC alarm to expire and wake us up - machine.sleep() - -SD card -------- - -See :ref:`machine.SD `. :: - - from machine import SD - import os - - # clock pin, cmd pin, data0 pin - sd = SD(pins=('GP10', 'GP11', 'GP15')) - # or use default ones for the expansion board - sd = SD() - os.mount(sd, '/sd') - -WLAN (WiFi) ------------ - -See :ref:`network.WLAN ` and :mod:`machine`. :: - - import machine - from network import WLAN - - # configure the WLAN subsystem in station mode (the default is AP) - wlan = WLAN(mode=WLAN.STA) - # go for fixed IP settings - wlan.ifconfig(config=('192.168.0.107', '255.255.255.0', '192.168.0.1', '8.8.8.8')) - wlan.scan() # scan for available networks - wlan.connect(ssid='mynetwork', auth=(WLAN.WPA2, 'mynetworkkey')) - while not wlan.isconnected(): - pass - print(wlan.ifconfig()) - # enable wake on WLAN - wlan.irq(trigger=WLAN.ANY_EVENT, wake=machine.SLEEP) - # go to sleep - machine.sleep() - # now, connect to the FTP or the Telnet server and the WiPy will wake-up - -Telnet and FTP server ---------------------- - -See :ref:`network.Server ` :: - - from network import Server - - # init with new user, password and seconds timeout - server = Server(login=('user', 'password'), timeout=60) - server.timeout(300) # change the timeout - server.timeout() # get the timeout - server.isrunning() # check whether the server is running or not - -Heart beat LED --------------- - -See :mod:`wipy`. :: - - import wipy - - wipy.heartbeat(False) # disable the heartbeat LED - wipy.heartbeat(True) # enable the heartbeat LED - wipy.heartbeat() # get the heartbeat state diff --git a/docs/wipy/tutorial/blynk.rst b/docs/wipy/tutorial/blynk.rst deleted file mode 100644 index b5a2f24a472..00000000000 --- a/docs/wipy/tutorial/blynk.rst +++ /dev/null @@ -1,19 +0,0 @@ -Getting started with Blynk and the WiPy ---------------------------------------- - -Blynk is a platform with iOS and Android apps to control -Arduino, Raspberry Pi and the likes over the Internet. -You can easily build graphic interfaces for all your -projects by simply dragging and dropping widgets. - -There are several examples available that work out-of-the-box with -the WiPy. Before anything else, make sure that your WiPy is running -the latest software, check :ref:`OTA How-To ` for instructions. - -1. Get the `Blynk library `_ and put it in ``/flash/lib/`` via FTP. -2. Get the `Blynk examples `_, edit the network settings, and afterwards - upload them to ``/flash/lib/`` via FTP as well. -3. Follow the instructions on each example to setup the Blynk dashboard on your smartphone or tablet. -4. Give it a try, for instance:: - - >>> execfile('01_simple.py') diff --git a/docs/wipy/tutorial/index.rst b/docs/wipy/tutorial/index.rst deleted file mode 100644 index 816de27b5aa..00000000000 --- a/docs/wipy/tutorial/index.rst +++ /dev/null @@ -1,18 +0,0 @@ -.. _wipy_tutorial_index: - -WiPy tutorials and examples -=========================== - -Before starting, make sure that you are running the latest firmware, -for instructions see :ref:`OTA How-To `. - -.. toctree:: - :maxdepth: 1 - :numbered: - - intro.rst - repl.rst - blynk.rst - wlan.rst - timer.rst - reset.rst diff --git a/docs/wipy/tutorial/intro.rst b/docs/wipy/tutorial/intro.rst deleted file mode 100644 index 3acc0510f13..00000000000 --- a/docs/wipy/tutorial/intro.rst +++ /dev/null @@ -1,64 +0,0 @@ -Introduction to the WiPy -======================== - -To get the most out of your WiPy, there are a few basic things to -understand about how it works. - -Caring for your WiPy and expansion board ----------------------------------------- - -Because the WiPy/expansion board does not have a housing it needs a bit of care: - - - Be gentle when plugging/unplugging the USB cable. Whilst the USB connector - is well soldered and is relatively strong, if it breaks off it can be very - difficult to fix. - - - Static electricity can shock the components on the WiPy and destroy them. - If you experience a lot of static electricity in your area (eg dry and cold - climates), take extra care not to shock the WiPy. If your WiPy came - in a ESD bag, then this bag is the best way to store and carry the - WiPy as it will protect it against static discharges. - -As long as you take care of the hardware, you should be okay. It's almost -impossible to break the software on the WiPy, so feel free to play around -with writing code as much as you like. If the filesystem gets corrupt, see -below on how to reset it. In the worst case you might need to do a safe boot, -which is explained in detail :ref:`here `. - -Plugging into the expansion board and powering on -------------------------------------------------- - -The expansion board can power the WiPy via USB. The WiPy comes with a sticker -on top of the RF shield that labels all pins, and this should match the label -numbers on the expansion board headers. When plugging it in, the WiPy antenna -will end up on top of the SD card connector of the expansion board. A video -showing how to do this can be found `here `_. - -Expansion board hardware guide ------------------------------- - -The document explaining the hardware details of the expansion board can be found -`here `_. - -Powering by an external power source ------------------------------------- - -The WiPy can be powered by a battery or other external power source. - -**Be sure to connect the positive lead of the power supply to VIN, and -ground to GND. There is no polarity protection on the WiPy so you -must be careful when connecting anything to VIN.** - -- When powering via ``VIN``: - - **The input voltage must be between 3.6V and 5.5V.** - -- When powering via ``3V3``: - - **The input voltage must be exactly 3V3, ripple free and from a supply capable - of sourcing at least 300mA of current** - -Performing firmware upgrades ----------------------------- - -For detailed instructions see :ref:`OTA How-To `. diff --git a/docs/wipy/tutorial/repl.rst b/docs/wipy/tutorial/repl.rst deleted file mode 100644 index e7b51f9c59a..00000000000 --- a/docs/wipy/tutorial/repl.rst +++ /dev/null @@ -1,130 +0,0 @@ -Getting a MicroPython REPL prompt -================================= - -REPL stands for Read Evaluate Print Loop, and is the name given to the -interactive MicroPython prompt that you can access on the WiPy. Using -the REPL is by far the easiest way to test out your code and run commands. -You can use the REPL in addition to writing scripts in ``main.py``. - -.. _wipy_uart: - -To use the REPL, you must connect to the WiPy either via :ref:`telnet `, -or with a USB to serial converter wired to one of the two UARTs on the -WiPy. To enable REPL duplication on UART0 (the one accessible via the expansion board) -do:: - - >>> from machine import UART - >>> import os - >>> uart = UART(0, 115200) - >>> os.dupterm(uart) - -Place this piece of code inside your `boot.py` so that it's done automatically after -reset. - -Windows -------- - -First you need to install the FTDI drivers for the expansion board's USB to serial -converter. Then you need a terminal software. The best option is to download the -free program PuTTY: `putty.exe `_. - -**In order to get to the telnet REPL:** - -Using putty, select ``Telnet`` as connection type, leave the default port (23) -and enter the IP address of your WiPy (192.168.1.1 when in ``WLAN.AP`` mode), -then click open. - -**In order to get to the REPL UART:** - -Using your serial program you must connect to the COM port that you found in the -previous step. With PuTTY, click on "Session" in the left-hand panel, then click -the "Serial" radio button on the right, then enter you COM port (eg COM4) in the -"Serial Line" box. Finally, click the "Open" button. - -Mac OS X --------- - -Open a terminal and run:: - - $ telnet 192.168.1.1 - -or:: - - $ screen /dev/tty.usbmodem* 115200 - -When you are finished and want to exit ``screen``, type CTRL-A CTRL-\\. If your keyboard does not have a \\-key (i.e. you need an obscure combination for \\ like ALT-SHIFT-7) you can remap the ``quit`` command: - -- create ``~/.screenrc`` -- add ``bind q quit`` - -This will allow you to quit ``screen`` by hitting CTRL-A Q. - -Linux ------ - -Open a terminal and run:: - - $ telnet 192.168.1.1 - -or:: - - $ screen /dev/ttyUSB0 115200 - -You can also try ``picocom`` or ``minicom`` instead of screen. You may have to -use ``/dev/ttyUSB01`` or a higher number for ``ttyUSB``. And, you may need to give -yourself the correct permissions to access this devices (eg group ``uucp`` or ``dialout``, -or use sudo). - -Using the REPL prompt ---------------------- - -Now let's try running some MicroPython code directly on the WiPy. - -With your serial program open (PuTTY, screen, picocom, etc) you may see a blank -screen with a flashing cursor. Press Enter and you should be presented with a -MicroPython prompt, i.e. ``>>>``. Let's make sure it is working with the obligatory test:: - - >>> print("hello WiPy!") - hello WiPy! - -In the above, you should not type in the ``>>>`` characters. They are there to -indicate that you should type the text after it at the prompt. In the end, once -you have entered the text ``print("hello WiPy!")`` and pressed Enter, the output -on your screen should look like it does above. - -If you already know some Python you can now try some basic commands here. - -If any of this is not working you can try either a hard reset or a soft reset; -see below. - -Go ahead and try typing in some other commands. For example:: - - >>> from machine import Pin - >>> import wipy - >>> wipy.heartbeat(False) # disable the heartbeat - >>> led = Pin('GP25', mode=Pin.OUT) - >>> led(1) - >>> led(0) - >>> led.toggle() - >>> 1 + 2 - 3 - >>> 4 // 2 - 2 - >>> 20 * 'py' - 'pypypypypypypypypypypypypypypypypypypypy' - -Resetting the board -------------------- - -If something goes wrong, you can reset the board in two ways. The first is to press CTRL-D -at the MicroPython prompt, which performs a soft reset. You will see a message something like:: - - >>> - PYB: soft reboot - MicroPython v1.4.6-146-g1d8b5e5 on 2015-10-21; WiPy with CC3200 - Type "help()" for more information. - >>> - -If that isn't working you can perform a hard reset (turn-it-off-and-on-again) by pressing the -RST switch (the small black button next to the heartbeat LED). During telnet, this will end -your session, disconnecting whatever program that you used to connect to the WiPy. diff --git a/docs/wipy/tutorial/reset.rst b/docs/wipy/tutorial/reset.rst deleted file mode 100644 index ece28498b8e..00000000000 --- a/docs/wipy/tutorial/reset.rst +++ /dev/null @@ -1,54 +0,0 @@ -Reset and boot modes -==================== - -There are soft resets and hard resets. - - - A soft reset simply clears the state of the MicroPython virtual machine, - but leaves hardware peripherals unaffected. To do a soft reset, simply press - **Ctrl+D** on the REPL, or within a script do:: - - import sys - sys.exit() - - - A hard reset is the same as performing a power cycle to the board. In order to - hard reset the WiPy, press the switch on the board or:: - - import machine - machine.reset() - -Safe boot ---------- - -If something goes wrong with your WiPy, don't panic! It is almost -impossible for you to break the WiPy by programming the wrong thing. - -The first thing to try is to boot in safe mode: this temporarily skips -execution of ``boot.py`` and ``main.py`` and gives default WLAN settings. - -If you have problems with the filesystem you can :ref:`format the internal flash -drive `. - -To boot in safe mode, follow the detailed instructions described :ref:`here `. - -In safe mode, the ``boot.py`` and ``main.py`` files are not executed, and so -the WiPy boots up with default settings. This means you now have access -to the filesystem, and you can edit ``boot.py`` and ``main.py`` to fix any problems. - -Entering safe mode is temporary, and does not make any changes to the -files on the WiPy. - -.. _wipy_factory_reset: - -Factory reset the filesystem ----------------------------- - -If you WiPy's filesystem gets corrupted (very unlikely, but possible), you -can format it very easily by doing:: - - >>> import os - >>> os.mkfs('/flash') - -Resetting the filesystem deletes all files on the internal WiPy storage -(not the SD card), and restores the files ``boot.py`` and ``main.py`` back -to their original state after the next reset. - diff --git a/docs/wipy/tutorial/timer.rst b/docs/wipy/tutorial/timer.rst deleted file mode 100644 index c87ac44959c..00000000000 --- a/docs/wipy/tutorial/timer.rst +++ /dev/null @@ -1,70 +0,0 @@ -Hardware timers -=============== - -Timers can be used for a great variety of tasks, calling a function periodically, -counting events, and generating a PWM signal are among the most common use cases. -Each timer consists of two 16-bit channels and this channels can be tied together to -form one 32-bit timer. The operating mode needs to be configured per timer, but then -the period (or the frequency) can be independently configured on each channel. -By using the callback method, the timer event can call a Python function. - -Example usage to toggle an LED at a fixed frequency:: - - from machine import Timer - from machine import Pin - led = Pin('GP16', mode=Pin.OUT) # enable GP16 as output to drive the LED - tim = Timer(3) # create a timer object using timer 3 - tim.init(mode=Timer.PERIODIC) # initialize it in periodic mode - tim_ch = tim.channel(Timer.A, freq=5) # configure channel A at a frequency of 5Hz - tim_ch.irq(handler=lambda t:led.toggle(), trigger=Timer.TIMEOUT) # toggle a LED on every cycle of the timer - -Example using named function for the callback:: - - from machine import Timer - from machine import Pin - tim = Timer(1, mode=Timer.PERIODIC, width=32) - tim_a = tim.channel(Timer.A | Timer.B, freq=1) # 1 Hz frequency requires a 32 bit timer - - led = Pin('GP16', mode=Pin.OUT) # enable GP16 as output to drive the LED - - def tick(timer): # we will receive the timer object when being called - global led - led.toggle() # toggle the LED - - tim_a.irq(handler=tick, trigger=Timer.TIMEOUT) # create the interrupt - -Further examples:: - - from machine import Timer - tim1 = Timer(1, mode=Timer.ONE_SHOT) # initialize it in one shot mode - tim2 = Timer(2, mode=Timer.PWM) # initialize it in PWM mode - tim1_ch = tim1.channel(Timer.A, freq=10, polarity=Timer.POSITIVE) # start the event counter with a frequency of 10Hz and triggered by positive edges - tim2_ch = tim2.channel(Timer.B, freq=10000, duty_cycle=5000) # start the PWM on channel B with a 50% duty cycle - tim2_ch.freq(20) # set the frequency (can also get) - tim2_ch.duty_cycle(3010) # set the duty cycle to 30.1% (can also get) - tim2_ch.duty_cycle(3020, Timer.NEGATIVE) # set the duty cycle to 30.2% and change the polarity to negative - tim2_ch.period(2000000) # change the period to 2 seconds - - -Additional constants for Timer class ------------------------------------- - -.. data:: Timer.PWM - - PWM timer operating mode. - -.. data:: Timer.A -.. data:: Timer.B - - Selects the timer channel. Must be ORed (``Timer.A`` | ``Timer.B``) when - using a 32-bit timer. - -.. data:: Timer.POSITIVE -.. data:: Timer.NEGATIVE - - Timer channel polarity selection (only relevant in PWM mode). - -.. data:: Timer.TIMEOUT -.. data:: Timer.MATCH - - Timer channel IRQ triggers. diff --git a/docs/wipy/tutorial/wlan.rst b/docs/wipy/tutorial/wlan.rst deleted file mode 100644 index 434367cd935..00000000000 --- a/docs/wipy/tutorial/wlan.rst +++ /dev/null @@ -1,71 +0,0 @@ -WLAN step by step -================= - -The WLAN is a system feature of the WiPy, therefore it is always enabled -(even while in ``machine.SLEEP``), except when deepsleep mode is entered. - -In order to retrieve the current WLAN instance, do:: - - >>> from network import WLAN - >>> wlan = WLAN() # we call the constructor without params - -You can check the current mode (which is always ``WLAN.AP`` after power up):: - - >>> wlan.mode() - -.. warning:: - When you change the WLAN mode following the instructions below, your WLAN - connection to the WiPy will be broken. This means you will not be able - to run these commands interactively over the WLAN. - - There are two ways around this:: - 1. put this setup code into your :ref:`boot.py file` so that it gets executed automatically after reset. - 2. :ref:`duplicate the REPL on UART `, so that you can run commands via USB. - -Connecting to your home router ------------------------------- - -The WLAN network card always boots in ``WLAN.AP`` mode, so we must first configure -it as a station:: - - from network import WLAN - wlan = WLAN(mode=WLAN.STA) - - -Now you can proceed to scan for networks:: - - nets = wlan.scan() - for net in nets: - if net.ssid == 'mywifi': - print('Network found!') - wlan.connect(net.ssid, auth=(net.sec, 'mywifikey'), timeout=5000) - while not wlan.isconnected(): - machine.idle() # save power while waiting - print('WLAN connection succeeded!') - break - -Assigning a static IP address when booting ------------------------------------------- - -If you want your WiPy to connect to your home router after boot-up, and with a fixed -IP address so that you can access it via telnet or FTP, use the following script as /flash/boot.py:: - - import machine - from network import WLAN - wlan = WLAN() # get current object, without changing the mode - - if machine.reset_cause() != machine.SOFT_RESET: - wlan.init(WLAN.STA) - # configuration below MUST match your home router settings!! - wlan.ifconfig(config=('192.168.178.107', '255.255.255.0', '192.168.178.1', '8.8.8.8')) - - if not wlan.isconnected(): - # change the line below to match your network ssid, security and password - wlan.connect('mywifi', auth=(WLAN.WPA2, 'mywifikey'), timeout=5000) - while not wlan.isconnected(): - machine.idle() # save power while waiting - -.. note:: - - Notice how we check for the reset cause and the connection status, this is crucial in order - to be able to soft reset the WiPy during a telnet session without breaking the connection. diff --git a/docs/wipy_index.rst b/docs/wipy_index.rst deleted file mode 100644 index 15c04c0fba8..00000000000 --- a/docs/wipy_index.rst +++ /dev/null @@ -1,12 +0,0 @@ -MicroPython documentation and references -======================================== - -.. toctree:: - - wipy/quickref.rst - wipy/general.rst - wipy/tutorial/index.rst - library/index.rst - reference/index.rst - genrst/index.rst - license.rst diff --git a/drivers/README.md b/drivers/README.md deleted file mode 100644 index 854acc50b62..00000000000 --- a/drivers/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This directory contains drivers for specific hardware. The drivers are -intended to work across multiple ports. diff --git a/drivers/cc3000/inc/cc3000_common.h b/drivers/cc3000/inc/cc3000_common.h deleted file mode 100644 index aa16242310d..00000000000 --- a/drivers/cc3000/inc/cc3000_common.h +++ /dev/null @@ -1,365 +0,0 @@ -/***************************************************************************** -* -* cc3000_common.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_COMMON_H__ -#define __CC3000_COMMON_H__ - -#include "data_types.h" - -//****************************************************************************** -// Include files -//****************************************************************************** -#include -#include - -//***************************************************************************** -// Prefix exported names to avoid name clash -//***************************************************************************** -#define CC3000_EXPORT(name) cc3000_ ## name - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - -extern int CC3000_EXPORT(errno); - -//***************************************************************************** -// ERROR CODES -//***************************************************************************** -#define ESUCCESS 0 -#define EFAIL -1 -#define EERROR EFAIL - -//***************************************************************************** -// COMMON DEFINES -//***************************************************************************** -#define ERROR_SOCKET_INACTIVE -57 - -#define WLAN_ENABLE (1) -#define WLAN_DISABLE (0) - -#define MAC_ADDR_LEN (6) - -#define SP_PORTION_SIZE (32) - -/*Defines for minimal and maximal RX buffer size. This size includes the spi - header and hci header. - The maximal buffer size derives from: - MTU + HCI header + SPI header + sendto() agrs size - The minimum buffer size derives from: - HCI header + SPI header + max args size - - This buffer is used for receiving events and data. - The packet can not be longer than MTU size and CC3000 does not support - fragmentation. Note that the same buffer is used for reception of the data - and events from CC3000. That is why the minimum is defined. - The calculation for the actual size of buffer for reception is: - Given the maximal data size MAX_DATA that is expected to be received by - application, the required buffer is: - Using recv() or recvfrom(): - - max(CC3000_MINIMAL_RX_SIZE, MAX_DATA + HEADERS_SIZE_DATA + fromlen - + ucArgsize + 1) - - Using gethostbyname() with minimal buffer size will limit the host name - returned to 99 bytes only. - The 1 is used for the overrun detection - - Buffer size increased to 130 following the add_profile() with WEP security - which requires TX buffer size of 130 bytes: - HEADERS_SIZE_EVNT + WLAN_ADD_PROFILE_WEP_PARAM_LEN + MAX SSID LEN + 4 * MAX KEY LEN = 130 - MAX SSID LEN = 32 - MAX SSID LEN = 13 (with add_profile only ascii key setting is supported, - therfore maximum key size is 13) -*/ - -#define CC3000_MINIMAL_RX_SIZE (130 + 1) -#define CC3000_MAXIMAL_RX_SIZE (1519 + 1) - -/*Defines for minimal and maximal TX buffer size. - This buffer is used for sending events and data. - The packet can not be longer than MTU size and CC3000 does not support - fragmentation. Note that the same buffer is used for transmission of the data - and commands. That is why the minimum is defined. - The calculation for the actual size of buffer for transmission is: - Given the maximal data size MAX_DATA, the required buffer is: - Using Sendto(): - - max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE - + SOCKET_SENDTO_PARAMS_LEN + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1) - - Using Send(): - - max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE - + HCI_CMND_SEND_ARG_LENGTH + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1) - - The 1 is used for the overrun detection */ - -#define CC3000_MINIMAL_TX_SIZE (130 + 1) -#define CC3000_MAXIMAL_TX_SIZE (1519 + 1) - -//TX and RX buffer sizes, allow to receive and transmit maximum data at length 8. -#ifdef CC3000_TINY_DRIVER -#define TINY_CC3000_MAXIMAL_RX_SIZE 44 -#define TINY_CC3000_MAXIMAL_TX_SIZE 59 -#endif - -/*In order to determine your preferred buffer size, - change CC3000_MAXIMAL_RX_SIZE and CC3000_MAXIMAL_TX_SIZE to a value between - the minimal and maximal specified above. - Note that the buffers are allocated by SPI. - In case you change the size of those buffers, you might need also to change - the linker file, since for example on MSP430 FRAM devices the buffers are - allocated in the FRAM section that is allocated manually and not by IDE. -*/ - -#ifndef CC3000_TINY_DRIVER - - #define CC3000_RX_BUFFER_SIZE (CC3000_MAXIMAL_RX_SIZE) - #define CC3000_TX_BUFFER_SIZE (CC3000_MAXIMAL_TX_SIZE) - -//if defined TINY DRIVER we use smaller RX and TX buffer in order to minimize RAM consumption -#else - #define CC3000_RX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_RX_SIZE) - #define CC3000_TX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_TX_SIZE) - -#endif - -//***************************************************************************** -// Compound Types -//***************************************************************************** -typedef INT32 time_t; -typedef UINT32 clock_t; -typedef INT32 suseconds_t; - -typedef struct cc3000_timeval cc3000_timeval; - -struct cc3000_timeval -{ - time_t tv_sec; /* seconds */ - suseconds_t tv_usec; /* microseconds */ -}; - -typedef CHAR *(*tFWPatches)(UINT32 *usLength); - -typedef CHAR *(*tDriverPatches)(UINT32 *usLength); - -typedef CHAR *(*tBootLoaderPatches)(UINT32 *usLength); - -typedef void (*tWlanCB)(INT32 event_type, CHAR * data, UINT8 length ); - -typedef INT32 (*tWlanReadInteruptPin)(void); - -typedef void (*tWlanInterruptEnable)(void); - -typedef void (*tWlanInterruptDisable)(void); - -typedef void (*tWriteWlanPin)(UINT8 val); - -typedef struct -{ - UINT16 usRxEventOpcode; - UINT16 usEventOrDataReceived; - UINT8 *pucReceivedData; - UINT8 *pucTxCommandBuffer; - - tFWPatches sFWPatches; - tDriverPatches sDriverPatches; - tBootLoaderPatches sBootLoaderPatches; - tWlanCB sWlanCB; - tWlanReadInteruptPin ReadWlanInterruptPin; - tWlanInterruptEnable WlanInterruptEnable; - tWlanInterruptDisable WlanInterruptDisable; - tWriteWlanPin WriteWlanPin; - - INT32 slTransmitDataError; - UINT16 usNumberOfFreeBuffers; - UINT16 usSlBufferLength; - UINT16 usBufferSize; - UINT16 usRxDataPending; - - UINT32 NumberOfSentPackets; - UINT32 NumberOfReleasedPackets; - - UINT8 InformHostOnTxComplete; -}sSimplLinkInformation; - -extern volatile sSimplLinkInformation tSLInformation; - - -//***************************************************************************** -// Prototypes for the APIs. -//***************************************************************************** - - - -//***************************************************************************** -// -//! SimpleLinkWaitEvent -//! -//! @param usOpcode command operation code -//! @param pRetParams command return parameters -//! -//! @return none -//! -//! @brief Wait for event, pass it to the hci_event_handler and -//! update the event opcode in a global variable. -// -//***************************************************************************** - -extern void SimpleLinkWaitEvent(UINT16 usOpcode, void *pRetParams); - -//***************************************************************************** -// -//! SimpleLinkWaitData -//! -//! @param pBuf data buffer -//! @param from from information -//! @param fromlen from information length -//! -//! @return none -//! -//! @brief Wait for data, pass it to the hci_event_handler -//! and update in a global variable that there is -//! data to read. -// -//***************************************************************************** - -extern void SimpleLinkWaitData(UINT8 *pBuf, UINT8 *from, UINT8 *fromlen); - -//***************************************************************************** -// -//! UINT32_TO_STREAM_f -//! -//! \param p pointer to the new stream -//! \param u32 pointer to the 32 bit -//! -//! \return pointer to the new stream -//! -//! \brief This function is used for copying 32 bit to stream -//! while converting to little endian format. -// -//***************************************************************************** - -extern UINT8* UINT32_TO_STREAM_f (UINT8 *p, UINT32 u32); - -//***************************************************************************** -// -//! UINT16_TO_STREAM_f -//! -//! \param p pointer to the new stream -//! \param u32 pointer to the 16 bit -//! -//! \return pointer to the new stream -//! -//! \brief This function is used for copying 16 bit to stream -//! while converting to little endian format. -// -//***************************************************************************** - -extern UINT8* UINT16_TO_STREAM_f (UINT8 *p, UINT16 u16); - -//***************************************************************************** -// -//! STREAM_TO_UINT16_f -//! -//! \param p pointer to the stream -//! \param offset offset in the stream -//! -//! \return pointer to the new 16 bit -//! -//! \brief This function is used for copying received stream to -//! 16 bit in little endian format. -// -//***************************************************************************** - -extern UINT16 STREAM_TO_UINT16_f(CHAR* p, UINT16 offset); - -//***************************************************************************** -// -//! STREAM_TO_UINT32_f -//! -//! \param p pointer to the stream -//! \param offset offset in the stream -//! -//! \return pointer to the new 32 bit -//! -//! \brief This function is used for copying received stream to -//! 32 bit in little endian format. -// -//***************************************************************************** - -extern UINT32 STREAM_TO_UINT32_f(CHAR* p, UINT16 offset); - - -//***************************************************************************** -// COMMON MACROs -//***************************************************************************** - - -//This macro is used for copying 8 bit to stream while converting to little endian format. -#define UINT8_TO_STREAM(_p, _val) {*(_p)++ = (_val);} -//This macro is used for copying 16 bit to stream while converting to little endian format. -#define UINT16_TO_STREAM(_p, _u16) (UINT16_TO_STREAM_f(_p, _u16)) -//This macro is used for copying 32 bit to stream while converting to little endian format. -#define UINT32_TO_STREAM(_p, _u32) (UINT32_TO_STREAM_f(_p, _u32)) -//This macro is used for copying a specified value length bits (l) to stream while converting to little endian format. -#define ARRAY_TO_STREAM(p, a, l) {register INT16 _i; for (_i = 0; _i < l; _i++) *(p)++ = ((UINT8 *) a)[_i];} -//This macro is used for copying received stream to 8 bit in little endian format. -#define STREAM_TO_UINT8(_p, _offset, _u8) {_u8 = (UINT8)(*(_p + _offset));} -//This macro is used for copying received stream to 16 bit in little endian format. -#define STREAM_TO_UINT16(_p, _offset, _u16) {_u16 = STREAM_TO_UINT16_f(_p, _offset);} -//This macro is used for copying received stream to 32 bit in little endian format. -#define STREAM_TO_UINT32(_p, _offset, _u32) {_u32 = STREAM_TO_UINT32_f(_p, _offset);} -#define STREAM_TO_STREAM(p, a, l) {register INT16 _i; for (_i = 0; _i < l; _i++) *(a)++= ((UINT8 *) p)[_i];} - - - - -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __CC3000_COMMON_H__ diff --git a/drivers/cc3000/inc/ccspi.h b/drivers/cc3000/inc/ccspi.h deleted file mode 100644 index 8fa3ecd10c2..00000000000 --- a/drivers/cc3000/inc/ccspi.h +++ /dev/null @@ -1,84 +0,0 @@ -/***************************************************************************** -* -* spi.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - - -#ifndef __CC3000_SPI_H__ -#define __CC3000_SPI_H__ - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*gcSpiHandleRx)(void *p); -typedef void (*gcSpiHandleTx)(void); -extern unsigned char wlan_tx_buffer[]; - -//***************************************************************************** -// -// Prototypes for the APIs. -// -//***************************************************************************** - -// the arguments must be of type pin_obj_t* and SPI_HandleTypeDef* -extern void SpiInit(void *spi, const void *pin_cs, const void *pin_en, const void *pin_irq); - -extern void SpiOpen(gcSpiHandleRx pfRxHandler); -extern void SpiClose(void); -extern void SpiPauseSpi(void); -extern void SpiResumeSpi(void); -extern long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength); -extern void SpiConfigureHwMapping(void); -extern void SpiCleanGPIOISR(void); -extern void SSIConfigure(unsigned long ulSSIFreq, unsigned long bForceGpioConfiguration, unsigned long uiReconfigureSysClock); -extern int init_spi(void); -extern long ReadWlanInterruptPin(void); -extern void WriteWlanPin(unsigned char val); -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif - diff --git a/drivers/cc3000/inc/data_types.h b/drivers/cc3000/inc/data_types.h deleted file mode 100644 index 0520a9202fb..00000000000 --- a/drivers/cc3000/inc/data_types.h +++ /dev/null @@ -1,107 +0,0 @@ -/***************************************************************************** -* -* data_types.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_DATA_TYPES__ -#define __CC3000_DATA_TYPES__ - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - - -#ifndef NULL -#define NULL (0) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -#ifndef OK -#define OK (0) -#endif - -#ifndef _INT8 -#define _INT8 -typedef signed char INT8; -#endif - -#ifndef _UINT8 -#define _UINT8 -typedef unsigned char UINT8; -#endif - -#ifndef _INT16 -#define _INT16 -typedef signed short INT16; -#endif - -#ifndef _UINT16 -#define _UINT16 -typedef unsigned short UINT16; -#endif - -#ifndef _BOOLEAN -#define _BOOLEAN -typedef unsigned char BOOLEAN; -#endif - -#ifndef _INT32 -#define _INT32 -typedef signed long INT32; -#endif - -#ifndef _UINT32 -#define _UINT32 -typedef unsigned long UINT32; -#endif - -typedef int INT; -typedef char CHAR; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __CC3000_DATA_TYPES__ */ diff --git a/drivers/cc3000/inc/evnt_handler.h b/drivers/cc3000/inc/evnt_handler.h deleted file mode 100644 index d05a442f05f..00000000000 --- a/drivers/cc3000/inc/evnt_handler.h +++ /dev/null @@ -1,166 +0,0 @@ -/***************************************************************************** -* -* evnt_handler.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_EVENT_HANDLER_H__ -#define __CC3000_EVENT_HANDLER_H__ -#include "hci.h" -#include "socket.h" - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - -//***************************************************************************** -// -// Prototypes for the APIs. -// -//***************************************************************************** - -//***************************************************************************** -// -//! hci_event_handler -//! -//! @param pRetParams incoming data buffer -//! @param from from information (in case of data received) -//! @param fromlen from information length (in case of data received) -//! -//! @return none -//! -//! @brief Parse the incoming events packets and issues corresponding -//! event handler from global array of handlers pointers -// -//***************************************************************************** -extern UINT8 *hci_event_handler(void *pRetParams, UINT8 *from, UINT8 *fromlen); - -//***************************************************************************** -// -//! hci_unsol_event_handler -//! -//! @param event_hdr event header -//! -//! @return 1 if event supported and handled -//! 0 if event is not supported -//! -//! @brief Handle unsolicited events -// -//***************************************************************************** -extern INT32 hci_unsol_event_handler(CHAR *event_hdr); - -//***************************************************************************** -// -//! hci_unsolicited_event_handler -//! -//! @param None -//! -//! @return ESUCCESS if successful, EFAIL if an error occurred -//! -//! @brief Parse the incoming unsolicited event packets and issues -//! corresponding event handler. -// -//***************************************************************************** -extern INT32 hci_unsolicited_event_handler(void); - -#define M_BSD_RESP_PARAMS_OFFSET(hci_event_hdr)((CHAR *)(hci_event_hdr) + HCI_EVENT_HEADER_SIZE) - -#define SOCKET_STATUS_ACTIVE 0 -#define SOCKET_STATUS_INACTIVE 1 -/* Init socket_active_status = 'all ones': init all sockets with SOCKET_STATUS_INACTIVE. - Will be changed by 'set_socket_active_status' upon 'connect' and 'accept' calls */ -#define SOCKET_STATUS_INIT_VAL 0xFFFF -#define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7)) -#define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE)) - -extern UINT32 socket_active_status; - -extern void set_socket_active_status(INT32 Sd, INT32 Status); -extern INT32 get_socket_active_status(INT32 Sd); - -typedef struct _bsd_accept_return_t -{ - INT32 iSocketDescriptor; - INT32 iStatus; - sockaddr tSocketAddress; - -} tBsdReturnParams; - - -typedef struct _bsd_read_return_t -{ - INT32 iSocketDescriptor; - INT32 iNumberOfBytes; - UINT32 uiFlags; -} tBsdReadReturnParams; - -#define BSD_RECV_FROM_FROMLEN_OFFSET (4) -#define BSD_RECV_FROM_FROM_OFFSET (16) - - -typedef struct _bsd_select_return_t -{ - INT32 iStatus; - UINT32 uiRdfd; - UINT32 uiWrfd; - UINT32 uiExfd; -} tBsdSelectRecvParams; - - -typedef struct _bsd_getsockopt_return_t -{ - UINT8 ucOptValue[4]; - CHAR iStatus; -} tBsdGetSockOptReturnParams; - -typedef struct _bsd_gethostbyname_return_t -{ - INT32 retVal; - INT32 outputAddress; -} tBsdGethostbynameParams; - -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __CC3000_EVENT_HANDLER_H__ - diff --git a/drivers/cc3000/inc/hci.h b/drivers/cc3000/inc/hci.h deleted file mode 100644 index f12b00e918e..00000000000 --- a/drivers/cc3000/inc/hci.h +++ /dev/null @@ -1,330 +0,0 @@ -/***************************************************************************** -* -* hci.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_HCI_H__ -#define __CC3000_HCI_H__ - -#include "cc3000_common.h" - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - - -#define SPI_HEADER_SIZE (5) -#define SIMPLE_LINK_HCI_CMND_HEADER_SIZE (4) -#define HEADERS_SIZE_CMD (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE) -#define SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE (5) -#define SIMPLE_LINK_HCI_DATA_HEADER_SIZE (5) -#define SIMPLE_LINK_HCI_PATCH_HEADER_SIZE (2) - - -//***************************************************************************** -// -// Values that can be used as HCI Commands and HCI Packet header defines -// -//***************************************************************************** -#define HCI_TYPE_CMND 0x1 -#define HCI_TYPE_DATA 0x2 -#define HCI_TYPE_PATCH 0x3 -#define HCI_TYPE_EVNT 0x4 - - -#define HCI_EVENT_PATCHES_DRV_REQ (1) -#define HCI_EVENT_PATCHES_FW_REQ (2) -#define HCI_EVENT_PATCHES_BOOTLOAD_REQ (3) - - -#define HCI_CMND_WLAN_BASE (0x0000) -#define HCI_CMND_WLAN_CONNECT 0x0001 -#define HCI_CMND_WLAN_DISCONNECT 0x0002 -#define HCI_CMND_WLAN_IOCTL_SET_SCANPARAM 0x0003 -#define HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY 0x0004 -#define HCI_CMND_WLAN_IOCTL_ADD_PROFILE 0x0005 -#define HCI_CMND_WLAN_IOCTL_DEL_PROFILE 0x0006 -#define HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS 0x0007 -#define HCI_CMND_EVENT_MASK 0x0008 -#define HCI_CMND_WLAN_IOCTL_STATUSGET 0x0009 -#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START 0x000A -#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP 0x000B -#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX 0x000C -#define HCI_CMND_WLAN_CONFIGURE_PATCH 0x000D - - -#define HCI_CMND_SOCKET_BASE 0x1000 -#define HCI_CMND_SOCKET 0x1001 -#define HCI_CMND_BIND 0x1002 -#define HCI_CMND_RECV 0x1004 -#define HCI_CMND_ACCEPT 0x1005 -#define HCI_CMND_LISTEN 0x1006 -#define HCI_CMND_CONNECT 0x1007 -#define HCI_CMND_BSD_SELECT 0x1008 -#define HCI_CMND_SETSOCKOPT 0x1009 -#define HCI_CMND_GETSOCKOPT 0x100A -#define HCI_CMND_CLOSE_SOCKET 0x100B -#define HCI_CMND_RECVFROM 0x100D -#define HCI_CMND_GETHOSTNAME 0x1010 -#define HCI_CMND_MDNS_ADVERTISE 0x1011 -#define HCI_CMND_GETMSSVALUE 0x1012 - - -#define HCI_DATA_BASE 0x80 - -#define HCI_CMND_SEND (0x01 + HCI_DATA_BASE) -#define HCI_CMND_SENDTO (0x03 + HCI_DATA_BASE) -#define HCI_DATA_BSD_RECVFROM (0x04 + HCI_DATA_BASE) -#define HCI_DATA_BSD_RECV (0x05 + HCI_DATA_BASE) - - -#define HCI_CMND_NVMEM_CBASE (0x0200) - - -#define HCI_CMND_NVMEM_CREATE_ENTRY (0x0203) -#define HCI_CMND_NVMEM_SWAP_ENTRY (0x0205) -#define HCI_CMND_NVMEM_READ (0x0201) -#define HCI_CMND_NVMEM_WRITE (0x0090) -#define HCI_CMND_NVMEM_WRITE_PATCH (0x0204) -#define HCI_CMND_READ_SP_VERSION (0x0207) - -#define HCI_CMND_READ_BUFFER_SIZE 0x400B -#define HCI_CMND_SIMPLE_LINK_START 0x4000 - -#define HCI_CMND_NETAPP_BASE 0x2000 - -#define HCI_NETAPP_DHCP (0x0001 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_PING_SEND (0x0002 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_PING_REPORT (0x0003 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_PING_STOP (0x0004 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_IPCONFIG (0x0005 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_ARP_FLUSH (0x0006 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_SET_DEBUG_LEVEL (0x0008 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_SET_TIMERS (0x0009 + HCI_CMND_NETAPP_BASE) - - - - - - -//***************************************************************************** -// -// Values that can be used as HCI Events defines -// -//***************************************************************************** -#define HCI_EVNT_WLAN_BASE 0x0000 -#define HCI_EVNT_WLAN_CONNECT 0x0001 -#define HCI_EVNT_WLAN_DISCONNECT \ - 0x0002 -#define HCI_EVNT_WLAN_IOCTL_ADD_PROFILE \ - 0x0005 - - -#define HCI_EVNT_SOCKET HCI_CMND_SOCKET -#define HCI_EVNT_BIND HCI_CMND_BIND -#define HCI_EVNT_RECV HCI_CMND_RECV -#define HCI_EVNT_ACCEPT HCI_CMND_ACCEPT -#define HCI_EVNT_LISTEN HCI_CMND_LISTEN -#define HCI_EVNT_CONNECT HCI_CMND_CONNECT -#define HCI_EVNT_SELECT HCI_CMND_BSD_SELECT -#define HCI_EVNT_CLOSE_SOCKET HCI_CMND_CLOSE_SOCKET -#define HCI_EVNT_RECVFROM HCI_CMND_RECVFROM -#define HCI_EVNT_SETSOCKOPT HCI_CMND_SETSOCKOPT -#define HCI_EVNT_GETSOCKOPT HCI_CMND_GETSOCKOPT -#define HCI_EVNT_BSD_GETHOSTBYNAME HCI_CMND_GETHOSTNAME -#define HCI_EVNT_MDNS_ADVERTISE HCI_CMND_MDNS_ADVERTISE -#define HCI_EVNT_GETMSSVALUE HCI_CMND_GETMSSVALUE - -#define HCI_EVNT_SEND 0x1003 -#define HCI_EVNT_WRITE 0x100E -#define HCI_EVNT_SENDTO 0x100F - -#define HCI_EVNT_PATCHES_REQ 0x1000 - -#define HCI_EVNT_UNSOL_BASE 0x4000 - -#define HCI_EVNT_WLAN_UNSOL_BASE (0x8000) - -#define HCI_EVNT_WLAN_UNSOL_CONNECT (0x0001 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_UNSOL_DISCONNECT (0x0002 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_UNSOL_INIT (0x0004 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_TX_COMPLETE (0x0008 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_UNSOL_DHCP (0x0010 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_ASYNC_PING_REPORT (0x0040 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE (0x0080 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_KEEPALIVE (0x0200 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_BSD_TCP_CLOSE_WAIT (0x0800 + HCI_EVNT_WLAN_UNSOL_BASE) - -#define HCI_EVNT_DATA_UNSOL_FREE_BUFF \ - 0x4100 - -#define HCI_EVNT_NVMEM_CREATE_ENTRY \ - HCI_CMND_NVMEM_CREATE_ENTRY -#define HCI_EVNT_NVMEM_SWAP_ENTRY HCI_CMND_NVMEM_SWAP_ENTRY - -#define HCI_EVNT_NVMEM_READ HCI_CMND_NVMEM_READ -#define HCI_EVNT_NVMEM_WRITE (0x0202) - -#define HCI_EVNT_READ_SP_VERSION \ - HCI_CMND_READ_SP_VERSION - -#define HCI_EVNT_INPROGRESS 0xFFFF - - -#define HCI_DATA_RECVFROM 0x84 -#define HCI_DATA_RECV 0x85 -#define HCI_DATA_NVMEM 0x91 - -#define HCI_EVENT_CC3000_CAN_SHUT_DOWN 0x99 - -//***************************************************************************** -// -// Prototypes for the structures for APIs. -// -//***************************************************************************** - -#define HCI_DATA_HEADER_SIZE (5) -#define HCI_EVENT_HEADER_SIZE (5) -#define HCI_DATA_CMD_HEADER_SIZE (5) -#define HCI_PATCH_HEADER_SIZE (6) - -#define HCI_PACKET_TYPE_OFFSET (0) -#define HCI_PACKET_ARGSIZE_OFFSET (2) -#define HCI_PACKET_LENGTH_OFFSET (3) - - -#define HCI_EVENT_OPCODE_OFFSET (1) -#define HCI_EVENT_LENGTH_OFFSET (3) -#define HCI_EVENT_STATUS_OFFSET (4) -#define HCI_DATA_LENGTH_OFFSET (3) - - - - -//***************************************************************************** -// -// Prototypes for the APIs. -// -//***************************************************************************** - -//***************************************************************************** -// -//! hci_command_send -//! -//! @param usOpcode command operation code -//! @param pucBuff pointer to the command's arguments buffer -//! @param ucArgsLength length of the arguments -//! -//! @return none -//! -//! @brief Initiate an HCI command. -// -//***************************************************************************** -extern UINT16 hci_command_send(UINT16 usOpcode, - UINT8 *ucArgs, - UINT8 ucArgsLength); - - -//***************************************************************************** -// -//! hci_data_send -//! -//! @param usOpcode command operation code -//! @param ucArgs pointer to the command's arguments buffer -//! @param usArgsLength length of the arguments -//! @param ucTail pointer to the data buffer -//! @param usTailLength buffer length -//! -//! @return none -//! -//! @brief Initiate an HCI data write operation -// -//***************************************************************************** -extern INT32 hci_data_send(UINT8 ucOpcode, - UINT8 *ucArgs, - UINT16 usArgsLength, - UINT16 usDataLength, - const UINT8 *ucTail, - UINT16 usTailLength); - - -//***************************************************************************** -// -//! hci_data_command_send -//! -//! @param usOpcode command operation code -//! @param pucBuff pointer to the data buffer -//! @param ucArgsLength arguments length -//! @param ucDataLength data length -//! -//! @return none -//! -//! @brief Prepare HCI header and initiate an HCI data write operation -// -//***************************************************************************** -extern void hci_data_command_send(UINT16 usOpcode, UINT8 *pucBuff, - UINT8 ucArgsLength, UINT16 ucDataLength); - -//***************************************************************************** -// -//! hci_patch_send -//! -//! @param usOpcode command operation code -//! @param pucBuff pointer to the command's arguments buffer -//! @param patch pointer to patch content buffer -//! @param usDataLength data length -//! -//! @return none -//! -//! @brief Prepare HCI header and initiate an HCI patch write operation -// -//***************************************************************************** -extern void hci_patch_send(UINT8 ucOpcode, UINT8 *pucBuff, CHAR *patch, UINT16 usDataLength); - - - -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __CC3000_HCI_H__ diff --git a/drivers/cc3000/inc/host_driver_version.h b/drivers/cc3000/inc/host_driver_version.h deleted file mode 100644 index a28d21f1bea..00000000000 --- a/drivers/cc3000/inc/host_driver_version.h +++ /dev/null @@ -1,40 +0,0 @@ -/***************************************************************************** -* -* host_driver_version.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_HOST_DRIVER_VERSION_H__ -#define __CC3000_HOST_DRIVER_VERSION_H__ - -#define DRIVER_VERSION_NUMBER 15 - -#endif // __CC3000_HOST_DRIVER_VERSION_H__ diff --git a/drivers/cc3000/inc/inet_ntop.h b/drivers/cc3000/inc/inet_ntop.h deleted file mode 100644 index fa70806206a..00000000000 --- a/drivers/cc3000/inc/inet_ntop.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef __INET_NTOP_H -#define __INET_NTOP_H -char *inet_ntop(int af, const void *addr, char *buf, size_t size); -#endif /* __INET_NTOP_H */ diff --git a/drivers/cc3000/inc/inet_pton.h b/drivers/cc3000/inc/inet_pton.h deleted file mode 100644 index 0896d5d29fd..00000000000 --- a/drivers/cc3000/inc/inet_pton.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef __INET_PTON_H -#define __INET_PTON_H -int inet_pton(int, const char *, void *); -#endif /* __INET_PTON_H */ diff --git a/drivers/cc3000/inc/netapp.h b/drivers/cc3000/inc/netapp.h deleted file mode 100644 index 1e4f2658965..00000000000 --- a/drivers/cc3000/inc/netapp.h +++ /dev/null @@ -1,343 +0,0 @@ -/***************************************************************************** -* -* netapp.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_NETAPP_H__ -#define __CC3000_NETAPP_H__ - -#include "data_types.h" - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - -//***************************************************************************** -// -//! \addtogroup netapp_api -//! @{ -// -//***************************************************************************** - -typedef struct _netapp_dhcp_ret_args_t -{ - UINT8 aucIP[4]; - UINT8 aucSubnetMask[4]; - UINT8 aucDefaultGateway[4]; - UINT8 aucDHCPServer[4]; - UINT8 aucDNSServer[4]; -}tNetappDhcpParams; - -typedef struct _netapp_ipconfig_ret_args_t -{ - UINT8 aucIP[4]; - UINT8 aucSubnetMask[4]; - UINT8 aucDefaultGateway[4]; - UINT8 aucDHCPServer[4]; - UINT8 aucDNSServer[4]; - UINT8 uaMacAddr[6]; - UINT8 uaSSID[32]; -}tNetappIpconfigRetArgs; - - -/*Ping send report parameters*/ -typedef struct _netapp_pingreport_args -{ - UINT32 packets_sent; - UINT32 packets_received; - UINT32 min_round_time; - UINT32 max_round_time; - UINT32 avg_round_time; -} netapp_pingreport_args_t; - - -//***************************************************************************** -// -//! netapp_config_mac_adrress -//! -//! @param mac device mac address, 6 bytes. Saved: yes -//! -//! @return return on success 0, otherwise error. -//! -//! @brief Configure device MAC address and store it in NVMEM. -//! The value of the MAC address configured through the API will -//! be stored in CC3000 non volatile memory, thus preserved -//! over resets. -// -//***************************************************************************** -extern INT32 netapp_config_mac_adrress( UINT8 *mac ); - -//***************************************************************************** -// -//! netapp_dhcp -//! -//! @param aucIP device mac address, 6 bytes. Saved: yes -//! @param aucSubnetMask device mac address, 6 bytes. Saved: yes -//! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes -//! @param aucDNSServer device mac address, 6 bytes. Saved: yes -//! -//! @return return on success 0, otherwise error. -//! -//! @brief netapp_dhcp is used to configure the network interface, -//! static or dynamic (DHCP).\n In order to activate DHCP mode, -//! aucIP, aucSubnetMask, aucDefaultGateway must be 0. -//! The default mode of CC3000 is DHCP mode. -//! Note that the configuration is saved in non volatile memory -//! and thus preserved over resets. -//! -//! @note If the mode is altered a reset of CC3000 device is required -//! in order to apply changes.\nAlso note that asynchronous event -//! of DHCP_EVENT, which is generated when an IP address is -//! allocated either by the DHCP server or due to static -//! allocation is generated only upon a connection to the -//! AP was established. -//! -//***************************************************************************** -extern INT32 netapp_dhcp(UINT32 *aucIP, UINT32 *aucSubnetMask,UINT32 *aucDefaultGateway, UINT32 *aucDNSServer); - - - -//***************************************************************************** -// -//! netapp_timeout_values -//! -//! @param aucDHCP DHCP lease time request, also impact -//! the DHCP renew timeout. Range: [0-0xffffffff] seconds, -//! 0 or 0xffffffff == infinity lease timeout. -//! Resolution:10 seconds. Influence: only after -//! reconnecting to the AP. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 seconds. -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 14400 seconds. -//! -//! @param aucARP ARP refresh timeout, if ARP entry is not updated by -//! incoming packet, the ARP entry will be deleted by -//! the end of the timeout. -//! Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout -//! Resolution: 10 seconds. Influence: on runtime. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 seconds -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 3600 seconds. -//! -//! @param aucKeepalive Keepalive event sent by the end of keepalive timeout -//! Range: [0-0xffffffff] seconds, 0 == infinity timeout -//! Resolution: 10 seconds. -//! Influence: on runtime. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 sec -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 10 seconds. -//! -//! @param aucInactivity Socket inactivity timeout, socket timeout is -//! refreshed by incoming or outgoing packet, by the -//! end of the socket timeout the socket will be closed -//! Range: [0-0xffffffff] sec, 0 == infinity timeout. -//! Resolution: 10 seconds. Influence: on runtime. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 sec -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 60 seconds. -//! -//! @return return on success 0, otherwise error. -//! -//! @brief Set new timeout values. Function set new timeout values for: -//! DHCP lease timeout, ARP refresh timeout, keepalive event -//! timeout and socket inactivity timeout -//! -//! @note If a parameter set to non zero value which is less than 10s, -//! it will be set automatically to 10s. -//! -//***************************************************************************** -#ifndef CC3000_TINY_DRIVER -extern INT32 netapp_timeout_values(UINT32 *aucDHCP, UINT32 *aucARP, UINT32 *aucKeepalive, UINT32 *aucInactivity); -#endif - -//***************************************************************************** -// -//! netapp_ping_send -//! -//! @param ip destination IP address -//! @param pingAttempts number of echo requests to send -//! @param pingSize send buffer size which may be up to 1400 bytes -//! @param pingTimeout Time to wait for a response,in milliseconds. -//! -//! @return return on success 0, otherwise error. -//! -//! @brief send ICMP ECHO_REQUEST to network hosts -//! -//! @note If an operation finished successfully asynchronous ping report -//! event will be generated. The report structure is as defined -//! by structure netapp_pingreport_args_t. -//! -//! @warning Calling this function while a previous Ping Requests are in -//! progress will stop the previous ping request. -//***************************************************************************** - - #ifndef CC3000_TINY_DRIVER -extern INT32 netapp_ping_send(UINT32 *ip, UINT32 ulPingAttempts, UINT32 ulPingSize, UINT32 ulPingTimeout); -#endif - -//***************************************************************************** -// -//! netapp_ping_stop -//! -//! @param none -//! -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief Stop any ping request. -//! -//! -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -extern INT32 netapp_ping_stop(); -#endif -//***************************************************************************** -// -//! netapp_ping_report -//! -//! @param none -//! -//! @return none -//! -//! @brief Request for ping status. This API triggers the CC3000 to send -//! asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT. -//! This event will carry the report structure: -//! netapp_pingreport_args_t. This structure is filled in with ping -//! results up till point of triggering API. -//! netapp_pingreport_args_t:\n packets_sent - echo sent, -//! packets_received - echo reply, min_round_time - minimum -//! round time, max_round_time - max round time, -//! avg_round_time - average round time -//! -//! @note When a ping operation is not active, the returned structure -//! fields are 0. -//! -//***************************************************************************** -#ifndef CC3000_TINY_DRIVER -extern void netapp_ping_report(); -#endif - - -//***************************************************************************** -// -//! netapp_ipconfig -//! -//! @param[out] ipconfig This argument is a pointer to a -//! tNetappIpconfigRetArgs structure. This structure is -//! filled in with the network interface configuration. -//! tNetappIpconfigRetArgs:\n aucIP - ip address, -//! aucSubnetMask - mask, aucDefaultGateway - default -//! gateway address, aucDHCPServer - dhcp server address -//! aucDNSServer - dns server address, uaMacAddr - mac -//! address, uaSSID - connected AP ssid -//! -//! @return none -//! -//! @brief Obtain the CC3000 Network interface information. -//! Note that the information is available only after the WLAN -//! connection was established. Calling this function before -//! associated, will cause non-defined values to be returned. -//! -//! @note The function is useful for figuring out the IP Configuration of -//! the device when DHCP is used and for figuring out the SSID of -//! the Wireless network the device is associated with. -//! -//***************************************************************************** - -extern void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig ); - - -//***************************************************************************** -// -//! netapp_arp_flush -//! -//! @param none -//! -//! @return none -//! -//! @brief Flushes ARP table -//! -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -extern INT32 netapp_arp_flush(); -#endif - - -//***************************************************************************** -// -//! netapp_set_debug_level -//! -//! @param[in] level debug level. Bitwise [0-8], -//! 0(disable)or 1(enable).\n Bitwise map: 0 - Critical -//! message, 1 information message, 2 - core messages, 3 - -//! HCI messages, 4 - Network stack messages, 5 - wlan -//! messages, 6 - wlan driver messages, 7 - epprom messages, -//! 8 - general messages. Default: 0x13f. Saved: no -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Debug messages sent via the UART debug channel, this function -//! enable/disable the debug level -//! -//***************************************************************************** - - -#ifndef CC3000_TINY_DRIVER -INT32 netapp_set_debug_level(UINT32 ulLevel); -#endif -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** - - - -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __CC3000_NETAPP_H__ - diff --git a/drivers/cc3000/inc/nvmem.h b/drivers/cc3000/inc/nvmem.h deleted file mode 100644 index b99a2e7b9ec..00000000000 --- a/drivers/cc3000/inc/nvmem.h +++ /dev/null @@ -1,248 +0,0 @@ -/***************************************************************************** -* -* nvmem.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_NVRAM_H__ -#define __CC3000_NVRAM_H__ - -#include "cc3000_common.h" - - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - - -//***************************************************************************** -// -//! \addtogroup nvmem_api -//! @{ -// -//***************************************************************************** - -/**************************************************************************** -** -** Definitions for File IDs -** -****************************************************************************/ -/* NVMEM file ID - system files*/ -#define NVMEM_NVS_FILEID (0) -#define NVMEM_NVS_SHADOW_FILEID (1) -#define NVMEM_WLAN_CONFIG_FILEID (2) -#define NVMEM_WLAN_CONFIG_SHADOW_FILEID (3) -#define NVMEM_WLAN_DRIVER_SP_FILEID (4) -#define NVMEM_WLAN_FW_SP_FILEID (5) -#define NVMEM_MAC_FILEID (6) -#define NVMEM_FRONTEND_VARS_FILEID (7) -#define NVMEM_IP_CONFIG_FILEID (8) -#define NVMEM_IP_CONFIG_SHADOW_FILEID (9) -#define NVMEM_BOOTLOADER_SP_FILEID (10) -#define NVMEM_RM_FILEID (11) - -/* NVMEM file ID - user files*/ -#define NVMEM_AES128_KEY_FILEID (12) -#define NVMEM_SHARED_MEM_FILEID (13) - -/* max entry in order to invalid nvmem */ -#define NVMEM_MAX_ENTRY (16) - - -//***************************************************************************** -// -//! nvmem_read -//! -//! @param ulFileId nvmem file id:\n -//! NVMEM_NVS_FILEID, NVMEM_NVS_SHADOW_FILEID, -//! NVMEM_WLAN_CONFIG_FILEID, NVMEM_WLAN_CONFIG_SHADOW_FILEID, -//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, -//! NVMEM_MAC_FILEID, NVMEM_FRONTEND_VARS_FILEID, -//! NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID, -//! NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID, -//! and user files 12-15. -//! @param ulLength number of bytes to read -//! @param ulOffset ulOffset in file from where to read -//! @param buff output buffer pointer -//! -//! @return on success 0, error otherwise. -//! -//! @brief Reads data from the file referred by the ulFileId parameter. -//! Reads data from file ulOffset till length. Err if the file can't -//! be used, is invalid, or if the read is out of bounds. -//! -//***************************************************************************** - -extern INT32 nvmem_read(UINT32 file_id, UINT32 length, UINT32 offset, UINT8 *buff); - -//***************************************************************************** -// -//! nvmem_write -//! -//! @param ulFileId nvmem file id:\n -//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, -//! NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID, -//! and user files 12-15. -//! @param ulLength number of bytes to write -//! @param ulEntryOffset offset in file to start write operation from -//! @param buff data to write -//! -//! @return on success 0, error otherwise. -//! -//! @brief Write data to nvmem. -//! writes data to file referred by the ulFileId parameter. -//! Writes data to file ulOffset till ulLength.The file id will be -//! marked invalid till the write is done. The file entry doesn't -//! need to be valid - only allocated. -//! -//***************************************************************************** - -extern INT32 nvmem_write(UINT32 ulFileId, UINT32 ulLength, UINT32 ulEntryOffset, UINT8 *buff); - - -//***************************************************************************** -// -//! nvmem_set_mac_address -//! -//! @param mac mac address to be set -//! -//! @return on success 0, error otherwise. -//! -//! @brief Write MAC address to EEPROM. -//! mac address as appears over the air (OUI first) -//! -//***************************************************************************** -extern UINT8 nvmem_set_mac_address(UINT8 *mac); - - -//***************************************************************************** -// -//! nvmem_get_mac_address -//! -//! @param[out] mac mac address -//! -//! @return on success 0, error otherwise. -//! -//! @brief Read MAC address from EEPROM. -//! mac address as appears over the air (OUI first) -//! -//***************************************************************************** -extern UINT8 nvmem_get_mac_address(UINT8 *mac); - - -//***************************************************************************** -// -//! nvmem_write_patch -//! -//! @param ulFileId nvmem file id:\n -//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, -//! @param spLength number of bytes to write -//! @param spData SP data to write -//! -//! @return on success 0, error otherwise. -//! -//! @brief program a patch to a specific file ID. -//! The SP data is assumed to be organized in 2-dimensional. -//! Each line is SP_PORTION_SIZE bytes long. Actual programming is -//! applied in SP_PORTION_SIZE bytes portions. -//! -//***************************************************************************** -extern UINT8 nvmem_write_patch(UINT32 ulFileId, UINT32 spLength, const UINT8 *spData); - - -//***************************************************************************** -// -//! nvmem_read_sp_version -//! -//! @param[out] patchVer first number indicates package ID and the second -//! number indicates package build number -//! -//! @return on success 0, error otherwise. -//! -//! @brief Read patch version. read package version (WiFi FW patch, -//! driver-supplicant-NS patch, bootloader patch) -//! -//***************************************************************************** -#ifndef CC3000_TINY_DRIVER -extern UINT8 nvmem_read_sp_version(UINT8* patchVer); -#endif - -//***************************************************************************** -// -//! nvmem_create_entry -//! -//! @param ulFileId nvmem file Id:\n -//! * NVMEM_AES128_KEY_FILEID: 12 -//! * NVMEM_SHARED_MEM_FILEID: 13 -//! * and fileIDs 14 and 15 -//! @param ulNewLen entry ulLength -//! -//! @return on success 0, error otherwise. -//! -//! @brief Create new file entry and allocate space on the NVMEM. -//! Applies only to user files. -//! Modify the size of file. -//! If the entry is unallocated - allocate it to size -//! ulNewLen (marked invalid). -//! If it is allocated then deallocate it first. -//! To just mark the file as invalid without resizing - -//! set ulNewLen=0. -//! -//***************************************************************************** -extern INT32 nvmem_create_entry(UINT32 file_id, UINT32 newlen); - - -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** - - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** - - -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __CC3000_NVRAM_H__ diff --git a/drivers/cc3000/inc/patch_prog.h b/drivers/cc3000/inc/patch_prog.h deleted file mode 100644 index 0a141a0cb53..00000000000 --- a/drivers/cc3000/inc/patch_prog.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __CC3000_PATCH_PROG_H__ -#define __CC3000_PATCH_PROG_H__ -extern unsigned short fw_length; -extern const unsigned char fw_patch[]; - -extern unsigned short drv_length; -extern const unsigned char wlan_drv_patch[]; -extern const unsigned char cRMdefaultParams[128]; - -void patch_prog_start(); -#endif //__CC3000_PATCH_PROG_H__ diff --git a/drivers/cc3000/inc/security.h b/drivers/cc3000/inc/security.h deleted file mode 100644 index cd1baf55416..00000000000 --- a/drivers/cc3000/inc/security.h +++ /dev/null @@ -1,130 +0,0 @@ -/***************************************************************************** -* -* security.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_SECURITY__ -#define __CC3000_SECURITY__ - -#include "nvmem.h" - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - - -#define AES128_KEY_SIZE 16 - -#ifndef CC3000_UNENCRYPTED_SMART_CONFIG - - -//***************************************************************************** -// -//! aes_encrypt -//! -//! @param[in] key AES128 key of size 16 bytes -//! @param[in\out] state 16 bytes of plain text and cipher text -//! -//! @return none -//! -//! @brief AES128 encryption: -//! Given AES128 key and 16 bytes plain text, cipher text of 16 bytes -//! is computed. The AES implementation is in mode ECB (Electronic -//! Code Book). -//! -//! -//***************************************************************************** -extern void aes_encrypt(UINT8 *state, UINT8 *key); - -//***************************************************************************** -// -//! aes_decrypt -//! -//! @param[in] key AES128 key of size 16 bytes -//! @param[in\out] state 16 bytes of cipher text and plain text -//! -//! @return none -//! -//! @brief AES128 decryption: -//! Given AES128 key and 16 bytes cipher text, plain text of 16 bytes -//! is computed The AES implementation is in mode ECB -//! (Electronic Code Book). -//! -//! -//***************************************************************************** -extern void aes_decrypt(UINT8 *state, UINT8 *key); - - -//***************************************************************************** -// -//! aes_read_key -//! -//! @param[out] key AES128 key of size 16 bytes -//! -//! @return on success 0, error otherwise. -//! -//! @brief Reads AES128 key from EEPROM -//! Reads the AES128 key from fileID #12 in EEPROM -//! returns an error if the key does not exist. -//! -//! -//***************************************************************************** -extern INT32 aes_read_key(UINT8 *key); - -//***************************************************************************** -// -//! aes_write_key -//! -//! @param[out] key AES128 key of size 16 bytes -//! -//! @return on success 0, error otherwise. -//! -//! @brief writes AES128 key from EEPROM -//! Writes the AES128 key to fileID #12 in EEPROM -//! -//! -//***************************************************************************** -extern INT32 aes_write_key(UINT8 *key); - -#endif //CC3000_UNENCRYPTED_SMART_CONFIG - -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif diff --git a/drivers/cc3000/inc/socket.h b/drivers/cc3000/inc/socket.h deleted file mode 100644 index 96c814bf77a..00000000000 --- a/drivers/cc3000/inc/socket.h +++ /dev/null @@ -1,676 +0,0 @@ -/***************************************************************************** -* -* socket.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_SOCKET_H__ -#define __CC3000_SOCKET_H__ - -#include "cc3000_common.h" - -//***************************************************************************** -// -//! \addtogroup socket_api -//! @{ -// -//***************************************************************************** - - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - -#define HOSTNAME_MAX_LENGTH (230) // 230 bytes + header shouldn't exceed 8 bit value - -//--------- Address Families -------- - -#define AF_INET 2 -#define AF_INET6 23 - -//------------ Socket Types ------------ - -#define SOCK_STREAM 1 -#define SOCK_DGRAM 2 -#define SOCK_RAW 3 // Raw sockets allow new IPv4 protocols to be implemented in user space. A raw socket receives or sends the raw datagram not including link level headers -#define SOCK_RDM 4 -#define SOCK_SEQPACKET 5 - -//----------- Socket Protocol ---------- - -#define IPPROTO_IP 0 // dummy for IP -#define IPPROTO_ICMP 1 // control message protocol -#define IPPROTO_IPV4 IPPROTO_IP // IP inside IP -#define IPPROTO_TCP 6 // tcp -#define IPPROTO_UDP 17 // user datagram protocol -#define IPPROTO_IPV6 41 // IPv6 in IPv6 -#define IPPROTO_NONE 59 // No next header -#define IPPROTO_RAW 255 // raw IP packet -#define IPPROTO_MAX 256 - -//----------- Socket retunr codes ----------- - -#define SOC_ERROR (-1) // error -#define SOC_IN_PROGRESS (-2) // socket in progress - -//----------- Socket Options ----------- -#define SOL_SOCKET 0xffff // socket level -#define SOCKOPT_RECV_NONBLOCK 0 // recv non block mode, set SOCK_ON or SOCK_OFF (default block mode) -#define SOCKOPT_RECV_TIMEOUT 1 // optname to configure recv and recvfromtimeout -#define SOCKOPT_ACCEPT_NONBLOCK 2 // accept non block mode, set SOCK_ON or SOCK_OFF (default block mode) -#define SOCK_ON 0 // socket non-blocking mode is enabled -#define SOCK_OFF 1 // socket blocking mode is enabled - -#define MAX_PACKET_SIZE 1500 -#define MAX_LISTEN_QUEUE 4 - -#define IOCTL_SOCKET_EVENTMASK - -#define ENOBUFS 55 // No buffer space available - -#define __FD_SETSIZE 32 - -#define ASIC_ADDR_LEN 8 - -#define NO_QUERY_RECIVED -3 - - -typedef struct _in_addr_t -{ - UINT32 s_addr; // load with inet_aton() -} in_addr; - -typedef struct _sockaddr_t -{ - UINT16 sa_family; - UINT8 sa_data[14]; -} sockaddr; - -typedef struct _sockaddr_in_t -{ - INT16 sin_family; // e.g. AF_INET - UINT16 sin_port; // e.g. htons(3490) - in_addr sin_addr; // see struct in_addr, below - CHAR sin_zero[8]; // zero this if you want to -} sockaddr_in; - -typedef UINT32 socklen_t; - -// The fd_set member is required to be an array of INT32s. -typedef INT32 __fd_mask; - -// It's easier to assume 8-bit bytes than to get CHAR_BIT. -#define __NFDBITS (8 * sizeof (__fd_mask)) -#define __FDELT(d) ((d) / __NFDBITS) -#define __FDMASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS)) - -// fd_set for select and pselect. -typedef struct -{ - __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS]; -#define __FDS_BITS(set) ((set)->fds_bits) -} fd_set; - -// We don't use `memset' because this would require a prototype and -// the array isn't too big. -#define __FD_ZERO(set) \ - do { \ - UINT16 __i; \ - fd_set *__arr = (set); \ - for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) \ - __FDS_BITS (__arr)[__i] = 0; \ - } while (0) -#define __FD_SET(d, set) (__FDS_BITS (set)[__FDELT (d)] |= __FDMASK (d)) -#define __FD_CLR(d, set) (__FDS_BITS (set)[__FDELT (d)] &= ~__FDMASK (d)) -#define __FD_ISSET(d, set) (__FDS_BITS (set)[__FDELT (d)] & __FDMASK (d)) - -// Access macros for 'fd_set'. -#define FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp) -#define FD_CLR(fd, fdsetp) __FD_CLR (fd, fdsetp) -#define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp) -#define FD_ZERO(fdsetp) __FD_ZERO (fdsetp) - -//Use in case of Big Endian only - -#define htonl(A) ((((UINT32)(A) & 0xff000000) >> 24) | \ - (((UINT32)(A) & 0x00ff0000) >> 8) | \ - (((UINT32)(A) & 0x0000ff00) << 8) | \ - (((UINT32)(A) & 0x000000ff) << 24)) - -#define ntohl htonl - -//Use in case of Big Endian only -#define htons(A) ((((UINT32)(A) & 0xff00) >> 8) | \ - (((UINT32)(A) & 0x00ff) << 8)) - - -#define ntohs htons - -// mDNS port - 5353 mDNS multicast address - 224.0.0.251 -#define SET_mDNS_ADD(sockaddr) sockaddr.sa_data[0] = 0x14; \ - sockaddr.sa_data[1] = 0xe9; \ - sockaddr.sa_data[2] = 0xe0; \ - sockaddr.sa_data[3] = 0x0; \ - sockaddr.sa_data[4] = 0x0; \ - sockaddr.sa_data[5] = 0xfb; - - -//***************************************************************************** -// -// Prototypes for the APIs. -// -//***************************************************************************** - -//***************************************************************************** -// -//! socket -//! -//! @param domain selects the protocol family which will be used for -//! communication. On this version only AF_INET is supported -//! @param type specifies the communication semantics. On this version -//! only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported -//! @param protocol specifies a particular protocol to be used with the -//! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are -//! supported. -//! -//! @return On success, socket handle that is used for consequent socket -//! operations. On error, -1 is returned. -//! -//! @brief create an endpoint for communication -//! The socket function creates a socket that is bound to a specific -//! transport service provider. This function is called by the -//! application layer to obtain a socket handle. -// -//***************************************************************************** -extern INT16 CC3000_EXPORT(socket)(INT32 domain, INT32 type, INT32 protocol); - -//***************************************************************************** -// -//! closesocket -//! -//! @param sd socket handle. -//! -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief The socket function closes a created socket. -// -//***************************************************************************** -extern INT32 CC3000_EXPORT(closesocket)(INT32 sd); - -//***************************************************************************** -// -//! accept -//! -//! @param[in] sd socket descriptor (handle) -//! @param[out] addr the argument addr is a pointer to a sockaddr structure -//! This structure is filled in with the address of the -//! peer socket, as known to the communications layer. -//! determined. The exact format of the address returned -//! addr is by the socket's address sockaddr. -//! On this version only AF_INET is supported. -//! This argument returns in network order. -//! @param[out] addrlen the addrlen argument is a value-result argument: -//! it should initially contain the size of the structure -//! pointed to by addr. -//! -//! @return For socket in blocking mode: -//! On success, socket handle. on failure negative -//! For socket in non-blocking mode: -//! - On connection establishment, socket handle -//! - On connection pending, SOC_IN_PROGRESS (-2) -//! - On failure, SOC_ERROR (-1) -//! -//! @brief accept a connection on a socket: -//! This function is used with connection-based socket types -//! (SOCK_STREAM). It extracts the first connection request on the -//! queue of pending connections, creates a new connected socket, and -//! returns a new file descriptor referring to that socket. -//! The newly created socket is not in the listening state. -//! The original socket sd is unaffected by this call. -//! The argument sd is a socket that has been created with socket(), -//! bound to a local address with bind(), and is listening for -//! connections after a listen(). The argument addr is a pointer -//! to a sockaddr structure. This structure is filled in with the -//! address of the peer socket, as known to the communications layer. -//! The exact format of the address returned addr is determined by the -//! socket's address family. The addrlen argument is a value-result -//! argument: it should initially contain the size of the structure -//! pointed to by addr, on return it will contain the actual -//! length (in bytes) of the address returned. -//! -//! @sa socket ; bind ; listen -// -//***************************************************************************** -extern INT32 CC3000_EXPORT(accept)(INT32 sd, sockaddr *addr, socklen_t *addrlen); - -//***************************************************************************** -// -//! bind -//! -//! @param[in] sd socket descriptor (handle) -//! @param[out] addr specifies the destination address. On this version -//! only AF_INET is supported. -//! @param[out] addrlen contains the size of the structure pointed to by addr. -//! -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief assign a name to a socket -//! This function gives the socket the local address addr. -//! addr is addrlen bytes long. Traditionally, this is called when a -//! socket is created with socket, it exists in a name space (address -//! family) but has no name assigned. -//! It is necessary to assign a local address before a SOCK_STREAM -//! socket may receive connections. -//! -//! @sa socket ; accept ; listen -// -//***************************************************************************** -extern INT32 CC3000_EXPORT(bind)(INT32 sd, const sockaddr *addr, INT32 addrlen); - -//***************************************************************************** -// -//! listen -//! -//! @param[in] sd socket descriptor (handle) -//! @param[in] backlog specifies the listen queue depth. On this version -//! backlog is not supported. -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief listen for connections on a socket -//! The willingness to accept incoming connections and a queue -//! limit for incoming connections are specified with listen(), -//! and then the connections are accepted with accept. -//! The listen() call applies only to sockets of type SOCK_STREAM -//! The backlog parameter defines the maximum length the queue of -//! pending connections may grow to. -//! -//! @sa socket ; accept ; bind -//! -//! @note On this version, backlog is not supported -// -//***************************************************************************** -extern INT32 CC3000_EXPORT(listen)(INT32 sd, INT32 backlog); - -//***************************************************************************** -// -//! gethostbyname -//! -//! @param[in] hostname host name -//! @param[in] usNameLen name length -//! @param[out] out_ip_addr This parameter is filled in with host IP address. -//! In case that host name is not resolved, -//! out_ip_addr is zero. -//! @return On success, positive is returned. On error, negative is returned -//! -//! @brief Get host IP by name. Obtain the IP Address of machine on network, -//! by its name. -//! -//! @note On this version, only blocking mode is supported. Also note that -//! the function requires DNS server to be configured prior to its usage. -// -//***************************************************************************** -#ifndef CC3000_TINY_DRIVER -extern INT16 CC3000_EXPORT(gethostbyname)(CHAR * hostname, UINT16 usNameLen, UINT32* out_ip_addr); -#endif - - -//***************************************************************************** -// -//! connect -//! -//! @param[in] sd socket descriptor (handle) -//! @param[in] addr specifies the destination addr. On this version -//! only AF_INET is supported. -//! @param[out] addrlen contains the size of the structure pointed to by addr -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief initiate a connection on a socket -//! Function connects the socket referred to by the socket descriptor -//! sd, to the address specified by addr. The addrlen argument -//! specifies the size of addr. The format of the address in addr is -//! determined by the address space of the socket. If it is of type -//! SOCK_DGRAM, this call specifies the peer with which the socket is -//! to be associated; this address is that to which datagrams are to be -//! sent, and the only address from which datagrams are to be received. -//! If the socket is of type SOCK_STREAM, this call attempts to make a -//! connection to another socket. The other socket is specified by -//! address, which is an address in the communications space of the -//! socket. Note that the function implements only blocking behavior -//! thus the caller will be waiting either for the connection -//! establishment or for the connection establishment failure. -//! -//! @sa socket -// -//***************************************************************************** -extern INT32 CC3000_EXPORT(connect)(INT32 sd, const sockaddr *addr, INT32 addrlen); - -//***************************************************************************** -// -//! select -//! -//! @param[in] nfds the highest-numbered file descriptor in any of the -//! three sets, plus 1. -//! @param[out] writesds socket descriptors list for write monitoring -//! @param[out] readsds socket descriptors list for read monitoring -//! @param[out] exceptsds socket descriptors list for exception monitoring -//! @param[in] timeout is an upper bound on the amount of time elapsed -//! before select() returns. Null means infinity -//! timeout. The minimum timeout is 5 milliseconds, -//! less than 5 milliseconds will be set -//! automatically to 5 milliseconds. -//! @return On success, select() returns the number of file descriptors -//! contained in the three returned descriptor sets (that is, the -//! total number of bits that are set in readfds, writefds, -//! exceptfds) which may be zero if the timeout expires before -//! anything interesting happens. -//! On error, -1 is returned. -//! *readsds - return the sockets on which Read request will -//! return without delay with valid data. -//! *writesds - return the sockets on which Write request -//! will return without delay. -//! *exceptsds - return the sockets which closed recently. -//! -//! @brief Monitor socket activity -//! Select allow a program to monitor multiple file descriptors, -//! waiting until one or more of the file descriptors become -//! "ready" for some class of I/O operation -//! -//! @Note If the timeout value set to less than 5ms it will automatically set -//! to 5ms to prevent overload of the system -//! -//! @sa socket -// -//***************************************************************************** -extern INT16 CC3000_EXPORT(select)(INT32 nfds, fd_set *readsds, fd_set *writesds, - fd_set *exceptsds, struct cc3000_timeval *timeout); - -//***************************************************************************** -// -//! setsockopt -//! -//! @param[in] sd socket handle -//! @param[in] level defines the protocol level for this option -//! @param[in] optname defines the option name to Interrogate -//! @param[in] optval specifies a value for the option -//! @param[in] optlen specifies the length of the option value -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief set socket options -//! This function manipulate the options associated with a socket. -//! Options may exist at multiple protocol levels; they are always -//! present at the uppermost socket level. -//! When manipulating socket options the level at which the option -//! resides and the name of the option must be specified. -//! To manipulate options at the socket level, level is specified as -//! SOL_SOCKET. To manipulate options at any other level the protocol -//! number of the appropriate protocol controlling the option is -//! supplied. For example, to indicate that an option is to be -//! interpreted by the TCP protocol, level should be set to the -//! protocol number of TCP; -//! The parameters optval and optlen are used to access optval - -//! use for setsockopt(). For getsockopt() they identify a buffer -//! in which the value for the requested option(s) are to -//! be returned. For getsockopt(), optlen is a value-result -//! parameter, initially containing the size of the buffer -//! pointed to by option_value, and modified on return to -//! indicate the actual size of the value returned. If no option -//! value is to be supplied or returned, option_value may be NULL. -//! -//! @Note On this version the following two socket options are enabled: -//! The only protocol level supported in this version -//! is SOL_SOCKET (level). -//! 1. SOCKOPT_RECV_TIMEOUT (optname) -//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout -//! in milliseconds. -//! In that case optval should be pointer to UINT32. -//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on -//! or off. -//! In that case optval should be SOCK_ON or SOCK_OFF (optval). -//! -//! @sa getsockopt -// -//***************************************************************************** -#ifndef CC3000_TINY_DRIVER -extern INT16 CC3000_EXPORT(setsockopt)(INT32 sd, INT32 level, INT32 optname, const void *optval, - socklen_t optlen); -#endif -//***************************************************************************** -// -//! getsockopt -//! -//! @param[in] sd socket handle -//! @param[in] level defines the protocol level for this option -//! @param[in] optname defines the option name to Interrogate -//! @param[out] optval specifies a value for the option -//! @param[out] optlen specifies the length of the option value -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief set socket options -//! This function manipulate the options associated with a socket. -//! Options may exist at multiple protocol levels; they are always -//! present at the uppermost socket level. -//! When manipulating socket options the level at which the option -//! resides and the name of the option must be specified. -//! To manipulate options at the socket level, level is specified as -//! SOL_SOCKET. To manipulate options at any other level the protocol -//! number of the appropriate protocol controlling the option is -//! supplied. For example, to indicate that an option is to be -//! interpreted by the TCP protocol, level should be set to the -//! protocol number of TCP; -//! The parameters optval and optlen are used to access optval - -//! use for setsockopt(). For getsockopt() they identify a buffer -//! in which the value for the requested option(s) are to -//! be returned. For getsockopt(), optlen is a value-result -//! parameter, initially containing the size of the buffer -//! pointed to by option_value, and modified on return to -//! indicate the actual size of the value returned. If no option -//! value is to be supplied or returned, option_value may be NULL. -//! -//! @Note On this version the following two socket options are enabled: -//! The only protocol level supported in this version -//! is SOL_SOCKET (level). -//! 1. SOCKOPT_RECV_TIMEOUT (optname) -//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout -//! in milliseconds. -//! In that case optval should be pointer to UINT32. -//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on -//! or off. -//! In that case optval should be SOCK_ON or SOCK_OFF (optval). -//! -//! @sa setsockopt -// -//***************************************************************************** -extern INT16 CC3000_EXPORT(getsockopt)(INT32 sd, INT32 level, INT32 optname, void *optval, - socklen_t *optlen); - -//***************************************************************************** -// -//! recv -//! -//! @param[in] sd socket handle -//! @param[out] buf Points to the buffer where the message should be stored -//! @param[in] len Specifies the length in bytes of the buffer pointed to -//! by the buffer argument. -//! @param[in] flags Specifies the type of message reception. -//! On this version, this parameter is not supported. -//! -//! @return Return the number of bytes received, or -1 if an error -//! occurred -//! -//! @brief function receives a message from a connection-mode socket -//! -//! @sa recvfrom -//! -//! @Note On this version, only blocking mode is supported. -// -//***************************************************************************** -extern INT16 CC3000_EXPORT(recv)(INT32 sd, void *buf, INT32 len, INT32 flags); - -//***************************************************************************** -// -//! recvfrom -//! -//! @param[in] sd socket handle -//! @param[out] buf Points to the buffer where the message should be stored -//! @param[in] len Specifies the length in bytes of the buffer pointed to -//! by the buffer argument. -//! @param[in] flags Specifies the type of message reception. -//! On this version, this parameter is not supported. -//! @param[in] from pointer to an address structure indicating the source -//! address: sockaddr. On this version only AF_INET is -//! supported. -//! @param[in] fromlen source address structure size -//! -//! @return Return the number of bytes received, or -1 if an error -//! occurred -//! -//! @brief read data from socket -//! function receives a message from a connection-mode or -//! connectionless-mode socket. Note that raw sockets are not -//! supported. -//! -//! @sa recv -//! -//! @Note On this version, only blocking mode is supported. -// -//***************************************************************************** -extern INT16 CC3000_EXPORT(recvfrom)(INT32 sd, void *buf, INT32 len, INT32 flags, sockaddr *from, - socklen_t *fromlen); - -//***************************************************************************** -// -//! send -//! -//! @param sd socket handle -//! @param buf Points to a buffer containing the message to be sent -//! @param len message size in bytes -//! @param flags On this version, this parameter is not supported -//! -//! @return Return the number of bytes transmitted, or -1 if an -//! error occurred -//! -//! @brief Write data to TCP socket -//! This function is used to transmit a message to another -//! socket. -//! -//! @Note On this version, only blocking mode is supported. -//! -//! @sa sendto -// -//***************************************************************************** - -extern INT16 CC3000_EXPORT(send)(INT32 sd, const void *buf, INT32 len, INT32 flags); - -//***************************************************************************** -// -//! sendto -//! -//! @param sd socket handle -//! @param buf Points to a buffer containing the message to be sent -//! @param len message size in bytes -//! @param flags On this version, this parameter is not supported -//! @param to pointer to an address structure indicating the destination -//! address: sockaddr. On this version only AF_INET is -//! supported. -//! @param tolen destination address structure size -//! -//! @return Return the number of bytes transmitted, or -1 if an -//! error occurred -//! -//! @brief Write data to TCP socket -//! This function is used to transmit a message to another -//! socket. -//! -//! @Note On this version, only blocking mode is supported. -//! -//! @sa send -// -//***************************************************************************** - -extern INT16 CC3000_EXPORT(sendto)(INT32 sd, const void *buf, INT32 len, INT32 flags, - const sockaddr *to, socklen_t tolen); - -//***************************************************************************** -// -//! mdnsAdvertiser -//! -//! @param[in] mdnsEnabled flag to enable/disable the mDNS feature -//! @param[in] deviceServiceName Service name as part of the published -//! canonical domain name -//! @param[in] deviceServiceNameLength Length of the service name - up to 32 chars -//! -//! -//! @return On success, zero is returned, return SOC_ERROR if socket was not -//! opened successfully, or if an error occurred. -//! -//! @brief Set CC3000 in mDNS advertiser mode in order to advertise itself. -// -//***************************************************************************** -extern INT16 CC3000_EXPORT(mdnsAdvertiser)(UINT16 mdnsEnabled, CHAR * deviceServiceName, UINT16 deviceServiceNameLength); - - -//***************************************************************************** -// -//! getmssvalue -//! -//! @param[in] sd socket descriptor -//! -//! @return On success, returns the MSS value of a TCP connection -//! -//! @brief Returns the MSS value of a TCP connection according to the socket descriptor -// -//***************************************************************************** -extern UINT16 CC3000_EXPORT(getmssvalue) (INT32 sd); - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** - - -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __SOCKET_H__ diff --git a/drivers/cc3000/inc/wlan.h b/drivers/cc3000/inc/wlan.h deleted file mode 100644 index 48d195b32ae..00000000000 --- a/drivers/cc3000/inc/wlan.h +++ /dev/null @@ -1,518 +0,0 @@ -/***************************************************************************** -* -* wlan.h - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -#ifndef __CC3000_WLAN_H__ -#define __CC3000_WLAN_H__ - -#include "cc3000_common.h" - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" { -#endif - -#define WLAN_SEC_UNSEC (0) -#define WLAN_SEC_WEP (1) -#define WLAN_SEC_WPA (2) -#define WLAN_SEC_WPA2 (3) -//***************************************************************************** -// -//! \addtogroup wlan_api -//! @{ -// -//***************************************************************************** - - -//***************************************************************************** -// -//! wlan_init -//! -//! @param sWlanCB Asynchronous events callback. -//! 0 no event call back. -//! -call back parameters: -//! 1) event_type: HCI_EVNT_WLAN_UNSOL_CONNECT connect event, -//! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event, -//! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE config done, -//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp report, -//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report OR -//! HCI_EVNT_WLAN_KEEPALIVE keepalive. -//! 2) data: pointer to extra data that received by the event -//! (NULL no data). -//! 3) length: data length. -//! -Events with extra data: -//! HCI_EVNT_WLAN_UNSOL_DHCP: 4 bytes IP, 4 bytes Mask, -//! 4 bytes default gateway, 4 bytes DHCP server and 4 bytes -//! for DNS server. -//! HCI_EVNT_WLAN_ASYNC_PING_REPORT: 4 bytes Packets sent, -//! 4 bytes Packets received, 4 bytes Min round time, -//! 4 bytes Max round time and 4 bytes for Avg round time. -//! -//! @param sFWPatches 0 no patch or pointer to FW patches -//! @param sDriverPatches 0 no patch or pointer to driver patches -//! @param sBootLoaderPatches 0 no patch or pointer to bootloader patches -//! @param sReadWlanInterruptPin init callback. the callback read wlan -//! interrupt status. -//! @param sWlanInterruptEnable init callback. the callback enable wlan -//! interrupt. -//! @param sWlanInterruptDisable init callback. the callback disable wlan -//! interrupt. -//! @param sWriteWlanPin init callback. the callback write value -//! to device pin. -//! -//! @return none -//! -//! @sa wlan_set_event_mask , wlan_start , wlan_stop -//! -//! @brief Initialize wlan driver -//! -//! @warning This function must be called before ANY other wlan driver function -// -//***************************************************************************** -extern void wlan_init( tWlanCB sWlanCB, - tFWPatches sFWPatches, - tDriverPatches sDriverPatches, - tBootLoaderPatches sBootLoaderPatches, - tWlanReadInteruptPin sReadWlanInterruptPin, - tWlanInterruptEnable sWlanInterruptEnable, - tWlanInterruptDisable sWlanInterruptDisable, - tWriteWlanPin sWriteWlanPin); - - - -//***************************************************************************** -// -//! wlan_start -//! -//! @param usPatchesAvailableAtHost - flag to indicate if patches available -//! from host or from EEPROM. Due to the -//! fact the patches are burn to the EEPROM -//! using the patch programmer utility, the -//! patches will be available from the EEPROM -//! and not from the host. -//! -//! @return none -//! -//! @brief Start WLAN device. This function asserts the enable pin of -//! the device (WLAN_EN), starting the HW initialization process. -//! The function blocked until device Initialization is completed. -//! Function also configure patches (FW, driver or bootloader) -//! and calls appropriate device callbacks. -//! -//! @Note Prior calling the function wlan_init shall be called. -//! @Warning This function must be called after wlan_init and before any -//! other wlan API -//! @sa wlan_init , wlan_stop -//! -// -//***************************************************************************** -extern int wlan_start(UINT16 usPatchesAvailableAtHost); - -//***************************************************************************** -// -//! wlan_stop -//! -//! @param none -//! -//! @return none -//! -//! @brief Stop WLAN device by putting it into reset state. -//! -//! @sa wlan_start -// -//***************************************************************************** -extern void wlan_stop(void); - -//***************************************************************************** -// -//! wlan_connect -//! -//! @param sec_type security options: -//! WLAN_SEC_UNSEC, -//! WLAN_SEC_WEP (ASCII support only), -//! WLAN_SEC_WPA or WLAN_SEC_WPA2 -//! @param ssid up to 32 bytes and is ASCII SSID of the AP -//! @param ssid_len length of the SSID -//! @param bssid 6 bytes specified the AP bssid -//! @param key up to 32 bytes specified the AP security key -//! @param key_len key length -//! -//! @return On success, zero is returned. On error, negative is returned. -//! Note that even though a zero is returned on success to trigger -//! connection operation, it does not mean that CCC3000 is already -//! connected. An asynchronous "Connected" event is generated when -//! actual association process finishes and CC3000 is connected to -//! the AP. If DHCP is set, An asynchronous "DHCP" event is -//! generated when DHCP process is finish. -//! -//! -//! @brief Connect to AP -//! @warning Please Note that when connection to AP configured with security -//! type WEP, please confirm that the key is set as ASCII and not -//! as HEX. -//! @sa wlan_disconnect -// -//***************************************************************************** -#ifndef CC3000_TINY_DRIVER -extern INT32 wlan_connect(UINT32 ulSecType, CHAR *ssid, INT32 ssid_len, - UINT8 *bssid, UINT8 *key, INT32 key_len); -#else -extern INT32 wlan_connect(CHAR *ssid, INT32 ssid_len); - -#endif - -//***************************************************************************** -// -//! wlan_disconnect -//! -//! @return 0 disconnected done, other CC3000 already disconnected -//! -//! @brief Disconnect connection from AP. -//! -//! @sa wlan_connect -// -//***************************************************************************** - -extern INT32 wlan_disconnect(void); - -//***************************************************************************** -// -//! wlan_add_profile -//! -//! @param ulSecType WLAN_SEC_UNSEC,WLAN_SEC_WEP,WLAN_SEC_WPA,WLAN_SEC_WPA2 -//! @param ucSsid ssid SSID up to 32 bytes -//! @param ulSsidLen ssid length -//! @param ucBssid bssid 6 bytes -//! @param ulPriority ulPriority profile priority. Lowest priority:0. -//! @param ulPairwiseCipher_Or_TxKeyLen key length for WEP security -//! @param ulGroupCipher_TxKeyIndex key index -//! @param ulKeyMgmt KEY management -//! @param ucPf_OrKey security key -//! @param ulPassPhraseLen security key length for WPA\WPA2 -//! -//! @return On success, index (1-7) of the stored profile is returned. -//! On error, -1 is returned. -//! -//! @brief When auto start is enabled, the device connects to -//! station from the profiles table. Up to 7 profiles are supported. -//! If several profiles configured the device choose the highest -//! priority profile, within each priority group, device will choose -//! profile based on security policy, signal strength, etc -//! parameters. All the profiles are stored in CC3000 NVMEM. -//! -//! @sa wlan_ioctl_del_profile -// -//***************************************************************************** - -extern INT32 wlan_add_profile(UINT32 ulSecType, UINT8* ucSsid, - UINT32 ulSsidLen, - UINT8 *ucBssid, - UINT32 ulPriority, - UINT32 ulPairwiseCipher_Or_Key, - UINT32 ulGroupCipher_TxKeyLen, - UINT32 ulKeyMgmt, - UINT8* ucPf_OrKey, - UINT32 ulPassPhraseLen); - - - -//***************************************************************************** -// -//! wlan_ioctl_del_profile -//! -//! @param index number of profile to delete -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Delete WLAN profile -//! -//! @Note In order to delete all stored profile, set index to 255. -//! -//! @sa wlan_add_profile -// -//***************************************************************************** -extern INT32 wlan_ioctl_del_profile(UINT32 ulIndex); - -//***************************************************************************** -// -//! wlan_set_event_mask -//! -//! @param mask mask option: -//! HCI_EVNT_WLAN_UNSOL_CONNECT connect event -//! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event -//! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE smart config done -//! HCI_EVNT_WLAN_UNSOL_INIT init done -//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp event report -//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report -//! HCI_EVNT_WLAN_KEEPALIVE keepalive -//! HCI_EVNT_WLAN_TX_COMPLETE - disable information on end of transmission -//! Saved: no. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Mask event according to bit mask. In case that event is -//! masked (1), the device will not send the masked event to host. -// -//***************************************************************************** -extern INT32 wlan_set_event_mask(UINT32 ulMask); - -//***************************************************************************** -// -//! wlan_ioctl_statusget -//! -//! @param none -//! -//! @return WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING, -//! STATUS_CONNECTING or WLAN_STATUS_CONNECTED -//! -//! @brief get wlan status: disconnected, scanning, connecting or connected -// -//***************************************************************************** -extern INT32 wlan_ioctl_statusget(void); - - -//***************************************************************************** -// -//! wlan_ioctl_set_connection_policy -//! -//! @param should_connect_to_open_ap enable(1), disable(0) connect to any -//! available AP. This parameter corresponds to the configuration of -//! item # 3 in the brief description. -//! @param should_use_fast_connect enable(1), disable(0). if enabled, tries -//! to connect to the last connected AP. This parameter corresponds -//! to the configuration of item # 1 in the brief description. -//! @param auto_start enable(1), disable(0) auto connect -//! after reset and periodically reconnect if needed. This -//! configuration configures option 2 in the above description. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief When auto is enabled, the device tries to connect according -//! the following policy: -//! 1) If fast connect is enabled and last connection is valid, -//! the device will try to connect to it without the scanning -//! procedure (fast). The last connection will be marked as -//! invalid, due to adding/removing profile. -//! 2) If profile exists, the device will try to connect it -//! (Up to seven profiles). -//! 3) If fast and profiles are not found, and open mode is -//! enabled, the device will try to connect to any AP. -//! * Note that the policy settings are stored in the CC3000 NVMEM. -//! -//! @sa wlan_add_profile , wlan_ioctl_del_profile -// -//***************************************************************************** -extern INT32 wlan_ioctl_set_connection_policy( - UINT32 should_connect_to_open_ap, - UINT32 should_use_fast_connect, - UINT32 ulUseProfiles); - -//***************************************************************************** -// -//! wlan_ioctl_get_scan_results -//! -//! @param[in] scan_timeout parameter not supported -//! @param[out] ucResults scan result (_wlan_full_scan_results_args_t) -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Gets entry from scan result table. -//! The scan results are returned one by one, and each entry -//! represents a single AP found in the area. The following is a -//! format of the scan result: -//! - 4 Bytes: number of networks found -//! - 4 Bytes: The status of the scan: 0 - aged results, -//! 1 - results valid, 2 - no results -//! - 42 bytes: Result entry, where the bytes are arranged as follows: -//! -//! - 1 bit isValid - is result valid or not -//! - 7 bits rssi - RSSI value; -//! - 2 bits: securityMode - security mode of the AP: -//! 0 - Open, 1 - WEP, 2 WPA, 3 WPA2 -//! - 6 bits: SSID name length -//! - 2 bytes: the time at which the entry has entered into -//! scans result table -//! - 32 bytes: SSID name -//! - 6 bytes: BSSID -//! -//! @Note scan_timeout, is not supported on this version. -//! -//! @sa wlan_ioctl_set_scan_params -// -//***************************************************************************** - - -extern INT32 wlan_ioctl_get_scan_results(UINT32 ulScanTimeout, - UINT8 *ucResults); - -//***************************************************************************** -// -//! wlan_ioctl_set_scan_params -//! -//! @param uiEnable - start/stop application scan: -//! 1 = start scan with default interval value of 10 min. -//! in order to set a different scan interval value apply the value -//! in milliseconds. minimum 1 second. 0=stop). Wlan reset -//! (wlan_stop() wlan_start()) is needed when changing scan interval -//! value. Saved: No -//! @param uiMinDwellTime minimum dwell time value to be used for each -//! channel, in milliseconds. Saved: yes -//! Recommended Value: 100 (Default: 20) -//! @param uiMaxDwellTime maximum dwell time value to be used for each -//! channel, in milliseconds. Saved: yes -//! Recommended Value: 100 (Default: 30) -//! @param uiNumOfProbeRequests max probe request between dwell time. -//! Saved: yes. Recommended Value: 5 (Default:2) -//! @param uiChannelMask bitwise, up to 13 channels (0x1fff). -//! Saved: yes. Default: 0x7ff -//! @param uiRSSIThreshold RSSI threshold. Saved: yes (Default: -80) -//! @param uiSNRThreshold NSR threshold. Saved: yes (Default: 0) -//! @param uiDefaultTxPower probe Tx power. Saved: yes (Default: 205) -//! @param aiIntervalList pointer to array with 16 entries (16 channels) -//! each entry (UINT32) holds timeout between periodic scan -//! (connection scan) - in milliseconds. Saved: yes. Default 2000ms. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief start and stop scan procedure. Set scan parameters. -//! -//! @Note uiDefaultTxPower, is not supported on this version. -//! -//! @sa wlan_ioctl_get_scan_results -// -//***************************************************************************** -extern INT32 wlan_ioctl_set_scan_params(UINT32 uiEnable, UINT32 - uiMinDwellTime,UINT32 uiMaxDwellTime, - UINT32 uiNumOfProbeRequests, - UINT32 uiChannelMask, - INT32 iRSSIThreshold,UINT32 uiSNRThreshold, - UINT32 uiDefaultTxPower, - UINT32 *aiIntervalList); - - -//***************************************************************************** -// -//! wlan_smart_config_start -//! -//! @param algoEncryptedFlag indicates whether the information is encrypted -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Start to acquire device profile. The device acquire its own -//! profile, if profile message is found. The acquired AP information -//! is stored in CC3000 EEPROM only in case AES128 encryption is used. -//! In case AES128 encryption is not used, a profile is created by -//! CC3000 internally. -//! -//! @Note An asynchronous event - Smart Config Done will be generated as soon -//! as the process finishes successfully. -//! -//! @sa wlan_smart_config_set_prefix , wlan_smart_config_stop -// -//***************************************************************************** -extern INT32 wlan_smart_config_start(UINT32 algoEncryptedFlag); - - -//***************************************************************************** -// -//! wlan_smart_config_stop -//! -//! @param algoEncryptedFlag indicates whether the information is encrypted -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Stop the acquire profile procedure -//! -//! @sa wlan_smart_config_start , wlan_smart_config_set_prefix -// -//***************************************************************************** -extern INT32 wlan_smart_config_stop(void); - -//***************************************************************************** -// -//! wlan_smart_config_set_prefix -//! -//! @param newPrefix 3 bytes identify the SSID prefix for the Smart Config. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Configure station ssid prefix. The prefix is used internally -//! in CC3000. It should always be TTT. -//! -//! @Note The prefix is stored in CC3000 NVMEM -//! -//! @sa wlan_smart_config_start , wlan_smart_config_stop -// -//***************************************************************************** -extern INT32 wlan_smart_config_set_prefix(CHAR* cNewPrefix); - -//***************************************************************************** -// -//! wlan_smart_config_process -//! -//! @param none -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief process the acquired data and store it as a profile. The acquired -//! AP information is stored in CC3000 EEPROM encrypted. -//! The encrypted data is decrypted and stored as a profile. -//! behavior is as defined by connection policy. -// -//***************************************************************************** -extern INT32 wlan_smart_config_process(void); - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** - - - -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __CC3000_WLAN_H__ diff --git a/drivers/cc3000/src/cc3000_common.c b/drivers/cc3000/src/cc3000_common.c deleted file mode 100644 index b4c87848cf4..00000000000 --- a/drivers/cc3000/src/cc3000_common.c +++ /dev/null @@ -1,164 +0,0 @@ -/***************************************************************************** -* -* cc3000_common.c.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -//***************************************************************************** -// -//! \addtogroup common_api -//! @{ -// -//***************************************************************************** -/****************************************************************************** -* -* Include files -* -*****************************************************************************/ - -#include "cc3000_common.h" -#include "socket.h" -#include "wlan.h" -#include "evnt_handler.h" - -//***************************************************************************** -// -//! __error__ -//! -//! @param pcFilename - file name, where error occurred -//! @param ulLine - line number, where error occurred -//! -//! @return none -//! -//! @brief stub function for ASSERT macro -// -//***************************************************************************** -void __error__(CHAR *pcFilename, UINT32 ulLine) -{ - //TODO full up function -} - - - -//***************************************************************************** -// -//! UINT32_TO_STREAM_f -//! -//! @param p pointer to the new stream -//! @param u32 pointer to the 32 bit -//! -//! @return pointer to the new stream -//! -//! @brief This function is used for copying 32 bit to stream -//! while converting to little endian format. -// -//***************************************************************************** - -UINT8* UINT32_TO_STREAM_f (UINT8 *p, UINT32 u32) -{ - *(p)++ = (UINT8)(u32); - *(p)++ = (UINT8)((u32) >> 8); - *(p)++ = (UINT8)((u32) >> 16); - *(p)++ = (UINT8)((u32) >> 24); - return p; -} - -//***************************************************************************** -// -//! UINT16_TO_STREAM_f -//! -//! @param p pointer to the new stream -//! @param u32 pointer to the 16 bit -//! -//! @return pointer to the new stream -//! -//! @brief This function is used for copying 16 bit to stream -//! while converting to little endian format. -// -//***************************************************************************** - -UINT8* UINT16_TO_STREAM_f (UINT8 *p, UINT16 u16) -{ - *(p)++ = (UINT8)(u16); - *(p)++ = (UINT8)((u16) >> 8); - return p; -} - -//***************************************************************************** -// -//! STREAM_TO_UINT16_f -//! -//! @param p pointer to the stream -//! @param offset offset in the stream -//! -//! @return pointer to the new 16 bit -//! -//! @brief This function is used for copying received stream to -//! 16 bit in little endian format. -// -//***************************************************************************** - -UINT16 STREAM_TO_UINT16_f(CHAR* p, UINT16 offset) -{ - return (UINT16)((UINT16)((UINT16) - (*(p + offset + 1)) << 8) + (UINT16)(*(p + offset))); -} - -//***************************************************************************** -// -//! STREAM_TO_UINT32_f -//! -//! @param p pointer to the stream -//! @param offset offset in the stream -//! -//! @return pointer to the new 32 bit -//! -//! @brief This function is used for copying received stream to -//! 32 bit in little endian format. -// -//***************************************************************************** - -UINT32 STREAM_TO_UINT32_f(CHAR* p, UINT16 offset) -{ - return (UINT32)((UINT32)((UINT32) - (*(p + offset + 3)) << 24) + (UINT32)((UINT32) - (*(p + offset + 2)) << 16) + (UINT32)((UINT32) - (*(p + offset + 1)) << 8) + (UINT32)(*(p + offset))); -} - - - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** diff --git a/drivers/cc3000/src/ccspi.c b/drivers/cc3000/src/ccspi.c deleted file mode 100644 index 1dcd6188408..00000000000 --- a/drivers/cc3000/src/ccspi.c +++ /dev/null @@ -1,455 +0,0 @@ -/***************************************************************************** - * - * spi.c - CC3000 Host Driver Implementation. - * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ - -#include - -#include "py/runtime.h" -#include "pin.h" -#include "led.h" -#include "extint.h" -#include "spi.h" -#include "ccspi.h" -#include "evnt_handler.h" - -#if 0 // print debugging info -#include -#define DEBUG_printf(args...) printf(args) -#else // don't print debugging info -#define DEBUG_printf(args...) (void)0 -#endif - -// these need to be set to valid values before anything in this file will work -STATIC const spi_t *SPI_HANDLE = NULL; -STATIC const pin_obj_t *PIN_CS = NULL; -STATIC const pin_obj_t *PIN_EN = NULL; -STATIC const pin_obj_t *PIN_IRQ = NULL; - -#define CS_LOW() HAL_GPIO_WritePin(PIN_CS->gpio, PIN_CS->pin_mask, GPIO_PIN_RESET) -#define CS_HIGH() HAL_GPIO_WritePin(PIN_CS->gpio, PIN_CS->pin_mask, GPIO_PIN_SET) - -#define READ 3 -#define WRITE 1 - -#define HI(value) (((value) & 0xFF00) >> 8) -#define LO(value) ((value) & 0x00FF) - -#define SPI_TIMEOUT (1000) -#define HEADERS_SIZE_EVNT (SPI_HEADER_SIZE + 5) - -/* SPI bus states */ -#define eSPI_STATE_POWERUP (0) -#define eSPI_STATE_INITIALIZED (1) -#define eSPI_STATE_IDLE (2) -#define eSPI_STATE_WRITE_IRQ (3) -#define eSPI_STATE_WRITE_FIRST_PORTION (4) -#define eSPI_STATE_WRITE_EOT (5) -#define eSPI_STATE_READ_IRQ (6) -#define eSPI_STATE_READ_FIRST_PORTION (7) -#define eSPI_STATE_READ_EOT (8) - -// The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size) -// for the purpose of detection of the overrun. The location of the memory where the magic number -// resides shall never be written. In case it is written - the overrun occured and either recevie function -// or send function will stuck forever. -#define CC3000_BUFFER_MAGIC_NUMBER (0xDE) - -typedef struct { - gcSpiHandleRx SPIRxHandler; - unsigned short usTxPacketLength; - unsigned short usRxPacketLength; - unsigned long ulSpiState; - unsigned char *pTxPacket; - unsigned char *pRxPacket; -} tSpiInformation; -STATIC tSpiInformation sSpiInformation; - -STATIC char spi_buffer[CC3000_RX_BUFFER_SIZE]; -unsigned char wlan_tx_buffer[CC3000_TX_BUFFER_SIZE]; - -STATIC const mp_obj_fun_builtin_fixed_t irq_callback_obj; - -// set the pins to use to communicate with the CC3000 -// the arguments must be of type pin_obj_t* and SPI_HandleTypeDef* -void SpiInit(void *spi, const void *pin_cs, const void *pin_en, const void *pin_irq) { - SPI_HANDLE = spi; - PIN_CS = pin_cs; - PIN_EN = pin_en; - PIN_IRQ = pin_irq; -} - -void SpiClose(void) -{ - if (sSpiInformation.pRxPacket) { - sSpiInformation.pRxPacket = 0; - } - - tSLInformation.WlanInterruptDisable(); - - //HAL_SPI_DeInit(SPI_HANDLE); -} - -void SpiOpen(gcSpiHandleRx pfRxHandler) -{ - DEBUG_printf("SpiOpen\n"); - - /* initialize SPI state */ - sSpiInformation.ulSpiState = eSPI_STATE_POWERUP; - sSpiInformation.SPIRxHandler = pfRxHandler; - sSpiInformation.usTxPacketLength = 0; - sSpiInformation.pTxPacket = NULL; - sSpiInformation.pRxPacket = (unsigned char *)spi_buffer; - sSpiInformation.usRxPacketLength = 0; - spi_buffer[CC3000_RX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; - wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; - - /* SPI configuration */ - SPI_InitTypeDef *init = &SPI_HANDLE->spi->Init; - init->Mode = SPI_MODE_MASTER; - init->Direction = SPI_DIRECTION_2LINES; - init->DataSize = SPI_DATASIZE_8BIT; - init->CLKPolarity = SPI_POLARITY_LOW; - init->CLKPhase = SPI_PHASE_2EDGE; - init->NSS = SPI_NSS_SOFT; - init->BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; - init->FirstBit = SPI_FIRSTBIT_MSB; - init->TIMode = SPI_TIMODE_DISABLED; - init->CRCCalculation = SPI_CRCCALCULATION_DISABLED; - init->CRCPolynomial = 7; - spi_init(SPI_HANDLE, false); - - // configure wlan CS and EN pins - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.Speed = GPIO_SPEED_FAST; - GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStructure.Pull = GPIO_NOPULL; - GPIO_InitStructure.Alternate = 0; - - GPIO_InitStructure.Pin = PIN_CS->pin_mask; - HAL_GPIO_Init(PIN_CS->gpio, &GPIO_InitStructure); - - GPIO_InitStructure.Pin = PIN_EN->pin_mask; - HAL_GPIO_Init(PIN_EN->gpio, &GPIO_InitStructure); - - HAL_GPIO_WritePin(PIN_CS->gpio, PIN_CS->pin_mask, GPIO_PIN_SET); - HAL_GPIO_WritePin(PIN_EN->gpio, PIN_EN->pin_mask, GPIO_PIN_RESET); - - /* do a dummy read, this ensures SCLK is low before - actual communications start, it might be required */ - CS_LOW(); - uint8_t buf[1]; - HAL_SPI_Receive(SPI_HANDLE->spi, buf, sizeof(buf), SPI_TIMEOUT); - CS_HIGH(); - - // register EXTI - extint_register((mp_obj_t)PIN_IRQ, GPIO_MODE_IT_FALLING, GPIO_PULLUP, (mp_obj_t)&irq_callback_obj, true); - extint_enable(PIN_IRQ->pin); - - DEBUG_printf("SpiOpen finished; IRQ.pin=%d IRQ_LINE=%d\n", PIN_IRQ->pin, PIN_IRQ->pin); -} - -long ReadWlanInterruptPin(void) -{ - return HAL_GPIO_ReadPin(PIN_IRQ->gpio, PIN_IRQ->pin_mask); -} - -void WriteWlanPin(unsigned char val) -{ - HAL_GPIO_WritePin(PIN_EN->gpio, PIN_EN->pin_mask, - (WLAN_ENABLE)? GPIO_PIN_SET:GPIO_PIN_RESET); -} - -STATIC void SpiWriteDataSynchronous(unsigned char *data, unsigned short size) -{ - DEBUG_printf("SpiWriteDataSynchronous(data=%p [%x %x %x %x], size=%u)\n", data, data[0], data[1], data[2], data[3], size); - __disable_irq(); - if (HAL_SPI_TransmitReceive(SPI_HANDLE->spi, data, data, size, SPI_TIMEOUT) != HAL_OK) { - //BREAK(); - } - __enable_irq(); - DEBUG_printf(" - rx data = [%x %x %x %x]\n", data[0], data[1], data[2], data[3]); -} - -STATIC void SpiReadDataSynchronous(unsigned char *data, unsigned short size) -{ - memset(data, READ, size); - __disable_irq(); - if (HAL_SPI_TransmitReceive(SPI_HANDLE->spi, data, data, size, SPI_TIMEOUT) != HAL_OK) { - //BREAK(); - } - __enable_irq(); -} - -STATIC void __delay_cycles(volatile int x) -{ - x *= 6; // for 168 MHz CPU - while (x--); -} - -STATIC long SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength) -{ - DEBUG_printf("SpiFirstWrite %lu\n", sSpiInformation.ulSpiState); - - CS_LOW(); - - // Assuming we are running on 24 MHz ~50 micro delay is 1200 cycles; - __delay_cycles(1200); - - // SPI writes first 4 bytes of data - SpiWriteDataSynchronous(ucBuf, 4); - - __delay_cycles(1200); - - SpiWriteDataSynchronous(ucBuf + 4, usLength - 4); - - // From this point on - operate in a regular way - sSpiInformation.ulSpiState = eSPI_STATE_IDLE; - - CS_HIGH(); - - return(0); -} - -long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength) -{ - DEBUG_printf("SpiWrite %lu\n", sSpiInformation.ulSpiState); - - unsigned char ucPad = 0; - - // Figure out the total length of the packet in order to figure out if there - // is padding or not - if(!(usLength & 0x0001)) { - ucPad++; - } - - pUserBuffer[0] = WRITE; - pUserBuffer[1] = HI(usLength + ucPad); - pUserBuffer[2] = LO(usLength + ucPad); - pUserBuffer[3] = 0; - pUserBuffer[4] = 0; - - usLength += (SPI_HEADER_SIZE + ucPad); - - // The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size) - // for the purpose of detection of the overrun. If the magic number is overriten - buffer overrun - // occurred - and we will stuck here forever! - if (wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) { - while (1); - } - - if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP) { - while (sSpiInformation.ulSpiState != eSPI_STATE_INITIALIZED); - } - - if (sSpiInformation.ulSpiState == eSPI_STATE_INITIALIZED) { - // This is time for first TX/RX transactions over SPI: - // the IRQ is down - so need to send read buffer size command - SpiFirstWrite(pUserBuffer, usLength); - } else { - // - // We need to prevent here race that can occur in case 2 back to back packets are sent to the - // device, so the state will move to IDLE and once again to not IDLE due to IRQ - // - tSLInformation.WlanInterruptDisable(); - - while (sSpiInformation.ulSpiState != eSPI_STATE_IDLE); - - sSpiInformation.ulSpiState = eSPI_STATE_WRITE_IRQ; - sSpiInformation.pTxPacket = pUserBuffer; - sSpiInformation.usTxPacketLength = usLength; - - // Assert the CS line and wait till SSI IRQ line is active and then initialize write operation - CS_LOW(); - - // Re-enable IRQ - if it was not disabled - this is not a problem... - tSLInformation.WlanInterruptEnable(); - - // check for a missing interrupt between the CS assertion and enabling back the interrupts - if (tSLInformation.ReadWlanInterruptPin() == 0) { - SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength); - - sSpiInformation.ulSpiState = eSPI_STATE_IDLE; - - CS_HIGH(); - } - } - - // Due to the fact that we are currently implementing a blocking situation - // here we will wait till end of transaction - while (eSPI_STATE_IDLE != sSpiInformation.ulSpiState); - - return(0); -} - -#if 0 -unused -STATIC void SpiReadPacket(void) -{ - int length; - - /* read SPI header */ - SpiReadDataSynchronous(sSpiInformation.pRxPacket, SPI_HEADER_SIZE); - - /* parse data length */ - STREAM_TO_UINT8(sSpiInformation.pRxPacket, SPI_HEADER_SIZE-1, length); - - /* read the remainder of the packet */ - SpiReadDataSynchronous(sSpiInformation.pRxPacket + SPI_HEADER_SIZE, length); - - sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; -} -#endif - -STATIC void SpiReadHeader(void) -{ - SpiReadDataSynchronous(sSpiInformation.pRxPacket, 10); -} - -STATIC void SpiTriggerRxProcessing(void) -{ - SpiPauseSpi(); - CS_HIGH(); - - // The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size) - // for the purpose of detection of the overrun. If the magic number is overriten - buffer overrun - // occurred - and we will stuck here forever! - if (sSpiInformation.pRxPacket[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) { - while (1); - } - - sSpiInformation.ulSpiState = eSPI_STATE_IDLE; - sSpiInformation.SPIRxHandler(sSpiInformation.pRxPacket + SPI_HEADER_SIZE); -} - - -STATIC long SpiReadDataCont(void) -{ - long data_to_recv=0; - unsigned char *evnt_buff, type; - - //determine what type of packet we have - evnt_buff = sSpiInformation.pRxPacket; - STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_PACKET_TYPE_OFFSET, type); - - switch (type) { - case HCI_TYPE_DATA:{ - // We need to read the rest of data.. - STREAM_TO_UINT16((char *)(evnt_buff + SPI_HEADER_SIZE), - HCI_DATA_LENGTH_OFFSET, data_to_recv); - if (!((HEADERS_SIZE_EVNT + data_to_recv) & 1)) { - data_to_recv++; - } - - if (data_to_recv) { - SpiReadDataSynchronous(evnt_buff + 10, data_to_recv); - } - break; - } - case HCI_TYPE_EVNT: { - // Calculate the rest length of the data - STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), - HCI_EVENT_LENGTH_OFFSET, data_to_recv); - data_to_recv -= 1; - - // Add padding byte if needed - if ((HEADERS_SIZE_EVNT + data_to_recv) & 1) { - data_to_recv++; - } - - if (data_to_recv) { - SpiReadDataSynchronous(evnt_buff + 10, data_to_recv); - } - - sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; - break; - } - } - - return 0; -} - -STATIC void SSIContReadOperation(void) -{ - // The header was read - continue with the payload read - if (!SpiReadDataCont()) { - /* All the data was read - finalize handling by switching - to the task and calling from task Event Handler */ - SpiTriggerRxProcessing(); - } -} - -STATIC mp_obj_t irq_callback(mp_obj_t line) { - DEBUG_printf("<< IRQ; state=%lu >>\n", sSpiInformation.ulSpiState); - switch (sSpiInformation.ulSpiState) { - case eSPI_STATE_POWERUP: - /* This means IRQ line was low call a callback of HCI Layer to inform on event */ - DEBUG_printf(" - POWERUP\n"); - sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED; - break; - case eSPI_STATE_IDLE: - DEBUG_printf(" - IDLE\n"); - sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ; - - /* IRQ line goes down - we are start reception */ - CS_LOW(); - - // Wait for TX/RX Compete which will come as DMA interrupt - SpiReadHeader(); - - sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; - - SSIContReadOperation(); - break; - case eSPI_STATE_WRITE_IRQ: - DEBUG_printf(" - WRITE IRQ\n"); - SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength); - - sSpiInformation.ulSpiState = eSPI_STATE_IDLE; - - CS_HIGH(); - break; - } - return mp_const_none; -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_1(irq_callback_obj, irq_callback); - -void SpiPauseSpi(void) { - DEBUG_printf("SpiPauseSpi\n"); - extint_disable(PIN_IRQ->pin); -} - -void SpiResumeSpi(void) { - DEBUG_printf("SpiResumeSpi\n"); - extint_enable(PIN_IRQ->pin); -} diff --git a/drivers/cc3000/src/evnt_handler.c b/drivers/cc3000/src/evnt_handler.c deleted file mode 100644 index 80f34e469b2..00000000000 --- a/drivers/cc3000/src/evnt_handler.c +++ /dev/null @@ -1,849 +0,0 @@ -/***************************************************************************** -* -* evnt_handler.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ -//***************************************************************************** -// -//! \addtogroup evnt_handler_api -//! @{ -// -//****************************************************************************** - -//****************************************************************************** -// INCLUDE FILES -//****************************************************************************** - -#include "cc3000_common.h" -#include "string.h" -#include "hci.h" -#include "evnt_handler.h" -#include "wlan.h" -#include "socket.h" -#include "netapp.h" -#include "ccspi.h" - - - -//***************************************************************************** -// COMMON DEFINES -//***************************************************************************** - -#define FLOW_CONTROL_EVENT_HANDLE_OFFSET (0) -#define FLOW_CONTROL_EVENT_BLOCK_MODE_OFFSET (1) -#define FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET (2) -#define FLOW_CONTROL_EVENT_SIZE (4) - -#define BSD_RSP_PARAMS_SOCKET_OFFSET (0) -#define BSD_RSP_PARAMS_STATUS_OFFSET (4) - -#define GET_HOST_BY_NAME_RETVAL_OFFSET (0) -#define GET_HOST_BY_NAME_ADDR_OFFSET (4) - -#define ACCEPT_SD_OFFSET (0) -#define ACCEPT_RETURN_STATUS_OFFSET (4) -#define ACCEPT_ADDRESS__OFFSET (8) - -#define SL_RECEIVE_SD_OFFSET (0) -#define SL_RECEIVE_NUM_BYTES_OFFSET (4) -#define SL_RECEIVE__FLAGS__OFFSET (8) - - -#define SELECT_STATUS_OFFSET (0) -#define SELECT_READFD_OFFSET (4) -#define SELECT_WRITEFD_OFFSET (8) -#define SELECT_EXFD_OFFSET (12) - - -#define NETAPP_IPCONFIG_IP_OFFSET (0) -#define NETAPP_IPCONFIG_SUBNET_OFFSET (4) -#define NETAPP_IPCONFIG_GW_OFFSET (8) -#define NETAPP_IPCONFIG_DHCP_OFFSET (12) -#define NETAPP_IPCONFIG_DNS_OFFSET (16) -#define NETAPP_IPCONFIG_MAC_OFFSET (20) -#define NETAPP_IPCONFIG_SSID_OFFSET (26) - -#define NETAPP_IPCONFIG_IP_LENGTH (4) -#define NETAPP_IPCONFIG_MAC_LENGTH (6) -#define NETAPP_IPCONFIG_SSID_LENGTH (32) - - -#define NETAPP_PING_PACKETS_SENT_OFFSET (0) -#define NETAPP_PING_PACKETS_RCVD_OFFSET (4) -#define NETAPP_PING_MIN_RTT_OFFSET (8) -#define NETAPP_PING_MAX_RTT_OFFSET (12) -#define NETAPP_PING_AVG_RTT_OFFSET (16) - -#define GET_SCAN_RESULTS_TABlE_COUNT_OFFSET (0) -#define GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET (4) -#define GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET (8) -#define GET_SCAN_RESULTS_FRAME_TIME_OFFSET (10) -#define GET_SCAN_RESULTS_SSID_MAC_LENGTH (38) - -#define GET_MSS_VAL_RETVAL_OFFSET (0) - -//***************************************************************************** -// GLOBAL VARAIABLES -//***************************************************************************** - -UINT32 socket_active_status = SOCKET_STATUS_INIT_VAL; - - -//***************************************************************************** -// Prototypes for the static functions -//***************************************************************************** - -static INT32 hci_event_unsol_flowcontrol_handler(CHAR *pEvent); - -static void update_socket_active_status(CHAR *resp_params); - - -//***************************************************************************** -// -//! hci_unsol_handle_patch_request -//! -//! @param event_hdr event header -//! -//! @return none -//! -//! @brief Handle unsolicited event from type patch request -// -//***************************************************************************** -void hci_unsol_handle_patch_request(CHAR *event_hdr) -{ - CHAR *params = (CHAR *)(event_hdr) + HCI_EVENT_HEADER_SIZE; - UINT32 ucLength = 0; - CHAR *patch; - - switch (*params) - { - case HCI_EVENT_PATCHES_DRV_REQ: - - if (tSLInformation.sDriverPatches) - { - patch = tSLInformation.sDriverPatches(&ucLength); - - if (patch) - { - hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ, - tSLInformation.pucTxCommandBuffer, patch, ucLength); - return; - } - } - - // Send 0 length Patches response event - hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ, - tSLInformation.pucTxCommandBuffer, 0, 0); - break; - - case HCI_EVENT_PATCHES_FW_REQ: - - if (tSLInformation.sFWPatches) - { - patch = tSLInformation.sFWPatches(&ucLength); - - // Build and send a patch - if (patch) - { - hci_patch_send(HCI_EVENT_PATCHES_FW_REQ, - tSLInformation.pucTxCommandBuffer, patch, ucLength); - return; - } - } - - // Send 0 length Patches response event - hci_patch_send(HCI_EVENT_PATCHES_FW_REQ, - tSLInformation.pucTxCommandBuffer, 0, 0); - break; - - case HCI_EVENT_PATCHES_BOOTLOAD_REQ: - - if (tSLInformation.sBootLoaderPatches) - { - patch = tSLInformation.sBootLoaderPatches(&ucLength); - - if (patch) - { - hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, - tSLInformation.pucTxCommandBuffer, patch, ucLength); - return; - } - } - - // Send 0 length Patches response event - hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, - tSLInformation.pucTxCommandBuffer, 0, 0); - break; - } -} - - - -//***************************************************************************** -// -//! hci_event_handler -//! -//! @param pRetParams incoming data buffer -//! @param from from information (in case of data received) -//! @param fromlen from information length (in case of data received) -//! -//! @return none -//! -//! @brief Parse the incoming events packets and issues corresponding -//! event handler from global array of handlers pointers -// -//***************************************************************************** - - -UINT8 * hci_event_handler(void *pRetParams, UINT8 *from, UINT8 *fromlen) -{ - UINT8 *pucReceivedData, ucArgsize; - UINT16 usLength; - UINT8 *pucReceivedParams; - UINT16 usReceivedEventOpcode = 0; - UINT32 retValue32; - UINT8 * RecvParams; - UINT8 *RetParams; - - - while (1) - { - if (tSLInformation.usEventOrDataReceived != 0) - { - pucReceivedData = (tSLInformation.pucReceivedData); - - if (*pucReceivedData == HCI_TYPE_EVNT) - { - // Event Received - STREAM_TO_UINT16((CHAR *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET, - usReceivedEventOpcode); - pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE; - RecvParams = pucReceivedParams; - RetParams = pRetParams; - - // In case unsolicited event received - here the handling finished - if (hci_unsol_event_handler((CHAR *)pucReceivedData) == 0) - { - STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength); - - switch(usReceivedEventOpcode) - { - case HCI_CMND_READ_BUFFER_SIZE: - { - STREAM_TO_UINT8((CHAR *)pucReceivedParams, 0, - tSLInformation.usNumberOfFreeBuffers); - STREAM_TO_UINT16((CHAR *)pucReceivedParams, 1, - tSLInformation.usSlBufferLength); - } - break; - - case HCI_CMND_WLAN_CONFIGURE_PATCH: - case HCI_NETAPP_DHCP: - case HCI_NETAPP_PING_SEND: - case HCI_NETAPP_PING_STOP: - case HCI_NETAPP_ARP_FLUSH: - case HCI_NETAPP_SET_DEBUG_LEVEL: - case HCI_NETAPP_SET_TIMERS: - case HCI_EVNT_NVMEM_READ: - case HCI_EVNT_NVMEM_CREATE_ENTRY: - case HCI_CMND_NVMEM_WRITE_PATCH: - case HCI_NETAPP_PING_REPORT: - case HCI_EVNT_MDNS_ADVERTISE: - - STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET - ,*(UINT8 *)pRetParams); - break; - - case HCI_CMND_SETSOCKOPT: - case HCI_CMND_WLAN_CONNECT: - case HCI_CMND_WLAN_IOCTL_STATUSGET: - case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: - case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: - case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: - case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: - case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: - case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: - case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: - case HCI_CMND_EVENT_MASK: - case HCI_EVNT_WLAN_DISCONNECT: - case HCI_EVNT_SOCKET: - case HCI_EVNT_BIND: - case HCI_CMND_LISTEN: - case HCI_EVNT_CLOSE_SOCKET: - case HCI_EVNT_CONNECT: - case HCI_EVNT_NVMEM_WRITE: - - STREAM_TO_UINT32((CHAR *)pucReceivedParams,0 - ,*(UINT32 *)pRetParams); - break; - - case HCI_EVNT_READ_SP_VERSION: - - STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET - ,*(UINT8 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 1; - STREAM_TO_UINT32((CHAR *)pucReceivedParams, 0, retValue32); - UINT32_TO_STREAM((UINT8 *)pRetParams, retValue32); - break; - - case HCI_EVNT_BSD_GETHOSTBYNAME: - - STREAM_TO_UINT32((CHAR *)pucReceivedParams - ,GET_HOST_BY_NAME_RETVAL_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams - ,GET_HOST_BY_NAME_ADDR_OFFSET,*(UINT32 *)pRetParams); - break; - - case HCI_EVNT_GETMSSVALUE: - - STREAM_TO_UINT16((CHAR *)pucReceivedParams - ,GET_MSS_VAL_RETVAL_OFFSET,*(UINT16 *)pRetParams); - - break; - - case HCI_EVNT_ACCEPT: - { - STREAM_TO_UINT32((CHAR *)pucReceivedParams,ACCEPT_SD_OFFSET - ,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams - ,ACCEPT_RETURN_STATUS_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - - //This argument returns in network order - memcpy((UINT8 *)pRetParams, - pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr)); - break; - } - - case HCI_EVNT_RECV: - case HCI_EVNT_RECVFROM: - { - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(UINT32 *)pRetParams); - - if(((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE) - { - set_socket_active_status(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE); - } - break; - } - - case HCI_EVNT_SEND: - case HCI_EVNT_SENDTO: - { - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - - break; - } - - case HCI_EVNT_SELECT: - { - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SELECT_STATUS_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SELECT_READFD_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams,SELECT_EXFD_OFFSET,*(UINT32 *)pRetParams); - break; - } - - case HCI_CMND_GETSOCKOPT: - - STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)pRetParams)->iStatus); - //This argument returns in network order - memcpy((UINT8 *)pRetParams, pucReceivedParams, 4); - break; - - case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: - - STREAM_TO_UINT32((CHAR *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT32((CHAR *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 4; - STREAM_TO_UINT16((CHAR *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 2; - STREAM_TO_UINT16((CHAR *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(UINT32 *)pRetParams); - pRetParams = ((CHAR *)pRetParams) + 2; - memcpy((UINT8 *)pRetParams, (CHAR *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH); - break; - - case HCI_CMND_SIMPLE_LINK_START: - break; - - case HCI_NETAPP_IPCONFIG: - - //Read IP address - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read subnet - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read default GW - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read DHCP server - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read DNS server - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read Mac address - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH); - RecvParams += 6; - - //Read SSID - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH); - - } - } - - if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode) - { - tSLInformation.usRxEventOpcode = 0; - } - } - else - { - pucReceivedParams = pucReceivedData; - STREAM_TO_UINT8((CHAR *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize); - - STREAM_TO_UINT16((CHAR *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength); - - // Data received: note that the only case where from and from length - // are not null is in recv from, so fill the args accordingly - if (from) - { - STREAM_TO_UINT32((CHAR *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(UINT32 *)fromlen); - memcpy(from, (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen); - } - - memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize, - usLength - ucArgsize); - - tSLInformation.usRxDataPending = 0; - } - - tSLInformation.usEventOrDataReceived = 0; - - SpiResumeSpi(); - - // Since we are going to TX - we need to handle this event after the - // ResumeSPi since we need interrupts - if ((*pucReceivedData == HCI_TYPE_EVNT) && - (usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ)) - { - hci_unsol_handle_patch_request((CHAR *)pucReceivedData); - } - - if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0)) - { - return NULL; - } - } - } - -} - -//***************************************************************************** -// -//! hci_unsol_event_handler -//! -//! @param event_hdr event header -//! -//! @return 1 if event supported and handled -//! 0 if event is not supported -//! -//! @brief Handle unsolicited events -// -//***************************************************************************** -INT32 hci_unsol_event_handler(CHAR *event_hdr) -{ - CHAR * data = NULL; - INT32 event_type; - UINT32 NumberOfReleasedPackets; - UINT32 NumberOfSentPackets; - - STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type); - - if (event_type & HCI_EVNT_UNSOL_BASE) - { - switch(event_type) - { - - case HCI_EVNT_DATA_UNSOL_FREE_BUFF: - { - hci_event_unsol_flowcontrol_handler(event_hdr); - - NumberOfReleasedPackets = tSLInformation.NumberOfReleasedPackets; - NumberOfSentPackets = tSLInformation.NumberOfSentPackets; - - if (NumberOfReleasedPackets == NumberOfSentPackets) - { - if (tSLInformation.InformHostOnTxComplete) - { - tSLInformation.sWlanCB(HCI_EVENT_CC3000_CAN_SHUT_DOWN, NULL, 0); - } - } - return 1; - - } - } - } - - if(event_type & HCI_EVNT_WLAN_UNSOL_BASE) - { - switch(event_type) - { - case HCI_EVNT_WLAN_KEEPALIVE: - case HCI_EVNT_WLAN_UNSOL_CONNECT: - case HCI_EVNT_WLAN_UNSOL_DISCONNECT: - case HCI_EVNT_WLAN_UNSOL_INIT: - case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE: - - if( tSLInformation.sWlanCB ) - { - tSLInformation.sWlanCB(event_type, 0, 0); - } - break; - - case HCI_EVNT_WLAN_UNSOL_DHCP: - { - UINT8 params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status - UINT8 *recParams = params; - - data = (CHAR*)(event_hdr) + HCI_EVENT_HEADER_SIZE; - - //Read IP address - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - data += 4; - //Read subnet - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - data += 4; - //Read default GW - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - data += 4; - //Read DHCP server - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - data += 4; - //Read DNS server - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - // read the status - STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, *recParams); - - - if( tSLInformation.sWlanCB ) - { - tSLInformation.sWlanCB(event_type, (CHAR *)params, sizeof(params)); - } - } - break; - - case HCI_EVNT_WLAN_ASYNC_PING_REPORT: - { - netapp_pingreport_args_t params; - data = (CHAR*)(event_hdr) + HCI_EVENT_HEADER_SIZE; - STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent); - STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received); - STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time); - STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time); - STREAM_TO_UINT32(data, NETAPP_PING_AVG_RTT_OFFSET, params.avg_round_time); - - if( tSLInformation.sWlanCB ) - { - tSLInformation.sWlanCB(event_type, (CHAR *)¶ms, sizeof(params)); - } - } - break; - case HCI_EVNT_BSD_TCP_CLOSE_WAIT: - { - data = (CHAR *)(event_hdr) + HCI_EVENT_HEADER_SIZE; - if( tSLInformation.sWlanCB ) - { - //data[0] represents the socket id, for which FIN was received by remote. - //Upon receiving this event, the user can close the socket, or else the - //socket will be closded after inacvitity timeout (by default 60 seconds) - tSLInformation.sWlanCB(event_type, data, 1); - } - } - break; - - //'default' case which means "event not supported" - default: - return (0); - } - return(1); - } - - if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO) - || (event_type == HCI_EVNT_WRITE)) - { - CHAR *pArg; - INT32 status; - - pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr); - STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status); - - if (ERROR_SOCKET_INACTIVE == status) - { - // The only synchronous event that can come from SL device in form of - // command complete is "Command Complete" on data sent, in case SL device - // was unable to transmit - STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, tSLInformation.slTransmitDataError); - update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr)); - - return (1); - } - else - return (0); - } - - //handle a case where unsolicited event arrived, but was not handled by any of the cases above - if ((event_type != tSLInformation.usRxEventOpcode) && (event_type != HCI_EVNT_PATCHES_REQ)) - { - return(1); - } - - return(0); -} - -//***************************************************************************** -// -//! hci_unsolicited_event_handler -//! -//! @param None -//! -//! @return ESUCCESS if successful, EFAIL if an error occurred -//! -//! @brief Parse the incoming unsolicited event packets and issues -//! corresponding event handler. -// -//***************************************************************************** -INT32 hci_unsolicited_event_handler(void) -{ - UINT32 res = 0; - UINT8 *pucReceivedData; - - if (tSLInformation.usEventOrDataReceived != 0) - { - pucReceivedData = (tSLInformation.pucReceivedData); - - if (*pucReceivedData == HCI_TYPE_EVNT) - { - - // In case unsolicited event received - here the handling finished - if (hci_unsol_event_handler((CHAR *)pucReceivedData) == 1) - { - - // There was an unsolicited event received - we can release the buffer - // and clean the event received - tSLInformation.usEventOrDataReceived = 0; - - res = 1; - SpiResumeSpi(); - } - } - } - - return res; -} - -//***************************************************************************** -// -//! set_socket_active_status -//! -//! @param Sd -//! @param Status -//! @return none -//! -//! @brief Check if the socket ID and status are valid and set -//! accordingly the global socket status -// -//***************************************************************************** -void set_socket_active_status(INT32 Sd, INT32 Status) -{ - if(M_IS_VALID_SD(Sd) && M_IS_VALID_STATUS(Status)) - { - socket_active_status &= ~(1 << Sd); /* clean socket's mask */ - socket_active_status |= (Status << Sd); /* set new socket's mask */ - } -} - - -//***************************************************************************** -// -//! hci_event_unsol_flowcontrol_handler -//! -//! @param pEvent pointer to the string contains parameters for IPERF -//! @return ESUCCESS if successful, EFAIL if an error occurred -//! -//! @brief Called in case unsolicited event from type -//! HCI_EVNT_DATA_UNSOL_FREE_BUFF has received. -//! Keep track on the number of packets transmitted and update the -//! number of free buffer in the SL device. -// -//***************************************************************************** -INT32 hci_event_unsol_flowcontrol_handler(CHAR *pEvent) -{ - - INT32 temp, value; - UINT16 i; - UINT16 pusNumberOfHandles=0; - CHAR *pReadPayload; - - STREAM_TO_UINT16((CHAR *)pEvent,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles); - pReadPayload = ((CHAR *)pEvent + - HCI_EVENT_HEADER_SIZE + sizeof(pusNumberOfHandles)); - temp = 0; - - for(i = 0; i < pusNumberOfHandles ; i++) - { - STREAM_TO_UINT16(pReadPayload, FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET, value); - temp += value; - pReadPayload += FLOW_CONTROL_EVENT_SIZE; - } - - tSLInformation.usNumberOfFreeBuffers += temp; - tSLInformation.NumberOfReleasedPackets += temp; - - return(ESUCCESS); -} - -//***************************************************************************** -// -//! get_socket_active_status -//! -//! @param Sd Socket IS -//! @return Current status of the socket. -//! -//! @brief Retrieve socket status -// -//***************************************************************************** - -INT32 get_socket_active_status(INT32 Sd) -{ - if(M_IS_VALID_SD(Sd)) - { - return (socket_active_status & (1 << Sd)) ? SOCKET_STATUS_INACTIVE : SOCKET_STATUS_ACTIVE; - } - return SOCKET_STATUS_INACTIVE; -} - -//***************************************************************************** -// -//! update_socket_active_status -//! -//! @param resp_params Socket IS -//! @return Current status of the socket. -//! -//! @brief Retrieve socket status -// -//***************************************************************************** -void update_socket_active_status(CHAR *resp_params) -{ - INT32 status, sd; - - STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET,sd); - STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET,status); - - if(ERROR_SOCKET_INACTIVE == status) - { - set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); - } -} - - -//***************************************************************************** -// -//! SimpleLinkWaitEvent -//! -//! @param usOpcode command operation code -//! @param pRetParams command return parameters -//! -//! @return none -//! -//! @brief Wait for event, pass it to the hci_event_handler and -//! update the event opcode in a global variable. -// -//***************************************************************************** - -void SimpleLinkWaitEvent(UINT16 usOpcode, void *pRetParams) -{ - // In the blocking implementation the control to caller will be returned only - // after the end of current transaction - tSLInformation.usRxEventOpcode = usOpcode; - hci_event_handler(pRetParams, 0, 0); -} - -//***************************************************************************** -// -//! SimpleLinkWaitData -//! -//! @param pBuf data buffer -//! @param from from information -//! @param fromlen from information length -//! -//! @return none -//! -//! @brief Wait for data, pass it to the hci_event_handler -//! and update in a global variable that there is -//! data to read. -// -//***************************************************************************** - -void SimpleLinkWaitData(UINT8 *pBuf, UINT8 *from, UINT8 *fromlen) -{ - // In the blocking implementation the control to caller will be returned only - // after the end of current transaction, i.e. only after data will be received - tSLInformation.usRxDataPending = 1; - hci_event_handler(pBuf, from, fromlen); -} - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** diff --git a/drivers/cc3000/src/hci.c b/drivers/cc3000/src/hci.c deleted file mode 100644 index 4391692b8bc..00000000000 --- a/drivers/cc3000/src/hci.c +++ /dev/null @@ -1,225 +0,0 @@ -/***************************************************************************** -* -* hci.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - -//***************************************************************************** -// -//! \addtogroup hci_app -//! @{ -// -//***************************************************************************** - -#include -#include "cc3000_common.h" -#include "hci.h" -#include "ccspi.h" -#include "evnt_handler.h" -#include "wlan.h" - -#define SL_PATCH_PORTION_SIZE (1000) - - -//***************************************************************************** -// -//! hci_command_send -//! -//! @param usOpcode command operation code -//! @param pucBuff pointer to the command's arguments buffer -//! @param ucArgsLength length of the arguments -//! -//! @return none -//! -//! @brief Initiate an HCI command. -// -//***************************************************************************** -UINT16 hci_command_send(UINT16 usOpcode, UINT8 *pucBuff, UINT8 ucArgsLength) -{ - UINT8 *stream; - - stream = (pucBuff + SPI_HEADER_SIZE); - - UINT8_TO_STREAM(stream, HCI_TYPE_CMND); - stream = UINT16_TO_STREAM(stream, usOpcode); - UINT8_TO_STREAM(stream, ucArgsLength); - - //Update the opcode of the event we will be waiting for - SpiWrite(pucBuff, ucArgsLength + SIMPLE_LINK_HCI_CMND_HEADER_SIZE); - - return(0); -} - -//***************************************************************************** -// -//! hci_data_send -//! -//! @param usOpcode command operation code -//! @param ucArgs pointer to the command's arguments buffer -//! @param usArgsLength length of the arguments -//! @param ucTail pointer to the data buffer -//! @param usTailLength buffer length -//! -//! @return none -//! -//! @brief Initiate an HCI data write operation -// -//***************************************************************************** -INT32 hci_data_send(UINT8 ucOpcode, - UINT8 *ucArgs, - UINT16 usArgsLength, - UINT16 usDataLength, - const UINT8 *ucTail, - UINT16 usTailLength) -{ - UINT8 *stream; - - stream = ((ucArgs) + SPI_HEADER_SIZE); - - UINT8_TO_STREAM(stream, HCI_TYPE_DATA); - UINT8_TO_STREAM(stream, ucOpcode); - UINT8_TO_STREAM(stream, usArgsLength); - stream = UINT16_TO_STREAM(stream, usArgsLength + usDataLength + usTailLength); - - // Send the packet over the SPI - SpiWrite(ucArgs, SIMPLE_LINK_HCI_DATA_HEADER_SIZE + usArgsLength + usDataLength + usTailLength); - - return(ESUCCESS); -} - - -//***************************************************************************** -// -//! hci_data_command_send -//! -//! @param usOpcode command operation code -//! @param pucBuff pointer to the data buffer -//! @param ucArgsLength arguments length -//! @param ucDataLength data length -//! -//! @return none -//! -//! @brief Prepeare HCI header and initiate an HCI data write operation -// -//***************************************************************************** -void hci_data_command_send(UINT16 usOpcode, UINT8 *pucBuff, UINT8 ucArgsLength,UINT16 ucDataLength) -{ - UINT8 *stream = (pucBuff + SPI_HEADER_SIZE); - - UINT8_TO_STREAM(stream, HCI_TYPE_DATA); - UINT8_TO_STREAM(stream, usOpcode); - UINT8_TO_STREAM(stream, ucArgsLength); - stream = UINT16_TO_STREAM(stream, ucArgsLength + ucDataLength); - - // Send the command over SPI on data channel - SpiWrite(pucBuff, ucArgsLength + ucDataLength + SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE); - - return; -} - -//***************************************************************************** -// -//! hci_patch_send -//! -//! @param usOpcode command operation code -//! @param pucBuff pointer to the command's arguments buffer -//! @param patch pointer to patch content buffer -//! @param usDataLength data length -//! -//! @return none -//! -//! @brief Prepeare HCI header and initiate an HCI patch write operation -// -//***************************************************************************** -void hci_patch_send(UINT8 ucOpcode, UINT8 *pucBuff, CHAR *patch, UINT16 usDataLength) -{ - UINT8 *data_ptr = (pucBuff + SPI_HEADER_SIZE); - UINT16 usTransLength; - UINT8 *stream = (pucBuff + SPI_HEADER_SIZE); - - UINT8_TO_STREAM(stream, HCI_TYPE_PATCH); - UINT8_TO_STREAM(stream, ucOpcode); - stream = UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); - - if (usDataLength <= SL_PATCH_PORTION_SIZE) - { - UINT16_TO_STREAM(stream, usDataLength); - stream = UINT16_TO_STREAM(stream, usDataLength); - memcpy((pucBuff + SPI_HEADER_SIZE) + HCI_PATCH_HEADER_SIZE, patch, usDataLength); - - // Update the opcode of the event we will be waiting for - SpiWrite(pucBuff, usDataLength + HCI_PATCH_HEADER_SIZE); - } - else - { - - usTransLength = (usDataLength/SL_PATCH_PORTION_SIZE); - UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE + usTransLength*SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); - stream = UINT16_TO_STREAM(stream, SL_PATCH_PORTION_SIZE); - memcpy(pucBuff + SPI_HEADER_SIZE + HCI_PATCH_HEADER_SIZE, patch, SL_PATCH_PORTION_SIZE); - usDataLength -= SL_PATCH_PORTION_SIZE; - patch += SL_PATCH_PORTION_SIZE; - - // Update the opcode of the event we will be waiting for - SpiWrite(pucBuff, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE); - - while (usDataLength) - { - if (usDataLength <= SL_PATCH_PORTION_SIZE) - { - usTransLength = usDataLength; - usDataLength = 0; - - } - else - { - usTransLength = SL_PATCH_PORTION_SIZE; - usDataLength -= usTransLength; - } - - *(UINT16 *)data_ptr = usTransLength; - memcpy(data_ptr + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE, patch, usTransLength); - patch += usTransLength; - - // Update the opcode of the event we will be waiting for - SpiWrite((UINT8 *)data_ptr, usTransLength + sizeof(usTransLength)); - } - } -} - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -// -//***************************************************************************** diff --git a/drivers/cc3000/src/inet_ntop.c b/drivers/cc3000/src/inet_ntop.c deleted file mode 100644 index 83242efa00b..00000000000 --- a/drivers/cc3000/src/inet_ntop.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 1996-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING - * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include "cc3000_common.h" -#include "socket.h" -#include "inet_ntop.h" - -// We can't include stdio.h because it defines _types_fd_set, but we -// need to use the CC3000 version of this type. So we must provide -// our own declaration of snprintf. Grrr. -int snprintf(char *str, size_t size, const char *fmt, ...); - -#define IN6ADDRSZ 16 -#define INADDRSZ 4 -#define INT16SZ 2 - -#define ENOSPC (28) -#define EAFNOSUPPORT (106) -#define SET_ERRNO(err) (CC3000_EXPORT(errno)=-err) - -/* - * Format an IPv4 address, more or less like inet_ntoa(). - * - * Returns `dst' (as a const) - * Note: - * - uses no statics - * - takes a unsigned char* not an in_addr as input - */ -static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size) -{ - size_t len; - char tmp[sizeof "255.255.255.255"]; - - tmp[0] = '\0'; - (void)snprintf(tmp, sizeof(tmp), "%d.%d.%d.%d", - ((int)((unsigned char)src[3])) & 0xff, - ((int)((unsigned char)src[2])) & 0xff, - ((int)((unsigned char)src[1])) & 0xff, - ((int)((unsigned char)src[0])) & 0xff); - - len = strlen(tmp); - if(len == 0 || len >= size) - { - SET_ERRNO(ENOSPC); - return (NULL); - } - strcpy(dst, tmp); - return dst; -} - -#ifdef ENABLE_IPV6 -/* - * Convert IPv6 binary address into presentation (printable) format. - */ -static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size) -{ - /* - * Note that int32_t and int16_t need only be "at least" large enough - * to contain a value of the specified size. On some systems, like - * Crays, there is no such thing as an integer variable with 16 bits. - * Keep this in mind if you think this function should have been coded - * to use pointer overlays. All the world's not a VAX. - */ - char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; - char *tp; - struct { - long base; - long len; - } best, cur; - unsigned long words[IN6ADDRSZ / INT16SZ]; - int i; - - /* Preprocess: - * Copy the input (bytewise) array into a wordwise array. - * Find the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, '\0', sizeof(words)); - for (i = 0; i < IN6ADDRSZ; i++) - words[i/2] |= (src[i] << ((1 - (i % 2)) << 3)); - - best.base = -1; - cur.base = -1; - best.len = 0; - cur.len = 0; - - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) - { - if(words[i] == 0) - { - if(cur.base == -1) - cur.base = i, cur.len = 1; - else - cur.len++; - } - else if(cur.base != -1) - { - if(best.base == -1 || cur.len > best.len) - best = cur; - cur.base = -1; - } - } - if((cur.base != -1) && (best.base == -1 || cur.len > best.len)) - best = cur; - if(best.base != -1 && best.len < 2) - best.base = -1; - - /* Format the result. - */ - tp = tmp; - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) - { - /* Are we inside the best run of 0x00's? - */ - if(best.base != -1 && i >= best.base && i < (best.base + best.len)) - { - if(i == best.base) - *tp++ = ':'; - continue; - } - - /* Are we following an initial run of 0x00s or any real hex? - */ - if(i != 0) - *tp++ = ':'; - - /* Is this address an encapsulated IPv4? - */ - if(i == 6 && best.base == 0 && - (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) - { - if(!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp))) - { - SET_ERRNO(ENOSPC); - return (NULL); - } - tp += strlen(tp); - break; - } - tp += snprintf(tp, 5, "%lx", words[i]); - } - - /* Was it a trailing run of 0x00's? - */ - if(best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) - *tp++ = ':'; - *tp++ = '\0'; - - /* Check for overflow, copy, and we're done. - */ - if((size_t)(tp - tmp) > size) - { - SET_ERRNO(ENOSPC); - return (NULL); - } - strcpy(dst, tmp); - return dst; -} -#endif /* ENABLE_IPV6 */ - -/* - * Convert a network format address to presentation format. - * - * Returns pointer to presentation format address (`buf'). - * Returns NULL on error and errno set with the specific - * error, EAFNOSUPPORT or ENOSPC. - * - * On Windows we store the error in the thread errno, not - * in the winsock error code. This is to avoid loosing the - * actual last winsock error. So use macro ERRNO to fetch the - * errno this funtion sets when returning NULL, not SOCKERRNO. - */ -char *inet_ntop(int af, const void *src, char *buf, size_t size) -{ - switch (af) { - case AF_INET: - return inet_ntop4((const unsigned char*)src, buf, size); -#ifdef ENABLE_IPV6 - case AF_INET6: - return inet_ntop6((const unsigned char*)src, buf, size); -#endif - default: - SET_ERRNO(EAFNOSUPPORT); - return NULL; - } -} diff --git a/drivers/cc3000/src/inet_pton.c b/drivers/cc3000/src/inet_pton.c deleted file mode 100644 index 5f5ae5f9d7f..00000000000 --- a/drivers/cc3000/src/inet_pton.c +++ /dev/null @@ -1,216 +0,0 @@ -/* This is from the BIND 4.9.4 release, modified to compile by itself */ - -/* Copyright (c) 1996 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include -#include "cc3000_common.h" -#include "socket.h" -#include "inet_pton.h" - -#define IN6ADDRSZ 16 -#define INADDRSZ 4 -#define INT16SZ 2 - -static int inet_pton4(const char *src, unsigned char *dst); -#ifdef ENABLE_IPV6 -static int inet_pton6(const char *src, unsigned char *dst); -#endif - -#define EAFNOSUPPORT (106) -#define SET_ERRNO(err) (CC3000_EXPORT(errno)=-err) - -/* int - * inet_pton(af, src, dst) - * convert from presentation format (which usually means ASCII printable) - * to network format (which is usually some kind of binary format). - * return: - * 1 if the address was valid for the specified address family - * 0 if the address wasn't valid (`dst' is untouched in this case) - * -1 if some other error occurred (`dst' is untouched in this case, too) - * notice: - * On Windows we store the error in the thread errno, not - * in the winsock error code. This is to avoid loosing the - * actual last winsock error. So use macro ERRNO to fetch the - * errno this funtion sets when returning (-1), not SOCKERRNO. - * author: - * Paul Vixie, 1996. - */ -int inet_pton(int af, const char *src, void *dst) -{ - switch (af) { - case AF_INET: - return (inet_pton4(src, (unsigned char *)dst)); -#ifdef ENABLE_IPV6 - case AF_INET6: - return (inet_pton6(src, (unsigned char *)dst)); -#endif - default: - SET_ERRNO(EAFNOSUPPORT); - return (-1); - } - /* NOTREACHED */ -} - -/* int - * inet_pton4(src, dst) - * like inet_aton() but without all the hexadecimal and shorthand. - * return: - * 1 if `src' is a valid dotted quad, else 0. - * notice: - * does not touch `dst' unless it's returning 1. - * author: - * Paul Vixie, 1996. - */ -static int inet_pton4(const char *src, unsigned char *dst) -{ - static const char digits[] = "0123456789"; - int saw_digit, octets, ch; - unsigned char tmp[INADDRSZ], *tp; - - saw_digit = 0; - octets = 0; - tp = tmp; - *tp = 0; - while((ch = *src++) != '\0') { - const char *pch; - - if((pch = strchr(digits, ch)) != NULL) { - unsigned int val = *tp * 10 + (unsigned int)(pch - digits); - - if(saw_digit && *tp == 0) - return (0); - if(val > 255) - return (0); - *tp = (unsigned char)val; - if(! saw_digit) { - if(++octets > 4) - return (0); - saw_digit = 1; - } - } - else if(ch == '.' && saw_digit) { - if(octets == 4) - return (0); - *++tp = 0; - saw_digit = 0; - } - else - return (0); - } - if(octets < 4) - return (0); - memcpy(dst, tmp, INADDRSZ); - return (1); -} - -#ifdef ENABLE_IPV6 -/* int - * inet_pton6(src, dst) - * convert presentation level address to network order binary form. - * return: - * 1 if `src' is a valid [RFC1884 2.2] address, else 0. - * notice: - * (1) does not touch `dst' unless it's returning 1. - * (2) :: in a full address is silently ignored. - * credit: - * inspired by Mark Andrews. - * author: - * Paul Vixie, 1996. - */ -static int inet_pton6(const char *src, unsigned char *dst) -{ - static const char xdigits_l[] = "0123456789abcdef", - xdigits_u[] = "0123456789ABCDEF"; - unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp; - const char *xdigits, *curtok; - int ch, saw_xdigit; - unsigned int val; - - memset((tp = tmp), 0, IN6ADDRSZ); - endp = tp + IN6ADDRSZ; - colonp = NULL; - /* Leading :: requires some special handling. */ - if(*src == ':') - if(*++src != ':') - return (0); - curtok = src; - saw_xdigit = 0; - val = 0; - while((ch = *src++) != '\0') { - const char *pch; - - if((pch = strchr((xdigits = xdigits_l), ch)) == NULL) - pch = strchr((xdigits = xdigits_u), ch); - if(pch != NULL) { - val <<= 4; - val |= (pch - xdigits); - if(++saw_xdigit > 4) - return (0); - continue; - } - if(ch == ':') { - curtok = src; - if(!saw_xdigit) { - if(colonp) - return (0); - colonp = tp; - continue; - } - if(tp + INT16SZ > endp) - return (0); - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - saw_xdigit = 0; - val = 0; - continue; - } - if(ch == '.' && ((tp + INADDRSZ) <= endp) && - inet_pton4(curtok, tp) > 0) { - tp += INADDRSZ; - saw_xdigit = 0; - break; /* '\0' was seen by inet_pton4(). */ - } - return (0); - } - if(saw_xdigit) { - if(tp + INT16SZ > endp) - return (0); - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - } - if(colonp != NULL) { - /* - * Since some memmove()'s erroneously fail to handle - * overlapping regions, we'll do the shift by hand. - */ - const long n = tp - colonp; - long i; - - if(tp == endp) - return (0); - for (i = 1; i <= n; i++) { - endp[- i] = colonp[n - i]; - colonp[n - i] = 0; - } - tp = endp; - } - if(tp != endp) - return (0); - memcpy(dst, tmp, IN6ADDRSZ); - return (1); -} -#endif /* ENABLE_IPV6 */ diff --git a/drivers/cc3000/src/netapp.c b/drivers/cc3000/src/netapp.c deleted file mode 100644 index a6f60feda0d..00000000000 --- a/drivers/cc3000/src/netapp.c +++ /dev/null @@ -1,459 +0,0 @@ -/***************************************************************************** -* -* netapp.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - -#include -#include "netapp.h" -#include "hci.h" -#include "socket.h" -#include "evnt_handler.h" -#include "nvmem.h" - -#define MIN_TIMER_VAL_SECONDS 10 -#define MIN_TIMER_SET(t) if ((0 != t) && (t < MIN_TIMER_VAL_SECONDS)) \ - { \ - t = MIN_TIMER_VAL_SECONDS; \ - } - - -#define NETAPP_DHCP_PARAMS_LEN (20) -#define NETAPP_SET_TIMER_PARAMS_LEN (20) -#define NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN (4) -#define NETAPP_PING_SEND_PARAMS_LEN (16) - - -//***************************************************************************** -// -//! netapp_config_mac_adrress -//! -//! @param mac device mac address, 6 bytes. Saved: yes -//! -//! @return return on success 0, otherwise error. -//! -//! @brief Configure device MAC address and store it in NVMEM. -//! The value of the MAC address configured through the API will -//! be stored in CC3000 non volatile memory, thus preserved -//! over resets. -// -//***************************************************************************** -INT32 netapp_config_mac_adrress(UINT8 * mac) -{ - return nvmem_set_mac_address(mac); -} - -//***************************************************************************** -// -//! netapp_dhcp -//! -//! @param aucIP device mac address, 6 bytes. Saved: yes -//! @param aucSubnetMask device mac address, 6 bytes. Saved: yes -//! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes -//! @param aucDNSServer device mac address, 6 bytes. Saved: yes -//! -//! @return return on success 0, otherwise error. -//! -//! @brief netapp_dhcp is used to configure the network interface, -//! static or dynamic (DHCP).\n In order to activate DHCP mode, -//! aucIP, aucSubnetMask, aucDefaultGateway must be 0. -//! The default mode of CC3000 is DHCP mode. -//! Note that the configuration is saved in non volatile memory -//! and thus preserved over resets. -//! -//! @note If the mode is altered a reset of CC3000 device is required -//! in order to apply changes.\nAlso note that asynchronous event -//! of DHCP_EVENT, which is generated when an IP address is -//! allocated either by the DHCP server or due to static -//! allocation is generated only upon a connection to the -//! AP was established. -//! -//***************************************************************************** -INT32 netapp_dhcp(UINT32 *aucIP, UINT32 *aucSubnetMask,UINT32 *aucDefaultGateway, UINT32 *aucDNSServer) -{ - INT8 scRet; - UINT8 *ptr; - UINT8 *args; - - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - ARRAY_TO_STREAM(args,aucIP,4); - ARRAY_TO_STREAM(args,aucSubnetMask,4); - ARRAY_TO_STREAM(args,aucDefaultGateway,4); - args = UINT32_TO_STREAM(args, 0); - ARRAY_TO_STREAM(args,aucDNSServer,4); - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_DHCP, ptr, NETAPP_DHCP_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_DHCP, &scRet); - - return(scRet); -} - - -//***************************************************************************** -// -//! netapp_timeout_values -//! -//! @param aucDHCP DHCP lease time request, also impact -//! the DHCP renew timeout. Range: [0-0xffffffff] seconds, -//! 0 or 0xffffffff == infinity lease timeout. -//! Resolution:10 seconds. Influence: only after -//! reconnecting to the AP. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 seconds. -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 14400 seconds. -//! -//! @param aucARP ARP refresh timeout, if ARP entry is not updated by -//! incoming packet, the ARP entry will be deleted by -//! the end of the timeout. -//! Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout -//! Resolution: 10 seconds. Influence: on runtime. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 seconds -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 3600 seconds. -//! -//! @param aucKeepalive Keepalive event sent by the end of keepalive timeout -//! Range: [0-0xffffffff] seconds, 0 == infinity timeout -//! Resolution: 10 seconds. -//! Influence: on runtime. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 sec -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 10 seconds. -//! -//! @param aucInactivity Socket inactivity timeout, socket timeout is -//! refreshed by incoming or outgoing packet, by the -//! end of the socket timeout the socket will be closed -//! Range: [0-0xffffffff] sec, 0 == infinity timeout. -//! Resolution: 10 seconds. Influence: on runtime. -//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 sec -//! The parameter is saved into the CC3000 NVMEM. -//! The default value on CC3000 is 60 seconds. -//! -//! @return return on success 0, otherwise error. -//! -//! @brief Set new timeout values. Function set new timeout values for: -//! DHCP lease timeout, ARP refresh timeout, keepalive event -//! timeout and socket inactivity timeout -//! -//! @note If a parameter set to non zero value which is less than 10s, -//! it will be set automatically to 10s. -//! -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 netapp_timeout_values(UINT32 *aucDHCP, UINT32 *aucARP,UINT32 *aucKeepalive, UINT32 *aucInactivity) -{ - INT8 scRet; - UINT8 *ptr; - UINT8 *args; - - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Set minimal values of timers - MIN_TIMER_SET(*aucDHCP) - MIN_TIMER_SET(*aucARP) - MIN_TIMER_SET(*aucKeepalive) - MIN_TIMER_SET(*aucInactivity) - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, *aucDHCP); - args = UINT32_TO_STREAM(args, *aucARP); - args = UINT32_TO_STREAM(args, *aucKeepalive); - args = UINT32_TO_STREAM(args, *aucInactivity); - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_SET_TIMERS, ptr, NETAPP_SET_TIMER_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_SET_TIMERS, &scRet); - - return(scRet); -} -#endif - - -//***************************************************************************** -// -//! netapp_ping_send -//! -//! @param ip destination IP address -//! @param pingAttempts number of echo requests to send -//! @param pingSize send buffer size which may be up to 1400 bytes -//! @param pingTimeout Time to wait for a response,in milliseconds. -//! -//! @return return on success 0, otherwise error. -//! -//! @brief send ICMP ECHO_REQUEST to network hosts -//! -//! @note If an operation finished successfully asynchronous ping report -//! event will be generated. The report structure is as defined -//! by structure netapp_pingreport_args_t. -//! -//! @warning Calling this function while a previous Ping Requests are in -//! progress will stop the previous ping request. -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 - netapp_ping_send(UINT32 *ip, UINT32 ulPingAttempts, UINT32 ulPingSize, UINT32 ulPingTimeout) -{ - INT8 scRet; - UINT8 *ptr, *args; - - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, *ip); - args = UINT32_TO_STREAM(args, ulPingAttempts); - args = UINT32_TO_STREAM(args, ulPingSize); - args = UINT32_TO_STREAM(args, ulPingTimeout); - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_PING_SEND, ptr, NETAPP_PING_SEND_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_PING_SEND, &scRet); - - return(scRet); -} -#endif - -//***************************************************************************** -// -//! netapp_ping_report -//! -//! @param none -//! -//! @return none -//! -//! @brief Request for ping status. This API triggers the CC3000 to send -//! asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT. -//! This event will carry the report structure: -//! netapp_pingreport_args_t. This structure is filled in with ping -//! results up till point of triggering API. -//! netapp_pingreport_args_t:\n packets_sent - echo sent, -//! packets_received - echo reply, min_round_time - minimum -//! round time, max_round_time - max round time, -//! avg_round_time - average round time -//! -//! @note When a ping operation is not active, the returned structure -//! fields are 0. -//! -//***************************************************************************** - - -#ifndef CC3000_TINY_DRIVER -void netapp_ping_report() -{ - UINT8 *ptr; - ptr = tSLInformation.pucTxCommandBuffer; - INT8 scRet; - - scRet = EFAIL; - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_PING_REPORT, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_PING_REPORT, &scRet); -} -#endif - -//***************************************************************************** -// -//! netapp_ping_stop -//! -//! @param none -//! -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief Stop any ping request. -//! -//! -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 netapp_ping_stop() -{ - INT8 scRet; - UINT8 *ptr; - - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_PING_STOP, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_PING_STOP, &scRet); - - return(scRet); -} -#endif - -//***************************************************************************** -// -//! netapp_ipconfig -//! -//! @param[out] ipconfig This argument is a pointer to a -//! tNetappIpconfigRetArgs structure. This structure is -//! filled in with the network interface configuration. -//! tNetappIpconfigRetArgs:\n aucIP - ip address, -//! aucSubnetMask - mask, aucDefaultGateway - default -//! gateway address, aucDHCPServer - dhcp server address -//! aucDNSServer - dns server address, uaMacAddr - mac -//! address, uaSSID - connected AP ssid -//! -//! @return none -//! -//! @brief Obtain the CC3000 Network interface information. -//! Note that the information is available only after the WLAN -//! connection was established. Calling this function before -//! associated, will cause non-defined values to be returned. -//! -//! @note The function is useful for figuring out the IP Configuration of -//! the device when DHCP is used and for figuring out the SSID of -//! the Wireless network the device is associated with. -//! -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig ) -{ - UINT8 *ptr; - - ptr = tSLInformation.pucTxCommandBuffer; - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_IPCONFIG, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_IPCONFIG, ipconfig ); - -} -#else -void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig ) -{ - -} -#endif - -//***************************************************************************** -// -//! netapp_arp_flush -//! -//! @param none -//! -//! @return none -//! -//! @brief Flushes ARP table -//! -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 netapp_arp_flush(void) -{ - INT8 scRet; - UINT8 *ptr; - - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - - // Initiate a HCI command - hci_command_send(HCI_NETAPP_ARP_FLUSH, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_NETAPP_ARP_FLUSH, &scRet); - - return(scRet); -} -#endif - -//***************************************************************************** -// -//! netapp_set_debug_level -//! -//! @param[in] level debug level. Bitwise [0-8], -//! 0(disable)or 1(enable).\n Bitwise map: 0 - Critical -//! message, 1 information message, 2 - core messages, 3 - -//! HCI messages, 4 - Network stack messages, 5 - wlan -//! messages, 6 - wlan driver messages, 7 - epprom messages, -//! 8 - general messages. Default: 0x13f. Saved: no -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Debug messages sent via the UART debug channel, this function -//! enable/disable the debug level -//! -//***************************************************************************** - - -#ifndef CC3000_TINY_DRIVER -INT32 netapp_set_debug_level(UINT32 ulLevel) -{ - INT8 scRet; - UINT8 *ptr, *args; - - scRet = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // - // Fill in temporary command buffer - // - args = UINT32_TO_STREAM(args, ulLevel); - - - // - // Initiate a HCI command - // - hci_command_send(HCI_NETAPP_SET_DEBUG_LEVEL, ptr, NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN); - - // - // Wait for command complete event - // - SimpleLinkWaitEvent(HCI_NETAPP_SET_DEBUG_LEVEL, &scRet); - - return(scRet); - -} -#endif diff --git a/drivers/cc3000/src/nvmem.c b/drivers/cc3000/src/nvmem.c deleted file mode 100644 index c6e170a7465..00000000000 --- a/drivers/cc3000/src/nvmem.c +++ /dev/null @@ -1,334 +0,0 @@ -/***************************************************************************** -* -* nvmem.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - -//***************************************************************************** -// -//! \addtogroup nvmem_api -//! @{ -// -//***************************************************************************** - -#include -#include "nvmem.h" -#include "hci.h" -#include "socket.h" -#include "evnt_handler.h" - -//***************************************************************************** -// -// Prototypes for the structures for APIs. -// -//***************************************************************************** - -#define NVMEM_READ_PARAMS_LEN (12) -#define NVMEM_CREATE_PARAMS_LEN (8) -#define NVMEM_WRITE_PARAMS_LEN (16) - -//***************************************************************************** -// -//! nvmem_read -//! -//! @param ulFileId nvmem file id:\n -//! NVMEM_NVS_FILEID, NVMEM_NVS_SHADOW_FILEID, -//! NVMEM_WLAN_CONFIG_FILEID, NVMEM_WLAN_CONFIG_SHADOW_FILEID, -//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, -//! NVMEM_MAC_FILEID, NVMEM_FRONTEND_VARS_FILEID, -//! NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID, -//! NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID, -//! and user files 12-15. -//! @param ulLength number of bytes to read -//! @param ulOffset ulOffset in file from where to read -//! @param buff output buffer pointer -//! -//! @return on success 0, error otherwise. -//! -//! @brief Reads data from the file referred by the ulFileId parameter. -//! Reads data from file ulOffset till length. Err if the file can't -//! be used, is invalid, or if the read is out of bounds. -//! -//***************************************************************************** - -INT32 nvmem_read(UINT32 ulFileId, UINT32 ulLength, UINT32 ulOffset, UINT8 *buff) -{ - UINT8 ucStatus = 0xFF; - UINT8 *ptr; - UINT8 *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, ulFileId); - args = UINT32_TO_STREAM(args, ulLength); - args = UINT32_TO_STREAM(args, ulOffset); - - // Initiate a HCI command - hci_command_send(HCI_CMND_NVMEM_READ, ptr, NVMEM_READ_PARAMS_LEN); - SimpleLinkWaitEvent(HCI_CMND_NVMEM_READ, &ucStatus); - - // In case there is data - read it - even if an error code is returned - // Note: It is the user responsibility to ignore the data in case of an error code - - // Wait for the data in a synchronous way. Here we assume that the buffer is - // big enough to store also parameters of nvmem - - SimpleLinkWaitData(buff, 0, 0); - - return(ucStatus); -} - -//***************************************************************************** -// -//! nvmem_write -//! -//! @param ulFileId nvmem file id:\n -//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, -//! NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID, -//! and user files 12-15. -//! @param ulLength number of bytes to write -//! @param ulEntryOffset offset in file to start write operation from -//! @param buff data to write -//! -//! @return on success 0, error otherwise. -//! -//! @brief Write data to nvmem. -//! writes data to file referred by the ulFileId parameter. -//! Writes data to file ulOffset till ulLength.The file id will be -//! marked invalid till the write is done. The file entry doesn't -//! need to be valid - only allocated. -//! -//***************************************************************************** - -INT32 nvmem_write(UINT32 ulFileId, UINT32 ulLength, UINT32 ulEntryOffset, UINT8 *buff) -{ - INT32 iRes; - UINT8 *ptr; - UINT8 *args; - - iRes = EFAIL; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, ulFileId); - args = UINT32_TO_STREAM(args, 12); - args = UINT32_TO_STREAM(args, ulLength); - args = UINT32_TO_STREAM(args, ulEntryOffset); - - memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE + - NVMEM_WRITE_PARAMS_LEN),buff,ulLength); - - // Initiate a HCI command but it will come on data channel - hci_data_command_send(HCI_CMND_NVMEM_WRITE, ptr, NVMEM_WRITE_PARAMS_LEN, - ulLength); - - SimpleLinkWaitEvent(HCI_EVNT_NVMEM_WRITE, &iRes); - - return(iRes); -} - - -//***************************************************************************** -// -//! nvmem_set_mac_address -//! -//! @param mac mac address to be set -//! -//! @return on success 0, error otherwise. -//! -//! @brief Write MAC address to EEPROM. -//! mac address as appears over the air (OUI first) -//! -//***************************************************************************** - -UINT8 nvmem_set_mac_address(UINT8 *mac) -{ - return nvmem_write(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac); -} - -//***************************************************************************** -// -//! nvmem_get_mac_address -//! -//! @param[out] mac mac address -//! -//! @return on success 0, error otherwise. -//! -//! @brief Read MAC address from EEPROM. -//! mac address as appears over the air (OUI first) -//! -//***************************************************************************** - -UINT8 nvmem_get_mac_address(UINT8 *mac) -{ - return nvmem_read(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac); -} - -//***************************************************************************** -// -//! nvmem_write_patch -//! -//! @param ulFileId nvmem file id:\n -//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, -//! @param spLength number of bytes to write -//! @param spData SP data to write -//! -//! @return on success 0, error otherwise. -//! -//! @brief program a patch to a specific file ID. -//! The SP data is assumed to be organized in 2-dimensional. -//! Each line is SP_PORTION_SIZE bytes long. Actual programming is -//! applied in SP_PORTION_SIZE bytes portions. -//! -//***************************************************************************** - -UINT8 nvmem_write_patch(UINT32 ulFileId, UINT32 spLength, const UINT8 *spData) -{ - UINT8 status = 0; - UINT16 offset = 0; - UINT8* spDataPtr = (UINT8*)spData; - - while ((status == 0) && (spLength >= SP_PORTION_SIZE)) - { - status = nvmem_write(ulFileId, SP_PORTION_SIZE, offset, spDataPtr); - offset += SP_PORTION_SIZE; - spLength -= SP_PORTION_SIZE; - spDataPtr += SP_PORTION_SIZE; - } - - if (status !=0) - { - // NVMEM error occurred - return status; - } - - if (spLength != 0) - { - // if reached here, a reminder is left - status = nvmem_write(ulFileId, spLength, offset, spDataPtr); - } - - return status; -} - -//***************************************************************************** -// -//! nvmem_read_sp_version -//! -//! @param[out] patchVer first number indicates package ID and the second -//! number indicates package build number -//! -//! @return on success 0, error otherwise. -//! -//! @brief Read patch version. read package version (WiFi FW patch, -//! driver-supplicant-NS patch, bootloader patch) -//! -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -UINT8 nvmem_read_sp_version(UINT8* patchVer) -{ - UINT8 *ptr; - // 1st byte is the status and the rest is the SP version - UINT8 retBuf[5]; - - ptr = tSLInformation.pucTxCommandBuffer; - - // Initiate a HCI command, no args are required - hci_command_send(HCI_CMND_READ_SP_VERSION, ptr, 0); - SimpleLinkWaitEvent(HCI_CMND_READ_SP_VERSION, retBuf); - - // package ID - *patchVer = retBuf[3]; - // package build number - *(patchVer+1) = retBuf[4]; - - return(retBuf[0]); -} -#endif - -//***************************************************************************** -// -//! nvmem_create_entry -//! -//! @param ulFileId nvmem file Id:\n -//! * NVMEM_AES128_KEY_FILEID: 12 -//! * NVMEM_SHARED_MEM_FILEID: 13 -//! * and fileIDs 14 and 15 -//! @param ulNewLen entry ulLength -//! -//! @return on success 0, error otherwise. -//! -//! @brief Create new file entry and allocate space on the NVMEM. -//! Applies only to user files. -//! Modify the size of file. -//! If the entry is unallocated - allocate it to size -//! ulNewLen (marked invalid). -//! If it is allocated then deallocate it first. -//! To just mark the file as invalid without resizing - -//! set ulNewLen=0. -//! -//***************************************************************************** - -INT32 nvmem_create_entry(UINT32 ulFileId, UINT32 ulNewLen) -{ - UINT8 *ptr; - UINT8 *args; - UINT8 retval; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, ulFileId); - args = UINT32_TO_STREAM(args, ulNewLen); - - // Initiate a HCI command - hci_command_send(HCI_CMND_NVMEM_CREATE_ENTRY,ptr, NVMEM_CREATE_PARAMS_LEN); - - SimpleLinkWaitEvent(HCI_CMND_NVMEM_CREATE_ENTRY, &retval); - - return(retval); -} - - - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** diff --git a/drivers/cc3000/src/patch.c b/drivers/cc3000/src/patch.c deleted file mode 100644 index 227be3c9f2a..00000000000 --- a/drivers/cc3000/src/patch.c +++ /dev/null @@ -1,117 +0,0 @@ -/***************************************************************************** - * - * {PatchProgrammer_DR_Patch.c} - * - * Burn Patches to EEPROM - * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ - * ALL RIGHTS RESERVED - * - *****************************************************************************/ -// -// Service Pack version P1.13.7.15.28 - Driver patches -// This file contains the CC3K driver and firmware patches -// From CC3000-FRAM-PATCH V:1.13.7 15-MAY-2014 - -unsigned short fw_length = 5700; -unsigned short drv_length = 8024; - -const unsigned char wlan_drv_patch[8024] = { 0x00, 0x01, 0x00, 0x00, 0x50, 0x1F, 0x00, 0x00, 0xF0, 0x03, 0x18, 0x00, 0xE4, 0x62, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7A, 0x63, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x10, 0x64, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x20, 0x0C, 0x49, 0x08, 0x60, 0x0C, 0x48, 0x19, 0x30, 0xF7, 0x46, 0x30, 0xB5, 0x05, 0x1C, 0xAC, 0x69, 0x68, 0x68, 0x5F, 0x30, 0x09, 0xD1, 0x60, 0x6B, 0x0C, 0x38, 0x01, 0x21, 0x8E, 0x46, 0x06, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x00, 0x20, 0x60, 0x63, 0xAC, 0x69, 0x6C, 0x60, 0x04, 0x48, 0x5B, 0x30, 0x30, 0xBD, 0x40, 0x3B, 0x08, 0x00, 0x49, 0xD0, 0x01, 0x00, 0x09, 0xEA, 0x02, 0x00, 0x91, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xA6, 0x64, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3C, 0x65, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xB5, 0x85, 0xB0, 0x05, 0x1C, 0xA8, 0x88, 0x00, 0x90, 0x28, 0x89, 0x01, 0x90, 0xE9, 0x68, 0x02, 0x91, 0x28, 0x7C, 0x03, 0x90, 0x2A, 0x6A, 0x00, 0x20, 0x17, 0x56, 0x68, 0x60, 0x00, 0x29, 0x4C, 0xD0, 0x00, 0x2F, 0x4A, 0xDC , -0xCA, 0x49, 0x0C, 0x1C, 0x08, 0x26, 0x04, 0x90, 0x21, 0x88, 0x00, 0x98, 0x81, 0x42, 0x0C, 0xD1, 0x62, 0x88, 0x01, 0x98, 0x82, 0x42, 0x08, 0xD1, 0x46, 0x20, 0x02, 0x5D, 0x03, 0x98, 0x82, 0x42, 0x03, 0xD1, 0x0E, 0x20, 0x00, 0x57, 0xB8, 0x42, 0x0A, 0xD0, 0x46, 0x20, 0x00, 0x5D, 0x11, 0x28, 0x22, 0xD1, 0x00, 0x98, 0x81, 0x42, 0x1F, 0xD1, 0x0E, 0x20, 0x00, 0x57, 0xFF, 0xFF, 0xD2, 0x65, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xB8, 0x42, 0x1B, 0xD1, 0x04, 0x20, 0x02, 0x1C, 0x02, 0x98, 0xB9, 0x49, 0x01, 0x23, 0x9E, 0x46, 0xEC, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x17, 0xD0, 0x20, 0x1D, 0x02, 0x99, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0xE7, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x0D, 0xD0, 0x46, 0x20, 0x00, 0x5D, 0x11, 0x28, 0x09, 0xD0, 0xA0, 0x6D, 0x00, 0x28, 0x06, 0xD0, 0xAC, 0x34, 0x04, 0x98, 0x01, 0x30, 0x04, 0x90, 0x01, 0x3E, 0xC1, 0xD1, 0x07, 0xE0, 0x04, 0x98, 0x00, 0x06, 0x00, 0x0E , -0xAC, 0x21, 0x41, 0x43, 0xA6, 0x48, 0x40, 0x18, 0x68, 0x60, 0xA6, 0x48, 0xAD, 0x30, 0x05, 0xB0, 0xF0, 0xBD, 0x00, 0xB5, 0xC2, 0x68, 0x90, 0x69, 0x02, 0x21, 0x01, 0x23, 0x9E, 0x46, 0xA2, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xA2, 0x48, 0x61, 0x30, 0x00, 0xBD, 0x01, 0x79, 0x0B, 0x29, 0x03, 0xD0, 0x89, 0x00, 0x9F, 0x4A, 0x51, 0x5A, 0x01, 0xE0, 0x01, 0x21, 0x49, 0x02, 0x41, 0x60, 0x9D, 0x48, 0x0D, 0x30, 0xF7, 0x46, 0x01, 0x1C, 0xFF, 0xFF, 0x68, 0x66, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x9C, 0x48, 0x02, 0x68, 0x9C, 0x48, 0x01, 0x2A, 0x01, 0xD1, 0x25, 0x30, 0xF7, 0x46, 0x9B, 0x4A, 0x12, 0x68, 0x4A, 0x60, 0x19, 0x30, 0xF7, 0x46, 0x00, 0x21, 0x41, 0x60, 0x99, 0x48, 0x98, 0x49, 0x08, 0x18, 0xF7, 0x46, 0x00, 0x21, 0x41, 0x60, 0x97, 0x48, 0xE7, 0x49, 0x08, 0x18, 0xF7, 0x46, 0xFF, 0xB5, 0x46, 0x69, 0x40, 0x68, 0x01, 0x90, 0x94, 0x49, 0x0A, 0x7C, 0x9A, 0x4F, 0x01, 0x2A, 0x63, 0xD0, 0x09, 0x7C, 0x03, 0x29 , -0x60, 0xD0, 0x91, 0x4A, 0x92, 0x4B, 0x00, 0x21, 0x02, 0x91, 0x59, 0x56, 0x24, 0x23, 0x59, 0x43, 0x53, 0x18, 0x03, 0x93, 0x01, 0x28, 0x17, 0xD1, 0x8A, 0x18, 0x04, 0x23, 0x6C, 0x46, 0x8C, 0x49, 0x15, 0x79, 0x08, 0x78, 0xC0, 0x43, 0x28, 0x43, 0x20, 0x70, 0x01, 0x32, 0x01, 0x31, 0x01, 0x34, 0x01, 0x3B, 0xF5, 0xD1, 0x31, 0x1D, 0x68, 0x46, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0xA9, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x40, 0xD0, 0x35, 0x1D, 0x82, 0x48, 0x00, 0x78, 0xFF, 0x28, 0xFF, 0xFF, 0xFE, 0x66, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x11, 0xD0, 0x00, 0x28, 0x0F, 0xD0, 0x03, 0x98, 0x01, 0x1D, 0x28, 0x1C, 0x01, 0x24, 0xA6, 0x46, 0x7E, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x00, 0x28, 0x05, 0xD1, 0x7A, 0x48, 0xA6, 0x46, 0x7B, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x05, 0xE0, 0x28, 0x1C, 0x01, 0x21, 0x8E, 0x46, 0x78, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x01, 0x99, 0x01, 0x29, 0x01, 0xD1, 0x00, 0x28, 0x1E, 0xD1 , -0x01, 0x99, 0x5F, 0x31, 0x01, 0xD0, 0x00, 0x28, 0x0F, 0xD1, 0xA8, 0x20, 0x81, 0x5D, 0x00, 0x29, 0x08, 0xD0, 0x49, 0x1E, 0x81, 0x55, 0x80, 0x5D, 0x00, 0x28, 0x09, 0xD1, 0x38, 0x1C, 0xFF, 0x30, 0x08, 0x30, 0x11, 0xE0, 0x03, 0x21, 0x02, 0x91, 0x00, 0xE0, 0xA8, 0x20, 0x02, 0x99, 0x81, 0x55, 0x38, 0x1C, 0xFF, 0x30, 0x16, 0x30, 0x07, 0xE0, 0x01, 0x98, 0x01, 0x28, 0x02, 0xD1, 0x38, 0x1C, 0xA3, 0x30, 0x01, 0xE0, 0x38, 0x1C, 0x9F, 0x30, 0x00, 0x90, 0xFF, 0xBD, 0x00, 0xB5, 0x02, 0x1C, 0x10, 0x6A, 0xD1, 0x69, 0x52, 0x69, 0xC3, 0x69, 0x5A, 0x60, 0xFF, 0xFF, 0x94, 0x67, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x01, 0x22, 0x96, 0x46, 0x5E, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x5E, 0x48, 0xFF, 0x30, 0x6E, 0x30, 0x00, 0xBD, 0x10, 0xB5, 0x0A, 0x1C, 0x41, 0x69, 0x00, 0x6A, 0x93, 0x69, 0xDB, 0x69, 0x58, 0x60, 0x90, 0x69, 0x01, 0x24, 0xA6, 0x46, 0x56, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0xA6, 0x46, 0x56, 0x48, 0xFE, 0x44 , -0x00, 0x47, 0x55, 0x48, 0xFF, 0x30, 0xB6, 0x30, 0x10, 0xBD, 0x70, 0xB5, 0x05, 0x1C, 0x6E, 0x69, 0x53, 0x48, 0x02, 0x68, 0x5C, 0x21, 0x88, 0x5D, 0x04, 0x28, 0x15, 0xD1, 0x07, 0x20, 0x88, 0x55, 0x10, 0x0B, 0x11, 0xD2, 0x01, 0x24, 0xA6, 0x46, 0x4E, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x00, 0x28, 0x0A, 0xD0, 0x47, 0x21, 0x89, 0x57, 0xC1, 0x60, 0x11, 0x21, 0xC9, 0x02, 0x00, 0x22, 0x04, 0x23, 0xA6, 0x46, 0xE8, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x01, 0x20, 0x68, 0x60, 0x43, 0x48, 0xED, 0x49, 0x08, 0x18, 0x70, 0xBD, 0x70, 0xB5, 0x05, 0x1C, 0xAE, 0x69, 0x9C, 0x20, 0x80, 0x19, 0x4B, 0x21, 0x89, 0x00, 0x01, 0x24, 0xFF, 0xFF, 0x2A, 0x68, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xA6, 0x46, 0xE8, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x5C, 0x21, 0x88, 0x5D, 0x07, 0x28, 0x01, 0xD1, 0x09, 0x20, 0x00, 0xE0, 0x05, 0x20, 0xAA, 0x69, 0x88, 0x54, 0x30, 0x1C, 0xA6, 0x46, 0xE9, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x68, 0x60, 0xE8, 0x48 , -0x4D, 0x30, 0x70, 0xBD, 0xF0, 0xB5, 0x41, 0x68, 0x82, 0x68, 0x88, 0x23, 0x5E, 0x18, 0x37, 0x88, 0x0B, 0x6F, 0x00, 0x2B, 0x01, 0xD1, 0x00, 0x2F, 0x10, 0xD1, 0x06, 0x2F, 0x02, 0xDD, 0x00, 0x21, 0xC9, 0x43, 0x07, 0xE0, 0x33, 0x88, 0x9B, 0x00, 0xC9, 0x18, 0x0A, 0x67, 0x31, 0x88, 0x01, 0x31, 0x31, 0x80, 0x01, 0x21, 0x81, 0x60, 0xE1, 0x48, 0x1D, 0x30, 0xF0, 0xBD, 0x0B, 0x1C, 0x01, 0x24, 0x5D, 0x6F, 0x1D, 0x67, 0x04, 0x33, 0x01, 0x34, 0x06, 0x2C, 0xE1, 0xDA, 0xF8, 0xE7, 0x00, 0xB5, 0x00, 0x21, 0xC1, 0x60, 0xE9, 0x48, 0x01, 0x68, 0x10, 0x31, 0xE6, 0x48, 0x20, 0x22, 0x01, 0x23, 0x9E, 0x46, 0xE7, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xE5, 0x48, 0xFB, 0x30, 0x00, 0xBD, 0xFF, 0xFF, 0xC0, 0x68, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x14, 0x0D, 0x1B, 0x00, 0x54, 0x19, 0x1B, 0x00, 0x91, 0x1A, 0x01, 0x00, 0x4B, 0xAD, 0x03, 0x00, 0x61, 0x4E, 0x01, 0x00, 0x06, 0x32, 0x08, 0x00, 0x1F, 0x0B, 0x02, 0x00, 0x54, 0x3F , -0x08, 0x00, 0x45, 0xC1, 0x00, 0x00, 0x84, 0x3C, 0x08, 0x00, 0x1B, 0x02, 0x00, 0x00, 0xED, 0x17, 0x00, 0x00, 0xF3, 0xC1, 0x01, 0x00, 0x34, 0x19, 0x1B, 0x00, 0x08, 0x19, 0x1B, 0x00, 0xA6, 0x44, 0x08, 0x00, 0x1C, 0x17, 0x1B, 0x00, 0x18, 0x17, 0x1B, 0x00, 0xCB, 0x67, 0x03, 0x00, 0x0D, 0x47, 0x02, 0x00, 0x39, 0x42, 0x03, 0x00, 0xBD, 0xE7, 0x02, 0x00, 0xB1, 0x40, 0x03, 0x00, 0xB9, 0xEA, 0x01, 0x00, 0x45, 0xDA, 0x00, 0x00, 0x24, 0x41, 0x08, 0x00, 0x71, 0xC0, 0x02, 0x00, 0xF0, 0xB5, 0x88, 0xB0, 0x06, 0x91, 0x07, 0x90, 0x86, 0x69, 0xF0, 0x1C, 0xD9, 0xA1, 0x04, 0x22, 0x01, 0x24, 0xA6, 0x46, 0x14, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x32, 0xD1, 0xF2, 0x79, 0xD7, 0x48, 0x02, 0x70, 0x35, 0x7A, 0x77, 0x7A, 0x78, 0x1B, 0xFF, 0xFF, 0x56, 0x69, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x43, 0x1C, 0x93, 0x42, 0x1D, 0xD0, 0x16, 0x2A, 0x0C, 0xDB, 0x00, 0x2D, 0x0A, 0xD1, 0xD6, 0x48, 0x04, 0x70, 0x0A, 0x20 , -0x81, 0x19, 0xD0, 0x48, 0x1A, 0x1C, 0xA6, 0x46, 0xB8, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x74, 0xE0, 0xD2, 0x48, 0x04, 0x70, 0xCC, 0x48, 0x40, 0x19, 0x0A, 0x21, 0x89, 0x19, 0x7A, 0x1B, 0x52, 0x1C, 0xA6, 0x46, 0xB1, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x67, 0xE0, 0x8F, 0xC6, 0x03, 0x00, 0xC9, 0x48, 0x04, 0x70, 0xC9, 0x48, 0x04, 0x70, 0x0A, 0x20, 0x81, 0x19, 0xC2, 0x48, 0xA6, 0x46, 0xAA, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x59, 0xE0, 0xF0, 0x1C, 0x03, 0x21, 0x0A, 0x1C, 0xBC, 0xA1, 0xA6, 0x46, 0xC6, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x4F, 0xD1, 0xF1, 0x79, 0xBB, 0x48, 0x01, 0x70, 0xBB, 0x4D, 0xB2, 0x79, 0x2A, 0x70, 0x03, 0x20, 0x17, 0x49, 0xF4, 0x31, 0xA6, 0x46, 0xB8, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x28, 0x78, 0x00, 0x28, 0x0B, 0xD1, 0xFF, 0xE7, 0xB8, 0x49, 0x0C, 0x70, 0xB8, 0x49, 0xFF, 0xFF, 0xEC, 0x69, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x0C, 0x70, 0x03, 0x20, 0x0F, 0x49, 0xF5, 0x31, 0xA6, 0x46 , -0xB6, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x20, 0x1C, 0xF2, 0x79, 0x35, 0x7A, 0x77, 0x7A, 0x79, 0x1B, 0x4B, 0x1C, 0x93, 0x42, 0x20, 0xD0, 0xA9, 0x49, 0x09, 0x78, 0x16, 0x29, 0x0F, 0xDB, 0x00, 0x2D, 0x0D, 0xD1, 0xAB, 0x49, 0x08, 0x70, 0x0A, 0x20, 0x81, 0x19, 0xE9, 0x48, 0x1A, 0x1C, 0xA6, 0x46, 0x8B, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x1A, 0xE0, 0xC0, 0x46, 0xC7, 0x04, 0x00, 0x00, 0xA5, 0x49, 0x08, 0x70, 0xE3, 0x48, 0x40, 0x19, 0x0A, 0x21, 0x89, 0x19, 0x7A, 0x1B, 0x52, 0x1C, 0xA6, 0x46, 0x83, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x0A, 0xE0, 0x9E, 0x49, 0x08, 0x70, 0x9E, 0x49, 0x08, 0x70, 0x0A, 0x20, 0x81, 0x19, 0xDB, 0x48, 0xA6, 0x46, 0x7D, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x96, 0x48, 0x00, 0x78, 0x00, 0x28, 0x0A, 0xD0, 0x95, 0x48, 0x00, 0x78, 0x00, 0x28, 0x06, 0xD0, 0x94, 0x48, 0x00, 0x78, 0x00, 0x28, 0x02, 0xD0, 0x93, 0x48, 0x00, 0x78, 0x00, 0x28, 0xFF, 0xFF, 0x82, 0x6A, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00 , -0x00, 0xD1, 0x8C, 0xE0, 0x03, 0x20, 0x17, 0x21, 0x89, 0x01, 0xA6, 0x46, 0x90, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x87, 0x48, 0x01, 0x78, 0x87, 0x48, 0x07, 0x78, 0x84, 0x4E, 0x83, 0x4D, 0xE0, 0x48, 0x00, 0x68, 0x00, 0x28, 0x2E, 0xD1, 0x07, 0x98, 0x41, 0x61, 0x06, 0x62, 0xC6, 0x48, 0x06, 0x9A, 0x10, 0x64, 0x02, 0x2F, 0x01, 0xD0, 0x03, 0x2F, 0x01, 0xD1, 0x03, 0x22, 0x00, 0xE0, 0x3A, 0x1C, 0x06, 0x9B, 0xDA, 0x63, 0x2A, 0x78, 0x9A, 0x63, 0x01, 0x2F, 0x03, 0xD1, 0x05, 0x29, 0x04, 0xD0, 0x0D, 0x29, 0x02, 0xD0, 0xEC, 0x48, 0xDB, 0x30, 0x64, 0xE0, 0x00, 0x25, 0x00, 0x95, 0x01, 0x91, 0x02, 0x96, 0x03, 0x95, 0x04, 0x90, 0x2B, 0x1C, 0x20, 0x1C, 0x01, 0x1C, 0x8E, 0x46, 0xE6, 0x4E, 0xFE, 0x44, 0x30, 0x47, 0xE6, 0x48, 0x04, 0x60, 0x28, 0x1C, 0xA6, 0x46, 0xE5, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x4C, 0xE0, 0x0D, 0x27, 0x00, 0x20, 0x39, 0x1C, 0x05, 0xAA, 0xA6, 0x46, 0xE3, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x68, 0x46 , -0xFF, 0xFF, 0x18, 0x6B, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x80, 0x8A, 0x40, 0x08, 0x05, 0xD2, 0x38, 0x1C, 0x50, 0x21, 0xA6, 0x46, 0xDC, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x38, 0x1C, 0x21, 0x1C, 0x0B, 0x1C, 0x29, 0x1C, 0x00, 0x22, 0xA6, 0x46, 0xD9, 0x4F, 0xFE, 0x44, 0x38, 0x47, 0x2B, 0x78, 0x0D, 0x20, 0x31, 0x1C, 0x22, 0x1C, 0xA6, 0x46, 0xD5, 0x4E, 0xFE, 0x44, 0x30, 0x47, 0x28, 0x78, 0x01, 0x30, 0x02, 0x1C, 0x0D, 0x20, 0x57, 0x49, 0x23, 0x1C, 0xA6, 0x46, 0xD0, 0x4E, 0xFE, 0x44, 0x30, 0x47, 0x55, 0x4E, 0x28, 0x78, 0x02, 0x30, 0x02, 0x1C, 0x0D, 0x20, 0x31, 0x1C, 0x23, 0x1C, 0xA6, 0x46, 0xCA, 0x4F, 0xFE, 0x44, 0x38, 0x47, 0x30, 0x78, 0x00, 0x28, 0x0A, 0xD0, 0x28, 0x78, 0x03, 0x30, 0x02, 0x1C, 0x4C, 0x48, 0x03, 0x78, 0x0D, 0x20, 0x8F, 0x49, 0xA6, 0x46, 0xC3, 0x4D, 0xFE, 0x44, 0x28, 0x47, 0xBF, 0x48, 0x04, 0x60, 0x00, 0x20, 0xA6, 0x46, 0xBE, 0x49, 0xFE, 0x44, 0x08, 0x47, 0xB9, 0x48, 0xEC, 0x49 , -0x08, 0x18, 0x08, 0xB0, 0xF0, 0xBD, 0xC0, 0x46, 0x7B, 0xC0, 0xFF, 0xFF, 0xAE, 0x6B, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x1C, 0xE9, 0x48, 0x02, 0x68, 0xE9, 0x48, 0x00, 0x2A, 0x04, 0xD0, 0x00, 0x22, 0x0A, 0x62, 0x8A, 0x61, 0x1D, 0x30, 0xF7, 0x46, 0xD7, 0x30, 0xF7, 0x46, 0xC0, 0x46, 0x9F, 0x03, 0x00, 0x00, 0x7D, 0xB8, 0x03, 0x00, 0x01, 0x1C, 0xE2, 0x48, 0x02, 0x68, 0xE2, 0x48, 0x00, 0x2A, 0x02, 0xD0, 0xFF, 0x30, 0xB4, 0x30, 0xF7, 0x46, 0x00, 0x22, 0xCA, 0x61, 0x8A, 0x61, 0x4F, 0x30, 0xF7, 0x46, 0xC9, 0x21, 0x01, 0x00, 0x91, 0xE1, 0x00, 0x00, 0xDB, 0x48, 0x01, 0x68, 0x8A, 0x69, 0x01, 0x20, 0xC0, 0x03, 0x10, 0x43, 0x88, 0x61, 0x00, 0x20, 0x08, 0x61, 0xD8, 0x48, 0x23, 0x30, 0xF7, 0x46, 0x89, 0x17, 0x02, 0x00, 0x70, 0xB5, 0x05, 0x1C, 0xD5, 0x4E, 0x29, 0x6A, 0xEA, 0x69, 0x30, 0x1C, 0x01, 0x24, 0xA6, 0x46, 0x0B, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x68, 0x69, 0xA6, 0x46, 0xD1, 0x49 , -0xFE, 0x44, 0x08, 0x47, 0xA8, 0x69, 0x06, 0x30, 0xA8, 0x60, 0xCF, 0x48, 0x00, 0x68, 0x68, 0x60, 0xEE, 0x60, 0xCE, 0x48, 0xFF, 0xFF, 0x44, 0x6C, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x6D, 0x30, 0x70, 0xBD, 0x46, 0x17, 0x1B, 0x00, 0x30, 0x3F, 0x08, 0x00, 0x41, 0xEB, 0x00, 0x00, 0x09, 0xB4, 0x03, 0x00, 0x30, 0xB5, 0xEE, 0x48, 0x01, 0x6D, 0x80, 0x6C, 0x08, 0x43, 0x18, 0xD0, 0xEC, 0x49, 0x08, 0x1C, 0x07, 0x22, 0xFF, 0x23, 0x09, 0x33, 0x1B, 0x58, 0x00, 0x2B, 0x04, 0xD0, 0xFF, 0x30, 0x1D, 0x30, 0x01, 0x3A, 0xF6, 0xD1, 0x0B, 0xE0, 0x02, 0x20, 0xF0, 0x4A, 0xF1, 0x4B, 0x01, 0x24, 0xA6, 0x46, 0xF0, 0x4D, 0xFE, 0x44, 0x28, 0x47, 0xA6, 0x46, 0xEF, 0x48, 0xFE, 0x44, 0x00, 0x47, 0xEF, 0x48, 0xFF, 0x30, 0x5C, 0x30, 0x30, 0xBD, 0xC0, 0x46, 0x53, 0x53, 0x49, 0x44, 0x00, 0xC0, 0x46, 0xC0, 0x4B, 0x45, 0x59, 0x00, 0xEE, 0x62, 0x08, 0x00, 0xF0, 0x62, 0x08, 0x00, 0xEC, 0x62, 0x08, 0x00, 0xED, 0x62, 0x08, 0x00 , -0xE7, 0x7E, 0x03, 0x00, 0xE8, 0x62, 0x08, 0x00, 0xE9, 0x62, 0x08, 0x00, 0xEA, 0x62, 0x08, 0x00, 0xEB, 0x62, 0x08, 0x00, 0xDD, 0x7E, 0x03, 0x00, 0x8F, 0xC6, 0x03, 0x00, 0xF0, 0xB5, 0xFF, 0xFF, 0xDA, 0x6C, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x87, 0xB0, 0x00, 0x91, 0x01, 0x90, 0x6B, 0x48, 0x01, 0x68, 0xCC, 0x4A, 0x14, 0x1C, 0x02, 0x94, 0x07, 0x26, 0x00, 0x25, 0x03, 0x95, 0x04, 0x94, 0x05, 0x95, 0xDF, 0x48, 0x00, 0x68, 0x08, 0x43, 0x27, 0xD0, 0xE0, 0x68, 0x03, 0x99, 0x88, 0x42, 0x0A, 0xDD, 0x03, 0x90, 0x40, 0x1C, 0x00, 0x99, 0x88, 0x60, 0xC2, 0x49, 0xFF, 0x20, 0x1D, 0x30, 0x68, 0x43, 0x0C, 0x18, 0xE0, 0x68, 0x04, 0x91, 0x02, 0x99, 0xC9, 0x68, 0x88, 0x42, 0x10, 0xDB, 0x88, 0x42, 0x10, 0xD1, 0x02, 0x98, 0x01, 0x27, 0xBE, 0x46, 0xCE, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x06, 0x90, 0x20, 0x1C, 0xBE, 0x46, 0xCB, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x06, 0x99, 0x88, 0x42, 0x01, 0xDA, 0x05, 0x95, 0x02, 0x94 , -0x51, 0x48, 0x01, 0x68, 0xFF, 0x27, 0x09, 0x37, 0x38, 0x59, 0x00, 0x28, 0x06, 0xD0, 0xC7, 0x48, 0x00, 0x68, 0x07, 0x2E, 0x00, 0xD1, 0x2E, 0x1C, 0x08, 0x43, 0x04, 0xD0, 0xFF, 0x34, 0x1D, 0x34, 0x01, 0x35, 0x07, 0x2D, 0xC2, 0xDB, 0x07, 0x2E, 0xFF, 0xFF, 0x70, 0x6D, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x0A, 0xD1, 0xC0, 0x48, 0x00, 0x68, 0x08, 0x43, 0x06, 0xD0, 0x05, 0x9E, 0x30, 0x1C, 0x01, 0x21, 0x8E, 0x46, 0xBA, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x01, 0x98, 0x47, 0x61, 0x00, 0x21, 0x81, 0x61, 0xFF, 0x22, 0x1D, 0x32, 0x72, 0x43, 0x04, 0x99, 0x89, 0x18, 0xC1, 0x61, 0x06, 0x62, 0xB4, 0x48, 0x39, 0x30, 0x07, 0xB0, 0xF0, 0xBD, 0x10, 0xB5, 0x04, 0x1C, 0x00, 0x20, 0x01, 0x21, 0x8E, 0x46, 0xB1, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x40, 0x1E, 0x00, 0xD5, 0x00, 0x20, 0x60, 0x60, 0xE0, 0x61, 0xAE, 0x48, 0x21, 0x30, 0x10, 0xBD, 0xC0, 0x46, 0x10, 0x63, 0x08, 0x00, 0x70, 0xB5, 0x04, 0x1C, 0xE5, 0x69, 0x66, 0x69 , -0x00, 0x20, 0x01, 0x21, 0x8E, 0x46, 0xA7, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x60, 0x60, 0xAB, 0x19, 0xA6, 0x4A, 0xA5, 0x49, 0x93, 0x42, 0x02, 0xD3, 0x9A, 0x1A, 0x82, 0x42, 0x02, 0xD9, 0x08, 0x1C, 0x99, 0x30, 0x70, 0xBD, 0x08, 0x1C, 0xAB, 0x30, 0x70, 0xBD, 0x08, 0x6B, 0x41, 0x7D, 0x02, 0x88, 0x92, 0x00, 0xFF, 0xFF, 0x06, 0x6E, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x51, 0x1A, 0x3C, 0x39, 0xFF, 0x22, 0x5F, 0x32, 0x91, 0x42, 0x03, 0xD9, 0x65, 0x21, 0x01, 0x80, 0x02, 0x21, 0x81, 0x73, 0x9B, 0x48, 0x99, 0x49, 0x08, 0x18, 0xF7, 0x46, 0xC0, 0x46, 0x30, 0x63, 0x08, 0x00, 0xF8, 0xB5, 0x40, 0x68, 0x24, 0x21, 0x41, 0x43, 0x97, 0x48, 0x45, 0x18, 0x28, 0x1D, 0x0C, 0x21, 0x49, 0x19, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0x94, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x91, 0x4C, 0x00, 0x28, 0x1B, 0xD0, 0x2B, 0x1C, 0x04, 0x22, 0x6E, 0x46, 0x91, 0x49, 0x1F, 0x7B, 0x08, 0x78, 0xC0, 0x43, 0x38, 0x43, 0x30, 0x70, 0x01, 0x33 , -0x01, 0x31, 0x01, 0x36, 0x01, 0x3A, 0xF5, 0xD1, 0x0C, 0x20, 0x41, 0x19, 0x68, 0x46, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0x87, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x02, 0xD0, 0x20, 0x1C, 0x4A, 0x30, 0xF8, 0xBD, 0x20, 0x1C, 0xF8, 0xBD, 0xB1, 0xBD, 0x00, 0x00, 0x15, 0x95, 0x00, 0x00, 0x58, 0x3F, 0x08, 0x00, 0xF3, 0xF8, 0x00, 0x00, 0xE9, 0x09, 0x02, 0x00, 0xFF, 0xFF, 0x9C, 0x6E, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x2B, 0x09, 0x02, 0x00, 0xDD, 0x0A, 0x02, 0x00, 0xF8, 0xB5, 0x05, 0x1C, 0xAA, 0x69, 0x7D, 0x49, 0x00, 0x20, 0x08, 0x56, 0x24, 0x21, 0x41, 0x43, 0x76, 0x48, 0x43, 0x18, 0x04, 0x24, 0x6E, 0x46, 0x76, 0x49, 0x1F, 0x79, 0x08, 0x78, 0xC0, 0x43, 0x38, 0x43, 0x30, 0x70, 0x01, 0x33, 0x01, 0x31, 0x01, 0x36, 0x01, 0x3C, 0xF5, 0xD1, 0x11, 0x1D, 0x68, 0x46, 0x04, 0x22, 0x01, 0x24, 0xA6, 0x46, 0x6D, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x01, 0x1C, 0x6D, 0x48, 0x04, 0xD0, 0x6E, 0x49, 0x09, 0x78 , -0x69, 0x60, 0x45, 0x30, 0xF8, 0xBD, 0xEC, 0x61, 0xAF, 0x30, 0xF8, 0xBD, 0x70, 0xB5, 0xC5, 0x68, 0x81, 0x68, 0x0A, 0x89, 0x6D, 0x4E, 0x00, 0x2A, 0x22, 0xD0, 0x01, 0x24, 0xC2, 0x6D, 0xA2, 0x18, 0xC2, 0x65, 0x08, 0x89, 0x0D, 0x28, 0x1B, 0xD1, 0x68, 0x6B, 0x21, 0x1C, 0xA6, 0x46, 0x63, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x22, 0x1C, 0x28, 0x1C, 0x00, 0x21, 0xA6, 0x46, 0x60, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x2C, 0x60, 0xE9, 0x6B, 0xFF, 0xFF, 0x32, 0x6F, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x28, 0x1C, 0xA6, 0x46, 0x5E, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x28, 0x1C, 0xA6, 0x46, 0x5C, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x30, 0x1C, 0x3D, 0x30, 0x70, 0xBD, 0x30, 0x1C, 0x23, 0x30, 0x70, 0xBD, 0xC0, 0x46, 0xB1, 0x02, 0x00, 0x00, 0x74, 0x3F, 0x08, 0x00, 0x19, 0xC6, 0x00, 0x00, 0x5C, 0x3F, 0x08, 0x00, 0x1D, 0xC2, 0x00, 0x00, 0x68, 0x44, 0x08, 0x00, 0x43, 0x12, 0x03, 0x00, 0x34, 0x63, 0x08, 0x00, 0x2F, 0x7A, 0x02, 0x00 , -0xB4, 0x36, 0x08, 0x00, 0x8F, 0xF4, 0x01, 0x00, 0xF0, 0xB5, 0x05, 0x1C, 0xAB, 0x69, 0xEC, 0x69, 0x60, 0x68, 0x00, 0x68, 0x2A, 0x30, 0x01, 0x78, 0x0A, 0x06, 0x41, 0x78, 0x09, 0x04, 0x8A, 0x18, 0x81, 0x78, 0x09, 0x02, 0x8A, 0x18, 0xC1, 0x78, 0x8A, 0x18, 0x8E, 0x26, 0xF1, 0x5A, 0x09, 0x0A, 0x01, 0x70, 0xF0, 0x5C, 0x61, 0x68, 0x09, 0x68, 0x2B, 0x26, 0x70, 0x54, 0x8C, 0x20, 0xC0, 0x18, 0x61, 0x68, 0x0E, 0x68, 0x01, 0x88, 0x09, 0x0A, 0x2C, 0x27, 0xB9, 0x55, 0x61, 0x68, 0x09, 0x68, 0xFF, 0xFF, 0xC8, 0x6F, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x2D, 0x26, 0x00, 0x78, 0x70, 0x54, 0x60, 0x68, 0x01, 0x68, 0x32, 0x31, 0x08, 0x78, 0x00, 0x02, 0x49, 0x78, 0x08, 0x18, 0x00, 0x04, 0x00, 0x0C, 0x8C, 0x21, 0xCB, 0x58, 0x35, 0x49, 0x41, 0x40, 0x08, 0x04, 0x00, 0x0C, 0xC0, 0x18, 0x80, 0x1A, 0x01, 0x21, 0x8E, 0x46, 0x32, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x61, 0x68, 0x0A, 0x68, 0x32, 0x23, 0x01, 0x0A, 0x99, 0x54 , -0x61, 0x68, 0x09, 0x68, 0x33, 0x22, 0x50, 0x54, 0x60, 0x68, 0x68, 0x60, 0x2C, 0x48, 0xF0, 0xBD, 0x00, 0x00, 0x1B, 0x00, 0x34, 0x04, 0x1B, 0x00, 0x02, 0x6A, 0x8B, 0x69, 0xDB, 0x69, 0x1B, 0x68, 0x83, 0x60, 0x88, 0x69, 0xC0, 0x69, 0x41, 0x68, 0x8A, 0x42, 0x00, 0xDA, 0x42, 0x60, 0x25, 0x48, 0x79, 0x30, 0xF7, 0x46, 0x24, 0x48, 0x57, 0x30, 0xF7, 0x46, 0x24, 0x48, 0x91, 0x30, 0xF7, 0x46, 0x32, 0x04, 0x00, 0x00, 0xC4, 0x07, 0x00, 0x00, 0x15, 0x09, 0x02, 0x00, 0xC5, 0x93, 0x00, 0x00, 0x0D, 0x91, 0x00, 0x00, 0x40, 0x1E, 0x80, 0x00, 0x1E, 0x4B, 0xFF, 0xFF, 0x5E, 0x70, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x19, 0x50, 0x1C, 0x49, 0x0A, 0x50, 0xF7, 0x46, 0xC0, 0x46, 0xBD, 0xB5, 0x00, 0x00, 0x95, 0x92, 0x00, 0x00, 0xFD, 0x93, 0x00, 0x00, 0x54, 0x3F, 0x08, 0x00, 0x29, 0x4F, 0x03, 0x00, 0xDF, 0xE8, 0x02, 0x00, 0x36, 0x89, 0x41, 0x00, 0x81, 0x06, 0x00, 0x00, 0xB1, 0x78, 0x00, 0x00, 0x94, 0xEC, 0x01, 0x00 , -0x08, 0x19, 0x1B, 0x00, 0x8F, 0xC6, 0x03, 0x00, 0x1C, 0x17, 0x1B, 0x00, 0x67, 0x66, 0x03, 0x00, 0xA6, 0x44, 0x08, 0x00, 0x18, 0x17, 0x1B, 0x00, 0xA7, 0x2F, 0x02, 0x00, 0x91, 0x44, 0x03, 0x00, 0x91, 0x63, 0x03, 0x00, 0x5B, 0x44, 0x03, 0x00, 0xE7, 0x44, 0x03, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x61, 0xA2, 0x03, 0x00, 0x6A, 0x1E, 0x01, 0x00, 0x45, 0xDA, 0x00, 0x00, 0xD7, 0xE8, 0x01, 0x00, 0xE9, 0x78, 0x02, 0x00, 0x04, 0xF3, 0x1A, 0x00, 0x80, 0x7B, 0x08, 0x00, 0xFC, 0xB5, 0x04, 0x1C, 0xA5, 0x69, 0x60, 0x6A, 0x01, 0x90, 0x20, 0x69, 0x00, 0x28, 0x35, 0xD4, 0x08, 0x28, 0x33, 0xDA, 0xE1, 0x69, 0x09, 0x68, 0xFF, 0xFF, 0xF4, 0x70, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x10, 0x29, 0x2F, 0xD1, 0xAC, 0x21, 0x41, 0x43, 0x9E, 0x4A, 0x51, 0x5C, 0x49, 0x08, 0x27, 0xD3, 0x00, 0x06, 0x00, 0x16, 0xA2, 0x68, 0x69, 0x46, 0x01, 0x23, 0x9E, 0x46, 0x9A, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x06, 0x1C, 0x39, 0x30, 0x1F, 0xD0 , -0x00, 0x2E, 0x1D, 0xD0, 0x00, 0x98, 0x07, 0x68, 0x00, 0x99, 0x0C, 0x39, 0x01, 0x98, 0x01, 0x60, 0x28, 0x1D, 0x10, 0x21, 0x79, 0x1A, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0x91, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x02, 0x22, 0x2A, 0x80, 0xA8, 0x1C, 0x08, 0x21, 0x79, 0x1A, 0x01, 0x23, 0x9E, 0x46, 0x8C, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x03, 0xE0, 0x38, 0x20, 0x00, 0xE0, 0x00, 0x20, 0xC6, 0x43, 0x26, 0x60, 0x89, 0x48, 0x7C, 0x30, 0x20, 0x62, 0xFC, 0xBD, 0x30, 0xB5, 0x05, 0x1C, 0x28, 0x69, 0xA9, 0x69, 0x90, 0x29, 0x1D, 0xD1, 0x69, 0x69, 0x09, 0x78, 0x04, 0x29, 0x19, 0xD0, 0x05, 0x29, 0x17, 0xD0, 0x0A, 0x29, 0x15, 0xD0, 0x06, 0x29, 0x13, 0xD0, 0x0C, 0x29, 0x01, 0xDB, 0xFF, 0xFF, 0x8A, 0x71, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x10, 0x29, 0x0F, 0xD1, 0x01, 0x24, 0xA6, 0x46, 0x7D, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x7C, 0x48, 0x7D, 0x49, 0x00, 0x22, 0xA6, 0x46, 0x7C, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x7C, 0x48 , -0xFF, 0x30, 0x5F, 0x30, 0x28, 0x62, 0x30, 0xBD, 0xF0, 0xB5, 0x89, 0xB0, 0x05, 0x90, 0x41, 0x69, 0x02, 0x69, 0x75, 0x48, 0x79, 0x4E, 0x82, 0x42, 0x3A, 0xD0, 0x04, 0x30, 0x82, 0x42, 0x25, 0xD0, 0x74, 0x4D, 0xAA, 0x42, 0x00, 0xD0, 0xCC, 0xE0, 0x08, 0x68, 0x06, 0x1C, 0x0C, 0x22, 0x8F, 0x1A, 0x4A, 0x68, 0x89, 0x18, 0x09, 0x1D, 0x10, 0x22, 0x01, 0x24, 0xA6, 0x46, 0x6E, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x01, 0x1C, 0x09, 0xD1, 0xAC, 0x22, 0x72, 0x43, 0xCB, 0x48, 0x80, 0x18, 0x46, 0x22, 0x12, 0x5C, 0x11, 0x2A, 0x01, 0xD1, 0x44, 0x22, 0x14, 0x54, 0x28, 0x1C, 0x3A, 0x1C, 0xA6, 0x46, 0x62, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x69, 0x48, 0xEC, 0x30, 0xAB, 0xE0, 0x08, 0x68, 0xC0, 0x00, 0x30, 0x18, 0x8A, 0x68, 0x02, 0x2A, 0x02, 0xD0, 0xFF, 0xFF, 0x20, 0x72, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xE7, 0x20, 0x80, 0x00, 0xA2, 0xE0, 0xCA, 0x68, 0x89, 0x18, 0x09, 0x7B, 0x41, 0x60, 0x80, 0x21, 0x01, 0x60, 0x3B, 0x20 , -0x00, 0x01, 0x99, 0xE0, 0x08, 0x68, 0x06, 0x90, 0xC0, 0x00, 0x34, 0x58, 0x10, 0x20, 0x04, 0x90, 0x01, 0x25, 0xAE, 0x46, 0x57, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x07, 0x90, 0x00, 0x28, 0x00, 0xD1, 0x89, 0xE0, 0x0C, 0x21, 0x07, 0x98, 0x0F, 0x18, 0xB0, 0x49, 0xAC, 0x20, 0x06, 0x9A, 0x50, 0x43, 0x08, 0x18, 0x48, 0x22, 0x13, 0x5C, 0x5B, 0x06, 0x5B, 0x0E, 0x13, 0x54, 0x06, 0x9A, 0xD2, 0x00, 0xB6, 0x18, 0x71, 0x68, 0x00, 0x29, 0x47, 0xD1, 0x00, 0x2C, 0x01, 0xDD, 0x08, 0x2C, 0x21, 0xDB, 0x00, 0x22, 0x69, 0x46, 0x0A, 0x70, 0x01, 0x92, 0x0A, 0x81, 0x8A, 0x72, 0xCD, 0x72, 0x0D, 0x73, 0x4D, 0x73, 0x01, 0x88, 0x44, 0x48, 0x06, 0x23, 0xAE, 0x46, 0x44, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x04, 0x1C, 0x02, 0xDC, 0x00, 0x20, 0xC0, 0x43, 0x36, 0xE0, 0x34, 0x60, 0xAC, 0x20, 0x60, 0x43, 0x9A, 0x49, 0xFF, 0xFF, 0xB6, 0x72, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x09, 0x18, 0x5C, 0x22, 0x28, 0x1C, 0x50, 0x54, 0x48, 0x20 , -0x42, 0x5C, 0x52, 0x06, 0x52, 0x0E, 0x42, 0x54, 0xAC, 0x20, 0x60, 0x43, 0x94, 0x49, 0x08, 0x18, 0x5C, 0x21, 0x09, 0x5C, 0x49, 0x1E, 0x02, 0x29, 0x16, 0xD9, 0x03, 0x39, 0x08, 0xD0, 0x00, 0x20, 0x30, 0x56, 0xAE, 0x46, 0xEA, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x80, 0x20, 0x30, 0x60, 0xDB, 0xE7, 0x08, 0x94, 0x80, 0x21, 0x31, 0x60, 0x48, 0x22, 0x13, 0x5C, 0x19, 0x43, 0x11, 0x54, 0xAE, 0x46, 0xE4, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x0A, 0xE0, 0x01, 0x20, 0xCE, 0xE7, 0x06, 0x98, 0x39, 0x1C, 0x04, 0xAA, 0xAE, 0x46, 0xE0, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x04, 0x1C, 0x08, 0x90, 0x06, 0x98, 0x38, 0x60, 0x08, 0x98, 0x78, 0x60, 0x00, 0x28, 0x15, 0xD0, 0xAC, 0x20, 0x60, 0x43, 0x7C, 0x49, 0x09, 0x18, 0x48, 0x88, 0x02, 0x04, 0x02, 0x20, 0x10, 0x43, 0xB8, 0x60, 0x48, 0x68, 0x02, 0x0E, 0x01, 0x02, 0x09, 0x0E, 0x09, 0x02, 0x11, 0x43, 0x02, 0x04, 0x12, 0x0E, 0xFF, 0xFF, 0x4C, 0x73, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00 , -0x12, 0x04, 0x0A, 0x43, 0x00, 0x06, 0x10, 0x43, 0xF8, 0x60, 0x07, 0x98, 0x0D, 0x49, 0x00, 0x22, 0x10, 0x23, 0xAE, 0x46, 0xCE, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x13, 0x48, 0x00, 0xE0, 0x16, 0x20, 0xCC, 0x49, 0x09, 0x18, 0x05, 0x98, 0x01, 0x62, 0x09, 0xB0, 0xF0, 0xBD, 0x5D, 0x0D, 0x1B, 0x00, 0x81, 0xE7, 0x02, 0x00, 0x09, 0xB4, 0x03, 0x00, 0x27, 0x1A, 0x02, 0x00, 0x2F, 0x7A, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x05, 0x10, 0x00, 0x00, 0xCF, 0xF6, 0x00, 0x00, 0xD5, 0xF4, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x91, 0x19, 0x02, 0x00, 0x50, 0x65, 0x08, 0x00, 0x71, 0xC0, 0x02, 0x00, 0x50, 0x19, 0x1B, 0x00, 0x29, 0x16, 0x01, 0x00, 0x2A, 0x03, 0x00, 0x00, 0xF0, 0xB5, 0x8B, 0xB0, 0x07, 0x90, 0x05, 0x69, 0x47, 0x69, 0x0C, 0x20, 0x38, 0x1A, 0x08, 0x90, 0xB6, 0x49, 0x8D, 0x42, 0x16, 0xD1, 0x78, 0x68, 0x0F, 0x30, 0x00, 0x11, 0x00, 0x01, 0x78, 0x60, 0x38, 0x68, 0x0B, 0x28, 0x0E, 0xD8, 0x00, 0x23, 0x68, 0x46 , -0xFF, 0xFF, 0xE2, 0x73, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x03, 0x70, 0x08, 0x98, 0x05, 0x22, 0x01, 0x24, 0xA6, 0x46, 0xAE, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0xAE, 0x48, 0xFF, 0x30, 0x95, 0x30, 0x07, 0x99, 0x08, 0x62, 0xAC, 0x48, 0x85, 0x42, 0x23, 0xD1, 0xAC, 0x48, 0x02, 0x78, 0x6C, 0x46, 0x22, 0x72, 0x43, 0x78, 0x63, 0x72, 0x81, 0x78, 0xA1, 0x72, 0xC0, 0x78, 0xE0, 0x72, 0x00, 0x91, 0x01, 0x90, 0x03, 0x20, 0xA6, 0x49, 0x01, 0x39, 0x01, 0x26, 0xB6, 0x46, 0xF3, 0x4E, 0xFE, 0x44, 0x30, 0x47, 0x04, 0x20, 0x20, 0x70, 0x08, 0x98, 0x9F, 0x49, 0x00, 0x22, 0x02, 0xAB, 0x01, 0x24, 0xA6, 0x46, 0x9B, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x9A, 0x48, 0xFF, 0x30, 0x95, 0x30, 0x07, 0x99, 0x08, 0x62, 0xEB, 0x49, 0x8D, 0x42, 0x14, 0xD1, 0x02, 0x22, 0x68, 0x46, 0x02, 0x70, 0x3A, 0x68, 0xAC, 0x20, 0x42, 0x43, 0x30, 0x48, 0x68, 0x30, 0x83, 0x18, 0x08, 0x98, 0x00, 0x22, 0x01, 0x24, 0xA6, 0x46, 0x8F, 0x4C, 0xFE, 0x44 , -0x20, 0x47, 0x8E, 0x48, 0xFF, 0x30, 0x95, 0x30, 0x07, 0x99, 0xFF, 0xFF, 0x78, 0x74, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x08, 0x62, 0xEF, 0x48, 0x85, 0x42, 0x00, 0xD0, 0x04, 0xE1, 0x03, 0x20, 0x8C, 0x49, 0x01, 0x22, 0x96, 0x46, 0xEC, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x86, 0x48, 0xFF, 0x30, 0x95, 0x30, 0x09, 0x90, 0x38, 0x68, 0xEA, 0x4D, 0x00, 0x28, 0x00, 0xD1, 0xE2, 0xE0, 0x01, 0x24, 0xA6, 0x46, 0xE6, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x00, 0x28, 0x00, 0xD1, 0xD6, 0xE0, 0xE4, 0x48, 0x02, 0x68, 0x03, 0x20, 0x7F, 0x49, 0x01, 0x31, 0xA6, 0x46, 0xE2, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xDF, 0x48, 0x00, 0x68, 0x00, 0x28, 0x5A, 0xD1, 0xDF, 0x4D, 0x2E, 0x20, 0x41, 0x19, 0xB8, 0x68, 0x03, 0x30, 0x08, 0x70, 0x38, 0x7A, 0x48, 0x70, 0x2E, 0x1C, 0x30, 0x36, 0xB8, 0x68, 0x28, 0x18, 0x30, 0x30, 0xDA, 0x49, 0x0A, 0x68, 0x30, 0x3A, 0x31, 0x1C, 0xA6, 0x46, 0xD8, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x78, 0x68, 0x38, 0x18 , -0x01, 0x1D, 0xBA, 0x68, 0x30, 0x1C, 0xA6, 0x46, 0xD9, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xB8, 0x68, 0x41, 0x19, 0x97, 0x22, 0xFF, 0xFF, 0x0E, 0x75, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x09, 0x30, 0x50, 0x54, 0xB8, 0x68, 0x46, 0x19, 0x9E, 0x36, 0x30, 0x70, 0x01, 0x36, 0xB8, 0x68, 0x01, 0xE0, 0x14, 0x0D, 0x1B, 0x00, 0x30, 0x18, 0xCA, 0x49, 0x0A, 0x68, 0x9E, 0x3A, 0x31, 0x1C, 0xA6, 0x46, 0xC8, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x78, 0x68, 0x38, 0x18, 0x01, 0x1D, 0xBA, 0x68, 0x30, 0x1C, 0xA6, 0x46, 0xC9, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xB8, 0x68, 0x40, 0x00, 0xC0, 0x49, 0x09, 0x68, 0x08, 0x18, 0x28, 0x18, 0xC0, 0x49, 0x0A, 0x79, 0x02, 0x70, 0x4A, 0x79, 0x42, 0x70, 0x8A, 0x79, 0x82, 0x70, 0xC9, 0x79, 0xC1, 0x70, 0x04, 0x30, 0x0F, 0x21, 0x41, 0x1A, 0x0A, 0x78, 0xBB, 0x68, 0x9A, 0x18, 0x0A, 0x70, 0x40, 0x1B, 0x00, 0x04, 0x00, 0x0C, 0xB5, 0x49, 0x08, 0x60, 0xB1, 0x48, 0x04, 0x60, 0x02, 0x20, 0x01, 0x1C , -0x11, 0x22, 0xA6, 0x46, 0xB4, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x06, 0x1C, 0x63, 0xD4, 0x03, 0x20, 0xA6, 0x46, 0xB1, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x0A, 0x90, 0x00, 0x25, 0x01, 0x1C, 0xFF, 0xFF, 0xA4, 0x75, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x8D, 0x42, 0x50, 0xD0, 0x29, 0x1C, 0x2B, 0x22, 0xA6, 0x46, 0xAD, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x0C, 0x20, 0x0A, 0x99, 0x40, 0x18, 0xAC, 0x22, 0x72, 0x43, 0xAB, 0x49, 0x8F, 0x18, 0x78, 0x63, 0x29, 0x1C, 0x18, 0x22, 0xA6, 0x46, 0xA6, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x9F, 0x48, 0x02, 0x68, 0x79, 0x6B, 0x4A, 0x60, 0x0A, 0x98, 0xAC, 0x30, 0x08, 0x60, 0x08, 0x68, 0x9A, 0x49, 0xA6, 0x46, 0xA0, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x29, 0x1C, 0x03, 0xA8, 0x10, 0x22, 0xA6, 0x46, 0x9C, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xE0, 0x21, 0x68, 0x46, 0x01, 0x74, 0x45, 0x74, 0x85, 0x74, 0xFB, 0x21, 0xC1, 0x74, 0xEE, 0x49, 0xC1, 0x81, 0x02, 0x21, 0x81, 0x81, 0x79, 0x6B, 0xCA, 0x68 , -0x01, 0x20, 0xC0, 0x03, 0x10, 0x43, 0xC8, 0x60, 0x48, 0x68, 0x00, 0x90, 0x2A, 0x1C, 0x30, 0x1C, 0x0A, 0x9D, 0x29, 0x1C, 0x03, 0xAB, 0xA6, 0x46, 0xE6, 0x4F, 0xFE, 0x44, 0x38, 0x47, 0x07, 0x1C, 0x30, 0x06, 0x00, 0x16, 0xA6, 0x46, 0xEF, 0x49, 0xFF, 0xFF, 0x3A, 0x76, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xFE, 0x44, 0x08, 0x47, 0x28, 0x1C, 0xA6, 0x46, 0xEE, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x11, 0xE0, 0x30, 0x06, 0x00, 0x16, 0xA6, 0x46, 0xE9, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x01, 0x20, 0xC7, 0x43, 0x08, 0xE0, 0x07, 0x1C, 0x06, 0xE0, 0x00, 0x20, 0x00, 0x21, 0xCF, 0x43, 0x01, 0xE0, 0x00, 0x20, 0x07, 0x1C, 0x28, 0x60, 0x00, 0x23, 0x68, 0x46, 0x03, 0x70, 0x3A, 0x06, 0x12, 0x0E, 0x08, 0x98, 0x6F, 0x49, 0x01, 0x24, 0xA6, 0x46, 0x09, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x07, 0x98, 0x09, 0x99, 0x01, 0x62, 0x0B, 0xB0, 0xF0, 0xBD, 0xC1, 0x18, 0x01, 0x00, 0xF1, 0x1B, 0x01, 0x00, 0xF3, 0x1C, 0x02, 0x00, 0x7B, 0xC0 , -0x02, 0x00, 0x91, 0xF0, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0xA3, 0xC0, 0x02, 0x00, 0xA9, 0xE9, 0x00, 0x00, 0x07, 0x02, 0x00, 0x00, 0xE4, 0x62, 0x08, 0x00, 0xAC, 0x05, 0x00, 0x00, 0xFE, 0xB5, 0x07, 0x1C, 0x7D, 0x69, 0xBE, 0x69, 0x0C, 0x20, 0x30, 0x1A, 0x01, 0x90, 0xDF, 0x4C, 0x0A, 0x2D, 0x13, 0xD1, 0xFF, 0xFF, 0xD0, 0x76, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x30, 0x68, 0xDB, 0x49, 0x08, 0x60, 0x01, 0x20, 0x86, 0x46, 0xDA, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x0A, 0x20, 0x00, 0x21, 0x01, 0x9A, 0x01, 0x23, 0x9E, 0x46, 0xE6, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xF5, 0x20, 0x80, 0x00, 0x00, 0x19, 0x38, 0x62, 0x03, 0x2D, 0x79, 0xD1, 0xF5, 0x20, 0x80, 0x00, 0x00, 0x19, 0x02, 0x90, 0x70, 0x68, 0x00, 0x28, 0x0C, 0xD1, 0x00, 0x21, 0xCF, 0x48, 0x01, 0x60, 0xCF, 0x48, 0x00, 0x68, 0x00, 0x28, 0x61, 0xD0, 0x01, 0x21, 0x8E, 0x46, 0xCD, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x5B, 0xE0, 0xCC, 0x48, 0xB1, 0x68, 0x01, 0x60 , -0xF1, 0x68, 0x41, 0x60, 0x31, 0x69, 0x81, 0x60, 0x71, 0x69, 0xC1, 0x60, 0xB1, 0x69, 0xC1, 0x63, 0xF1, 0x69, 0x01, 0x64, 0x31, 0x6A, 0xC1, 0x64, 0x01, 0x24, 0xA6, 0x46, 0xC5, 0x48, 0xFE, 0x44, 0x00, 0x47, 0xA6, 0x46, 0xC4, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x70, 0x68, 0x7D, 0x25, 0xED, 0x00, 0xA8, 0x42, 0x21, 0xD8, 0x01, 0x28, 0x18, 0xD0, 0x02, 0x28, 0x05, 0xD0, 0xFF, 0xFF, 0x66, 0x77, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x28, 0x1C, 0xA6, 0x46, 0xBE, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x1C, 0xE0, 0xB9, 0x48, 0x00, 0x23, 0x19, 0x1C, 0x59, 0x43, 0x3E, 0x22, 0x4A, 0x43, 0x82, 0x83, 0x02, 0x30, 0x01, 0x33, 0x10, 0x2B, 0xF6, 0xDB, 0xA6, 0x46, 0xB4, 0x48, 0xFE, 0x44, 0x00, 0x47, 0xB5, 0x48, 0x0D, 0xE0, 0xB5, 0x4D, 0x28, 0x1C, 0xA6, 0x46, 0xB2, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x04, 0xE0, 0xA6, 0x46, 0xAF, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x75, 0x68, 0xAE, 0x48, 0x05, 0x60, 0x05, 0x1C, 0xA7, 0x4E, 0x30, 0x68 , -0x00, 0x28, 0x06, 0xD1, 0xAD, 0x48, 0x00, 0x68, 0xA6, 0x46, 0xAC, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x30, 0x60, 0x00, 0x94, 0x2B, 0x68, 0xAA, 0x49, 0xAB, 0x4A, 0xA6, 0x46, 0xAB, 0x4D, 0xFE, 0x44, 0x28, 0x47, 0x9C, 0x48, 0x04, 0x60, 0x03, 0x20, 0x00, 0x21, 0x01, 0x9A, 0x01, 0x23, 0x9E, 0x46, 0xA7, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x02, 0x98, 0x38, 0x62, 0xFE, 0xBD, 0xC0, 0x46, 0x13, 0x7F, 0x03, 0x00, 0x12, 0x10, 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x77, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x30, 0xB5, 0x05, 0x1C, 0x00, 0x20, 0x01, 0x24, 0xA6, 0x46, 0xA0, 0x49, 0xFE, 0x44, 0x08, 0x47, 0xA6, 0x46, 0x9F, 0x49, 0xFE, 0x44, 0x08, 0x47, 0xA6, 0x46, 0x9E, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x7D, 0x21, 0xC9, 0x00, 0xA6, 0x46, 0x9E, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x9B, 0x49, 0x08, 0x18, 0x99, 0x49, 0x08, 0x80, 0x9B, 0x48, 0x0A, 0x30, 0x28, 0x62, 0x30, 0xBD, 0x11, 0x10, 0x00, 0x00, 0xDD, 0x7E, 0x03, 0x00, 0xB9, 0x90 , -0x00, 0x00, 0x6C, 0x64, 0x08, 0x00, 0xE7, 0x7E, 0x03, 0x00, 0x74, 0x64, 0x08, 0x00, 0x70, 0x64, 0x08, 0x00, 0x6D, 0xC6, 0x03, 0x00, 0x08, 0x19, 0x1B, 0x00, 0x11, 0x18, 0x02, 0x00, 0xD1, 0x78, 0x02, 0x00, 0xC9, 0xBA, 0x03, 0x00, 0x09, 0xB4, 0x03, 0x00, 0x14, 0x0D, 0x1B, 0x00, 0xFE, 0xB5, 0x02, 0x90, 0x45, 0x69, 0x68, 0x46, 0x01, 0x21, 0x8E, 0x46, 0x89, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x89, 0x48, 0x04, 0x1C, 0x68, 0x68, 0x01, 0x69, 0x4A, 0x78, 0x00, 0x27, 0x3E, 0x1C, 0x20, 0x88, 0xFF, 0xFF, 0x92, 0x78, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x40, 0x08, 0x22, 0xD3, 0x20, 0x1D, 0x89, 0x1C, 0x01, 0x23, 0x9E, 0x46, 0x83, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x07, 0xD1, 0x68, 0x68, 0x00, 0x69, 0x40, 0x78, 0x21, 0x88, 0x09, 0x04, 0x89, 0x16, 0x81, 0x42, 0x3D, 0xD0, 0x02, 0x20, 0x00, 0x5F, 0x00, 0x99, 0x08, 0x1A, 0x00, 0x04, 0x00, 0x14, 0x3C, 0x28, 0x03, 0xDD, 0x20, 0x88, 0x40, 0x10, 0x40, 0x00 , -0x20, 0x80, 0x78, 0x1C, 0x07, 0x06, 0x3F, 0x0E, 0x68, 0x68, 0x01, 0x69, 0x4A, 0x78, 0x2A, 0x34, 0x01, 0x36, 0x14, 0x2E, 0xD5, 0xDB, 0x00, 0x2A, 0x02, 0xD1, 0xAB, 0x20, 0x40, 0x00, 0x50, 0xE0, 0x00, 0x9B, 0x6D, 0x48, 0x14, 0x21, 0x00, 0x22, 0x04, 0x88, 0x64, 0x08, 0x03, 0xD3, 0x2A, 0x30, 0x01, 0x32, 0x01, 0x39, 0xF8, 0xD1, 0x12, 0x06, 0x12, 0x0E, 0x14, 0x2F, 0x16, 0xD1, 0x66, 0x48, 0x00, 0x88, 0x00, 0x06, 0x44, 0x16, 0x64, 0x49, 0x00, 0x22, 0x01, 0x20, 0x4E, 0x8D, 0x36, 0x06, 0x76, 0x16, 0xA6, 0x42, 0x02, 0xDD, 0x34, 0x1C, 0x02, 0x06, 0xFF, 0xFF, 0x28, 0x79, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x12, 0x0E, 0x2A, 0x31, 0x01, 0x30, 0x14, 0x28, 0xF3, 0xDB, 0x02, 0xE0, 0x32, 0x06, 0x12, 0x0E, 0x00, 0x9B, 0x2A, 0x20, 0x42, 0x43, 0x5A, 0x48, 0x11, 0x18, 0x0C, 0x88, 0x01, 0x20, 0x20, 0x43, 0x00, 0x04, 0x00, 0x0C, 0x08, 0x80, 0xFE, 0x24, 0xA0, 0x43, 0x14, 0x24, 0x64, 0x57, 0x64, 0x06, 0x24, 0x0E , -0x04, 0x43, 0x52, 0x48, 0x14, 0x52, 0x14, 0x18, 0x63, 0x80, 0x08, 0x88, 0x80, 0x05, 0x82, 0x0D, 0x68, 0x68, 0x00, 0x69, 0x40, 0x78, 0x80, 0x02, 0x10, 0x43, 0x08, 0x80, 0x68, 0x68, 0x02, 0x69, 0x20, 0x1D, 0x91, 0x1C, 0x52, 0x78, 0x01, 0x23, 0x9E, 0x46, 0x4B, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x02, 0x98, 0x04, 0x61, 0xFE, 0x20, 0x47, 0x49, 0x09, 0x18, 0x02, 0x98, 0x01, 0x62, 0xFE, 0xBD, 0x82, 0x69, 0x41, 0x69, 0x03, 0x69, 0x02, 0x2B, 0x0A, 0xD1, 0x01, 0x2A, 0x01, 0xD1, 0x00, 0x29, 0x05, 0xD0, 0x02, 0x2A, 0x04, 0xD1, 0x00, 0x29, 0x02, 0xD1, 0x11, 0x21, 0x00, 0xE0, 0x06, 0x21, 0x41, 0x61, 0xF7, 0x46, 0xFF, 0xFF, 0xBE, 0x79, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xC0, 0x46, 0x14, 0xE9, 0x00, 0x00, 0xC9, 0x18, 0x02, 0x00, 0x30, 0xB5, 0x05, 0x1C, 0x3A, 0x48, 0x00, 0x78, 0x00, 0x28, 0x04, 0xD0, 0x01, 0x20, 0x86, 0x46, 0x38, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x01, 0x24, 0xA6, 0x46, 0x37, 0x48, 0xFE, 0x44 , -0x00, 0x47, 0xA6, 0x46, 0x36, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x35, 0x48, 0x0E, 0x30, 0x28, 0x62, 0x30, 0xBD, 0x49, 0x19, 0x01, 0x00, 0x2F, 0x7A, 0x02, 0x00, 0x18, 0xB5, 0x43, 0x69, 0x81, 0x69, 0x31, 0x48, 0x81, 0x29, 0x00, 0xD1, 0x0B, 0x38, 0x00, 0x21, 0x00, 0x91, 0x1A, 0x68, 0x9B, 0x68, 0x01, 0x24, 0xA6, 0x46, 0x2D, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x18, 0xBD, 0x18, 0xB5, 0x40, 0x69, 0x00, 0x21, 0x00, 0x91, 0x02, 0x68, 0x83, 0x68, 0x27, 0x48, 0x01, 0x30, 0x01, 0x24, 0xA6, 0x46, 0x26, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x18, 0xBD, 0xC0, 0x46, 0x30, 0x63, 0x08, 0x00, 0x19, 0x9E, 0x00, 0x00, 0xB9, 0xEC, 0x00, 0x00, 0x74, 0x3F, 0x08, 0x00, 0x80, 0x3F, 0x08, 0x00, 0xFF, 0xFF, 0x54, 0x7A, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xB7, 0x5D, 0x03, 0x00, 0x00, 0x00, 0x1B, 0x00, 0xD3, 0x8E, 0x00, 0x00, 0xF7, 0xC6, 0x00, 0x00, 0xE5, 0x90, 0x00, 0x00, 0x68, 0x64, 0x08, 0x00, 0xC0, 0x27, 0x09, 0x00, 0xA0, 0x3B , -0x08, 0x00, 0x3D, 0x5D, 0x03, 0x00, 0x19, 0xC6, 0x00, 0x00, 0xE8, 0x3A, 0x08, 0x00, 0x81, 0x5D, 0x03, 0x00, 0xCF, 0xF6, 0x00, 0x00, 0x4B, 0x4F, 0x03, 0x00, 0x6B, 0xC0, 0x03, 0x00, 0x95, 0x1E, 0x01, 0x00, 0xDA, 0x40, 0x08, 0x00, 0xDC, 0x05, 0x00, 0x00, 0x55, 0xAA, 0x03, 0x00, 0x0D, 0x91, 0x00, 0x00, 0xD7, 0x56, 0x03, 0x00, 0x08, 0x51, 0x08, 0x00, 0x8F, 0xC6, 0x03, 0x00, 0x65, 0xB8, 0x00, 0x00, 0x09, 0xB4, 0x03, 0x00, 0x84, 0x17, 0x1B, 0x00, 0xB5, 0x86, 0x01, 0x00, 0x3D, 0x47, 0x02, 0x00, 0x73, 0x49, 0x02, 0x00, 0x5F, 0x90, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x00, 0xF7, 0xF6, 0x00, 0x00, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x76, 0xFF, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x5A, 0xFF, 0xFF, 0xBD, 0xFF, 0xB5, 0xFF, 0xFF, 0xEA, 0x7A, 0x08, 0x00, 0x58, 0x00, 0x00, 0x00, 0x68, 0x46, 0xFF, 0xF7, 0x99, 0xFF, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x83, 0xFF, 0xFF, 0xBD, 0xFF, 0xB5 , -0x68, 0x46, 0xFF, 0xF7, 0xB6, 0xFE, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x55, 0xFC, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x27, 0xFB, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0xDD, 0xFA, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x68, 0xFE, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x3D, 0xFB, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0xBE, 0xFD, 0xFF, 0xBD, 0x78, 0x7B, 0x08, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0xB5, 0xF8, 0xF0, 0x43, 0xFA, 0x00, 0xBD, 0x35, 0x66, 0x08, 0x00, 0x67, 0x66, 0x08, 0x00, 0x71, 0x65, 0x08, 0x00, 0x4D, 0x66, 0x08, 0x00, 0x25, 0x64, 0x08, 0x00, 0x81, 0x66, 0x08, 0x00, 0x8D, 0x66, 0x08, 0x00, 0x99, 0x66, 0x08, 0x00, 0x87, 0x67, 0x08, 0x00, 0xA7, 0x67, 0x08, 0x00, 0xD1, 0x67, 0x08, 0x00, 0x1B, 0x68, 0x08, 0x00, 0x57, 0x68, 0x08, 0x00, 0x2D, 0x69, 0x08, 0x00, 0xB1, 0x6B, 0x08, 0x00, 0xD5, 0x6B, 0x08, 0x00, 0xF9, 0x6B , -0x08, 0x00, 0x15, 0x6C, 0x08, 0x00, 0xA1, 0x68, 0x08, 0x00, 0x59, 0x6C, 0x08, 0x00, 0xA7, 0x6D, 0x08, 0x00, 0xFF, 0x6D, 0x08, 0x00, 0x29, 0x6E, 0x08, 0x00, 0xF9, 0x6E, 0x08, 0x00, 0xD9, 0x6C, 0x08, 0x00, 0xA5, 0x6E, 0x08, 0x00, 0xCD, 0x6D, 0x08, 0x00, 0x81, 0x6F, 0x08, 0x00, 0x1D, 0x70, 0x08, 0x00, 0x31, 0x64, 0x08, 0x00, 0x39, 0x70, 0x08, 0x00, 0x3F, 0x70, 0x08, 0x00, 0x04, 0xF3, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x00, 0xB2, 0x4E, 0x01, 0x00, 0x5A, 0xC1, 0x00, 0x00, 0x96, 0x1A, 0x01, 0x00, 0x22, 0x0B, 0x02, 0x00, 0x60, 0xD0, 0x01, 0x00, 0x06, 0x1A, 0x00, 0x00, 0xB8, 0xC6, 0x01, 0x00, 0xD8, 0x42, 0x03, 0x00, 0x16, 0x42, 0x03, 0x00, 0xEE, 0xDB, 0x00, 0x00, 0x62, 0xDC, 0x00, 0x00, 0xC8, 0xE1, 0x00, 0x00, 0x8A, 0x17, 0x02, 0x00, 0x38, 0xBE, 0x00, 0x00, 0x26, 0xC6, 0x00, 0x00, 0x56, 0xC2, 0x00, 0x00, 0x62, 0x12, 0x03, 0x00, 0xE4, 0xF4, 0x01, 0x00, 0x3A, 0xEC, 0x00, 0x00, 0x5E, 0x92, 0x00, 0x00 , -0xFE, 0xE8, 0x02, 0x00, 0x18, 0x7F, 0x00, 0x00, 0x64, 0xEC, 0x01, 0x00, 0xFE, 0x44, 0x03, 0x00, 0x1C, 0x94, 0x00, 0x00, 0xA8, 0x66, 0x03, 0x00, 0x74, 0xE9, 0x02, 0x00, 0x68, 0x1E, 0x01, 0x00, 0xBC, 0xDA, 0x00, 0x00, 0xEA, 0xE1, 0x00, 0x00, 0x24, 0xE9, 0x01, 0x00, 0x70, 0x79, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x1C, 0xF0, 0xB5, 0x88, 0xB0, 0xCA, 0x4C, 0x03, 0x20, 0x22, 0x78, 0x63, 0x78, 0xCA, 0x4E, 0x31, 0x1C, 0x01, 0x39, 0x01, 0x25, 0xAE, 0x46, 0xC7, 0x4F, 0xFE, 0x44, 0x38, 0x47, 0xA2, 0x78, 0xE3, 0x78, 0x03, 0x20, 0x31, 0x1C, 0xAE, 0x46, 0xC3, 0x4F, 0xFE, 0x44, 0x38, 0x47, 0x03, 0x20, 0x31, 0x1C, 0x01, 0x31, 0xAE, 0x46, 0xC1, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0xC1, 0x48, 0x21, 0x78, 0x01, 0x70, 0x61, 0x78, 0x41, 0x70, 0xE1, 0x78, 0xC1, 0x70, 0xA1, 0x78, 0x81, 0x70, 0xBF, 0x48, 0x04, 0x1C, 0x33, 0x3C, 0x20, 0x1C, 0x00, 0x21, 0xDC, 0x22, 0xAE, 0x46 , -0xBA, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x84, 0x20, 0xA0, 0x70, 0x05, 0x27, 0xE7, 0x71, 0x0C, 0x26, 0x26, 0x73, 0x0D, 0x20, 0x00, 0x19, 0x98, 0xA1, 0x32, 0x1C, 0xAE, 0x46, 0xB4, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x04, 0x20, 0x60, 0x76, 0x1A, 0x20, 0x00, 0x19, 0x97, 0xA1, 0x06, 0x91, 0x04, 0x22, 0xAE, 0x46, 0xAE, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xFF, 0xFF, 0x96, 0x00, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0xA7, 0x77, 0x1F, 0x34, 0x95, 0xA1, 0x07, 0x91, 0x20, 0x1C, 0x3A, 0x1C, 0xAE, 0x46, 0xA9, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xE6, 0x71, 0x28, 0x1C, 0x60, 0x72, 0x11, 0x20, 0x20, 0x73, 0x94, 0x20, 0x60, 0x73, 0xC0, 0x25, 0x65, 0x74, 0xA6, 0x74, 0x09, 0x22, 0xE2, 0x74, 0xA3, 0x4C, 0x20, 0x1C, 0x8C, 0xA1, 0x01, 0x23, 0x9E, 0x46, 0x9F, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x07, 0x22, 0x62, 0x72, 0x9E, 0x4C, 0x0A, 0x34, 0x20, 0x1C, 0x89, 0xA1, 0x01, 0x23, 0x9E, 0x46, 0x9A, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x04, 0x20 , -0xE0, 0x71, 0x98, 0x4C, 0x12, 0x34, 0x20, 0x1C, 0x06, 0x99, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0x94, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x27, 0x71, 0x93, 0x4C, 0x17, 0x34, 0x20, 0x1C, 0x07, 0x99, 0x3A, 0x1C, 0x01, 0x23, 0x9E, 0x46, 0x8E, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xE6, 0x71, 0x01, 0x20, 0x60, 0x72, 0x11, 0x20, 0x20, 0x73, 0x94, 0x20, 0x60, 0x73, 0x02, 0x20, 0xE0, 0x73, 0x25, 0x74, 0x66, 0x74, 0xFF, 0xFF, 0x2C, 0x01, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0xA5, 0x74, 0x2F, 0x27, 0xE7, 0x74, 0x10, 0x20, 0x60, 0x75, 0x80, 0x26, 0xA6, 0x75, 0x01, 0x20, 0xE0, 0x75, 0x11, 0x20, 0xA0, 0x76, 0x94, 0x20, 0xE0, 0x76, 0x24, 0x20, 0x60, 0x77, 0x0A, 0x22, 0xA2, 0x77, 0x80, 0x4C, 0x36, 0x34, 0x20, 0x1C, 0x6D, 0xA1, 0x01, 0x23, 0x9E, 0x46, 0x7C, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x18, 0x22, 0xA2, 0x72, 0x7A, 0x4C, 0x41, 0x34, 0x20, 0x1C, 0x6B, 0xA1, 0x01, 0x23, 0x9E, 0x46, 0x76, 0x4B, 0xFE, 0x44, 0x18, 0x47 , -0x25, 0x76, 0x67, 0x76, 0x21, 0x20, 0xE0, 0x76, 0x26, 0x77, 0x01, 0x20, 0x60, 0x77, 0x72, 0x48, 0x61, 0x30, 0x11, 0x21, 0x01, 0x70, 0x94, 0x21, 0x41, 0x70, 0x04, 0x21, 0x01, 0x72, 0xD2, 0x21, 0x41, 0x72, 0xC5, 0x72, 0x1E, 0x21, 0x01, 0x73, 0x45, 0x73, 0x9E, 0x21, 0x81, 0x73, 0x01, 0x21, 0x01, 0x74, 0x46, 0x74, 0x81, 0x74, 0x11, 0x21, 0x41, 0x75, 0x94, 0x21, 0x81, 0x75, 0x04, 0x21, 0x01, 0x76, 0xAD, 0x20, 0x66, 0x49, 0x08, 0x60, 0x00, 0x24, 0x0F, 0x25, 0xFF, 0xFF, 0xC2, 0x01, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0x29, 0x06, 0x09, 0x0E, 0x00, 0x20, 0x6A, 0x46, 0x01, 0x23, 0x9E, 0x46, 0x62, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x6B, 0x46, 0x18, 0x88, 0x40, 0x08, 0x0E, 0xD3, 0xA0, 0x00, 0x0F, 0x21, 0xCA, 0x43, 0x69, 0x46, 0x0E, 0x88, 0x16, 0x40, 0x01, 0xAF, 0x3E, 0x52, 0x49, 0x88, 0x11, 0x40, 0x68, 0x44, 0xC1, 0x80, 0x60, 0x1C, 0x04, 0x04, 0x24, 0x0C, 0x01, 0x3D, 0x0B, 0x2D, 0xE0, 0xDA, 0x60, 0x1E , -0x00, 0x04, 0x00, 0x0C, 0x1D, 0xD0, 0x86, 0x46, 0x01, 0x1C, 0x01, 0xAD, 0x01, 0x22, 0xAE, 0x88, 0x90, 0x00, 0xC7, 0x5A, 0xB7, 0x42, 0x0A, 0xDA, 0xBC, 0x46, 0x07, 0x1C, 0x6F, 0x44, 0x7F, 0x88, 0x68, 0x44, 0x06, 0x80, 0xEE, 0x88, 0x46, 0x80, 0x60, 0x46, 0xA8, 0x80, 0xEF, 0x80, 0x04, 0x35, 0x50, 0x1C, 0x02, 0x04, 0x12, 0x0C, 0x01, 0x39, 0xE9, 0xD1, 0x70, 0x46, 0x01, 0x38, 0x86, 0x46, 0xE2, 0xD1, 0x99, 0x88, 0x68, 0x46, 0xC0, 0x88, 0x40, 0x18, 0x00, 0x04, 0x00, 0x0C, 0x42, 0x4B, 0x18, 0x80, 0x42, 0x49, 0x08, 0x1A, 0xFF, 0xFF, 0x58, 0x02, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0x58, 0x80, 0x02, 0x2C, 0x1E, 0xDB, 0x65, 0x1E, 0x01, 0xAA, 0x01, 0x20, 0x01, 0x1C, 0x8C, 0x00, 0x6B, 0x46, 0xE6, 0x5A, 0x93, 0x88, 0xD4, 0x88, 0xE7, 0x18, 0xB7, 0x42, 0x0C, 0xDA, 0x06, 0x24, 0x44, 0x43, 0x38, 0x4B, 0x1B, 0x19, 0x1F, 0x80, 0x1C, 0x88, 0x34, 0x1B, 0x5C, 0x80, 0x01, 0x24, 0x1C, 0x71, 0x40, 0x1C, 0x00, 0x04 , -0x00, 0x0C, 0x04, 0x32, 0x49, 0x1C, 0x09, 0x06, 0x09, 0x0E, 0x01, 0x3D, 0xE4, 0xD1, 0x00, 0x24, 0x31, 0x48, 0x04, 0x70, 0x31, 0x48, 0x04, 0x70, 0x31, 0x48, 0x04, 0x70, 0x31, 0x48, 0x04, 0x70, 0x01, 0x20, 0x86, 0x46, 0x30, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x2F, 0x49, 0x22, 0x1C, 0x08, 0x68, 0x00, 0x28, 0x02, 0xD0, 0x01, 0x20, 0x90, 0x40, 0x04, 0x43, 0x04, 0x31, 0x01, 0x32, 0x20, 0x2A, 0xF5, 0xD3, 0x2A, 0x48, 0x04, 0x60, 0x08, 0xB0, 0xF0, 0xBD, 0x5F, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2D, 0x69, 0x6E, 0x66, 0x6F, 0x00, 0xC0, 0x46, 0xC0, 0x5F, 0x75, 0x64, 0x70, 0x00, 0xC0, 0xFF, 0xFF, 0xEE, 0x02, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0x46, 0xC0, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x00, 0xC0, 0x46, 0x5F, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x00, 0xC0, 0x46, 0x5F, 0x64, 0x6E, 0x73, 0x2D, 0x73, 0x64, 0x00, 0x64, 0x65, 0x76, 0x3D, 0x43, 0x43, 0x33, 0x30, 0x30, 0x30, 0x00, 0xC0, 0x76, 0x65 , -0x6E, 0x64, 0x6F, 0x72, 0x3D, 0x54, 0x65, 0x78, 0x61, 0x73, 0x2D, 0x49, 0x6E, 0x73, 0x74, 0x72, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x00, 0xC0, 0x46, 0xC0, 0x00, 0x00, 0x18, 0x00, 0xF3, 0x7E, 0x03, 0x00, 0xC6, 0x05, 0x00, 0x00, 0xDD, 0x7E, 0x03, 0x00, 0xE4, 0x62, 0x08, 0x00, 0xC9, 0xBA, 0x03, 0x00, 0x09, 0xB4, 0x03, 0x00, 0xA7, 0x64, 0x08, 0x00, 0x70, 0x64, 0x08, 0x00, 0xDD, 0x0A, 0x02, 0x00, 0x48, 0x32, 0x08, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xE8, 0x62, 0x08, 0x00, 0xE9, 0x62, 0x08, 0x00, 0xEA, 0x62, 0x08, 0x00, 0xEB, 0x62, 0x08, 0x00, 0x81, 0x03, 0x18, 0x00, 0x80, 0x7B, 0x08, 0x00, 0x84, 0xF3, 0x1A, 0x00, 0x0D, 0x49, 0x0E, 0x48, 0xFF, 0xFF, 0x84, 0x03, 0x18, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x88, 0x67, 0x0E, 0x48, 0x88, 0x64, 0x0E, 0x48, 0x48, 0x64, 0x0E, 0x48, 0xC8, 0x64, 0x0E, 0x48, 0x08, 0x65, 0x11, 0x48, 0x02, 0x1C, 0x04, 0x32, 0x0C, 0x4B, 0x13, 0x60, 0x0C, 0x4B, 0x93, 0x62, 0x0C, 0x4A , -0x8A, 0x66, 0x0D, 0x49, 0x01, 0x60, 0x0D, 0x48, 0x0E, 0x49, 0x01, 0x60, 0x0E, 0x49, 0x41, 0x60, 0xF7, 0x46, 0x1C, 0x21, 0x08, 0x00, 0x1B, 0x7B, 0x08, 0x00, 0x11, 0x7B, 0x08, 0x00, 0x07, 0x7B, 0x08, 0x00, 0x39, 0x7B, 0x08, 0x00, 0x2F, 0x7B, 0x08, 0x00, 0x25, 0x7B, 0x08, 0x00, 0xFD, 0x7A, 0x08, 0x00, 0xDF, 0x7A, 0x08, 0x00, 0x50, 0x23, 0x08, 0x00, 0xD5, 0x7A, 0x08, 0x00, 0x58, 0x26, 0x08, 0x00, 0xF3, 0x7A, 0x08, 0x00, 0xE9, 0x7A, 0x08, 0x00 }; - - -const unsigned char cRMdefaultParams[128] = { 0x03, 0x00, 0x01, 0x01, 0x14, 0x14, 0x00, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x23, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x23, 0x23, 0x23, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x01, 0x77, 0x80, 0x1D, 0x1F, 0x22, 0x26, 0x28, 0x29, 0x1A, 0x1F, 0x22, 0x24, 0x26, 0x28, 0x16, 0x1D, 0x1E, 0x20, 0x24, 0x25, 0x1E, 0x2D, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x15, 0x15, 0x15, 0x11, 0x15, 0x15, 0x0E, 0x00}; - -// -//Service Pack version P1.13.7.15.15 - FW patches -// -const unsigned char fw_patch[5700] = { 0x00, 0x01, 0x00, 0x00, 0x3C, 0x16, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x14, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x68, 0x46, 0x25, 0xF0, 0x95, 0xFB, 0xE0, 0x6B, 0xD0, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x25, 0xF0, 0x38, 0xFB, 0x2C, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x25, 0xF0, 0x0A, 0xFB, 0x04, 0x15, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xB8, 0xF1, 0x90, 0x0F, 0xA4, 0x16, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x66, 0xE0, 0x04, 0xA8, 0x35, 0x1D, 0x21, 0xF0, 0x99, 0xFC, 0x68, 0x46, 0x23, 0xF0, 0x28, 0xFB, 0x9A, 0xF8, 0x00, 0x00, 0x01, 0x28, 0x07, 0xD1, 0x28, 0x46, 0x05, 0xF0, 0xC3, 0xFE, 0x01, 0x46, 0x01, 0xAA, 0x00, 0x20, 0x21, 0xF0, 0x50, 0xF9, 0x28, 0x46, 0x05, 0xF0, 0xBB, 0xFE, 0x01, 0xA9, 0x21, 0xF0, 0x2A, 0xFA, 0xE9, 0x79, 0x4F, 0xEA, 0xE0, 0x00, 0x40, 0xB2, 0x11, 0xB1, 0x00, 0xF1, 0x06, 0x00, 0x40, 0xB2, 0xA8, 0x71, 0x1F, 0x38, 0x40, 0x00, 0xE8, 0x71, 0x30, 0x46 , -0x01, 0xF0, 0x0D, 0xFF, 0x10, 0xF1, 0x00, 0x09, 0x4F, 0xF0, 0x00, 0x01, 0x09, 0xD0, 0x28, 0x68, 0x40, 0x0C, 0x09, 0xD3, 0xE8, 0x68, 0xC0, 0x0B, 0x03, 0xD2, 0x48, 0x46, 0xFF, 0xF7, 0xDD, 0xFE, 0x01, 0x21, 0x28, 0x68, 0x40, 0x0C, 0x0A, 0xD2, 0x38, 0x68, 0x40, 0x1C, 0x38, 0x60, 0x20, 0x68, 0x6F, 0xF3, 0x0F, 0x00, 0x20, 0x60, 0x22, 0x68, 0x38, 0x68, 0x10, 0x43, 0x20, 0x60, 0xE8, 0x68, 0xC0, 0x0B, 0x0F, 0xD3, 0xD8, 0xF8, 0x00, 0x00, 0x00, 0xF1, 0x01, 0x00, 0xC8, 0xF8, 0x00, 0x00, 0x20, 0x68, 0x6F, 0xF3, 0x1F, 0x40, 0x20, 0x60, 0xD8, 0xF8, 0x00, 0x20, 0x20, 0x68, 0x40, 0xEA, 0x02, 0x40, 0x20, 0x60, 0x49, 0xB9, 0xB9, 0xF1, 0x00, 0x0F, 0x03, 0xD1, 0x30, 0x46, 0x07, 0xF0, 0xBE, 0xF9, 0x02, 0xE0, 0x48, 0x46, 0x07, 0xF0, 0x06, 0xFA, 0x6C, 0x17, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x68, 0x46, 0x0E, 0xF0, 0x85, 0xFB, 0x00, 0x9E, 0x00, 0x2E, 0x96, 0xD1, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0xC0, 0x46 , -0x9C, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x23, 0xF0, 0x2A, 0xFE, 0x74, 0x47, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x21, 0x21, 0xF0, 0x41, 0xFA, 0x20, 0x68, 0x18, 0x4B, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x21, 0xF0, 0x1C, 0xF9, 0x0A, 0xE0, 0x20, 0x68, 0x00, 0x68, 0x0C, 0x21, 0x40, 0xF0, 0x20, 0x00, 0x21, 0xF0, 0x14, 0xF9, 0x10, 0x57, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0xA8, 0x20, 0xF0, 0x97, 0xF9, 0x01, 0x98, 0x5C, 0x57, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x20, 0xF0, 0x71, 0xF9, 0x03, 0x98, 0x00, 0x58, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0xF0, 0x20, 0xF9, 0x1C, 0x58, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0xF0, 0x12, 0xF9, 0x54, 0x58, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0xA8, 0x20, 0xF0, 0xF5, 0xF8, 0x04, 0xAB, 0x04, 0x62, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x79, 0x1F, 0xF0, 0x1B, 0xFD, 0x69, 0xE0, 0x60, 0x93, 0x00, 0x00, 0x40, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xA6, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1B, 0xF0, 0x39, 0xFB, 0x28, 0x46, 0x90, 0xA8, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1B, 0xF0, 0x69, 0xF9, 0x1E, 0x48, 0x34, 0xAD, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x68, 0xFF, 0x29, 0x98, 0xAD, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, 0xD4, 0x21, 0xD4, 0xB2, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0xD0, 0x1A, 0xF0, 0x47, 0xFC, 0x20, 0x98, 0xAC, 0xC5, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x78, 0x19, 0xF0 , -0xDB, 0xFA, 0x09, 0x49, 0x28, 0xC6, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x19, 0xF0, 0x9E, 0xFA, 0xDC, 0xD3, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xB5, 0x18, 0xF0, 0xAB, 0xFC, 0x00, 0xF0, 0x03, 0xF8, 0x00, 0xBD, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xDF, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x17, 0xF0, 0xA8, 0xFD, 0xCC, 0xEB, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x38, 0x78, 0x17, 0xF0, 0x77, 0xF8, 0x38, 0x78, 0x16, 0xF0, 0xF0, 0xFF, 0xA8, 0xF7, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0E, 0x49, 0x09, 0x68, 0x23, 0x22, 0x41, 0x61, 0xC8, 0xF7, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x31, 0x2E, 0x31, 0x39, 0x2E, 0x33, 0x31, 0x34, 0x5F, 0x4E, 0x65, 0x77, 0x5F, 0x43, 0x43, 0x41, 0x5F, 0x61, 0x6C, 0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, 0xC0, 0x74, 0x56, 0x30, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xF9, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x16, 0xF0, 0x79, 0xF8 , -0x12, 0xE0, 0x38, 0xFA, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0xA8, 0x16, 0xF0, 0x03, 0xF8, 0x32, 0x20, 0x94, 0xFB, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x0C, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x14, 0xF0, 0x05, 0xFF, 0x01, 0xF0, 0x10, 0x1B, 0x01, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1E, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0xF0, 0x46, 0xBF, 0x18, 0x30, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x30, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x12, 0xF0, 0xD8, 0xFC, 0x9C, 0x31, 0x01, 0x00, 0x08, 0x00 , -0x00, 0x00, 0x68, 0x46, 0x12, 0xF0, 0x51, 0xFC, 0xFE, 0xF7, 0xF0, 0x35, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x68, 0x46, 0x12, 0xF0, 0x27, 0xFA, 0xFE, 0xF7, 0xF0, 0x3D, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0xA9, 0x11, 0xF0, 0x27, 0xFE, 0x20, 0x6F, 0xD0, 0x62, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0xB8, 0xFB, 0x80, 0x7E, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0xDF, 0xF8, 0x58, 0x82, 0xE0, 0x7E, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0D, 0xF0, 0x6A, 0xFE, 0x0B, 0xF0, 0x9A, 0xF9, 0x03, 0x20, 0xA8, 0xF5, 0x88, 0x71, 0x08, 0x60, 0xF2, 0xF7, 0x16, 0xF9, 0x7A, 0x48, 0x6B, 0x49, 0x9C, 0x7F, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x70, 0x51, 0x4D, 0xC4, 0x7F, 0x01, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x40, 0x49, 0x00, 0xF1, 0x52, 0x00, 0x3A, 0x4A, 0xA8, 0x81, 0x28, 0x83, 0xE8, 0x83, 0xE8, 0x84, 0xA8, 0x85, 0x2A, 0x60, 0x39, 0x48, 0x41, 0xF2, 0x11, 0x12, 0x2A, 0x85, 0x18, 0x90, 0x19, 0x91 , -0x39, 0x49, 0x1A, 0x91, 0x39, 0x49, 0x1B, 0x91, 0x39, 0x49, 0x20, 0x46, 0xDF, 0xF8, 0xC4, 0x90, 0x1C, 0x91, 0x38, 0x49, 0xDF, 0xF8, 0xC0, 0xB0, 0x31, 0x4E, 0x1D, 0x91, 0x48, 0x80, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0xF0, 0x7C, 0xFA, 0xB4, 0x80, 0x01, 0x00, 0x34, 0x00, 0x00, 0x00, 0x34, 0x12, 0x66, 0x09, 0x84, 0x6B, 0x00, 0x20, 0x94, 0x70, 0x00, 0x20, 0xB4, 0x70, 0x00, 0x20, 0xC4, 0x78, 0x00, 0x20, 0x50, 0x7A, 0x00, 0x20, 0xFE, 0xFF, 0x03, 0x00, 0xA4, 0x70, 0x00, 0x20, 0xB0, 0x70, 0x00, 0x20, 0xB8, 0x70, 0x00, 0x20, 0x60, 0x55, 0x30, 0x80, 0x3C, 0x5C, 0x00, 0x20, 0x04, 0x74, 0x00, 0x20, 0xB8, 0xE4, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x20, 0x78, 0x07, 0xF0, 0x01, 0xFC, 0x20, 0x78, 0x07, 0xF0, 0x7A, 0xFB, 0x04, 0x4D, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0xAD, 0xF1, 0x8C, 0x0D, 0x04, 0x68, 0x0F, 0x30, 0x03, 0x94, 0xFE, 0xF7, 0xDB, 0xFA, 0x04, 0xF1, 0x14, 0x00 , -0x04, 0x90, 0x21, 0x7D, 0x00, 0x20, 0x21, 0xF0, 0x73, 0x01, 0x88, 0x29, 0x08, 0xBF, 0x01, 0x20, 0x05, 0x90, 0x03, 0x98, 0x00, 0x1D, 0x06, 0x90, 0x5D, 0x48, 0x00, 0x68, 0x01, 0x28, 0x40, 0xF0, 0xFA, 0x83, 0x5B, 0x4D, 0x5C, 0x48, 0xDF, 0xF8, 0x70, 0x91, 0x29, 0x68, 0xDF, 0xF8, 0x70, 0x81, 0xDF, 0xF8, 0x74, 0xA1, 0x88, 0x42, 0x21, 0xD1, 0x10, 0x22, 0x00, 0x21, 0x48, 0x46, 0x4F, 0x46, 0xFB, 0xF7, 0xB7, 0xFE, 0x10, 0x22, 0x00, 0x21, 0x40, 0x46, 0xFB, 0xF7, 0xB2, 0xFE, 0x54, 0x49, 0x08, 0x68, 0x40, 0xF4, 0x80, 0x10, 0x08, 0x60, 0x01, 0x20, 0x51, 0x46, 0x08, 0x60, 0x00, 0x21, 0x29, 0x60, 0x39, 0x78, 0x46, 0x46, 0x00, 0x91, 0x31, 0x78, 0x41, 0xF2, 0x11, 0x13, 0x04, 0x22, 0x01, 0x91, 0x07, 0x21, 0x02, 0x90, 0x03, 0x20, 0xF3, 0xF7, 0x41, 0xFC, 0x51, 0x46, 0x07, 0x91, 0x08, 0x68, 0x56, 0x49, 0xDF, 0xF8, 0x5C, 0xB1, 0x01, 0x28, 0x08, 0x91, 0x56, 0x49, 0xDF, 0xF8, 0x48, 0xA1, 0x09, 0x91, 0x55, 0x49 , -0x0A, 0x91, 0x44, 0x49, 0x0B, 0x91, 0x44, 0x49, 0x0C, 0x91, 0x44, 0x49, 0x0D, 0x91, 0x44, 0x49, 0x0E, 0x91, 0x44, 0x49, 0x0F, 0x91, 0x44, 0x49, 0x10, 0x91, 0x44, 0x49, 0xCC, 0x4D, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x11, 0x91, 0x44, 0x49, 0x12, 0x91, 0x44, 0x49, 0x13, 0x91, 0x44, 0x49, 0x14, 0x91, 0x44, 0x49, 0x15, 0x91, 0x44, 0x49, 0x16, 0x91, 0x9F, 0x49, 0x17, 0x91, 0x9F, 0x49, 0x18, 0x91, 0x9F, 0x49, 0x19, 0x91, 0x9F, 0x49, 0x1A, 0x91, 0x9F, 0x49, 0x1B, 0x91, 0x9F, 0x49, 0x1C, 0x91, 0x9F, 0x49, 0x1D, 0x91, 0x9F, 0x49, 0x1E, 0x91, 0x9F, 0x49, 0x1F, 0x91, 0x40, 0xF0, 0x00, 0x81, 0x04, 0x98, 0x40, 0x78, 0x00, 0xF0, 0x03, 0x01, 0x01, 0x29, 0x40, 0xF0, 0xF9, 0x80, 0x04, 0x99, 0x09, 0x78, 0x01, 0xF0, 0x0C, 0x01, 0x08, 0x29, 0x40, 0xF0, 0xF2, 0x80, 0x06, 0x99, 0x09, 0x88, 0xA1, 0xF1, 0x3C, 0x01, 0x0E, 0xB2, 0x05, 0x99, 0x11, 0xB1, 0xA6, 0xF1, 0x02, 0x06, 0x36, 0xB2, 0xC0, 0x09, 0x4F, 0xF0 , -0x00, 0x07, 0x15, 0xD3, 0x08, 0x3E, 0x36, 0xB2, 0x03, 0x2E, 0x10, 0xD0, 0x17, 0x2E, 0x0E, 0xD0, 0x08, 0x3E, 0x36, 0xB2, 0x03, 0x2E, 0x08, 0xD0, 0x17, 0x2E, 0x06, 0xD0, 0x36, 0x1F, 0x36, 0xB2, 0x03, 0x2E, 0x14, 0xBF, 0x17, 0x2E, 0x02, 0x27, 0x02, 0xE0, 0x03, 0x27, 0x00, 0xE0, 0x01, 0x27, 0x03, 0x2E, 0x18, 0xBF, 0x17, 0x2E, 0x04, 0x9A, 0x40, 0xF0, 0xC8, 0x80, 0x0A, 0x32, 0x12, 0xF8, 0x01, 0x1B, 0x05, 0x24, 0x12, 0xF8, 0x01, 0x3B, 0x4B, 0x40, 0x64, 0x1E, 0xD9, 0xB2, 0xF9, 0xD1, 0x81, 0xEA, 0x21, 0x11, 0x03, 0x2E, 0x94, 0x4E, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x01, 0xF0, 0x0F, 0x01, 0x48, 0x46, 0x35, 0xD0, 0x43, 0x46, 0xCA, 0x5C, 0x52, 0x1C, 0xCA, 0x54, 0x0C, 0x18, 0x33, 0xE0, 0x50, 0x57, 0x02, 0x00, 0x04, 0x74, 0x00, 0x20, 0x34, 0x12, 0x66, 0x09, 0x60, 0x57, 0x02, 0x00, 0x70, 0x57, 0x02, 0x00, 0xC8, 0x48, 0x30, 0x80, 0x4C, 0x57, 0x02, 0x00, 0x88, 0x57, 0x02, 0x00, 0x80, 0x57, 0x02, 0x00 , -0x18, 0x58, 0x02, 0x00, 0x20, 0x58, 0x02, 0x00, 0x28, 0x58, 0x02, 0x00, 0x30, 0x58, 0x02, 0x00, 0x38, 0x58, 0x02, 0x00, 0x40, 0x58, 0x02, 0x00, 0xE4, 0x58, 0x02, 0x00, 0xE2, 0x58, 0x02, 0x00, 0x14, 0x58, 0x02, 0x00, 0xEF, 0x58, 0x02, 0x00, 0xE0, 0x58, 0x02, 0x00, 0xEE, 0x58, 0x02, 0x00, 0x5C, 0x57, 0x02, 0x00, 0xE6, 0x58, 0x02, 0x00, 0xE8, 0x58, 0x02, 0x00, 0x0C, 0x18, 0x20, 0x78, 0x40, 0x1C, 0x20, 0x70, 0x20, 0x78, 0x43, 0x46, 0x03, 0xEB, 0x01, 0x08, 0x0A, 0x28, 0x76, 0xDB, 0x98, 0xF8, 0x00, 0x00, 0x0A, 0x28, 0x72, 0xDB, 0x94, 0x48, 0x00, 0x25, 0x01, 0x60, 0x04, 0x98, 0x00, 0xF1, 0x0A, 0x09, 0x40, 0x78, 0x41, 0x08, 0x24, 0xBF, 0x04, 0x99, 0x09, 0x1D, 0x04, 0xD2, 0x80, 0x08, 0x2E, 0xBF, 0x49, 0x46, 0x04, 0x99, 0x10, 0x31, 0x0B, 0x98, 0x06, 0x22, 0xFA, 0xF7, 0xB9, 0xFC, 0x0C, 0x98, 0x06, 0x22, 0x49, 0x46, 0xFA, 0xF7, 0xB4, 0xFC, 0x9B, 0x48, 0x9A, 0x49, 0x5C, 0x4F, 0x02, 0x00, 0xC8, 0x00 , -0x00, 0x00, 0x00, 0x78, 0x08, 0x22, 0x08, 0x60, 0x58, 0x46, 0x07, 0x60, 0x0D, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0xAF, 0xFD, 0x08, 0x22, 0x0E, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0xAA, 0xFD, 0x08, 0x22, 0x0F, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0xA5, 0xFD, 0x08, 0x22, 0x10, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0xA0, 0xFD, 0x08, 0x22, 0x11, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0x9B, 0xFD, 0x08, 0x22, 0x12, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0x96, 0xFD, 0x07, 0x99, 0x02, 0x20, 0x08, 0x60, 0x13, 0x99, 0x28, 0x46, 0x08, 0x80, 0x08, 0x99, 0x08, 0x70, 0x14, 0x99, 0x08, 0x70, 0x15, 0x99, 0x08, 0x60, 0x16, 0x99, 0x08, 0x70, 0x17, 0x99, 0x08, 0x60, 0x18, 0x99, 0x08, 0x60, 0x19, 0x99, 0x08, 0x60, 0x09, 0x99, 0x08, 0x80, 0x0A, 0x99, 0x08, 0x80, 0x1A, 0x99, 0x08, 0x80, 0x7D, 0x49, 0x0D, 0x60, 0x1B, 0x99, 0x08, 0x70, 0x1C, 0x99, 0x08, 0x70, 0x1D, 0x99, 0x08, 0x70, 0x1E, 0x99, 0x08, 0x80, 0x1F, 0x99, 0x08, 0x80, 0x51, 0x46, 0x08, 0x80 , -0x20, 0x78, 0x00, 0x96, 0x04, 0x22, 0x01, 0x90, 0x98, 0xF8, 0x00, 0x00, 0x41, 0xF2, 0x14, 0x13, 0x07, 0x21, 0x02, 0x90, 0x03, 0x20, 0xF3, 0xF7, 0x07, 0xFB, 0x07, 0x98, 0xA2, 0x49, 0x00, 0x68, 0x20, 0x91, 0xA2, 0x49, 0x05, 0x28, 0x21, 0x91, 0x9E, 0x49, 0x22, 0x91, 0x40, 0xF0, 0x37, 0x82, 0x04, 0x98, 0x40, 0x78, 0x24, 0x50, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x41, 0x08, 0x24, 0xBF, 0x04, 0x99, 0x09, 0x1D, 0x05, 0xD2, 0x80, 0x08, 0x27, 0xBF, 0x04, 0x99, 0x0A, 0x31, 0x04, 0x99, 0x10, 0x31, 0x0B, 0x98, 0xF8, 0xF7, 0x2D, 0xFC, 0x01, 0x28, 0x04, 0x98, 0x40, 0xF0, 0x23, 0x82, 0x40, 0x78, 0x00, 0xF0, 0x03, 0x00, 0x03, 0x28, 0x18, 0xD0, 0x02, 0x28, 0x07, 0xBF, 0x04, 0x99, 0x10, 0x31, 0x04, 0x99, 0x0A, 0x31, 0x13, 0xE0, 0x48, 0x58, 0x02, 0x00, 0x4C, 0x58, 0x02, 0x00, 0x50, 0x58, 0x02, 0x00, 0xF0, 0x58, 0x02, 0x00, 0xF2, 0x58, 0x02, 0x00, 0xF3, 0x58, 0x02, 0x00, 0xF4, 0x58, 0x02, 0x00, 0xEA, 0x58 , -0x02, 0x00, 0xEC, 0x58, 0x02, 0x00, 0x04, 0x99, 0x18, 0x31, 0x0C, 0x98, 0xF8, 0xF7, 0x06, 0xFC, 0x04, 0x99, 0x01, 0x28, 0x40, 0xF0, 0xFC, 0x81, 0x49, 0x78, 0x01, 0xF0, 0x03, 0x01, 0x01, 0x29, 0x40, 0xF0, 0xF6, 0x81, 0x59, 0x46, 0x09, 0x68, 0x04, 0x9A, 0x8E, 0x46, 0x51, 0x46, 0xD2, 0x8A, 0x0B, 0x88, 0x12, 0x11, 0x93, 0x42, 0x00, 0xF0, 0x37, 0x82, 0x0A, 0x80, 0x06, 0x99, 0x09, 0x88, 0x3C, 0x39, 0x0B, 0xB2, 0x71, 0x46, 0x49, 0x1E, 0x09, 0xD0, 0x49, 0x1E, 0x04, 0xD0, 0x49, 0x1E, 0x08, 0xD1, 0xA3, 0xF1, 0x10, 0x03, 0x04, 0xE0, 0xA3, 0xF1, 0x14, 0x03, 0x01, 0xE0, 0xA3, 0xF1, 0x08, 0x03, 0x1B, 0xB2, 0x05, 0x98, 0x10, 0xB1, 0xA3, 0xF1, 0x02, 0x03, 0x1B, 0xB2, 0xEC, 0x50, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0xF1, 0xCE, 0x81, 0x16, 0x98, 0x40, 0xF2, 0x77, 0x51, 0x99, 0x42, 0x0B, 0x90, 0x14, 0x98, 0x05, 0x90, 0x00, 0xF0, 0xA3, 0x81, 0x08, 0x46, 0x00, 0xF1, 0x3C, 0x00, 0x98, 0x42 , -0x05, 0x9A, 0x00, 0xF0, 0x9A, 0x81, 0xDF, 0xF8, 0x48, 0x82, 0x14, 0x78, 0x0B, 0x9A, 0xBB, 0x2C, 0x12, 0x78, 0x0C, 0x92, 0x63, 0xD1, 0xDD, 0xF8, 0x68, 0xC0, 0xBC, 0xF9, 0x00, 0x20, 0x91, 0x42, 0x18, 0xBF, 0x90, 0x42, 0x5B, 0xD1, 0x1C, 0x2B, 0x4F, 0xF0, 0x00, 0x00, 0xC0, 0xF2, 0x82, 0x81, 0x3D, 0x2B, 0x13, 0x9D, 0x80, 0xF2, 0x7E, 0x81, 0xA3, 0xF1, 0x1C, 0x01, 0x09, 0xB2, 0x29, 0x80, 0x1E, 0x9A, 0xDD, 0xF8, 0x30, 0x90, 0xB2, 0xF9, 0x00, 0x60, 0xB9, 0xF1, 0x01, 0x0F, 0x15, 0xD1, 0xDD, 0xF8, 0x24, 0x90, 0x03, 0x2E, 0x0D, 0xDA, 0xB9, 0xF9, 0x00, 0x70, 0xB9, 0x42, 0x07, 0xD0, 0x01, 0x26, 0x16, 0x80, 0x4A, 0x46, 0x0E, 0x46, 0x03, 0xE0, 0xC0, 0x46, 0x90, 0x57, 0x02, 0x00, 0x76, 0x1C, 0x16, 0x80, 0x1B, 0x9A, 0x16, 0x78, 0x1D, 0x9A, 0x16, 0x70, 0x0C, 0x9A, 0x1F, 0x9E, 0x02, 0x2A, 0x28, 0xD1, 0xB6, 0xF9, 0x00, 0x20, 0xBE, 0xF1, 0x00, 0x0F, 0x1A, 0xD0, 0x03, 0x2A, 0x35, 0x46, 0x0B, 0xDA, 0x0A, 0x9E , -0xB6, 0xF9, 0x00, 0x70, 0xB9, 0x42, 0x04, 0xD0, 0x01, 0x22, 0x2A, 0x80, 0x0A, 0x46, 0x35, 0x46, 0x00, 0xE0, 0xB4, 0x51, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x52, 0x1C, 0x2A, 0x80, 0x1C, 0x99, 0x0A, 0x78, 0x1D, 0x99, 0x0A, 0x70, 0x0F, 0xE0, 0xC0, 0x46, 0x58, 0x57, 0x02, 0x00, 0xA6, 0x64, 0x00, 0x20, 0x54, 0x57, 0x02, 0x00, 0x28, 0x80, 0x05, 0x99, 0x08, 0x70, 0x08, 0x9A, 0x11, 0x78, 0x41, 0xF0, 0x04, 0x01, 0x11, 0x70, 0x04, 0x46, 0x45, 0x46, 0xAC, 0xF8, 0x00, 0x00, 0x28, 0x70, 0xCC, 0x2C, 0x09, 0x9A, 0x40, 0xF0, 0x00, 0x81, 0xDD, 0xF8, 0x7C, 0xC0, 0x0A, 0x99, 0x1E, 0x9F, 0x45, 0x46, 0xB1, 0xF9, 0x00, 0x60, 0xB2, 0xF9, 0x00, 0x90, 0x28, 0x78, 0xCD, 0xF8, 0x50, 0xC0, 0x16, 0x91, 0x0A, 0x97, 0x13, 0x92, 0x09, 0x95, 0x0C, 0x99, 0x01, 0x29, 0x05, 0xD1, 0x05, 0x9A, 0xB0, 0xEB, 0x49, 0x0F, 0x01, 0xD1, 0x00, 0x21, 0x11, 0x70, 0x0C, 0x99, 0x02, 0x29, 0x05, 0xD1, 0x05, 0x9A, 0xB0, 0xEB, 0x46, 0x0F , -0x01, 0xD1, 0x00, 0x21, 0x11, 0x70, 0xB3, 0xF5, 0x14, 0x7F, 0x40, 0xF3, 0xBA, 0x80, 0x40, 0xF2, 0x51, 0x31, 0x99, 0x42, 0x08, 0x99, 0x40, 0xF3, 0xB4, 0x80, 0x09, 0x78, 0x06, 0x29, 0x00, 0xF0, 0xB0, 0x80, 0xA3, 0xF2, 0x51, 0x21, 0x0B, 0xB2, 0x4F, 0xEA, 0xE3, 0x01, 0x03, 0xEB, 0x11, 0x71, 0x4F, 0xEA, 0x21, 0x11, 0xCA, 0xB2, 0x4F, 0xEA, 0xE3, 0x01, 0x03, 0xEB, 0x11, 0x71, 0x15, 0x9D, 0x21, 0xF0, 0x0F, 0x01, 0xA3, 0xEB, 0x01, 0x03, 0x1D, 0x99, 0x2E, 0x68, 0x7C, 0x52, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x91, 0xF8, 0x00, 0xE0, 0x5F, 0xFA, 0x83, 0xF8, 0x60, 0xB1, 0x31, 0x18, 0x11, 0xF8, 0x01, 0x1C, 0x51, 0x40, 0xCB, 0xB2, 0x07, 0xE0, 0xC0, 0x46, 0x58, 0x58, 0x02, 0x00, 0x54, 0x58, 0x02, 0x00, 0xDC, 0x58, 0x02, 0x00, 0x13, 0x46, 0x19, 0x99, 0xDD, 0xF8, 0x6C, 0xA0, 0xDD, 0xF8, 0x70, 0xB0, 0xD1, 0xF8, 0x00, 0xC0, 0x00, 0xF0, 0x0F, 0x01, 0x99, 0x42, 0x22, 0xD0, 0x0A, 0x9B, 0x86, 0x45, 0x9A, 0xF8 , -0x00, 0x10, 0xB3, 0xF9, 0x00, 0x30, 0x9B, 0xF8, 0x00, 0x50, 0x15, 0xDD, 0x37, 0x5C, 0x44, 0x1C, 0x82, 0xEA, 0x07, 0x0C, 0x04, 0xF0, 0x0F, 0x07, 0x67, 0x45, 0x0B, 0xD0, 0xA6, 0x45, 0x06, 0x44, 0x0A, 0xDD, 0x76, 0x78, 0x72, 0x40, 0x86, 0x1C, 0x06, 0xF0, 0x0F, 0x06, 0x96, 0x42, 0x03, 0xD1, 0xC0, 0x1C, 0x4D, 0xE0, 0x80, 0x1C, 0x4B, 0xE0, 0x05, 0x9E, 0x00, 0x22, 0x32, 0x70, 0x4A, 0xE0, 0x00, 0xF0, 0x1F, 0x01, 0x01, 0x22, 0x8A, 0x40, 0x17, 0x99, 0xC4, 0x10, 0x0B, 0x68, 0x24, 0xF0, 0x03, 0x01, 0x5C, 0xF8, 0x01, 0x70, 0x3A, 0x42, 0x32, 0xD1, 0x5F, 0x58, 0x3A, 0x42, 0x06, 0x44, 0x1F, 0xD0, 0x18, 0x9B, 0x37, 0x78, 0x1B, 0x68, 0xB8, 0x45, 0x04, 0xD1, 0x58, 0x58, 0x02, 0x42, 0x19, 0xD0, 0x63, 0x46, 0x15, 0xE0, 0xA1, 0x10, 0x8C, 0x00, 0x19, 0x59, 0x91, 0x43, 0x19, 0x51, 0x00, 0x90, 0x30, 0x78, 0x01, 0x90, 0x44, 0x53, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x03, 0x20, 0x06, 0x21, 0x02, 0x46, 0x4D, 0xF6 , -0x80, 0x53, 0xF3, 0xF7, 0x63, 0xF9, 0x09, 0x99, 0x28, 0x68, 0x0E, 0x78, 0x36, 0x18, 0x06, 0xE0, 0xE3, 0x58, 0x02, 0x00, 0xA0, 0x10, 0x81, 0x00, 0x58, 0x58, 0x02, 0x43, 0x5A, 0x50, 0x86, 0xF8, 0x00, 0x80, 0x0B, 0x98, 0x00, 0x78, 0x0C, 0x90, 0x13, 0x98, 0xB0, 0xF9, 0x00, 0x90, 0x09, 0x98, 0x00, 0x78, 0x0A, 0x9A, 0x40, 0x1C, 0x9B, 0xF8, 0x00, 0x50, 0x9A, 0xF8, 0x00, 0x10, 0xB2, 0xF9, 0x00, 0x30, 0x09, 0x9A, 0xC0, 0xB2, 0x10, 0x70, 0x0C, 0x9A, 0x01, 0x2A, 0x03, 0xD1, 0x88, 0x42, 0xC8, 0xBF, 0x8A, 0xF8, 0x00, 0x00, 0x0C, 0x99, 0x02, 0x29, 0x07, 0xD1, 0xA8, 0x42, 0xC8, 0xBF, 0x8B, 0xF8, 0x00, 0x00, 0x02, 0xE0, 0x0A, 0x98, 0xB0, 0xF9, 0x00, 0x30, 0xB9, 0xF1, 0x00, 0x0F, 0x06, 0xDD, 0x03, 0x2B, 0x04, 0xD1, 0x11, 0x98, 0x01, 0x22, 0x49, 0x46, 0x00, 0xF0, 0x72, 0xFB, 0x16, 0x98, 0xB0, 0xF9, 0x00, 0x10, 0x14, 0x98, 0x00, 0x29, 0xB0, 0xF9, 0x00, 0x00, 0x05, 0xDD, 0x03, 0x28, 0x03, 0xD1, 0x12, 0x98 , -0x02, 0x22, 0x00, 0xF0, 0x64, 0xFB, 0x05, 0x98, 0x04, 0x78, 0x0B, 0x98, 0x00, 0x78, 0x0C, 0x90, 0x08, 0x98, 0xBB, 0x2C, 0x01, 0x78, 0x02, 0xD0, 0xAA, 0x2C, 0x2F, 0xD0, 0x31, 0xE0, 0x0C, 0x98, 0x01, 0x28, 0x0B, 0xD1, 0x0D, 0x98, 0x17, 0x9A, 0x10, 0x60, 0x0C, 0x54, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x0F, 0x98, 0x18, 0x9A, 0x10, 0x60, 0x19, 0x9A, 0x11, 0x98, 0x10, 0x60, 0x47, 0x4A, 0x15, 0x98, 0x02, 0x60, 0x0C, 0x98, 0x02, 0x28, 0x0B, 0xD1, 0x0E, 0x98, 0x17, 0x9A, 0x10, 0x60, 0x10, 0x98, 0x18, 0x9A, 0x10, 0x60, 0x19, 0x9A, 0x12, 0x98, 0x10, 0x60, 0x41, 0x4A, 0x15, 0x98, 0x02, 0x60, 0xCC, 0x20, 0x0F, 0xE0, 0x08, 0x99, 0x09, 0x78, 0x0C, 0xE0, 0x02, 0x20, 0x00, 0xE0, 0x01, 0x20, 0x0B, 0x99, 0x08, 0x70, 0x1A, 0x99, 0x0B, 0x80, 0x13, 0x99, 0x00, 0x20, 0x08, 0x80, 0x08, 0x98, 0x01, 0x78, 0xBB, 0x20, 0x05, 0x9A, 0x10, 0x70, 0x06, 0x29, 0x07, 0x99, 0x11, 0xD1, 0x06, 0x20, 0x08, 0x60, 0x20, 0x98 , -0x00, 0x25, 0x05, 0x70, 0x21, 0x98, 0x29, 0x46, 0x04, 0x22, 0xFB, 0xF7, 0x27, 0xFB, 0x01, 0x20, 0x00, 0xF0, 0x3A, 0xFA, 0x02, 0x20, 0x00, 0xF0, 0x37, 0xFA, 0x22, 0x98, 0x05, 0x60, 0x07, 0x98, 0x04, 0x99, 0x00, 0x68, 0x07, 0x28, 0x44, 0xD1, 0x09, 0x78, 0x03, 0x9C, 0x80, 0x29, 0x40, 0xD1, 0x38, 0x34, 0x21, 0x78, 0x64, 0x1C, 0x22, 0x46, 0x00, 0x29, 0x3A, 0xD1, 0x20, 0x98, 0x90, 0xF8, 0x00, 0xA0, 0x22, 0x98, 0x05, 0x90, 0xD0, 0xF8, 0x00, 0x90, 0x51, 0x46, 0x48, 0x46, 0xFD, 0xF7, 0x79, 0xF9, 0x5F, 0xFA, 0x80, 0xF8, 0x21, 0x9F, 0x15, 0x78, 0x51, 0x46, 0x48, 0x46, 0x17, 0xF8, 0x08, 0x30, 0xFD, 0xF7, 0xD4, 0x54, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x6F, 0xF9, 0x1E, 0x46, 0x1B, 0x1D, 0xC0, 0xB2, 0x38, 0x5C, 0x00, 0x1D, 0xA8, 0x42, 0x28, 0x46, 0x07, 0xDD, 0x80, 0x18, 0x82, 0x1C, 0x10, 0x78, 0x2D, 0x18, 0xAD, 0x1C, 0xAD, 0xB2, 0xAB, 0x42, 0xF7, 0xDC, 0x04, 0xF8, 0x01, 0x6B, 0x11, 0x49, 0x32, 0x46 , -0x20, 0x46, 0x01, 0xEB, 0x48, 0x11, 0xFA, 0xF7, 0xDC, 0xF9, 0xAD, 0x1B, 0xFF, 0x20, 0x34, 0x19, 0xAD, 0x1E, 0x04, 0xF8, 0x01, 0x0B, 0x25, 0x70, 0x05, 0x98, 0x01, 0x68, 0x49, 0x1C, 0x01, 0x60, 0x07, 0x98, 0x00, 0x68, 0x07, 0x28, 0x04, 0xD0, 0x06, 0x99, 0x08, 0x68, 0x20, 0xF4, 0x80, 0x30, 0x08, 0x60, 0x23, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xC0, 0x46, 0x94, 0x57, 0x02, 0x00, 0xD4, 0x57, 0x02, 0x00, 0x5C, 0x58, 0x02, 0x00, 0x6E, 0x48, 0x2D, 0xE9, 0xF0, 0x47, 0x6E, 0x4D, 0x82, 0x89, 0x4A, 0xF6, 0x55, 0x21, 0xAD, 0xF5, 0xFE, 0x7D, 0x91, 0x42, 0x4F, 0xF0, 0x00, 0x01, 0xAD, 0xF1, 0x38, 0x0D, 0x12, 0xD1, 0x29, 0x60, 0x68, 0x4A, 0x11, 0x70, 0x41, 0xF2, 0x10, 0x41, 0x81, 0x81, 0x4F, 0xF6, 0xFF, 0x70, 0x66, 0x49, 0x08, 0x60, 0x28, 0x68, 0x00, 0x90, 0x02, 0x22, 0x05, 0x21, 0x03, 0x20, 0x41, 0xF2, 0x34, 0x23, 0xF3, 0xF7, 0x48, 0xF8, 0x29, 0x68, 0x61, 0x4C, 0x01, 0x29, 0x20, 0x68, 0x40, 0xF0, 0xAF, 0x80 , -0x5F, 0x4D, 0x02, 0x28, 0x29, 0x68, 0x23, 0xD1, 0x9C, 0x55, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x5E, 0x48, 0x00, 0x68, 0x5F, 0x4A, 0x12, 0x5C, 0x00, 0x92, 0x01, 0x91, 0x5E, 0x49, 0x09, 0x68, 0x02, 0x91, 0x5B, 0x49, 0x0B, 0x5C, 0x03, 0x20, 0x07, 0x21, 0x04, 0x22, 0xF3, 0xF7, 0x2E, 0xF8, 0x5B, 0x49, 0x4A, 0x79, 0x59, 0x48, 0x00, 0x92, 0x02, 0x79, 0x01, 0x92, 0x40, 0x79, 0x04, 0x22, 0x02, 0x90, 0x03, 0x20, 0x0B, 0x79, 0x07, 0x21, 0xF3, 0xF7, 0x20, 0xF8, 0x03, 0x20, 0x20, 0x60, 0xEC, 0xF7, 0x1A, 0xFF, 0x20, 0x68, 0x29, 0x68, 0x04, 0x28, 0x15, 0xD1, 0x0D, 0x20, 0x8D, 0xF8, 0x10, 0x00, 0x00, 0x25, 0x8D, 0xF8, 0x14, 0x50, 0x8D, 0xF8, 0x15, 0x10, 0x28, 0x46, 0x63, 0x21, 0x00, 0xF0, 0xAA, 0xFB, 0x63, 0x21, 0x28, 0x46, 0x00, 0xF0, 0xFA, 0xFA, 0x03, 0xA9, 0x04, 0xA8, 0xE0, 0xF7, 0xCA, 0xFC, 0x05, 0x20, 0x20, 0x60, 0x46, 0x4D, 0x05, 0x28, 0x29, 0x68, 0x01, 0xF1, 0x01, 0x01, 0x29, 0x60, 0x1D, 0xD1 , -0x44, 0x4A, 0x8A, 0x42, 0x1A, 0xD1, 0x43, 0x48, 0x01, 0x68, 0x00, 0x91, 0x40, 0x68, 0x01, 0x90, 0x03, 0x20, 0x02, 0x46, 0x06, 0x21, 0x41, 0x4E, 0x33, 0x46, 0x22, 0x3B, 0xF2, 0xF7, 0xEB, 0xFF, 0x3E, 0x48, 0x01, 0x68, 0x00, 0x91, 0x40, 0x68, 0x33, 0x46, 0x06, 0x21, 0x01, 0x90, 0x03, 0x20, 0x02, 0x46, 0xF2, 0xF7, 0xE0, 0xFF, 0x00, 0x20, 0x28, 0x60, 0x20, 0x68, 0x06, 0x28, 0x47, 0xD1, 0x4F, 0xF0, 0x64, 0x56, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x07, 0x0A, 0xC4, 0xF8, 0x00, 0xA0, 0x03, 0x20, 0x48, 0xF2, 0x70, 0x53, 0x01, 0x22, 0x04, 0x21, 0xF2, 0xF7, 0xD0, 0xFF, 0xDF, 0xF8, 0xCC, 0x80, 0x31, 0x4F, 0x48, 0xF2, 0x70, 0x59, 0x01, 0x25, 0x49, 0xEA, 0x05, 0x03, 0x01, 0x22, 0x04, 0x21, 0x03, 0x20, 0xF2, 0xF7, 0xC3, 0xFF, 0x00, 0x24, 0x17, 0xF8, 0x02, 0x0F, 0x20, 0xE0, 0x69, 0x01, 0x04, 0xEB, 0x08, 0x02, 0x88, 0x18, 0xC6, 0x1C, 0x43, 0x78, 0x00, 0x93, 0x80, 0x78, 0x01, 0x90, 0x30, 0x78, 0x02, 0x90 , -0x53, 0x5C, 0x51, 0x46, 0x04, 0x22, 0x03, 0x20, 0xF2, 0xF7, 0xAE, 0xFF, 0x38, 0x78, 0x01, 0x1B, 0xB1, 0xF1, 0xFF, 0x3F, 0x08, 0xD1, 0xF0, 0x78, 0x00, 0x90, 0xB3, 0x78, 0x03, 0x20, 0x02, 0x22, 0x05, 0x21, 0xF2, 0xF7, 0xA1, 0xFF, 0x38, 0x78, 0x24, 0x1D, 0xE4, 0xB2, 0xA0, 0x42, 0xDC, 0xDC, 0xAD, 0x1C, 0xED, 0xB2, 0x04, 0x2D, 0xCD, 0xDB, 0x63, 0x21, 0x4F, 0xF4, 0x05, 0x70, 0xF1, 0xF7, 0xA3, 0xFC, 0xE1, 0xF7, 0x85, 0xFD, 0x7F, 0xB0, 0x0E, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0xC0, 0x46, 0x04, 0x74, 0x00, 0x20, 0x50, 0x57, 0x02, 0x00, 0x6C, 0x5D, 0x02, 0x00, 0x40, 0x00, 0x3D, 0x80, 0x4C, 0x57, 0x02, 0x00, 0x58, 0x57, 0x02, 0x00, 0x90, 0x57, 0x02, 0x00, 0x60, 0x57, 0x02, 0x00, 0x70, 0x57, 0x02, 0x00, 0x5C, 0x57, 0x02, 0x00, 0x80, 0x57, 0x02, 0x00, 0x2C, 0x57, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x88, 0x57, 0x02, 0x00, 0x54, 0x57, 0x02, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0x38, 0x58, 0x02, 0x00, 0x40, 0x58 , -0x02, 0x00, 0x66, 0x55, 0xDD, 0xEE, 0xDB, 0x58, 0x02, 0x00, 0x5C, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x57, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x58, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0xE9, 0xFE, 0x4F, 0x4A, 0x4A, 0x49, 0x4D, 0x00, 0x90, 0xB2, 0xF9, 0x00, 0x20, 0x43, 0xA3, 0x29, 0x78, 0x01, 0x93, 0x43, 0xA3, 0x01, 0x28, 0x02, 0x93, 0x47, 0x4E, 0xDF, 0xF8, 0x1C, 0x81, 0xDF, 0xF8, 0x1C, 0x91, 0x1E, 0xD0, 0x43, 0x48, 0x04, 0x78, 0x48, 0x01, 0x87, 0x19, 0x30, 0x18, 0x01, 0x99, 0x06, 0x22, 0xF9, 0xF7, 0xC8, 0xFF, 0x40, 0x46, 0x01, 0x78, 0x00, 0x68, 0x07, 0xF1, 0x06, 0x07, 0x07, 0xF8, 0x01, 0x1B, 0x07, 0xF8, 0x01, 0x4B, 0x4F, 0xF0, 0x00, 0x01, 0x07, 0xF8, 0x01, 0x1B, 0x20, 0xB9, 0x39, 0x70, 0x28, 0x78, 0x4E, 0x46, 0x0A, 0x21, 0x58, 0xE0, 0xDF, 0xF8, 0xE4, 0xB0, 0x0F, 0xE0, 0xD4, 0xB2, 0x48, 0x01, 0x87, 0x19, 0x30, 0x18, 0x02, 0x99, 0x07, 0x22, 0xF9, 0xF7, 0xAA, 0xFF, 0xFF, 0x1D, 0x00, 0x20, 0xDF, 0xF8, 0xCC, 0xB0, 0x07, 0xF8, 0x01, 0x4B, 0x07, 0xF8, 0x01, 0x0B, 0x16, 0x2C, 0xB2, 0x46, 0xAE, 0xBF, 0x14, 0x20, 0x84, 0x59 , -0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x60, 0x1E, 0xC0, 0xB2, 0x38, 0x70, 0x4E, 0x46, 0x7F, 0x1C, 0x40, 0x1C, 0xC2, 0xB2, 0x28, 0x78, 0x5B, 0x46, 0x00, 0x21, 0x32, 0x54, 0x38, 0x46, 0x00, 0xF0, 0xBC, 0xF9, 0x28, 0x78, 0x16, 0x2C, 0x31, 0x5C, 0x01, 0xF1, 0x0A, 0x01, 0x31, 0x54, 0x00, 0xF1, 0x01, 0x00, 0xC0, 0xB2, 0x28, 0x70, 0x2B, 0xDB, 0x00, 0x99, 0x0A, 0xEB, 0x40, 0x10, 0x07, 0x46, 0x01, 0x29, 0xA4, 0xF1, 0x01, 0x09, 0x09, 0xD0, 0x01, 0x99, 0x06, 0x22, 0xF9, 0xF7, 0x79, 0xFF, 0x40, 0x46, 0x00, 0x78, 0xBF, 0x1D, 0x07, 0xF8, 0x01, 0x0B, 0x04, 0xE0, 0x02, 0x99, 0x07, 0x22, 0xF9, 0xF7, 0x6F, 0xFF, 0xFF, 0x1D, 0x07, 0xF8, 0x01, 0x4B, 0x15, 0x3C, 0x15, 0x21, 0x28, 0x78, 0xE2, 0xB2, 0x5B, 0x46, 0x07, 0xF8, 0x01, 0x1B, 0x32, 0x54, 0x07, 0xF8, 0x01, 0x9B, 0x38, 0x46, 0x00, 0xF0, 0x8B, 0xF9, 0x28, 0x78, 0x31, 0x5C, 0x0A, 0x31, 0x31, 0x54, 0x40, 0x1C, 0x28, 0x70, 0xBD, 0xE8, 0xFE, 0x8F, 0xC0, 0x46 , -0x54, 0x54, 0x54, 0x4B, 0x45, 0x59, 0x00, 0xC0, 0x54, 0x54, 0x54, 0x53, 0x53, 0x49, 0x44, 0x00, 0x54, 0x58, 0x02, 0x00, 0xE6, 0x58, 0x02, 0x00, 0xE8, 0x58, 0x02, 0x00, 0x5C, 0x58, 0x02, 0x00, 0x5C, 0x57, 0x02, 0x00, 0xDC, 0x58, 0x02, 0x00, 0xD4, 0x57, 0x02, 0x00, 0x94, 0x57, 0x02, 0x00, 0xFF, 0xB5, 0x0C, 0x46, 0x06, 0x46, 0xF7, 0xF7, 0x4C, 0x5A, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0xE3, 0xFE, 0x15, 0x49, 0x15, 0x4A, 0x0D, 0x68, 0x01, 0xA9, 0x92, 0xE8, 0x8C, 0x00, 0x81, 0xE8, 0x8C, 0x00, 0xF7, 0xF7, 0xFD, 0xFE, 0x01, 0x98, 0x11, 0x49, 0x28, 0x1A, 0x03, 0x9D, 0x25, 0x60, 0x02, 0x9A, 0x80, 0x18, 0x82, 0x42, 0x30, 0x60, 0x0E, 0xD8, 0x08, 0x46, 0x00, 0x68, 0x22, 0x68, 0x82, 0x42, 0x0E, 0xD2, 0x68, 0x46, 0xE8, 0xF7, 0xB9, 0xFF, 0x9D, 0xF8, 0x00, 0x00, 0x05, 0xF1, 0x01, 0x05, 0x30, 0xB9, 0x03, 0x95, 0x03, 0xE0, 0x25, 0x68, 0x6D, 0x1C, 0x25, 0x60, 0x0C, 0x46, 0x25, 0x60, 0x00, 0x20, 0x00, 0x90 , -0xFF, 0xBD, 0x60, 0x55, 0x30, 0x80, 0x24, 0x5D, 0x00, 0x20, 0x6C, 0x5D, 0x02, 0x00, 0x70, 0xB5, 0x4D, 0x00, 0x20, 0x2D, 0x4F, 0xF0, 0x00, 0x01, 0x0C, 0x46, 0x4F, 0xEA, 0x55, 0x13, 0x09, 0xD3, 0x50, 0xF8, 0x21, 0x60, 0xB6, 0xF1, 0xFF, 0x3F, 0x04, 0xD1, 0x49, 0x1C, 0xC9, 0xB2, 0x20, 0x3D, 0x5B, 0x1E, 0xF5, 0xD1, 0x4D, 0xB1, 0x20, 0x2D, 0x09, 0xD2, 0x01, 0x23, 0xAB, 0x40, 0x5B, 0x1E, 0x50, 0xF8, 0x21, 0x00, 0x18, 0x40, 0x83, 0x42, 0x01, 0xD1, 0x4F, 0xF0, 0x01, 0x04, 0x07, 0x48, 0x03, 0x78, 0x2C, 0xB9, 0x01, 0x21, 0x91, 0x40, 0xC9, 0x43, 0xC9, 0xB2, 0x0B, 0x40, 0x03, 0xE0, 0x01, 0x21, 0x91, 0x40, 0xC9, 0xB2, 0x0B, 0x43, 0x03, 0x70, 0x70, 0xBD, 0xC0, 0x46, 0xEE, 0x58, 0x02, 0x00, 0x14, 0x5B, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x7E, 0xB5, 0x05, 0x46, 0x95, 0xF8, 0x36, 0x20, 0x0E, 0x46, 0x0F, 0x49, 0x07, 0x2A, 0x12, 0xBF, 0x08, 0x68, 0x01, 0x20, 0x08, 0x60, 0x0D, 0x4C, 0x00, 0x92, 0x21, 0x68 , -0x41, 0xF2, 0x12, 0x13, 0x04, 0x22, 0x01, 0x91, 0x07, 0x21, 0x02, 0x90, 0x03, 0x20, 0xF2, 0xF7, 0x6B, 0xFD, 0x31, 0x46, 0x28, 0x46, 0xE7, 0xF7, 0x21, 0xFC, 0x21, 0x68, 0x00, 0x22, 0x05, 0x29, 0x02, 0xD1, 0x04, 0x49, 0x08, 0x31, 0x0A, 0x60, 0x7E, 0xBD, 0xC0, 0x46, 0x50, 0x57, 0x02, 0x00, 0x4C, 0x57, 0x02, 0x00, 0x00, 0x7C, 0x00, 0x20, 0x0E, 0x49, 0x09, 0x68, 0x49, 0x08, 0x15, 0xD2, 0x0D, 0x49, 0x09, 0x78, 0x91, 0xB1, 0x44, 0xF2, 0xE9, 0x21, 0x68, 0xB9, 0x0B, 0x48, 0x01, 0x78, 0x07, 0x48, 0x01, 0x29, 0x03, 0xD1, 0x0A, 0x49, 0x09, 0x78, 0x0E, 0x29, 0x02, 0xD0, 0x44, 0xF2, 0xDE, 0x21, 0x41, 0x60, 0x01, 0x21, 0x00, 0xE0, 0x06, 0x48, 0x01, 0x60, 0x70, 0x47, 0xC0, 0x46, 0x00, 0x97, 0x3C, 0x80, 0x10, 0x0C, 0x30, 0x80, 0xDD, 0x6A, 0x00, 0x20, 0xE0, 0x7C, 0x00, 0x20, 0xA6, 0x64, 0x00, 0x20, 0x04, 0x97, 0x3C, 0x80, 0x00, 0xB5, 0xAD, 0xF1, 0x18, 0x0D, 0x4F, 0xF0, 0x09, 0x00, 0x00, 0x90, 0x4F, 0xF4 , -0x0C, 0x60, 0x03, 0x90, 0x4F, 0xF0, 0x00, 0x00, 0x01, 0x90, 0x02, 0x90, 0x08, 0x48, 0x08, 0x49, 0x05, 0x90, 0x08, 0x68, 0x20, 0xB9, 0xDC, 0x5B, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x68, 0x46, 0x03, 0x22, 0xED, 0xF7, 0x3A, 0xFA, 0x03, 0xE0, 0x68, 0x46, 0x03, 0x22, 0xED, 0xF7, 0xC1, 0xFC, 0x06, 0xB0, 0x00, 0xBD, 0xC0, 0x46, 0x81, 0x5C, 0x02, 0x00, 0xDC, 0x7C, 0x00, 0x20, 0x1C, 0xB5, 0x0F, 0x4C, 0x22, 0x68, 0x01, 0x2A, 0x15, 0xD1, 0x0C, 0x48, 0x00, 0x68, 0x07, 0x28, 0x14, 0xBF, 0x40, 0x20, 0x4F, 0xF4, 0x05, 0x70, 0x63, 0x21, 0xF1, 0xF7, 0x0F, 0xFA, 0x20, 0x68, 0x00, 0x90, 0x43, 0xF2, 0x33, 0x33, 0x06, 0x21, 0x40, 0x20, 0x01, 0x90, 0x03, 0x20, 0x02, 0x46, 0xF2, 0xF7, 0xF4, 0xFC, 0x1C, 0xBD, 0xF1, 0xF7, 0x01, 0xFA, 0x1C, 0xBD, 0x4C, 0x57, 0x02, 0x00, 0x50, 0x57, 0x02, 0x00, 0x1E, 0xB5, 0x04, 0x46, 0x0A, 0x49, 0x00, 0x20, 0x0A, 0x4A, 0x08, 0x60, 0x0A, 0x49, 0x00, 0x90, 0x01, 0x90, 0x11, 0x60 , -0x09, 0x4A, 0x45, 0xF2, 0x55, 0x53, 0x02, 0x91, 0x10, 0x60, 0x07, 0x21, 0x04, 0x22, 0x03, 0x20, 0xF2, 0xF7, 0xD8, 0xFC, 0x20, 0x46, 0xE7, 0xF7, 0x59, 0xFD, 0x1E, 0xBD, 0x50, 0x57, 0x02, 0x00, 0x04, 0x74, 0x00, 0x20, 0x34, 0x12, 0x66, 0x09, 0x4C, 0x57, 0x02, 0x00, 0x00, 0xB5, 0x0B, 0x49, 0x00, 0x20, 0x08, 0x60, 0xE0, 0x20, 0xF7, 0xF7, 0xAA, 0xFD, 0x09, 0x49, 0x09, 0x78, 0x49, 0xB1, 0x08, 0x49, 0x0A, 0x78, 0x08, 0x49, 0x00, 0x2A, 0x06, 0xBF, 0x01, 0x22, 0x09, 0x1F, 0x44, 0xF2, 0xA4, 0x5C, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0xE9, 0x22, 0x0A, 0x60, 0xF7, 0xF7, 0xA1, 0xFD, 0x00, 0xBD, 0xC0, 0x46, 0xDC, 0x7C, 0x00, 0x20, 0xDD, 0x6A, 0x00, 0x20, 0xA7, 0x64, 0x00, 0x20, 0x04, 0x97, 0x3C, 0x80, 0x50, 0xB9, 0x09, 0x48, 0x00, 0x78, 0x01, 0x28, 0x06, 0xD1, 0x08, 0x48, 0x00, 0x78, 0x0E, 0x28, 0x08, 0xBF, 0x44, 0xF2, 0xCB, 0x20, 0x01, 0xD0, 0x44, 0xF2, 0xDE, 0x20, 0x04, 0x49, 0x08, 0x60, 0x01, 0x20 , -0x41, 0xF8, 0x04, 0x0C, 0x70, 0x47, 0xE0, 0x7C, 0x00, 0x20, 0xA6, 0x64, 0x00, 0x20, 0x04, 0x97, 0x3C, 0x80, 0x30, 0xB5, 0x0D, 0x46, 0x84, 0x69, 0xDC, 0xF7, 0x97, 0xFB, 0x24, 0x1D, 0x01, 0x28, 0x04, 0xEB, 0x45, 0x01, 0x06, 0xD1, 0x89, 0x8E, 0x04, 0xEB, 0x85, 0x04, 0x11, 0xB9, 0x21, 0x69, 0x01, 0xB9, 0x00, 0x20, 0x30, 0xBD, 0x30, 0xB5, 0x05, 0x46, 0x5A, 0xB1, 0x03, 0xEB, 0x41, 0x03, 0x1C, 0x78, 0x59, 0x78, 0x41, 0xEA, 0x04, 0x11, 0x52, 0x1E, 0x03, 0xF1, 0x02, 0x03, 0x05, 0xF8, 0x01, 0x1B, 0xF5, 0xD1, 0x30, 0xBD, 0x00, 0xB5, 0x00, 0x20, 0xE7, 0xF7, 0xD6, 0xFE, 0x03, 0x48, 0x01, 0x68, 0x03, 0x29, 0x04, 0xBF, 0x04, 0x21, 0x01, 0x60, 0x00, 0xBD, 0xC0, 0x46, 0x4C, 0x57, 0x02, 0x00, 0x03, 0x4A, 0x12, 0x68, 0x01, 0x2A, 0x04, 0xBF, 0x02, 0x48, 0x63, 0x21, 0xF1, 0xF7, 0x76, 0xB9, 0x50, 0x57, 0x02, 0x00, 0x02, 0x20, 0x01, 0x00, 0x6C, 0x5D, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; diff --git a/drivers/cc3000/src/patch_prog.c b/drivers/cc3000/src/patch_prog.c deleted file mode 100644 index fd128928fba..00000000000 --- a/drivers/cc3000/src/patch_prog.c +++ /dev/null @@ -1,414 +0,0 @@ -#include -#include -#include "cc3000_common.h" -#include "nvmem.h" -#include "ccspi.h" -#include "hci.h" -#include "wlan.h" -#include "patch_prog.h" -#define BIT0 0x1 -#define BIT1 0x2 -#define BIT2 0x4 -#define BIT3 0x8 -#define BIT4 0x10 -#define BIT5 0x20 -#define BIT6 0x40 -#define BIT7 0x80 - -static unsigned char ucStatus_Dr; -static unsigned char ucStatus_FW; -static unsigned char return_status = 0xFF; - -static signed char mac_status = -1; -static unsigned char counter = 0; - -// Array to store RM parameters from EEPROM. -static unsigned char cRMParamsFromEeprom[128]; -// Array to store MAC address from EEPROM. -static unsigned char cMacFromEeprom[MAC_ADDR_LEN]; -// Smart Config Prefix -static const char aucCC3000_prefix[] = {'T', 'T', 'T'}; - -static void systick_sleep(unsigned long ms) { - extern void HAL_Delay(volatile uint32_t Delay); - HAL_Delay(ms); -} - -// 2 dim array to store address and length of new FAT -static const unsigned short aFATEntries[2][NVMEM_RM_FILEID + 1] = -/* address */ {{0x50, 0x1f0, 0x390, 0x1390, 0x2390, 0x4390, 0x6390, 0x63a0, 0x63b0, 0x63f0, 0x6430, 0x6830}, -/* length */ {0x1a0, 0x1a0, 0x1000, 0x1000, 0x2000, 0x2000, 0x10, 0x10, 0x40, 0x40, 0x400, 0x200}}; -/* 0. NVS */ -/* 1. NVS Shadow */ -/* 2. Wireless Conf */ -/* 3. Wireless Conf Shadow */ -/* 4. BT (WLAN driver) Patches */ -/* 5. WiLink (Firmware) Patches */ -/* 6. MAC addr */ -/* 7. Frontend Vars */ -/* 8. IP config */ -/* 9. IP config Shadow */ -/* 10. Bootloader Patches */ -/* 11. Radio Module params */ -/* 12. AES128 for smart config */ -/* 13. user file */ -/* 14. user file */ -/* 15. user file */ - -//***************************************************************************** -// -//! sendDriverPatch -//! -//! \param pointer to the length -//! -//! \return none -//! -//! \brief The function returns a pointer to the driver patch: -//! since there is no patch yet - it returns 0 -// -//***************************************************************************** - -static char *sendDriverPatch(unsigned long *Length) -{ - *Length = 0; - return NULL; -} - - -//***************************************************************************** -// -//! sendBootLoaderPatch -//! -//! \param pointer to the length -//! -//! \return none -//! -//! \brief The function returns a pointer to the boot loader patch: -//! since there is no patch yet - it returns 0 -// -//***************************************************************************** - -static char *sendBootLoaderPatch(unsigned long *Length) -{ - *Length = 0; - return NULL; -} - -//***************************************************************************** -// -//! sendWLFWPatch -//! -//! \param pointer to the length -//! -//! \return none -//! -//! \brief The function returns a pointer to the FW patch: -//! since there is no patch yet - it returns 0 -// -//***************************************************************************** - -static char *sendWLFWPatch(unsigned long *Length) -{ - *Length = 0; - return NULL; -} - -//***************************************************************************** -// -//! CC3000_UsynchCallback -//! -//! \param Event type -//! -//! \return none -//! -//! \brief The function handles asynchronous events that come from CC3000 -//! device and operates a LED4 to have an on-board indication -// -//***************************************************************************** - -static void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length) -{ - -} - -//***************************************************************************** -// -//! initDriver -//! -//! \param[in] cRequestPatch 0 to load with EEPROM patches -//! and 1 to load with no patches -//! -//! \return none -//! -//! \brief The function initializes a CC3000 device -//! and triggers it to start operation -// -//***************************************************************************** -static int initDriver(unsigned short cRequestPatch) -{ - // WLAN On API Implementation - wlan_init(CC3000_UsynchCallback, sendWLFWPatch, sendDriverPatch, sendBootLoaderPatch, - ReadWlanInterruptPin, SpiResumeSpi, SpiPauseSpi, WriteWlanPin); - - // Trigger a WLAN device - wlan_start(cRequestPatch); - wlan_smart_config_set_prefix((char*)aucCC3000_prefix); - wlan_ioctl_set_connection_policy(0, 0, 0); - wlan_ioctl_del_profile(255); - - // Mask out all non-required events from CC3000 - wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE| - HCI_EVNT_WLAN_UNSOL_INIT| - HCI_EVNT_WLAN_ASYNC_PING_REPORT); - - //unsolicicted_events_timer_init(); - systick_sleep(100); - return(0); -} - - -//***************************************************************************** -// -//! fat_read_content -//! -//! \param[out] is_allocated array of is_allocated in FAT table:\n -//! an allocated entry implies the address and length of the -//! file are valid. -//! 0: not allocated; 1: allocated. -//! \param[out] is_valid array of is_valid in FAT table:\n -//! a valid entry implies the content of the file is relevant. -//! 0: not valid; 1: valid. -//! \param[out] write_protected array of write_protected in FAT table:\n -//! a write protected entry implies it is not possible to write -//! into this entry. -//! 0: not protected; 1: protected. -//! \param[out] file_address array of file address in FAT table:\n -//! this is the absolute address of the file in the EEPROM. -//! \param[out] file_length array of file length in FAT table:\n -//! this is the upper limit of the file size in the EEPROM. -//! -//! \return on succes 0, error otherwise -//! -//! \brief parse the FAT table from eeprom -// -//***************************************************************************** -static unsigned char __attribute__ ((unused)) -fat_read_content(unsigned char *is_allocated, unsigned char *is_valid, - unsigned char *write_protected, unsigned short *file_address, unsigned short *file_length) -{ - unsigned short index; - unsigned char ucStatus; - unsigned char fatTable[48]; - unsigned char* fatTablePtr = fatTable; - - // - // Read in 6 parts to work with tiny driver - // - for (index = 0; index < 6; index++) - { - ucStatus = nvmem_read(16, 8, 4 + 8*index, fatTablePtr); - fatTablePtr += 8; - } - - fatTablePtr = fatTable; - - for (index = 0; index <= NVMEM_RM_FILEID; index++) - { - *is_allocated++ = (*fatTablePtr) & BIT0; - *is_valid++ = ((*fatTablePtr) & BIT1) >> 1; - *write_protected++ = ((*fatTablePtr) & BIT2) >> 2; - *file_address++ = ((*(fatTablePtr+1)<<8) | (*fatTablePtr)) & (BIT4|BIT5|BIT6|BIT7); - *file_length++ = ((*(fatTablePtr+3)<<8) | (*(fatTablePtr+2))) & (BIT4|BIT5|BIT6|BIT7); - - // - // Move to next file ID - // - fatTablePtr += 4; - } - - return ucStatus; -} - -//***************************************************************************** -// -//! fat_write_content -//! -//! \param[in] file_address array of file address in FAT table:\n -//! this is the absolute address of the file in the EEPROM. -//! \param[in] file_length array of file length in FAT table:\n -//! this is the upper limit of the file size in the EEPROM. -//! -//! \return on succes 0, error otherwise -//! -//! \brief parse the FAT table from eeprom -// -//***************************************************************************** -static unsigned char fat_write_content(unsigned short const *file_address, - unsigned short const *file_length) -{ - unsigned short index = 0; - unsigned char ucStatus; - unsigned char fatTable[48]; - unsigned char* fatTablePtr = fatTable; - - // - // First, write the magic number. - // - ucStatus = nvmem_write(16, 2, 0, (unsigned char*)"LS"); - - for (; index <= NVMEM_RM_FILEID; index++) - { - // - // Write address low char and mark as allocated. - // - *fatTablePtr++ = (unsigned char)(file_address[index] & 0xff) | BIT0; - - // - // Write address high char. - // - *fatTablePtr++ = (unsigned char)((file_address[index]>>8) & 0xff); - - // - // Write length low char. - // - *fatTablePtr++ = (unsigned char)(file_length[index] & 0xff); - - // - // Write length high char. - // - *fatTablePtr++ = (unsigned char)((file_length[index]>>8) & 0xff); - } - - // - // Second, write the FAT. - // Write in two parts to work with tiny driver. - // - ucStatus = nvmem_write(16, 24, 4, fatTable); - ucStatus = nvmem_write(16, 24, 24+4, &fatTable[24]); - - // - // Third, we want to erase any user files. - // - memset(fatTable, 0, sizeof(fatTable)); - ucStatus = nvmem_write(16, 16, 52, fatTable); - - return ucStatus; -} - -void patch_prog_start() -{ - unsigned short index; - unsigned char *pRMParams; - - printf("Initializing module...\n"); - - // Init module and request to load with no patches. - // This is in order to overwrite restrictions to - // write to specific places in EEPROM. - initDriver(1); - - // Read MAC address. - mac_status = nvmem_get_mac_address(cMacFromEeprom); - - return_status = 1; - - printf("Reading RM parameters...\n"); - while ((return_status) && (counter < 3)) { - // Read RM parameters. - // Read in 16 parts to work with tiny driver. - return_status = 0; - pRMParams = cRMParamsFromEeprom; - for (index = 0; index < 16; index++) { - return_status |= nvmem_read(NVMEM_RM_FILEID, 8, 8*index, pRMParams); - pRMParams += 8; - } - counter++; - } - - // If RM file is not valid, load the default one. - if (counter == 3) { - printf("RM is not valid, loading default one...\n"); - pRMParams = (unsigned char *)cRMdefaultParams; - } else { - printf("RM is valid.\n"); - pRMParams = cRMParamsFromEeprom; - } - - return_status = 1; - - printf("Writing new FAT\n"); - while (return_status) { - // Write new FAT. - return_status = fat_write_content(aFATEntries[0], aFATEntries[1]); - } - - return_status = 1; - - printf("Writing RM parameters...\n"); - while (return_status) { - // Write RM parameters. - // Write in 4 parts to work with tiny driver. - return_status = 0; - - for (index = 0; index < 4; index++) { - return_status |= nvmem_write(NVMEM_RM_FILEID, - 32, - 32*index, - (pRMParams + 32*index)); - } - } - - return_status = 1; - - // Write back the MAC address, only if exists. - if (mac_status == 0) { - // Zero out MCAST bit if set. - cMacFromEeprom[0] &= 0xfe; - printf("Writing back MAC address..\n"); - while (return_status) { - return_status = nvmem_set_mac_address(cMacFromEeprom); - } - } - - // Update driver - ucStatus_Dr = 1; - printf("Updating driver patch...\n"); - while (ucStatus_Dr) { - // Writing driver patch to EEPRROM - PROTABLE CODE - // Note that the array itself is changing between the - // different Service Packs. - ucStatus_Dr = nvmem_write_patch(NVMEM_WLAN_DRIVER_SP_FILEID, - drv_length, - wlan_drv_patch); - } - - // Update firmware - ucStatus_FW = 1; - printf("Updating firmware patch...\n"); - while (ucStatus_FW) { - // Writing FW patch to EEPRROM - PROTABLE CODE - // Note that the array itself is changing between the - // different Service Packs. - ucStatus_FW = nvmem_write_patch(NVMEM_WLAN_FW_SP_FILEID, - fw_length, - fw_patch); - } - - printf("Update complete, resetting module\n"\ - "If this doesn't work, reset manually...\n"); - - wlan_stop(); - systick_sleep(500); - - // Re-Init module and request to load with patches. - initDriver(0); - - // If MAC does not exist, it is recommended - // that the user will write a valid mac address. - if (mac_status != 0) { - printf("MAC address is not valid, please write a new one\n"); - } - - // Patch update done - printf("All done, call wlan.patch_version()\n"); -} diff --git a/drivers/cc3000/src/security.c b/drivers/cc3000/src/security.c deleted file mode 100644 index 62b4f881343..00000000000 --- a/drivers/cc3000/src/security.c +++ /dev/null @@ -1,530 +0,0 @@ -/***************************************************************************** -* -* security.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - -//***************************************************************************** -// -//! \addtogroup security_api -//! @{ -// -//***************************************************************************** - -#include "security.h" - -#ifndef CC3000_UNENCRYPTED_SMART_CONFIG -// foreward sbox -const UINT8 sbox[256] = { -//0 1 2 3 4 5 6 7 8 9 A B C D E F -0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0 -0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1 -0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2 -0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3 -0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4 -0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5 -0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6 -0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7 -0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8 -0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9 -0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A -0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B -0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C -0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D -0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E -0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F -// inverse sbox -const UINT8 rsbox[256] = -{ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb -, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb -, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e -, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 -, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 -, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 -, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 -, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b -, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 -, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e -, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b -, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 -, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f -, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef -, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 -, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; -// round constant -const UINT8 Rcon[11] = { - 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; - - -UINT8 expandedKey[176]; - -//***************************************************************************** -// -//! expandKey -//! -//! @param key AES128 key - 16 bytes -//! @param expandedKey expanded AES128 key -//! -//! @return none -//! -//! @brief expend a 16 bytes key for AES128 implementation -//! -//***************************************************************************** - -void expandKey(UINT8 *expandedKey, UINT8 *key) -{ - UINT16 ii, buf1; - for (ii=0;ii<16;ii++) - expandedKey[ii] = key[ii]; - for (ii=1;ii<11;ii++){ - buf1 = expandedKey[ii*16 - 4]; - expandedKey[ii*16 + 0] = sbox[expandedKey[ii*16 - 3]]^expandedKey[(ii-1)*16 + 0]^Rcon[ii]; - expandedKey[ii*16 + 1] = sbox[expandedKey[ii*16 - 2]]^expandedKey[(ii-1)*16 + 1]; - expandedKey[ii*16 + 2] = sbox[expandedKey[ii*16 - 1]]^expandedKey[(ii-1)*16 + 2]; - expandedKey[ii*16 + 3] = sbox[buf1 ]^expandedKey[(ii-1)*16 + 3]; - expandedKey[ii*16 + 4] = expandedKey[(ii-1)*16 + 4]^expandedKey[ii*16 + 0]; - expandedKey[ii*16 + 5] = expandedKey[(ii-1)*16 + 5]^expandedKey[ii*16 + 1]; - expandedKey[ii*16 + 6] = expandedKey[(ii-1)*16 + 6]^expandedKey[ii*16 + 2]; - expandedKey[ii*16 + 7] = expandedKey[(ii-1)*16 + 7]^expandedKey[ii*16 + 3]; - expandedKey[ii*16 + 8] = expandedKey[(ii-1)*16 + 8]^expandedKey[ii*16 + 4]; - expandedKey[ii*16 + 9] = expandedKey[(ii-1)*16 + 9]^expandedKey[ii*16 + 5]; - expandedKey[ii*16 +10] = expandedKey[(ii-1)*16 +10]^expandedKey[ii*16 + 6]; - expandedKey[ii*16 +11] = expandedKey[(ii-1)*16 +11]^expandedKey[ii*16 + 7]; - expandedKey[ii*16 +12] = expandedKey[(ii-1)*16 +12]^expandedKey[ii*16 + 8]; - expandedKey[ii*16 +13] = expandedKey[(ii-1)*16 +13]^expandedKey[ii*16 + 9]; - expandedKey[ii*16 +14] = expandedKey[(ii-1)*16 +14]^expandedKey[ii*16 +10]; - expandedKey[ii*16 +15] = expandedKey[(ii-1)*16 +15]^expandedKey[ii*16 +11]; - } - -} - -//***************************************************************************** -// -//! galois_mul2 -//! -//! @param value argument to multiply -//! -//! @return multiplied argument -//! -//! @brief multiply by 2 in the galois field -//! -//***************************************************************************** - -UINT8 galois_mul2(UINT8 value) -{ - if (value>>7) - { - value = value << 1; - return (value^0x1b); - } else - return value<<1; -} - -//***************************************************************************** -// -//! aes_encr -//! -//! @param[in] expandedKey expanded AES128 key -//! @param[in/out] state 16 bytes of plain text and cipher text -//! -//! @return none -//! -//! @brief internal implementation of AES128 encryption. -//! straight forward aes encryption implementation -//! first the group of operations -//! - addRoundKey -//! - subbytes -//! - shiftrows -//! - mixcolums -//! is executed 9 times, after this addroundkey to finish the 9th -//! round, after that the 10th round without mixcolums -//! no further subfunctions to save cycles for function calls -//! no structuring with "for (....)" to save cycles. -//! -//! -//***************************************************************************** - -void aes_encr(UINT8 *state, UINT8 *expandedKey) -{ - UINT8 buf1, buf2, buf3, round; - - for (round = 0; round < 9; round ++){ - // addroundkey, sbox and shiftrows - // row 0 - state[ 0] = sbox[(state[ 0] ^ expandedKey[(round*16) ])]; - state[ 4] = sbox[(state[ 4] ^ expandedKey[(round*16) + 4])]; - state[ 8] = sbox[(state[ 8] ^ expandedKey[(round*16) + 8])]; - state[12] = sbox[(state[12] ^ expandedKey[(round*16) + 12])]; - // row 1 - buf1 = state[1] ^ expandedKey[(round*16) + 1]; - state[ 1] = sbox[(state[ 5] ^ expandedKey[(round*16) + 5])]; - state[ 5] = sbox[(state[ 9] ^ expandedKey[(round*16) + 9])]; - state[ 9] = sbox[(state[13] ^ expandedKey[(round*16) + 13])]; - state[13] = sbox[buf1]; - // row 2 - buf1 = state[2] ^ expandedKey[(round*16) + 2]; - buf2 = state[6] ^ expandedKey[(round*16) + 6]; - state[ 2] = sbox[(state[10] ^ expandedKey[(round*16) + 10])]; - state[ 6] = sbox[(state[14] ^ expandedKey[(round*16) + 14])]; - state[10] = sbox[buf1]; - state[14] = sbox[buf2]; - // row 3 - buf1 = state[15] ^ expandedKey[(round*16) + 15]; - state[15] = sbox[(state[11] ^ expandedKey[(round*16) + 11])]; - state[11] = sbox[(state[ 7] ^ expandedKey[(round*16) + 7])]; - state[ 7] = sbox[(state[ 3] ^ expandedKey[(round*16) + 3])]; - state[ 3] = sbox[buf1]; - - // mixcolums ////////// - // col1 - buf1 = state[0] ^ state[1] ^ state[2] ^ state[3]; - buf2 = state[0]; - buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1; - buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1; - buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1; - buf3 = state[3]^buf2; buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1; - // col2 - buf1 = state[4] ^ state[5] ^ state[6] ^ state[7]; - buf2 = state[4]; - buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1; - buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1; - buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1; - buf3 = state[7]^buf2; buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1; - // col3 - buf1 = state[8] ^ state[9] ^ state[10] ^ state[11]; - buf2 = state[8]; - buf3 = state[8]^state[9]; buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1; - buf3 = state[9]^state[10]; buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1; - buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1; - buf3 = state[11]^buf2; buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1; - // col4 - buf1 = state[12] ^ state[13] ^ state[14] ^ state[15]; - buf2 = state[12]; - buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1; - buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1; - buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1; - buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1; - - } - // 10th round without mixcols - state[ 0] = sbox[(state[ 0] ^ expandedKey[(round*16) ])]; - state[ 4] = sbox[(state[ 4] ^ expandedKey[(round*16) + 4])]; - state[ 8] = sbox[(state[ 8] ^ expandedKey[(round*16) + 8])]; - state[12] = sbox[(state[12] ^ expandedKey[(round*16) + 12])]; - // row 1 - buf1 = state[1] ^ expandedKey[(round*16) + 1]; - state[ 1] = sbox[(state[ 5] ^ expandedKey[(round*16) + 5])]; - state[ 5] = sbox[(state[ 9] ^ expandedKey[(round*16) + 9])]; - state[ 9] = sbox[(state[13] ^ expandedKey[(round*16) + 13])]; - state[13] = sbox[buf1]; - // row 2 - buf1 = state[2] ^ expandedKey[(round*16) + 2]; - buf2 = state[6] ^ expandedKey[(round*16) + 6]; - state[ 2] = sbox[(state[10] ^ expandedKey[(round*16) + 10])]; - state[ 6] = sbox[(state[14] ^ expandedKey[(round*16) + 14])]; - state[10] = sbox[buf1]; - state[14] = sbox[buf2]; - // row 3 - buf1 = state[15] ^ expandedKey[(round*16) + 15]; - state[15] = sbox[(state[11] ^ expandedKey[(round*16) + 11])]; - state[11] = sbox[(state[ 7] ^ expandedKey[(round*16) + 7])]; - state[ 7] = sbox[(state[ 3] ^ expandedKey[(round*16) + 3])]; - state[ 3] = sbox[buf1]; - // last addroundkey - state[ 0]^=expandedKey[160]; - state[ 1]^=expandedKey[161]; - state[ 2]^=expandedKey[162]; - state[ 3]^=expandedKey[163]; - state[ 4]^=expandedKey[164]; - state[ 5]^=expandedKey[165]; - state[ 6]^=expandedKey[166]; - state[ 7]^=expandedKey[167]; - state[ 8]^=expandedKey[168]; - state[ 9]^=expandedKey[169]; - state[10]^=expandedKey[170]; - state[11]^=expandedKey[171]; - state[12]^=expandedKey[172]; - state[13]^=expandedKey[173]; - state[14]^=expandedKey[174]; - state[15]^=expandedKey[175]; -} - -//***************************************************************************** -// -//! aes_decr -//! -//! @param[in] expandedKey expanded AES128 key -//! @param[in\out] state 16 bytes of cipher text and plain text -//! -//! @return none -//! -//! @brief internal implementation of AES128 decryption. -//! straight forward aes decryption implementation -//! the order of substeps is the exact reverse of decryption -//! inverse functions: -//! - addRoundKey is its own inverse -//! - rsbox is inverse of sbox -//! - rightshift instead of leftshift -//! - invMixColumns = barreto + mixColumns -//! no further subfunctions to save cycles for function calls -//! no structuring with "for (....)" to save cycles -//! -//***************************************************************************** - -void aes_decr(UINT8 *state, UINT8 *expandedKey) -{ - UINT8 buf1, buf2, buf3; - INT8 round; - round = 9; - - // initial addroundkey - state[ 0]^=expandedKey[160]; - state[ 1]^=expandedKey[161]; - state[ 2]^=expandedKey[162]; - state[ 3]^=expandedKey[163]; - state[ 4]^=expandedKey[164]; - state[ 5]^=expandedKey[165]; - state[ 6]^=expandedKey[166]; - state[ 7]^=expandedKey[167]; - state[ 8]^=expandedKey[168]; - state[ 9]^=expandedKey[169]; - state[10]^=expandedKey[170]; - state[11]^=expandedKey[171]; - state[12]^=expandedKey[172]; - state[13]^=expandedKey[173]; - state[14]^=expandedKey[174]; - state[15]^=expandedKey[175]; - - // 10th round without mixcols - state[ 0] = rsbox[state[ 0]] ^ expandedKey[(round*16) ]; - state[ 4] = rsbox[state[ 4]] ^ expandedKey[(round*16) + 4]; - state[ 8] = rsbox[state[ 8]] ^ expandedKey[(round*16) + 8]; - state[12] = rsbox[state[12]] ^ expandedKey[(round*16) + 12]; - // row 1 - buf1 = rsbox[state[13]] ^ expandedKey[(round*16) + 1]; - state[13] = rsbox[state[ 9]] ^ expandedKey[(round*16) + 13]; - state[ 9] = rsbox[state[ 5]] ^ expandedKey[(round*16) + 9]; - state[ 5] = rsbox[state[ 1]] ^ expandedKey[(round*16) + 5]; - state[ 1] = buf1; - // row 2 - buf1 = rsbox[state[ 2]] ^ expandedKey[(round*16) + 10]; - buf2 = rsbox[state[ 6]] ^ expandedKey[(round*16) + 14]; - state[ 2] = rsbox[state[10]] ^ expandedKey[(round*16) + 2]; - state[ 6] = rsbox[state[14]] ^ expandedKey[(round*16) + 6]; - state[10] = buf1; - state[14] = buf2; - // row 3 - buf1 = rsbox[state[ 3]] ^ expandedKey[(round*16) + 15]; - state[ 3] = rsbox[state[ 7]] ^ expandedKey[(round*16) + 3]; - state[ 7] = rsbox[state[11]] ^ expandedKey[(round*16) + 7]; - state[11] = rsbox[state[15]] ^ expandedKey[(round*16) + 11]; - state[15] = buf1; - - for (round = 8; round >= 0; round--){ - // barreto - //col1 - buf1 = galois_mul2(galois_mul2(state[0]^state[2])); - buf2 = galois_mul2(galois_mul2(state[1]^state[3])); - state[0] ^= buf1; state[1] ^= buf2; state[2] ^= buf1; state[3] ^= buf2; - //col2 - buf1 = galois_mul2(galois_mul2(state[4]^state[6])); - buf2 = galois_mul2(galois_mul2(state[5]^state[7])); - state[4] ^= buf1; state[5] ^= buf2; state[6] ^= buf1; state[7] ^= buf2; - //col3 - buf1 = galois_mul2(galois_mul2(state[8]^state[10])); - buf2 = galois_mul2(galois_mul2(state[9]^state[11])); - state[8] ^= buf1; state[9] ^= buf2; state[10] ^= buf1; state[11] ^= buf2; - //col4 - buf1 = galois_mul2(galois_mul2(state[12]^state[14])); - buf2 = galois_mul2(galois_mul2(state[13]^state[15])); - state[12] ^= buf1; state[13] ^= buf2; state[14] ^= buf1; state[15] ^= buf2; - // mixcolums ////////// - // col1 - buf1 = state[0] ^ state[1] ^ state[2] ^ state[3]; - buf2 = state[0]; - buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1; - buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1; - buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1; - buf3 = state[3]^buf2; buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1; - // col2 - buf1 = state[4] ^ state[5] ^ state[6] ^ state[7]; - buf2 = state[4]; - buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1; - buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1; - buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1; - buf3 = state[7]^buf2; buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1; - // col3 - buf1 = state[8] ^ state[9] ^ state[10] ^ state[11]; - buf2 = state[8]; - buf3 = state[8]^state[9]; buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1; - buf3 = state[9]^state[10]; buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1; - buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1; - buf3 = state[11]^buf2; buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1; - // col4 - buf1 = state[12] ^ state[13] ^ state[14] ^ state[15]; - buf2 = state[12]; - buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1; - buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1; - buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1; - buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1; - - // addroundkey, rsbox and shiftrows - // row 0 - state[ 0] = rsbox[state[ 0]] ^ expandedKey[(round*16) ]; - state[ 4] = rsbox[state[ 4]] ^ expandedKey[(round*16) + 4]; - state[ 8] = rsbox[state[ 8]] ^ expandedKey[(round*16) + 8]; - state[12] = rsbox[state[12]] ^ expandedKey[(round*16) + 12]; - // row 1 - buf1 = rsbox[state[13]] ^ expandedKey[(round*16) + 1]; - state[13] = rsbox[state[ 9]] ^ expandedKey[(round*16) + 13]; - state[ 9] = rsbox[state[ 5]] ^ expandedKey[(round*16) + 9]; - state[ 5] = rsbox[state[ 1]] ^ expandedKey[(round*16) + 5]; - state[ 1] = buf1; - // row 2 - buf1 = rsbox[state[ 2]] ^ expandedKey[(round*16) + 10]; - buf2 = rsbox[state[ 6]] ^ expandedKey[(round*16) + 14]; - state[ 2] = rsbox[state[10]] ^ expandedKey[(round*16) + 2]; - state[ 6] = rsbox[state[14]] ^ expandedKey[(round*16) + 6]; - state[10] = buf1; - state[14] = buf2; - // row 3 - buf1 = rsbox[state[ 3]] ^ expandedKey[(round*16) + 15]; - state[ 3] = rsbox[state[ 7]] ^ expandedKey[(round*16) + 3]; - state[ 7] = rsbox[state[11]] ^ expandedKey[(round*16) + 7]; - state[11] = rsbox[state[15]] ^ expandedKey[(round*16) + 11]; - state[15] = buf1; - } - -} - -//***************************************************************************** -// -//! aes_encrypt -//! -//! @param[in] key AES128 key of size 16 bytes -//! @param[in\out] state 16 bytes of plain text and cipher text -//! -//! @return none -//! -//! @brief AES128 encryption: -//! Given AES128 key and 16 bytes plain text, cipher text of 16 bytes -//! is computed. The AES implementation is in mode ECB (Electronic -//! Code Book). -//! -//! -//***************************************************************************** - -void aes_encrypt(UINT8 *state, UINT8 *key) -{ - // expand the key into 176 bytes - expandKey(expandedKey, key); - aes_encr(state, expandedKey); -} - -//***************************************************************************** -// -//! aes_decrypt -//! -//! @param[in] key AES128 key of size 16 bytes -//! @param[in\out] state 16 bytes of cipher text and plain text -//! -//! @return none -//! -//! @brief AES128 decryption: -//! Given AES128 key and 16 bytes cipher text, plain text of 16 bytes -//! is computed The AES implementation is in mode ECB -//! (Electronic Code Book). -//! -//! -//***************************************************************************** - -void aes_decrypt(UINT8 *state, UINT8 *key) -{ - expandKey(expandedKey, key); // expand the key into 176 bytes - aes_decr(state, expandedKey); -} - -//***************************************************************************** -// -//! aes_read_key -//! -//! @param[out] key AES128 key of size 16 bytes -//! -//! @return on success 0, error otherwise. -//! -//! @brief Reads AES128 key from EEPROM -//! Reads the AES128 key from fileID #12 in EEPROM -//! returns an error if the key does not exist. -//! -//! -//***************************************************************************** - -INT32 aes_read_key(UINT8 *key) -{ - INT32 returnValue; - - returnValue = nvmem_read(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key); - - return returnValue; -} - -//***************************************************************************** -// -//! aes_write_key -//! -//! @param[out] key AES128 key of size 16 bytes -//! -//! @return on success 0, error otherwise. -//! -//! @brief writes AES128 key from EEPROM -//! Writes the AES128 key to fileID #12 in EEPROM -//! -//! -//***************************************************************************** - -INT32 aes_write_key(UINT8 *key) -{ - INT32 returnValue; - - returnValue = nvmem_write(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key); - - return returnValue; -} - -#endif //CC3000_UNENCRYPTED_SMART_CONFIG - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** diff --git a/drivers/cc3000/src/socket.c b/drivers/cc3000/src/socket.c deleted file mode 100644 index ddd7e56e807..00000000000 --- a/drivers/cc3000/src/socket.c +++ /dev/null @@ -1,1182 +0,0 @@ -/***************************************************************************** -* -* socket.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - -//***************************************************************************** -// -//! \addtogroup socket_api -//! @{ -// -//***************************************************************************** - -#include -#include -#include "hci.h" -#include "socket.h" -#include "evnt_handler.h" -#include "netapp.h" - - - -//Enable this flag if and only if you must comply with BSD socket -//close() function -#ifdef _API_USE_BSD_CLOSE -#define close(sd) closesocket(sd) -#endif - -//Enable this flag if and only if you must comply with BSD socket read() and -//write() functions -#ifdef _API_USE_BSD_READ_WRITE -#define read(sd, buf, len, flags) recv(sd, buf, len, flags) -#define write(sd, buf, len, flags) send(sd, buf, len, flags) -#endif - -#define SOCKET_OPEN_PARAMS_LEN (12) -#define SOCKET_CLOSE_PARAMS_LEN (4) -#define SOCKET_ACCEPT_PARAMS_LEN (4) -#define SOCKET_BIND_PARAMS_LEN (20) -#define SOCKET_LISTEN_PARAMS_LEN (8) -#define SOCKET_GET_HOST_BY_NAME_PARAMS_LEN (9) -#define SOCKET_CONNECT_PARAMS_LEN (20) -#define SOCKET_SELECT_PARAMS_LEN (44) -#define SOCKET_SET_SOCK_OPT_PARAMS_LEN (20) -#define SOCKET_GET_SOCK_OPT_PARAMS_LEN (12) -#define SOCKET_RECV_FROM_PARAMS_LEN (12) -#define SOCKET_SENDTO_PARAMS_LEN (24) -#define SOCKET_MDNS_ADVERTISE_PARAMS_LEN (12) -#define SOCKET_GET_MSS_VALUE_PARAMS_LEN (4) - -// The legnth of arguments for the SEND command: sd + buff_offset + len + flags, -// while size of each parameter is 32 bit - so the total length is 16 bytes; - -#define HCI_CMND_SEND_ARG_LENGTH (16) - - -#define SELECT_TIMEOUT_MIN_MICRO_SECONDS 5000 - -#define HEADERS_SIZE_DATA (SPI_HEADER_SIZE + 5) - -#define SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE) - -#define MDNS_DEVICE_SERVICE_MAX_LENGTH (32) - - -//***************************************************************************** -// -//! HostFlowControlConsumeBuff -//! -//! @param sd socket descriptor -//! -//! @return 0 in case there are buffers available, -//! -1 in case of bad socket -//! -2 if there are no free buffers present (only when -//! SEND_NON_BLOCKING is enabled) -//! -//! @brief if SEND_NON_BLOCKING not define - block until have free buffer -//! becomes available, else return immediately with correct status -//! regarding the buffers available. -// -//***************************************************************************** -static INT16 HostFlowControlConsumeBuff(INT16 sd) -{ -#ifndef SEND_NON_BLOCKING - /* wait in busy loop */ - do - { - // In case last transmission failed then we will return the last failure - // reason here. - // Note that the buffer will not be allocated in this case - if (tSLInformation.slTransmitDataError != 0) - { - CC3000_EXPORT(errno) = tSLInformation.slTransmitDataError; - tSLInformation.slTransmitDataError = 0; - return CC3000_EXPORT(errno); - } - - if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd)) - return -1; - } while(0 == tSLInformation.usNumberOfFreeBuffers); - - tSLInformation.usNumberOfFreeBuffers--; - - return 0; -#else - - // In case last transmission failed then we will return the last failure - // reason here. - // Note that the buffer will not be allocated in this case - if (tSLInformation.slTransmitDataError != 0) - { - CC3000_EXPORT(errno) = tSLInformation.slTransmitDataError; - tSLInformation.slTransmitDataError = 0; - return CC3000_EXPORT(errno); - } - if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd)) - return -1; - - //If there are no available buffers, return -2. It is recommended to use - // select or receive to see if there is any buffer occupied with received data - // If so, call receive() to release the buffer. - if(0 == tSLInformation.usNumberOfFreeBuffers) - { - return -2; - } - else - { - tSLInformation.usNumberOfFreeBuffers--; - return 0; - } -#endif -} - -//***************************************************************************** -// -//! socket -//! -//! @param domain selects the protocol family which will be used for -//! communication. On this version only AF_INET is supported -//! @param type specifies the communication semantics. On this version -//! only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported -//! @param protocol specifies a particular protocol to be used with the -//! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are -//! supported. -//! -//! @return On success, socket handle that is used for consequent socket -//! operations. On error, -1 is returned. -//! -//! @brief create an endpoint for communication -//! The socket function creates a socket that is bound to a specific -//! transport service provider. This function is called by the -//! application layer to obtain a socket handle. -// -//***************************************************************************** - -INT16 CC3000_EXPORT(socket)(INT32 domain, INT32 type, INT32 protocol) -{ - INT32 ret; - UINT8 *ptr, *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, domain); - args = UINT32_TO_STREAM(args, type); - args = UINT32_TO_STREAM(args, protocol); - - // Initiate a HCI command - hci_command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_SOCKET, &ret); - - // Process the event - CC3000_EXPORT(errno) = ret; - - set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); - - return(ret); -} - -//***************************************************************************** -// -//! closesocket -//! -//! @param sd socket handle. -//! -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief The socket function closes a created socket. -// -//***************************************************************************** - -INT32 CC3000_EXPORT(closesocket)(INT32 sd) -{ - INT32 ret; - UINT8 *ptr, *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, sd); - - // Initiate a HCI command - hci_command_send(HCI_CMND_CLOSE_SOCKET, - ptr, SOCKET_CLOSE_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_CLOSE_SOCKET, &ret); - CC3000_EXPORT(errno) = ret; - - // since 'close' call may result in either OK (and then it closed) or error - // mark this socket as invalid - set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); - - return(ret); -} - -//***************************************************************************** -// -//! accept -//! -//! @param[in] sd socket descriptor (handle) -//! @param[out] addr the argument addr is a pointer to a sockaddr structure -//! This structure is filled in with the address of the -//! peer socket, as known to the communications layer. -//! determined. The exact format of the address returned -//! addr is by the socket's address sockaddr. -//! On this version only AF_INET is supported. -//! This argument returns in network order. -//! @param[out] addrlen the addrlen argument is a value-result argument: -//! it should initially contain the size of the structure -//! pointed to by addr. -//! -//! @return For socket in blocking mode: -//! On success, socket handle. on failure negative -//! For socket in non-blocking mode: -//! - On connection establishment, socket handle -//! - On connection pending, SOC_IN_PROGRESS (-2) -//! - On failure, SOC_ERROR (-1) -//! -//! @brief accept a connection on a socket: -//! This function is used with connection-based socket types -//! (SOCK_STREAM). It extracts the first connection request on the -//! queue of pending connections, creates a new connected socket, and -//! returns a new file descriptor referring to that socket. -//! The newly created socket is not in the listening state. -//! The original socket sd is unaffected by this call. -//! The argument sd is a socket that has been created with socket(), -//! bound to a local address with bind(), and is listening for -//! connections after a listen(). The argument addr is a pointer -//! to a sockaddr structure. This structure is filled in with the -//! address of the peer socket, as known to the communications layer. -//! The exact format of the address returned addr is determined by the -//! socket's address family. The addrlen argument is a value-result -//! argument: it should initially contain the size of the structure -//! pointed to by addr, on return it will contain the actual -//! length (in bytes) of the address returned. -//! -//! @sa socket ; bind ; listen -// -//***************************************************************************** - -INT32 CC3000_EXPORT(accept)(INT32 sd, sockaddr *addr, socklen_t *addrlen) -{ - INT32 ret; - UINT8 *ptr, *args; - tBsdReturnParams tAcceptReturnArguments; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - - // Initiate a HCI command - hci_command_send(HCI_CMND_ACCEPT, - ptr, SOCKET_ACCEPT_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_ACCEPT, &tAcceptReturnArguments); - - - // need specify return parameters!!! - memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN); - *addrlen = ASIC_ADDR_LEN; - CC3000_EXPORT(errno) = tAcceptReturnArguments.iStatus; - ret = CC3000_EXPORT(errno); - - // if succeeded, iStatus = new socket descriptor. otherwise - error number - if(M_IS_VALID_SD(ret)) - { - set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); - } - else - { - set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); - } - - return(ret); -} - -//***************************************************************************** -// -//! bind -//! -//! @param[in] sd socket descriptor (handle) -//! @param[out] addr specifies the destination address. On this version -//! only AF_INET is supported. -//! @param[out] addrlen contains the size of the structure pointed to by addr. -//! -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief assign a name to a socket -//! This function gives the socket the local address addr. -//! addr is addrlen bytes long. Traditionally, this is called when a -//! socket is created with socket, it exists in a name space (address -//! family) but has no name assigned. -//! It is necessary to assign a local address before a SOCK_STREAM -//! socket may receive connections. -//! -//! @sa socket ; accept ; listen -// -//***************************************************************************** - -INT32 CC3000_EXPORT(bind)(INT32 sd, const sockaddr *addr, INT32 addrlen) -{ - INT32 ret; - UINT8 *ptr, *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - addrlen = ASIC_ADDR_LEN; - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, 0x00000008); - args = UINT32_TO_STREAM(args, addrlen); - ARRAY_TO_STREAM(args, ((UINT8 *)addr), addrlen); - - // Initiate a HCI command - hci_command_send(HCI_CMND_BIND, - ptr, SOCKET_BIND_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_BIND, &ret); - - CC3000_EXPORT(errno) = ret; - - return(ret); -} - -//***************************************************************************** -// -//! listen -//! -//! @param[in] sd socket descriptor (handle) -//! @param[in] backlog specifies the listen queue depth. On this version -//! backlog is not supported. -//! @return On success, zero is returned. On error, -1 is returned. -//! -//! @brief listen for connections on a socket -//! The willingness to accept incoming connections and a queue -//! limit for incoming connections are specified with listen(), -//! and then the connections are accepted with accept. -//! The listen() call applies only to sockets of type SOCK_STREAM -//! The backlog parameter defines the maximum length the queue of -//! pending connections may grow to. -//! -//! @sa socket ; accept ; bind -//! -//! @note On this version, backlog is not supported -// -//***************************************************************************** - -INT32 CC3000_EXPORT(listen)(INT32 sd, INT32 backlog) -{ - INT32 ret; - UINT8 *ptr, *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, backlog); - - // Initiate a HCI command - hci_command_send(HCI_CMND_LISTEN, - ptr, SOCKET_LISTEN_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_LISTEN, &ret); - CC3000_EXPORT(errno) = ret; - - return(ret); -} - -//***************************************************************************** -// -//! gethostbyname -//! -//! @param[in] hostname host name -//! @param[in] usNameLen name length -//! @param[out] out_ip_addr This parameter is filled in with host IP address. -//! In case that host name is not resolved, -//! out_ip_addr is zero. -//! @return On success, positive is returned. On error, negative is returned -//! -//! @brief Get host IP by name. Obtain the IP Address of machine on network, -//! by its name. -//! -//! @note On this version, only blocking mode is supported. Also note that -//! the function requires DNS server to be configured prior to its usage. -// -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT16 CC3000_EXPORT(gethostbyname)(CHAR * hostname, UINT16 usNameLen, - UINT32* out_ip_addr) -{ - tBsdGethostbynameParams ret; - UINT8 *ptr, *args; - - CC3000_EXPORT(errno) = EFAIL; - - if (usNameLen > HOSTNAME_MAX_LENGTH) - { - return CC3000_EXPORT(errno); - } - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, 8); - args = UINT32_TO_STREAM(args, usNameLen); - ARRAY_TO_STREAM(args, hostname, usNameLen); - - // Initiate a HCI command - hci_command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN - + usNameLen - 1); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_EVNT_BSD_GETHOSTBYNAME, &ret); - - CC3000_EXPORT(errno) = ret.retVal; - - (*((INT32*)out_ip_addr)) = ret.outputAddress; - - return CC3000_EXPORT(errno); - -} -#endif - -//***************************************************************************** -// -//! connect -//! -//! @param[in] sd socket descriptor (handle) -//! @param[in] addr specifies the destination addr. On this version -//! only AF_INET is supported. -//! @param[out] addrlen contains the size of the structure pointed to by addr -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief initiate a connection on a socket -//! Function connects the socket referred to by the socket descriptor -//! sd, to the address specified by addr. The addrlen argument -//! specifies the size of addr. The format of the address in addr is -//! determined by the address space of the socket. If it is of type -//! SOCK_DGRAM, this call specifies the peer with which the socket is -//! to be associated; this address is that to which datagrams are to be -//! sent, and the only address from which datagrams are to be received. -//! If the socket is of type SOCK_STREAM, this call attempts to make a -//! connection to another socket. The other socket is specified by -//! address, which is an address in the communications space of the -//! socket. Note that the function implements only blocking behavior -//! thus the caller will be waiting either for the connection -//! establishment or for the connection establishment failure. -//! -//! @sa socket -// -//***************************************************************************** - -INT32 CC3000_EXPORT(connect)(INT32 sd, const sockaddr *addr, INT32 addrlen) -{ - INT32 ret; - UINT8 *ptr, *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); - addrlen = 8; - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, 0x00000008); - args = UINT32_TO_STREAM(args, addrlen); - ARRAY_TO_STREAM(args, ((UINT8 *)addr), addrlen); - - // Initiate a HCI command - hci_command_send(HCI_CMND_CONNECT, - ptr, SOCKET_CONNECT_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_CONNECT, &ret); - - CC3000_EXPORT(errno) = ret; - - return((INT32)ret); -} - - -//***************************************************************************** -// -//! select -//! -//! @param[in] nfds the highest-numbered file descriptor in any of the -//! three sets, plus 1. -//! @param[out] writesds socket descriptors list for write monitoring -//! @param[out] readsds socket descriptors list for read monitoring -//! @param[out] exceptsds socket descriptors list for exception monitoring -//! @param[in] timeout is an upper bound on the amount of time elapsed -//! before select() returns. Null means infinity -//! timeout. The minimum timeout is 5 milliseconds, -//! less than 5 milliseconds will be set -//! automatically to 5 milliseconds. -//! @return On success, select() returns the number of file descriptors -//! contained in the three returned descriptor sets (that is, the -//! total number of bits that are set in readfds, writefds, -//! exceptfds) which may be zero if the timeout expires before -//! anything interesting happens. -//! On error, -1 is returned. -//! *readsds - return the sockets on which Read request will -//! return without delay with valid data. -//! *writesds - return the sockets on which Write request -//! will return without delay. -//! *exceptsds - return the sockets which closed recently. -//! -//! @brief Monitor socket activity -//! Select allow a program to monitor multiple file descriptors, -//! waiting until one or more of the file descriptors become -//! "ready" for some class of I/O operation -//! -//! @Note If the timeout value set to less than 5ms it will automatically set -//! to 5ms to prevent overload of the system -//! -//! @sa socket -// -//***************************************************************************** - -INT16 CC3000_EXPORT(select)(INT32 nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, -struct cc3000_timeval *timeout) -{ - UINT8 *ptr, *args; - tBsdSelectRecvParams tParams; - UINT32 is_blocking; - - if( timeout == NULL) - { - is_blocking = 1; /* blocking , infinity timeout */ - } - else - { - is_blocking = 0; /* no blocking, timeout */ - } - - // Fill in HCI packet structure - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, nfds); - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, is_blocking); - args = UINT32_TO_STREAM(args, ((readsds) ? *(UINT32*)readsds : 0)); - args = UINT32_TO_STREAM(args, ((writesds) ? *(UINT32*)writesds : 0)); - args = UINT32_TO_STREAM(args, ((exceptsds) ? *(UINT32*)exceptsds : 0)); - - if (timeout) - { - if ( 0 == timeout->tv_sec && timeout->tv_usec < - SELECT_TIMEOUT_MIN_MICRO_SECONDS) - { - timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS; - } - args = UINT32_TO_STREAM(args, timeout->tv_sec); - args = UINT32_TO_STREAM(args, timeout->tv_usec); - } - - // Initiate a HCI command - hci_command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_EVNT_SELECT, &tParams); - - // Update actually read FD - if (tParams.iStatus >= 0) - { - if (readsds) - { - memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd)); - } - - if (writesds) - { - memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd)); - } - - if (exceptsds) - { - memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd)); - } - - return(tParams.iStatus); - - } - else - { - CC3000_EXPORT(errno) = tParams.iStatus; - return(-1); - } -} - -//***************************************************************************** -// -//! setsockopt -//! -//! @param[in] sd socket handle -//! @param[in] level defines the protocol level for this option -//! @param[in] optname defines the option name to Interrogate -//! @param[in] optval specifies a value for the option -//! @param[in] optlen specifies the length of the option value -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief set socket options -//! This function manipulate the options associated with a socket. -//! Options may exist at multiple protocol levels; they are always -//! present at the uppermost socket level. -//! When manipulating socket options the level at which the option -//! resides and the name of the option must be specified. -//! To manipulate options at the socket level, level is specified as -//! SOL_SOCKET. To manipulate options at any other level the protocol -//! number of the appropriate protocol controlling the option is -//! supplied. For example, to indicate that an option is to be -//! interpreted by the TCP protocol, level should be set to the -//! protocol number of TCP; -//! The parameters optval and optlen are used to access optval - -//! use for setsockopt(). For getsockopt() they identify a buffer -//! in which the value for the requested option(s) are to -//! be returned. For getsockopt(), optlen is a value-result -//! parameter, initially containing the size of the buffer -//! pointed to by option_value, and modified on return to -//! indicate the actual size of the value returned. If no option -//! value is to be supplied or returned, option_value may be NULL. -//! -//! @Note On this version the following two socket options are enabled: -//! The only protocol level supported in this version -//! is SOL_SOCKET (level). -//! 1. SOCKOPT_RECV_TIMEOUT (optname) -//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout -//! in milliseconds. -//! In that case optval should be pointer to UINT32. -//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on -//! or off. -//! In that case optval should be SOCK_ON or SOCK_OFF (optval). -//! -//! @sa getsockopt -// -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT16 CC3000_EXPORT(setsockopt)(INT32 sd, INT32 level, INT32 optname, const void *optval, - socklen_t optlen) -{ - INT32 ret; - UINT8 *ptr, *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, level); - args = UINT32_TO_STREAM(args, optname); - args = UINT32_TO_STREAM(args, 0x00000008); - args = UINT32_TO_STREAM(args, optlen); - ARRAY_TO_STREAM(args, ((UINT8 *)optval), optlen); - - // Initiate a HCI command - hci_command_send(HCI_CMND_SETSOCKOPT, - ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_SETSOCKOPT, &ret); - - if (ret >= 0) - { - return (0); - } - else - { - CC3000_EXPORT(errno) = ret; - return ret; - } -} -#endif - -//***************************************************************************** -// -//! getsockopt -//! -//! @param[in] sd socket handle -//! @param[in] level defines the protocol level for this option -//! @param[in] optname defines the option name to Interrogate -//! @param[out] optval specifies a value for the option -//! @param[out] optlen specifies the length of the option value -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief set socket options -//! This function manipulate the options associated with a socket. -//! Options may exist at multiple protocol levels; they are always -//! present at the uppermost socket level. -//! When manipulating socket options the level at which the option -//! resides and the name of the option must be specified. -//! To manipulate options at the socket level, level is specified as -//! SOL_SOCKET. To manipulate options at any other level the protocol -//! number of the appropriate protocol controlling the option is -//! supplied. For example, to indicate that an option is to be -//! interpreted by the TCP protocol, level should be set to the -//! protocol number of TCP; -//! The parameters optval and optlen are used to access optval - -//! use for setsockopt(). For getsockopt() they identify a buffer -//! in which the value for the requested option(s) are to -//! be returned. For getsockopt(), optlen is a value-result -//! parameter, initially containing the size of the buffer -//! pointed to by option_value, and modified on return to -//! indicate the actual size of the value returned. If no option -//! value is to be supplied or returned, option_value may be NULL. -//! -//! @Note On this version the following two socket options are enabled: -//! The only protocol level supported in this version -//! is SOL_SOCKET (level). -//! 1. SOCKOPT_RECV_TIMEOUT (optname) -//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout -//! in milliseconds. -//! In that case optval should be pointer to UINT32. -//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on -//! or off. -//! In that case optval should be SOCK_ON or SOCK_OFF (optval). -//! -//! @sa setsockopt -// -//***************************************************************************** - -INT16 CC3000_EXPORT(getsockopt) (INT32 sd, INT32 level, INT32 optname, void *optval, socklen_t *optlen) -{ - UINT8 *ptr, *args; - tBsdGetSockOptReturnParams tRetParams; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, level); - args = UINT32_TO_STREAM(args, optname); - - // Initiate a HCI command - hci_command_send(HCI_CMND_GETSOCKOPT, - ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_CMND_GETSOCKOPT, &tRetParams); - - if (((INT8)tRetParams.iStatus) >= 0) - { - *optlen = 4; - memcpy(optval, tRetParams.ucOptValue, 4); - return (0); - } - else - { - CC3000_EXPORT(errno) = tRetParams.iStatus; - return CC3000_EXPORT(errno); - } -} - -//***************************************************************************** -// -//! simple_link_recv -//! -//! @param sd socket handle -//! @param buf read buffer -//! @param len buffer length -//! @param flags indicates blocking or non-blocking operation -//! @param from pointer to an address structure indicating source address -//! @param fromlen source address structure size -//! -//! @return Return the number of bytes received, or -1 if an error -//! occurred -//! -//! @brief Read data from socket -//! Return the length of the message on successful completion. -//! If a message is too long to fit in the supplied buffer, -//! excess bytes may be discarded depending on the type of -//! socket the message is received from -// -//***************************************************************************** -static INT16 simple_link_recv(INT32 sd, void *buf, INT32 len, INT32 flags, sockaddr *from, - socklen_t *fromlen, INT32 opcode) -{ - UINT8 *ptr, *args; - tBsdReadReturnParams tSocketReadEvent; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, len); - args = UINT32_TO_STREAM(args, flags); - - // Generate the read command, and wait for the - hci_command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(opcode, &tSocketReadEvent); - - // In case the number of bytes is more then zero - read data - if (tSocketReadEvent.iNumberOfBytes > 0) - { - // Wait for the data in a synchronous way. Here we assume that the bug is - // big enough to store also parameters of receive from too.... - SimpleLinkWaitData(buf, (UINT8 *)from, (UINT8 *)fromlen); - } - - CC3000_EXPORT(errno) = tSocketReadEvent.iNumberOfBytes; - - return(tSocketReadEvent.iNumberOfBytes); -} - -//***************************************************************************** -// -//! recv -//! -//! @param[in] sd socket handle -//! @param[out] buf Points to the buffer where the message should be stored -//! @param[in] len Specifies the length in bytes of the buffer pointed to -//! by the buffer argument. -//! @param[in] flags Specifies the type of message reception. -//! On this version, this parameter is not supported. -//! -//! @return Return the number of bytes received, or -1 if an error -//! occurred -//! -//! @brief function receives a message from a connection-mode socket -//! -//! @sa recvfrom -//! -//! @Note On this version, only blocking mode is supported. -// -//***************************************************************************** - -INT16 CC3000_EXPORT(recv)(INT32 sd, void *buf, INT32 len, INT32 flags) -{ - return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV)); -} - -//***************************************************************************** -// -//! recvfrom -//! -//! @param[in] sd socket handle -//! @param[out] buf Points to the buffer where the message should be stored -//! @param[in] len Specifies the length in bytes of the buffer pointed to -//! by the buffer argument. -//! @param[in] flags Specifies the type of message reception. -//! On this version, this parameter is not supported. -//! @param[in] from pointer to an address structure indicating the source -//! address: sockaddr. On this version only AF_INET is -//! supported. -//! @param[in] fromlen source address tructure size -//! -//! @return Return the number of bytes received, or -1 if an error -//! occurred -//! -//! @brief read data from socket -//! function receives a message from a connection-mode or -//! connectionless-mode socket. Note that raw sockets are not -//! supported. -//! -//! @sa recv -//! -//! @Note On this version, only blocking mode is supported. -// -//***************************************************************************** -INT16 CC3000_EXPORT(recvfrom)(INT32 sd, void *buf, INT32 len, INT32 flags, sockaddr *from, - socklen_t *fromlen) -{ - return(simple_link_recv(sd, buf, len, flags, from, fromlen, - HCI_CMND_RECVFROM)); -} - -//***************************************************************************** -// -//! simple_link_send -//! -//! @param sd socket handle -//! @param buf write buffer -//! @param len buffer length -//! @param flags On this version, this parameter is not supported -//! @param to pointer to an address structure indicating destination -//! address -//! @param tolen destination address structure size -//! -//! @return Return the number of bytes transmitted, or -1 if an error -//! occurred, or -2 in case there are no free buffers available -//! (only when SEND_NON_BLOCKING is enabled) -//! -//! @brief This function is used to transmit a message to another -//! socket -// -//***************************************************************************** -static INT16 simple_link_send(INT32 sd, const void *buf, INT32 len, INT32 flags, - const sockaddr *to, INT32 tolen, INT32 opcode) -{ - UINT8 uArgSize=0, addrlen; - UINT8 *ptr, *pDataPtr=0, *args; - UINT32 addr_offset=0; - INT16 res; - tBsdReadReturnParams tSocketSendEvent; - - // Check the bsd_arguments - if (0 != (res = HostFlowControlConsumeBuff(sd))) - { - return res; - } - - //Update the number of sent packets - tSLInformation.NumberOfSentPackets++; - - // Allocate a buffer and construct a packet and send it over spi - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_DATA); - - // Update the offset of data and parameters according to the command - switch(opcode) - { - case HCI_CMND_SENDTO: - { - addr_offset = len + sizeof(len) + sizeof(len); - addrlen = 8; - uArgSize = SOCKET_SENDTO_PARAMS_LEN; - pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN; - break; - } - - case HCI_CMND_SEND: - { - tolen = 0; - to = NULL; - uArgSize = HCI_CMND_SEND_ARG_LENGTH; - pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH; - break; - } - - default: - { - break; - } - } - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd)); - args = UINT32_TO_STREAM(args, len); - args = UINT32_TO_STREAM(args, flags); - - if (opcode == HCI_CMND_SENDTO) - { - args = UINT32_TO_STREAM(args, addr_offset); - args = UINT32_TO_STREAM(args, addrlen); - } - - // Copy the data received from user into the TX Buffer - ARRAY_TO_STREAM(pDataPtr, ((UINT8 *)buf), len); - - // In case we are using SendTo, copy the to parameters - if (opcode == HCI_CMND_SENDTO) - { - ARRAY_TO_STREAM(pDataPtr, ((UINT8 *)to), tolen); - } - - // Initiate a HCI command - hci_data_send(opcode, ptr, uArgSize, len,(UINT8*)to, tolen); - - if (opcode == HCI_CMND_SENDTO) - SimpleLinkWaitEvent(HCI_EVNT_SENDTO, &tSocketSendEvent); - else - SimpleLinkWaitEvent(HCI_EVNT_SEND, &tSocketSendEvent); - - return (len); -} - - -//***************************************************************************** -// -//! send -//! -//! @param sd socket handle -//! @param buf Points to a buffer containing the message to be sent -//! @param len message size in bytes -//! @param flags On this version, this parameter is not supported -//! -//! @return Return the number of bytes transmitted, or -1 if an -//! error occurred -//! -//! @brief Write data to TCP socket -//! This function is used to transmit a message to another -//! socket. -//! -//! @Note On this version, only blocking mode is supported. -//! -//! @sa sendto -// -//***************************************************************************** - -INT16 CC3000_EXPORT(send)(INT32 sd, const void *buf, INT32 len, INT32 flags) -{ - return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND)); -} - -//***************************************************************************** -// -//! sendto -//! -//! @param sd socket handle -//! @param buf Points to a buffer containing the message to be sent -//! @param len message size in bytes -//! @param flags On this version, this parameter is not supported -//! @param to pointer to an address structure indicating the destination -//! address: sockaddr. On this version only AF_INET is -//! supported. -//! @param tolen destination address structure size -//! -//! @return Return the number of bytes transmitted, or -1 if an -//! error occurred -//! -//! @brief Write data to TCP socket -//! This function is used to transmit a message to another -//! socket. -//! -//! @Note On this version, only blocking mode is supported. -//! -//! @sa send -// -//***************************************************************************** - -INT16 CC3000_EXPORT(sendto)(INT32 sd, const void *buf, INT32 len, INT32 flags, const sockaddr *to, - socklen_t tolen) -{ - return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO)); -} - -//***************************************************************************** -// -//! mdnsAdvertiser -//! -//! @param[in] mdnsEnabled flag to enable/disable the mDNS feature -//! @param[in] deviceServiceName Service name as part of the published -//! canonical domain name -//! @param[in] deviceServiceNameLength Length of the service name - up to 32 chars -//! -//! -//! @return On success, zero is returned, return SOC_ERROR if socket was not -//! opened successfully, or if an error occurred. -//! -//! @brief Set CC3000 in mDNS advertiser mode in order to advertise itself. -// -//***************************************************************************** - -INT16 CC3000_EXPORT(mdnsAdvertiser)(UINT16 mdnsEnabled, CHAR * deviceServiceName, UINT16 deviceServiceNameLength) -{ - INT8 ret; - UINT8 *pTxBuffer, *pArgs; - - if (deviceServiceNameLength > MDNS_DEVICE_SERVICE_MAX_LENGTH) - { - return EFAIL; - } - - pTxBuffer = tSLInformation.pucTxCommandBuffer; - pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); - - // Fill in HCI packet structure - pArgs = UINT32_TO_STREAM(pArgs, mdnsEnabled); - pArgs = UINT32_TO_STREAM(pArgs, 8); - pArgs = UINT32_TO_STREAM(pArgs, deviceServiceNameLength); - ARRAY_TO_STREAM(pArgs, deviceServiceName, deviceServiceNameLength); - - // Initiate a HCI command - hci_command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + deviceServiceNameLength); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_EVNT_MDNS_ADVERTISE, &ret); - - return ret; - -} - - -//***************************************************************************** -// -//! getmssvalue -//! -//! @param[in] sd socket descriptor -//! -//! @return On success, returns the MSS value of a TCP connection -//! -//! @brief Returns the MSS value of a TCP connection according to the socket descriptor -// -//***************************************************************************** -UINT16 CC3000_EXPORT(getmssvalue) (INT32 sd) -{ - UINT8 *ptr, *args; - UINT16 ret; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - - // Initiate a HCI command - hci_command_send(HCI_CMND_GETMSSVALUE, ptr, SOCKET_GET_MSS_VALUE_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - SimpleLinkWaitEvent(HCI_EVNT_GETMSSVALUE, &ret); - - return ret; -} diff --git a/drivers/cc3000/src/wlan.c b/drivers/cc3000/src/wlan.c deleted file mode 100644 index 6385937778c..00000000000 --- a/drivers/cc3000/src/wlan.c +++ /dev/null @@ -1,1252 +0,0 @@ -/***************************************************************************** -* -* wlan.c - CC3000 Host Driver Implementation. -* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*****************************************************************************/ - -//***************************************************************************** -// -//! \addtogroup wlan_api -//! @{ -// -//***************************************************************************** - -#include -#include "wlan.h" -#include "hci.h" -#include "ccspi.h" -#include "socket.h" -#include "nvmem.h" -#include "security.h" -#include "evnt_handler.h" - - -volatile sSimplLinkInformation tSLInformation; - -#define SMART_CONFIG_PROFILE_SIZE 67 // 67 = 32 (max ssid) + 32 (max key) + 1 (SSID length) + 1 (security type) + 1 (key length) - -#ifndef CC3000_UNENCRYPTED_SMART_CONFIG -UINT8 key[AES128_KEY_SIZE]; -UINT8 profileArray[SMART_CONFIG_PROFILE_SIZE]; -#endif //CC3000_UNENCRYPTED_SMART_CONFIG - -/* patches type */ -#define PATCHES_HOST_TYPE_WLAN_DRIVER 0x01 -#define PATCHES_HOST_TYPE_WLAN_FW 0x02 -#define PATCHES_HOST_TYPE_BOOTLOADER 0x03 - -#define SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE (16) -#define SL_SIMPLE_CONFIG_PREFIX_LENGTH (3) -#define ETH_ALEN (6) -#define MAXIMAL_SSID_LENGTH (32) - -#define SL_PATCHES_REQUEST_DEFAULT (0) -#define SL_PATCHES_REQUEST_FORCE_HOST (1) -#define SL_PATCHES_REQUEST_FORCE_NONE (2) - - -#define WLAN_SEC_UNSEC (0) -#define WLAN_SEC_WEP (1) -#define WLAN_SEC_WPA (2) -#define WLAN_SEC_WPA2 (3) - - -#define WLAN_SL_INIT_START_PARAMS_LEN (1) -#define WLAN_PATCH_PARAMS_LENGTH (8) -#define WLAN_SET_CONNECTION_POLICY_PARAMS_LEN (12) -#define WLAN_DEL_PROFILE_PARAMS_LEN (4) -#define WLAN_SET_MASK_PARAMS_LEN (4) -#define WLAN_SET_SCAN_PARAMS_LEN (100) -#define WLAN_GET_SCAN_RESULTS_PARAMS_LEN (4) -#define WLAN_ADD_PROFILE_NOSEC_PARAM_LEN (24) -#define WLAN_ADD_PROFILE_WEP_PARAM_LEN (36) -#define WLAN_ADD_PROFILE_WPA_PARAM_LEN (44) -#define WLAN_CONNECT_PARAM_LEN (29) -#define WLAN_SMART_CONFIG_START_PARAMS_LEN (4) - - - - -//***************************************************************************** -// -//! SimpleLink_Init_Start -//! -//! @param usPatchesAvailableAtHost flag to indicate if patches available -//! from host or from EEPROM. Due to the -//! fact the patches are burn to the EEPROM -//! using the patch programmer utility, the -//! patches will be available from the EEPROM -//! and not from the host. -//! -//! @return none -//! -//! @brief Send HCI_CMND_SIMPLE_LINK_START to CC3000 -// -//***************************************************************************** -static void SimpleLink_Init_Start(UINT16 usPatchesAvailableAtHost) -{ - UINT8 *ptr; - UINT8 *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (UINT8 *)(ptr + HEADERS_SIZE_CMD); - - UINT8_TO_STREAM(args, ((usPatchesAvailableAtHost) ? SL_PATCHES_REQUEST_FORCE_NONE : SL_PATCHES_REQUEST_DEFAULT)); - - // IRQ Line asserted - send HCI_CMND_SIMPLE_LINK_START to CC3000 - hci_command_send(HCI_CMND_SIMPLE_LINK_START, ptr, WLAN_SL_INIT_START_PARAMS_LEN); - - SimpleLinkWaitEvent(HCI_CMND_SIMPLE_LINK_START, 0); -} - - - -//***************************************************************************** -// -//! wlan_init -//! -//! @param sWlanCB Asynchronous events callback. -//! 0 no event call back. -//! -call back parameters: -//! 1) event_type: HCI_EVNT_WLAN_UNSOL_CONNECT connect event, -//! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event, -//! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE config done, -//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp report, -//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report OR -//! HCI_EVNT_WLAN_KEEPALIVE keepalive. -//! 2) data: pointer to extra data that received by the event -//! (NULL no data). -//! 3) length: data length. -//! -Events with extra data: -//! HCI_EVNT_WLAN_UNSOL_DHCP: 4 bytes IP, 4 bytes Mask, -//! 4 bytes default gateway, 4 bytes DHCP server and 4 bytes -//! for DNS server. -//! HCI_EVNT_WLAN_ASYNC_PING_REPORT: 4 bytes Packets sent, -//! 4 bytes Packets received, 4 bytes Min round time, -//! 4 bytes Max round time and 4 bytes for Avg round time. -//! -//! @param sFWPatches 0 no patch or pointer to FW patches -//! @param sDriverPatches 0 no patch or pointer to driver patches -//! @param sBootLoaderPatches 0 no patch or pointer to bootloader patches -//! @param sReadWlanInterruptPin init callback. the callback read wlan -//! interrupt status. -//! @param sWlanInterruptEnable init callback. the callback enable wlan -//! interrupt. -//! @param sWlanInterruptDisable init callback. the callback disable wlan -//! interrupt. -//! @param sWriteWlanPin init callback. the callback write value -//! to device pin. -//! -//! @return none -//! -//! @sa wlan_set_event_mask , wlan_start , wlan_stop -//! -//! @brief Initialize wlan driver -//! -//! @warning This function must be called before ANY other wlan driver function -// -//***************************************************************************** - -void wlan_init( tWlanCB sWlanCB, - tFWPatches sFWPatches, - tDriverPatches sDriverPatches, - tBootLoaderPatches sBootLoaderPatches, - tWlanReadInteruptPin sReadWlanInterruptPin, - tWlanInterruptEnable sWlanInterruptEnable, - tWlanInterruptDisable sWlanInterruptDisable, - tWriteWlanPin sWriteWlanPin) -{ - - tSLInformation.sFWPatches = sFWPatches; - tSLInformation.sDriverPatches = sDriverPatches; - tSLInformation.sBootLoaderPatches = sBootLoaderPatches; - - // init io callback - tSLInformation.ReadWlanInterruptPin = sReadWlanInterruptPin; - tSLInformation.WlanInterruptEnable = sWlanInterruptEnable; - tSLInformation.WlanInterruptDisable = sWlanInterruptDisable; - tSLInformation.WriteWlanPin = sWriteWlanPin; - - //init asynchronous events callback - tSLInformation.sWlanCB= sWlanCB; - - // By default TX Complete events are routed to host too - tSLInformation.InformHostOnTxComplete = 1; -} - -//***************************************************************************** -// -//! SpiReceiveHandler -//! -//! @param pvBuffer - pointer to the received data buffer -//! The function triggers Received event/data processing -//! -//! @param Pointer to the received data -//! @return none -//! -//! @brief The function triggers Received event/data processing. It is -//! called from the SPI library to receive the data -// -//***************************************************************************** -void SpiReceiveHandler(void *pvBuffer) -{ - tSLInformation.usEventOrDataReceived = 1; - tSLInformation.pucReceivedData = (UINT8 *)pvBuffer; - - hci_unsolicited_event_handler(); -} - - -//***************************************************************************** -// -//! wlan_start -//! -//! @param usPatchesAvailableAtHost - flag to indicate if patches available -//! from host or from EEPROM. Due to the -//! fact the patches are burn to the EEPROM -//! using the patch programmer utility, the -//! patches will be available from the EEPROM -//! and not from the host. -//! -//! @return none -//! -//! @brief Start WLAN device. This function asserts the enable pin of -//! the device (WLAN_EN), starting the HW initialization process. -//! The function blocked until device Initialization is completed. -//! Function also configure patches (FW, driver or bootloader) -//! and calls appropriate device callbacks. -//! -//! @Note Prior calling the function wlan_init shall be called. -//! @Warning This function must be called after wlan_init and before any -//! other wlan API -//! @sa wlan_init , wlan_stop -//! -// -//***************************************************************************** -#define TIMEOUT (500000) - -int wlan_start(UINT16 usPatchesAvailableAtHost) -{ - - UINT32 ulSpiIRQState; - UINT32 wlan_timeout; - - tSLInformation.NumberOfSentPackets = 0; - tSLInformation.NumberOfReleasedPackets = 0; - tSLInformation.usRxEventOpcode = 0; - tSLInformation.usNumberOfFreeBuffers = 0; - tSLInformation.usSlBufferLength = 0; - tSLInformation.usBufferSize = 0; - tSLInformation.usRxDataPending = 0; - tSLInformation.slTransmitDataError = 0; - tSLInformation.usEventOrDataReceived = 0; - tSLInformation.pucReceivedData = 0; - - // Allocate the memory for the RX/TX data transactions - tSLInformation.pucTxCommandBuffer = (UINT8 *)wlan_tx_buffer; - - // init spi - SpiOpen(SpiReceiveHandler); - - // Check the IRQ line - ulSpiIRQState = tSLInformation.ReadWlanInterruptPin(); - - // Chip enable: toggle WLAN EN line - tSLInformation.WriteWlanPin( WLAN_ENABLE ); - - wlan_timeout = TIMEOUT; - if (ulSpiIRQState) { - // wait till the IRQ line goes low - while(tSLInformation.ReadWlanInterruptPin() != 0 && --wlan_timeout) - { - } - } - else - { - // wait till the IRQ line goes high and than low - while(tSLInformation.ReadWlanInterruptPin() == 0 && --wlan_timeout) - { - } - - if (wlan_timeout == 0) { - return -1; - } - - wlan_timeout = TIMEOUT; - while(tSLInformation.ReadWlanInterruptPin() != 0 && --wlan_timeout) - { - } - } - - if (wlan_timeout ==0) { - return -1; - } - - SimpleLink_Init_Start(usPatchesAvailableAtHost); - - // Read Buffer's size and finish - hci_command_send(HCI_CMND_READ_BUFFER_SIZE, tSLInformation.pucTxCommandBuffer, 0); - SimpleLinkWaitEvent(HCI_CMND_READ_BUFFER_SIZE, 0); - - return 0; -} - - -//***************************************************************************** -// -//! wlan_stop -//! -//! @param none -//! -//! @return none -//! -//! @brief Stop WLAN device by putting it into reset state. -//! -//! @sa wlan_start -// -//***************************************************************************** - -void wlan_stop(void) -{ - // Chip disable - tSLInformation.WriteWlanPin( WLAN_DISABLE ); - - // Wait till IRQ line goes high... - while(tSLInformation.ReadWlanInterruptPin() == 0) - { - } - - // Free the used by WLAN Driver memory - if (tSLInformation.pucTxCommandBuffer) - { - tSLInformation.pucTxCommandBuffer = 0; - } - - SpiClose(); -} - - -//***************************************************************************** -// -//! wlan_connect -//! -//! @param sec_type security options: -//! WLAN_SEC_UNSEC, -//! WLAN_SEC_WEP (ASCII support only), -//! WLAN_SEC_WPA or WLAN_SEC_WPA2 -//! @param ssid up to 32 bytes and is ASCII SSID of the AP -//! @param ssid_len length of the SSID -//! @param bssid 6 bytes specified the AP bssid -//! @param key up to 32 bytes specified the AP security key -//! @param key_len key length -//! -//! @return On success, zero is returned. On error, negative is returned. -//! Note that even though a zero is returned on success to trigger -//! connection operation, it does not mean that CCC3000 is already -//! connected. An asynchronous "Connected" event is generated when -//! actual association process finishes and CC3000 is connected to -//! the AP. If DHCP is set, An asynchronous "DHCP" event is -//! generated when DHCP process is finish. -//! -//! -//! @brief Connect to AP -//! @warning Please Note that when connection to AP configured with security -//! type WEP, please confirm that the key is set as ASCII and not -//! as HEX. -//! @sa wlan_disconnect -// -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 wlan_connect(UINT32 ulSecType, CHAR *ssid, INT32 ssid_len, - UINT8 *bssid, UINT8 *key, INT32 key_len) -{ - INT32 ret; - UINT8 *ptr; - UINT8 *args; - UINT8 bssid_zero[] = {0, 0, 0, 0, 0, 0}; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in command buffer - args = UINT32_TO_STREAM(args, 0x0000001c); - args = UINT32_TO_STREAM(args, ssid_len); - args = UINT32_TO_STREAM(args, ulSecType); - args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len); - args = UINT32_TO_STREAM(args, key_len); - args = UINT16_TO_STREAM(args, 0); - - // padding shall be zeroed - if(bssid) - { - ARRAY_TO_STREAM(args, bssid, ETH_ALEN); - } - else - { - ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); - } - - ARRAY_TO_STREAM(args, ssid, ssid_len); - - if(key_len && key) - { - ARRAY_TO_STREAM(args, key, key_len); - } - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + - ssid_len + key_len - 1); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret); - CC3000_EXPORT(errno) = ret; - - return(ret); -} -#else -INT32 wlan_connect(CHAR *ssid, INT32 ssid_len) -{ - INT32 ret; - UINT8 *ptr; - UINT8 *args; - UINT8 bssid_zero[] = {0, 0, 0, 0, 0, 0}; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in command buffer - args = UINT32_TO_STREAM(args, 0x0000001c); - args = UINT32_TO_STREAM(args, ssid_len); - args = UINT32_TO_STREAM(args, 0); - args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len); - args = UINT32_TO_STREAM(args, 0); - args = UINT16_TO_STREAM(args, 0); - - // padding shall be zeroed - ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); - ARRAY_TO_STREAM(args, ssid, ssid_len); - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + - ssid_len - 1); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret); - CC3000_EXPORT(errno) = ret; - - return(ret); -} -#endif - -//***************************************************************************** -// -//! wlan_disconnect -//! -//! @return 0 disconnected done, other CC3000 already disconnected -//! -//! @brief Disconnect connection from AP. -//! -//! @sa wlan_connect -// -//***************************************************************************** - -INT32 wlan_disconnect() -{ - INT32 ret; - UINT8 *ptr; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - - hci_command_send(HCI_CMND_WLAN_DISCONNECT, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_DISCONNECT, &ret); - CC3000_EXPORT(errno) = ret; - - return(ret); -} - -//***************************************************************************** -// -//! wlan_ioctl_set_connection_policy -//! -//! @param should_connect_to_open_ap enable(1), disable(0) connect to any -//! available AP. This parameter corresponds to the configuration of -//! item # 3 in the brief description. -//! @param should_use_fast_connect enable(1), disable(0). if enabled, tries -//! to connect to the last connected AP. This parameter corresponds -//! to the configuration of item # 1 in the brief description. -//! @param auto_start enable(1), disable(0) auto connect -//! after reset and periodically reconnect if needed. This -//! configuration configures option 2 in the above description. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief When auto is enabled, the device tries to connect according -//! the following policy: -//! 1) If fast connect is enabled and last connection is valid, -//! the device will try to connect to it without the scanning -//! procedure (fast). The last connection will be marked as -//! invalid, due to adding/removing profile. -//! 2) If profile exists, the device will try to connect it -//! (Up to seven profiles). -//! 3) If fast and profiles are not found, and open mode is -//! enabled, the device will try to connect to any AP. -//! * Note that the policy settings are stored in the CC3000 NVMEM. -//! -//! @sa wlan_add_profile , wlan_ioctl_del_profile -// -//***************************************************************************** - -INT32 wlan_ioctl_set_connection_policy(UINT32 should_connect_to_open_ap, - UINT32 ulShouldUseFastConnect, - UINT32 ulUseProfiles) -{ - INT32 ret; - UINT8 *ptr; - UINT8 *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (UINT8 *)(ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, should_connect_to_open_ap); - args = UINT32_TO_STREAM(args, ulShouldUseFastConnect); - args = UINT32_TO_STREAM(args, ulUseProfiles); - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, - ptr, WLAN_SET_CONNECTION_POLICY_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, &ret); - - return(ret); -} - -//***************************************************************************** -// -//! wlan_add_profile -//! -//! @param ulSecType WLAN_SEC_UNSEC,WLAN_SEC_WEP,WLAN_SEC_WPA,WLAN_SEC_WPA2 -//! @param ucSsid ssid SSID up to 32 bytes -//! @param ulSsidLen ssid length -//! @param ucBssid bssid 6 bytes -//! @param ulPriority ulPriority profile priority. Lowest priority:0. -//! Important Note: Smartconfig process (in unencrypted mode) -//! stores the profile internally with priority 1, so changing -//! priorities when adding new profiles should be done with extra care -//! @param ulPairwiseCipher_Or_TxKeyLen key length for WEP security -//! @param ulGroupCipher_TxKeyIndex key index -//! @param ulKeyMgmt KEY management -//! @param ucPf_OrKey security key -//! @param ulPassPhraseLen security key length for WPA\WPA2 -//! -//! @return On success, index (1-7) of the stored profile is returned. -//! On error, -1 is returned. -//! -//! @brief When auto start is enabled, the device connects to -//! station from the profiles table. Up to 7 profiles are supported. -//! If several profiles configured the device choose the highest -//! priority profile, within each priority group, device will choose -//! profile based on security policy, signal strength, etc -//! parameters. All the profiles are stored in CC3000 NVMEM. -//! -//! @sa wlan_ioctl_del_profile -// -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 wlan_add_profile(UINT32 ulSecType, - UINT8* ucSsid, - UINT32 ulSsidLen, - UINT8 *ucBssid, - UINT32 ulPriority, - UINT32 ulPairwiseCipher_Or_TxKeyLen, - UINT32 ulGroupCipher_TxKeyIndex, - UINT32 ulKeyMgmt, - UINT8* ucPf_OrKey, - UINT32 ulPassPhraseLen) -{ - UINT16 arg_len=0; - INT32 ret; - UINT8 *ptr; - INT32 i = 0; - UINT8 *args; - UINT8 bssid_zero[] = {0, 0, 0, 0, 0, 0}; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - args = UINT32_TO_STREAM(args, ulSecType); - - // Setup arguments in accordance with the security type - switch (ulSecType) - { - //OPEN - case WLAN_SEC_UNSEC: - { - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, ulSsidLen); - args = UINT16_TO_STREAM(args, 0); - if(ucBssid) - { - ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); - } - else - { - ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); - } - args = UINT32_TO_STREAM(args, ulPriority); - ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); - - arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ulSsidLen; - } - break; - - //WEP - case WLAN_SEC_WEP: - { - args = UINT32_TO_STREAM(args, 0x00000020); - args = UINT32_TO_STREAM(args, ulSsidLen); - args = UINT16_TO_STREAM(args, 0); - if(ucBssid) - { - ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); - } - else - { - ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); - } - args = UINT32_TO_STREAM(args, ulPriority); - args = UINT32_TO_STREAM(args, 0x0000000C + ulSsidLen); - args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen); - args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex); - ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); - - for(i = 0; i < 4; i++) - { - UINT8 *p = &ucPf_OrKey[i * ulPairwiseCipher_Or_TxKeyLen]; - - ARRAY_TO_STREAM(args, p, ulPairwiseCipher_Or_TxKeyLen); - } - - arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ulSsidLen + - ulPairwiseCipher_Or_TxKeyLen * 4; - - } - break; - - //WPA - //WPA2 - case WLAN_SEC_WPA: - case WLAN_SEC_WPA2: - { - args = UINT32_TO_STREAM(args, 0x00000028); - args = UINT32_TO_STREAM(args, ulSsidLen); - args = UINT16_TO_STREAM(args, 0); - if(ucBssid) - { - ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); - } - else - { - ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); - } - args = UINT32_TO_STREAM(args, ulPriority); - args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen); - args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex); - args = UINT32_TO_STREAM(args, ulKeyMgmt); - args = UINT32_TO_STREAM(args, 0x00000008 + ulSsidLen); - args = UINT32_TO_STREAM(args, ulPassPhraseLen); - ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); - ARRAY_TO_STREAM(args, ucPf_OrKey, ulPassPhraseLen); - - arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ulSsidLen + ulPassPhraseLen; - } - - break; - } - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, - ptr, arg_len); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret); - - return(ret); -} -#else -INT32 wlan_add_profile(UINT32 ulSecType, - UINT8* ucSsid, - UINT32 ulSsidLen, - UINT8 *ucBssid, - UINT32 ulPriority, - UINT32 ulPairwiseCipher_Or_TxKeyLen, - UINT32 ulGroupCipher_TxKeyIndex, - UINT32 ulKeyMgmt, - UINT8* ucPf_OrKey, - UINT32 ulPassPhraseLen) -{ - return -1; -} -#endif - -//***************************************************************************** -// -//! wlan_ioctl_del_profile -//! -//! @param index number of profile to delete -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Delete WLAN profile -//! -//! @Note In order to delete all stored profile, set index to 255. -//! -//! @sa wlan_add_profile -// -//***************************************************************************** - -INT32 wlan_ioctl_del_profile(UINT32 ulIndex) -{ - INT32 ret; - UINT8 *ptr; - UINT8 *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (UINT8 *)(ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, ulIndex); - ret = EFAIL; - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, - ptr, WLAN_DEL_PROFILE_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, &ret); - - return(ret); -} - -//***************************************************************************** -// -//! wlan_ioctl_get_scan_results -//! -//! @param[in] scan_timeout parameter not supported -//! @param[out] ucResults scan results (_wlan_full_scan_results_args_t) -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Gets entry from scan result table. -//! The scan results are returned one by one, and each entry -//! represents a single AP found in the area. The following is a -//! format of the scan result: -//! - 4 Bytes: number of networks found -//! - 4 Bytes: The status of the scan: 0 - aged results, -//! 1 - results valid, 2 - no results -//! - 42 bytes: Result entry, where the bytes are arranged as follows: -//! -//! - 1 bit isValid - is result valid or not -//! - 7 bits rssi - RSSI value; -//! - 2 bits: securityMode - security mode of the AP: -//! 0 - Open, 1 - WEP, 2 WPA, 3 WPA2 -//! - 6 bits: SSID name length -//! - 2 bytes: the time at which the entry has entered into -//! scans result table -//! - 32 bytes: SSID name -//! - 6 bytes: BSSID -//! -//! @Note scan_timeout, is not supported on this version. -//! -//! @sa wlan_ioctl_set_scan_params -// -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 wlan_ioctl_get_scan_results(UINT32 ulScanTimeout, - UINT8 *ucResults) -{ - UINT8 *ptr; - UINT8 *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, ulScanTimeout); - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, - ptr, WLAN_GET_SCAN_RESULTS_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, ucResults); - - return(0); -} -#endif - -//***************************************************************************** -// -//! wlan_ioctl_set_scan_params -//! -//! @param uiEnable - start/stop application scan: -//! 1 = start scan with default interval value of 10 min. -//! in order to set a different scan interval value apply the value -//! in milliseconds. minimum 1 second. 0=stop). Wlan reset -//! (wlan_stop() wlan_start()) is needed when changing scan interval -//! value. Saved: No -//! @param uiMinDwellTime minimum dwell time value to be used for each -//! channel, in milliseconds. Saved: yes -//! Recommended Value: 100 (Default: 20) -//! @param uiMaxDwellTime maximum dwell time value to be used for each -//! channel, in milliseconds. Saved: yes -//! Recommended Value: 100 (Default: 30) -//! @param uiNumOfProbeRequests max probe request between dwell time. -//! Saved: yes. Recommended Value: 5 (Default:2) -//! @param uiChannelMask bitwise, up to 13 channels (0x1fff). -//! Saved: yes. Default: 0x7ff -//! @param uiRSSIThreshold RSSI threshold. Saved: yes (Default: -80) -//! @param uiSNRThreshold NSR threshold. Saved: yes (Default: 0) -//! @param uiDefaultTxPower probe Tx power. Saved: yes (Default: 205) -//! @param aiIntervalList pointer to array with 16 entries (16 channels) -//! each entry (UINT32) holds timeout between periodic scan -//! (connection scan) - in millisecond. Saved: yes. Default 2000ms. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief start and stop scan procedure. Set scan parameters. -//! -//! @Note uiDefaultTxPower, is not supported on this version. -//! -//! @sa wlan_ioctl_get_scan_results -// -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 wlan_ioctl_set_scan_params(UINT32 uiEnable, UINT32 uiMinDwellTime, - UINT32 uiMaxDwellTime, - UINT32 uiNumOfProbeRequests, - UINT32 uiChannelMask,INT32 iRSSIThreshold, - UINT32 uiSNRThreshold, - UINT32 uiDefaultTxPower, - UINT32 *aiIntervalList) -{ - UINT32 uiRes; - UINT8 *ptr; - UINT8 *args; - - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, 36); - args = UINT32_TO_STREAM(args, uiEnable); - args = UINT32_TO_STREAM(args, uiMinDwellTime); - args = UINT32_TO_STREAM(args, uiMaxDwellTime); - args = UINT32_TO_STREAM(args, uiNumOfProbeRequests); - args = UINT32_TO_STREAM(args, uiChannelMask); - args = UINT32_TO_STREAM(args, iRSSIThreshold); - args = UINT32_TO_STREAM(args, uiSNRThreshold); - args = UINT32_TO_STREAM(args, uiDefaultTxPower); - ARRAY_TO_STREAM(args, aiIntervalList, sizeof(UINT32) * - SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE); - - // Initiate a HCI command - hci_command_send(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, - ptr, WLAN_SET_SCAN_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, &uiRes); - - return(uiRes); -} -#endif - -//***************************************************************************** -// -//! wlan_set_event_mask -//! -//! @param mask mask option: -//! HCI_EVNT_WLAN_UNSOL_CONNECT connect event -//! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event -//! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE smart config done -//! HCI_EVNT_WLAN_UNSOL_INIT init done -//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp event report -//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report -//! HCI_EVNT_WLAN_KEEPALIVE keepalive -//! HCI_EVNT_WLAN_TX_COMPLETE - disable information on end of transmission -//! Saved: no. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Mask event according to bit mask. In case that event is -//! masked (1), the device will not send the masked event to host. -// -//***************************************************************************** - -INT32 wlan_set_event_mask(UINT32 ulMask) -{ - INT32 ret; - UINT8 *ptr; - UINT8 *args; - - - if ((ulMask & HCI_EVNT_WLAN_TX_COMPLETE) == HCI_EVNT_WLAN_TX_COMPLETE) - { - tSLInformation.InformHostOnTxComplete = 0; - - // Since an event is a virtual event - i.e. it is not coming from CC3000 - // there is no need to send anything to the device if it was an only event - if (ulMask == HCI_EVNT_WLAN_TX_COMPLETE) - { - return 0; - } - - ulMask &= ~HCI_EVNT_WLAN_TX_COMPLETE; - ulMask |= HCI_EVNT_WLAN_UNSOL_BASE; - } - else - { - tSLInformation.InformHostOnTxComplete = 1; - } - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (UINT8 *)(ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, ulMask); - - // Initiate a HCI command - hci_command_send(HCI_CMND_EVENT_MASK, - ptr, WLAN_SET_MASK_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_EVENT_MASK, &ret); - - return(ret); -} - -//***************************************************************************** -// -//! wlan_ioctl_statusget -//! -//! @param none -//! -//! @return WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING, -//! STATUS_CONNECTING or WLAN_STATUS_CONNECTED -//! -//! @brief get wlan status: disconnected, scanning, connecting or connected -// -//***************************************************************************** - -#ifndef CC3000_TINY_DRIVER -INT32 wlan_ioctl_statusget(void) -{ - INT32 ret; - UINT8 *ptr; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - - hci_command_send(HCI_CMND_WLAN_IOCTL_STATUSGET, - ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_STATUSGET, &ret); - - return(ret); -} -#endif - -//***************************************************************************** -// -//! wlan_smart_config_start -//! -//! @param algoEncryptedFlag indicates whether the information is encrypted -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Start to acquire device profile. The device acquire its own -//! profile, if profile message is found. The acquired AP information -//! is stored in CC3000 EEPROM only in case AES128 encryption is used. -//! In case AES128 encryption is not used, a profile is created by -//! CC3000 internally. -//! -//! @Note An asynchronous event - Smart Config Done will be generated as soon -//! as the process finishes successfully. -//! -//! @sa wlan_smart_config_set_prefix , wlan_smart_config_stop -// -//***************************************************************************** - -INT32 wlan_smart_config_start(UINT32 algoEncryptedFlag) -{ - INT32 ret; - UINT8 *ptr; - UINT8 *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (UINT8 *)(ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, algoEncryptedFlag); - ret = EFAIL; - - hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, ptr, - WLAN_SMART_CONFIG_START_PARAMS_LEN); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, &ret); - - return(ret); -} - -//***************************************************************************** -// -//! wlan_smart_config_stop -//! -//! @param algoEncryptedFlag indicates whether the information is encrypted -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Stop the acquire profile procedure -//! -//! @sa wlan_smart_config_start , wlan_smart_config_set_prefix -// -//***************************************************************************** - -INT32 wlan_smart_config_stop(void) -{ - INT32 ret; - UINT8 *ptr; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - - hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, ptr, 0); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, &ret); - - return(ret); -} - -//***************************************************************************** -// -//! wlan_smart_config_set_prefix -//! -//! @param newPrefix 3 bytes identify the SSID prefix for the Smart Config. -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief Configure station ssid prefix. The prefix is used internally -//! in CC3000. It should always be TTT. -//! -//! @Note The prefix is stored in CC3000 NVMEM -//! -//! @sa wlan_smart_config_start , wlan_smart_config_stop -// -//***************************************************************************** - -INT32 wlan_smart_config_set_prefix(CHAR* cNewPrefix) -{ - INT32 ret; - UINT8 *ptr; - UINT8 *args; - - ret = EFAIL; - ptr = tSLInformation.pucTxCommandBuffer; - args = (ptr + HEADERS_SIZE_CMD); - - if (cNewPrefix == NULL) - return ret; - else // with the new Smart Config, prefix must be TTT - { - *cNewPrefix = 'T'; - *(cNewPrefix + 1) = 'T'; - *(cNewPrefix + 2) = 'T'; - } - - ARRAY_TO_STREAM(args, cNewPrefix, SL_SIMPLE_CONFIG_PREFIX_LENGTH); - - hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, ptr, - SL_SIMPLE_CONFIG_PREFIX_LENGTH); - - // Wait for command complete event - SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, &ret); - - return(ret); -} - -//***************************************************************************** -// -//! wlan_smart_config_process -//! -//! @param none -//! -//! @return On success, zero is returned. On error, -1 is returned -//! -//! @brief process the acquired data and store it as a profile. The acquired -//! AP information is stored in CC3000 EEPROM encrypted. -//! The encrypted data is decrypted and stored as a profile. -//! behavior is as defined by connection policy. -// -//***************************************************************************** - - -#ifndef CC3000_UNENCRYPTED_SMART_CONFIG -INT32 wlan_smart_config_process() -{ - INT32 returnValue; - UINT32 ssidLen, keyLen; - UINT8 *decKeyPtr; - UINT8 *ssidPtr; - - // read the key from EEPROM - fileID 12 - returnValue = aes_read_key(key); - - if (returnValue != 0) - return returnValue; - - // read the received data from fileID #13 and parse it according to the followings: - // 1) SSID LEN - not encrypted - // 2) SSID - not encrypted - // 3) KEY LEN - not encrypted. always 32 bytes long - // 4) Security type - not encrypted - // 5) KEY - encrypted together with true key length as the first byte in KEY - // to elaborate, there are two corner cases: - // 1) the KEY is 32 bytes long. In this case, the first byte does not represent KEY length - // 2) the KEY is 31 bytes long. In this case, the first byte represent KEY length and equals 31 - returnValue = nvmem_read(NVMEM_SHARED_MEM_FILEID, SMART_CONFIG_PROFILE_SIZE, 0, profileArray); - - if (returnValue != 0) - return returnValue; - - ssidPtr = &profileArray[1]; - - ssidLen = profileArray[0]; - - decKeyPtr = &profileArray[profileArray[0] + 3]; - - aes_decrypt(decKeyPtr, key); - if (profileArray[profileArray[0] + 1] > 16) - aes_decrypt((UINT8 *)(decKeyPtr + 16), key); - - if (*(UINT8 *)(decKeyPtr +31) != 0) - { - if (*decKeyPtr == 31) - { - keyLen = 31; - decKeyPtr++; - } - else - { - keyLen = 32; - } - } - else - { - keyLen = *decKeyPtr; - decKeyPtr++; - } - - // add a profile - switch (profileArray[profileArray[0] + 2]) - { - case WLAN_SEC_UNSEC://None - { - returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], // security type - ssidPtr, // SSID - ssidLen, // SSID length - NULL, // BSSID - 1, // Priority - 0, 0, 0, 0, 0); - - break; - } - - case WLAN_SEC_WEP://WEP - { - returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], // security type - ssidPtr, // SSID - ssidLen, // SSID length - NULL, // BSSID - 1, // Priority - keyLen, // KEY length - 0, // KEY index - 0, - decKeyPtr, // KEY - 0); - - break; - } - - case WLAN_SEC_WPA://WPA - case WLAN_SEC_WPA2://WPA2 - { - returnValue = wlan_add_profile(WLAN_SEC_WPA2, // security type - ssidPtr, - ssidLen, - NULL, // BSSID - 1, // Priority - 0x18, // PairwiseCipher - 0x1e, // GroupCipher - 2, // KEY management - decKeyPtr, // KEY - keyLen); // KEY length - - break; - } - } - - return returnValue; -} -#endif //CC3000_UNENCRYPTED_SMART_CONFIG - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** diff --git a/drivers/cc3100/inc/device.h b/drivers/cc3100/inc/device.h deleted file mode 100644 index 169736da213..00000000000 --- a/drivers/cc3100/inc/device.h +++ /dev/null @@ -1,656 +0,0 @@ -/* - * device.h - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ -#include "simplelink.h" - -#ifndef __DEVICE_H__ -#define __DEVICE_H__ - - - -#ifdef __cplusplus -extern "C" { -#endif - - - -/*! - - \addtogroup device - @{ - -*/ - -/*****************************************************************************/ -/* Macro declarations */ -/*****************************************************************************/ - - -/* SL internal Error codes */ - -/* Receive this error in case there are no resources to issue the command - If possible, increase the number of MAX_CUNCURENT_ACTIONS (result in memory increase) - If not, try again later */ -#define SL_POOL_IS_EMPTY (-2000) - -/* Receive this error in case a given length for RX buffer was too small. - Receive payload was bigger than the given buffer size. Therefore, payload is cut according to receive size - Recommend to increase buffer size */ -#define SL_ESMALLBUF (-2001) - -/* Receive this error in case zero length is supplied to a "get" API - Recommend to supply length according to requested information (view options defines for help) */ -#define SL_EZEROLEN (-2002) - -/* User supplied invalid parameter */ -#define SL_INVALPARAM (-2003) - - -/* Failed to open interface */ -#define SL_BAD_INTERFACE (-2004) - -/* End of SL internal Error codes */ - - - -/*****************************************************************************/ -/* Errors returned from the general error async event */ -/*****************************************************************************/ - -/* Send types */ -typedef enum -{ - SL_ERR_SENDER_HEALTH_MON, - SL_ERR_SENDER_CLI_UART, - SL_ERR_SENDER_SUPPLICANT, - SL_ERR_SENDER_NETWORK_STACK, - SL_ERR_SENDER_WLAN_DRV_IF, - SL_ERR_SENDER_WILINK, - SL_ERR_SENDER_INIT_APP, - SL_ERR_SENDER_NETX, - SL_ERR_SENDER_HOST_APD, - SL_ERR_SENDER_MDNS, - SL_ERR_SENDER_HTTP_SERVER, - SL_ERR_SENDER_DHCP_SERVER, - SL_ERR_SENDER_DHCP_CLIENT, - SL_ERR_DISPATCHER, - SL_ERR_NUM_SENDER_LAST=0xFF -}SlErrorSender_e; - - -/* Error codes */ -#define SL_ERROR_STATIC_ADDR_SUBNET_ERROR (-60) /* network stack error*/ -#define SL_ERROR_ILLEGAL_CHANNEL (-61) /* supplicant error */ -#define SL_ERROR_SUPPLICANT_ERROR (-72) /* init error code */ -#define SL_ERROR_HOSTAPD_INIT_FAIL (-73) /* init error code */ -#define SL_ERROR_HOSTAPD_INIT_IF_FAIL (-74) /* init error code */ -#define SL_ERROR_WLAN_DRV_INIT_FAIL (-75) /* init error code */ -#define SL_ERROR_WLAN_DRV_START_FAIL (-76) /* wlan start error */ -#define SL_ERROR_FS_FILE_TABLE_LOAD_FAILED (-77) /* init file system failed */ -#define SL_ERROR_PREFERRED_NETWORKS_FILE_LOAD_FAILED (-78) /* init file system failed */ -#define SL_ERROR_HOSTAPD_BSSID_VALIDATION_ERROR (-79) /* Ap configurations BSSID error */ -#define SL_ERROR_HOSTAPD_FAILED_TO_SETUP_INTERFACE (-80) /* Ap configurations interface error */ -#define SL_ERROR_MDNS_ENABLE_FAIL (-81) /* mDNS enable failed */ -#define SL_ERROR_HTTP_SERVER_ENABLE_FAILED (-82) /* HTTP server enable failed */ -#define SL_ERROR_DHCP_SERVER_ENABLE_FAILED (-83) /* DHCP server enable failed */ -#define SL_ERROR_PREFERRED_NETWORK_LIST_FULL (-93) /* supplicant error */ -#define SL_ERROR_PREFERRED_NETWORKS_FILE_WRITE_FAILED (-94) /* supplicant error */ -#define SL_ERROR_DHCP_CLIENT_RENEW_FAILED (-100) /* DHCP client error */ -/* WLAN Connection management status */ -#define SL_ERROR_CON_MGMT_STATUS_UNSPECIFIED (-102) -#define SL_ERROR_CON_MGMT_STATUS_AUTH_REJECT (-103) -#define SL_ERROR_CON_MGMT_STATUS_ASSOC_REJECT (-104) -#define SL_ERROR_CON_MGMT_STATUS_SECURITY_FAILURE (-105) -#define SL_ERROR_CON_MGMT_STATUS_AP_DEAUTHENTICATE (-106) -#define SL_ERROR_CON_MGMT_STATUS_AP_DISASSOCIATE (-107) -#define SL_ERROR_CON_MGMT_STATUS_ROAMING_TRIGGER (-108) -#define SL_ERROR_CON_MGMT_STATUS_DISCONNECT_DURING_CONNECT (-109) -#define SL_ERROR_CON_MGMT_STATUS_SG_RESELECT (-110) -#define SL_ERROR_CON_MGMT_STATUS_ROC_FAILURE (-111) -#define SL_ERROR_CON_MGMT_STATUS_MIC_FAILURE (-112) -/* end of WLAN connection management error statuses */ -#define SL_ERROR_WAKELOCK_ERROR_PREFIX (-115) /* Wake lock expired */ -#define SL_ERROR_LENGTH_ERROR_PREFIX (-116) /* Uart header length error */ -#define SL_ERROR_MDNS_CREATE_FAIL (-121) /* mDNS create failed */ -#define SL_ERROR_GENERAL_ERROR (-127) - - - -#define SL_DEVICE_GENERAL_CONFIGURATION (1) -#define SL_DEVICE_GENERAL_CONFIGURATION_DATE_TIME (11) -#define SL_DEVICE_GENERAL_VERSION (12) -#define SL_DEVICE_STATUS (2) - -/* - Declare the different event group classifications - The SimpleLink device send asynchronous events. Each event has a group - classification according to its nature. -*/ -/* SL_EVENT_CLASS_WLAN connection user events */ -#define SL_WLAN_CONNECT_EVENT (1) -#define SL_WLAN_DISCONNECT_EVENT (2) -/* WLAN Smart Config user events */ -#define SL_WLAN_SMART_CONFIG_COMPLETE_EVENT (3) -#define SL_WLAN_SMART_CONFIG_STOP_EVENT (4) -/* WLAN AP user events */ -#define SL_WLAN_STA_CONNECTED_EVENT (5) -#define SL_WLAN_STA_DISCONNECTED_EVENT (6) -/* WLAN P2P user events */ -#define SL_WLAN_P2P_DEV_FOUND_EVENT (7) -#define SL_WLAN_P2P_NEG_REQ_RECEIVED_EVENT (8) -#define SL_WLAN_CONNECTION_FAILED_EVENT (9) -/* SL_EVENT_CLASS_DEVICE user events */ -#define SL_DEVICE_FATAL_ERROR_EVENT (1) -#define SL_DEVICE_ABORT_ERROR_EVENT (2) - -/* SL_EVENT_CLASS_BSD user events */ -#define SL_SOCKET_TX_FAILED_EVENT (1) -#define SL_SOCKET_ASYNC_EVENT (2) -/* SL_EVENT_CLASS_NETAPP user events */ -#define SL_NETAPP_IPV4_IPACQUIRED_EVENT (1) -#define SL_NETAPP_IPV6_IPACQUIRED_EVENT (2) -#define SL_NETAPP_IP_LEASED_EVENT (3) -#define SL_NETAPP_IP_RELEASED_EVENT (4) - -/* Server Events */ -#define SL_NETAPP_HTTPGETTOKENVALUE_EVENT (1) -#define SL_NETAPP_HTTPPOSTTOKENVALUE_EVENT (2) - - -/* - Declare the different event group classifications for sl_DevGet - for getting status indications - */ - -/* Events list to mask/unmask*/ -#define SL_EVENT_CLASS_GLOBAL (0) -#define SL_EVENT_CLASS_DEVICE (1) -#define SL_EVENT_CLASS_WLAN (2) -#define SL_EVENT_CLASS_BSD (3) -#define SL_EVENT_CLASS_NETAPP (4) -#define SL_EVENT_CLASS_NETCFG (5) -#define SL_EVENT_CLASS_FS (6) - - -/****************** DEVICE CLASS status ****************/ -#define EVENT_DROPPED_DEVICE_ASYNC_GENERAL_ERROR (0x00000001L) -#define STATUS_DEVICE_SMART_CONFIG_ACTIVE (0x80000000L) - -/****************** WLAN CLASS status ****************/ -#define EVENT_DROPPED_WLAN_WLANASYNCONNECTEDRESPONSE (0x00000001L) -#define EVENT_DROPPED_WLAN_WLANASYNCDISCONNECTEDRESPONSE (0x00000002L) -#define EVENT_DROPPED_WLAN_STA_CONNECTED (0x00000004L) -#define EVENT_DROPPED_WLAN_STA_DISCONNECTED (0x00000008L) -#define STATUS_WLAN_STA_CONNECTED (0x80000000L) - -/****************** NETAPP CLASS status ****************/ -#define EVENT_DROPPED_NETAPP_IPACQUIRED (0x00000001L) -#define EVENT_DROPPED_NETAPP_IPACQUIRED_V6 (0x00000002L) -#define EVENT_DROPPED_NETAPP_IP_LEASED (0x00000004L) -#define EVENT_DROPPED_NETAPP_IP_RELEASED (0x00000008L) - -/****************** BSD CLASS status ****************/ -#define EVENT_DROPPED_SOCKET_TXFAILEDASYNCRESPONSE (0x00000001L) - -/****************** FS CLASS ****************/ - - - -/*****************************************************************************/ -/* Structure/Enum declarations */ -/*****************************************************************************/ - -#define ROLE_UNKNOWN_ERR (-1) - -#ifdef SL_IF_TYPE_UART -typedef struct -{ - _u32 BaudRate; - _u8 FlowControlEnable; - _u8 CommPort; -} SlUartIfParams_t; -#endif - -typedef struct -{ - _u32 ChipId; - _u32 FwVersion[4]; - _u8 PhyVersion[4]; -}_SlPartialVersion; - -typedef struct -{ - _SlPartialVersion ChipFwAndPhyVersion; - _u32 NwpVersion[4]; - _u16 RomVersion; - _u16 Padding; -}SlVersionFull; - - -typedef struct -{ - _u32 AbortType; - _u32 AbortData; -}sl_DeviceReportAbort; - - -typedef struct -{ - _i8 status; - SlErrorSender_e sender; -}sl_DeviceReport; - -typedef union -{ - sl_DeviceReport deviceEvent; - sl_DeviceReportAbort deviceReport; -} _SlDeviceEventData_u; - -typedef struct -{ - _u32 Event; - _SlDeviceEventData_u EventData; -} SlDeviceEvent_t; - -typedef struct -{ - /* time */ - _u32 sl_tm_sec; - _u32 sl_tm_min; - _u32 sl_tm_hour; - /* date */ - _u32 sl_tm_day; /* 1-31 */ - _u32 sl_tm_mon; /* 1-12 */ - _u32 sl_tm_year; /* YYYY 4 digits */ - _u32 sl_tm_week_day; /* not required */ - _u32 sl_tm_year_day; /* not required */ - _u32 reserved[3]; -}SlDateTime_t; - - -/******************************************************************************/ -/* Type declarations */ -/******************************************************************************/ -typedef void (*P_INIT_CALLBACK)(_u32 Status); - -/*****************************************************************************/ -/* Function prototypes */ -/*****************************************************************************/ - -/*! - \brief Start the SimpleLink device - - This function initialize the communication interface, set the enable pin - of the device, and call to the init complete callback. - - \param[in] pIfHdl Opened Interface Object. In case the interface - must be opened outside the SimpleLink Driver, the - user might give the handler to be used in \n - any access of the communication interface with the - device (UART/SPI). \n - The SimpleLink driver will open an interface port - only if this parameter is null! \n - \param[in] pDevName The name of the device to open. Could be used when - the pIfHdl is null, to transfer information to the - open interface function \n - This pointer could be used to pass additional information to - sl_IfOpen in case it is required (e.g. UART com port name) - \param[in] pInitCallBack Pointer to function that would be called - on completion of the initialization process.\n - If this parameter is NULL the function is - blocked until the device initialization - is completed, otherwise the function returns - immediately. - - \return Returns the current active role (STA/AP/P2P) or an error code: - - ROLE_STA, ROLE_AP, ROLE_P2P in case of success, - otherwise in failure one of the following is return: - - ROLE_STA_ERR (Failure to load MAC/PHY in STA role) - - ROLE_AP_ERR (Failure to load MAC/PHY in AP role) - - ROLE_P2P_ERR (Failure to load MAC/PHY in P2P role) - - - \sa sl_Stop - - \note belongs to \ref basic_api - - \warning This function must be called before any other SimpleLink API is used, or after sl_Stop is called for reinit the device - \par Example: - \code - An example for open interface without callback routine. The interface name and handler are - handled by the sl_IfOpen routine: - - if( sl_Start(NULL, NULL, NULL) < 0 ) - { - LOG("Error opening interface to device\n"); - } - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_Start) -_i16 sl_Start(const void* pIfHdl, _i8* pDevName, const P_INIT_CALLBACK pInitCallBack); -#endif - -/*! - \brief Stop the SimpleLink device - - This function clears the enable pin of the device, closes the communication \n - interface and invokes the stop complete callback - - \param[in] timeout Stop timeout in msec. Should be used to give the device time to finish \n - any transmission/reception that is not completed when the function was called. \n - Additional options: - - 0 Enter to hibernate immediately \n - - 0xFFFF Host waits for device's response before \n - hibernating, without timeout protection \n - - 0 < Timeout[msec] < 0xFFFF Host waits for device's response before \n - hibernating, with a defined timeout protection \n - This timeout defines the max time to wait. The NWP \n - response can be sent earlier than this timeout. - - \return On success, zero is returned. On error, -1 is returned - - \sa sl_Start - - \note This API will shutdown the device and invoke the "i/f close" function regardless \n - if it was opened implicitly or explicitly. \n - It is up to the platform interface library to properly handle interface close \n - routine \n - belongs to \ref basic_api \n - \warning -*/ -#if _SL_INCLUDE_FUNC(sl_Stop) -_i16 sl_Stop(const _u16 timeout); -#endif - - -/*! - \brief Internal function for setting device configurations - - \return On success, zero is returned. On error, -1 is - returned - - \param[in] DeviceSetId configuration id - \param[in] Option configurations option - \param[in] ConfigLen configurations len - \param[in] pValues configurations values - - \sa - \note - \warning - \par Examples: - \code - Setting device time and date example: - - SlDateTime_t dateTime= {0}; - dateTime.sl_tm_day = (_u32)23; // Day of month (DD format) range 1-31 - dateTime.sl_tm_mon = (_u32)6; // Month (MM format) in the range of 1-12 - dateTime.sl_tm_year = (_u32)2014; // Year (YYYY format) - dateTime.sl_tm_hour = (_u32)17; // Hours in the range of 0-23 - dateTime.sl_tm_min = (_u32)55; // Minutes in the range of 0-59 - dateTime.sl_tm_sec = (_u32)22; // Seconds in the range of 0-59 - sl_DevSet(SL_DEVICE_GENERAL_CONFIGURATION, - SL_DEVICE_GENERAL_CONFIGURATION_DATE_TIME, - sizeof(SlDateTime_t), - (_u8 *)(&dateTime)); - - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_DevSet) -_i32 sl_DevSet(const _u8 DeviceSetId ,const _u8 Option,const _u8 ConfigLen,const _u8 *pValues); -#endif - -/*! - \brief Internal function for getting device configurations - \return On success, zero is returned. On error, -1 is - returned - \param[in] DeviceGetId configuration id - example SL_DEVICE_STATUS - \param[out] pOption Get configurations option, example for get status options - - SL_EVENT_CLASS_GLOBAL - - SL_EVENT_CLASS_DEVICE - - SL_EVENT_CLASS_WLAN - - SL_EVENT_CLASS_BSD - - SL_EVENT_CLASS_NETAPP - - SL_EVENT_CLASS_NETCFG - - SL_EVENT_CLASS_FS - \param[out] pConfigLen The length of the allocated memory as input, when the - function complete, the value of this parameter would be - the len that actually read from the device.\n - If the device return length that is longer from the input - value, the function will cut the end of the returned structure - and will return SL_ESMALLBUF - \param[out] pValues Get configurations values - \sa - \note - \warning - \par Examples: - \code - Example for getting WLAN class status: - _u32 statusWlan; - _u8 pConfigOpt; - _u8 pConfigLen; - pConfigOpt = SL_EVENT_CLASS_WLAN; - pConfigLen = sizeof(_u32); - sl_DevGet(SL_DEVICE_STATUS,&pConfigOpt,&pConfigLen,(_u8 *)(&statusWlan)); - Example for getting version: - SlVersionFull ver; - pConfigLen = sizeof(ver); - pConfigOpt = SL_DEVICE_GENERAL_VERSION; - sl_DevGet(SL_DEVICE_GENERAL_CONFIGURATION,&pConfigOpt,&pConfigLen,(_u8 *)(&ver)); - printf("CHIP %d\nMAC 31.%d.%d.%d.%d\nPHY %d.%d.%d.%d\nNWP %d.%d.%d.%d\nROM %d\nHOST %d.%d.%d.%d\n", - ver.ChipFwAndPhyVersion.ChipId, - ver.ChipFwAndPhyVersion.FwVersion[0],ver.ChipFwAndPhyVersion.FwVersion[1], - ver.ChipFwAndPhyVersion.FwVersion[2],ver.ChipFwAndPhyVersion.FwVersion[3], - ver.ChipFwAndPhyVersion.PhyVersion[0],ver.ChipFwAndPhyVersion.PhyVersion[1], - ver.ChipFwAndPhyVersion.PhyVersion[2],ver.ChipFwAndPhyVersion.PhyVersion[3], - ver.NwpVersion[0],ver.NwpVersion[1],ver.NwpVersion[2],ver.NwpVersion[3], - ver.RomVersion, - SL_MAJOR_VERSION_NUM,SL_MINOR_VERSION_NUM,SL_VERSION_NUM,SL_SUB_VERSION_NUM); - - \endcode - \code - Getting Device time and date example: - - SlDateTime_t dateTime = {0}; - _i8 configLen = sizeof(SlDateTime_t); - _i8 configOpt = SL_DEVICE_GENERAL_CONFIGURATION_DATE_TIME; - sl_DevGet(SL_DEVICE_GENERAL_CONFIGURATION,&configOpt, &configLen,(_u8 *)(&dateTime)); - - printf("Day %d,Mon %d,Year %d,Hour %,Min %d,Sec %d\n",dateTime.sl_tm_day,dateTime.sl_tm_mon,dateTime.sl_tm_year - dateTime.sl_tm_hour,dateTime.sl_tm_min,dateTime.sl_tm_sec); - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_DevGet) -_i32 sl_DevGet(const _u8 DeviceGetId,_u8 *pOption,_u8 *pConfigLen, _u8 *pValues); -#endif - - -/*! - \brief Set asynchronous event mask - - Mask asynchronous events from the device. Masked events do not - generate asynchronous messages from the device. - By default - all events are active - - \param[in] EventClass The classification groups that the - mask is referred to. Need to be one of - the following: - - SL_EVENT_CLASS_GLOBAL - - SL_EVENT_CLASS_DEVICE - - SL_EVENT_CLASS_WLAN - - SL_EVENT_CLASS_BSD - - SL_EVENT_CLASS_NETAPP - - SL_EVENT_CLASS_NETCFG - - SL_EVENT_CLASS_FS - - - \param[in] Mask Event Mask bitmap. Valid mask are (per group): - - SL_EVENT_CLASS_WLAN user events - - SL_WLAN_CONNECT_EVENT - - SL_WLAN_DISCONNECT_EVENT - - SL_EVENT_CLASS_DEVICE user events - - SL_DEVICE_FATAL_ERROR_EVENT - - SL_EVENT_CLASS_BSD user events - - SL_SOCKET_TX_FAILED_EVENT - - SL_SOCKET_ASYNC_EVENT - - SL_EVENT_CLASS_NETAPP user events - - SL_NETAPP_IPV4_IPACQUIRED_EVENT - - SL_NETAPP_IPV6_IPACQUIRED_EVENT - - \return On success, zero is returned. On error, -1 is returned - - \sa sl_EventMaskGet - - \note belongs to \ref ext_api - - \warning - \par Example: - \code - - An example of masking connection/disconnection async events from WLAN class: - sl_EventMaskSet(SL_EVENT_CLASS_WLAN, (SL_WLAN_CONNECT_EVENT | SL_WLAN_DISCONNECT_EVENT) ); - - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_EventMaskSet) -_i16 sl_EventMaskSet(const _u8 EventClass ,const _u32 Mask); -#endif - -/*! - \brief Get current event mask of the device - - return the events bit mask from the device. In case that event is - masked, the device is not sending this event. - - \param[in] EventClass The classification groups that the - mask is referred to. Need to be one of - the following: - - SL_EVENT_CLASS_GLOBAL - - SL_EVENT_CLASS_DEVICE - - SL_EVENT_CLASS_WLAN - - SL_EVENT_CLASS_BSD - - SL_EVENT_CLASS_NETAPP - - SL_EVENT_CLASS_NETCFG - - SL_EVENT_CLASS_FS - - \param[out] pMask Pointer to Mask bitmap where the - value should be stored. Bitmasks are the same as in \ref sl_EventMaskSet - - \return On success, zero is returned. On error, -1 is returned - - \sa sl_EventMaskSet - - \note belongs to \ref ext_api - - \warning - \par Example: - \code - - An example of getting an event mask for WLAN class - _u32 maskWlan; - sl_StatusGet(SL_EVENT_CLASS_WLAN,&maskWlan); - - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_EventMaskGet) -_i16 sl_EventMaskGet(const _u8 EventClass,_u32 *pMask); -#endif - - -/*! - \brief the simple link task entry - - \Param - This function must be called from the main loop or from dedicated thread in - the following cases: - - Non-Os Platform - should be called from the mail loop - - Multi Threaded Platform when the user does not implement the external spawn functions - - should be called from dedicated thread allocated to the simplelink driver. - In this mode the function never return. - - \return None - - \sa sl_Stop - - \note belongs to \ref basic_api - - \warning This function must be called from a thread that is start running before - any call to other simple link API -*/ -#if _SL_INCLUDE_FUNC(sl_Task) -void sl_Task(void); -#endif - - -/*! - \brief Setting the internal uart mode - - \param[in] pUartParams Pointer to the uart configuration parameter set: - baudrate - up to 711 Kbps - flow control - enable/disable - comm port - the comm port number - - \return On success zero is returned, otherwise - Failed. - - \sa sl_Stop - - \note belongs to \ref basic_api - - \warning This function must consider the host uart capability -*/ -#ifdef SL_IF_TYPE_UART -#if _SL_INCLUDE_FUNC(sl_UartSetMode) -_i16 sl_UartSetMode(const SlUartIfParams_t* pUartParams); -#endif -#endif - -/*! - - Close the Doxygen group. - @} - - */ - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __DEVICE_H__ */ - - diff --git a/drivers/cc3100/inc/driver.h b/drivers/cc3100/inc/driver.h deleted file mode 100644 index 4ef484dfb5d..00000000000 --- a/drivers/cc3100/inc/driver.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - * driver.h - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - -#ifndef __DRIVER_INT_H__ -#define __DRIVER_INT_H__ - - -/*****************************************************************************/ -/* Macro declarations */ -/*****************************************************************************/ - -#ifndef CPU_FREQ_IN_MHZ - #define CPU_FREQ_IN_MHZ (200) -#endif -#define USEC_DELAY (50) - -/*****************************************************************************/ -/* Structure/Enum declarations */ -/*****************************************************************************/ - -typedef struct -{ - _SlOpcode_t Opcode; - _SlArgSize_t TxDescLen; - _SlArgSize_t RxDescLen; -}_SlCmdCtrl_t; - -typedef struct -{ - _u16 TxPayloadLen; - _i16 RxPayloadLen; - _i16 ActualRxPayloadLen; - _u8 *pTxPayload; - _u8 *pRxPayload; -}_SlCmdExt_t; - - -typedef struct _SlArgsData_t -{ - _u8 *pArgs; - _u8 *pData; -} _SlArgsData_t; - - -typedef struct _SlPoolObj_t -{ - _SlSyncObj_t SyncObj; - _u8 *pRespArgs; - _u8 ActionID; - _u8 AdditionalData; /* use for socketID and one bit which indicate supprt IPV6 or not (1=support, 0 otherwise) */ - _u8 NextIndex; - -} _SlPoolObj_t; - - -typedef enum -{ - SOCKET_0, - SOCKET_1, - SOCKET_2, - SOCKET_3, - SOCKET_4, - SOCKET_5, - SOCKET_6, - SOCKET_7, - MAX_SOCKET_ENUM_IDX, -#ifndef SL_TINY_EXT - ACCEPT_ID = MAX_SOCKET_ENUM_IDX, - CONNECT_ID, -#else - CONNECT_ID = MAX_SOCKET_ENUM_IDX, -#endif -#ifndef SL_TINY_EXT - SELECT_ID, -#endif - GETHOSYBYNAME_ID, -#ifndef SL_TINY_EXT - GETHOSYBYSERVICE_ID, - PING_ID, -#endif - START_STOP_ID, - RECV_ID -}_SlActionID_e; - -typedef struct _SlActionLookup_t -{ - _u8 ActionID; - _u16 ActionAsyncOpcode; - _SlSpawnEntryFunc_t AsyncEventHandler; - -} _SlActionLookup_t; - - -typedef struct -{ - _u8 TxPoolCnt; - _SlLockObj_t TxLockObj; - _SlSyncObj_t TxSyncObj; -}_SlFlowContCB_t; - -typedef enum -{ - RECV_RESP_CLASS, - CMD_RESP_CLASS, - ASYNC_EVT_CLASS, - DUMMY_MSG_CLASS -}_SlRxMsgClass_e; - -typedef struct -{ - _u8 *pAsyncBuf; /* place to write pointer to buffer with CmdResp's Header + Arguments */ - _u8 ActionIndex; - _SlSpawnEntryFunc_t AsyncEvtHandler; /* place to write pointer to AsyncEvent handler (calc-ed by Opcode) */ - _SlRxMsgClass_e RxMsgClass; /* type of Rx message */ -} AsyncExt_t; - -typedef _u8 _SlSd_t; - -typedef struct -{ - _SlCmdCtrl_t *pCmdCtrl; - _u8 *pTxRxDescBuff; - _SlCmdExt_t *pCmdExt; - AsyncExt_t AsyncExt; -}_SlFunctionParams_t; - - -typedef struct -{ - _SlFd_t FD; - _SlLockObj_t GlobalLockObj; - _SlCommandHeader_t TempProtocolHeader; - P_INIT_CALLBACK pInitCallback; - - _SlPoolObj_t ObjPool[MAX_CONCURRENT_ACTIONS]; - _u8 FreePoolIdx; - _u8 PendingPoolIdx; - _u8 ActivePoolIdx; - _u32 ActiveActionsBitmap; - _SlLockObj_t ProtectionLockObj; - - _SlSyncObj_t CmdSyncObj; - _u8 IsCmdRespWaited; - _SlFlowContCB_t FlowContCB; - _u8 TxSeqNum; - _u8 RxDoneCnt; - _u8 SocketNonBlocking; - _u8 SocketTXFailure; - /* for stack reduction the parameters are globals */ - _SlFunctionParams_t FunctionParams; - - _u8 ActionIndex; -}_SlDriverCb_t; - -extern _volatile _u8 RxIrqCnt; - -extern _SlDriverCb_t* g_pCB; -extern P_SL_DEV_PING_CALLBACK pPingCallBackFunc; - -/*****************************************************************************/ -/* Function prototypes */ -/*****************************************************************************/ -extern void _SlDrvDriverCBInit(void); -extern void _SlDrvDriverCBDeinit(void); -extern void _SlDrvRxIrqHandler(void *pValue); -extern _SlReturnVal_t _SlDrvCmdOp(_SlCmdCtrl_t *pCmdCtrl , void* pTxRxDescBuff , _SlCmdExt_t* pCmdExt); -extern _SlReturnVal_t _SlDrvCmdSend(_SlCmdCtrl_t *pCmdCtrl , void* pTxRxDescBuff , _SlCmdExt_t* pCmdExt); -extern _SlReturnVal_t _SlDrvDataReadOp(_SlSd_t Sd, _SlCmdCtrl_t *pCmdCtrl , void* pTxRxDescBuff , _SlCmdExt_t* pCmdExt); -extern _SlReturnVal_t _SlDrvDataWriteOp(_SlSd_t Sd, _SlCmdCtrl_t *pCmdCtrl , void* pTxRxDescBuff , _SlCmdExt_t* pCmdExt); -extern void _sl_HandleAsync_InitComplete(void *pVoidBuf); -extern void _sl_HandleAsync_Connect(void *pVoidBuf); - - -#ifndef SL_TINY_EXT -extern _i16 _SlDrvBasicCmd(_SlOpcode_t Opcode); -extern void _sl_HandleAsync_Accept(void *pVoidBuf); -extern void _sl_HandleAsync_DnsGetHostByService(void *pVoidBuf); -extern void _sl_HandleAsync_Select(void *pVoidBuf); -#endif - - -extern void _sl_HandleAsync_DnsGetHostByName(void *pVoidBuf); -extern void _sl_HandleAsync_DnsGetHostByAddr(void *pVoidBuf); -extern void _sl_HandleAsync_PingResponse(void *pVoidBuf); -extern void _SlDrvNetAppEventHandler(void* pArgs); -extern void _SlDrvDeviceEventHandler(void* pArgs); -extern void _sl_HandleAsync_Stop(void *pVoidBuf); -extern _u8 _SlDrvWaitForPoolObj(_u8 ActionID, _u8 SocketID); -extern void _SlDrvReleasePoolObj(_u8 pObj); -extern _u16 _SlDrvAlignSize(_u16 msgLen); -extern _u8 _SlDrvProtectAsyncRespSetting(_u8 *pAsyncRsp, _u8 ActionID, _u8 SocketID); - - -extern void _SlDrvSyncObjWaitForever(_SlSyncObj_t *pSyncObj); -extern void _SlDrvSyncObjSignal(_SlSyncObj_t *pSyncObj); -extern void _SlDrvObjLock(_SlLockObj_t *pLockObj, _SlTime_t Timeout); -extern void _SlDrvObjLockWaitForever(_SlLockObj_t *pLockObj); -extern void _SlDrvProtectionObjLockWaitForever(); -extern void _SlDrvObjUnLock(_SlLockObj_t *pLockObj); -extern void _SlDrvProtectionObjUnLock(); - -extern void _SlDrvMemZero(void* Addr, _u16 size); -extern void _SlDrvResetCmdExt(_SlCmdExt_t* pCmdExt); - - - -#define _SL_PROTOCOL_ALIGN_SIZE(msgLen) (((msgLen)+3) & (~3)) -#define _SL_IS_PROTOCOL_ALIGNED_SIZE(msgLen) (!((msgLen) & 3)) - - -#define _SL_PROTOCOL_CALC_LEN(pCmdCtrl,pCmdExt) ((pCmdExt) ? \ - (_SL_PROTOCOL_ALIGN_SIZE(pCmdCtrl->TxDescLen) + _SL_PROTOCOL_ALIGN_SIZE(pCmdExt->TxPayloadLen)) : \ - (_SL_PROTOCOL_ALIGN_SIZE(pCmdCtrl->TxDescLen))) -#endif /* __DRIVER_INT_H__ */ diff --git a/drivers/cc3100/inc/flowcont.h b/drivers/cc3100/inc/flowcont.h deleted file mode 100644 index 3dcc130d837..00000000000 --- a/drivers/cc3100/inc/flowcont.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * flowcont.h - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - -#ifndef __FLOWCONT_H__ -#define __FLOWCONT_H__ - - -#ifdef __cplusplus -extern "C" { -#endif - -/*****************************************************************************/ -/* Macro declarations */ -/*****************************************************************************/ -#define FLOW_CONT_MIN 1 - -/*****************************************************************************/ -/* Function prototypes */ -/*****************************************************************************/ -extern void _SlDrvFlowContInit(void); -extern void _SlDrvFlowContDeinit(void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __FLOWCONT_H__ */ - diff --git a/drivers/cc3100/inc/fs.h b/drivers/cc3100/inc/fs.h deleted file mode 100644 index 078feafff6c..00000000000 --- a/drivers/cc3100/inc/fs.h +++ /dev/null @@ -1,382 +0,0 @@ -/* - * fs.h - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ - -#include "simplelink.h" - -#ifndef __FS_H__ -#define __FS_H__ - - - -#ifdef __cplusplus -extern "C" { -#endif - -/*! - - \addtogroup FileSystem - @{ - -*/ - -/*****************************************************************************/ -/* Macro declarations */ -/*****************************************************************************/ - -/* FS error codes */ -#define SL_FS_OK (0) -#define SL_FS_ERR_EMPTY_SFLASH (-67) -#define SL_FS_ERR_FILE_IS_NOT_SECURE_AND_SIGN (-66) -#define SL_FS_ERASING_FLASH (-65) -#define SL_FS_FILE_HAS_NOT_BEEN_CLOSE_CORRECTLY (-64) -#define SL_FS_WRONG_SIGNATURE (-63) -#define SL_FS_WRONG_SIGNATURE_OR_CERTIFIC_NAME_LENGTH (-62) -#define SL_FS_NOT_16_ALIGNED (-61) -#define SL_FS_CERT_CHAIN_ERROR (-60) -#define SL_FS_FILE_NAME_EXIST (-59) -#define SL_FS_SECURITY_BUF_ALREADY_ALLOC (-58) -#define SL_FS_SECURE_FILE_MUST_BE_COMMIT (-57) -#define SL_FS_ERR_INCORRECT_OFFSET_ALIGNMENT (-56) -#define SL_FS_ERR_FAILED_READ_NVMEM_HEADER (-55) -#define SL_FS_WRONG_FILE_NAME (-54) -#define SL_FS_FILE_SYSTEM_IS_LOCKED (-53) -#define SL_FS_SECURITY_ALLERT (-52) -#define SL_FS_FILE_UNVALID_FILE_SIZE (-51) -#define SL_FS_ERR_TOKEN_IS_NOT_VALID (-50) -#define SL_FS_NO_DEVICE_IS_LOADED (-49) -#define SL_FS_DATA_ADDRESS_SHOUD_BE_IN_DATA_RAM (-48) -#define SL_FS_DATA_IS_NOT_ALIGNED (-47) -#define SL_FS_ERR_OVERLAP_DETECTION_THRESHHOLD (-46) -#define SL_FS_FILE_HAS_RESERVED_NV_INDEX (-45) -#define SL_FS_ERR_MAX_FS_FILES_IS_LARGER (-44) -#define SL_FS_ERR_MAX_FS_FILES_IS_SMALLER (-43) -#define SL_FS_FILE_MAX_SIZE_EXCEEDED (-42) -#define SL_FS_INVALID_BUFFER_FOR_READ (-41) -#define SL_FS_INVALID_BUFFER_FOR_WRITE (-40) -#define SL_FS_ERR_FILE_IMAGE_IS_CORRUPTED (-39) -#define SL_FS_ERR_SIZE_OF_FILE_EXT_EXCEEDED (-38) -#define SL_FS_WARNING_FILE_NAME_NOT_KEPT (-37) -#define SL_FS_ERR_DEVICE_IS_NOT_FORMATTED (-36) -#define SL_FS_ERR_FAILED_WRITE_NVMEM_HEADER (-35) -#define SL_FS_ERR_NO_AVAILABLE_NV_INDEX (-34) -#define SL_FS_ERR_FAILED_TO_ALLOCATE_MEM (-33) -#define SL_FS_ERR_FAILED_TO_READ_INTEGRITY_HEADER_2 (-32) -#define SL_FS_ERR_FAILED_TO_READ_INTEGRITY_HEADER_1 (-31) -#define SL_FS_ERR_NO_AVAILABLE_BLOCKS (-30) -#define SL_FS_ERR_FILE_MAX_SIZE_BIGGER_THAN_EXISTING_FILE (-29) -#define SL_FS_ERR_FILE_EXISTS_ON_DIFFERENT_DEVICE_ID (-28) -#define SL_FS_ERR_INVALID_ACCESS_TYPE (-27) -#define SL_FS_ERR_FILE_ALREADY_EXISTS (-26) -#define SL_FS_ERR_PROGRAM (-25) -#define SL_FS_ERR_NO_ENTRIES_AVAILABLE (-24) -#define SL_FS_ERR_FILE_ACCESS_IS_DIFFERENT (-23) -#define SL_FS_ERR_BAD_FILE_MODE (-22) -#define SL_FS_ERR_FAILED_READ_NVFILE (-21) -#define SL_FS_ERR_FAILED_INIT_STORAGE (-20) -#define SL_FS_ERR_CONTINUE_WRITE_MUST_BE_MOD_4 (-19) -#define SL_FS_ERR_FAILED_LOAD_FILE (-18) -#define SL_FS_ERR_INVALID_HANDLE (-17) -#define SL_FS_ERR_FAILED_TO_WRITE (-16) -#define SL_FS_ERR_OFFSET_OUT_OF_RANGE (-15) -#define SL_FS_ERR_ALLOC (-14) -#define SL_FS_ERR_READ_DATA_LENGTH (-13) -#define SL_FS_ERR_INVALID_FILE_ID (-12) -#define SL_FS_ERR_FILE_NOT_EXISTS (-11) -#define SL_FS_ERR_EMPTY_ERROR (-10) -#define SL_FS_ERR_INVALID_ARGS (-9) -#define SL_FS_ERR_FAILED_TO_CREATE_FILE (-8) -#define SL_FS_ERR_FS_ALREADY_LOADED (-7) -#define SL_FS_ERR_UNKNOWN (-6) -#define SL_FS_ERR_FAILED_TO_CREATE_LOCK_OBJ (-5) -#define SL_FS_ERR_DEVICE_NOT_LOADED (-4) -#define SL_FS_ERR_INVALID_MAGIC_NUM (-3) -#define SL_FS_ERR_FAILED_TO_READ (-2) -#define SL_FS_ERR_NOT_SUPPORTED (-1) -/* end of error codes */ - -#define _FS_MODE_ACCESS_RESERVED_OFFSET (24) -#define _FS_MODE_ACCESS_RESERVED_MASK (0xFF) -#define _FS_MODE_ACCESS_FLAGS_OFFSET (16) -#define _FS_MODE_ACCESS_FLAGS_MASK (0xFF) -#define _FS_MODE_ACCESS_OFFSET (12) -#define _FS_MODE_ACCESS_MASK (0xF) -#define _FS_MODE_OPEN_SIZE_GRAN_OFFSET (8) -#define _FS_MODE_OPEN_SIZE_GRAN_MASK (0xF) -#define _FS_MODE_OPEN_SIZE_OFFSET (0) -#define _FS_MODE_OPEN_SIZE_MASK (0xFF) -#define MAX_MODE_SIZE (0xFF) -#define _FS_MODE(Access, SizeGran, Size,Flags) (_u32)(((_u32)((Access) & _FS_MODE_ACCESS_MASK)<<_FS_MODE_ACCESS_OFFSET) | \ - ((_u32)((SizeGran) & _FS_MODE_OPEN_SIZE_GRAN_MASK)<<_FS_MODE_OPEN_SIZE_GRAN_OFFSET) | \ - ((_u32)((Size) & _FS_MODE_OPEN_SIZE_MASK)<<_FS_MODE_OPEN_SIZE_OFFSET) | \ - ((_u32)((Flags) & _FS_MODE_ACCESS_FLAGS_MASK)<<_FS_MODE_ACCESS_FLAGS_OFFSET)) - - -/* sl_FsOpen options */ -/* Open for Read */ -#define FS_MODE_OPEN_READ _FS_MODE(_FS_MODE_OPEN_READ,0,0,0) -/* Open for Write (in case file exist) */ -#define FS_MODE_OPEN_WRITE _FS_MODE(_FS_MODE_OPEN_WRITE,0,0,0) -/* Open for Creating a new file */ -#define FS_MODE_OPEN_CREATE(maxSizeInBytes,accessModeFlags) _sl_GetCreateFsMode(maxSizeInBytes,accessModeFlags) - -/*****************************************************************************/ -/* Structure/Enum declarations */ -/*****************************************************************************/ -typedef struct -{ - _u16 flags; - _u32 FileLen; - _u32 AllocatedLen; - _u32 Token[4]; -}SlFsFileInfo_t; - -typedef enum -{ - _FS_MODE_OPEN_READ = 0, - _FS_MODE_OPEN_WRITE, - _FS_MODE_OPEN_CREATE, - _FS_MODE_OPEN_WRITE_CREATE_IF_NOT_EXIST -}SlFsFileOpenAccessType_e; - -typedef enum -{ - _FS_FILE_OPEN_FLAG_COMMIT = 0x1, /* MIRROR - for fail safe */ - _FS_FILE_OPEN_FLAG_SECURE = 0x2, /* SECURE */ - _FS_FILE_OPEN_FLAG_NO_SIGNATURE_TEST = 0x4, /* Relevant to secure file only */ - _FS_FILE_OPEN_FLAG_STATIC = 0x8, /* Relevant to secure file only */ - _FS_FILE_OPEN_FLAG_VENDOR = 0x10, /* Relevant to secure file only */ - _FS_FILE_PUBLIC_WRITE= 0x20, /* Relevant to secure file only, the file can be opened for write without Token */ - _FS_FILE_PUBLIC_READ = 0x40 /* Relevant to secure file only, the file can be opened for read without Token */ -}SlFileOpenFlags_e; - -typedef enum -{ - _FS_MODE_SIZE_GRAN_256B = 0, /* MAX_SIZE = 64K */ - _FS_MODE_SIZE_GRAN_1KB, /* MAX_SIZE = 256K */ - _FS_MODE_SIZE_GRAN_4KB, /* MAX_SZIE = 1M */ - _FS_MODE_SIZE_GRAN_16KB, /* MAX_SIZE = 4M */ - _FS_MODE_SIZE_GRAN_64KB, /* MAX_SIZE = 16M */ - _FS_MAX_MODE_SIZE_GRAN -}_SlFsFileOpenMaxSizeGran_e; - -/*****************************************************************************/ -/* Internal Function prototypes */ -/*****************************************************************************/ -_u32 _sl_GetCreateFsMode(_u32 maxSizeInBytes,_u32 accessFlags); - -/*****************************************************************************/ -/* Function prototypes */ -/*****************************************************************************/ - -/*! - \brief open file for read or write from/to storage device - - \param[in] pFileName File Name buffer pointer - \param[in] AccessModeAndMaxSize Options: As described below - \param[in] pToken Reserved for future use. Use NULL for this field - \param[out] pFileHandle Pointing on the file and used for read and write commands to the file - - AccessModeAndMaxSize possible input \n - FS_MODE_OPEN_READ - Read a file \n - FS_MODE_OPEN_WRITE - Open for write for an existing file \n - FS_MODE_OPEN_CREATE(maxSizeInBytes,accessModeFlags) - Open for creating a new file. Max file size is defined in bytes. \n - For optimal FS size, use max size in 4K-512 bytes steps (e.g. 3584,7680,117760) \n - Several access modes bits can be combined together from SlFileOpenFlags_e enum - - \return On success, zero is returned. On error, an error code is returned - - \sa sl_FsRead sl_FsWrite sl_FsClose - \note belongs to \ref basic_api - \warning - \par Example: - \code - char* DeviceFileName = "MyFile.txt"; - unsigned long MaxSize = 63 * 1024; //62.5K is max file size - long DeviceFileHandle = -1; - long RetVal; //negative retval is an error - unsigned long Offset = 0; - unsigned char InputBuffer[100]; - - // Create a file and write data. The file in this example is secured, without signature and with a fail safe commit - RetVal = sl_FsOpen((unsigned char *)DeviceFileName, - FS_MODE_OPEN_CREATE(MaxSize , _FS_FILE_OPEN_FLAG_NO_SIGNATURE_TEST | _FS_FILE_OPEN_FLAG_COMMIT ), - NULL, &DeviceFileHandle); - - Offset = 0; - //Preferred in secure file that the Offset and the length will be aligned to 16 bytes. - RetVal = sl_FsWrite( DeviceFileHandle, Offset, (unsigned char *)"HelloWorld", strlen("HelloWorld")); - - RetVal = sl_FsClose(DeviceFileHandle, NULL, NULL , 0); - - // open the same file for read, using the Token we got from the creation procedure above - RetVal = sl_FsOpen((unsigned char *)DeviceFileName, - FS_MODE_OPEN_READ, - NULL, &DeviceFileHandle); - - Offset = 0; - RetVal = sl_FsRead( DeviceFileHandle, Offset, (unsigned char *)InputBuffer, strlen("HelloWorld")); - - RetVal = sl_FsClose(DeviceFileHandle, NULL, NULL , 0); - - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_FsOpen) -_i32 sl_FsOpen(const _u8 *pFileName,const _u32 AccessModeAndMaxSize,_u32 *pToken,_i32 *pFileHandle); -#endif - -/*! - \brief close file in storage device - - \param[in] FileHdl Pointer to the file (assigned from sl_FsOpen) - \param[in] pCeritificateFileName Reserved for future use. Use NULL. - \param[in] pSignature Reserved for future use. Use NULL. - \param[in] SignatureLen Reserved for future use. Use 0. - - - \return On success, zero is returned. On error, an error code is returned - - \sa sl_FsRead sl_FsWrite sl_FsOpen - \note Call the fs_Close with signature = 'A' signature len = 1 for activating an abort action - \warning - \par Example: - \code - sl_FsClose(FileHandle,0,0,0); - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_FsClose) -_i16 sl_FsClose(const _i32 FileHdl,const _u8* pCeritificateFileName,const _u8* pSignature,const _u32 SignatureLen); -#endif - -/*! - \brief Read block of data from a file in storage device - - \param[in] FileHdl Pointer to the file (assigned from sl_FsOpen) - \param[in] Offset Offset to specific read block - \param[out] pData Pointer for the received data - \param[in] Len Length of the received data - - \return On success, returns the number of read bytes. On error, negative number is returned - - \sa sl_FsClose sl_FsWrite sl_FsOpen - \note belongs to \ref basic_api - \warning - \par Example: - \code - Status = sl_FsRead(FileHandle, 0, &readBuff[0], readSize); - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_FsRead) -_i32 sl_FsRead(const _i32 FileHdl,_u32 Offset ,_u8* pData,_u32 Len); -#endif - -/*! - \brief write block of data to a file in storage device - - \param[in] FileHdl Pointer to the file (assigned from sl_FsOpen) - \param[in] Offset Offset to specific block to be written - \param[in] pData Pointer the transmitted data to the storage device - \param[in] Len Length of the transmitted data - - \return On success, returns the number of written bytes. On error, an error code is returned - - \sa - \note belongs to \ref basic_api - \warning - \par Example: - \code - Status = sl_FsWrite(FileHandle, 0, &buff[0], readSize); - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_FsWrite) -_i32 sl_FsWrite(const _i32 FileHdl,_u32 Offset,_u8* pData,_u32 Len); -#endif - -/*! - \brief get info on a file - - \param[in] pFileName File name - \param[in] Token Reserved for future use. Use 0 - \param[out] pFsFileInfo Returns the File's Information: flags,file size, allocated size and Tokens - - \return On success, zero is returned. On error, an error code is returned - - \sa sl_FsOpen - \note belongs to \ref basic_api - \warning - \par Example: - \code - Status = sl_FsGetInfo("FileName.html",0,&FsFileInfo); - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_FsGetInfo) -_i16 sl_FsGetInfo(const _u8 *pFileName,const _u32 Token,SlFsFileInfo_t* pFsFileInfo); -#endif - -/*! - \brief Delete specific file from a storage or all files from a storage (format) - - \param[in] pFileName File Name - \param[in] Token Reserved for future use. Use 0 - \return On success, zero is returned. On error, an error code is returned - - \sa - \note belongs to \ref basic_api - \warning - \par Example: - \code - Status = sl_FsDel("FileName.html",0); - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_FsDel) -_i16 sl_FsDel(const _u8 *pFileName,const _u32 Token); -#endif -/*! - - Close the Doxygen group. - @} - - */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __FS_H__ */ - diff --git a/drivers/cc3100/inc/netapp.h b/drivers/cc3100/inc/netapp.h deleted file mode 100644 index a968e7d0ba5..00000000000 --- a/drivers/cc3100/inc/netapp.h +++ /dev/null @@ -1,884 +0,0 @@ -/* - * netapp.h - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ - -#include "simplelink.h" - -#ifndef __NETAPP_H__ -#define __NETAPP_H__ - - - - -#ifdef __cplusplus -extern "C" { -#endif - -/*! - - \addtogroup netapp - @{ - -*/ - -/*****************************************************************************/ -/* Macro declarations */ -/*****************************************************************************/ - -/*ERROR code*/ -#define SL_ERROR_NETAPP_RX_BUFFER_LENGTH_ERROR (-230) - -/* Http Server interface */ -#define MAX_INPUT_STRING (64) /* because of WPA */ - -#define MAX_AUTH_NAME_LEN (20) -#define MAX_AUTH_PASSWORD_LEN (20) -#define MAX_AUTH_REALM_LEN (20) - -#define MAX_DEVICE_URN_LEN (15+1) -#define MAX_DOMAIN_NAME_LEN (24+1) - -#define MAX_ACTION_LEN (30) -/* Important: in case the max len is changed, make sure the struct sl_NetAppHttpServerSendToken_t in protocol.h is padded correctly! */ -#define MAX_TOKEN_NAME_LEN (20) -#define MAX_TOKEN_VALUE_LEN MAX_INPUT_STRING - -#define NETAPP_MAX_SERVICE_TEXT_SIZE (256) -#define NETAPP_MAX_SERVICE_NAME_SIZE (60) -#define NETAPP_MAX_SERVICE_HOST_NAME_SIZE (64) - - -/* Server Responses */ -#define SL_NETAPP_RESPONSE_NONE (0) -#define SL_NETAPP_HTTPSETTOKENVALUE (1) - -#define SL_NETAPP_FAMILY_MASK (0x80) - -/* mDNS types */ -#define SL_NET_APP_MASK_IPP_TYPE_OF_SERVICE (0x00000001) -#define SL_NET_APP_MASK_DEVICE_INFO_TYPE_OF_SERVICE (0x00000002) -#define SL_NET_APP_MASK_HTTP_TYPE_OF_SERVICE (0x00000004) -#define SL_NET_APP_MASK_HTTPS_TYPE_OF_SERVICE (0x00000008) -#define SL_NET_APP_MASK_WORKSATION_TYPE_OF_SERVICE (0x00000010) -#define SL_NET_APP_MASK_GUID_TYPE_OF_SERVICE (0x00000020) -#define SL_NET_APP_MASK_H323_TYPE_OF_SERVICE (0x00000040) -#define SL_NET_APP_MASK_NTP_TYPE_OF_SERVICE (0x00000080) -#define SL_NET_APP_MASK_OBJECITVE_TYPE_OF_SERVICE (0x00000100) -#define SL_NET_APP_MASK_RDP_TYPE_OF_SERVICE (0x00000200) -#define SL_NET_APP_MASK_REMOTE_TYPE_OF_SERVICE (0x00000400) -#define SL_NET_APP_MASK_RTSP_TYPE_OF_SERVICE (0x00000800) -#define SL_NET_APP_MASK_SIP_TYPE_OF_SERVICE (0x00001000) -#define SL_NET_APP_MASK_SMB_TYPE_OF_SERVICE (0x00002000) -#define SL_NET_APP_MASK_SOAP_TYPE_OF_SERVICE (0x00004000) -#define SL_NET_APP_MASK_SSH_TYPE_OF_SERVICE (0x00008000) -#define SL_NET_APP_MASK_TELNET_TYPE_OF_SERVICE (0x00010000) -#define SL_NET_APP_MASK_TFTP_TYPE_OF_SERVICE (0x00020000) -#define SL_NET_APP_MASK_XMPP_CLIENT_TYPE_OF_SERVICE (0x00040000) -#define SL_NET_APP_MASK_RAOP_TYPE_OF_SERVICE (0x00080000) -#define SL_NET_APP_MASK_ALL_TYPE_OF_SERVICE (0xFFFFFFFF) - -/********************************************************************************************************/ -/* sl_NetAppDnsGetHostByName error codes */ - -#define SL_NET_APP_DNS_QUERY_NO_RESPONSE (-159) /* DNS query failed, no response */ -#define SL_NET_APP_DNS_NO_SERVER (-161) /* No DNS server was specified */ -#define SL_NET_APP_DNS_PARAM_ERROR (-162) /* mDNS parameters error */ -#define SL_NET_APP_DNS_QUERY_FAILED (-163) /* DNS query failed; no DNS server sent an 'answer' */ -#define SL_NET_APP_DNS_INTERNAL_1 (-164) -#define SL_NET_APP_DNS_INTERNAL_2 (-165) -#define SL_NET_APP_DNS_MALFORMED_PACKET (-166) /* Improperly formed or corrupted DNS packet received */ -#define SL_NET_APP_DNS_INTERNAL_3 (-167) -#define SL_NET_APP_DNS_INTERNAL_4 (-168) -#define SL_NET_APP_DNS_INTERNAL_5 (-169) -#define SL_NET_APP_DNS_INTERNAL_6 (-170) -#define SL_NET_APP_DNS_INTERNAL_7 (-171) -#define SL_NET_APP_DNS_INTERNAL_8 (-172) -#define SL_NET_APP_DNS_INTERNAL_9 (-173) -#define SL_NET_APP_DNS_MISMATCHED_RESPONSE (-174) /* Server response type does not match the query request*/ -#define SL_NET_APP_DNS_INTERNAL_10 (-175) -#define SL_NET_APP_DNS_INTERNAL_11 (-176) -#define SL_NET_APP_DNS_NO_ANSWER (-177) /* No response for one-shot query */ -#define SL_NET_APP_DNS_NO_KNOWN_ANSWER (-178) /* No known answer for query */ -#define SL_NET_APP_DNS_NAME_MISMATCH (-179) /* Illegal service name according to the RFC */ -#define SL_NET_APP_DNS_NOT_STARTED (-180) /* mDNS is not running */ -#define SL_NET_APP_DNS_HOST_NAME_ERROR (-181) /* Host name error. Host name format is not allowed according to RFC 1033,1034,1035, 6763 */ -#define SL_NET_APP_DNS_NO_MORE_ENTRIES (-182) /* No more entries be found. */ - -#define SL_NET_APP_DNS_MAX_SERVICES_ERROR (-200) /* Maximum advertise services are already configured */ -#define SL_NET_APP_DNS_IDENTICAL_SERVICES_ERROR (-201) /* Trying to register a service that is already exists */ -#define SL_NET_APP_DNS_NOT_EXISTED_SERVICE_ERROR (-203) /* Trying to delete service that does not existed */ -#define SL_NET_APP_DNS_ERROR_SERVICE_NAME_ERROR (-204) /* Illegal service name according to the RFC */ -#define SL_NET_APP_DNS_RX_PACKET_ALLOCATION_ERROR (-205) /* Retry request */ -#define SL_NET_APP_DNS_BUFFER_SIZE_ERROR (-206) /* List size buffer is bigger than internally allowed in the NWP */ -#define SL_NET_APP_DNS_NET_APP_SET_ERROR (-207) /* Illegal length of one of the mDNS Set functions */ -#define SL_NET_APP_DNS_GET_SERVICE_LIST_FLAG_ERROR (-208) -#define SL_NET_APP_DNS_NO_CONFIGURATION_ERROR (-209) - -/* Set Dev name error codes (NETAPP_SET_GET_DEV_CONF_OPT_DEVICE_URN) */ -#define SL_ERROR_DEVICE_NAME_LEN_ERR (-117) -#define SL_ERROR_DEVICE_NAME_INVALID (-118) -/* Set domain name error codes (NETAPP_SET_GET_DEV_CONF_OPT_DOMAIN_NAME) */ -#define SL_ERROR_DOMAIN_NAME_LEN_ERR (-119) -#define SL_ERROR_DOMAIN_NAME_INVALID (-120) - -/********************************************************************************************************/ - -/* NetApp application IDs */ -#define SL_NET_APP_HTTP_SERVER_ID (1) -#define SL_NET_APP_DHCP_SERVER_ID (2) -#define SL_NET_APP_MDNS_ID (4) -#define SL_NET_APP_DNS_SERVER_ID (8) -#define SL_NET_APP_DEVICE_CONFIG_ID (16) -/* NetApp application set/get options */ -#define NETAPP_SET_DHCP_SRV_BASIC_OPT (0) -/* HTTP server set/get options */ -#define NETAPP_SET_GET_HTTP_OPT_PORT_NUMBER (0) -#define NETAPP_SET_GET_HTTP_OPT_AUTH_CHECK (1) -#define NETAPP_SET_GET_HTTP_OPT_AUTH_NAME (2) -#define NETAPP_SET_GET_HTTP_OPT_AUTH_PASSWORD (3) -#define NETAPP_SET_GET_HTTP_OPT_AUTH_REALM (4) -#define NETAPP_SET_GET_HTTP_OPT_ROM_PAGES_ACCESS (5) - -#define NETAPP_SET_GET_MDNS_CONT_QUERY_OPT (1) -#define NETAPP_SET_GET_MDNS_QEVETN_MASK_OPT (2) -#define NETAPP_SET_GET_MDNS_TIMING_PARAMS_OPT (3) - -/* DNS server set/get options */ -#define NETAPP_SET_GET_DNS_OPT_DOMAIN_NAME (0) - -/* Device Config set/get options */ -#define NETAPP_SET_GET_DEV_CONF_OPT_DEVICE_URN (0) -#define NETAPP_SET_GET_DEV_CONF_OPT_DOMAIN_NAME (1) - - -/*****************************************************************************/ -/* Structure/Enum declarations */ -/*****************************************************************************/ - -typedef struct -{ - _u32 PacketsSent; - _u32 PacketsReceived; - _u16 MinRoundTime; - _u16 MaxRoundTime; - _u16 AvgRoundTime; - _u32 TestTime; -}SlPingReport_t; - -typedef struct -{ - _u32 PingIntervalTime; /* delay between pings, in milliseconds */ - _u16 PingSize; /* ping packet size in bytes */ - _u16 PingRequestTimeout; /* timeout time for every ping in milliseconds */ - _u32 TotalNumberOfAttempts; /* max number of ping requests. 0 - forever */ - _u32 Flags; /* flag - 0 report only when finished, 1 - return response for every ping, 2 - stop after 1 successful ping. */ - _u32 Ip; /* IPv4 address or IPv6 first 4 bytes */ - _u32 Ip1OrPaadding; - _u32 Ip2OrPaadding; - _u32 Ip3OrPaadding; -}SlPingStartCommand_t; - -typedef struct _slHttpServerString_t -{ - _u8 len; - _u8 *data; -} slHttpServerString_t; - -typedef struct _slHttpServerData_t -{ - _u8 value_len; - _u8 name_len; - _u8 *token_value; - _u8 *token_name; -} slHttpServerData_t; - -typedef struct _slHttpServerPostData_t -{ - slHttpServerString_t action; - slHttpServerString_t token_name; - slHttpServerString_t token_value; -}slHttpServerPostData_t; - -typedef union -{ - slHttpServerString_t httpTokenName; /* SL_NETAPP_HTTPGETTOKENVALUE */ - slHttpServerPostData_t httpPostData; /* SL_NETAPP_HTTPPOSTTOKENVALUE */ -} SlHttpServerEventData_u; - -typedef union -{ - slHttpServerString_t token_value; -} SlHttpServerResponsedata_u; - -typedef struct -{ - _u32 Event; - SlHttpServerEventData_u EventData; -}SlHttpServerEvent_t; - -typedef struct -{ - _u32 Response; - SlHttpServerResponsedata_u ResponseData; -}SlHttpServerResponse_t; - - -typedef struct -{ - _u32 lease_time; - _u32 ipv4_addr_start; - _u32 ipv4_addr_last; -}SlNetAppDhcpServerBasicOpt_t; - -/*mDNS parameters*/ -typedef enum -{ - SL_NET_APP_FULL_SERVICE_WITH_TEXT_IPV4_TYPE = 1, - SL_NET_APP_FULL_SERVICE_IPV4_TYPE, - SL_NET_APP_SHORT_SERVICE_IPV4_TYPE - -} SlNetAppGetServiceListType_e; - -typedef struct -{ - _u32 service_ipv4; - _u16 service_port; - _u16 Reserved; -}SlNetAppGetShortServiceIpv4List_t; - -typedef struct -{ - _u32 service_ipv4; - _u16 service_port; - _u16 Reserved; - _u8 service_name[NETAPP_MAX_SERVICE_NAME_SIZE]; - _u8 service_host[NETAPP_MAX_SERVICE_HOST_NAME_SIZE]; -}SlNetAppGetFullServiceIpv4List_t; - -typedef struct -{ - _u32 service_ipv4; - _u16 service_port; - _u16 Reserved; - _u8 service_name[NETAPP_MAX_SERVICE_NAME_SIZE]; - _u8 service_host[NETAPP_MAX_SERVICE_HOST_NAME_SIZE]; - _u8 service_text[NETAPP_MAX_SERVICE_TEXT_SIZE]; -}SlNetAppGetFullServiceWithTextIpv4List_t; - -typedef struct -{ - /*The below parameters are used to configure the advertise times and interval - For example: - If: - Period is set to T - Repetitions are set to P - Telescopic factor is K=2 - The transmission shall be: - advertise P times - wait T - advertise P times - wait 4 * T - advertise P time - wait 16 * T ... (till max time reached / configuration changed / query issued) - */ - _u32 t; /* Number of ticks for the initial period. Default is 100 ticks for 1 second. */ - _u32 p; /* Number of repetitions. Default value is 1 */ - _u32 k; /* Telescopic factor. Default value is 2. */ - _u32 RetransInterval;/* Announcing retransmission interval */ - _u32 Maxinterval; /* Announcing max period interval */ - _u32 max_time; /* Announcing max time */ -}SlNetAppServiceAdvertiseTimingParameters_t; - -/*****************************************************************************/ -/* Types declarations */ -/*****************************************************************************/ -typedef void (*P_SL_DEV_PING_CALLBACK)(SlPingReport_t*); - -/*****************************************************************************/ -/* Function prototypes */ -/*****************************************************************************/ - - -/*! - \brief Starts a network application - - Gets and starts network application for the current WLAN mode - - \param[in] AppBitMap application bitmap, could be one or combination of the following: \n - - SL_NET_APP_HTTP_SERVER_ID - - SL_NET_APP_DHCP_SERVER_ID - - SL_NET_APP_MDNS_ID - - \return On error, negative number is returned - - \sa Stop one or more the above started applications using sl_NetAppStop - \note This command activates the application for the current WLAN mode (AP or STA) - \warning - \par Example: - \code - For example: Starting internal HTTP server + DHCP server: - sl_NetAppStart(SL_NET_APP_HTTP_SERVER_ID | SL_NET_APP_DHCP_SERVER_ID) - - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_NetAppStart) -_i16 sl_NetAppStart(const _u32 AppBitMap); -#endif -/*! - \brief Stops a network application - - Gets and stops network application for the current WLAN mode - - \param[in] AppBitMap application id, could be one of the following: \n - - SL_NET_APP_HTTP_SERVER_ID - - SL_NET_APP_DHCP_SERVER_ID - - SL_NET_APP_MDNS_ID - - \return On error, negative number is returned - - \sa - \note This command disables the application for the current active WLAN mode (AP or STA) - \warning - \par Example: - \code - - For example: Stopping internal HTTP server: - sl_NetAppStop(SL_NET_APP_HTTP_SERVER_ID); - - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_NetAppStop) -_i16 sl_NetAppStop(const _u32 AppBitMap); -#endif - -/*! - \brief Get host IP by name - - Obtain the IP Address of machine on network, by machine name. - - \param[in] hostname host name - \param[in] usNameLen name length - \param[out] out_ip_addr This parameter is filled in with - host IP address. In case that host name is not - resolved, out_ip_addr is zero. - \param[in] family protocol family - - \return On success, 0 is returned. - On error, negative is returned - SL_POOL_IS_EMPTY may be return in case there are no resources in the system - In this case try again later or increase MAX_CONCURRENT_ACTIONS - Possible DNS error codes: - - SL_NET_APP_DNS_QUERY_NO_RESPONSE - - SL_NET_APP_DNS_NO_SERVER - - SL_NET_APP_DNS_QUERY_FAILED - - SL_NET_APP_DNS_MALFORMED_PACKET - - SL_NET_APP_DNS_MISMATCHED_RESPONSE - - \sa - \note Only one sl_NetAppDnsGetHostByName can be handled at a time. - Calling this API while the same command is called from another thread, may result - in one of the two scenarios: - 1. The command will wait (internal) until the previous command finish, and then be executed. - 2. There are not enough resources and POOL_IS_EMPTY error will return. - In this case, MAX_CONCURRENT_ACTIONS can be increased (result in memory increase) or try - again later to issue the command. - \warning - In case an IP address in a string format is set as input, without any prefix (e.g. "1.2.3.4") the device will not - try to access the DNS and it will return the input address on the 'out_ip_addr' field - \par Example: - \code - _u32 DestinationIP; - sl_NetAppDnsGetHostByName("www.google.com", strlen("www.google.com"), &DestinationIP,SL_AF_INET); - - Addr.sin_family = SL_AF_INET; - Addr.sin_port = sl_Htons(80); - Addr.sin_addr.s_addr = sl_Htonl(DestinationIP); - AddrSize = sizeof(SlSockAddrIn_t); - SockID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0); - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_NetAppDnsGetHostByName) -_i16 sl_NetAppDnsGetHostByName(_i8 * hostname,const _u16 usNameLen, _u32* out_ip_addr,const _u8 family ); -#endif - -/*! - \brief Return service attributes like IP address, port and text according to service name - \par - The user sets a service name Full/Part (see example below), and should get: - - IP of service - - The port of service - - The text of service - - Hence it can make a connection to the specific service and use it. - It is similar to get host by name method. - It is done by a single shot query with PTR type on the service name. - The command that is sent is from constant parameters and variables parameters. - - \param[in] pService Service name can be full or partial. \n - Example for full service name: - 1. PC1._ipp._tcp.local - 2. PC2_server._ftp._tcp.local \n - . - Example for partial service name: - 1. _ipp._tcp.local - 2. _ftp._tcp.local - - \param[in] ServiceLen The length of the service name (in_pService). - \param[in] Family IPv4 or IPv6 (SL_AF_INET , SL_AF_INET6). - \param[out] pAddr Contains the IP address of the service. - \param[out] pPort Contains the port of the service. - \param[out] pTextLen Has 2 options. One as Input field and the other one as output: - - Input: \n - Contains the max length of the text that the user wants to get.\n - It means that if the text len of service is bigger that its value than - the text is cut to inout_TextLen value. - - Output: \n - Contain the length of the text that is returned. Can be full text or part of the text (see above). - - \param[out] pOut_pText Contains the text of the service full or partial - - \return On success, zero is returned - SL_POOL_IS_EMPTY may be return in case there are no resources in the system - In this case try again later or increase MAX_CONCURRENT_ACTIONS - In case No service is found error SL_NET_APP_DNS_NO_ANSWER will be returned - - \note The returns attributes belongs to the first service found. - There may be other services with the same service name that will response to the query. - The results of these responses are saved in the peer cache of the Device and should be read by another API. - - Only one sl_NetAppDnsGetHostByService can be handled at a time. - Calling this API while the same command is called from another thread, may result - in one of the two scenarios: - 1. The command will wait (internal) until the previous command finish, and then be executed. - 2. There are not enough resources and SL_POOL_IS_EMPTY error will return. - In this case, MAX_CONCURRENT_ACTIONS can be increased (result in memory increase) or try - again later to issue the command. - - \warning Text length can be 120 bytes only -*/ -#if _SL_INCLUDE_FUNC(sl_NetAppDnsGetHostByService) -_i32 sl_NetAppDnsGetHostByService(_i8 *pServiceName, /* string containing all (or only part): name + subtype + service */ - const _u8 ServiceLen, - const _u8 Family, /* 4-IPv4 , 16-IPv6 */ - _u32 pAddr[], - _u32 *pPort, - _u16 *pTextLen, /* in: max len , out: actual len */ - _i8 *pText - ); - -#endif - -/*! - \brief Get service List - Insert into out pBuffer a list of peer's services that are the NWP. - The list is in a form of service struct. The user should chose the type - of the service struct like: - - Full service parameters with text. - - Full service parameters. - - Short service parameters (port and IP only) especially for tiny hosts. - - The different types of struct are made to give the - Possibility to save memory in the host - - - The user also chose how many max services to get and start point index - NWP peer cache. - For example: - 1. Get max of 3 full services from index 0.Up to 3 full services - from index 0 are inserted into pBuffer (services that are in indexes 0,1,2). - 2. Get max of 4 full services from index 3.Up to 4 full services - from index 3 are inserted into pBuffer (services that are in indexes 3,4,5,6). - 3. Get max of 2 int services from index 6.Up to 2 int services - from index 6 are inserted into pBuffer (services that are in indexes 6,7). - - See below - command parameters. - - \param[in] indexOffset - The start index in the peer cache that from it the first service is returned. - \param[in] MaxServiceCount - The Max services that can be returned if existed or if not exceed the max index - in the peer cache - \param[in] Flags - an ENUM number that means which service struct to use (means which types of service to fill) - - use SlNetAppGetFullServiceWithTextIpv4List_t - - use SlNetAppGetFullServiceIpv4List_t - - use SlNetAppGetShortServiceIpv4List_t - - \param[out] Buffer - The Services are inserted into this buffer. In the struct form according to the bit that is set in the Flags - input parameter. - - \return ServiceFoundCount - The number of the services that were inserted into the buffer. zero means no service is found - negative number means an error - \sa sl_NetAppMDNSRegisterService - \note - \warning - if the out pBuffer size is bigger than an RX packet(1480), than - an error is returned because there - is no place in the RX packet. - The size is a multiply of MaxServiceCount and size of service struct(that is set - according to flag value). -*/ - -#if _SL_INCLUDE_FUNC(sl_NetAppGetServiceList) -_i16 sl_NetAppGetServiceList(const _u8 IndexOffest, - const _u8 MaxServiceCount, - const _u8 Flags, - _i8 *pBuffer, - const _u32 RxBufferLength - ); - -#endif - -/*! - \brief Unregister mDNS service - This function deletes the mDNS service from the mDNS package and the database. - - The mDNS service that is to be unregistered is a service that the application no longer wishes to provide. \n - The service name should be the full service name according to RFC - of the DNS-SD - meaning the value in name field in the SRV answer. - - Examples for service names: - 1. PC1._ipp._tcp.local - 2. PC2_server._ftp._tcp.local - - \param[in] pServiceName Full service name. \n - Example for service name: - 1. PC1._ipp._tcp.local - 2. PC2_server._ftp._tcp.local - \param[in] ServiceLen The length of the service. - \return On success, zero is returned - \sa sl_NetAppMDNSRegisterService - \note - \warning - The size of the service length should be smaller than 255. -*/ -#if _SL_INCLUDE_FUNC(sl_NetAppMDNSUnRegisterService) -_i16 sl_NetAppMDNSUnRegisterService(const _i8 *pServiceName,const _u8 ServiceNameLen); -#endif - -/*! - \brief Register a new mDNS service - \par - This function registers a new mDNS service to the mDNS package and the DB. - - This registered service is a service offered by the application. - The service name should be full service name according to RFC - of the DNS-SD - meaning the value in name field in the SRV answer. - Example for service name: - 1. PC1._ipp._tcp.local - 2. PC2_server._ftp._tcp.local - - If the option is_unique is set, mDNS probes the service name to make sure - it is unique before starting to announce the service on the network. - Instance is the instance portion of the service name. - - \param[in] ServiceLen The length of the service. - \param[in] TextLen The length of the service should be smaller than 64. - \param[in] port The port on this target host port. - \param[in] TTL The TTL of the service - \param[in] Options bitwise parameters: \n - - bit 0 - service is unique (means that the service needs to be unique) - - bit 31 - for internal use if the service should be added or deleted (set means ADD). - - bit 1-30 for future. - - \param[in] pServiceName The service name. - Example for service name: \n - 1. PC1._ipp._tcp.local - 2. PC2_server._ftp._tcp.local - - \param[in] pText The description of the service. - should be as mentioned in the RFC - (according to type of the service IPP,FTP...) - - \return On success, zero is returned - Possible error codes: - - Maximum advertise services are already configured. - Delete another existed service that is registered and then register again the new service - - Trying to register a service that is already exists - - Trying to delete service that does not existed - - Illegal service name according to the RFC - - Retry request - - Illegal length of one of the mDNS Set functions - - mDNS is not operational as the device has no IP.Connect the device to an AP to get an IP address. - - mDNS parameters error - - mDNS internal cache error - - mDNS internal error - - Adding a service is not allowed as it is already exist (duplicate service) - - mDNS is not running - - Host name error. Host name format is not allowed according to RFC 1033,1034,1035, 6763 - - List size buffer is bigger than internally allowed in the NWP (API get service list), - change the APIs’ parameters to decrease the size of the list - - - \sa sl_NetAppMDNSUnRegisterService - - \warning 1) Temporary - there is an allocation on stack of internal buffer. - Its size is NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH. \n - It means that the sum of the text length and service name length cannot be bigger than - NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH.\n - If it is - An error is returned. \n - 2) According to now from certain constraints the variables parameters are set in the - attribute part (contain constant parameters) -*/ -#if _SL_INCLUDE_FUNC(sl_NetAppMDNSRegisterService) -_i16 sl_NetAppMDNSRegisterService( const _i8* pServiceName, - const _u8 ServiceNameLen, - const _i8* pText, - const _u8 TextLen, - const _u16 Port, - const _u32 TTL, - _u32 Options); -#endif - -/*! - \brief send ICMP ECHO_REQUEST to network hosts - - Ping uses the ICMP protocol's mandatory ECHO_REQUEST - - \param[in] pPingParams Pointer to the ping request structure: \n - - if flags parameter is set to 0, ping will report back once all requested pings are done (as defined by TotalNumberOfAttempts). \n - - if flags parameter is set to 1, ping will report back after every ping, for TotalNumberOfAttempts. - - if flags parameter is set to 2, ping will stop after the first successful ping, and report back for the successful ping, as well as any preceding failed ones. - For stopping an ongoing ping activity, set parameters IP address to 0 - - \param[in] family SL_AF_INET or SL_AF_INET6 - \param[out] pReport Ping pReport - \param[out] pCallback Callback function upon completion. - If callback is NULL, the API is blocked until data arrives - - - \return On success, zero is returned. On error, -1 is returned - SL_POOL_IS_EMPTY may be return in case there are no resources in the system - In this case try again later or increase MAX_CONCURRENT_ACTIONS - - \sa sl_NetAppPingReport - \note Only one sl_NetAppPingStart can be handled at a time. - Calling this API while the same command is called from another thread, may result - in one of the two scenarios: - 1. The command will wait (internal) until the previous command finish, and then be executed. - 2. There are not enough resources and SL_POOL_IS_EMPTY error will return. - In this case, MAX_CONCURRENT_ACTIONS can be increased (result in memory increase) or try - again later to issue the command. - \warning - \par Example: - \code - - An example of sending 20 ping requests and reporting results to a callback routine when - all requests are sent: - - // callback routine - void pingRes(SlPingReport_t* pReport) - { - // handle ping results - } - - // ping activation - void PingTest() - { - SlPingReport_t report; - SlPingStartCommand_t pingCommand; - - pingCommand.Ip = SL_IPV4_VAL(10,1,1,200); // destination IP address is 10.1.1.200 - pingCommand.PingSize = 150; // size of ping, in bytes - pingCommand.PingIntervalTime = 100; // delay between pings, in milliseconds - pingCommand.PingRequestTimeout = 1000; // timeout for every ping in milliseconds - pingCommand.TotalNumberOfAttempts = 20; // max number of ping requests. 0 - forever - pingCommand.Flags = 0; // report only when finished - - sl_NetAppPingStart( &pingCommand, SL_AF_INET, &report, pingRes ) ; - } - - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_NetAppPingStart) -_i16 sl_NetAppPingStart(const SlPingStartCommand_t* pPingParams,const _u8 family,SlPingReport_t *pReport,const P_SL_DEV_PING_CALLBACK pPingCallback); -#endif - -/*! - \brief Internal function for setting network application configurations - - \return On success, zero is returned. On error, -1 is - returned - - \param[in] AppId Application id, could be one of the following: \n - - SL_NET_APP_HTTP_SERVER_ID - - SL_NET_APP_DHCP_SERVER_ID - - SL_NET_APP_MDNS_ID - - SL_NET_APP_DEVICE_CONFIG_ID - - \param[in] SetOptions set option, could be one of the following: \n - - SL_NET_APP_DHCP_SERVER_ID - - NETAPP_SET_DHCP_SRV_BASIC_OPT - - SL_NET_APP_HTTP_SERVER_ID - - NETAPP_SET_GET_HTTP_OPT_PORT_NUMBER - - NETAPP_SET_GET_HTTP_OPT_AUTH_CHECK - - NETAPP_SET_GET_HTTP_OPT_AUTH_NAME - - NETAPP_SET_GET_HTTP_OPT_AUTH_PASSWORD - - NETAPP_SET_GET_HTTP_OPT_AUTH_REALM - - NETAPP_SET_GET_HTTP_OPT_ROM_PAGES_ACCESS - - SL_NET_APP_MDNS_ID - - NETAPP_SET_GET_MDNS_CONT_QUERY_OPT - - NETAPP_SET_GET_MDNS_QEVETN_MASK_OPT - - NETAPP_SET_GET_MDNS_TIMING_PARAMS_OPT - - SL_NET_APP_DEVICE_CONFIG_ID - - NETAPP_SET_GET_DEV_CONF_OPT_DEVICE_URN - - NETAPP_SET_GET_DEV_CONF_OPT_DOMAIN_NAME - - - \param[in] OptionLen option structure length - - \param[in] pOptionValues pointer to the option structure - \sa - \note - \warning - \par - \code - Set DHCP Server (AP mode) parameters example: - - SlNetAppDhcpServerBasicOpt_t dhcpParams; - _u8 outLen = sizeof(SlNetAppDhcpServerBasicOpt_t); - dhcpParams.lease_time = 4096; // lease time (in seconds) of the IP Address - dhcpParams.ipv4_addr_start = SL_IPV4_VAL(192,168,1,10); // first IP Address for allocation. IP Address should be set as Hex number - i.e. 0A0B0C01 for (10.11.12.1) - dhcpParams.ipv4_addr_last = SL_IPV4_VAL(192,168,1,16); // last IP Address for allocation. IP Address should be set as Hex number - i.e. 0A0B0C01 for (10.11.12.1) - sl_NetAppStop(SL_NET_APP_DHCP_SERVER_ID); // Stop DHCP server before settings - sl_NetAppSet(SL_NET_APP_DHCP_SERVER_ID, NETAPP_SET_DHCP_SRV_BASIC_OPT, outLen, (_u8* )&dhcpParams); // set parameters - sl_NetAppStart(SL_NET_APP_DHCP_SERVER_ID); // Start DHCP server with new settings - \endcode - \code - Set Device URN name example: - - Device name, maximum length of 33 characters - Device name affects URN name, own SSID name in AP mode, and WPS file "device name" in WPS I.E (STA-WPS / P2P) - In case no device URN name set, the default name is "mysimplelink" - Allowed characters in device name are: 'a - z' , 'A - Z' , '0-9' and '-' - - _u8 *my_device = "MY-SIMPLELINK-DEV"; - sl_NetAppSet (SL_NET_APP_DEVICE_CONFIG_ID, NETAPP_SET_GET_DEV_CONF_OPT_DEVICE_URN, strlen(my_device), (_u8 *) my_device); - \endcode - -*/ -#if _SL_INCLUDE_FUNC(sl_NetAppSet) -_i32 sl_NetAppSet(const _u8 AppId ,const _u8 Option,const _u8 OptionLen,const _u8 *pOptionValue); -#endif - -/*! - \brief Internal function for getting network applications configurations - - \return On success, zero is returned. On error, -1 is - returned - - \param[in] AppId Application id, could be one of the following: \n - - SL_NET_APP_HTTP_SERVER_ID - - SL_NET_APP_DHCP_SERVER_ID - - SL_NET_APP_MDNS_ID - - SL_NET_APP_DEVICE_CONFIG_ID - - \param[in] SetOptions set option, could be one of the following: \n - - SL_NET_APP_DHCP_SERVER_ID - - NETAPP_SET_DHCP_SRV_BASIC_OPT - - SL_NET_APP_HTTP_SERVER_ID - - NETAPP_SET_GET_HTTP_OPT_PORT_NUMBER - - NETAPP_SET_GET_HTTP_OPT_AUTH_CHECK - - NETAPP_SET_GET_HTTP_OPT_AUTH_NAME - - NETAPP_SET_GET_HTTP_OPT_AUTH_PASSWORD - - NETAPP_SET_GET_HTTP_OPT_AUTH_REALM - - NETAPP_SET_GET_HTTP_OPT_ROM_PAGES_ACCESS - - SL_NET_APP_MDNS_ID - - NETAPP_SET_GET_MDNS_CONT_QUERY_OPT - - NETAPP_SET_GET_MDNS_QEVETN_MASK_OPT - - NETAPP_SET_GET_MDNS_TIMING_PARAMS_OPT - - SL_NET_APP_DEVICE_CONFIG_ID - - NETAPP_SET_GET_DEV_CONF_OPT_DEVICE_URN - - NETAPP_SET_GET_DEV_CONF_OPT_DOMAIN_NAME - - - \param[in] OptionLen The length of the allocated memory as input, when the - function complete, the value of this parameter would be - the len that actually read from the device. - If the device return length that is longer from the input - value, the function will cut the end of the returned structure - and will return ESMALLBUF - - \param[out] pValues pointer to the option structure which will be filled with the response from the device - - \sa - \note - \warning - \par - \code - Get DHCP Server parameters example: - - SlNetAppDhcpServerBasicOpt_t dhcpParams; - _u8 outLen = sizeof(SlNetAppDhcpServerBasicOpt_t); - sl_NetAppGet(SL_NET_APP_DHCP_SERVER_ID, NETAPP_SET_DHCP_SRV_BASIC_OPT, &outLen, (_u8* )&dhcpParams); - - printf("DHCP Start IP %d.%d.%d.%d End IP %d.%d.%d.%d Lease time seconds %d\n", - SL_IPV4_BYTE(dhcpParams.ipv4_addr_start,3),SL_IPV4_BYTE(dhcpParams.ipv4_addr_start,2), - SL_IPV4_BYTE(dhcpParams.ipv4_addr_start,1),SL_IPV4_BYTE(dhcpParams.ipv4_addr_start,0), - SL_IPV4_BYTE(dhcpParams.ipv4_addr_last,3),SL_IPV4_BYTE(dhcpParams.ipv4_addr_last,2), - SL_IPV4_BYTE(dhcpParams.ipv4_addr_last,1),SL_IPV4_BYTE(dhcpParams.ipv4_addr_last,0), - dhcpParams.lease_time); - \endcode - \code - Get Device URN name example: - Maximum length of 33 characters of device name. - Device name affects URN name, own SSID name in AP mode, and WPS file "device name" in WPS I.E (STA-WPS / P2P) - in case no device URN name set, the default name is "mysimplelink" - - _u8 my_device_name[35]; - sl_NetAppGet (SL_NET_APP_DEVICE_CONFIG_ID, NETAPP_SET_GET_DEV_CONF_OPT_DEVICE_URN, strlen(my_device_name), (_u8 *)my_device_name); - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_NetAppGet) -_i32 sl_NetAppGet(const _u8 AppId,const _u8 Option,_u8 *pOptionLen, _u8 *pOptionValue); -#endif - - - -/*! - - Close the Doxygen group. - @} - - */ - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __NETAPP_H__ */ - diff --git a/drivers/cc3100/inc/netcfg.h b/drivers/cc3100/inc/netcfg.h deleted file mode 100644 index cc8cfbcaaf1..00000000000 --- a/drivers/cc3100/inc/netcfg.h +++ /dev/null @@ -1,283 +0,0 @@ -/* - * netcfg.h - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ -#include "simplelink.h" - - -#ifndef __NETCFG_H__ -#define __NETCFG_H__ - - -#ifdef __cplusplus -extern "C" { -#endif - - - -/*! - - \addtogroup netcfg - @{ - -*/ - - -/*****************************************************************************/ -/* Macro declarations */ -/*****************************************************************************/ - -#define SL_MAC_ADDR_LEN (6) -#define SL_IPV4_VAL(add_3,add_2,add_1,add_0) ((((_u32)add_3 << 24) & 0xFF000000) | (((_u32)add_2 << 16) & 0xFF0000) | (((_u32)add_1 << 8) & 0xFF00) | ((_u32)add_0 & 0xFF) ) -#define SL_IPV4_BYTE(val,index) ( (val >> (index*8)) & 0xFF ) - -#define IPCONFIG_MODE_DISABLE_IPV4 (0) -#define IPCONFIG_MODE_ENABLE_IPV4 (1) - -/*****************************************************************************/ -/* Structure/Enum declarations */ -/*****************************************************************************/ -typedef enum -{ - SL_MAC_ADDRESS_SET = 1, - SL_MAC_ADDRESS_GET = 2, - SL_IPV4_STA_P2P_CL_GET_INFO = 3, - SL_IPV4_STA_P2P_CL_DHCP_ENABLE = 4, - SL_IPV4_STA_P2P_CL_STATIC_ENABLE = 5, - SL_IPV4_AP_P2P_GO_GET_INFO = 6, - SL_IPV4_AP_P2P_GO_STATIC_ENABLE = 7, - SL_SET_HOST_RX_AGGR = 8, - MAX_SETTINGS = 0xFF -}Sl_NetCfg_e; - - -typedef struct -{ - _u32 ipV4; - _u32 ipV4Mask; - _u32 ipV4Gateway; - _u32 ipV4DnsServer; -}SlNetCfgIpV4Args_t; - - -/*****************************************************************************/ -/* Function prototypes */ -/*****************************************************************************/ - -/*! - \brief Internal function for setting network configurations - - \return On success, zero is returned. On error, -1 is - returned - - \param[in] ConfigId configuration id - \param[in] ConfigOpt configurations option - \param[in] ConfigLen configurations len - \param[in] pValues configurations values - - \sa - \note - \warning - - \par Examples: - \code - SL_MAC_ADDRESS_SET: - - Setting MAC address to the Device. - The new MAC address will override the default MAC address and it be saved in the FileSystem. - Requires restarting the device for updating this setting. - - _u8 MAC_Address[6]; - MAC_Address[0] = 0x8; - MAC_Address[1] = 0x0; - MAC_Address[2] = 0x28; - MAC_Address[3] = 0x22; - MAC_Address[4] = 0x69; - MAC_Address[5] = 0x31; - sl_NetCfgSet(SL_MAC_ADDRESS_SET,1,SL_MAC_ADDR_LEN,(_u8 *)newMacAddress); - sl_Stop(0); - sl_Start(NULL,NULL,NULL); - \endcode - - \code - SL_IPV4_STA_P2P_CL_STATIC_ENABLE: - - Setting a static IP address to the device working in STA mode or P2P client. - The IP address will be stored in the FileSystem. - In order to disable the static IP and get the address assigned from DHCP one should use SL_STA_P2P_CL_IPV4_DHCP_SET - - SlNetCfgIpV4Args_t ipV4; - ipV4.ipV4 = (_u32)SL_IPV4_VAL(10,1,1,201); // _u32 IP address - ipV4.ipV4Mask = (_u32)SL_IPV4_VAL(255,255,255,0); // _u32 Subnet mask for this STA/P2P - ipV4.ipV4Gateway = (_u32)SL_IPV4_VAL(10,1,1,1); // _u32 Default gateway address - ipV4.ipV4DnsServer = (_u32)SL_IPV4_VAL(8,16,32,64); // _u32 DNS server address - - sl_NetCfgSet(SL_IPV4_STA_P2P_CL_STATIC_ENABLE,IPCONFIG_MODE_ENABLE_IPV4,sizeof(SlNetCfgIpV4Args_t),(_u8 *)&ipV4); - sl_Stop(0); - sl_Start(NULL,NULL,NULL); - \endcode - - \code - SL_IPV4_STA_P2P_CL_DHCP_ENABLE: - - Setting IP address by DHCP to FileSystem using WLAN sta mode or P2P client. - This should be done once if using Serial Flash. - This is the system's default mode for acquiring an IP address after WLAN connection. - _u8 val = 1; - sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE,IPCONFIG_MODE_ENABLE_IPV4,1,&val); - sl_Stop(0); - sl_Start(NULL,NULL,NULL); - \endcode - - \code - SL_IPV4_AP_P2P_GO_STATIC_ENABLE: - - Setting a static IP address to the device working in AP mode or P2P go. - The IP address will be stored in the FileSystem. Requires restart. - - SlNetCfgIpV4Args_t ipV4; - ipV4.ipV4 = (_u32)SL_IPV4_VAL(10,1,1,201); // _u32 IP address - ipV4.ipV4Mask = (_u32)SL_IPV4_VAL(255,255,255,0); // _u32 Subnet mask for this AP/P2P - ipV4.ipV4Gateway = (_u32)SL_IPV4_VAL(10,1,1,1); // _u32 Default gateway address - ipV4.ipV4DnsServer = (_u32)SL_IPV4_VAL(8,16,32,64); // _u32 DNS server address - - sl_NetCfgSet(SL_IPV4_AP_P2P_GO_STATIC_ENABLE,IPCONFIG_MODE_ENABLE_IPV4,sizeof(SlNetCfgIpV4Args_t),(_u8 *)&ipV4); - sl_Stop(0); - sl_Start(NULL,NULL,NULL); - \endcode - - -*/ -#if _SL_INCLUDE_FUNC(sl_NetCfgSet) -_i32 sl_NetCfgSet(const _u8 ConfigId,const _u8 ConfigOpt,const _u8 ConfigLen,const _u8 *pValues); -#endif - - -/*! - \brief Internal function for getting network configurations - - \return On success, zero is returned. On error, -1 is - returned - - \param[in] ConfigId configuration id - - \param[out] pConfigOpt Get configurations option - - \param[out] pConfigLen The length of the allocated memory as input, when the - function complete, the value of this parameter would be - the len that actually read from the device.\n - If the device return length that is longer from the input - value, the function will cut the end of the returned structure - and will return ESMALLBUF - - \param[out] pValues - get configurations values - - \sa - \note - \warning - \par Examples: - \code - SL_MAC_ADDRESS_GET: - - Get the device MAC address. - The returned MAC address is taken from FileSystem first. If the MAC address was not set by SL_MAC_ADDRESS_SET, the default MAC address - is retrieved from HW. - - _u8 macAddressVal[SL_MAC_ADDR_LEN]; - _u8 macAddressLen = SL_MAC_ADDR_LEN; - sl_NetCfgGet(SL_MAC_ADDRESS_GET,NULL,&macAddressLen,(_u8 *)macAddressVal); - - \endcode - - \code - SL_IPV4_STA_P2P_CL_GET_INFO: - - Get IP address from WLAN station or P2P client. A DHCP flag is returned to indicate if the IP address is static or from DHCP. - - _u8 len = sizeof(SlNetCfgIpV4Args_t); - _u8 dhcpIsOn = 0; - SlNetCfgIpV4Args_t ipV4 = {0}; - sl_NetCfgGet(SL_IPV4_STA_P2P_CL_GET_INFO,&dhcpIsOn,&len,(_u8 *)&ipV4); - - printf("DHCP is %s IP %d.%d.%d.%d MASK %d.%d.%d.%d GW %d.%d.%d.%d DNS %d.%d.%d.%d\n", - (dhcpIsOn > 0) ? "ON" : "OFF", - SL_IPV4_BYTE(ipV4.ipV4,3),SL_IPV4_BYTE(ipV4.ipV4,2),SL_IPV4_BYTE(ipV4.ipV4,1),SL_IPV4_BYTE(ipV4.ipV4,0), - SL_IPV4_BYTE(ipV4.ipV4Mask,3),SL_IPV4_BYTE(ipV4.ipV4Mask,2),SL_IPV4_BYTE(ipV4.ipV4Mask,1),SL_IPV4_BYTE(ipV4.ipV4Mask,0), - SL_IPV4_BYTE(ipV4.ipV4Gateway,3),SL_IPV4_BYTE(ipV4.ipV4Gateway,2),SL_IPV4_BYTE(ipV4.ipV4Gateway,1),SL_IPV4_BYTE(ipV4.ipV4Gateway,0), - SL_IPV4_BYTE(ipV4.ipV4DnsServer,3),SL_IPV4_BYTE(ipV4.ipV4DnsServer,2),SL_IPV4_BYTE(ipV4.ipV4DnsServer,1),SL_IPV4_BYTE(ipV4.ipV4DnsServer,0)); - - \endcode - - \code - SL_IPV4_AP_P2P_GO_GET_INFO: - - Get static IP address for AP or P2P go. - - _u8 len = sizeof(SlNetCfgIpV4Args_t); - _u8 dhcpIsOn = 0; // this flag is meaningless on AP/P2P go. - SlNetCfgIpV4Args_t ipV4 = {0}; - sl_NetCfgGet(SL_IPV4_AP_P2P_GO_GET_INFO,&dhcpIsOn,&len,(_u8 *)&ipV4); - - printf("IP %d.%d.%d.%d MASK %d.%d.%d.%d GW %d.%d.%d.%d DNS %d.%d.%d.%d\n", - SL_IPV4_BYTE(ipV4.ipV4,3),SL_IPV4_BYTE(ipV4.ipV4,2),SL_IPV4_BYTE(ipV4.ipV4,1),SL_IPV4_BYTE(ipV4.ipV4,0), - SL_IPV4_BYTE(ipV4.ipV4Mask,3),SL_IPV4_BYTE(ipV4.ipV4Mask,2),SL_IPV4_BYTE(ipV4.ipV4Mask,1),SL_IPV4_BYTE(ipV4.ipV4Mask,0), - SL_IPV4_BYTE(ipV4.ipV4Gateway,3),SL_IPV4_BYTE(ipV4.ipV4Gateway,2),SL_IPV4_BYTE(ipV4.ipV4Gateway,1),SL_IPV4_BYTE(ipV4.ipV4Gateway,0), - SL_IPV4_BYTE(ipV4.ipV4DnsServer,3),SL_IPV4_BYTE(ipV4.ipV4DnsServer,2),SL_IPV4_BYTE(ipV4.ipV4DnsServer,1),SL_IPV4_BYTE(ipV4.ipV4DnsServer,0)); - - \endcode - - -*/ -#if _SL_INCLUDE_FUNC(sl_NetCfgGet) -_i32 sl_NetCfgGet(const _u8 ConfigId ,_u8 *pConfigOpt, _u8 *pConfigLen, _u8 *pValues); -#endif - -/*! - - Close the Doxygen group. - @} - - */ - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __NETCFG_H__ */ - diff --git a/drivers/cc3100/inc/nonos.h b/drivers/cc3100/inc/nonos.h deleted file mode 100644 index 568c0ff26eb..00000000000 --- a/drivers/cc3100/inc/nonos.h +++ /dev/null @@ -1,325 +0,0 @@ -/* - * nonos.h - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - -#ifndef __NONOS_H__ -#define __NONOS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - - -#ifndef SL_PLATFORM_MULTI_THREADED - -/* This function call the user defined function, if defined, from the sync wait loop */ -/* The use case of this function is to allow nonos system to call a user function to put the device into sleep */ -/* The wake up should be activated after getting an interrupt from the device to Host */ -/* The user function must return without blocking to prevent a delay on the event handling */ -/* -#define _SlSyncWaitLoopCallback UserSleepFunction -*/ - - - -#define NONOS_WAIT_FOREVER 0xFF -#define NONOS_NO_WAIT 0x00 - -#define NONOS_RET_OK (0) -#define NONOS_RET_ERR (0xFF) -#define OSI_OK NONOS_RET_OK - -#define __NON_OS_SYNC_OBJ_CLEAR_VALUE 0x11 -#define __NON_OS_SYNC_OBJ_SIGNAL_VALUE 0x22 -#define __NON_OS_LOCK_OBJ_UNLOCK_VALUE 0x33 -#define __NON_OS_LOCK_OBJ_LOCK_VALUE 0x44 - -/*! - \brief type definition for the return values of this adaptation layer -*/ -typedef _i8 _SlNonOsRetVal_t; - -/*! - \brief type definition for a time value -*/ -typedef _u8 _SlNonOsTime_t; - -/*! - \brief type definition for a sync object container - - Sync object is object used to synchronize between two threads or thread and interrupt handler. - One thread is waiting on the object and the other thread send a signal, which then - release the waiting thread. - The signal must be able to be sent from interrupt context. - This object is generally implemented by binary semaphore or events. -*/ -typedef _u8 _SlNonOsSemObj_t; - - -#define _SlTime_t _SlNonOsTime_t - -#define _SlSyncObj_t _SlNonOsSemObj_t - -#define _SlLockObj_t _SlNonOsSemObj_t - -#define SL_OS_WAIT_FOREVER NONOS_WAIT_FOREVER - -#define SL_OS_RET_CODE_OK NONOS_RET_OK - -#define SL_OS_NO_WAIT NONOS_NO_WAIT - - - - - -/*! - \brief This function creates a sync object - - The sync object is used for synchronization between different thread or ISR and - a thread. - - \param pSyncObj - pointer to the sync object control block - - \return upon successful creation the function return 0 - Otherwise, a negative value indicating the error code shall be returned - \note - \warning -*/ -#define _SlNonOsSyncObjCreate(pSyncObj) _SlNonOsSemSet(pSyncObj,__NON_OS_SYNC_OBJ_CLEAR_VALUE) - -/*! - \brief This function deletes a sync object - - \param pSyncObj - pointer to the sync object control block - - \return upon successful deletion the function should return 0 - Otherwise, a negative value indicating the error code shall be returned - \note - \warning -*/ -#define _SlNonOsSyncObjDelete(pSyncObj) _SlNonOsSemSet(pSyncObj,0) - -/*! - \brief This function generates a sync signal for the object. - - All suspended threads waiting on this sync object are resumed - - \param pSyncObj - pointer to the sync object control block - - \return upon successful signaling the function should return 0 - Otherwise, a negative value indicating the error code shall be returned - \note the function could be called from ISR context - \warning -*/ -#define _SlNonOsSyncObjSignal(pSyncObj) _SlNonOsSemSet(pSyncObj,__NON_OS_SYNC_OBJ_SIGNAL_VALUE) - -/*! - \brief This function waits for a sync signal of the specific sync object - - \param pSyncObj - pointer to the sync object control block - \param Timeout - numeric value specifies the maximum number of mSec to - stay suspended while waiting for the sync signal - Currently, the simple link driver uses only two values: - - NONOS_WAIT_FOREVER - - NONOS_NO_WAIT - - \return upon successful reception of the signal within the timeout window return 0 - Otherwise, a negative value indicating the error code shall be returned - \note - \warning -*/ -#define _SlNonOsSyncObjWait(pSyncObj , Timeout) _SlNonOsSemGet(pSyncObj,__NON_OS_SYNC_OBJ_SIGNAL_VALUE,__NON_OS_SYNC_OBJ_CLEAR_VALUE,Timeout) - -/*! - \brief This function clears a sync object - - \param pSyncObj - pointer to the sync object control block - - \return upon successful clearing the function should return 0 - Otherwise, a negative value indicating the error code shall be returned - \note - \warning -*/ -#define _SlNonOsSyncObjClear(pSyncObj) _SlNonOsSemSet(pSyncObj,__NON_OS_SYNC_OBJ_CLEAR_VALUE) - -/*! - \brief This function creates a locking object. - - The locking object is used for protecting a shared resources between different - threads. - - \param pLockObj - pointer to the locking object control block - - \return upon successful creation the function should return 0 - Otherwise, a negative value indicating the error code shall be returned - \note - \warning -*/ -#define _SlNonOsLockObjCreate(pLockObj) _SlNonOsSemSet(pLockObj,__NON_OS_LOCK_OBJ_UNLOCK_VALUE) - -/*! - \brief This function deletes a locking object. - - \param pLockObj - pointer to the locking object control block - - \return upon successful deletion the function should return 0 - Otherwise, a negative value indicating the error code shall be returned - \note - \warning -*/ -#define _SlNonOsLockObjDelete(pLockObj) _SlNonOsSemSet(pLockObj,0) - -/*! - \brief This function locks a locking object. - - All other threads that call this function before this thread calls - the _SlNonOsLockObjUnlock would be suspended - - \param pLockObj - pointer to the locking object control block - \param Timeout - numeric value specifies the maximum number of mSec to - stay suspended while waiting for the locking object - Currently, the simple link driver uses only two values: - - NONOS_WAIT_FOREVER - - NONOS_NO_WAIT - - - \return upon successful reception of the locking object the function should return 0 - Otherwise, a negative value indicating the error code shall be returned - \note - \warning -*/ -#define _SlNonOsLockObjLock(pLockObj , Timeout) _SlNonOsSemGet(pLockObj,__NON_OS_LOCK_OBJ_UNLOCK_VALUE,__NON_OS_LOCK_OBJ_LOCK_VALUE,Timeout) - -/*! - \brief This function unlock a locking object. - - \param pLockObj - pointer to the locking object control block - - \return upon successful unlocking the function should return 0 - Otherwise, a negative value indicating the error code shall be returned - \note - \warning -*/ -#define _SlNonOsLockObjUnlock(pLockObj) _SlNonOsSemSet(pLockObj,__NON_OS_LOCK_OBJ_UNLOCK_VALUE) - - -/*! - \brief This function call the pEntry callback from a different context - - \param pEntry - pointer to the entry callback function - - \param pValue - pointer to any type of memory structure that would be - passed to pEntry callback from the execution thread. - - \param flags - execution flags - reserved for future usage - - \return upon successful registration of the spawn the function return 0 - (the function is not blocked till the end of the execution of the function - and could be returned before the execution is actually completed) - Otherwise, a negative value indicating the error code shall be returned - \note - \warning -*/ -_SlNonOsRetVal_t _SlNonOsSpawn(_SlSpawnEntryFunc_t pEntry , void* pValue , _u32 flags); - - -/*! - \brief This function must be called from the main loop in non-os paltforms - - \param None - - \return 0 - No more activities - 1 - Activity still in progress - \note - \warning -*/ -_SlNonOsRetVal_t _SlNonOsMainLoopTask(void); - -extern _SlNonOsRetVal_t _SlNonOsSemGet(_SlNonOsSemObj_t* pSyncObj, _SlNonOsSemObj_t WaitValue, _SlNonOsSemObj_t SetValue, _SlNonOsTime_t Timeout); -extern _SlNonOsRetVal_t _SlNonOsSemSet(_SlNonOsSemObj_t* pSemObj , _SlNonOsSemObj_t Value); -extern _SlNonOsRetVal_t _SlNonOsSpawn(_SlSpawnEntryFunc_t pEntry , void* pValue , _u32 flags); - -#if (defined(_SlSyncWaitLoopCallback)) -extern void _SlSyncWaitLoopCallback(void); -#endif - - -/***************************************************************************** - - Overwrite SimpleLink driver OS adaptation functions - - - *****************************************************************************/ - -#undef sl_SyncObjCreate -#define sl_SyncObjCreate(pSyncObj,pName) _SlNonOsSemSet(pSyncObj,__NON_OS_SYNC_OBJ_CLEAR_VALUE) - -#undef sl_SyncObjDelete -#define sl_SyncObjDelete(pSyncObj) _SlNonOsSemSet(pSyncObj,0) - -#undef sl_SyncObjSignal -#define sl_SyncObjSignal(pSyncObj) _SlNonOsSemSet(pSyncObj,__NON_OS_SYNC_OBJ_SIGNAL_VALUE) - -#undef sl_SyncObjSignalFromIRQ -#define sl_SyncObjSignalFromIRQ(pSyncObj) _SlNonOsSemSet(pSyncObj,__NON_OS_SYNC_OBJ_SIGNAL_VALUE) - -#undef sl_SyncObjWait -#define sl_SyncObjWait(pSyncObj,Timeout) _SlNonOsSemGet(pSyncObj,__NON_OS_SYNC_OBJ_SIGNAL_VALUE,__NON_OS_SYNC_OBJ_CLEAR_VALUE,Timeout) - -#undef sl_LockObjCreate -#define sl_LockObjCreate(pLockObj,pName) _SlNonOsSemSet(pLockObj,__NON_OS_LOCK_OBJ_UNLOCK_VALUE) - -#undef sl_LockObjDelete -#define sl_LockObjDelete(pLockObj) _SlNonOsSemSet(pLockObj,0) - -#undef sl_LockObjLock -#define sl_LockObjLock(pLockObj,Timeout) _SlNonOsSemGet(pLockObj,__NON_OS_LOCK_OBJ_UNLOCK_VALUE,__NON_OS_LOCK_OBJ_LOCK_VALUE,Timeout) - -#undef sl_LockObjUnlock -#define sl_LockObjUnlock(pLockObj) _SlNonOsSemSet(pLockObj,__NON_OS_LOCK_OBJ_UNLOCK_VALUE) - -#undef sl_Spawn -#define sl_Spawn(pEntry,pValue,flags) _SlNonOsSpawn(pEntry,pValue,flags) - -#undef _SlTaskEntry -#define _SlTaskEntry _SlNonOsMainLoopTask - -#endif /* !SL_PLATFORM_MULTI_THREADED */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif diff --git a/drivers/cc3100/inc/objInclusion.h b/drivers/cc3100/inc/objInclusion.h deleted file mode 100644 index cfe875e76ef..00000000000 --- a/drivers/cc3100/inc/objInclusion.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - * objInclusion.h - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - -#include - -#ifndef OBJINCLUSION_H_ -#define OBJINCLUSION_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/****************************************************************************** - - For future use - -*******************************************************************************/ - -#define __inln /* if inline functions requiered: #define __inln inline */ - -#define SL_DEVICE /* Device silo is currently always mandatory */ - - - -/****************************************************************************** - - Qualifiers for package customizations - -*******************************************************************************/ - -#if defined (SL_DEVICE) -#define __dev 1 -#else -#define __dev 0 -#endif - -#if defined (SL_DEVICE) && defined (SL_INC_EXT_API) -#define __dev__ext 1 -#else -#define __dev__ext 0 -#endif - - -#if (!defined (SL_PLATFORM_MULTI_THREADED)) || (!defined (SL_PLATFORM_EXTERNAL_SPAWN)) -#define __int__spwn 1 -#else -#define __int__spwn 0 -#endif - -#if defined (SL_INC_NET_APP_PKG) -#define __nap 1 -#else -#define __nap 0 -#endif - -#if defined (SL_INC_NET_APP_PKG) && defined (SL_INC_SOCK_CLIENT_SIDE_API) -#define __nap__clt 1 -#else -#define __nap__clt 0 -#endif - -#if defined (SL_INC_NET_APP_PKG) && defined (SL_INC_EXT_API) -#define __nap__ext 1 -#else -#define __nap__ext 0 -#endif - -#if defined (SL_INC_NET_CFG_PKG) -#define __ncg 1 -#else -#define __ncg 0 -#endif - -#if defined (SL_INC_NET_CFG_PKG) && defined (SL_INC_EXT_API) -#define __ncg__ext 1 -#else -#define __ncg__ext 0 -#endif - -#if defined (SL_INC_NVMEM_PKG) -#define __nvm 1 -#else -#define __nvm 0 -#endif - -#if defined (SL_INC_SOCKET_PKG) -#define __sck 1 -#else -#define __sck 0 -#endif - -#if defined (SL_INC_SOCKET_PKG) && defined (SL_INC_EXT_API) -#define __sck__ext 1 -#else -#define __sck__ext 0 -#endif - -#if defined (SL_INC_SOCKET_PKG) && defined (SL_INC_SOCK_SERVER_SIDE_API) -#define __sck__srv 1 -#else -#define __sck__srv 0 -#endif - -#if defined (SL_INC_SOCKET_PKG) && defined (SL_INC_SOCK_CLIENT_SIDE_API) -#define __sck__clt 1 -#else -#define __sck__clt 0 -#endif - -#if defined (SL_INC_SOCKET_PKG) && defined (SL_INC_SOCK_RECV_API) -#define __sck__rcv 1 -#else -#define __sck__rcv 0 -#endif - -#if defined (SL_INC_SOCKET_PKG) && defined (SL_INC_SOCK_SEND_API) -#define __sck__snd 1 -#else -#define __sck__snd 0 -#endif - -#if defined (SL_INC_WLAN_PKG) -#define __wln 1 -#else -#define __wln 0 -#endif - -#if defined (SL_INC_WLAN_PKG) && defined (SL_INC_EXT_API) -#define __wln__ext 1 -#else -#define __wln__ext 0 -#endif - -/* The return 1 is the function need to be included in the output */ -#define _SL_INCLUDE_FUNC(Name) (_SL_INC_##Name) - -/* Driver */ -#define _SL_INC_sl_NetAppStart __nap__ext -#define _SL_INC_sl_NetAppStop __nap__ext - -#define _SL_INC_sl_NetAppDnsGetHostByName __nap__clt - - -#define _SL_INC_sl_NetAppDnsGetHostByService __nap__ext -#define _SL_INC_sl_NetAppMDNSRegisterService __nap__ext -#define _SL_INC_sl_NetAppMDNSUnRegisterService __nap__ext -#define _SL_INC_sl_NetAppMDNSRegisterUnregisterService __nap__ext -#define _SL_INC_sl_NetAppGetServiceList __nap__ext - - -#define _SL_INC_sl_DnsGetHostByAddr __nap__ext -#define _SL_INC_sl_NetAppPingStart __nap__ext -#define _SL_INC_sl_NetAppPingReport __nap__ext -#define _SL_INC_sl_NetAppSet __nap__ext -#define _SL_INC_sl_NetAppGet __nap__ext - - -/* FS */ -#define _SL_INC_sl_FsOpen __nvm - -#define _SL_INC_sl_FsClose __nvm - -#define _SL_INC_sl_FsRead __nvm - -#define _SL_INC_sl_FsWrite __nvm - -#define _SL_INC_sl_FsGetInfo __nvm - -#define _SL_INC_sl_FsDel __nvm - -/* netcfg */ -#define _SL_INC_sl_MacAdrrSet __ncg - -#define _SL_INC_sl_MacAdrrGet __ncg - -#define _SL_INC_sl_NetCfgGet __ncg - -#define _SL_INC_sl_NetCfgSet __ncg - - -/* socket */ -#define _SL_INC_sl_Socket __sck - -#define _SL_INC_sl_Close __sck - -#define _SL_INC_sl_Accept __sck__srv - -#define _SL_INC_sl_Bind __sck - -#define _SL_INC_sl_Listen __sck__srv - -#define _SL_INC_sl_Connect __sck__clt - -#define _SL_INC_sl_Select __sck - -#define _SL_INC_sl_SetSockOpt __sck - -#define _SL_INC_sl_GetSockOpt __sck__ext - -#define _SL_INC_sl_Recv __sck__rcv - -#define _SL_INC_sl_RecvFrom __sck__rcv - -#define _SL_INC_sl_Write __sck__snd - -#define _SL_INC_sl_Send __sck__snd - -#define _SL_INC_sl_SendTo __sck__snd - -#define _SL_INC_sl_Htonl __sck - -#define _SL_INC_sl_Htons __sck - -/* wlan */ -#define _SL_INC_sl_WlanConnect __wln__ext - -#define _SL_INC_sl_WlanDisconnect __wln__ext - -#define _SL_INC_sl_WlanProfileAdd __wln__ext - -#define _SL_INC_sl_WlanProfileGet __wln__ext - -#define _SL_INC_sl_WlanProfileDel __wln__ext - -#define _SL_INC_sl_WlanPolicySet __wln__ext - -#define _SL_INC_sl_WlanPolicyGet __wln__ext - -#define _SL_INC_sl_WlanGetNetworkList __wln__ext - -#define _SL_INC_sl_WlanRxFilterAdd __wln__ext - -#define _SL_INC_sl_WlanRxFilterSet __wln__ext - -#define _SL_INC_sl_WlanRxFilterGet __wln__ext - -#define _SL_INC_sl_SmartConfigStart __wln - -#define _SL_INC_sl_SmartConfigOptSet __wln__ext - - -#define _SL_INC_sl_WlanSmartConfigStart __wln - -#define _SL_INC_sl_WlanSmartConfigStop __wln - -#define _SL_INC_sl_WlanSetMode __wln - -#define _SL_INC_sl_WlanSet __wln - -#define _SL_INC_sl_WlanGet __wln - -#define _SL_INC_sl_SmartConfigOptSet __wln__ext - -#define _SL_INC_sl_SmartConfigOptGet __wln__ext - -#define _SL_INC_sl_WlanRxStatStart __wln__ext - -#define _SL_INC_sl_WlanRxStatStop __wln__ext - -#define _SL_INC_sl_WlanRxStatGet __wln__ext - - -/* device */ -#define _SL_INC_sl_Task __int__spwn - -#define _SL_INC_sl_Start __dev - -#define _SL_INC_sl_Stop __dev - -#define _SL_INC_sl_StatusGet __dev - -#ifdef SL_IF_TYPE_UART -#define _SL_INC_sl_UartSetMode __dev__ext -#endif - -#define _SL_INC_sl_EventMaskGet __dev__ext - -#define _SL_INC_sl_EventMaskSet __dev__ext - -#define _SL_INC_sl_DevGet __dev__ext - -#define _SL_INC_sl_DevSet __dev__ext - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /*OBJINCLUSION_H_ */ diff --git a/drivers/cc3100/inc/protocol.h b/drivers/cc3100/inc/protocol.h deleted file mode 100644 index 8a1299a6ab0..00000000000 --- a/drivers/cc3100/inc/protocol.h +++ /dev/null @@ -1,1182 +0,0 @@ -/* - * protocol.h - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - -/*******************************************************************************\ -* -* FILE NAME: protocol.h -* -* DESCRIPTION: Constant and data structure definitions and function -* prototypes for the SL protocol module, which implements -* processing of SimpleLink Commands. -* -* AUTHOR: -* -\*******************************************************************************/ - -#ifndef _SL_PROTOCOL_TYPES_H_ -#define _SL_PROTOCOL_TYPES_H_ - -/**************************************************************************** -** -** User I/F pools definitions -** -****************************************************************************/ - -/**************************************************************************** -** -** Definitions for SimpleLink Commands -** -****************************************************************************/ - - -/* pattern for LE 8/16/32 or BE*/ -#define H2N_SYNC_PATTERN {0xBBDDEEFF,0x4321,0x34,0x12} -#define H2N_CNYS_PATTERN {0xBBDDEEFF,0x8765,0x78,0x56} - -#define H2N_DUMMY_PATTERN (_u32)0xFFFFFFFF -#define N2H_SYNC_PATTERN (_u32)0xABCDDCBA -#define SYNC_PATTERN_LEN (_u32)sizeof(_u32) -#define UART_SET_MODE_MAGIC_CODE (_u32)0xAA55AA55 -#define SPI_16BITS_BUG(pattern) (_u32)((_u32)pattern & (_u32)0xFFFF7FFF) -#define SPI_8BITS_BUG(pattern) (_u32)((_u32)pattern & (_u32)0xFFFFFF7F) - - - -typedef struct -{ - _u16 Opcode; - _u16 Len; -}_SlGenericHeader_t; - - -typedef struct -{ - _u32 Long; - _u16 Short; - _u8 Byte1; - _u8 Byte2; -}_SlSyncPattern_t; - -typedef _SlGenericHeader_t _SlCommandHeader_t; - -typedef struct -{ - _SlGenericHeader_t GenHeader; - _u8 TxPoolCnt; - _u8 DevStatus; - _u8 SocketTXFailure; - _u8 SocketNonBlocking; -}_SlResponseHeader_t; - -#define _SL_RESP_SPEC_HDR_SIZE (sizeof(_SlResponseHeader_t) - sizeof(_SlGenericHeader_t)) -#define _SL_RESP_HDR_SIZE sizeof(_SlResponseHeader_t) -#define _SL_CMD_HDR_SIZE sizeof(_SlCommandHeader_t) - -#define _SL_RESP_ARGS_START(_pMsg) (((_SlResponseHeader_t *)(_pMsg)) + 1) - -/* Used only in NWP! */ -typedef struct -{ - _SlCommandHeader_t sl_hdr; - _u8 func_args_start; -} T_SCMD; - - -#define WLAN_CONN_STATUS_BIT 0x01 -#define EVENTS_Q_STATUS_BIT 0x02 -#define PENDING_RCV_CMD_BIT 0x04 -#define FW_BUSY_PACKETS_BIT 0x08 - -#define INIT_STA_OK 0x11111111 -#define INIT_STA_ERR 0x22222222 -#define INIT_AP_OK 0x33333333 -#define INIT_AP_ERR 0x44444444 -#define INIT_P2P_OK 0x55555555 -#define INIT_P2P_ERR 0x66666666 - -/**************************************************************************** -** OPCODES -****************************************************************************/ -#define SL_IPV4_IPV6_OFFSET ( 9 ) -#define SL_OPCODE_IPV4 ( 0x0 << SL_IPV4_IPV6_OFFSET ) -#define SL_OPCODE_IPV6 ( 0x1 << SL_IPV4_IPV6_OFFSET ) - -#define SL_SYNC_ASYNC_OFFSET ( 10 ) -#define SL_OPCODE_SYNC (0x1 << SL_SYNC_ASYNC_OFFSET ) -#define SL_OPCODE_SILO_OFFSET ( 11 ) -#define SL_OPCODE_SILO_MASK ( 0xF << SL_OPCODE_SILO_OFFSET ) -#define SL_OPCODE_SILO_DEVICE ( 0x0 << SL_OPCODE_SILO_OFFSET ) -#define SL_OPCODE_SILO_WLAN ( 0x1 << SL_OPCODE_SILO_OFFSET ) -#define SL_OPCODE_SILO_SOCKET ( 0x2 << SL_OPCODE_SILO_OFFSET ) -#define SL_OPCODE_SILO_NETAPP ( 0x3 << SL_OPCODE_SILO_OFFSET ) -#define SL_OPCODE_SILO_NVMEM ( 0x4 << SL_OPCODE_SILO_OFFSET ) -#define SL_OPCODE_SILO_NETCFG ( 0x5 << SL_OPCODE_SILO_OFFSET ) - -#define SL_FAMILY_SHIFT (0x4) -#define SL_FLAGS_MASK (0xF) - -#define SL_OPCODE_DEVICE_INITCOMPLETE 0x0008 -#define SL_OPCODE_DEVICE_ABORT 0x000C -#define SL_OPCODE_DEVICE_STOP_COMMAND 0x8473 -#define SL_OPCODE_DEVICE_STOP_RESPONSE 0x0473 -#define SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE 0x0073 -#define SL_OPCODE_DEVICE_DEVICEASYNCDUMMY 0x0063 - -#define SL_OPCODE_DEVICE_VERSIONREADCOMMAND 0x8470 -#define SL_OPCODE_DEVICE_VERSIONREADRESPONSE 0x0470 -#define SL_OPCODE_DEVICE_DEVICEASYNCFATALERROR 0x0078 -#define SL_OPCODE_WLAN_WLANCONNECTCOMMAND 0x8C80 -#define SL_OPCODE_WLAN_WLANCONNECTRESPONSE 0x0C80 -#define SL_OPCODE_WLAN_WLANASYNCCONNECTEDRESPONSE 0x0880 -#define SL_OPCODE_WLAN_P2P_DEV_FOUND 0x0830 -#define SL_OPCODE_WLAN_CONNECTION_FAILED 0x0831 -#define SL_OPCODE_WLAN_P2P_NEG_REQ_RECEIVED 0x0832 - -#define SL_OPCODE_WLAN_WLANDISCONNECTCOMMAND 0x8C81 -#define SL_OPCODE_WLAN_WLANDISCONNECTRESPONSE 0x0C81 -#define SL_OPCODE_WLAN_WLANASYNCDISCONNECTEDRESPONSE 0x0881 -#define SL_OPCODE_WLAN_WLANCONNECTEAPCOMMAND 0x8C82 -#define SL_OPCODE_WLAN_WLANCONNECTEAPCRESPONSE 0x0C82 -#define SL_OPCODE_WLAN_PROFILEADDCOMMAND 0x8C83 -#define SL_OPCODE_WLAN_PROFILEADDRESPONSE 0x0C83 -#define SL_OPCODE_WLAN_PROFILEGETCOMMAND 0x8C84 -#define SL_OPCODE_WLAN_PROFILEGETRESPONSE 0x0C84 -#define SL_OPCODE_WLAN_PROFILEDELCOMMAND 0x8C85 -#define SL_OPCODE_WLAN_PROFILEDELRESPONSE 0x0C85 -#define SL_OPCODE_WLAN_POLICYSETCOMMAND 0x8C86 -#define SL_OPCODE_WLAN_POLICYSETRESPONSE 0x0C86 -#define SL_OPCODE_WLAN_POLICYGETCOMMAND 0x8C87 -#define SL_OPCODE_WLAN_POLICYGETRESPONSE 0x0C87 -#define SL_OPCODE_WLAN_FILTERADD 0x8C88 -#define SL_OPCODE_WLAN_FILTERADDRESPONSE 0x0C88 -#define SL_OPCODE_WLAN_FILTERGET 0x8C89 -#define SL_OPCODE_WLAN_FILTERGETRESPONSE 0x0C89 -#define SL_OPCODE_WLAN_FILTERDELETE 0x8C8A -#define SL_OPCODE_WLAN_FILTERDELETERESPOSNE 0x0C8A -#define SL_OPCODE_WLAN_WLANGETSTATUSCOMMAND 0x8C8F -#define SL_OPCODE_WLAN_WLANGETSTATUSRESPONSE 0x0C8F -#define SL_OPCODE_WLAN_STARTTXCONTINUESCOMMAND 0x8CAA -#define SL_OPCODE_WLAN_STARTTXCONTINUESRESPONSE 0x0CAA -#define SL_OPCODE_WLAN_STOPTXCONTINUESCOMMAND 0x8CAB -#define SL_OPCODE_WLAN_STOPTXCONTINUESRESPONSE 0x0CAB -#define SL_OPCODE_WLAN_STARTRXSTATCOMMAND 0x8CAC -#define SL_OPCODE_WLAN_STARTRXSTATRESPONSE 0x0CAC -#define SL_OPCODE_WLAN_STOPRXSTATCOMMAND 0x8CAD -#define SL_OPCODE_WLAN_STOPRXSTATRESPONSE 0x0CAD -#define SL_OPCODE_WLAN_GETRXSTATCOMMAND 0x8CAF -#define SL_OPCODE_WLAN_GETRXSTATRESPONSE 0x0CAF -#define SL_OPCODE_WLAN_POLICYSETCOMMANDNEW 0x8CB0 -#define SL_OPCODE_WLAN_POLICYSETRESPONSENEW 0x0CB0 -#define SL_OPCODE_WLAN_POLICYGETCOMMANDNEW 0x8CB1 -#define SL_OPCODE_WLAN_POLICYGETRESPONSENEW 0x0CB1 - -#define SL_OPCODE_WLAN_SMART_CONFIG_START_COMMAND 0x8CB2 -#define SL_OPCODE_WLAN_SMART_CONFIG_START_RESPONSE 0x0CB2 -#define SL_OPCODE_WLAN_SMART_CONFIG_START_ASYNC_RESPONSE 0x08B2 -#define SL_OPCODE_WLAN_SMART_CONFIG_STOP_COMMAND 0x8CB3 -#define SL_OPCODE_WLAN_SMART_CONFIG_STOP_RESPONSE 0x0CB3 -#define SL_OPCODE_WLAN_SMART_CONFIG_STOP_ASYNC_RESPONSE 0x08B3 -#define SL_OPCODE_WLAN_SET_MODE 0x8CB4 -#define SL_OPCODE_WLAN_SET_MODE_RESPONSE 0x0CB4 -#define SL_OPCODE_WLAN_CFG_SET 0x8CB5 -#define SL_OPCODE_WLAN_CFG_SET_RESPONSE 0x0CB5 -#define SL_OPCODE_WLAN_CFG_GET 0x8CB6 -#define SL_OPCODE_WLAN_CFG_GET_RESPONSE 0x0CB6 -#define SL_OPCODE_WLAN_STA_CONNECTED 0x082E -#define SL_OPCODE_WLAN_STA_DISCONNECTED 0x082F -#define SL_OPCODE_WLAN_EAP_PROFILEADDCOMMAND 0x8C67 -#define SL_OPCODE_WLAN_EAP_PROFILEADDCOMMAND_RESPONSE 0x0C67 - -#define SL_OPCODE_SOCKET_SOCKET 0x9401 -#define SL_OPCODE_SOCKET_SOCKETRESPONSE 0x1401 -#define SL_OPCODE_SOCKET_CLOSE 0x9402 -#define SL_OPCODE_SOCKET_CLOSERESPONSE 0x1402 -#define SL_OPCODE_SOCKET_ACCEPT 0x9403 -#define SL_OPCODE_SOCKET_ACCEPTRESPONSE 0x1403 -#define SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE 0x1003 -#define SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE_V6 0x1203 -#define SL_OPCODE_SOCKET_BIND 0x9404 -#define SL_OPCODE_SOCKET_BIND_V6 0x9604 -#define SL_OPCODE_SOCKET_BINDRESPONSE 0x1404 -#define SL_OPCODE_SOCKET_LISTEN 0x9405 -#define SL_OPCODE_SOCKET_LISTENRESPONSE 0x1405 -#define SL_OPCODE_SOCKET_CONNECT 0x9406 -#define SL_OPCODE_SOCKET_CONNECT_V6 0x9606 -#define SL_OPCODE_SOCKET_CONNECTRESPONSE 0x1406 -#define SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE 0x1006 -#define SL_OPCODE_SOCKET_SELECT 0x9407 -#define SL_OPCODE_SOCKET_SELECTRESPONSE 0x1407 -#define SL_OPCODE_SOCKET_SELECTASYNCRESPONSE 0x1007 -#define SL_OPCODE_SOCKET_SETSOCKOPT 0x9408 -#define SL_OPCODE_SOCKET_SETSOCKOPTRESPONSE 0x1408 -#define SL_OPCODE_SOCKET_GETSOCKOPT 0x9409 -#define SL_OPCODE_SOCKET_GETSOCKOPTRESPONSE 0x1409 -#define SL_OPCODE_SOCKET_RECV 0x940A -#define SL_OPCODE_SOCKET_RECVASYNCRESPONSE 0x100A -#define SL_OPCODE_SOCKET_RECVFROM 0x940B -#define SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE 0x100B -#define SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6 0x120B -#define SL_OPCODE_SOCKET_SEND 0x940C -#define SL_OPCODE_SOCKET_SENDTO 0x940D -#define SL_OPCODE_SOCKET_SENDTO_V6 0x960D -#define SL_OPCODE_SOCKET_TXFAILEDASYNCRESPONSE 0x100E -#define SL_OPCODE_SOCKET_SOCKETASYNCEVENT 0x100F -#define SL_OPCODE_NETAPP_START_COMMAND 0x9C0A -#define SL_OPCODE_NETAPP_START_RESPONSE 0x1C0A -#define SL_OPCODE_NETAPP_NETAPPSTARTRESPONSE 0x1C0A -#define SL_OPCODE_NETAPP_STOP_COMMAND 0x9C61 -#define SL_OPCODE_NETAPP_STOP_RESPONSE 0x1C61 -#define SL_OPCODE_NETAPP_NETAPPSET 0x9C0B -#define SL_OPCODE_NETAPP_NETAPPSETRESPONSE 0x1C0B -#define SL_OPCODE_NETAPP_NETAPPGET 0x9C27 -#define SL_OPCODE_NETAPP_NETAPPGETRESPONSE 0x1C27 -#define SL_OPCODE_NETAPP_DNSGETHOSTBYNAME 0x9C20 -#define SL_OPCODE_NETAPP_DNSGETHOSTBYNAMERESPONSE 0x1C20 -#define SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE 0x1820 -#define SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE_V6 0x1A20 -#define SL_OPCODE_NETAPP_NETAPP_MDNS_LOOKUP_SERVICE 0x9C71 -#define SL_OPCODE_NETAPP_NETAPP_MDNS_LOOKUP_SERVICE_RESPONSE 0x1C72 -#define SL_OPCODE_NETAPP_MDNSREGISTERSERVICE 0x9C34 -#define SL_OPCODE_NETAPP_MDNSREGISTERSERVICERESPONSE 0x1C34 -#define SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICE 0x9C35 -#define SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICERESPONSE 0x1C35 -#define SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE 0x1835 -#define SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE_V6 0x1A35 -#define SL_OPCODE_NETAPP_DNSGETHOSTBYADDR 0x9C26 -#define SL_OPCODE_NETAPP_DNSGETHOSTBYADDR_V6 0x9E26 -#define SL_OPCODE_NETAPP_DNSGETHOSTBYADDRRESPONSE 0x1C26 -#define SL_OPCODE_NETAPP_DNSGETHOSTBYADDRASYNCRESPONSE 0x1826 -#define SL_OPCODE_NETAPP_PINGSTART 0x9C21 -#define SL_OPCODE_NETAPP_PINGSTART_V6 0x9E21 -#define SL_OPCODE_NETAPP_PINGSTARTRESPONSE 0x1C21 -#define SL_OPCODE_NETAPP_PINGREPORTREQUEST 0x9C22 -#define SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE 0x1822 -#define SL_OPCODE_NETAPP_PINGSTOP 0x9C23 -#define SL_OPCODE_NETAPP_PINGSTOPRESPONSE 0x1C23 -#define SL_OPCODE_NETAPP_ARPFLUSH 0x9C24 -#define SL_OPCODE_NETAPP_ARPFLUSHRESPONSE 0x1C24 -#define SL_OPCODE_NETAPP_IPACQUIRED 0x1825 -#define SL_OPCODE_NETAPP_IPV4_LOST 0x1832 -#define SL_OPCODE_NETAPP_DHCP_IPV4_ACQUIRE_TIMEOUT 0x1833 -#define SL_OPCODE_NETAPP_IPACQUIRED_V6 0x1A25 -#define SL_OPCODE_NETAPP_IPERFSTARTCOMMAND 0x9C28 -#define SL_OPCODE_NETAPP_IPERFSTARTRESPONSE 0x1C28 -#define SL_OPCODE_NETAPP_IPERFSTOPCOMMAND 0x9C29 -#define SL_OPCODE_NETAPP_IPERFSTOPRESPONSE 0x1C29 -#define SL_OPCODE_NETAPP_CTESTSTARTCOMMAND 0x9C2A -#define SL_OPCODE_NETAPP_CTESTSTARTRESPONSE 0x1C2A -#define SL_OPCODE_NETAPP_CTESTASYNCRESPONSE 0x182A -#define SL_OPCODE_NETAPP_CTESTSTOPCOMMAND 0x9C2B -#define SL_OPCODE_NETAPP_CTESTSTOPRESPONSE 0x1C2B -#define SL_OPCODE_NETAPP_IP_LEASED 0x182C -#define SL_OPCODE_NETAPP_IP_RELEASED 0x182D -#define SL_OPCODE_NETAPP_HTTPGETTOKENVALUE 0x182E -#define SL_OPCODE_NETAPP_HTTPSENDTOKENVALUE 0x9C2F -#define SL_OPCODE_NETAPP_HTTPPOSTTOKENVALUE 0x1830 -#define SL_OPCODE_NVMEM_FILEOPEN 0xA43C -#define SL_OPCODE_NVMEM_FILEOPENRESPONSE 0x243C -#define SL_OPCODE_NVMEM_FILECLOSE 0xA43D -#define SL_OPCODE_NVMEM_FILECLOSERESPONSE 0x243D -#define SL_OPCODE_NVMEM_FILEREADCOMMAND 0xA440 -#define SL_OPCODE_NVMEM_FILEREADRESPONSE 0x2440 -#define SL_OPCODE_NVMEM_FILEWRITECOMMAND 0xA441 -#define SL_OPCODE_NVMEM_FILEWRITERESPONSE 0x2441 -#define SL_OPCODE_NVMEM_FILEGETINFOCOMMAND 0xA442 -#define SL_OPCODE_NVMEM_FILEGETINFORESPONSE 0x2442 -#define SL_OPCODE_NVMEM_FILEDELCOMMAND 0xA443 -#define SL_OPCODE_NVMEM_FILEDELRESPONSE 0x2443 -#define SL_OPCODE_NVMEM_NVMEMFORMATCOMMAND 0xA444 -#define SL_OPCODE_NVMEM_NVMEMFORMATRESPONSE 0x2444 - -#define SL_OPCODE_DEVICE_SETDEBUGLEVELCOMMAND 0x846A -#define SL_OPCODE_DEVICE_SETDEBUGLEVELRESPONSE 0x046A - -#define SL_OPCODE_DEVICE_NETCFG_SET_COMMAND 0x8432 -#define SL_OPCODE_DEVICE_NETCFG_SET_RESPONSE 0x0432 -#define SL_OPCODE_DEVICE_NETCFG_GET_COMMAND 0x8433 -#define SL_OPCODE_DEVICE_NETCFG_GET_RESPONSE 0x0433 -/* */ -#define SL_OPCODE_DEVICE_SETUARTMODECOMMAND 0x846B -#define SL_OPCODE_DEVICE_SETUARTMODERESPONSE 0x046B -#define SL_OPCODE_DEVICE_SSISIZESETCOMMAND 0x846B -#define SL_OPCODE_DEVICE_SSISIZESETRESPONSE 0x046B - -/* */ -#define SL_OPCODE_DEVICE_EVENTMASKSET 0x8464 -#define SL_OPCODE_DEVICE_EVENTMASKSETRESPONSE 0x0464 -#define SL_OPCODE_DEVICE_EVENTMASKGET 0x8465 -#define SL_OPCODE_DEVICE_EVENTMASKGETRESPONSE 0x0465 - -#define SL_OPCODE_DEVICE_DEVICEGET 0x8466 -#define SL_OPCODE_DEVICE_DEVICEGETRESPONSE 0x0466 -#define SL_OPCODE_DEVICE_DEVICESET 0x84B7 -#define SL_OPCODE_DEVICE_DEVICESETRESPONSE 0x04B7 - -#define SL_OPCODE_WLAN_SCANRESULTSGETCOMMAND 0x8C8C -#define SL_OPCODE_WLAN_SCANRESULTSGETRESPONSE 0x0C8C -#define SL_OPCODE_WLAN_SMARTCONFIGOPTSET 0x8C8D -#define SL_OPCODE_WLAN_SMARTCONFIGOPTSETRESPONSE 0x0C8D -#define SL_OPCODE_WLAN_SMARTCONFIGOPTGET 0x8C8E -#define SL_OPCODE_WLAN_SMARTCONFIGOPTGETRESPONSE 0x0C8E - - -/* Rx Filters opcodes */ -#define SL_OPCODE_WLAN_WLANRXFILTERADDCOMMAND 0x8C6C -#define SL_OPCODE_WLAN_WLANRXFILTERADDRESPONSE 0x0C6C -#define SL_OPCODE_WLAN_WLANRXFILTERSETCOMMAND 0x8C6D -#define SL_OPCODE_WLAN_WLANRXFILTERSETRESPONSE 0x0C6D -#define SL_OPCODE_WLAN_WLANRXFILTERGETSTATISTICSINFOCOMMAND 0x8C6E -#define SL_OPCODE_WLAN_WLANRXFILTERGETSTATISTICSINFORESPONSE 0x0C6E -#define SL_OPCODE_WLAN_WLANRXFILTERGETCOMMAND 0x8C6F -#define SL_OPCODE_WLAN_WLANRXFILTERGETRESPONSE 0x0C6F -#define SL_OPCODE_WLAN_WLANRXFILTERGETINFO 0x8C70 -#define SL_OPCODE_WLAN_WLANRXFILTERGETINFORESPONSE 0x0C70 - - -/******************************************************************************************/ -/* Device structs */ -/******************************************************************************************/ -typedef _u32 InitStatus_t; - - -typedef struct -{ - _i32 Status; -}InitComplete_t; - -typedef struct -{ - _i16 status; - _u16 padding; - -}_BasicResponse_t; - -typedef struct -{ - _u16 Timeout; - _u16 padding; -}_DevStopCommand_t; - -typedef struct -{ - _u32 group; - _u32 mask; -}_DevMaskEventSetCommand_t; - -typedef _BasicResponse_t _DevMaskEventSetResponse_t; - - -typedef struct -{ - _u32 group; -}_DevMaskEventGetCommand_t; - - -typedef struct -{ - _u32 group; - _u32 mask; -}_DevMaskEventGetResponse_t; - - -typedef struct -{ - _u32 group; -}_DevStatusGetCommand_t; - - -typedef struct -{ - _u32 group; - _u32 status; -}_DevStatusGetResponse_t; - -typedef struct -{ - _u32 ChipId; - _u32 FwVersion[4]; - _u8 PhyVersion[4]; -}_Device_VersionReadResponsePart_t; - -typedef struct -{ - _Device_VersionReadResponsePart_t part; - _u32 NwpVersion[4]; - _u16 RomVersion; - _u16 Padding; -}_Device_VersionReadResponseFull_t; - - -typedef struct -{ - _u32 BaudRate; - _u8 FlowControlEnable; -}_DevUartSetModeCommand_t; - -typedef _BasicResponse_t _DevUartSetModeResponse_t; - -/******************************************************/ - -typedef struct -{ - _u8 SsiSizeInBytes; - _u8 Padding[3]; -}_StellarisSsiSizeSet_t; - -/*****************************************************************************************/ -/* WLAN structs */ -/*****************************************************************************************/ -#define MAXIMAL_PASSWORD_LENGTH (64) - -typedef struct{ - _u8 SecType; - _u8 SsidLen; - _u8 Bssid[6]; - _u8 PasswordLen; -}_WlanConnectCommon_t; - -#define SSID_STRING(pCmd) (_i8 *)((_WlanConnectCommon_t *)(pCmd) + 1) -#define PASSWORD_STRING(pCmd) (SSID_STRING(pCmd) + ((_WlanConnectCommon_t *)(pCmd))->SsidLen) - -typedef struct{ - _WlanConnectCommon_t Common; - _u8 UserLen; - _u8 AnonUserLen; - _u8 CertIndex; - _u32 EapBitmask; -}_WlanConnectEapCommand_t; - -#define EAP_SSID_STRING(pCmd) (_i8 *)((_WlanConnectEapCommand_t *)(pCmd) + 1) -#define EAP_PASSWORD_STRING(pCmd) (EAP_SSID_STRING(pCmd) + ((_WlanConnectEapCommand_t *)(pCmd))->Common.SsidLen) -#define EAP_USER_STRING(pCmd) (EAP_PASSWORD_STRING(pCmd) + ((_WlanConnectEapCommand_t *)(pCmd))->Common.PasswordLen) -#define EAP_ANON_USER_STRING(pCmd) (EAP_USER_STRING(pCmd) + ((_WlanConnectEapCommand_t *)(pCmd))->UserLen) - - -typedef struct -{ - _u8 PolicyType; - _u8 Padding; - _u8 PolicyOption; - _u8 PolicyOptionLen; -}_WlanPoliciySetGet_t; - - -typedef struct{ - _u32 minDwellTime; - _u32 maxDwellTime; - _u32 numProbeResponse; - _u32 G_Channels_mask; - _i32 rssiThershold; - _i32 snrThershold; - _i32 defaultTXPower; - _u16 intervalList[16]; -}_WlanScanParamSetCommand_t; - - -typedef struct{ - _i8 SecType; - _u8 SsidLen; - _u8 Priority; - _u8 Bssid[6]; - _u8 PasswordLen; - _u8 WepKeyId; -}_WlanAddGetProfile_t; - - -typedef struct{ - _WlanAddGetProfile_t Common; - _u8 UserLen; - _u8 AnonUserLen; - _u8 CertIndex; - _u16 padding; - _u32 EapBitmask; -}_WlanAddGetEapProfile_t; - - - - -#define PROFILE_SSID_STRING(pCmd) ((_i8 *)((_WlanAddGetProfile_t *)(pCmd) + 1)) -#define PROFILE_PASSWORD_STRING(pCmd) (PROFILE_SSID_STRING(pCmd) + ((_WlanAddGetProfile_t *)(pCmd))->SsidLen) - -#define EAP_PROFILE_SSID_STRING(pCmd) (_i8 *)((_WlanAddGetEapProfile_t *)(pCmd) + 1) -#define EAP_PROFILE_PASSWORD_STRING(pCmd) (EAP_PROFILE_SSID_STRING(pCmd) + ((_WlanAddGetEapProfile_t *)(pCmd))->Common.SsidLen) -#define EAP_PROFILE_USER_STRING(pCmd) (EAP_PROFILE_PASSWORD_STRING(pCmd) + ((_WlanAddGetEapProfile_t *)(pCmd))->Common.PasswordLen) -#define EAP_PROFILE_ANON_USER_STRING(pCmd) (EAP_PROFILE_USER_STRING(pCmd) + ((_WlanAddGetEapProfile_t *)(pCmd))->UserLen) - - - -typedef struct -{ - _u8 index; - _u8 padding[3]; -}_WlanProfileDelGetCommand_t; - -typedef _BasicResponse_t _WlanGetNetworkListResponse_t; - -typedef struct -{ - _u8 index; - _u8 count; - _i8 padding[2]; -}_WlanGetNetworkListCommand_t; - - - - -typedef struct -{ - _u32 groupIdBitmask; - _u8 cipher; - _u8 publicKeyLen; - _u8 group1KeyLen; - _u8 group2KeyLen; -}_WlanSmartConfigStartCommand_t; - -#define SMART_CONFIG_START_PUBLIC_KEY_STRING(pCmd) ((_i8 *)((_WlanSmartConfigStartCommand_t *)(pCmd) + 1)) -#define SMART_CONFIG_START_GROUP1_KEY_STRING(pCmd) ((_i8 *) (SMART_CONFIG_START_PUBLIC_KEY_STRING(pCmd) + ((_WlanSmartConfigStartCommand_t *)(pCmd))->publicKeyLen)) -#define SMART_CONFIG_START_GROUP2_KEY_STRING(pCmd) ((_i8 *) (SMART_CONFIG_START_GROUP1_KEY_STRING(pCmd) + ((_WlanSmartConfigStartCommand_t *)(pCmd))->group1KeyLen)) - - - -typedef struct -{ - _u8 mode; - _u8 padding[3]; -}_WlanSetMode_t; - - - - -typedef struct -{ - _u16 Status; - _u16 ConfigId; - _u16 ConfigOpt; - _u16 ConfigLen; -}_WlanCfgSetGet_t; - - -/* ******************************************************************************/ -/* RX filters - Start */ -/* ******************************************************************************/ -/* -- 80 bytes */ -typedef struct _WlanRxFilterAddCommand_t -{ - /* -- 1 byte */ - SlrxFilterRuleType_t RuleType; - /* -- 1 byte */ - SlrxFilterFlags_t FilterFlags; - /* -- 1 byte */ - SlrxFilterID_t FilterId; - /* -- 1 byte */ - _u8 Padding; - /* -- 56 byte */ - SlrxFilterRule_t Rule; - /* -- 12 byte ( 3 padding ) */ - SlrxFilterTrigger_t Trigger; - /* -- 8 byte */ - SlrxFilterAction_t Action; -}_WlanRxFilterAddCommand_t; - - - -/* -- 4 bytes */ -typedef struct l_WlanRxFilterAddCommandReponse_t -{ - /* -- 1 byte */ - SlrxFilterID_t FilterId; - /* -- 1 Byte */ - _u8 Status; - /* -- 2 byte */ - _u8 Padding[2]; - -}_WlanRxFilterAddCommandReponse_t; - - - -/* - * \struct _WlanRxFilterSetCommand_t - */ -typedef struct _WlanRxFilterSetCommand_t -{ - _u16 InputBufferLength; - /* 1 byte */ - SLrxFilterOperation_t RxFilterOperation; - _u8 Padding[1]; -}_WlanRxFilterSetCommand_t; - -/** - * \struct _WlanRxFilterSetCommandReponse_t - */ -typedef struct _WlanRxFilterSetCommandReponse_t -{ - /* 1 byte */ - _u8 Status; - /* 3 bytes */ - _u8 Padding[3]; - -}_WlanRxFilterSetCommandReponse_t; - -/** - * \struct _WlanRxFilterGetCommand_t - */ -typedef struct _WlanRxFilterGetCommand_t -{ - _u16 OutputBufferLength; - /* 1 byte */ - SLrxFilterOperation_t RxFilterOperation; - _u8 Padding[1]; -}_WlanRxFilterGetCommand_t; - -/** - * \struct _WlanRxFilterGetCommandReponse_t - */ -typedef struct _WlanRxFilterGetCommandReponse_t -{ - /* 1 byte */ - _u8 Status; - /* 1 bytes */ - _u8 Padding; - /* 2 byte */ - _u16 OutputBufferLength; - -}_WlanRxFilterGetCommandReponse_t; - - - -/* ******************************************************************************/ -/* RX filters -- End */ -/* ******************************************************************************/ - -typedef struct -{ - _u16 status; - _u8 WlanRole; /* 0 = station, 2 = AP */ - _u8 Ipv6Enabled; - _u8 Ipv6DhcpEnabled; - - _u32 ipV6Global[4]; - _u32 ipV6Local[4]; - _u32 ipV6DnsServer[4]; - _u8 Ipv6DhcpState; - -}_NetappIpV6configRetArgs_t; - - -typedef struct -{ - _u8 ipV4[4]; - _u8 ipV4Mask[4]; - _u8 ipV4Gateway[4]; - _u8 ipV4DnsServer[4]; - _u8 ipV4Start[4]; - _u8 ipV4End[4]; -}_NetCfgIpV4AP_Args_t; - - - -typedef struct -{ - _u16 status; - _u8 MacAddr[6]; -} _MAC_Address_SetGet_t; - - -typedef struct -{ - _u16 Status; - _u16 ConfigId; - _u16 ConfigOpt; - _u16 ConfigLen; -}_NetCfgSetGet_t; - -typedef struct -{ - _u16 Status; - _u16 DeviceSetId; - _u16 Option; - _u16 ConfigLen; -}_DeviceSetGet_t; - - - - -/******************************************************************************************/ -/* Socket structs */ -/******************************************************************************************/ - -typedef struct -{ - _u8 Domain; - _u8 Type; - _u8 Protocol; - _u8 Padding; -}_SocketCommand_t; - - -typedef struct -{ - _i16 statusOrLen; - _u8 sd; - _u8 padding; -}_SocketResponse_t; - -typedef struct -{ - _u8 sd; - _u8 family; - _u8 padding1; - _u8 padding2; -}_AcceptCommand_t; - - -typedef struct -{ - _i16 statusOrLen; - _u8 sd; - _u8 family; - _u16 port; - _u16 paddingOrAddr; - _u32 address; -}_SocketAddrAsyncIPv4Response_t; - -typedef struct -{ - _i16 statusOrLen; - _u8 sd; - _u8 family; - _u16 port; - _u8 address[6]; -}_SocketAddrAsyncIPv6EUI48Response_t; -typedef struct -{ - _i16 statusOrLen; - _u8 sd; - _u8 family; - _u16 port; - _u16 paddingOrAddr; - _u32 address[4]; -}_SocketAddrAsyncIPv6Response_t; - - -typedef struct -{ - _i16 lenOrPadding; - _u8 sd; - _u8 FamilyAndFlags; - _u16 port; - _u16 paddingOrAddr; - _u32 address; -}_SocketAddrIPv4Command_t; - -typedef struct -{ - _i16 lenOrPadding; - _u8 sd; - _u8 FamilyAndFlags; - _u16 port; - _u8 address[6]; -}_SocketAddrIPv6EUI48Command_t; -typedef struct -{ - _i16 lenOrPadding; - _u8 sd; - _u8 FamilyAndFlags; - _u16 port; - _u16 paddingOrAddr; - _u32 address[4]; -}_SocketAddrIPv6Command_t; - -typedef union { - _SocketAddrIPv4Command_t IpV4; - _SocketAddrIPv6EUI48Command_t IpV6EUI48; -#ifdef SL_SUPPORT_IPV6 - _SocketAddrIPv6Command_t IpV6; -#endif -} _SocketAddrCommand_u; - -typedef union { - _SocketAddrAsyncIPv4Response_t IpV4; - _SocketAddrAsyncIPv6EUI48Response_t IpV6EUI48; -#ifdef SL_SUPPORT_IPV6 - _SocketAddrAsyncIPv6Response_t IpV6; -#endif -} _SocketAddrResponse_u; - -typedef struct -{ - _u8 sd; - _u8 backlog; - _u8 padding1; - _u8 padding2; -}_ListenCommand_t; - -typedef struct -{ - _u8 sd; - _u8 padding0; - _u8 padding1; - _u8 padding2; -}_CloseCommand_t; - - -typedef struct -{ - _u8 nfds; - _u8 readFdsCount; - _u8 writeFdsCount; - _u8 padding; - _u16 readFds; - _u16 writeFds; - _u16 tv_usec; - _u16 tv_sec; -}_SelectCommand_t; - - -typedef struct -{ - _u16 status; - _u8 readFdsCount; - _u8 writeFdsCount; - _u16 readFds; - _u16 writeFds; -}_SelectAsyncResponse_t; - -typedef struct -{ - _u8 sd; - _u8 level; - _u8 optionName; - _u8 optionLen; -}_setSockOptCommand_t; - -typedef struct -{ - _u8 sd; - _u8 level; - _u8 optionName; - _u8 optionLen; -}_getSockOptCommand_t; - -typedef struct -{ - _i16 status; - _u8 sd; - _u8 optionLen; -}_getSockOptResponse_t; - - -typedef struct -{ - _u16 StatusOrLen; - _u8 sd; - _u8 FamilyAndFlags; -}_sendRecvCommand_t; - -/***************************************************************************************** -* NETAPP structs -******************************************************************************************/ - - -typedef _BasicResponse_t _NetAppStartStopResponse_t; - -typedef struct -{ - _u32 appId; -}_NetAppStartStopCommand_t; - -typedef struct -{ - _u16 Status; - _u16 AppId; - _u16 ConfigOpt; - _u16 ConfigLen; -}_NetAppSetGet_t; -typedef struct -{ - _u16 port_number; -} _NetAppHttpServerGetSet_port_num_t; - -typedef struct -{ - _u8 auth_enable; -}_NetAppHttpServerGetSet_auth_enable_t; - -typedef struct _sl_NetAppHttpServerGetToken_t -{ - _u8 token_name_len; - _u8 padd1; - _u16 padd2; -}sl_NetAppHttpServerGetToken_t; - -typedef struct _sl_NetAppHttpServerSendToken_t -{ - _u8 token_value_len; - _u8 token_name_len; - _u8 token_name[MAX_TOKEN_NAME_LEN]; - _u16 padd; -}sl_NetAppHttpServerSendToken_t; - -typedef struct _sl_NetAppHttpServerPostToken_t -{ - _u8 post_action_len; - _u8 token_name_len; - _u8 token_value_len; - _u8 padding; -}sl_NetAppHttpServerPostToken_t; - - -typedef struct -{ - _u16 Len; - _u8 family; - _u8 padding; -}_GetHostByNameCommand_t; - -typedef struct -{ - _u16 status; - _u16 padding; - _u32 ip0; - _u32 ip1; - _u32 ip2; - _u32 ip3; -}_GetHostByNameIPv6AsyncResponse_t; - -typedef struct -{ - _u16 status; - _u8 padding1; - _u8 padding2; - _u32 ip0; -}_GetHostByNameIPv4AsyncResponse_t; - - - - -typedef enum -{ - CTST_BSD_UDP_TX, - CTST_BSD_UDP_RX, - CTST_BSD_TCP_TX, - CTST_BSD_TCP_RX, - CTST_BSD_TCP_SERVER_BI_DIR, - CTST_BSD_TCP_CLIENT_BI_DIR, - CTST_BSD_UDP_BI_DIR, - CTST_BSD_RAW_TX, - CTST_BSD_RAW_RX, - CTST_BSD_RAW_BI_DIR, - CTST_BSD_SECURED_TCP_TX, - CTST_BSD_SECURED_TCP_RX, - CTST_BSD_SECURED_TCP_SERVER_BI_DIR, - CTST_BSD_SECURED_TCP_CLIENT_BI_DIR - }CommTest_e; - -typedef struct _sl_protocol_CtestStartCommand_t -{ - _u32 Test; - _u16 DestPort; - _u16 SrcPort; - _u32 DestAddr[4]; - _u32 PayloadSize; - _u32 timeout; - _u32 csEnabled; - _u32 secure; - _u32 rawProtocol; - _u8 reserved1[4]; -}_CtestStartCommand_t; - -typedef struct -{ - _u8 test; - _u8 socket; - _i16 status; - _u32 startTime; - _u32 endTime; - _u16 txKbitsSec; - _u16 rxKbitsSec; - _u32 outOfOrderPackets; - _u32 missedPackets; - _i16 token; -}_CtestAsyncResponse_t; - -typedef struct -{ - _u32 pingIntervalTime; - _u16 PingSize; - _u16 pingRequestTimeout; - _u32 totalNumberOfAttempts; - _u32 flags; - _u32 ip0; - _u32 ip1OrPaadding; - _u32 ip2OrPaadding; - _u32 ip3OrPaadding; -}_PingStartCommand_t; - -typedef struct -{ - _u16 status; - _u16 rttMin; - _u16 rttMax; - _u16 rttAvg; - _u32 numSuccsessPings; - _u32 numSendsPings; - _u32 testTime; -}_PingReportResponse_t; - - -typedef struct -{ - _u32 ip; - _u32 gateway; - _u32 dns; -}_IpV4AcquiredAsync_t; - - -typedef enum -{ - ACQUIRED_IPV6_LOCAL = 1, - ACQUIRED_IPV6_GLOBAL -}IpV6AcquiredType_e; - - -typedef struct -{ - _u32 type; - _u32 ip[4]; - _u32 gateway[4]; - _u32 dns[4]; -}_IpV6AcquiredAsync_t; - - -typedef union -{ - _SocketCommand_t EventMask; - _sendRecvCommand_t DeviceInit; -}_device_commands_t; - -/***************************************************************************************** -* FS structs -******************************************************************************************/ - -typedef struct -{ - _u32 FileHandle; - _u32 Offset; - _u16 Len; - _u16 Padding; -}_FsReadCommand_t; - -typedef struct -{ - _u32 Mode; - _u32 Token; -}_FsOpenCommand_t; - -typedef struct -{ - _u32 FileHandle; - _u32 Token; -}_FsOpenResponse_t; - - -typedef struct -{ - _u32 FileHandle; - _u32 CertificFileNameLength; - _u32 SignatureLen; -}_FsCloseCommand_t; - - -typedef _BasicResponse_t _FsReadResponse_t; -typedef _BasicResponse_t _FsDeleteResponse_t; -typedef _BasicResponse_t _FsCloseResponse_t; - -typedef struct -{ - _u16 Status; - _u16 flags; - _u32 FileLen; - _u32 AllocatedLen; - _u32 Token[4]; -}_FsGetInfoResponse_t; - -typedef struct -{ - _u8 DeviceID; - _u8 Padding[3]; -}_FsFormatCommand_t; - -typedef _BasicResponse_t _FsFormatResponse_t; - -typedef struct -{ - _u32 Token; -}_FsDeleteCommand_t; - -typedef _FsDeleteCommand_t _FsGetInfoCommand_t; - -typedef struct -{ - _u32 FileHandle; - _u32 Offset; - _u16 Len; - _u16 Padding; -}_FsWriteCommand_t; - -typedef _BasicResponse_t _FsWriteResponse_t; - - - -/* TODO: Set MAx Async Payload length depending on flavor (Tiny, Small, etc.) */ - - -#ifdef SL_TINY_EXT -#define SL_ASYNC_MAX_PAYLOAD_LEN 120 /* size must be aligned to 4 */ -#else -#define SL_ASYNC_MAX_PAYLOAD_LEN 160 /* size must be aligned to 4 */ -#endif - -#define SL_ASYNC_MAX_MSG_LEN (_SL_RESP_HDR_SIZE + SL_ASYNC_MAX_PAYLOAD_LEN) - -#define RECV_ARGS_SIZE (sizeof(_SocketResponse_t)) -#define RECVFROM_IPV4_ARGS_SIZE (sizeof(_SocketAddrAsyncIPv4Response_t)) -#define RECVFROM_IPV6_ARGS_SIZE (sizeof(_SocketAddrAsyncIPv6Response_t)) - -#define SL_IPV4_ADDRESS_SIZE (sizeof(_u32)) -#define SL_IPV6_ADDRESS_SIZE (4 * sizeof(_u32)) - -#endif /* _SL_PROTOCOL_TYPES_H_ */ diff --git a/drivers/cc3100/inc/simplelink.h b/drivers/cc3100/inc/simplelink.h deleted file mode 100644 index 19ca17f0c76..00000000000 --- a/drivers/cc3100/inc/simplelink.h +++ /dev/null @@ -1,948 +0,0 @@ -/* - * simplelink.h - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - - -/*! - \mainpage SimpleLink Driver - - \section intro_sec Introduction - - The SimpleLink CC31xx/CC2xx family allows to add Wi-Fi and networking capabilities - to low-cost embedded products without having prior Wi-Fi, RF or networking expertise. - The CC31xx/CC32xx is an ideal solution for microcontroller-based sensor and control - applications such as home appliances, home automation and smart metering. - The CC31xx/CC32xx has integrated a comprehensive TCP/IP network stack, Wi-Fi driver and - security supplicant leading to easier portability to microcontrollers, to an - ultra-low memory footprint, all without compromising the capabilities and robustness - of the final application. - - - - \section modules_sec Module Names - To make it simple, TI's SimpleLink CC31xx/CC32xx platform capabilities were divided into modules by topic (Silo). - These capabilities range from basic device management through wireless - network configuration, standard BSD socket and much more. - Listed below are the various modules in the SimpleLink CC31xx/CC32xx driver: - -# \ref device - controls the behaviour of the CC31xx/CC32xx device (start/stop, events masking and obtaining specific device status) - -# \ref wlan - controls the use of the WiFi WLAN module including: - - Connection features, such as: profiles, policies, SmartConfig� - - Advanced WLAN features, such as: scans, rx filters and rx statistics collection - -# \ref socket - controls standard client/server sockets programming options and capabilities - -# \ref netapp - activates networking applications, such as: HTTP Server, DHCP Server, Ping, DNS and mDNS. - -# \ref netcfg - controls the configuration of the device addresses (i.e. IP and MAC addresses) - -# \ref FileSystem - provides file system capabilities to TI's CC31XX that can be used by both the CC31XX device and the user. - - - \section proting_sec Porting Guide - - The porting of the SimpleLink driver to any new platform is based on few simple steps. - This guide takes you through this process step by step. Please follow the instructions - carefully to avoid any problems during this process and to enable efficient and proper - work with the device. - Please notice that all modifications and porting adjustments of the driver should be - made in the user.h header file only. - Keep making any of the changes only in this file will ensure smoothly transaction to - new versions of the driver at the future! - - - \subsection porting_step1 Step 1 - Create your own user.h file - - The first step is to create a user.h file that will include your configurations and - adjustments. You can use the empty template provided as part of this driver or - you can choose to base your file on file from one of the wide range of examples - applications provided by Texas Instruments - - - \subsection porting_step2 Step 2 - Select the capabilities set required for your application - - Texas Instruments made a lot of efforts to build set of predefined capability sets that would - fit most of the target application. - It is recommended to try and choose one of this predefined capabilities set before going to - build your own customized set. If you find compatible set you can skip the rest of this step. - - The available sets are: - -# SL_TINY - Compatible to be used on platforms with very limited resources. Provides - the best in class foot print in terms of Code and Data consumption. - -# SL_SMALL - Compatible to most common networking applications. Provide the most - common APIs with decent balance between code size, data size, functionality - and performances - -# SL_FULL - Provide access to all SimpleLink functionalities - - - \subsection porting_step3 Step 3 - Bind the device enable/disable output line - - The enable/disable line (nHib) provide mechanism to enter the device into the least current - consumption mode. This mode could be used when no traffic is required (tx/rx). - when this line is not connected to any IO of the host this define should be left empty. - Not connecting this line results in ability to start the driver only once. - - - \subsection porting_step4 Step 4 - Writing your interface communication driver - - The SimpleLink device support several standard communication protocol among SPI and - UART. Depending on your needs and your hardware design, you should choose the - communication channel type. - The interface for this communication channel should include 4 simple access functions: - -# open - -# close - -# read - -# write - - The way this driver would be implemented is directly effecting the efficiency and - the performances of the SimpleLink device on this platform. - If your system has DMA you should consider to use it in order to increase the utilization - of the communication channel - If you have enough memory resources you should consider using a buffer to increase the - efficiency of the write operations. - - - \subsection porting_step5 Step 5 - Choose your memory management model - - The SimpleLink driver support two memory models: - -# Static (default) - -# Dynamic - - If you choose to work in dynamic model you will have to provide alloc and free functions - to be used by the Simple Link driver otherwise nothing need to be done. - - - \subsection porting_step6 Step 6 - OS adaptation - - The SimpleLink driver could run on two kind of platforms: - -# Non-Os / Single Threaded (default) - -# Multi-Threaded - - If you choose to work in multi-threaded environment under operating system you will have to - provide some basic adaptation routines to allow the driver to protect access to resources - for different threads (locking object) and to allow synchronization between threads (sync objects). - In additional the driver support running without dedicated thread allocated solely to the simple - link driver. If you choose to work in this mode, you should also supply a spawn method that - will enable to run function on a temporary context. - - - \subsection porting_step7 Step 7 - Set your asynchronous event handlers routines - - The SimpleLink device generate asynchronous events in several situations. - These asynchronous events could be masked. - In order to catch these events you have to provide handler routines. - Please notice that if you not provide a handler routine and the event is received, - the driver will drop this event without any indication of this drop. - - - \subsection porting_step8 Step 8 - Run diagnostic tools to validate the correctness of your porting - - The driver is delivered with some porting diagnostic tools to simplify the porting validation process - and to reduce issues latter. It is very important to follow carefully this process. - - The diagnostic process include: - -# Validating Interface Communication Driver - -# Validating OS adaptation layer - -# Validating HW integrity - -# Validating basic work with the device - - - \section sw_license License - - * - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - - - -#ifndef __SIMPLELINK_H__ -#define __SIMPLELINK_H__ - -#include "user.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - - -/*! \attention Async event activation notes - Function prototypes for event callback handlers - Event handler function names should be defined in the user.h file - e.g. - "#define sl_WlanEvtHdlr SLWlanEventHandler" - Indicates all WLAN events are handled by User func "SLWlanEventHandler" - Important notes: - 1. Event handlers cannot activate another SimpleLink API from the event's context - 2. Event's data is valid during event's context. Any application data - which is required for the user application should be copied or marked - into user's variables - 3. It is not recommended to delay the execution of the event callback handler - -*/ - -/*! - - \addtogroup UserEvents - @{ - -*/ - - -/*****************************************************************************/ -/* Macro declarations for Host Driver version */ -/*****************************************************************************/ -#define SL_DRIVER_VERSION "1.0.0.10" -#define SL_MAJOR_VERSION_NUM 1L -#define SL_MINOR_VERSION_NUM 0L -#define SL_VERSION_NUM 0L -#define SL_SUB_VERSION_NUM 10L - - -/*****************************************************************************/ -/* Macro declarations for predefined configurations */ -/*****************************************************************************/ - -#ifdef SL_TINY -#undef SL_INC_ARG_CHECK -#undef SL_INC_EXT_API -#undef SL_INC_SOCK_SERVER_SIDE_API -#undef SL_INC_WLAN_PKG -#undef SL_INC_NET_CFG_PKG -#undef SL_INC_FS_PKG -#undef SL_INC_SET_UART_MODE -#undef SL_INC_STD_BSD_API_NAMING -#undef SL_INC_SOCK_CLIENT_SIDE_API -#undef SL_INC_NET_APP_PKG -#undef SL_INC_SOCK_RECV_API -#undef SL_INC_SOCK_SEND_API -#undef SL_INC_SOCKET_PKG -#endif - -#ifdef SL_SMALL -#undef SL_INC_EXT_API -#undef SL_INC_NET_APP_PKG -#undef SL_INC_NET_CFG_PKG -#undef SL_INC_FS_PKG -#define SL_INC_ARG_CHECK -#define SL_INC_WLAN_PKG -#define SL_INC_SOCKET_PKG -#define SL_INC_SOCK_CLIENT_SIDE_API -#define SL_INC_SOCK_SERVER_SIDE_API -#define SL_INC_SOCK_RECV_API -#define SL_INC_SOCK_SEND_API -#define SL_INC_SET_UART_MODE -#endif - -#ifdef SL_FULL -#define SL_INC_EXT_API -#define SL_INC_NET_APP_PKG -#define SL_INC_NET_CFG_PKG -#define SL_INC_FS_PKG -#define SL_INC_ARG_CHECK -#define SL_INC_WLAN_PKG -#define SL_INC_SOCKET_PKG -#define SL_INC_SOCK_CLIENT_SIDE_API -#define SL_INC_SOCK_SERVER_SIDE_API -#define SL_INC_SOCK_RECV_API -#define SL_INC_SOCK_SEND_API -#define SL_INC_SET_UART_MODE -#endif - -#define SL_RET_CODE_OK (0) -#define SL_RET_CODE_INVALID_INPUT (-2) -#define SL_RET_CODE_SELF_ERROR (-3) -#define SL_RET_CODE_NWP_IF_ERROR (-4) -#define SL_RET_CODE_MALLOC_ERROR (-5) - -#define sl_Memcpy memcpy -#define sl_Memset memset - -#define sl_SyncObjClear(pObj) sl_SyncObjWait(pObj,SL_OS_NO_WAIT) - -#ifndef SL_TINY_EXT -#define SL_MAX_SOCKETS (8) -#else -#define SL_MAX_SOCKETS (2) -#endif - - -/*****************************************************************************/ -/* Types definitions */ -/*****************************************************************************/ -typedef void (*_SlSpawnEntryFunc_t)(void* pValue); - -#ifndef NULL -#define NULL (0) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -#ifndef OK -#define OK (0) -#endif - -#ifndef _SL_USER_TYPES - typedef unsigned char _u8; - typedef signed char _i8; - - typedef unsigned short _u16; - typedef signed short _i16; - - typedef unsigned long _u32; - typedef signed long _i32; - #define _volatile volatile - #define _const const -#endif - -typedef _u16 _SlOpcode_t; -typedef _u8 _SlArgSize_t; -typedef _i16 _SlDataSize_t; -typedef _i16 _SlReturnVal_t; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - - -/* - * This event status used to block or continue the event propagation - * through all the registered external libs/user application - * - */ - - typedef enum { - EVENT_PROPAGATION_BLOCK = 0, - EVENT_PROPAGATION_CONTINUE - - } _SlEventPropogationStatus_e; - - - - - - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ - -#ifdef SL_PLATFORM_MULTI_THREADED - #include "spawn.h" -#else - #include "nonos.h" -#endif - - -/* - objInclusion.h and user.h must be included before all api header files - objInclusion.h must be the last arrangement just before including the API header files - since it based on the other configurations to decide which object should be included -*/ -#include "objInclusion.h" -#include "trace.h" -#include "fs.h" -#include "socket.h" -#include "netapp.h" -#include "wlan.h" -#include "device.h" -#include "netcfg.h" -#include "wlan_rx_filters.h" - - - /* The general events dispatcher which is - * initialized to the user handler */ -#ifdef sl_GeneralEvtHdlr -#define _SlDrvHandleGeneralEvents sl_GeneralEvtHdlr -#endif - - /* The wlan events dispatcher which is - * initialized to the user handler */ -#ifdef sl_WlanEvtHdlr -#define _SlDrvHandleWlanEvents sl_WlanEvtHdlr -#endif - - /* The NetApp events dispatcher which is - * initialized to the user handler */ -#ifdef sl_NetAppEvtHdlr -#define _SlDrvHandleNetAppEvents sl_NetAppEvtHdlr -#endif - - /* The http server events dispatcher which is - * initialized to the user handler if exists */ -#ifdef sl_HttpServerCallback -#define _SlDrvHandleHttpServerEvents sl_HttpServerCallback -#endif - - /* The socket events dispatcher which is - * initialized to the user handler */ -#ifdef sl_SockEvtHdlr -#define _SlDrvHandleSockEvents sl_SockEvtHdlr -#endif - - -#ifndef __CONCAT -#define __CONCAT(x,y) x ## y -#endif -#define __CONCAT2(x,y) __CONCAT(x,y) - - -/* - * The section below handles the external lib event registration - * according to the desired events it specified in its API header file. - * The external lib should be first installed by the user (see user.h) - */ -#ifdef SL_EXT_LIB_1 - - /* General Event Registration */ - #if __CONCAT2(SL_EXT_LIB_1, _NOTIFY_GENERAL_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_1, _GeneralEventHdl) (SlDeviceEvent_t *); - #define SlExtLib1GeneralEventHandler __CONCAT2(SL_EXT_LIB_1, _GeneralEventHdl) - - #undef EXT_LIB_REGISTERED_GENERAL_EVENTS - #define EXT_LIB_REGISTERED_GENERAL_EVENTS - #endif - - /* Wlan Event Registration */ - #if __CONCAT2(SL_EXT_LIB_1, _NOTIFY_WLAN_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_1, _WlanEventHdl) (SlWlanEvent_t *); - #define SlExtLib1WlanEventHandler __CONCAT2(SL_EXT_LIB_1, _WlanEventHdl) - - #undef EXT_LIB_REGISTERED_WLAN_EVENTS - #define EXT_LIB_REGISTERED_WLAN_EVENTS - #endif - - /* NetApp Event Registration */ - #if __CONCAT2(SL_EXT_LIB_1, _NOTIFY_NETAPP_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_1, _NetAppEventHdl) (SlNetAppEvent_t *); - #define SlExtLib1NetAppEventHandler __CONCAT2(SL_EXT_LIB_1, _NetAppEventHdl) - - #undef EXT_LIB_REGISTERED_NETAPP_EVENTS - #define EXT_LIB_REGISTERED_NETAPP_EVENTS - #endif - - /* Http Server Event Registration */ - #if __CONCAT2(SL_EXT_LIB_1, _NOTIFY_HTTP_SERVER_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_1, _HttpServerEventHdl) (SlHttpServerEvent_t* , SlHttpServerResponse_t*); - #define SlExtLib1HttpServerEventHandler __CONCAT2(SL_EXT_LIB_1, _HttpServerEventHdl) - - #undef EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS - #define EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS - #endif - - /* Socket Event Registration */ - #if __CONCAT2(SL_EXT_LIB_1, _NOTIFY_SOCK_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_1, _SockEventHdl) (SlSockEvent_t *); - #define SlExtLib1SockEventHandler __CONCAT2(SL_EXT_LIB_1, _SockEventHdl) - - #undef EXT_LIB_REGISTERED_SOCK_EVENTS - #define EXT_LIB_REGISTERED_SOCK_EVENTS - #endif - -#endif - - -#ifdef SL_EXT_LIB_2 - - /* General Event Registration */ - #if __CONCAT2(SL_EXT_LIB_2, _NOTIFY_GENERAL_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_2, _GeneralEventHdl) (SlDeviceEvent_t *); - #define SlExtLib2GeneralEventHandler __CONCAT2(SL_EXT_LIB_2, _GeneralEventHdl) - - #undef EXT_LIB_REGISTERED_GENERAL_EVENTS - #define EXT_LIB_REGISTERED_GENERAL_EVENTS - #endif - - /* Wlan Event Registration */ - #if __CONCAT2(SL_EXT_LIB_2, _NOTIFY_WLAN_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_2, _WlanEventHdl) (SlWlanEvent_t *); - #define SlExtLib2WlanEventHandler __CONCAT2(SL_EXT_LIB_2, _WlanEventHdl) - - #undef EXT_LIB_REGISTERED_WLAN_EVENTS - #define EXT_LIB_REGISTERED_WLAN_EVENTS - #endif - - /* NetApp Event Registration */ - #if __CONCAT2(SL_EXT_LIB_2, _NOTIFY_NETAPP_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_2, _NetAppEventHdl) (SlNetAppEvent_t *); - #define SlExtLib2NetAppEventHandler __CONCAT2(SL_EXT_LIB_2, _NetAppEventHdl) - - #undef EXT_LIB_REGISTERED_NETAPP_EVENTS - #define EXT_LIB_REGISTERED_NETAPP_EVENTS - #endif - - /* Http Server Event Registration */ - #if __CONCAT2(SL_EXT_LIB_2, _NOTIFY_HTTP_SERVER_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_2, _HttpServerEventHdl) (SlHttpServerEvent_t* , SlHttpServerResponse_t*); - #define SlExtLib2HttpServerEventHandler __CONCAT2(SL_EXT_LIB_2, _HttpServerEventHdl) - - #undef EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS - #define EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS - #endif - - /* Socket Event Registration */ - #if __CONCAT2(SL_EXT_LIB_2, _NOTIFY_SOCK_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_2, _SockEventHdl) (SlSockEvent_t *); - #define SlExtLib2SockEventHandler __CONCAT2(SL_EXT_LIB_2, _SockEventHdl) - - #undef EXT_LIB_REGISTERED_SOCK_EVENTS - #define EXT_LIB_REGISTERED_SOCK_EVENTS - #endif - -#endif - - -#ifdef SL_EXT_LIB_3 - - /* General Event Registration */ - #if __CONCAT2(SL_EXT_LIB_3, _NOTIFY_GENERAL_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_3, _GeneralEventHdl) (SlDeviceEvent_t *); - #define SlExtLib3GeneralEventHandler __CONCAT2(SL_EXT_LIB_3, _GeneralEventHdl) - - #undef EXT_LIB_REGISTERED_GENERAL_EVENTS - #define EXT_LIB_REGISTERED_GENERAL_EVENTS - #endif - - /* Wlan Event Registration */ - #if __CONCAT2(SL_EXT_LIB_3, _NOTIFY_WLAN_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_3, _WlanEventHdl) (SlWlanEvent_t *); - #define SlExtLib3WlanEventHandler __CONCAT2(SL_EXT_LIB_3, _WlanEventHdl) - - #undef EXT_LIB_REGISTERED_WLAN_EVENTS - #define EXT_LIB_REGISTERED_WLAN_EVENTS - #endif - - /* NetApp Event Registration */ - #if __CONCAT2(SL_EXT_LIB_3, _NOTIFY_NETAPP_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_3, _NetAppEventHdl) (SlNetAppEvent_t *); - #define SlExtLib3NetAppEventHandler __CONCAT2(SL_EXT_LIB_3, _NetAppEventHdl) - - #undef EXT_LIB_REGISTERED_NETAPP_EVENTS - #define EXT_LIB_REGISTERED_NETAPP_EVENTS - #endif - - /* Http Server Event Registration */ - #if __CONCAT2(SL_EXT_LIB_3, _NOTIFY_HTTP_SERVER_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_3, _HttpServerEventHdl) (SlHttpServerEvent_t* , SlHttpServerResponse_t*); - #define SlExtLib3HttpServerEventHandler __CONCAT2(SL_EXT_LIB_3, _HttpServerEventHdl) - - #undef EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS - #define EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS - #endif - - /* Socket Event Registration */ - #if __CONCAT2(SL_EXT_LIB_3, _NOTIFY_SOCK_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_3, _SockEventHdl) (SlSockEvent_t *); - #define SlExtLib3SockEventHandler __CONCAT2(SL_EXT_LIB_3, _SockEventHdl) - - #undef EXT_LIB_REGISTERED_SOCK_EVENTS - #define EXT_LIB_REGISTERED_SOCK_EVENTS - #endif - -#endif - - -#ifdef SL_EXT_LIB_4 - - /* General Event Registration */ - #if __CONCAT2(SL_EXT_LIB_4, _NOTIFY_GENERAL_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_4, _GeneralEventHdl) (SlDeviceEvent_t *); - #define SlExtLib4GeneralEventHandler __CONCAT2(SL_EXT_LIB_4, _GeneralEventHdl) - - #undef EXT_LIB_REGISTERED_GENERAL_EVENTS - #define EXT_LIB_REGISTERED_GENERAL_EVENTS - #endif - - /* Wlan Event Registration */ - #if __CONCAT2(SL_EXT_LIB_4, _NOTIFY_WLAN_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_4, _WlanEventHdl) (SlWlanEvent_t *); - #define SlExtLib4WlanEventHandler __CONCAT2(SL_EXT_LIB_4, _WlanEventHdl) - - #undef EXT_LIB_REGISTERED_WLAN_EVENTS - #define EXT_LIB_REGISTERED_WLAN_EVENTS - #endif - - /* NetApp Event Registration */ - #if __CONCAT2(SL_EXT_LIB_4, _NOTIFY_NETAPP_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_4, _NetAppEventHdl) (SlNetAppEvent_t *); - #define SlExtLib4NetAppEventHandler __CONCAT2(SL_EXT_LIB_4, _NetAppEventHdl) - - #undef EXT_LIB_REGISTERED_NETAPP_EVENTS - #define EXT_LIB_REGISTERED_NETAPP_EVENTS - #endif - - /* Http Server Event Registration */ - #if __CONCAT2(SL_EXT_LIB_4, _NOTIFY_HTTP_SERVER_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_4, _HttpServerEventHdl) (SlHttpServerEvent_t* , SlHttpServerResponse_t*); - #define SlExtLib4HttpServerEventHandler __CONCAT2(SL_EXT_LIB_4, _HttpServerEventHdl) - - #undef EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS - #define EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS - #endif - - /* Socket Event Registration */ - #if __CONCAT2(SL_EXT_LIB_4, _NOTIFY_SOCK_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_4, _SockEventHdl) (SlSockEvent_t *); - #define SlExtLib4SockEventHandler __CONCAT2(SL_EXT_LIB_4, _SockEventHdl) - - #undef EXT_LIB_REGISTERED_SOCK_EVENTS - #define EXT_LIB_REGISTERED_SOCK_EVENTS - #endif - -#endif - - -#ifdef SL_EXT_LIB_5 - - /* General Event Registration */ - #if __CONCAT2(SL_EXT_LIB_5, _NOTIFY_GENERAL_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_5, _GeneralEventHdl) (SlDeviceEvent_t *); - #define SlExtLib5GeneralEventHandler __CONCAT2(SL_EXT_LIB_5, _GeneralEventHdl) - - #undef EXT_LIB_REGISTERED_GENERAL_EVENTS - #define EXT_LIB_REGISTERED_GENERAL_EVENTS - #endif - - /* Wlan Event Registration */ - #if __CONCAT2(SL_EXT_LIB_5, _NOTIFY_WLAN_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_5, _WlanEventHdl) (SlWlanEvent_t *); - #define SlExtLib5WlanEventHandler __CONCAT2(SL_EXT_LIB_5, _WlanEventHdl) - - #undef EXT_LIB_REGISTERED_WLAN_EVENTS - #define EXT_LIB_REGISTERED_WLAN_EVENTS - #endif - - /* NetApp Event Registration */ - #if __CONCAT2(SL_EXT_LIB_5, _NOTIFY_NETAPP_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_5, _NetAppEventHdl) (SlNetAppEvent_t *); - #define SlExtLib5NetAppEventHandler __CONCAT2(SL_EXT_LIB_5, _NetAppEventHdl) - - #undef EXT_LIB_REGISTERED_NETAPP_EVENTS - #define EXT_LIB_REGISTERED_NETAPP_EVENTS - #endif - - /* Http Server Event Registration */ - #if __CONCAT2(SL_EXT_LIB_5, _NOTIFY_HTTP_SERVER_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_5, _HttpServerEventHdl) (SlHttpServerEvent_t* , SlHttpServerResponse_t*); - #define SlExtLib5HttpServerEventHandler __CONCAT2(SL_EXT_LIB_5, _HttpServerEventHdl) - - #undef EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS - #define EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS - #endif - - /* Socket Event Registration */ - #if __CONCAT2(SL_EXT_LIB_5, _NOTIFY_SOCK_EVENT) - extern _SlEventPropogationStatus_e __CONCAT2(SL_EXT_LIB_5, _SockEventHdl) (SlSockEvent_t *); - #define SlExtLib5SockEventHandler __CONCAT2(SL_EXT_LIB_5, _SockEventHdl) - - #undef EXT_LIB_REGISTERED_SOCK_EVENTS - #define EXT_LIB_REGISTERED_SOCK_EVENTS - #endif - -#endif - - - -#if defined(EXT_LIB_REGISTERED_GENERAL_EVENTS) -extern void _SlDrvHandleGeneralEvents(SlDeviceEvent_t *slGeneralEvent); -#endif - -#if defined(EXT_LIB_REGISTERED_WLAN_EVENTS) -extern void _SlDrvHandleWlanEvents(SlWlanEvent_t *slWlanEvent); -#endif - -#if defined (EXT_LIB_REGISTERED_NETAPP_EVENTS) -extern void _SlDrvHandleNetAppEvents(SlNetAppEvent_t *slNetAppEvent); -#endif - -#if defined(EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS) -extern void _SlDrvHandleHttpServerEvents(SlHttpServerEvent_t *slHttpServerEvent, SlHttpServerResponse_t *slHttpServerResponse); -#endif - - -#if defined(EXT_LIB_REGISTERED_SOCK_EVENTS) -extern void _SlDrvHandleSockEvents(SlSockEvent_t *slSockEvent); -#endif - - -typedef void (*_SlSpawnEntryFunc_t)(void* pValue); - - -/* Async functions description*/ - -/*! - \brief General async event for inspecting general events - - \param[out] pSlDeviceEvent pointer to SlDeviceEvent_t - - \par - Parameters: \n - - pSlDeviceEvent->Event = SL_DEVICE_FATAL_ERROR_EVENT - - pSlDeviceEvent->EventData.deviceEvent fields: - - status: An error code indication from the device - - sender: The sender originator which is based on SlErrorSender_e enum - - - pSlDeviceEvent->Event = SL_DEVICE_ABORT_ERROR_EVENT - Indicates a severe error occured and the device stopped - - pSlDeviceEvent->EventData.deviceReport fields: - - AbortType: An idication of the event type - - AbortData: Additional info about the data error - - - \par Example for fatal error: - \code - printf(General Event Handler - ID=%d Sender=%d\n\n", - pSlDeviceEvent->EventData.deviceEvent.status, // status of the general event - pSlDeviceEvent->EventData.deviceEvent.sender); // sender type - \endcode - \par Example for abort request: - \code - printf(Abort type =%d Abort Data=%d\n\n", - pSlDeviceEvent->EventData.deviceReport.AbortType, - pSlDeviceEvent->EventData.deviceReport.AbortData); - - \endcode -*/ -#if (defined(sl_GeneralEvtHdlr)) -extern void sl_GeneralEvtHdlr(SlDeviceEvent_t *pSlDeviceEvent); -#endif - - -/*! - \brief WLAN Async event handler - - \param[out] pSlWlanEvent pointer to SlWlanEvent_t data - - \par - Parameters: - - - pSlWlanEvent->Event = SL_WLAN_CONNECT_EVENT , STA or P2P client connection indication event - - pSlWlanEvent->EventData.STAandP2PModeWlanConnected main fields: - - ssid_name - - ssid_len - - bssid - - go_peer_device_name - - go_peer_device_name_len - - - pSlWlanEvent->Event = SL_WLAN_DISCONNECT_EVENT , STA or P2P client disconnection event - - pSlWlanEvent->EventData.STAandP2PModeDisconnected main fields: - - ssid_name - - ssid_len - - reason_code - - - pSlWlanEvent->Event = SL_WLAN_STA_CONNECTED_EVENT , AP/P2P(Go) connected STA/P2P(Client) - - pSlWlanEvent->EventData.APModeStaConnected fields: - - go_peer_device_name - - mac - - go_peer_device_name_len - - wps_dev_password_id - - own_ssid: relevant for event sta-connected only - - own_ssid_len: relevant for event sta-connected only - - - pSlWlanEvent->Event = SL_WLAN_STA_DISCONNECTED_EVENT , AP/P2P(Go) disconnected STA/P2P(Client) - - pSlWlanEvent->EventData.APModestaDisconnected fields: - - go_peer_device_name - - mac - - go_peer_device_name_len - - wps_dev_password_id - - own_ssid: relevant for event sta-connected only - - own_ssid_len: relevant for event sta-connected only - - - pSlWlanEvent->Event = SL_WLAN_SMART_CONFIG_COMPLETE_EVENT - - pSlWlanEvent->EventData.smartConfigStartResponse fields: - - status - - ssid_len - - ssid - - private_token_len - - private_token - - - pSlWlanEvent->Event = SL_WLAN_SMART_CONFIG_STOP_EVENT - - pSlWlanEvent->EventData.smartConfigStopResponse fields: - - status - - - pSlWlanEvent->Event = SL_WLAN_P2P_DEV_FOUND_EVENT - - pSlWlanEvent->EventData.P2PModeDevFound fields: - - go_peer_device_name - - mac - - go_peer_device_name_len - - wps_dev_password_id - - own_ssid: relevant for event sta-connected only - - own_ssid_len: relevant for event sta-connected only - - - pSlWlanEvent->Event = SL_WLAN_P2P_NEG_REQ_RECEIVED_EVENT - - pSlWlanEvent->EventData.P2PModeNegReqReceived fields - - go_peer_device_name - - mac - - go_peer_device_name_len - - wps_dev_password_id - - own_ssid: relevant for event sta-connected only - - - pSlWlanEvent->Event = SL_WLAN_CONNECTION_FAILED_EVENT , P2P only - - pSlWlanEvent->EventData.P2PModewlanConnectionFailure fields: - - status -*/ -#if (defined(sl_WlanEvtHdlr)) -extern void sl_WlanEvtHdlr(SlWlanEvent_t* pSlWlanEvent); -#endif - - -/*! - \brief NETAPP Async event handler - - \param[out] pSlNetApp pointer to SlNetAppEvent_t data - - \par - Parameters: - - pSlNetApp->Event = SL_NETAPP_IPV4_IPACQUIRED_EVENT, IPV4 acquired event - - pSlNetApp->EventData.ipAcquiredV4 fields: - - ip - - gateway - - dns - - - pSlNetApp->Event = SL_NETAPP_IP_LEASED_EVENT, AP or P2P go dhcp lease event - - pSlNetApp->EventData.ipLeased fields: - - ip_address - - lease_time - - mac - - - pSlNetApp->Event = SL_NETAPP_IP_RELEASED_EVENT, AP or P2P go dhcp ip release event - - pSlNetApp->EventData.ipReleased fields - - ip_address - - mac - - reason - -*/ -#if (defined(sl_NetAppEvtHdlr)) -extern void sl_NetAppEvtHdlr(SlNetAppEvent_t* pSlNetApp); -#endif - -/*! - \brief Socket Async event handler - - \param[out] pSlSockEvent pointer to SlSockEvent_t data - - \par - Parameters:\n - - pSlSockEvent->Event = SL_SOCKET_TX_FAILED_EVENT - - pSlSockEvent->SockTxFailData fields: - - sd - - status - - pSlSockEvent->Event = SL_SOCKET_ASYNC_EVENT - - pSlSockEvent->SockAsyncData fields: - - sd - - type: SSL_ACCEPT or RX_FRAGMENTATION_TOO_BIG or OTHER_SIDE_CLOSE_SSL_DATA_NOT_ENCRYPTED - - val - -*/ -#if (defined(sl_SockEvtHdlr)) -extern void sl_SockEvtHdlr(SlSockEvent_t* pSlSockEvent); -#endif - -/*! - \brief HTTP server async event - - \param[out] pSlHttpServerEvent pointer to SlHttpServerEvent_t - \param[in] pSlHttpServerResponse pointer to SlHttpServerResponse_t - - \par - Parameters: \n - - - pSlHttpServerEvent->Event = SL_NETAPP_HTTPGETTOKENVALUE_EVENT - - pSlHttpServerEvent->EventData fields: - - httpTokenName - - data - - len - - pSlHttpServerResponse->ResponseData fields: - - data - - len - - - pSlHttpServerEvent->Event = SL_NETAPP_HTTPPOSTTOKENVALUE_EVENT - - pSlHttpServerEvent->EventData.httpPostData fields: - - action - - token_name - - token_value - - pSlHttpServerResponse->ResponseData fields: - - data - - len - -*/ -#if (defined(sl_HttpServerCallback)) -extern void sl_HttpServerCallback(SlHttpServerEvent_t *pSlHttpServerEvent, SlHttpServerResponse_t *pSlHttpServerResponse); -#endif -/*! - - Close the Doxygen group. - @} - - */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __SIMPLELINK_H__ */ - diff --git a/drivers/cc3100/inc/socket.h b/drivers/cc3100/inc/socket.h deleted file mode 100644 index 81554d4afc2..00000000000 --- a/drivers/cc3100/inc/socket.h +++ /dev/null @@ -1,1573 +0,0 @@ -/* - * socket.h - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ -#include "simplelink.h" - -#ifndef __SL_SOCKET_H__ -#define __SL_SOCKET_H__ - - - - -#ifdef __cplusplus -extern "C" { -#endif - -/*! - - \addtogroup socket - @{ - -*/ - -/*****************************************************************************/ -/* Macro declarations */ -/*****************************************************************************/ - -#define SL_FD_SETSIZE SL_MAX_SOCKETS /* Number of sockets to select on - same is max sockets! */ -#define BSD_SOCKET_ID_MASK (0x0F) /* Index using the LBS 4 bits for socket id 0-7 */ -/* Define some BSD protocol constants. */ -#define SL_SOCK_STREAM (1) /* TCP Socket */ -#define SL_SOCK_DGRAM (2) /* UDP Socket */ -#define SL_SOCK_RAW (3) /* Raw socket */ -#define SL_IPPROTO_TCP (6) /* TCP Raw Socket */ -#define SL_IPPROTO_UDP (17) /* UDP Raw Socket */ -#define SL_IPPROTO_RAW (255) /* Raw Socket */ -#define SL_SEC_SOCKET (100) /* Secured Socket Layer (SSL,TLS) */ - -/* Address families. */ -#define SL_AF_INET (2) /* IPv4 socket (UDP, TCP, etc) */ -#define SL_AF_INET6 (3) /* IPv6 socket (UDP, TCP, etc) */ -#define SL_AF_INET6_EUI_48 (9) -#define SL_AF_RF (6) /* data include RF parameter, All layer by user (Wifi could be disconnected) */ -#define SL_AF_PACKET (17) -/* Protocol families, same as address families. */ -#define SL_PF_INET AF_INET -#define SL_PF_INET6 AF_INET6 -#define SL_INADDR_ANY (0) /* bind any address */ - -/* error codes */ -#define SL_SOC_ERROR (-1) /* Failure. */ -#define SL_SOC_OK ( 0) /* Success. */ -#define SL_INEXE (-8) /* socket command in execution */ -#define SL_EBADF (-9) /* Bad file number */ -#define SL_ENSOCK (-10) /* The system limit on the total number of open socket, has been reached */ -#define SL_EAGAIN (-11) /* Try again */ -#define SL_EWOULDBLOCK SL_EAGAIN -#define SL_ENOMEM (-12) /* Out of memory */ -#define SL_EACCES (-13) /* Permission denied */ -#define SL_EFAULT (-14) /* Bad address */ -#define SL_ECLOSE (-15) /* close socket operation failed to transmit all queued packets */ -#define SL_EALREADY_ENABLED (-21) /* Transceiver - Transceiver already ON. there could be only one */ -#define SL_EINVAL (-22) /* Invalid argument */ -#define SL_EAUTO_CONNECT_OR_CONNECTING (-69) /* Transceiver - During connection, connected or auto mode started */ -#define SL_CONNECTION_PENDING (-72) /* Transceiver - Device is connected, disconnect first to open transceiver */ -#define SL_EUNSUPPORTED_ROLE (-86) /* Transceiver - Trying to start when WLAN role is AP or P2P GO */ -#define SL_EDESTADDRREQ (-89) /* Destination address required */ -#define SL_EPROTOTYPE (-91) /* Protocol wrong type for socket */ -#define SL_ENOPROTOOPT (-92) /* Protocol not available */ -#define SL_EPROTONOSUPPORT (-93) /* Protocol not supported */ -#define SL_ESOCKTNOSUPPORT (-94) /* Socket type not supported */ -#define SL_EOPNOTSUPP (-95) /* Operation not supported on transport endpoint */ -#define SL_EAFNOSUPPORT (-97) /* Address family not supported by protocol */ -#define SL_EADDRINUSE (-98) /* Address already in use */ -#define SL_EADDRNOTAVAIL (-99) /* Cannot assign requested address */ -#define SL_ENETUNREACH (-101) /* Network is unreachable */ -#define SL_ENOBUFS (-105) /* No buffer space available */ -#define SL_EOBUFF SL_ENOBUFS -#define SL_EISCONN (-106) /* Transport endpoint is already connected */ -#define SL_ENOTCONN (-107) /* Transport endpoint is not connected */ -#define SL_ETIMEDOUT (-110) /* Connection timed out */ -#define SL_ECONNREFUSED (-111) /* Connection refused */ -#define SL_EALREADY (-114) /* Non blocking connect in progress, try again */ - -#define SL_ESEC_RSA_WRONG_TYPE_E (-130) /* RSA wrong block type for RSA function */ -#define SL_ESEC_RSA_BUFFER_E (-131) /* RSA buffer error, output too small or */ -#define SL_ESEC_BUFFER_E (-132) /* output buffer too small or input too large */ -#define SL_ESEC_ALGO_ID_E (-133) /* setting algo id error */ -#define SL_ESEC_PUBLIC_KEY_E (-134) /* setting public key error */ -#define SL_ESEC_DATE_E (-135) /* setting date validity error */ -#define SL_ESEC_SUBJECT_E (-136) /* setting subject name error */ -#define SL_ESEC_ISSUER_E (-137) /* setting issuer name error */ -#define SL_ESEC_CA_TRUE_E (-138) /* setting CA basic constraint true error */ -#define SL_ESEC_EXTENSIONS_E (-139) /* setting extensions error */ -#define SL_ESEC_ASN_PARSE_E (-140) /* ASN parsing error, invalid input */ -#define SL_ESEC_ASN_VERSION_E (-141) /* ASN version error, invalid number */ -#define SL_ESEC_ASN_GETINT_E (-142) /* ASN get big _i16 error, invalid data */ -#define SL_ESEC_ASN_RSA_KEY_E (-143) /* ASN key init error, invalid input */ -#define SL_ESEC_ASN_OBJECT_ID_E (-144) /* ASN object id error, invalid id */ -#define SL_ESEC_ASN_TAG_NULL_E (-145) /* ASN tag error, not null */ -#define SL_ESEC_ASN_EXPECT_0_E (-146) /* ASN expect error, not zero */ -#define SL_ESEC_ASN_BITSTR_E (-147) /* ASN bit string error, wrong id */ -#define SL_ESEC_ASN_UNKNOWN_OID_E (-148) /* ASN oid error, unknown sum id */ -#define SL_ESEC_ASN_DATE_SZ_E (-149) /* ASN date error, bad size */ -#define SL_ESEC_ASN_BEFORE_DATE_E (-150) /* ASN date error, current date before */ -#define SL_ESEC_ASN_AFTER_DATE_E (-151) /* ASN date error, current date after */ -#define SL_ESEC_ASN_SIG_OID_E (-152) /* ASN signature error, mismatched oid */ -#define SL_ESEC_ASN_TIME_E (-153) /* ASN time error, unknown time type */ -#define SL_ESEC_ASN_INPUT_E (-154) /* ASN input error, not enough data */ -#define SL_ESEC_ASN_SIG_CONFIRM_E (-155) /* ASN sig error, confirm failure */ -#define SL_ESEC_ASN_SIG_HASH_E (-156) /* ASN sig error, unsupported hash type */ -#define SL_ESEC_ASN_SIG_KEY_E (-157) /* ASN sig error, unsupported key type */ -#define SL_ESEC_ASN_DH_KEY_E (-158) /* ASN key init error, invalid input */ -#define SL_ESEC_ASN_NTRU_KEY_E (-159) /* ASN ntru key decode error, invalid input */ -#define SL_ESEC_ECC_BAD_ARG_E (-170) /* ECC input argument of wrong type */ -#define SL_ESEC_ASN_ECC_KEY_E (-171) /* ASN ECC bad input */ -#define SL_ESEC_ECC_CURVE_OID_E (-172) /* Unsupported ECC OID curve type */ -#define SL_ESEC_BAD_FUNC_ARG (-173) /* Bad function argument provided */ -#define SL_ESEC_NOT_COMPILED_IN (-174) /* Feature not compiled in */ -#define SL_ESEC_UNICODE_SIZE_E (-175) /* Unicode password too big */ -#define SL_ESEC_NO_PASSWORD (-176) /* no password provided by user */ -#define SL_ESEC_ALT_NAME_E (-177) /* alt name size problem, too big */ -#define SL_ESEC_AES_GCM_AUTH_E (-180) /* AES-GCM Authentication check failure */ -#define SL_ESEC_AES_CCM_AUTH_E (-181) /* AES-CCM Authentication check failure */ -#define SL_SOCKET_ERROR_E (-208) /* Error state on socket */ - -#define SL_ESEC_MEMORY_ERROR (-203) /* out of memory */ -#define SL_ESEC_VERIFY_FINISHED_ERROR (-204) /* verify problem on finished */ -#define SL_ESEC_VERIFY_MAC_ERROR (-205) /* verify mac problem */ -#define SL_ESEC_UNKNOWN_HANDSHAKE_TYPE (-207) /* weird handshake type */ -#define SL_ESEC_SOCKET_ERROR_E (-208) /* error state on socket */ -#define SL_ESEC_SOCKET_NODATA (-209) /* expected data, not there */ -#define SL_ESEC_INCOMPLETE_DATA (-210) /* don't have enough data to complete task */ -#define SL_ESEC_UNKNOWN_RECORD_TYPE (-211) /* unknown type in record hdr */ -#define SL_ESEC_FATAL_ERROR (-213) /* recvd alert fatal error */ -#define SL_ESEC_ENCRYPT_ERROR (-214) /* error during encryption */ -#define SL_ESEC_NO_PEER_KEY (-216) /* need peer's key */ -#define SL_ESEC_NO_PRIVATE_KEY (-217) /* need the private key */ -#define SL_ESEC_RSA_PRIVATE_ERROR (-218) /* error during rsa priv op */ -#define SL_ESEC_NO_DH_PARAMS (-219) /* server missing DH params */ -#define SL_ESEC_BUILD_MSG_ERROR (-220) /* build message failure */ -#define SL_ESEC_BAD_HELLO (-221) /* client hello malformed */ -#define SL_ESEC_DOMAIN_NAME_MISMATCH (-222) /* peer subject name mismatch */ -#define SL_ESEC_WANT_READ (-223) /* want read, call again */ -#define SL_ESEC_NOT_READY_ERROR (-224) /* handshake layer not ready */ -#define SL_ESEC_PMS_VERSION_ERROR (-225) /* pre m secret version error */ -#define SL_ESEC_VERSION_ERROR (-226) /* record layer version error */ -#define SL_ESEC_WANT_WRITE (-227) /* want write, call again */ -#define SL_ESEC_BUFFER_ERROR (-228) /* malformed buffer input */ -#define SL_ESEC_VERIFY_CERT_ERROR (-229) /* verify cert error */ -#define SL_ESEC_VERIFY_SIGN_ERROR (-230) /* verify sign error */ - -#define SL_ESEC_LENGTH_ERROR (-241) /* record layer length error */ -#define SL_ESEC_PEER_KEY_ERROR (-242) /* can't decode peer key */ -#define SL_ESEC_ZERO_RETURN (-243) /* peer sent close notify */ -#define SL_ESEC_SIDE_ERROR (-244) /* wrong client/server type */ -#define SL_ESEC_NO_PEER_CERT (-245) /* peer didn't send key */ -#define SL_ESEC_ECC_CURVETYPE_ERROR (-250) /* Bad ECC Curve Type */ -#define SL_ESEC_ECC_CURVE_ERROR (-251) /* Bad ECC Curve */ -#define SL_ESEC_ECC_PEERKEY_ERROR (-252) /* Bad Peer ECC Key */ -#define SL_ESEC_ECC_MAKEKEY_ERROR (-253) /* Bad Make ECC Key */ -#define SL_ESEC_ECC_EXPORT_ERROR (-254) /* Bad ECC Export Key */ -#define SL_ESEC_ECC_SHARED_ERROR (-255) /* Bad ECC Shared Secret */ -#define SL_ESEC_NOT_CA_ERROR (-257) /* Not a CA cert error */ -#define SL_ESEC_BAD_PATH_ERROR (-258) /* Bad path for opendir */ -#define SL_ESEC_BAD_CERT_MANAGER_ERROR (-259) /* Bad Cert Manager */ -#define SL_ESEC_MAX_CHAIN_ERROR (-268) /* max chain depth exceeded */ -#define SL_ESEC_SUITES_ERROR (-271) /* suites pointer error */ -#define SL_ESEC_SSL_NO_PEM_HEADER (-272) /* no PEM header found */ -#define SL_ESEC_OUT_OF_ORDER_E (-273) /* out of order message */ -#define SL_ESEC_SANITY_CIPHER_E (-275) /* sanity check on cipher error */ -#define SL_ESEC_GEN_COOKIE_E (-277) /* Generate Cookie Error */ -#define SL_ESEC_NO_PEER_VERIFY (-278) /* Need peer cert verify Error */ -#define SL_ESEC_UNKNOWN_SNI_HOST_NAME_E (-281) /* Unrecognized host name Error */ -/* begin negotiation parameter errors */ -#define SL_ESEC_UNSUPPORTED_SUITE (-290) /* unsupported cipher suite */ -#define SL_ESEC_MATCH_SUITE_ERROR (-291 ) /* can't match cipher suite */ - -/* ssl tls security start with -300 offset */ -#define SL_ESEC_CLOSE_NOTIFY (-300) /* ssl/tls alerts */ -#define SL_ESEC_UNEXPECTED_MESSAGE (-310) /* ssl/tls alerts */ -#define SL_ESEC_BAD_RECORD_MAC (-320) /* ssl/tls alerts */ -#define SL_ESEC_DECRYPTION_FAILED (-321) /* ssl/tls alerts */ -#define SL_ESEC_RECORD_OVERFLOW (-322) /* ssl/tls alerts */ -#define SL_ESEC_DECOMPRESSION_FAILURE (-330) /* ssl/tls alerts */ -#define SL_ESEC_HANDSHAKE_FAILURE (-340) /* ssl/tls alerts */ -#define SL_ESEC_NO_CERTIFICATE (-341) /* ssl/tls alerts */ -#define SL_ESEC_BAD_CERTIFICATE (-342) /* ssl/tls alerts */ -#define SL_ESEC_UNSUPPORTED_CERTIFICATE (-343) /* ssl/tls alerts */ -#define SL_ESEC_CERTIFICATE_REVOKED (-344) /* ssl/tls alerts */ -#define SL_ESEC_CERTIFICATE_EXPIRED (-345) /* ssl/tls alerts */ -#define SL_ESEC_CERTIFICATE_UNKNOWN (-346) /* ssl/tls alerts */ -#define SL_ESEC_ILLEGAL_PARAMETER (-347) /* ssl/tls alerts */ -#define SL_ESEC_UNKNOWN_CA (-348) /* ssl/tls alerts */ -#define SL_ESEC_ACCESS_DENIED (-349) /* ssl/tls alerts */ -#define SL_ESEC_DECODE_ERROR (-350) /* ssl/tls alerts */ -#define SL_ESEC_DECRYPT_ERROR (-351) /* ssl/tls alerts */ -#define SL_ESEC_EXPORT_RESTRICTION (-360) /* ssl/tls alerts */ -#define SL_ESEC_PROTOCOL_VERSION (-370) /* ssl/tls alerts */ -#define SL_ESEC_INSUFFICIENT_SECURITY (-371) /* ssl/tls alerts */ -#define SL_ESEC_INTERNAL_ERROR (-380) /* ssl/tls alerts */ -#define SL_ESEC_USER_CANCELLED (-390) /* ssl/tls alerts */ -#define SL_ESEC_NO_RENEGOTIATION (-400) /* ssl/tls alerts */ -#define SL_ESEC_UNSUPPORTED_EXTENSION (-410) /* ssl/tls alerts */ -#define SL_ESEC_CERTIFICATE_UNOBTAINABLE (-411) /* ssl/tls alerts */ -#define SL_ESEC_UNRECOGNIZED_NAME (-412) /* ssl/tls alerts */ -#define SL_ESEC_BAD_CERTIFICATE_STATUS_RESPONSE (-413) /* ssl/tls alerts */ -#define SL_ESEC_BAD_CERTIFICATE_HASH_VALUE (-414) /* ssl/tls alerts */ -/* propierty secure */ -#define SL_ESECGENERAL (-450) /* error secure level general error */ -#define SL_ESECDECRYPT (-451) /* error secure level, decrypt recv packet fail */ -#define SL_ESECCLOSED (-452) /* secure layrer is closed by other size , tcp is still connected */ -#define SL_ESECSNOVERIFY (-453) /* Connected without server verification */ -#define SL_ESECNOCAFILE (-454) /* error secure level CA file not found*/ -#define SL_ESECMEMORY (-455) /* error secure level No memory space available */ -#define SL_ESECBADCAFILE (-456) /* error secure level bad CA file */ -#define SL_ESECBADCERTFILE (-457) /* error secure level bad Certificate file */ -#define SL_ESECBADPRIVATEFILE (-458) /* error secure level bad private file */ -#define SL_ESECBADDHFILE (-459) /* error secure level bad DH file */ -#define SL_ESECT00MANYSSLOPENED (-460) /* MAX SSL Sockets are opened */ -#define SL_ESECDATEERROR (-461) /* connected with certificate date verification error */ -#define SL_ESECHANDSHAKETIMEDOUT (-462) /* connection timed out due to handshake time */ - -/* end error codes */ - -/* Max payload size by protocol */ -#define SL_SOCKET_PAYLOAD_TYPE_MASK (0xF0) /*4 bits type, 4 bits sockets id */ -#define SL_SOCKET_PAYLOAD_TYPE_UDP_IPV4 (0x00) /* 1472 bytes */ -#define SL_SOCKET_PAYLOAD_TYPE_TCP_IPV4 (0x10) /* 1460 bytes */ -#define SL_SOCKET_PAYLOAD_TYPE_UDP_IPV6 (0x20) /* 1452 bytes */ -#define SL_SOCKET_PAYLOAD_TYPE_TCP_IPV6 (0x30) /* 1440 bytes */ -#define SL_SOCKET_PAYLOAD_TYPE_UDP_IPV4_SECURE (0x40) /* */ -#define SL_SOCKET_PAYLOAD_TYPE_TCP_IPV4_SECURE (0x50) /* */ -#define SL_SOCKET_PAYLOAD_TYPE_UDP_IPV6_SECURE (0x60) /* */ -#define SL_SOCKET_PAYLOAD_TYPE_TCP_IPV6_SECURE (0x70) /* */ -#define SL_SOCKET_PAYLOAD_TYPE_RAW_TRANCEIVER (0x80) /* 1536 bytes */ -#define SL_SOCKET_PAYLOAD_TYPE_RAW_PACKET (0x90) /* 1536 bytes */ -#define SL_SOCKET_PAYLOAD_TYPE_RAW_IP4 (0xa0) -#define SL_SOCKET_PAYLOAD_TYPE_RAW_IP6 (SL_SOCKET_PAYLOAD_TYPE_RAW_IP4 ) - - - -#define SL_SOL_SOCKET (1) /* Define the socket option category. */ -#define SL_IPPROTO_IP (2) /* Define the IP option category. */ -#define SL_SOL_PHY_OPT (3) /* Define the PHY option category. */ - -#define SL_SO_RCVBUF (8) /* Setting TCP receive buffer size */ -#define SL_SO_KEEPALIVE (9) /* Connections are kept alive with periodic messages */ -#define SL_SO_RCVTIMEO (20) /* Enable receive timeout */ -#define SL_SO_NONBLOCKING (24) /* Enable . disable nonblocking mode */ -#define SL_SO_SECMETHOD (25) /* security metohd */ -#define SL_SO_SECURE_MASK (26) /* security mask */ -#define SL_SO_SECURE_FILES (27) /* security files */ -#define SL_SO_CHANGE_CHANNEL (28) /* This option is available only when transceiver started */ -#define SL_SO_SECURE_FILES_PRIVATE_KEY_FILE_NAME (30) /* This option used to configue secure file */ -#define SL_SO_SECURE_FILES_CERTIFICATE_FILE_NAME (31) /* This option used to configue secure file */ -#define SL_SO_SECURE_FILES_CA_FILE_NAME (32) /* This option used to configue secure file */ -#define SL_SO_SECURE_FILES_DH_KEY_FILE_NAME (33) /* This option used to configue secure file */ - -#define SL_IP_MULTICAST_IF (60) /* Specify outgoing multicast interface */ -#define SL_IP_MULTICAST_TTL (61) /* Specify the TTL value to use for outgoing multicast packet. */ -#define SL_IP_ADD_MEMBERSHIP (65) /* Join IPv4 multicast membership */ -#define SL_IP_DROP_MEMBERSHIP (66) /* Leave IPv4 multicast membership */ -#define SL_IP_HDRINCL (67) /* Raw socket IPv4 header included. */ -#define SL_IP_RAW_RX_NO_HEADER (68) /* Proprietary socket option that does not includeIPv4/IPv6 header (and extension headers) on received raw sockets*/ -#define SL_IP_RAW_IPV6_HDRINCL (69) /* Transmitted buffer over IPv6 socket contains IPv6 header. */ - -#define SL_SO_PHY_RATE (100) /* WLAN Transmit rate */ -#define SL_SO_PHY_TX_POWER (101) /* TX Power level */ -#define SL_SO_PHY_NUM_FRAMES_TO_TX (102) /* Number of frames to transmit */ -#define SL_SO_PHY_PREAMBLE (103) /* Preamble for transmission */ - -#define SL_SO_SEC_METHOD_SSLV3 (0) /* security metohd SSL v3*/ -#define SL_SO_SEC_METHOD_TLSV1 (1) /* security metohd TLS v1*/ -#define SL_SO_SEC_METHOD_TLSV1_1 (2) /* security metohd TLS v1_1*/ -#define SL_SO_SEC_METHOD_TLSV1_2 (3) /* security metohd TLS v1_2*/ -#define SL_SO_SEC_METHOD_SSLv3_TLSV1_2 (4) /* use highest possible version from SSLv3 - TLS 1.2*/ -#define SL_SO_SEC_METHOD_DLSV1 (5) /* security metohd DTL v1 */ - -#define SL_SEC_MASK_SSL_RSA_WITH_RC4_128_SHA (1 << 0) -#define SL_SEC_MASK_SSL_RSA_WITH_RC4_128_MD5 (1 << 1) -#define SL_SEC_MASK_TLS_RSA_WITH_AES_256_CBC_SHA (1 << 2) -#define SL_SEC_MASK_TLS_DHE_RSA_WITH_AES_256_CBC_SHA (1 << 3) -#define SL_SEC_MASK_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (1 << 4) -#define SL_SEC_MASK_TLS_ECDHE_RSA_WITH_RC4_128_SHA (1 << 5) -#define SL_SEC_MASK_TLS_RSA_WITH_AES_128_CBC_SHA256 (1 << 6) -#define SL_SEC_MASK_TLS_RSA_WITH_AES_256_CBC_SHA256 (1 << 7) -#define SL_SEC_MASK_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (1 << 8) -#define SL_SEC_MASK_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (1 << 9) - - -#define SL_SEC_MASK_SECURE_DEFAULT ((SL_SEC_MASK_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 << 1) - 1) - -#define SL_MSG_DONTWAIT (0x00000008) /* Nonblocking IO */ - -/* AP DHCP Server - IP Release reason code */ -#define SL_IP_LEASE_PEER_RELEASE (0) -#define SL_IP_LEASE_PEER_DECLINE (1) -#define SL_IP_LEASE_EXPIRED (2) - -/* possible types when receiving SL_SOCKET_ASYNC_EVENT*/ -#define SSL_ACCEPT (1) /* accept failed due to ssl issue ( tcp pass) */ -#define RX_FRAGMENTATION_TOO_BIG (2) /* connection less mode, rx packet fragmentation > 16K, packet is being released */ -#define OTHER_SIDE_CLOSE_SSL_DATA_NOT_ENCRYPTED (3) /* remote side down from secure to unsecure */ - - - -#ifdef SL_INC_STD_BSD_API_NAMING - -#define FD_SETSIZE SL_FD_SETSIZE - -#define SOCK_STREAM SL_SOCK_STREAM -#define SOCK_DGRAM SL_SOCK_DGRAM -#define SOCK_RAW SL_SOCK_RAW -#define IPPROTO_TCP SL_IPPROTO_TCP -#define IPPROTO_UDP SL_IPPROTO_UDP -#define IPPROTO_RAW SL_IPPROTO_RAW - -#define AF_INET SL_AF_INET -#define AF_INET6 SL_AF_INET6 -#define AF_INET6_EUI_48 SL_AF_INET6_EUI_48 -#define AF_RF SL_AF_RF -#define AF_PACKET SL_AF_PACKET - -#define PF_INET SL_PF_INET -#define PF_INET6 SL_PF_INET6 - -#define INADDR_ANY SL_INADDR_ANY -#define ERROR SL_SOC_ERROR -#define INEXE SL_INEXE -#define EBADF SL_EBADF -#define ENSOCK SL_ENSOCK -#define EAGAIN SL_EAGAIN -#define EWOULDBLOCK SL_EWOULDBLOCK -#define ENOMEM SL_ENOMEM -#define EACCES SL_EACCES -#define EFAULT SL_EFAULT -#define EINVAL SL_EINVAL -#define EDESTADDRREQ SL_EDESTADDRREQ -#define EPROTOTYPE SL_EPROTOTYPE -#define ENOPROTOOPT SL_ENOPROTOOPT -#define EPROTONOSUPPORT SL_EPROTONOSUPPORT -#define ESOCKTNOSUPPORT SL_ESOCKTNOSUPPORT -#define EOPNOTSUPP SL_EOPNOTSUPP -#define EAFNOSUPPORT SL_EAFNOSUPPORT -#define EADDRINUSE SL_EADDRINUSE -#define EADDRNOTAVAIL SL_EADDRNOTAVAIL -#define ENETUNREACH SL_ENETUNREACH -#define ENOBUFS SL_ENOBUFS -#define EOBUFF SL_EOBUFF -#define EISCONN SL_EISCONN -#define ENOTCONN SL_ENOTCONN -#define ETIMEDOUT SL_ETIMEDOUT -#define ECONNREFUSED SL_ECONNREFUSED - -#define SOL_SOCKET SL_SOL_SOCKET -#define IPPROTO_IP SL_IPPROTO_IP -#define SO_KEEPALIVE SL_SO_KEEPALIVE - -#define SO_RCVTIMEO SL_SO_RCVTIMEO -#define SO_NONBLOCKING SL_SO_NONBLOCKING - -#define IP_MULTICAST_IF SL_IP_MULTICAST_IF -#define IP_MULTICAST_TTL SL_IP_MULTICAST_TTL -#define IP_ADD_MEMBERSHIP SL_IP_ADD_MEMBERSHIP -#define IP_DROP_MEMBERSHIP SL_IP_DROP_MEMBERSHIP - -#define socklen_t SlSocklen_t -#define timeval SlTimeval_t -#define sockaddr SlSockAddr_t -#define in6_addr SlIn6Addr_t -#define sockaddr_in6 SlSockAddrIn6_t -#define in_addr SlInAddr_t -#define sockaddr_in SlSockAddrIn_t - -#define MSG_DONTWAIT SL_MSG_DONTWAIT - -#define FD_SET SL_FD_SET -#define FD_CLR SL_FD_CLR -#define FD_ISSET SL_FD_ISSET -#define FD_ZERO SL_FD_ZERO -#define fd_set SlFdSet_t - -#define socket sl_Socket -#define close sl_Close -#define accept sl_Accept -#define bind sl_Bind -#define listen sl_Listen -#define connect sl_Connect -#define select sl_Select -#define setsockopt sl_SetSockOpt -#define getsockopt sl_GetSockOpt -#define recv sl_Recv -#define recvfrom sl_RecvFrom -#define write sl_Write -#define send sl_Send -#define sendto sl_SendTo -#define gethostbyname sl_NetAppDnsGetHostByName -#define htonl sl_Htonl -#define ntohl sl_Ntohl -#define htons sl_Htons -#define ntohs sl_Ntohs -#endif - -/*****************************************************************************/ -/* Structure/Enum declarations */ -/*****************************************************************************/ - -/* Internet address */ -typedef struct SlInAddr_t -{ -#ifndef s_addr - _u32 s_addr; /* Internet address 32 bits */ -#else - union S_un { - struct { _u8 s_b1,s_b2,s_b3,s_b4; } S_un_b; - struct { _u8 s_w1,s_w2; } S_un_w; - _u32 S_addr; - } S_un; -#endif -}SlInAddr_t; - - -/* sockopt */ -typedef struct -{ - _u32 KeepaliveEnabled; /* 0 = disabled;1 = enabled; default = 1*/ -}SlSockKeepalive_t; - -typedef struct -{ - _u32 ReuseaddrEnabled; /* 0 = disabled; 1 = enabled; default = 1*/ -}SlSockReuseaddr_t; - -typedef struct -{ - _u32 Winsize; /* receive window size for tcp sockets */ -}SlSockWinsize_t; - -typedef struct -{ - _u32 NonblockingEnabled;/* 0 = disabled;1 = enabled;default = 1*/ -}SlSockNonblocking_t; - - -typedef struct -{ - _u8 sd; - _u8 type; - _i16 val; - _u8* pExtraInfo; -} SlSocketAsyncEvent_t; - -typedef struct -{ - _i16 status; - _u8 sd; - _u8 padding; -} SlSockTxFailEventData_t; - - -typedef union -{ - SlSockTxFailEventData_t SockTxFailData; - SlSocketAsyncEvent_t SockAsyncData; -} SlSockEventData_u; - - -typedef struct -{ - _u32 Event; - SlSockEventData_u socketAsyncEvent; -} SlSockEvent_t; - - - - - - -typedef struct -{ - _u32 secureMask; -} SlSockSecureMask; - -typedef struct -{ - _u8 secureMethod; -} SlSockSecureMethod; - -typedef enum -{ - SL_BSD_SECURED_PRIVATE_KEY_IDX = 0, - SL_BSD_SECURED_CERTIFICATE_IDX, - SL_BSD_SECURED_CA_IDX, - SL_BSD_SECURED_DH_IDX -}slBsd_secureSocketFilesIndex_e; - -typedef struct -{ - SlInAddr_t imr_multiaddr; /* The IPv4 multicast address to join */ - SlInAddr_t imr_interface; /* The interface to use for this group */ -} SlSockIpMreq; - - -/* sockopt */ -typedef _u32 SlTime_t; -typedef _u32 SlSuseconds_t; - -typedef struct SlTimeval_t -{ - SlTime_t tv_sec; /* Seconds */ - SlSuseconds_t tv_usec; /* Microseconds */ -}SlTimeval_t; - -typedef _u16 SlSocklen_t; - -/* IpV4 socket address */ -typedef struct SlSockAddr_t -{ - _u16 sa_family; /* Address family (e.g. , AF_INET) */ - _u8 sa_data[14]; /* Protocol- specific address information*/ -}SlSockAddr_t; - - -/* IpV6 or Ipv6 EUI64 */ -typedef struct SlIn6Addr_t -{ - union - { - _u8 _S6_u8[16]; - _u32 _S6_u32[4]; - } _S6_un; -}SlIn6Addr_t; - -typedef struct SlSockAddrIn6_t -{ - _u16 sin6_family; /* AF_INET6 || AF_INET6_EUI_48*/ - _u16 sin6_port; /* Transport layer port. */ - _u32 sin6_flowinfo; /* IPv6 flow information. */ - SlIn6Addr_t sin6_addr; /* IPv6 address. */ - _u32 sin6_scope_id; /* set of interfaces for a scope. */ -}SlSockAddrIn6_t; - -/* Socket address, Internet style. */ - -typedef struct SlSockAddrIn_t -{ - _u16 sin_family; /* Internet Protocol (AF_INET). */ - _u16 sin_port; /* Address port (16 bits). */ - SlInAddr_t sin_addr; /* Internet address (32 bits). */ - _i8 sin_zero[8]; /* Not used. */ -}SlSockAddrIn_t; - -typedef struct -{ - _u32 ip; - _u32 gateway; - _u32 dns; -}SlIpV4AcquiredAsync_t; - -typedef struct -{ - _u32 type; - _u32 ip[4]; - _u32 gateway[4]; - _u32 dns[4]; -}SlIpV6AcquiredAsync_t; - -typedef struct -{ - _u32 ip_address; - _u32 lease_time; - _u8 mac[6]; - _u16 padding; -}SlIpLeasedAsync_t; - -typedef struct -{ - _u32 ip_address; - _u8 mac[6]; - _u16 reason; -}SlIpReleasedAsync_t; - - -typedef union -{ - SlIpV4AcquiredAsync_t ipAcquiredV4; /*SL_NETAPP_IPV4_IPACQUIRED_EVENT*/ - SlIpV6AcquiredAsync_t ipAcquiredV6; /*SL_NETAPP_IPV6_IPACQUIRED_EVENT*/ - _u32 sd; /*SL_SOCKET_TX_FAILED_EVENT*/ - SlIpLeasedAsync_t ipLeased; /* SL_NETAPP_IP_LEASED_EVENT */ - SlIpReleasedAsync_t ipReleased; /* SL_NETAPP_IP_RELEASED_EVENT */ -} SlNetAppEventData_u; - -typedef struct -{ - _u32 Event; - SlNetAppEventData_u EventData; -}SlNetAppEvent_t; - - -typedef struct sock_secureFiles -{ - _u8 secureFiles[4]; -}SlSockSecureFiles_t; - - -typedef struct SlFdSet_t /* The select socket array manager */ -{ - _u32 fd_array[(SL_FD_SETSIZE + 31)/32]; /* Bit map of SOCKET Descriptors */ -} SlFdSet_t; - -typedef struct -{ - _u8 rate; /* Recevied Rate */ - _u8 channel; /* The received channel*/ - _i8 rssi; /* The computed RSSI value in db of current frame */ - _u8 padding; /* pad to align to 32 bits */ - _u32 timestamp; /* Timestamp in microseconds, */ -}SlTransceiverRxOverHead_t; - - - -/*****************************************************************************/ -/* Function prototypes */ -/*****************************************************************************/ - -/*! - - \brief create an endpoint for communication - - The socket function creates a new socket of a certain socket type, identified - by an integer number, and allocates system resources to it. - This function is called by the application layer to obtain a socket handle. - - \param[in] domain specifies the protocol family of the created socket. - For example: - AF_INET for network protocol IPv4 - AF_RF for starting transceiver mode. Notes: - - sending and receiving any packet overriding 802.11 header - - for optimized power consumption the socket will be started in TX - only mode until receive command is activated - AF_INET6 for IPv6 - - - \param[in] type specifies the communication semantic, one of: - SOCK_STREAM (reliable stream-oriented service or Stream Sockets) - SOCK_DGRAM (datagram service or Datagram Sockets) - SOCK_RAW (raw protocols atop the network layer) - when used with AF_RF: - SOCK_DGRAM - L2 socket - SOCK_RAW - L1 socket - bypass WLAN CCA (Clear Channel Assessment) - - \param[in] protocol specifies a particular transport to be used with - the socket. - The most common are IPPROTO_TCP, IPPROTO_SCTP, IPPROTO_UDP, - IPPROTO_DCCP. - The value 0 may be used to select a default - protocol from the selected domain and type - - - \return On success, socket handle that is used for consequent socket operations. - A successful return code should be a positive number (int16) - On error, a negative (int16) value will be returned specifying the error code. - SL_EAFNOSUPPORT - illegal domain parameter - SL_EPROTOTYPE - illegal type parameter - SL_EACCES - permission denied - SL_ENSOCK - exceeded maximal number of socket - SL_ENOMEM - memory allocation error - SL_EINVAL - error in socket configuration - SL_EPROTONOSUPPORT - illegal protocol parameter - SL_EOPNOTSUPP - illegal combination of protocol and type parameters - - - \sa sl_Close - \note belongs to \ref basic_api - \warning -*/ -#if _SL_INCLUDE_FUNC(sl_Socket) -_i16 sl_Socket(_i16 Domain, _i16 Type, _i16 Protocol); -#endif - -/*! - \brief gracefully close socket - - This function causes the system to release resources allocated to a socket. \n - In case of TCP, the connection is terminated. - - \param[in] sd socket handle (received in sl_Socket) - - \return On success, zero is returned. - On error, a negative number is returned. - - \sa sl_Socket - \note belongs to \ref ext_api - \warning -*/ -#if _SL_INCLUDE_FUNC(sl_Close) -_i16 sl_Close(_i16 sd); -#endif - -/*! - \brief Accept a connection on a socket - - This function is used with connection-based socket types (SOCK_STREAM). - It extracts the first connection request on the queue of pending - connections, creates a new connected socket, and returns a new file - descriptor referring to that socket. - The newly created socket is not in the listening state. The - original socket sd is unaffected by this call. - The argument sd is a socket that has been created with - sl_Socket(), bound to a local address with sl_Bind(), and is - listening for connections after a sl_Listen(). The argument \b - \e addr is a pointer to a sockaddr structure. This structure - is filled in with the address of the peer socket, as known to - the communications layer. The exact format of the address - returned addr is determined by the socket's address family. - The \b \e addrlen argument is a value-result argument: it - should initially contain the size of the structure pointed to - by addr, on return it will contain the actual length (in - bytes) of the address returned. - - \param[in] sd socket descriptor (handle) - \param[out] addr the argument addr is a pointer - to a sockaddr structure. This - structure is filled in with the - address of the peer socket, as - known to the communications - layer. The exact format of the - address returned addr is - determined by the socket's - address\n - sockaddr:\n - code for the - address format. On this version - only AF_INET is supported.\n - - socket address, the length - depends on the code format - \param[out] addrlen the addrlen argument is a value-result - argument: it should initially contain the - size of the structure pointed to by addr - - \return On success, a socket handle. - On a non-blocking accept a possible negative value is SL_EAGAIN. - On failure, negative value. - SL_POOL_IS_EMPTY may be return in case there are no resources in the system - In this case try again later or increase MAX_CONCURRENT_ACTIONS - - \sa sl_Socket sl_Bind sl_Listen - \note belongs to \ref server_side - \warning -*/ -#if _SL_INCLUDE_FUNC(sl_Accept) -_i16 sl_Accept(_i16 sd, SlSockAddr_t *addr, SlSocklen_t *addrlen); -#endif - -/*! - \brief assign a name to a socket - - This function gives the socket the local address addr. - addr is addrlen bytes long. Traditionally, this is called - When a socket is created with socket, it exists in a name - space (address family) but has no name assigned. - It is necessary to assign a local address before a SOCK_STREAM - socket may receive connections. - - \param[in] sd socket descriptor (handle) - \param[in] addr specifies the destination - addrs\n sockaddr:\n - code for - the address format. On this - version only AF_INET is - supported.\n - socket address, - the length depends on the code - format - \param[in] addrlen contains the size of the structure pointed to by addr - - \return On success, zero is returned. On error, a negative error code is returned. - - \sa sl_Socket sl_Accept sl_Listen - \note belongs to \ref basic_api - \warning -*/ -#if _SL_INCLUDE_FUNC(sl_Bind) -_i16 sl_Bind(_i16 sd, const SlSockAddr_t *addr, _i16 addrlen); -#endif - -/*! - \brief listen for connections on a socket - - The willingness to accept incoming connections and a queue - limit for incoming connections are specified with listen(), - and then the connections are accepted with accept. - The listen() call applies only to sockets of type SOCK_STREAM - The backlog parameter defines the maximum length the queue of - pending connections may grow to. - - \param[in] sd socket descriptor (handle) - \param[in] backlog specifies the listen queue depth. - - - \return On success, zero is returned. On error, a negative error code is returned. - - \sa sl_Socket sl_Accept sl_Bind - \note belongs to \ref server_side - \warning -*/ -#if _SL_INCLUDE_FUNC(sl_Listen) -_i16 sl_Listen(_i16 sd, _i16 backlog); -#endif - -/*! - \brief Initiate a connection on a socket - - Function connects the socket referred to by the socket - descriptor sd, to the address specified by addr. The addrlen - argument specifies the size of addr. The format of the - address in addr is determined by the address space of the - socket. If it is of type SOCK_DGRAM, this call specifies the - peer with which the socket is to be associated; this address - is that to which datagrams are to be sent, and the only - address from which datagrams are to be received. If the - socket is of type SOCK_STREAM, this call attempts to make a - connection to another socket. The other socket is specified - by address, which is an address in the communications space - of the socket. - - - \param[in] sd socket descriptor (handle) - \param[in] addr specifies the destination addr\n - sockaddr:\n - code for the - address format. On this version - only AF_INET is supported.\n - - socket address, the length - depends on the code format - - \param[in] addrlen contains the size of the structure pointed - to by addr - - \return On success, a socket handle. - On a non-blocking connect a possible negative value is SL_EALREADY. - On failure, negative value. - SL_POOL_IS_EMPTY may be return in case there are no resources in the system - In this case try again later or increase MAX_CONCURRENT_ACTIONS - - \sa sl_Socket - \note belongs to \ref client_side - \warning -*/ -#if _SL_INCLUDE_FUNC(sl_Connect) -_i16 sl_Connect(_i16 sd, const SlSockAddr_t *addr, _i16 addrlen); -#endif - -/*! - \brief Monitor socket activity - - Select allow a program to monitor multiple file descriptors, - waiting until one or more of the file descriptors become - "ready" for some class of I/O operation - - - \param[in] nfds the highest-numbered file descriptor in any of the - three sets, plus 1. - \param[out] readsds socket descriptors list for read monitoring and accept monitoring - \param[out] writesds socket descriptors list for connect monitoring only, write monitoring is not supported, non blocking connect is supported - \param[out] exceptsds socket descriptors list for exception monitoring, not supported. - \param[in] timeout is an upper bound on the amount of time elapsed - before select() returns. Null or above 0xffff seconds means - infinity timeout. The minimum timeout is 10 milliseconds, - less than 10 milliseconds will be set automatically to 10 milliseconds. - Max microseconds supported is 0xfffc00. - - \return On success, select() returns the number of - file descriptors contained in the three returned - descriptor sets (that is, the total number of bits that - are set in readfds, writefds, exceptfds) which may be - zero if the timeout expires before anything interesting - happens. On error, a negative value is returned. - readsds - return the sockets on which Read request will - return without delay with valid data. - writesds - return the sockets on which Write request - will return without delay. - exceptsds - return the sockets closed recently. - SL_POOL_IS_EMPTY may be return in case there are no resources in the system - In this case try again later or increase MAX_CONCURRENT_ACTIONS - - \sa sl_Socket - \note If the timeout value set to less than 5ms it will automatically set - to 5ms to prevent overload of the system - belongs to \ref basic_api - - Only one sl_Select can be handled at a time. - Calling this API while the same command is called from another thread, may result - in one of the two scenarios: - 1. The command will wait (internal) until the previous command finish, and then be executed. - 2. There are not enough resources and SL_POOL_IS_EMPTY error will return. - In this case, MAX_CONCURRENT_ACTIONS can be increased (result in memory increase) or try - again later to issue the command. - - \warning -*/ -#if _SL_INCLUDE_FUNC(sl_Select) -_i16 sl_Select(_i16 nfds, SlFdSet_t *readsds, SlFdSet_t *writesds, SlFdSet_t *exceptsds, struct SlTimeval_t *timeout); - - -/*! - \brief Select's SlFdSet_t SET function - - Sets current socket descriptor on SlFdSet_t container -*/ -void SL_FD_SET(_i16 fd, SlFdSet_t *fdset); - -/*! - \brief Select's SlFdSet_t CLR function - - Clears current socket descriptor on SlFdSet_t container -*/ -void SL_FD_CLR(_i16 fd, SlFdSet_t *fdset); - - -/*! - \brief Select's SlFdSet_t ISSET function - - Checks if current socket descriptor is set (TRUE/FALSE) - - \return Returns TRUE if set, FALSE if unset - -*/ -_i16 SL_FD_ISSET(_i16 fd, SlFdSet_t *fdset); - -/*! - \brief Select's SlFdSet_t ZERO function - - Clears all socket descriptors from SlFdSet_t -*/ -void SL_FD_ZERO(SlFdSet_t *fdset); - - - -#endif - -/*! - \brief set socket options - - This function manipulate the options associated with a socket. - Options may exist at multiple protocol levels; they are always - present at the uppermost socket level. - - When manipulating socket options the level at which the option resides - and the name of the option must be specified. To manipulate options at - the socket level, level is specified as SOL_SOCKET. To manipulate - options at any other level the protocol number of the appropriate proto- - col controlling the option is supplied. For example, to indicate that an - option is to be interpreted by the TCP protocol, level should be set to - the protocol number of TCP; - - The parameters optval and optlen are used to access optval - - ues for setsockopt(). For getsockopt() they identify a - buffer in which the value for the requested option(s) are to - be returned. For getsockopt(), optlen is a value-result - parameter, initially containing the size of the buffer - pointed to by option_value, and modified on return to - indicate the actual size of the value returned. If no option - value is to be supplied or returned, option_value may be - NULL. - - \param[in] sd socket handle - \param[in] level defines the protocol level for this option - - SL_SOL_SOCKET Socket level configurations (L4, transport layer) - - SL_IPPROTO_IP IP level configurations (L3, network layer) - - SL_SOL_PHY_OPT Link level configurations (L2, link layer) - \param[in] optname defines the option name to interrogate - - SL_SOL_SOCKET - - SL_SO_KEEPALIVE \n - Enable/Disable periodic keep alive. - Keeps TCP connections active by enabling the periodic transmission of messages \n - Timeout is 5 minutes.\n - Default: Enabled \n - This options takes SlSockKeepalive_t struct as parameter - - SL_SO_RCVTIMEO \n - Sets the timeout value that specifies the maximum amount of time an input function waits until it completes. \n - Default: No timeout \n - This options takes SlTimeval_t struct as parameter - - SL_SO_RCVBUF \n - Sets tcp max recv window size. \n - This options takes SlSockWinsize_t struct as parameter - - SL_SO_NONBLOCKING \n - Sets socket to non-blocking operation Impacts: connect, accept, send, sendto, recv and recvfrom. \n - Default: Blocking. - This options takes SlSockNonblocking_t struct as parameter - - SL_SO_SECMETHOD \n - Sets method to tcp secured socket (SL_SEC_SOCKET) \n - Default: SL_SO_SEC_METHOD_SSLv3_TLSV1_2 \n - This options takes SlSockSecureMethod struct as parameter - - SL_SO_SEC_MASK \n - Sets specific cipher to tcp secured socket (SL_SEC_SOCKET) \n - Default: "Best" cipher suitable to method \n - This options takes SlSockSecureMask struct as parameter - - SL_SO_SECURE_FILES_CA_FILE_NAME \n - Map secured socket to CA file by name \n - This options takes _u8 buffer as parameter - - SL_SO_SECURE_FILES_PRIVATE_KEY_FILE_NAME \n - Map secured socket to private key by name \n - This options takes _u8 buffer as parameter - - SL_SO_SECURE_FILES_CERTIFICATE_FILE_NAME \n - Map secured socket to certificate file by name \n - This options takes _u8 buffer as parameter - - SL_SO_SECURE_FILES_DH_KEY_FILE_NAME \n - Map secured socket to Diffie Hellman file by name \n - This options takes _u8 buffer as parameter - - SL_SO_CHANGE_CHANNEL \n - Sets channel in transceiver mode. - This options takes _u32 as channel number parameter - - SL_IPPROTO_IP - - SL_IP_MULTICAST_TTL \n - Set the time-to-live value of outgoing multicast packets for this socket. \n - This options takes _u8 as parameter - - SL_IP_ADD_MEMBERSHIP \n - UDP socket, Join a multicast group. \n - This options takes SlSockIpMreq struct as parameter - - SL_IP_DROP_MEMBERSHIP \n - UDP socket, Leave a multicast group \n - This options takes SlSockIpMreq struct as parameter - - SL_IP_RAW_RX_NO_HEADER \n - Raw socket remove IP header from received data. \n - Default: data includes ip header \n - This options takes _u32 as parameter - - SL_IP_HDRINCL \n - RAW socket only, the IPv4 layer generates an IP header when sending a packet unless \n - the IP_HDRINCL socket option is enabled on the socket. \n - When it is enabled, the packet must contain an IP header. \n - Default: disabled, IPv4 header generated by Network Stack \n - This options takes _u32 as parameter - - SL_IP_RAW_IPV6_HDRINCL (inactive) \n - RAW socket only, the IPv6 layer generates an IP header when sending a packet unless \n - the IP_HDRINCL socket option is enabled on the socket. When it is enabled, the packet must contain an IP header \n - Default: disabled, IPv4 header generated by Network Stack \n - This options takes _u32 as parameter - - SL_SOL_PHY_OPT - - SL_SO_PHY_RATE \n - RAW socket, set WLAN PHY transmit rate \n - The values are based on RateIndex_e \n - This options takes _u32 as parameter - - SL_SO_PHY_TX_POWER \n - RAW socket, set WLAN PHY TX power \n - Valid rage is 1-15 \n - This options takes _u32 as parameter - - SL_SO_PHY_NUM_FRAMES_TO_TX \n - RAW socket, set number of frames to transmit in transceiver mode. - Default: 1 packet - This options takes _u32 as parameter - - SL_SO_PHY_PREAMBLE \n - RAW socket, set WLAN PHY preamble for Long/Short\n - This options takes _u32 as parameter - - \param[in] optval specifies a value for the option - \param[in] optlen specifies the length of the - option value - - \return On success, zero is returned. - On error, a negative value is returned. - \sa sl_getsockopt - \note belongs to \ref basic_api - \warning - \par Examples: - \par - SL_SO_KEEPALIVE: (disable Keepalive) - \code - SlSockKeepalive_t enableOption; - enableOption.KeepaliveEnabled = 0; - sl_SetSockOpt(SockID,SL_SOL_SOCKET,SL_SO_KEEPALIVE, (_u8 *)&enableOption,sizeof(enableOption)); - \endcode - \par - SL_SO_RCVTIMEO: - \code - struct SlTimeval_t timeVal; - timeVal.tv_sec = 1; // Seconds - timeVal.tv_usec = 0; // Microseconds. 10000 microseconds resolution - sl_SetSockOpt(SockID,SL_SOL_SOCKET,SL_SO_RCVTIMEO, (_u8 *)&timeVal, sizeof(timeVal)); // Enable receive timeout - \endcode - \par - SL_SO_RCVBUF: - \code - SlSockWinsize_t size; - size.Winsize = 3000; // bytes - sl_SetSockOpt(SockID,SL_SOL_SOCKET,SL_SO_RCVBUF, (_u8 *)&size, sizeof(size)); - \endcode - \par - SL_SO_NONBLOCKING: - \code - SlSockNonblocking_t enableOption; - enableOption.NonblockingEnabled = 1; - sl_SetSockOpt(SockID,SL_SOL_SOCKET,SL_SO_NONBLOCKING, (_u8 *)&enableOption,sizeof(enableOption)); // Enable/disable nonblocking mode - \endcode - \par - SL_SO_SECMETHOD: - \code - SlSockSecureMethod method; - method.secureMethod = SL_SO_SEC_METHOD_SSLV3; // security method we want to use - SockID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, SL_SEC_SOCKET); - sl_SetSockOpt(SockID, SL_SOL_SOCKET, SL_SO_SECMETHOD, (_u8 *)&method, sizeof(method)); - \endcode - \par - SL_SO_SECURE_MASK: - \code - SlSockSecureMask cipher; - cipher.secureMask = SL_SEC_MASK_SSL_RSA_WITH_RC4_128_SHA; // cipher type - SockID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, SL_SEC_SOCKET); - sl_SetSockOpt(SockID, SL_SOL_SOCKET, SL_SO_SEC_MASK,(_u8 *)&cipher, sizeof(cipher)); - \endcode - \par - SL_SO_SECURE_FILES_CA_FILE_NAME: - \code - sl_SetSockOpt(SockID,SL_SOL_SOCKET,SL_SO_SECURE_FILES_CA_FILE_NAME,"exuifaxCaCert.der",strlen("exuifaxCaCert.der")); - \endcode - - \par - SL_SO_SECURE_FILES_PRIVATE_KEY_FILE_NAME: - \code - sl_SetSockOpt(SockID,SL_SOL_SOCKET,SL_SO_SECURE_FILES_PRIVATE_KEY_FILE_NAME,"myPrivateKey.der",strlen("myPrivateKey.der")); - \endcode - - \par - SL_SO_SECURE_FILES_CERTIFICATE_FILE_NAME: - \code - sl_SetSockOpt(SockID,SL_SOL_SOCKET,SL_SO_SECURE_FILES_CERTIFICATE_FILE_NAME,"myCertificate.der",strlen("myCertificate.der")); - \endcode - - \par - SL_SO_SECURE_FILES_DH_KEY_FILE_NAME: - \code - sl_SetSockOpt(SockID,SL_SOL_SOCKET,SL_SO_SECURE_FILES_DH_KEY_FILE_NAME,"myDHinServerMode.der",strlen("myDHinServerMode.der")); - \endcode - - \par - SL_IP_MULTICAST_TTL: - \code - _u8 ttl = 20; - sl_SetSockOpt(SockID, SL_IPPROTO_IP, SL_IP_MULTICAST_TTL, &ttl, sizeof(ttl)); - \endcode - - \par - SL_IP_ADD_MEMBERSHIP: - \code - SlSockIpMreq mreq; - sl_SetSockOpt(SockID, SL_IPPROTO_IP, SL_IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); - \endcode - - \par - SL_IP_DROP_MEMBERSHIP: - \code - SlSockIpMreq mreq; - sl_SetSockOpt(SockID, SL_IPPROTO_IP, SL_IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)); - \endcode - - \par - SL_SO_CHANGE_CHANNEL: - \code - _u32 newChannel = 6; // range is 1-13 - sl_SetSockOpt(SockID, SL_SOL_SOCKET, SL_SO_CHANGE_CHANNEL, &newChannel, sizeof(newChannel)); - \endcode - - \par - SL_IP_RAW_RX_NO_HEADER: - \code - _u32 header = 1; // remove ip header - sl_SetSockOpt(SockID, SL_IPPROTO_IP, SL_IP_RAW_RX_NO_HEADER, &header, sizeof(header)); - \endcode - - \par - SL_IP_HDRINCL: - \code - _u32 header = 1; - sl_SetSockOpt(SockID, SL_IPPROTO_IP, SL_IP_HDRINCL, &header, sizeof(header)); - \endcode - \par - SL_IP_RAW_IPV6_HDRINCL: - \code - _u32 header = 1; - sl_SetSockOpt(SockID, SL_IPPROTO_IP, SL_IP_RAW_IPV6_HDRINCL, &header, sizeof(header)); - \endcode - - \par - SL_SO_PHY_RATE: - \code - _u32 rate = 6; // see wlan.h RateIndex_e for values - sl_SetSockOpt(SockID, SL_SOL_PHY_OPT, SL_SO_PHY_RATE, &rate, sizeof(rate)); - \endcode - - \par - SL_SO_PHY_TX_POWER: - \code - _u32 txpower = 1; // valid range is 1-15 - sl_SetSockOpt(SockID, SL_SOL_PHY_OPT, SL_SO_PHY_TX_POWER, &txpower, sizeof(txpower)); - \endcode - - \par - SL_SO_PHY_NUM_FRAMES_TO_TX: - \code - _u32 numframes = 1; - sl_SetSockOpt(SockID, SL_SOL_PHY_OPT, SL_SO_PHY_NUM_FRAMES_TO_TX, &numframes, sizeof(numframes)); - \endcode - - \par - SL_SO_PHY_PREAMBLE: - \code - _u32 preamble = 1; - sl_SetSockOpt(SockID, SL_SOL_PHY_OPT, SL_SO_PHY_PREAMBLE, &preamble, sizeof(preamble)); - \endcode - -*/ -#if _SL_INCLUDE_FUNC(sl_SetSockOpt) -_i16 sl_SetSockOpt(_i16 sd, _i16 level, _i16 optname, const void *optval, SlSocklen_t optlen); -#endif - -/*! - \brief Get socket options - - This function manipulate the options associated with a socket. - Options may exist at multiple protocol levels; they are always - present at the uppermost socket level. - - When manipulating socket options the level at which the option resides - and the name of the option must be specified. To manipulate options at - the socket level, level is specified as SOL_SOCKET. To manipulate - options at any other level the protocol number of the appropriate proto- - col controlling the option is supplied. For example, to indicate that an - option is to be interpreted by the TCP protocol, level should be set to - the protocol number of TCP; - - The parameters optval and optlen are used to access optval - - ues for setsockopt(). For getsockopt() they identify a - buffer in which the value for the requested option(s) are to - be returned. For getsockopt(), optlen is a value-result - parameter, initially containing the size of the buffer - pointed to by option_value, and modified on return to - indicate the actual size of the value returned. If no option - value is to be supplied or returned, option_value may be - NULL. - - - \param[in] sd socket handle - \param[in] level defines the protocol level for this option - \param[in] optname defines the option name to interrogate - \param[out] optval specifies a value for the option - \param[out] optlen specifies the length of the - option value - - \return On success, zero is returned. - On error, a negative value is returned. - \sa sl_SetSockOpt - \note See sl_SetSockOpt - belongs to \ref ext_api - \warning -*/ -#if _SL_INCLUDE_FUNC(sl_GetSockOpt) -_i16 sl_GetSockOpt(_i16 sd, _i16 level, _i16 optname, void *optval, SlSocklen_t *optlen); -#endif - -/*! - \brief read data from TCP socket - - function receives a message from a connection-mode socket - - \param[in] sd socket handle - \param[out] buf Points to the buffer where the - message should be stored. - \param[in] Len Specifies the length in bytes of - the buffer pointed to by the buffer argument. - Range: 1-16000 bytes - \param[in] flags Specifies the type of message - reception. On this version, this parameter is not - supported. - - \return return the number of bytes received, - or a negative value if an error occurred. - using a non-blocking recv a possible negative value is SL_EAGAIN. - SL_POOL_IS_EMPTY may be return in case there are no resources in the system - In this case try again later or increase MAX_CONCURRENT_ACTIONS - - \sa sl_RecvFrom - \note belongs to \ref recv_api - \warning - \par Examples: - \code An example of receiving data using TCP socket: - - SlSockAddrIn_t Addr; - SlSockAddrIn_t LocalAddr; - _i16 AddrSize = sizeof(SlSockAddrIn_t); - _i16 SockID, newSockID; - _i16 Status; - _i8 Buf[RECV_BUF_LEN]; - - LocalAddr.sin_family = SL_AF_INET; - LocalAddr.sin_port = sl_Htons(5001); - LocalAddr.sin_addr.s_addr = 0; - - Addr.sin_family = SL_AF_INET; - Addr.sin_port = sl_Htons(5001); - Addr.sin_addr.s_addr = sl_Htonl(SL_IPV4_VAL(10,1,1,200)); - - SockID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0); - Status = sl_Bind(SockID, (SlSockAddr_t *)&LocalAddr, AddrSize); - Status = sl_Listen(SockID, 0); - newSockID = sl_Accept(SockID, (SlSockAddr_t*)&Addr, (SlSocklen_t*) &AddrSize); - Status = sl_Recv(newSockID, Buf, 1460, 0); - \endcode - \code Example code for Rx transceiver mode using a raw socket - _i8 buffer[1536]; - _i16 sd; - _u16 size; - SlTransceiverRxOverHead_t *transHeader; - sd = sl_Socket(SL_AF_RF,SL_SOCK_RAW,11); // channel 11 - while(1) - { - size = sl_Recv(sd,buffer,1536,0); - transHeader = (SlTransceiverRxOverHead_t *)buffer; - printf("RSSI is %d frame type is 0x%x size %d\n",transHeader->rssi,buffer[sizeof(SlTransceiverRxOverHead_t)],size); - } - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_Recv) -_i16 sl_Recv(_i16 sd, void *buf, _i16 Len, _i16 flags); -#endif - -/*! - \brief read data from socket - - function receives a message from a connection-mode or - connectionless-mode socket - - \param[in] sd socket handle - \param[out] buf Points to the buffer where the message should be stored. - \param[in] Len Specifies the length in bytes of the buffer pointed to by the buffer argument. - Range: 1-16000 bytes - \param[in] flags Specifies the type of message - reception. On this version, this parameter is not - supported. - \param[in] from pointer to an address structure - indicating the source - address.\n sockaddr:\n - code - for the address format. On this - version only AF_INET is - supported.\n - socket address, - the length depends on the code - format - \param[in] fromlen source address structure - size. This parameter MUST be set to the size of the structure pointed to by addr. - - - \return return the number of bytes received, - or a negative value if an error occurred. - using a non-blocking recv a possible negative value is SL_EAGAIN. - SL_RET_CODE_INVALID_INPUT (-2) will be returned if fromlen has incorrect length. - SL_POOL_IS_EMPTY may be return in case there are no resources in the system - In this case try again later or increase MAX_CONCURRENT_ACTIONS - - \sa sl_Recv - \note belongs to \ref recv_api - \warning - \par Example: - \code An example of receiving data: - - SlSockAddrIn_t Addr; - SlSockAddrIn_t LocalAddr; - _i16 AddrSize = sizeof(SlSockAddrIn_t); - _i16 SockID; - _i16 Status; - _i8 Buf[RECV_BUF_LEN]; - - LocalAddr.sin_family = SL_AF_INET; - LocalAddr.sin_port = sl_Htons(5001); - LocalAddr.sin_addr.s_addr = 0; - - SockID = sl_Socket(SL_AF_INET,SL_SOCK_DGRAM, 0); - Status = sl_Bind(SockID, (SlSockAddr_t *)&LocalAddr, AddrSize); - Status = sl_RecvFrom(SockID, Buf, 1472, 0, (SlSockAddr_t *)&Addr, (SlSocklen_t*)&AddrSize); - - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_RecvFrom) -_i16 sl_RecvFrom(_i16 sd, void *buf, _i16 Len, _i16 flags, SlSockAddr_t *from, SlSocklen_t *fromlen); -#endif - -/*! - \brief write data to TCP socket - - This function is used to transmit a message to another socket. - Returns immediately after sending data to device. - In case of TCP failure an async event SL_SOCKET_TX_FAILED_EVENT is going to - be received. - In case of a RAW socket (transceiver mode), extra 4 bytes should be reserved at the end of the - frame data buffer for WLAN FCS - - \param[in] sd socket handle - \param[in] buf Points to a buffer containing - the message to be sent - \param[in] Len message size in bytes. Range: 1-1460 bytes - \param[in] flags Specifies the type of message - transmission. On this version, this parameter is not - supported for TCP. - For transceiver mode, the SL_RAW_RF_TX_PARAMS macro can be used to determine - transmission parameters (channel,rate,tx_power,preamble) - - - \return Return the number of bytes transmitted, - or -1 if an error occurred - - \sa sl_SendTo - \note belongs to \ref send_api - \warning - \par Example: - \code An example of sending data: - - SlSockAddrIn_t Addr; - _i16 AddrSize = sizeof(SlSockAddrIn_t); - _i16 SockID; - _i16 Status; - _i8 Buf[SEND_BUF_LEN]; - - Addr.sin_family = SL_AF_INET; - Addr.sin_port = sl_Htons(5001); - Addr.sin_addr.s_addr = sl_Htonl(SL_IPV4_VAL(10,1,1,200)); - - SockID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0); - Status = sl_Connect(SockID, (SlSockAddr_t *)&Addr, AddrSize); - Status = sl_Send(SockID, Buf, 1460, 0 ); - - \endcode - */ -#if _SL_INCLUDE_FUNC(sl_Send ) -_i16 sl_Send(_i16 sd, const void *buf, _i16 Len, _i16 flags); -#endif - -/*! - \brief write data to socket - - This function is used to transmit a message to another socket - (connection less socket SOCK_DGRAM, SOCK_RAW). - Returns immediately after sending data to device. - In case of transmission failure an async event SL_SOCKET_TX_FAILED_EVENT is going to - be received. - - \param[in] sd socket handle - \param[in] buf Points to a buffer containing - the message to be sent - \param[in] Len message size in bytes. Range: 1-1460 bytes - \param[in] flags Specifies the type of message - transmission. On this version, this parameter is not - supported - \param[in] to pointer to an address structure - indicating the destination - address.\n sockaddr:\n - code - for the address format. On this - version only AF_INET is - supported.\n - socket address, - the length depends on the code - format - \param[in] tolen destination address structure size - - \return Return the number of transmitted bytes, - or -1 if an error occurred - - \sa sl_Send - \note belongs to \ref send_api - \warning - \par Example: - \code An example of sending data: - - SlSockAddrIn_t Addr; - _i16 AddrSize = sizeof(SlSockAddrIn_t); - _i16 SockID; - _i16 Status; - _i8 Buf[SEND_BUF_LEN]; - - Addr.sin_family = SL_AF_INET; - Addr.sin_port = sl_Htons(5001); - Addr.sin_addr.s_addr = sl_Htonl(SL_IPV4_VAL(10,1,1,200)); - - SockID = sl_Socket(SL_AF_INET,SL_SOCK_DGRAM, 0); - Status = sl_SendTo(SockID, Buf, 1472, 0, (SlSockAddr_t *)&Addr, AddrSize); - - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_SendTo) -_i16 sl_SendTo(_i16 sd, const void *buf, _i16 Len, _i16 flags, const SlSockAddr_t *to, SlSocklen_t tolen); -#endif - -/*! - \brief Reorder the bytes of a 32-bit unsigned value - - This function is used to Reorder the bytes of a 32-bit unsigned value from processor order to network order. - - \param[in] var variable to reorder - - \return Return the reorder variable, - - \sa sl_SendTo sl_Bind sl_Connect sl_RecvFrom sl_Accept - \note belongs to \ref send_api - \warning -*/ -#if _SL_INCLUDE_FUNC(sl_Htonl ) -_u32 sl_Htonl( _u32 val ); - -#define sl_Ntohl sl_Htonl /* Reorder the bytes of a 16-bit unsigned value from network order to processor orde. */ -#endif - -/*! - \brief Reorder the bytes of a 16-bit unsigned value - - This function is used to Reorder the bytes of a 16-bit unsigned value from processor order to network order. - - \param[in] var variable to reorder - - \return Return the reorder variable, - - \sa sl_SendTo sl_Bind sl_Connect sl_RecvFrom sl_Accept - \note belongs to \ref send_api - \warning -*/ -#if _SL_INCLUDE_FUNC(sl_Htons ) -_u16 sl_Htons( _u16 val ); - -#define sl_Ntohs sl_Htons /* Reorder the bytes of a 16-bit unsigned value from network order to processor orde. */ -#endif - -/*! - - Close the Doxygen group. - @} - - */ - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __SOCKET_H__ */ - - diff --git a/drivers/cc3100/inc/spawn.h b/drivers/cc3100/inc/spawn.h deleted file mode 100644 index 82c112d2e13..00000000000 --- a/drivers/cc3100/inc/spawn.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * spawn.h - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - -#ifndef __NONOS_H__ -#define __NONOS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - - -#if (defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN)) - -extern void _SlInternalSpawnTaskEntry(); -extern _i16 _SlInternalSpawn(_SlSpawnEntryFunc_t pEntry , void* pValue , _u32 flags); - -#undef sl_Spawn -#define sl_Spawn(pEntry,pValue,flags) _SlInternalSpawn(pEntry,pValue,flags) - -#undef _SlTaskEntry -#define _SlTaskEntry _SlInternalSpawnTaskEntry - - -#endif - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif diff --git a/drivers/cc3100/inc/trace.h b/drivers/cc3100/inc/trace.h deleted file mode 100644 index 4ca42c77016..00000000000 --- a/drivers/cc3100/inc/trace.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * trace.h - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - - - -#include "simplelink.h" - -#ifndef __SIMPLELINK_TRACE_H__ -#define __SIMPLELINK_TRACE_H__ - - -#ifdef __cplusplus -extern "C" { -#endif - -/*****************************************************************************/ -/* Macro declarations */ -/*****************************************************************************/ - -#define SL_SYNC_SCAN_THRESHOLD (( _u32 )2000) - -#define _SL_ASSERT(expr) { ASSERT(expr); } -#define _SL_ERROR(expr, error) { if(!(expr)){return (error); } } - -#define SL_HANDLING_ASSERT 2 -#define SL_HANDLING_ERROR 1 -#define SL_HANDLING_NONE 0 - -#define SL_SELF_COND_HANDLING SL_HANDLING_NONE -#define SL_PROTOCOL_HANDLING SL_HANDLING_NONE -#define SL_DRV_RET_CODE_HANDLING SL_HANDLING_NONE -#define SL_NWP_IF_HANDLING SL_HANDLING_NONE -#define SL_OSI_RET_OK_HANDLING SL_HANDLING_NONE -#define SL_MALLOC_OK_HANDLING SL_HANDLING_NONE -#define SL_USER_ARGS_HANDLING SL_HANDLING_NONE - -#if (SL_DRV_RET_CODE_HANDLING == SL_HANDLING_ASSERT) -#define VERIFY_RET_OK(Func) {_SlReturnVal_t _RetVal = (Func); _SL_ASSERT((_SlReturnVal_t)SL_OS_RET_CODE_OK == _RetVal)} -#elif (SL_DRV_RET_CODE_HANDLING == SL_HANDLING_ERROR) -#define VERIFY_RET_OK(Func) {_SlReturnVal_t _RetVal = (Func); if (SL_OS_RET_CODE_OK != _RetVal) return _RetVal;} -#else -#define VERIFY_RET_OK(Func) (Func); -#endif - -#if (SL_PROTOCOL_HANDLING == SL_HANDLING_ASSERT) -#define VERIFY_PROTOCOL(expr) _SL_ASSERT(expr) -#elif (SL_PROTOCOL_HANDLING == SL_HANDLING_ERROR) -#define VERIFY_PROTOCOL(expr) _SL_ERROR(expr, SL_RET_CODE_PROTOCOL_ERROR) -#else -#define VERIFY_PROTOCOL(expr) -#endif - -#if (defined(PROTECT_SOCKET_ASYNC_RESP) && (SL_SELF_COND_HANDLING == SL_HANDLING_ASSERT)) -#define VERIFY_SOCKET_CB(expr) _SL_ASSERT(expr) -#elif (defined(PROTECT_SOCKET_ASYNC_RESP) && (SL_SELF_COND_HANDLING == SL_HANDLING_ERROR)) -#define VERIFY_SOCKET_CB(expr) _SL_ERROR(expr, SL_RET_CODE_SELF_ERROR) -#else -#define VERIFY_SOCKET_CB(expr) -#endif - -#if (SL_NWP_IF_HANDLING == SL_HANDLING_ASSERT) -#define NWP_IF_WRITE_CHECK(fd,pBuff,len) { _i16 RetSize, ExpSize = (len); RetSize = sl_IfWrite((fd),(pBuff),ExpSize); _SL_ASSERT(ExpSize == RetSize)} -#define NWP_IF_READ_CHECK(fd,pBuff,len) { _i16 RetSize, ExpSize = (len); RetSize = sl_IfRead((fd),(pBuff),ExpSize); _SL_ASSERT(ExpSize == RetSize)} -#elif (SL_NWP_IF_HANDLING == SL_HANDLING_ERROR) -#define NWP_IF_WRITE_CHECK(fd,pBuff,len) { _SL_ERROR((len == sl_IfWrite((fd),(pBuff),(len))), SL_RET_CODE_NWP_IF_ERROR);} -#define NWP_IF_READ_CHECK(fd,pBuff,len) { _SL_ERROR((len == sl_IfRead((fd),(pBuff),(len))), SL_RET_CODE_NWP_IF_ERROR);} -#else -#define NWP_IF_WRITE_CHECK(fd,pBuff,len) { sl_IfWrite((fd),(pBuff),(len));} -#define NWP_IF_READ_CHECK(fd,pBuff,len) { sl_IfRead((fd),(pBuff),(len));} -#endif - -#if (SL_OSI_RET_OK_HANDLING == SL_HANDLING_ASSERT) -#define OSI_RET_OK_CHECK(Func) {_SlReturnVal_t _RetVal = (Func); _SL_ASSERT((_SlReturnVal_t)SL_OS_RET_CODE_OK == _RetVal)} -#elif (SL_OSI_RET_OK_HANDLING == SL_HANDLING_ERROR) -#define OSI_RET_OK_CHECK(Func) {_SlReturnVal_t _RetVal = (Func); if (SL_OS_RET_CODE_OK != _RetVal) return _RetVal;} -#else -#define OSI_RET_OK_CHECK(Func) (Func); -#endif - -#if (SL_MALLOC_OK_HANDLING == SL_HANDLING_ASSERT) -#define MALLOC_OK_CHECK(Ptr) _SL_ASSERT(NULL != Ptr) -#elif (SL_MALLOC_OK_HANDLING == SL_HANDLING_ERROR) -#define MALLOC_OK_CHECK(Ptr) _SL_ERROR((NULL != Ptr), SL_RET_CODE_MALLOC_ERROR) -#else -#define MALLOC_OK_CHECK(Ptr) -#endif - -#ifdef SL_INC_ARG_CHECK - -#if (SL_USER_ARGS_HANDLING == SL_HANDLING_ASSERT) -#define ARG_CHECK_PTR(Ptr) _SL_ASSERT(NULL != Ptr) -#elif (SL_USER_ARGS_HANDLING == SL_HANDLING_ERROR) -#define ARG_CHECK_PTR(Ptr) _SL_ERROR((NULL != Ptr), SL_RET_CODE_INVALID_INPUT) -#else -#define ARG_CHECK_PTR(Ptr) -#endif - -#else -#define ARG_CHECK_PTR(Ptr) -#endif - -#define SL_TRACE0(level,msg_id,str) -#define SL_TRACE1(level,msg_id,str,p1) -#define SL_TRACE2(level,msg_id,str,p1,p2) -#define SL_TRACE3(level,msg_id,str,p1,p2,p3) -#define SL_TRACE4(level,msg_id,str,p1,p2,p3,p4) -#define SL_ERROR_TRACE(msg_id,str) -#define SL_ERROR_TRACE1(msg_id,str,p1) -#define SL_ERROR_TRACE2(msg_id,str,p1,p2) -#define SL_ERROR_TRACE3(msg_id,str,p1,p2,p3) -#define SL_ERROR_TRACE4(msg_id,str,p1,p2,p3,p4) -#define SL_TRACE_FLUSH() - -/* #define SL_DBG_CNT_ENABLE */ -#ifdef SL_DBG_CNT_ENABLE -#define _SL_DBG_CNT_INC(Cnt) g_DbgCnt. ## Cnt++ -#define _SL_DBG_SYNC_LOG(index,value) {if(index < SL_DBG_SYNC_LOG_SIZE){*(_u32 *)&g_DbgCnt.SyncLog[index] = *(_u32 *)(value);}} - -#else -#define _SL_DBG_CNT_INC(Cnt) -#define _SL_DBG_SYNC_LOG(index,value) -#endif - -#define SL_DBG_LEVEL_1 1 -#define SL_DBG_LEVEL_2 2 -#define SL_DBG_LEVEL_3 4 -#define SL_DBG_LEVEL_MASK (SL_DBG_LEVEL_2|SL_DBG_LEVEL_3) - -#define SL_INCLUDE_DBG_FUNC(Name) ((Name ## _DBG_LEVEL) & SL_DBG_LEVEL_MASK) - -#define _SlDrvPrintStat_DBG_LEVEL SL_DBG_LEVEL_3 -#define _SlDrvOtherFunc_DBG_LEVEL SL_DBG_LEVEL_1 - -#ifdef __cplusplus -} -#endif - - -#endif /*__SIMPLELINK_TRACE_H__*/ - diff --git a/drivers/cc3100/inc/wlan.h b/drivers/cc3100/inc/wlan.h deleted file mode 100644 index 156b94eab82..00000000000 --- a/drivers/cc3100/inc/wlan.h +++ /dev/null @@ -1,1308 +0,0 @@ -/* - * wlan.h - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ -#include "simplelink.h" - -#ifndef __WLAN_H__ -#define __WLAN_H__ - - - - -#ifdef __cplusplus -extern "C" { -#endif - - -/*****************************************************************************/ -/* Macro declarations */ -/*****************************************************************************/ - -/*! - - \addtogroup wlan - @{ - -*/ - -#define SL_BSSID_LENGTH (6) -#define MAXIMAL_SSID_LENGTH (32) - -#define NUM_OF_RATE_INDEXES (20) -#define SIZE_OF_RSSI_HISTOGRAM (6) - -/* WLAN Disconnect Reason Codes */ -#define SL_DISCONNECT_RESERVED_0 (0) -#define SL_DISCONNECT_UNSPECIFIED_REASON (1) -#define SL_PREVIOUS_AUTHENTICATION_NO_LONGER_VALID (2) -#define SL_DEAUTHENTICATED_BECAUSE_SENDING_STATION_IS_LEAVING (3) -#define SL_DISASSOCIATED_DUE_TO_INACTIVITY (4) -#define SL_DISASSOCIATED_BECAUSE_AP_IS_UNABLE_TO_HANDLE_ALL_CURRENTLY_ASSOCIATED_STATIONS (5) -#define SL_CLASS_2_FRAME_RECEIVED_FROM_NONAUTHENTICATED_STATION (6) -#define SL_CLASS_3_FRAME_RECEIVED_FROM_NONASSOCIATED_STATION (7) -#define SL_DISASSOCIATED_BECAUSE_SENDING_STATION_IS_LEAVING_BSS (8) -#define SL_STATION_REQUESTING_ASSOCIATION_IS_NOT_AUTHENTICATED_WITH_RESPONDING_STATION (9) -#define SL_DISASSOCIATED_BECAUSE_THE_INFORMATION_IN_THE_POWER_CAPABILITY_ELEMENT_IS_UNACCEPTABLE (10) -#define SL_DISASSOCIATED_BECAUSE_THE_INFORMATION_IN_THE_SUPPORTED_CHANNELS_ELEMENT_IS_UNACCEPTABLE (11) -#define SL_DISCONNECT_RESERVED_1 (12) -#define SL_INVALID_INFORMATION_ELEMENT (13) -#define SL_MESSAGE_INTEGRITY_CODE_MIC_FAILURE (14) -#define SL_FOUR_WAY_HANDSHAKE_TIMEOUT (15) -#define SL_GROUP_KEY_HANDSHAKE_TIMEOUT (16) -#define SL_RE_ASSOCIATION_REQUEST_PROBE_RESPONSE_BEACON_FRAME (17) -#define SL_INVALID_GROUP_CIPHER (18) -#define SL_INVALID_PAIRWISE_CIPHER (19) -#define SL_INVALID_AKMP (20) -#define SL_UNSUPPORTED_RSN_INFORMATION_ELEMENT_VERSION (21) -#define SL_INVALID_RSN_INFORMATION_ELEMENT_CAPABILITIES (22) -#define SL_IEEE_802_1X_AUTHENTICATION_FAILED (23) -#define SL_CIPHER_SUITE_REJECTED_BECAUSE_OF_THE_SECURITY_POLICY (24) -#define SL_DISCONNECT_RESERVED_2 (25) -#define SL_DISCONNECT_RESERVED_3 (26) -#define SL_DISCONNECT_RESERVED_4 (27) -#define SL_DISCONNECT_RESERVED_5 (28) -#define SL_DISCONNECT_RESERVED_6 (29) -#define SL_DISCONNECT_RESERVED_7 (30) -#define SL_DISCONNECT_RESERVED_8 (31) -#define SL_USER_INITIATED_DISCONNECTION (200) - -/* Wlan error codes */ -#define SL_ERROR_KEY_ERROR (-3) -#define SL_ERROR_INVALID_ROLE (-71) -#define SL_ERROR_INVALID_SECURITY_TYPE (-84) -#define SL_ERROR_PASSPHRASE_TOO_LONG (-85) -#define SL_ERROR_WPS_NO_PIN_OR_WRONG_PIN_LEN (-87) -#define SL_ERROR_EAP_WRONG_METHOD (-88) -#define SL_ERROR_PASSWORD_ERROR (-89) -#define SL_ERROR_EAP_ANONYMOUS_LEN_ERROR (-90) -#define SL_ERROR_SSID_LEN_ERROR (-91) -#define SL_ERROR_USER_ID_LEN_ERROR (-92) -#define SL_ERROR_ILLEGAL_WEP_KEY_INDEX (-95) -#define SL_ERROR_INVALID_DWELL_TIME_VALUES (-96) -#define SL_ERROR_INVALID_POLICY_TYPE (-97) -#define SL_ERROR_PM_POLICY_INVALID_OPTION (-98) -#define SL_ERROR_PM_POLICY_INVALID_PARAMS (-99) -#define SL_ERROR_WIFI_ALREADY_DISCONNECTED (-129) -#define SL_ERROR_WIFI_NOT_CONNECTED (-59) - - - -#define SL_SEC_TYPE_OPEN (0) -#define SL_SEC_TYPE_WEP (1) -#define SL_SEC_TYPE_WPA (2) /* deprecated */ -#define SL_SEC_TYPE_WPA_WPA2 (2) -#define SL_SEC_TYPE_WPS_PBC (3) -#define SL_SEC_TYPE_WPS_PIN (4) -#define SL_SEC_TYPE_WPA_ENT (5) -#define SL_SEC_TYPE_P2P_PBC (6) -#define SL_SEC_TYPE_P2P_PIN_KEYPAD (7) -#define SL_SEC_TYPE_P2P_PIN_DISPLAY (8) -#define SL_SEC_TYPE_P2P_PIN_AUTO (9) /* NOT Supported yet */ - - - -#define SL_SCAN_SEC_TYPE_OPEN (0) -#define SL_SCAN_SEC_TYPE_WEP (1) -#define SL_SCAN_SEC_TYPE_WPA (2) -#define SL_SCAN_SEC_TYPE_WPA2 (3) - - - -#define TLS (0x1) -#define MSCHAP (0x0) -#define PSK (0x2) -#define TTLS (0x10) -#define PEAP0 (0x20) -#define PEAP1 (0x40) -#define FAST (0x80) - -#define FAST_AUTH_PROVISIONING (0x02) -#define FAST_UNAUTH_PROVISIONING (0x01) -#define FAST_NO_PROVISIONING (0x00) - -#define EAPMETHOD_PHASE2_SHIFT (8) -#define EAPMETHOD_PAIRWISE_CIPHER_SHIFT (19) -#define EAPMETHOD_GROUP_CIPHER_SHIFT (27) - -#define WPA_CIPHER_CCMP (0x1) -#define WPA_CIPHER_TKIP (0x2) -#define CC31XX_DEFAULT_CIPHER (WPA_CIPHER_CCMP | WPA_CIPHER_TKIP) - -#define EAPMETHOD(phase1,phase2,pairwise_cipher,group_cipher) \ -((phase1) | \ - ((phase2) << EAPMETHOD_PHASE2_SHIFT ) |\ - ((_u32)(pairwise_cipher) << EAPMETHOD_PAIRWISE_CIPHER_SHIFT ) |\ - ((_u32)(group_cipher) << EAPMETHOD_GROUP_CIPHER_SHIFT )) - -/* phase1 phase2 pairwise_cipher group_cipher */ -#define SL_ENT_EAP_METHOD_TLS EAPMETHOD(TLS , 0 , CC31XX_DEFAULT_CIPHER , CC31XX_DEFAULT_CIPHER) -#define SL_ENT_EAP_METHOD_TTLS_TLS EAPMETHOD(TTLS , TLS , CC31XX_DEFAULT_CIPHER , CC31XX_DEFAULT_CIPHER) -#define SL_ENT_EAP_METHOD_TTLS_MSCHAPv2 EAPMETHOD(TTLS , MSCHAP , CC31XX_DEFAULT_CIPHER , CC31XX_DEFAULT_CIPHER) -#define SL_ENT_EAP_METHOD_TTLS_PSK EAPMETHOD(TTLS , PSK , CC31XX_DEFAULT_CIPHER , CC31XX_DEFAULT_CIPHER) -#define SL_ENT_EAP_METHOD_PEAP0_TLS EAPMETHOD(PEAP0 , TLS , CC31XX_DEFAULT_CIPHER , CC31XX_DEFAULT_CIPHER) -#define SL_ENT_EAP_METHOD_PEAP0_MSCHAPv2 EAPMETHOD(PEAP0 , MSCHAP , CC31XX_DEFAULT_CIPHER , CC31XX_DEFAULT_CIPHER) -#define SL_ENT_EAP_METHOD_PEAP0_PSK EAPMETHOD(PEAP0 , PSK , CC31XX_DEFAULT_CIPHER , CC31XX_DEFAULT_CIPHER) -#define SL_ENT_EAP_METHOD_PEAP1_TLS EAPMETHOD(PEAP1 , TLS , CC31XX_DEFAULT_CIPHER , CC31XX_DEFAULT_CIPHER) -#define SL_ENT_EAP_METHOD_PEAP1_MSCHAPv2 EAPMETHOD(PEAP1 , MSCHAP , CC31XX_DEFAULT_CIPHER , CC31XX_DEFAULT_CIPHER) -#define SL_ENT_EAP_METHOD_PEAP1_PSK EAPMETHOD(PEAP1 , PSK , CC31XX_DEFAULT_CIPHER , CC31XX_DEFAULT_CIPHER) -#define SL_ENT_EAP_METHOD_FAST_AUTH_PROVISIONING EAPMETHOD(FAST , FAST_AUTH_PROVISIONING , CC31XX_DEFAULT_CIPHER , CC31XX_DEFAULT_CIPHER) -#define SL_ENT_EAP_METHOD_FAST_UNAUTH_PROVISIONING EAPMETHOD(FAST , FAST_UNAUTH_PROVISIONING , CC31XX_DEFAULT_CIPHER , CC31XX_DEFAULT_CIPHER) -#define SL_ENT_EAP_METHOD_FAST_NO_PROVISIONING EAPMETHOD(FAST , FAST_NO_PROVISIONING , CC31XX_DEFAULT_CIPHER , CC31XX_DEFAULT_CIPHER) - -#define SL_LONG_PREAMBLE (0) -#define SL_SHORT_PREAMBLE (1) - -#define SL_RAW_RF_TX_PARAMS_CHANNEL_SHIFT (0) -#define SL_RAW_RF_TX_PARAMS_RATE_SHIFT (6) -#define SL_RAW_RF_TX_PARAMS_POWER_SHIFT (11) -#define SL_RAW_RF_TX_PARAMS_PREAMBLE_SHIFT (15) - -#define SL_RAW_RF_TX_PARAMS(chan,rate,power,preamble) \ - ((chan << SL_RAW_RF_TX_PARAMS_CHANNEL_SHIFT) | \ - (rate << SL_RAW_RF_TX_PARAMS_RATE_SHIFT) | \ - (power << SL_RAW_RF_TX_PARAMS_POWER_SHIFT) | \ - (preamble << SL_RAW_RF_TX_PARAMS_PREAMBLE_SHIFT)) - - -/* wlan config application IDs */ -#define SL_WLAN_CFG_AP_ID (0) -#define SL_WLAN_CFG_GENERAL_PARAM_ID (1) -#define SL_WLAN_CFG_P2P_PARAM_ID (2) - -/* wlan AP Config set/get options */ -#define WLAN_AP_OPT_SSID (0) -#define WLAN_AP_OPT_CHANNEL (3) -#define WLAN_AP_OPT_HIDDEN_SSID (4) -#define WLAN_AP_OPT_SECURITY_TYPE (6) -#define WLAN_AP_OPT_PASSWORD (7) -#define WLAN_GENERAL_PARAM_OPT_COUNTRY_CODE (9) -#define WLAN_GENERAL_PARAM_OPT_STA_TX_POWER (10) -#define WLAN_GENERAL_PARAM_OPT_AP_TX_POWER (11) - -#define WLAN_P2P_OPT_DEV_NAME (12) -#define WLAN_P2P_OPT_DEV_TYPE (13) -#define WLAN_P2P_OPT_CHANNEL_N_REGS (14) -#define WLAN_GENERAL_PARAM_OPT_INFO_ELEMENT (16) -#define WLAN_GENERAL_PARAM_OPT_SCAN_PARAMS (18) /* change the scan channels and RSSI threshold using this configuration option */ - -/* SmartConfig CIPHER options */ -#define SMART_CONFIG_CIPHER_SFLASH (0) /* password is not delivered by the application. The Simple Manager should */ - /* check if the keys are stored in the Flash. */ -#define SMART_CONFIG_CIPHER_AES (1) /* AES (other types are not supported) */ -#define SMART_CONFIG_CIPHER_NONE (0xFF) /* do not check in the flash */ - - -#define SL_POLICY_CONNECTION (0x10) -#define SL_POLICY_SCAN (0x20) -#define SL_POLICY_PM (0x30) -#define SL_POLICY_P2P (0x40) - -#define VAL_2_MASK(position,value) ((1 & (value))<<(position)) -#define MASK_2_VAL(position,mask) (((1 << position) & (mask)) >> (position)) - -#define SL_CONNECTION_POLICY(Auto,Fast,Open,anyP2P,autoSmartConfig) (VAL_2_MASK(0,Auto) | VAL_2_MASK(1,Fast) | VAL_2_MASK(2,Open) | VAL_2_MASK(3,anyP2P) | VAL_2_MASK(4,autoSmartConfig)) -#define SL_SCAN_POLICY_EN(policy) (MASK_2_VAL(0,policy)) -#define SL_SCAN_POLICY(Enable) (VAL_2_MASK(0,Enable)) - - -#define SL_NORMAL_POLICY (0) -#define SL_LOW_LATENCY_POLICY (1) -#define SL_LOW_POWER_POLICY (2) -#define SL_ALWAYS_ON_POLICY (3) -#define SL_LONG_SLEEP_INTERVAL_POLICY (4) - -#define SL_P2P_ROLE_NEGOTIATE (3) -#define SL_P2P_ROLE_GROUP_OWNER (15) -#define SL_P2P_ROLE_CLIENT (0) - -#define SL_P2P_NEG_INITIATOR_ACTIVE (0) -#define SL_P2P_NEG_INITIATOR_PASSIVE (1) -#define SL_P2P_NEG_INITIATOR_RAND_BACKOFF (2) - -#define POLICY_VAL_2_OPTIONS(position,mask,policy) ((mask & policy) << position ) - -#define SL_P2P_POLICY(p2pNegType,p2pNegInitiator) (POLICY_VAL_2_OPTIONS(0,0xF,(p2pNegType > SL_P2P_ROLE_GROUP_OWNER ? SL_P2P_ROLE_GROUP_OWNER : p2pNegType)) | \ - POLICY_VAL_2_OPTIONS(4,0x1,(p2pNegType > SL_P2P_ROLE_GROUP_OWNER ? 1:0)) | \ - POLICY_VAL_2_OPTIONS(5,0x3, p2pNegInitiator)) - - -/* Info elements */ - -#define INFO_ELEMENT_DEFAULT_ID (0) /* 221 will be used */ - -/* info element size is up to 252 bytes (+ 3 bytes of OUI). */ -#define INFO_ELEMENT_MAX_SIZE (252) - -/* For AP - the total length of all info elements is 300 bytes (for example - 4 info elements of 75 bytes each) */ -#define INFO_ELEMENT_MAX_TOTAL_LENGTH_AP (300) -/* For P2P - the total length of all info elements is 150 bytes (for example - 4 info elements of 40 bytes each) */ -#define INFO_ELEMENT_MAX_TOTAL_LENGTH_P2P_GO (160) - -#define INFO_ELEMENT_AP_ROLE (0) -#define INFO_ELEMENT_P2P_GO_ROLE (1) - -/* we support up to 4 info elements per Role. */ -#define MAX_PRIVATE_INFO_ELEMENTS_SUPPROTED (4) - -#define INFO_ELEMENT_DEFAULT_OUI_0 (0x08) -#define INFO_ELEMENT_DEFAULT_OUI_1 (0x00) -#define INFO_ELEMENT_DEFAULT_OUI_2 (0x28) - -#define INFO_ELEMENT_DEFAULT_OUI (0x000000) /* 08, 00, 28 will be used */ - -/*****************************************************************************/ -/* Structure/Enum declarations */ -/*****************************************************************************/ - -typedef enum -{ - RATE_1M = 1, - RATE_2M = 2, - RATE_5_5M = 3, - RATE_11M = 4, - RATE_6M = 6, - RATE_9M = 7, - RATE_12M = 8, - RATE_18M = 9, - RATE_24M = 10, - RATE_36M = 11, - RATE_48M = 12, - RATE_54M = 13, - RATE_MCS_0 = 14, - RATE_MCS_1 = 15, - RATE_MCS_2 = 16, - RATE_MCS_3 = 17, - RATE_MCS_4 = 18, - RATE_MCS_5 = 19, - RATE_MCS_6 = 20, - RATE_MCS_7 = 21, - MAX_NUM_RATES = 0xFF -}SlRateIndex_e; - -typedef enum { - DEV_PW_DEFAULT=0, - DEV_PW_PIN_KEYPAD=1, - DEV_PW_PUSH_BUTTON=4, - DEV_PW_PIN_DISPLAY=5 -} sl_p2p_dev_password_method; - - -typedef struct -{ - _u32 status; - _u32 ssid_len; - _u8 ssid[32]; - _u32 private_token_len; - _u8 private_token[32]; -}slSmartConfigStartAsyncResponse_t; - -typedef struct -{ - _u16 status; - _u16 padding; -}slSmartConfigStopAsyncResponse_t; - -typedef struct -{ - _u16 status; - _u16 padding; -}slWlanConnFailureAsyncResponse_t; - -typedef struct -{ - _u8 connection_type;/* 0-STA,3-P2P_CL */ - _u8 ssid_len; - _u8 ssid_name[32]; - _u8 go_peer_device_name_len; - _u8 go_peer_device_name[32]; - _u8 bssid[6]; - _u8 reason_code; - _u8 padding[2]; -} slWlanConnectAsyncResponse_t; - -typedef struct -{ - _u8 go_peer_device_name[32]; - _u8 mac[6]; - _u8 go_peer_device_name_len; - _u8 wps_dev_password_id; - _u8 own_ssid[32];/* relevant for event sta-connected only */ - _u8 own_ssid_len;/* relevant for event sta-connected only */ - _u8 padding[3]; -}slPeerInfoAsyncResponse_t; - - -typedef union -{ - slSmartConfigStartAsyncResponse_t smartConfigStartResponse; /*SL_WLAN_SMART_CONFIG_COMPLETE_EVENT*/ - slSmartConfigStopAsyncResponse_t smartConfigStopResponse; /*SL_WLAN_SMART_CONFIG_STOP_EVENT */ - slPeerInfoAsyncResponse_t APModeStaConnected; /* SL_WLAN_STA_CONNECTED_EVENT - relevant only in AP mode - holds information regarding a new STA connection */ - slPeerInfoAsyncResponse_t APModestaDisconnected; /* SL_WLAN_STA_DISCONNECTED_EVENT - relevant only in AP mode - holds information regarding a STA disconnection */ - slWlanConnectAsyncResponse_t STAandP2PModeWlanConnected; /* SL_WLAN_CONNECT_EVENT - relevant only in STA and P2P mode - holds information regarding a new connection */ - slWlanConnectAsyncResponse_t STAandP2PModeDisconnected; /* SL_WLAN_DISCONNECT_EVENT - relevant only in STA and P2P mode - holds information regarding a disconnection */ - slPeerInfoAsyncResponse_t P2PModeDevFound; /* SL_WLAN_P2P_DEV_FOUND_EVENT - relevant only in P2P mode */ - slPeerInfoAsyncResponse_t P2PModeNegReqReceived; /* SL_WLAN_P2P_NEG_REQ_RECEIVED_EVENT - relevant only in P2P mode */ - slWlanConnFailureAsyncResponse_t P2PModewlanConnectionFailure; /* SL_WLAN_CONNECTION_FAILED_EVENT - relevant only in P2P mode */ - -} SlWlanEventData_u; - -typedef struct -{ - _u32 Event; - SlWlanEventData_u EventData; -} SlWlanEvent_t; - - -typedef struct -{ - _u32 ReceivedValidPacketsNumber; /* sum of the packets that been received OK (include filtered) */ - _u32 ReceivedFcsErrorPacketsNumber; /* sum of the packets that been dropped due to FCS error */ - _u32 ReceivedAddressMismatchPacketsNumber; /* sum of the packets that been received but filtered out by one of the HW filters */ - _i16 AvarageDataCtrlRssi; /* average RSSI for all valid data packets received */ - _i16 AvarageMgMntRssi; /* average RSSI for all valid management packets received */ - _u16 RateHistogram[NUM_OF_RATE_INDEXES]; /* rate histogram for all valid packets received */ - _u16 RssiHistogram[SIZE_OF_RSSI_HISTOGRAM]; /* RSSI histogram from -40 until -87 (all below and above\n RSSI will appear in the first and last cells */ - _u32 StartTimeStamp; /* the time stamp started collecting the statistics in uSec */ - _u32 GetTimeStamp; /* the time stamp called the get statistics command */ -}SlGetRxStatResponse_t; - - -typedef struct -{ - _u8 ssid[MAXIMAL_SSID_LENGTH]; - _u8 ssid_len; - _u8 sec_type; - _u8 bssid[SL_BSSID_LENGTH]; - _i8 rssi; - _i8 reserved[3]; -}Sl_WlanNetworkEntry_t; - - -typedef struct -{ - _u8 Type; - _i8* Key; - _u8 KeyLen; -}SlSecParams_t; - -typedef struct -{ - _i8* User; - _u8 UserLen; - _i8* AnonUser; - _u8 AnonUserLen; - _u8 CertIndex; /* not supported */ - _u32 EapMethod; -}SlSecParamsExt_t; - -typedef struct -{ - _i8 User[32]; - _u8 UserLen; - _i8 AnonUser[32]; - _u8 AnonUserLen; - _u8 CertIndex; /* not supported */ - _u32 EapMethod; -}SlGetSecParamsExt_t; - -typedef enum -{ - ROLE_STA = 0, - ROLE_AP = 2, - ROLE_P2P = 3, - ROLE_STA_ERR = -1, /* Failure to load MAC/PHY in STA role */ - ROLE_AP_ERR = -ROLE_AP, /* Failure to load MAC/PHY in AP role */ - ROLE_P2P_ERR = -ROLE_P2P /* Failure to load MAC/PHY in P2P role */ -}SlWlanMode_t; - -typedef struct -{ - _u32 G_Channels_mask; - _i32 rssiThershold; -}slWlanScanParamCommand_t; - - -typedef struct -{ - _u8 id; - _u8 oui[3]; - _u16 length; - _u8 data[252]; -} sl_protocol_InfoElement_t; - -typedef struct -{ - _u8 index; /* 0 - MAX_PRIVATE_INFO_ELEMENTS_SUPPROTED */ - _u8 role; /* bit0: AP = 0, GO = 1 */ - sl_protocol_InfoElement_t ie; -} sl_protocol_WlanSetInfoElement_t; - - -/*****************************************************************************/ -/* Function prototypes */ -/*****************************************************************************/ - - -/*! - \brief Connect to wlan network as a station - - \param[in] pName up to 32 bytes in case of STA the name is the SSID of the Access Point - \param[in] NameLen name length - \param[in] pMacAddr 6 bytes for MAC address - \param[in] pSecParams Security parameters (use NULL key for SL_SEC_TYPE_OPEN) - Security types options: \n - - SL_SEC_TYPE_OPEN - - SL_SEC_TYPE_WEP - - SL_SEC_TYPE_WPA_WPA2 - - SL_SEC_TYPE_WPA_ENT - - SL_SEC_TYPE_WPS_PBC - - SL_SEC_TYPE_WPS_PIN - - \param[in] pSecExtParams Enterprise parameters (set NULL in case Enterprise parameters is not in use) - - \return On success, zero is returned. On error, negative is returned - In case error number (-71) is returned, it indicates a connection was activated while the device it running in AP role - - \sa sl_WlanDisconnect - \note belongs to \ref ext_api - \warning In this version only single enterprise mode could be used - SL_SEC_TYPE_WPA is a deprecated definition, the new definition is SL_SEC_TYPE_WPA_WPA2 -*/ -#if _SL_INCLUDE_FUNC(sl_WlanConnect) -_i16 sl_WlanConnect(const _i8* pName,const _i16 NameLen,const _u8 *pMacAddr,const SlSecParams_t* pSecParams ,const SlSecParamsExt_t* pSecExtParams); -#endif - -/*! - \brief wlan disconnect - - Disconnect connection - - \return 0 disconnected done, other already disconnected - - \sa sl_WlanConnect - \note belongs to \ref ext_api - \warning -*/ -#if _SL_INCLUDE_FUNC(sl_WlanDisconnect) -_i16 sl_WlanDisconnect(void); -#endif - -/*! - \brief add profile - - When auto start is enabled, the device connects to a - station from the profiles table. Up to 7 profiles are - supported. If several profiles configured the device chose - the highest priority profile, within each priority group, - device will chose profile based on security policy, signal - strength, etc parameters. - - - \param[in] pName up to 32 bytes in case of STA the name is the - SSID of the Access Point - in case of P2P the name is the remote device name - \param[in] NameLen name length - \param[in] pMacAddr 6 bytes for MAC address - \param[in] pSecParams Security parameters - security type - (SL_SEC_TYPE_OPEN,SL_SEC_TYPE_WEP,SL_SEC_TYPE_WPA_WPA2, - SL_SEC_TYPE_P2P_PBC,SL_SEC_TYPE_P2P_PIN_KEYPAD,SL_SEC_TYPE_P2P_PIN_DISPLAY, SL_SEC_TYPE_WPA_ENT), key, and key length - in case of p2p security type pin the key refers to pin code - \param[in] pSecExtParams Enterprise parameters - identity, identity length, - Anonymous, Anonymous length, CertIndex (not supported, - certificates need to be placed in a specific file ID), - EapMethod.Use NULL in case Enterprise parameters is not in use - - \param[in] Priority profile priority. Lowest priority: 0 - \param[in] Options Not supported - - \return On success, profile stored index is returned. On error, negative value is returned - - \sa sl_WlanProfileGet , sl_WlanProfileDel - \note belongs to \ref ext_api - \warning Only one Enterprise profile is supported. - Please Note that in case of adding an existing profile (compared by pName,pMACAddr and security type) - the old profile will be deleted and the same index will be returned. - SL_SEC_TYPE_WPA is a deprecated definition, the new definition is SL_SEC_TYPE_WPA_WPA2 - -*/ -#if _SL_INCLUDE_FUNC(sl_WlanProfileAdd) -_i16 sl_WlanProfileAdd(const _i8* pName,const _i16 NameLen,const _u8 *pMacAddr,const SlSecParams_t* pSecParams ,const SlSecParamsExt_t* pSecExtParams,const _u32 Priority,const _u32 Options); -#endif - -/*! - \brief get profile - - read profile from the device - - \param[in] Index profile stored index, if index does not exists - error is return - \param[out] pName up to 32 bytes, in case of sta mode the name of the Access Point - in case of p2p mode the name of the Remote Device - \param[out] pNameLen name length - \param[out] pMacAddr 6 bytes for MAC address - \param[out] pSecParams security parameters - security type - (SL_SEC_TYPE_OPEN, SL_SEC_TYPE_WEP, SL_SEC_TYPE_WPA_WPA2 or - SL_SEC_TYPE_WPS_PBC, SL_SEC_TYPE_WPS_PIN, SL_SEC_TYPE_WPA_ENT,SL_SEC_TYPE_P2P_PBC,SL_SEC_TYPE_P2P_PIN_KEYPAD or SL_SEC_TYPE_P2P_PIN_DISPLAY), key and key length are not - in case of p2p security type pin the key refers to pin code - return due to security reasons. - \param[out] pSecExtParams enterprise parameters - identity, identity - length, Anonymous, Anonymous length - CertIndex (not supported), EapMethod. - \param[out] Priority profile priority - - \return On success, Profile security type is returned (0 or positive number). On error, -1 is - returned - - \sa sl_WlanProfileAdd , sl_WlanProfileDel - \note belongs to \ref ext_api - \warning -*/ -#if _SL_INCLUDE_FUNC(sl_WlanProfileGet) -_i16 sl_WlanProfileGet(const _i16 Index,_i8* pName, _i16 *pNameLen, _u8 *pMacAddr, SlSecParams_t* pSecParams, SlGetSecParamsExt_t* pSecExtParams, _u32 *pPriority); -#endif - -/*! - \brief Delete WLAN profile - - Delete WLAN profile - - \param[in] index number of profile to delete.Possible values are 0 to 6. - Index value 255 will delete all saved profiles - - \return On success, zero is returned. On error, -1 is - returned - - \sa sl_WlanProfileAdd , sl_WlanProfileGet - \note belongs to \ref ext_api - \warning -*/ -#if _SL_INCLUDE_FUNC(sl_WlanProfileDel) -_i16 sl_WlanProfileDel(const _i16 Index); -#endif - -/*! - \brief Set policy values - - \param[in] Type Type of policy to be modified. The Options are:\n - - SL_POLICY_CONNECTION - - SL_POLICY_SCAN - - SL_POLICY_PM - - SL_POLICY_P2P - \param[in] Policy The option value which depends on action type - \param[in] pVal An optional value pointer - \param[in] ValLen An optional value length, in bytes - \return On success, zero is returned. On error, -1 is - returned - \sa sl_WlanPolicyGet - \note belongs to \ref ext_api - \warning - \par - SL_POLICY_CONNECTION type defines three options available to connect the CC31xx device to the AP: \n - - - If Auto Connect is set, the CC31xx device tries to automatically reconnect to one of its stored profiles, each time the connection fails or the device is rebooted.\n - To set this option, use: \n - sl_WlanPolicySet(SL_POLICY_CONNECTION,SL_CONNECTION_POLICY(1,0,0,0,0),NULL,0) - - If Fast Connect is set, the CC31xx device tries to establish a fast connection to AP. \n - To set this option, use: \n - sl_WlanPolicySet(SL_POLICY_CONNECTION,SL_CONNECTION_POLICY(0,1,0,0,0),NULL,0) - - (relevant for P2P mode only) - If Any P2P is set, CC31xx/CC32xx device tries to automatically connect to the first P2P device available, \n - supporting push button only. To set this option, use: \n - sl_WlanPolicySet(SL_POLICY_CONNECTION,SL_CONNECTION_POLICY(0,0,0,1,0),NULL,0) - - For auto smart config upon restart (any command from Host will end this state) use: \n - sl_WlanPolicySet(SL_POLICY_CONNECTION,SL_CONNECTION_POLICY(0,0,0,0,1),NULL,0) \n - The options above could be combined to a single action, if more than one action is required. \n - \par - SL_POLICY_SCAN defines system scan time interval.Default interval is 10 minutes. \n - After settings scan interval, an immediate scan is activated. The next scan will be based on the interval settings. \n - - For example, setting scan interval to 1 minute interval use: \n - _u32 intervalInSeconds = 60; \n - #define SL_SCAN_ENABLE 1 \n - sl_WlanPolicySet(SL_POLICY_SCAN,SL_SCAN_ENABLE, (_u8 *)&intervalInSeconds,sizeof(intervalInSeconds)); \n - - - For example, disable scan: \n - #define SL_SCAN_DISABLE 0 \n - sl_WlanPolicySet(SL_POLICY_SCAN,SL_SCAN_DISABLE,0,0); \n - \par - SL_POLICY_PM defines a power management policy for Station mode only: - - For setting normal power management (default) policy use: sl_WlanPolicySet(SL_POLICY_PM , SL_NORMAL_POLICY, NULL,0) - - For setting low latency power management policy use: sl_WlanPolicySet(SL_POLICY_PM , SL_LOW_LATENCY_POLICY, NULL,0) - - For setting low power management policy use: sl_WlanPolicySet(SL_POLICY_PM , SL_LOW_POWER_POLICY, NULL,0) - - For setting always on power management policy use: sl_WlanPolicySet(SL_POLICY_PM , SL_ALWAYS_ON_POLICY, NULL,0) - - For setting Long Sleep Interval policy use: \n - _u16 PolicyBuff[4] = {0,0,800,0}; // PolicyBuff[2] is max sleep time in mSec \n - sl_WlanPolicySet(SL_POLICY_PM , SL_LONG_SLEEP_INTERVAL_POLICY, (_u8*)PolicyBuff,sizeof(PolicyBuff)); \n - - SL_POLICY_P2P defines p2p negotiation policy parameters for P2P role: - - To set intent negotiation value, set on of the following: - SL_P2P_ROLE_NEGOTIATE - intent 3 - SL_P2P_ROLE_GROUP_OWNER - intent 15 - SL_P2P_ROLE_CLIENT - intent 0 - - To set negotiation initiator value (initiator policy of first negotiation action frame), set on of the following: - SL_P2P_NEG_INITIATOR_ACTIVE - SL_P2P_NEG_INITIATOR_PASSIVE - SL_P2P_NEG_INITIATOR_RAND_BACKOFF - For example: \n - sl_WlanPolicySet(SL_POLICY_P2P, SL_P2P_POLICY(SL_P2P_ROLE_NEGOTIATE,SL_P2P_NEG_INITIATOR_RAND_BACKOFF),NULL,0) - -*/ -#if _SL_INCLUDE_FUNC(sl_WlanPolicySet) -_i16 sl_WlanPolicySet(const _u8 Type , const _u8 Policy, _u8 *pVal,const _u8 ValLen); -#endif -/*! - \brief get policy values - - \param[in] Type SL_POLICY_CONNECTION, SL_POLICY_SCAN, SL_POLICY_PM,SL_POLICY_P2P \n - - \param[in] Policy argument may be set to any value \n - - \param[out] The returned values, depends on each policy type, will be stored in the allocated buffer pointed by pVal - with a maximum buffer length set by the calling function and pointed to by argument *pValLen - - \return On success, zero is returned. On error, -1 is returned - - \sa sl_WlanPolicySet - - \note belongs to \ref ext_api - - \warning The value pointed by the argument *pValLen should be set to a value different from 0 and - greater than the buffer length returned from the SL device. Otherwise, an error will be returned. - -*/ -#if _SL_INCLUDE_FUNC(sl_WlanPolicyGet) -_i16 sl_WlanPolicyGet(const _u8 Type , _u8 Policy,_u8 *pVal,_u8 *pValLen); -#endif -/*! - \brief Gets the WLAN scan operation results - - Gets scan results , gets entry from scan result table - - \param[in] Index - Starting index identifier (range 0-19) for getting scan results - \param[in] Count - How many entries to fetch. Max is (20-"Index"). - \param[out] pEntries - pointer to an allocated Sl_WlanNetworkEntry_t. - the number of array items should match "Count" - sec_type: SL_SCAN_SEC_TYPE_OPEN, SL_SCAN_SEC_TYPE_WEP, SL_SCAN_SEC_TYPE_WPA or SL_SCAN_SEC_TYPE_WPA2 - - - \return Number of valid networks list items - - \sa - \note belongs to \ref ext_api - \warning This command do not initiate any active scanning action - \par Example: - \code An example of fetching max 10 results: - - Sl_WlanNetworkEntry_t netEntries[10]; - _i16 resultsCount = sl_WlanGetNetworkList(0,10,&netEntries[0]); - for(i=0; i< resultsCount; i++) - { - printf("%s\n",netEntries[i].ssid); - } - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_WlanGetNetworkList) -_i16 sl_WlanGetNetworkList(const _u8 Index,const _u8 Count, Sl_WlanNetworkEntry_t *pEntries); -#endif - -/*! - \brief Start collecting wlan RX statistics, for unlimited time. - - \return On success, zero is returned. On error, -1 is returned - - \sa sl_WlanRxStatStop sl_WlanRxStatGet - \note belongs to \ref ext_api - \warning - \par Example: - \code Getting wlan RX statistics: - - void RxStatCollectTwice() - { - SlGetRxStatResponse_t rxStat; - _i16 rawSocket; - _i8 DataFrame[200]; - struct SlTimeval_t timeval; - timeval.tv_sec = 0; // Seconds - timeval.tv_usec = 20000; // Microseconds. 10000 microseconds resolution - - sl_WlanRxStatStart(); // set statistics mode - - rawSocket = sl_Socket(SL_AF_RF, SL_SOCK_RAW, eChannel); - // set timeout - in case we have no activity for the specified channel - sl_SetSockOpt(rawSocket,SL_SOL_SOCKET,SL_SO_RCVTIMEO, &timeval, sizeof(timeval)); // Enable receive timeout - status = sl_Recv(rawSocket, DataFrame, sizeof(DataFrame), 0); - - Sleep(1000); // sleep for 1 sec - sl_WlanRxStatGet(&rxStat,0); // statistics has been cleared upon read - Sleep(1000); // sleep for 1 sec - sl_WlanRxStatGet(&rxStat,0); - - } - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_WlanRxStatStart) -_i16 sl_WlanRxStatStart(void); -#endif - - -/*! - \brief Stop collecting wlan RX statistic, (if previous called sl_WlanRxStatStart) - - \return On success, zero is returned. On error, -1 is returned - - \sa sl_WlanRxStatStart sl_WlanRxStatGet - \note belongs to \ref ext_api - \warning -*/ -#if _SL_INCLUDE_FUNC(sl_WlanRxStatStop) -_i16 sl_WlanRxStatStop(void); -#endif - - -/*! - \brief Get wlan RX statistics. upon calling this command, the statistics counters will be cleared. - - \param[in] Flags should be 0 ( not applicable right now, will be added the future ) - \param[in] pRxStat a pointer to SlGetRxStatResponse_t filled with Rx statistics results - \return On success, zero is returned. On error, -1 is returned - - \sa sl_WlanRxStatStart sl_WlanRxStatStop - \note belongs to \ref ext_api - \warning -*/ -#if _SL_INCLUDE_FUNC(sl_WlanRxStatGet) -_i16 sl_WlanRxStatGet(SlGetRxStatResponse_t *pRxStat,const _u32 Flags); -#endif - - -/*! - \brief Stop Smart Config procedure. Once Smart Config will be stopped, - Asynchronous event will be received - SL_OPCODE_WLAN_SMART_CONFIG_STOP_ASYNC_RESPONSE. - - \param[in] none - \param[out] none - - \return 0 - if Stop Smart Config is about to be executed without errors. - - \sa sl_WlanSmartConfigStart - \note belongs to \ref ext_api - \warning - -*/ -#if _SL_INCLUDE_FUNC(sl_WlanSmartConfigStop) -_i16 sl_WlanSmartConfigStop(void); -#endif - -/*! - \brief Start Smart Config procedure - \par - The target of the procedure is to let the \n - device to gain the network parameters: SSID and Password (if network is secured) \n - and to connect to it once located in the network range. \n - An external application should be used on a device connected to any mobile network. \n - The external application will transmit over the air the network parameters in secured manner.\n - The Password may be decrypted using a Key. \n - The decryption method may be decided in the command or embedded in the Flash. \n - The procedure can be activated for 1-3 group ID in the range of BIT_0 - BIT_15 where the default group ID id 0 (BIT_0) \n - Once Smart Config has ended successfully, Asynchronous event will be received - \n - SL_OPCODE_WLAN_SMART_CONFIG_START_ASYNC_RESPONSE. \n - The Event will hold the SSID and an extra field that might have been delivered as well (i.e. - device name) - - \param[in] groupIdBitmask - each bit represent a group ID that should be searched. - The Default group ID id BIT_0. 2 more group can be searched - in addition. The range is BIT_0 - BIT_15. - \param[in] chiper - 0: check in flash, 1 - AES, 0xFF - do not check in flash - \param[in] publicKeyLen - public key len (used for the default group ID - BIT_0) - \param[in] group1KeyLen - group ID1 length - \param[in] group2KeyLen - group ID2 length - \param[in] publicKey - public key (used for the default group ID - BIT_0) - \param[in] group1Key - group ID1 key - \param[in] group2Key - group ID2 key - - \param[out] none - - \return 0 - if Smart Config started successfully. - - \sa sl_WlanSmartConfigStop - \note belongs to \ref ext_api - \warning - \par - \code An example of starting smart Config on group ID's 0 + 1 + 2 - - sl_WlanSmartConfigStart(7, //group ID's (BIT_0 | BIT_1 | BIT_2) - 1, //decrypt key by AES method - 16, //decryption key length for group ID0 - 16, //decryption key length for group ID1 - 16, //decryption key length for group ID2 - "Key0Key0Key0Key0", //decryption key for group ID0 - "Key1Key1Key1Key1", //decryption key for group ID1 - "Key2Key2Key2Key2" //decryption key for group ID2 - ); - \endcode -*/ -#if _SL_INCLUDE_FUNC(sl_WlanSmartConfigStart) -_i16 sl_WlanSmartConfigStart(const _u32 groupIdBitmask, - const _u8 cipher, - const _u8 publicKeyLen, - const _u8 group1KeyLen, - const _u8 group2KeyLen, - const _u8* publicKey, - const _u8* group1Key, - const _u8* group2Key); -#endif - - -/*! - \brief Wlan set mode - - Setting WLAN mode - - \param[in] mode - WLAN mode to start the CC31xx device. Possible options are: - - ROLE_STA - for WLAN station mode - - ROLE_AP - for WLAN AP mode - - ROLE_P2P -for WLAN P2P mode - \return 0 - if mode was set correctly - \sa sl_Start sl_Stop - \note belongs to \ref ext_api - \warning After setting the mode the system must be restarted for activating the new mode - \par Example: - \code - //Switch from any role to STA: - sl_WlanSetMode(ROLE_STA); - sl_Stop(0); - sl_Start(NULL,NULL,NULL); - \endcode - -*/ -#if _SL_INCLUDE_FUNC(sl_WlanSetMode) -_i16 sl_WlanSetMode(const _u8 mode); -#endif - - -/*! - \brief Internal function for setting WLAN configurations - - \return On success, zero is returned. On error one of the following error codes returned: - - CONF_ERROR (-1) - - CONF_NVMEM_ACCESS_FAILED (-2) - - CONF_OLD_FILE_VERSION (-3) - - CONF_ERROR_NO_SUCH_COUNTRY_CODE (-4) - - - \param[in] ConfigId - configuration id - - SL_WLAN_CFG_AP_ID - - SL_WLAN_CFG_GENERAL_PARAM_ID - - SL_WLAN_CFG_P2P_PARAM_ID - - \param[in] ConfigOpt - configurations option - - SL_WLAN_CFG_AP_ID - - WLAN_AP_OPT_SSID \n - Set SSID for AP mode. \n - This options takes _u8 buffer as parameter - - WLAN_AP_OPT_CHANNEL \n - Set channel for AP mode. \n - The channel is dependant on the country code which is set. i.e. for "US" the channel should be in the range of [1-11] \n - This option takes _u8 as a parameter - - WLAN_AP_OPT_HIDDEN_SSID \n - Set Hidden SSID Mode for AP mode.Hidden options: \n - 0: disabled \n - 1: Send empty (length=0) SSID in beacon and ignore probe request for broadcast SSID \n - 2: Clear SSID (ASCII 0), but keep the original length (this may be required with some \n - clients that do not support empty SSID) and ignore probe requests for broadcast SSID \n - This option takes _u8 as a parameter - - WLAN_AP_OPT_SECURITY_TYPE \n - Set Security type for AP mode. Security options are: - - Open security: SL_SEC_TYPE_OPEN - - WEP security: SL_SEC_TYPE_WEP - - WPA security: SL_SEC_TYPE_WPA_WPA2 \n - This option takes _u8 pointer as a parameter - - WLAN_AP_OPT_PASSWORD \n - Set Password for for AP mode (for WEP or for WPA): \n - Password - for WPA: 8 - 63 characters \n - for WEP: 5 / 13 characters (ascii) \n - This options takes _u8 buffer as parameter - - SL_WLAN_CFG_GENERAL_PARAM_ID - - WLAN_GENERAL_PARAM_OPT_SCAN_PARAMS \n - Set scan parameters. - This option uses slWlanScanParamCommand_t as parameter - - WLAN_GENERAL_PARAM_OPT_COUNTRY_CODE \n - Set Country Code for AP mode \n - This options takes _u8 2 bytes buffer as parameter - - WLAN_GENERAL_PARAM_OPT_STA_TX_POWER \n - Set STA mode Tx power level \n - Number between 0-15, as dB offset from max power (0 will set MAX power) \n - This options takes _u8 as parameter - - WLAN_GENERAL_PARAM_OPT_AP_TX_POWER - Set AP mode Tx power level \n - Number between 0-15, as dB offset from max power (0 will set MAX power) \n - This options takes _u8 as parameter - - WLAN_GENERAL_PARAM_OPT_INFO_ELEMENT - Set Info Element for AP mode. \n - The Application can set up to MAX_PRIVATE_INFO_ELEMENTS_SUPPROTED info elements per Role (AP / P2P GO). \n - To delete an info element use the relevant index and length = 0. \n - The Application can set up to MAX_PRIVATE_INFO_ELEMENTS_SUPPROTED to the same role. \n - However, for AP - no more than INFO_ELEMENT_MAX_TOTAL_LENGTH_AP bytes can be stored for all info elements. \n - For P2P GO - no more than INFO_ELEMENT_MAX_TOTAL_LENGTH_P2P_GO bytes can be stored for all info elements. \n - This option takes sl_protocol_WlanSetInfoElement_t as parameter - - SL_WLAN_CFG_P2P_PARAM_ID - - WLAN_P2P_OPT_DEV_TYPE \n - Set P2P Device type.Maximum length of 17 characters. Device type is published under P2P I.E, \n - allows to make devices easier to recognize. \n - In case no device type is set, the default type is "1-0050F204-1" \n - This options takes _u8 buffer as parameter - - WLAN_P2P_OPT_CHANNEL_N_REGS \n - Set P2P Channels. \n - listen channel (either 1/6/11 for 2.4GHz) \n - listen regulatory class (81 for 2.4GHz) \n - oper channel (either 1/6/11 for 2.4GHz) \n - oper regulatory class (81 for 2.4GHz) \n - listen channel and regulatory class will determine the device listen channel during p2p find listen phase \n - oper channel and regulatory class will determine the operating channel preferred by this device (in case it is group owner this will be the operating channel) \n - channels should be one of the social channels (1/6/11). In case no listen/oper channel selected, a random 1/6/11 will be selected. - This option takes pointer to _u8[4] as parameter - - \param[in] ConfigLen - configurations len - - \param[in] pValues - configurations values - - \sa - \note - \warning - \par Examples: - \par - WLAN_AP_OPT_SSID: - \code - _u8 str[33]; - memset(str, 0, 33); - memcpy(str, ssid, len); // ssid string of 32 characters - sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID, strlen(ssid), str); - \endcode - \par - WLAN_AP_OPT_CHANNEL: - \code - _u8 val = channel; - sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_CHANNEL, 1, (_u8 *)&val); - \endcode - \par - WLAN_AP_OPT_HIDDEN_SSID: - \code - _u8 val = hidden; - sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_HIDDEN_SSID, 1, (_u8 *)&val); - \endcode - \par - WLAN_AP_OPT_SECURITY_TYPE: - \code - _u8 val = SL_SEC_TYPE_WPA_WPA2; - sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SECURITY_TYPE, 1, (_u8 *)&val); - \endcode - \par - WLAN_AP_OPT_PASSWORD: - \code - _u8 str[65]; - _u16 len = strlen(password); - memset(str, 0, 65); - memcpy(str, password, len); - sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_PASSWORD, len, (_u8 *)str); - \endcode - \par - WLAN_GENERAL_PARAM_OPT_STA_TX_POWER: - \code - _u8 stapower=(_u8)power; - sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_STA_TX_POWER,1,(_u8 *)&stapower); - \endcode - \par - WLAN_GENERAL_PARAM_OPT_SCAN_PARAMS: - \code - slWlanScanParamCommand_t ScanParamConfig; - ScanParamConfig.G_Channels_mask = 0x01; // bit mask for channels:1 means channel 1 is enabled, 3 means channels 1 + 2 are enabled - ScanParamConfig.rssiThershold = -70; // only for RSSI level which is higher than -70 - sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID ,WLAN_GENERAL_PARAM_OPT_SCAN_PARAMS,sizeof(slWlanScanParamCommand_t),(_u8*)&ScanParamConfig); - \endcode - - \par - WLAN_GENERAL_PARAM_OPT_COUNTRY_CODE: - \code - _u8* str = (_u8 *) country; // string of 2 characters. i.e. - "US" - sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_COUNTRY_CODE, 2, str); - \endcode - \par - WLAN_GENERAL_PARAM_OPT_AP_TX_POWER: - \code - _u8 appower=(_u8)power; - sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_AP_TX_POWER,1,(_u8 *)&appower); - \endcode - \par - WLAN_P2P_OPT_DEV_TYPE: - \code - _u8 str[17]; - _u16 len = strlen(device_type); - memset(str, 0, 17); - memcpy(str, device_type, len); - sl_WlanSet(SL_WLAN_CFG_P2P_PARAM_ID, WLAN_P2P_OPT_DEV_TYPE, len, str); - \endcode - \par - WLAN_P2P_OPT_CHANNEL_N_REGS: - \code - _u8 str[4]; - str[0] = (_u8)11; // listen channel - str[1] = (_u8)81; // listen regulatory class - str[2] = (_u8)6; // oper channel - str[3] = (_u8)81; // oper regulatory class - sl_WlanSet(SL_WLAN_CFG_P2P_PARAM_ID, WLAN_P2P_OPT_CHANNEL_N_REGS, 4, str); - \endcode - \par - WLAN_GENERAL_PARAM_OPT_INFO_ELEMENT: - \code - sl_protocol_WlanSetInfoElement_t infoele; - infoele.index = Index; // Index of the info element. range: 0 - MAX_PRIVATE_INFO_ELEMENTS_SUPPROTED - infoele.role = Role; // INFO_ELEMENT_AP_ROLE (0) or INFO_ELEMENT_P2P_GO_ROLE (1) - infoele.ie.id = Id; // Info element ID. if INFO_ELEMENT_DEFAULT_ID (0) is set, ID will be set to 221. - // Organization unique ID. If all 3 bytes are zero - it will be replaced with 08,00,28. - infoele.ie.oui[0] = Oui0; // Organization unique ID first Byte - infoele.ie.oui[1] = Oui1; // Organization unique ID second Byte - infoele.ie.oui[2] = Oui2; // Organization unique ID third Byte - infoele.ie.length = Len; // Length of the info element. must be smaller than 253 bytes - memset(infoele.ie.data, 0, INFO_ELEMENT_MAX_SIZE); - if ( Len <= INFO_ELEMENT_MAX_SIZE ) - { - memcpy(infoele.ie.data, IE, Len); // Info element. length of the info element is [0-252] - sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID,WLAN_GENERAL_PARAM_OPT_INFO_ELEMENT,sizeof(sl_protocol_WlanSetInfoElement_t),(_u8* ) &infoele); - } - sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID,WLAN_GENERAL_PARAM_OPT_INFO_ELEMENT,sizeof(sl_protocol_WlanSetInfoElement_t),(_u8* ) &infoele); - \endcode - -*/ -#if _SL_INCLUDE_FUNC(sl_WlanSet) -_i16 sl_WlanSet(const _u16 ConfigId ,const _u16 ConfigOpt,const _u16 ConfigLen,const _u8 *pValues); -#endif - -/*! - \brief Internal function for getting WLAN configurations - - \return On success, zero is returned. On error, -1 is - returned - - \param[in] ConfigId - configuration id - - SL_WLAN_CFG_AP_ID - - SL_WLAN_CFG_GENERAL_PARAM_ID - - SL_WLAN_CFG_P2P_PARAM_ID - - \param[out] pConfigOpt - get configurations option - - SL_WLAN_CFG_AP_ID - - WLAN_AP_OPT_SSID \n - Get SSID for AP mode. \n - Get up to 32 characters of SSID \n - This options takes _u8 as parameter - - WLAN_AP_OPT_CHANNEL \n - Get channel for AP mode. \n - This option takes _u8 as a parameter - - WLAN_AP_OPT_HIDDEN_SSID \n - Get Hidden SSID Mode for AP mode.Hidden options: \n - 0: disabled \n - 1: Send empty (length=0) SSID in beacon and ignore probe request for broadcast SSID \n - 2: Clear SSID (ASCII 0), but keep the original length (this may be required with some \n - clients that do not support empty SSID) and ignore probe requests for broadcast SSID \n - This option takes _u8 as a parameter - - WLAN_AP_OPT_SECURITY_TYPE \n - Get Security type for AP mode. Security options are: - - Open security: SL_SEC_TYPE_OPEN - - WEP security: SL_SEC_TYPE_WEP - - WPA security: SL_SEC_TYPE_WPA_WPA2 \n - This option takes _u8 as a parameter - - WLAN_AP_OPT_PASSWORD \n - Get Password for for AP mode (for WEP or for WPA): \n - Returns password - string, fills up to 64 characters. \n - This options takes _u8 buffer as parameter - - SL_WLAN_CFG_GENERAL_PARAM_ID - - WLAN_GENERAL_PARAM_OPT_SCAN_PARAMS \n - Get scan parameters. - This option uses slWlanScanParamCommand_t as parameter - - WLAN_GENERAL_PARAM_OPT_COUNTRY_CODE \n - Get Country Code for AP mode \n - This options takes _u8 buffer as parameter - - WLAN_GENERAL_PARAM_OPT_STA_TX_POWER \n - Get STA mode Tx power level \n - Number between 0-15, as dB offset from max power (0 indicates MAX power) \n - This options takes _u8 as parameter - - WLAN_GENERAL_PARAM_OPT_AP_TX_POWER - Get AP mode Tx power level \n - Number between 0-15, as dB offset from max power (0 indicates MAX power) \n - This options takes _u8 as parameter - - SL_WLAN_CFG_P2P_PARAM_ID - - WLAN_P2P_OPT_CHANNEL_N_REGS \n - Get P2P Channels. \n - listen channel (either 1/6/11 for 2.4GHz) \n - listen regulatory class (81 for 2.4GHz) \n - oper channel (either 1/6/11 for 2.4GHz) \n - oper regulatory class (81 for 2.4GHz) \n - listen channel and regulatory class will determine the device listen channel during p2p find listen phase \n - oper channel and regulatory class will determine the operating channel preferred by this device (in case it is group owner this will be the operating channel) \n - channels should be one of the social channels (1/6/11). In case no listen/oper channel selected, a random 1/6/11 will be selected. \n - This option takes pointer to _u8[4] as parameter - - \param[out] pConfigLen - The length of the allocated memory as input, when the - function complete, the value of this parameter would be - the len that actually read from the device. - If the device return length that is longer from the input - value, the function will cut the end of the returned structure - and will return SL_ESMALLBUF. - - - \param[out] pValues - get configurations values - - \sa sl_WlanSet - - \note - - \warning - - \par Examples: - \par - WLAN_GENERAL_PARAM_OPT_SCAN_PARAMS: - \code - slWlanScanParamCommand_t ScanParamConfig; - _u16 Option = WLAN_GENERAL_PARAM_OPT_SCAN_PARAMS; - _u16 OptionLen = sizeof(slWlanScanParamCommand_t); - sl_WlanGet(SL_WLAN_CFG_GENERAL_PARAM_ID ,&Option,&OptionLen,(_u8 *)&ScanParamConfig); - \endcode - \par - WLAN_GENERAL_PARAM_OPT_AP_TX_POWER: - \code - _i8 TXPower = 0; - _u16 Option = WLAN_GENERAL_PARAM_OPT_AP_TX_POWER; - _u16 OptionLen = sizeof(_i8); - sl_WlanGet(SL_WLAN_CFG_GENERAL_PARAM_ID ,&Option,&OptionLen,(_u8 *)&TXPower); - \endcode - \par - WLAN_GENERAL_PARAM_OPT_STA_TX_POWER: - \code - _i8 TXPower = 0; - _u16 Option = WLAN_GENERAL_PARAM_OPT_STA_TX_POWER; - _u16 OptionLen = sizeof(_i8); - - sl_WlanGet(SL_WLAN_CFG_GENERAL_PARAM_ID ,&Option,&OptionLen,(_u8 *)&TXPower); - \endcode - \par - WLAN_P2P_OPT_DEV_TYPE: - \code - _i8 device_type[18]; - _u16 len = 18; - _u16 config_opt = WLAN_P2P_OPT_DEV_TYPE; - sl_WlanGet(SL_WLAN_CFG_P2P_PARAM_ID, &config_opt , &len, (_u8* )device_type); - \endcode - \par - WLAN_AP_OPT_SSID: - \code - _i8 ssid[32]; - _u16 len = 32; - _u16 config_opt = WLAN_AP_OPT_SSID; - sl_WlanGet(SL_WLAN_CFG_AP_ID, &config_opt , &len, (_u8* )ssid); - \endcode - \par - WLAN_GENERAL_PARAM_OPT_COUNTRY_CODE: - \code - _i8 country[3]; - _u16 len = 3; - _u16 config_opt = WLAN_GENERAL_PARAM_OPT_COUNTRY_CODE; - sl_WlanGet(SL_WLAN_CFG_GENERAL_PARAM_ID, &config_opt, &len, (_u8* )country); - \endcode - \par - WLAN_AP_OPT_CHANNEL: - \code - _i8 channel; - _u16 len = 1; - _u16 config_opt = WLAN_AP_OPT_CHANNEL; - sl_WlanGet(SL_WLAN_CFG_AP_ID, &config_opt, &len, (_u8* )&channel); - \endcode - \par - WLAN_AP_OPT_HIDDEN_SSID: - \code - _u8 hidden; - _u16 len = 1; - _u16 config_opt = WLAN_AP_OPT_HIDDEN_SSID; - sl_WlanGet(SL_WLAN_CFG_AP_ID, &config_opt, &len, (_u8* )&hidden); - \endcode - \par - WLAN_AP_OPT_SECURITY_TYPE: - \code - _u8 sec_type; - _u16 len = 1; - _u16 config_opt = WLAN_AP_OPT_SECURITY_TYPE; - sl_WlanGet(SL_WLAN_CFG_AP_ID, &config_opt, &len, (_u8* )&sec_type); - \endcode - \par - WLAN_AP_OPT_PASSWORD: - \code - _u8 password[64]; - _u16 len = 64; - memset(password,0,64); - _u16 config_opt = WLAN_AP_OPT_PASSWORD; - sl_WlanGet(SL_WLAN_CFG_AP_ID, &config_opt, &len, (_u8* )password); - - \endcode - \par - WLAN_P2P_OPT_CHANNEL_N_REGS: - \code - _u16 listen_channel,listen_reg,oper_channel,oper_reg; - _u16 len = 4; - _u16 config_opt = WLAN_P2P_OPT_CHANNEL_N_REGS; - _u8 channel_n_regs[4]; - sl_WlanGet(SL_WLAN_CFG_P2P_PARAM_ID, &config_opt, &len, (_u8* )channel_n_regs); - listen_channel = channel_n_regs[0]; - listen_reg = channel_n_regs[1]; - oper_channel = channel_n_regs[2]; - oper_reg = channel_n_regs[3]; - \endcode -*/ - -#if _SL_INCLUDE_FUNC(sl_WlanGet) -_i16 sl_WlanGet(const _u16 ConfigId, _u16 *pConfigOpt,_u16 *pConfigLen, _u8 *pValues); -#endif -/*! - - Close the Doxygen group. - @} - - */ - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __WLAN_H__ */ - diff --git a/drivers/cc3100/inc/wlan_rx_filters.h b/drivers/cc3100/inc/wlan_rx_filters.h deleted file mode 100644 index 8bd712f0df7..00000000000 --- a/drivers/cc3100/inc/wlan_rx_filters.h +++ /dev/null @@ -1,932 +0,0 @@ -/* - * wlan_rx_filters.h - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ -#include "simplelink.h" - -#ifndef RX_FILTERS_PREPROCESSOR_CLI_IF_H_ -#define RX_FILTERS_PREPROCESSOR_CLI_IF_H_ - - - -#ifdef __cplusplus -extern "C" { -#endif - - -/*****************************************************************************/ -/* Macro declarations */ -/*****************************************************************************/ - -/*! - * \def SL_RX_FILTER_MAX_FILTERS - * The Max number of filters for 64 filters - */ -#define SL_RX_FILTER_MAX_FILTERS 64 - -/*! - * \def SL_RX_FILTER_MAX_PRE_PREPARED_FILTERS_SETS - * The Max number of software filters - */ -#define SL_RX_FILTER_MAX_PRE_PREPARED_FILTERS_SETS (32) -/*! - * \def SL_RX_FILTER_NUM_OF_FILTER_HEADER_ARGS - * - */ -#define SL_RX_FILTER_NUM_OF_FILTER_HEADER_ARGS (2) -/*! - * \def SL_RX_FILTER_NUM_OF_FILTER_PAYLOAD_ARGS - * - */ -#define SL_RX_FILTER_NUM_OF_FILTER_PAYLOAD_ARGS (2) -/*! - * \def SL_RX_FILTER_NUM_OF_FILTER_PAYLOAD_ARGS - * - */ -#define SL_RX_FILTER_NUM_OF_COMBINATION_TYPE_ARGS (2) -/*! - * \def SL_RX_FILTER_LENGTH_OF_REGX_PATTERN_LENGTH - * - */ -#define SL_RX_FILTER_LENGTH_OF_REGX_PATTERN_LENGTH (32) - - -/* List of possible error numbers */ -#define RXFL_OK (0) /* O.K */ -#define RXFL_OUTPUT_OR_INPUT_BUFFER_LENGTH_TOO_SMALL (76) /* ! The output buffer length is smaller than required for that operation */ -#define RXFL_DEPENDENT_FILTER_SOFTWARE_FILTER_NOT_FIT (75) /* Node filter can't be child of software filter and vice_versa */ -#define RXFL_DEPENDENCY_IS_NOT_PERSISTENT (74) /* Dependency filter is not persistent */ -#define RXFL_SYSTEM_STATE_NOT_SUPPORTED_FOR_THIS_FILTER (72) /* System state is not supported */ -#define RXFL_TRIGGER_USE_REG5_TO_REG8 (71) /* Only counters 5 - 8 are allowed, for Tigger */ -#define RXFL_TRIGGER_USE_REG1_TO_REG4 (70) /* Only counters 1 - 4 are allowed, for trigger */ -#define RXFL_ACTION_USE_REG5_TO_REG8 (69) /* Only counters 5 - 8 are allowed, for action */ -#define RXFL_ACTION_USE_REG1_TO_REG4 (68) /* Only counters 1 - 4 are allowed, for action */ -#define RXFL_FIELD_SUPPORT_ONLY_EQUAL_AND_NOTEQUAL (67) /* Rule compare function Id is out of range */ -#define RXFL_WRONG_MULTICAST_BROADCAST_ADDRESS (66) /* The address should be of type mutlicast or broadcast */ -#define RXFL_THE_FILTER_IS_NOT_OF_HEADER_TYPE (65) /* The filter should be of header type */ -#define RXFL_WRONG_COMPARE_FUNC_FOR_BROADCAST_ADDRESS (64) /* The compare funcion is not suitable for broadcast address */ -#define RXFL_WRONG_MULTICAST_ADDRESS (63) /* The address should be of muticast type */ -#define RXFL_DEPENDENT_FILTER_IS_NOT_PERSISTENT (62) /* The dependency filter is not persistent */ -#define RXFL_DEPENDENT_FILTER_IS_NOT_ENABLED (61) /* The dependency filter is not enabled */ -#define RXFL_FILTER_HAS_CHILDS (60) /* The filter has childs and can't be removed */ -#define RXFL_CHILD_IS_ENABLED (59) /* Can't disable filter while the child is enabled */ -#define RXFL_DEPENDENCY_IS_DISABLED (58) /* Can't enable filetr in case its depndency filter is disabled */ -#define RXFL_NUMBER_OF_CONNECTION_POINTS_EXCEEDED (52) /* Number of connection points exceeded */ -#define RXFL_DEPENDENT_FILTER_DEPENDENCY_ACTION_IS_DROP (51) /* The dependent filter has Drop action, thus the filter can't be created */ -#define RXFL_FILTER_DO_NOT_EXISTS (50) /* The filter doesn't exists */ -#define RXFL_DEPEDENCY_NOT_ON_THE_SAME_LAYER (49) /* The filter and its dependency must be on the same layer */ -#define RXFL_NUMBER_OF_ARGS_EXCEEDED (48) /* Number of arguments excceded */ -#define RXFL_ACTION_NO_REG_NUMBER (47) /* Action require counter number */ -#define RXFL_DEPENDENT_FILTER_LAYER_DO_NOT_FIT (46) /* the filter and its dependency should be from the same layer */ -#define RXFL_DEPENDENT_FILTER_SYSTEM_STATE_DO_NOT_FIT (45) /* The filter and its dependency system state don't fit */ -#define RXFL_DEPENDENT_FILTER_DO_NOT_EXIST_2 (44) /* The parent filter don't exist */ -#define RXFL_DEPENDENT_FILTER_DO_NOT_EXIST_1 (43) /* The parent filter is null */ -#define RXFL_RULE_HEADER_ACTION_TYPE_NOT_SUPPORTED (42) /* The action type is not supported */ -#define RXFL_RULE_HEADER_TRIGGER_COMPARE_FUNC_OUT_OF_RANGE (41) /* The Trigger comparision function is out of range */ -#define RXFL_RULE_HEADER_TRIGGER_OUT_OF_RANGE (40) /* The Trigger is out of range */ -#define RXFL_RULE_HEADER_COMPARE_FUNC_OUT_OF_RANGE (39) /* The rule compare function is out of range */ -#define RXFL_FRAME_TYPE_NOT_SUPPORTED (38) /* ASCII frame type string is illegal */ -#define RXFL_RULE_FIELD_ID_NOT_SUPPORTED (37) /* Rule field ID is out of range */ -#define RXFL_RULE_HEADER_FIELD_ID_ASCII_NOT_SUPPORTED (36) /* This ASCII field ID is not supported */ -#define RXFL_RULE_HEADER_NOT_SUPPORTED (35) /* The header rule is not supported on current release */ -#define RXFL_RULE_HEADER_OUT_OF_RANGE (34) /* The header rule is out of range */ -#define RXFL_RULE_HEADER_COMBINATION_OPERATOR_OUT_OF_RANGE (33) /* Combination function Id is out of ramge */ -#define RXFL_RULE_HEADER_FIELD_ID_OUT_OF_RANGE (32) /* rule field Id is out of range */ -#define RXFL_UPDATE_NOT_SUPPORTED (31) /* Update not supported */ -#define RXFL_NO_FILTERS_ARE_DEFINED (24) /* No filters are defined in the system */ -#define RXFL_NUMBER_OF_FILTER_EXCEEDED (23) /* Number of max filters excceded */ - - -/******************************************************************************/ -/* Type declarations */ -/******************************************************************************/ - -/*! - - - * \typedef SlrxFilterID_t - * Unique filter ID which is allocated by the system , negative number means error - */ -typedef _i8 SlrxFilterID_t; - - -/*! - * \typedef SlrxFilterCompareMask_t - * The mask is used for the rule comparison function - */ -typedef _u8 SlrxFilterCompareMask_t; - -/*! - * \typedef SlrxFilterIdMask_t - * Representation of filters Id as a bit field - * The bit field is used to declare which filters are involved - * in operation. Number of filter can be up to 128 filters. i.e. 128 bits are needed. - * On the current release, up to 64 filters can be defined. - */ -typedef _u8 SlrxFilterIdMask_t[128/8]; - -/*! - * \typedef SlrxFilterPrePreparedFilters_t - * Describes the supported software filter sets, - */ -typedef _u8 SlrxFilterPrePreparedFilters_t; -#define SL_ARP_AUTO_REPLY_PRE_PREPARED_FILTERS (0) -#define SL_MULTICASTSIPV4_DROP_PREPREPARED_FILTERS (1) -#define SL_MULTICASTSIPV6_DROP_PREPREPARED_FILTERS (2) -#define SL_MULTICASTSWIFI_DROP_PREPREPARED_FILTERS (3) - - - -/*! - * \typedef SlrxFilterPrePreparedFiltersMask_t - * Describes the supported software filter sets, - * each bit represents different software filter set - * The filter sets are defined at SlrxFilterPrePreparedFilters_t - */ -typedef _u8 SlrxFilterPrePreparedFiltersMask_t[SL_RX_FILTER_MAX_PRE_PREPARED_FILTERS_SETS/8]; - - -/*! \typedef SlrxFilterRegxPattern_t - * The struct contains the regular expression pattern which is used in case of payload rule. - * Not supported in the current release - */ -typedef struct SlrxFilterRegxPattern_t -{ - _u8 x[SL_RX_FILTER_LENGTH_OF_REGX_PATTERN_LENGTH]; -}SlrxFilterRegxPattern_t; - - -/*! \typedef SlrxFilterAsciiArg_t - * The buffer is used to provide container for ASCII argument, which may be used in case of HEADER rule. - * example for ASCII argument can be : IP = 256.0.67.1 - */ -typedef _u8 SlrxFilterAsciiArg_t; - - -/*! \typedef SlrxFilterBinaryArg_t - * The buffer provides container for binary argument, which may be used in case of HEADER rule - */ -typedef _u8 SlrxFilterBinaryArg_t ; - - -/*! \typedef SlrxFilterActionArg_t - * Provides container for the filter action argument. - * for example: in case action is to send automatic response , the argument is the template to be used for the automatic response. - * - * - */ -typedef _u8 SlrxFilterActionArg_t ; - - - -/*! \typedef SlrxFilterOffset_t - * The offset relative to the packet payload start location. - * Not supported on current release - */ -typedef _u32 SlrxFilterOffset_t; - - - -/*! \typedef SlrxFilterRuleType_t - * Enumerates the different filter types. - * On the current release only HEADER and COMBINATION are supported. - */ -typedef _u8 SlrxFilterRuleType_t; -/* possible values for SlrxFilterRuleType_t */ -#define HEADER (0) -#define COMBINATION (1) -#define EXACT_PATTERN (2) -#define LIKELIHOOD_PATTERN (3) -#define ALWAYS_TRUE (4) -#define NUM_OF_FILTER_TYPES (5) - - -/*! \typedef SlrxFilterFlags_t - * Bit field which sets the behaviour of the RX filter - * - */ - -#define RX_FILTER_BINARY (0x1) -#define RX_FILTER_PERSISTENT (0x8) -#define RX_FILTER_ENABLE (0x10) - -typedef union SlrxFilterFlags_t -{ - - /* struct - { */ - /*! - * The filter argument can be set as binary argument or ASCII arguments. - * When the bit is on the argument are binary. - */ - /* _u8 Binary: 1; */ - /*! - * - */ - /* _u8 AutoSort : 1; */ - /*! - * - */ - /* _u8 AutoFaultDetect : 1; */ - /*! - * When the bit is on it means the the node is enabled . - */ - /* _u8 Enabled : 1; */ - /* _u8 padding : 3; */ - /* - };*/ - - _u8 IntRepresentation; - -}SlrxFilterFlags_t; - -/*! \typedef SlrxFilterCompareFunction_t - * Used as comparison function for the header type arguments - * - */ -typedef _u8 SlrxFilterCompareFunction_t; -/* Possible values for SlrxFilterCompareFunction_t */ -#define COMPARE_FUNC_IN_BETWEEN (0) -#define COMPARE_FUNC_EQUAL (1) -#define COMPARE_FUNC_NOT_EQUAL_TO (2) -#define COMPARE_FUNC_NOT_IN_BETWEEN (3) -#define COMPARE_FUNC_NUM_OF_FILTER_COMPARE_FUNC (4) - -/*! \typedef SlrxFilterCompareFunction_t - * Used as comparison function for the header type arguments - * - */ -typedef _u8 SlrxTriggerCompareFunction_t; -/* Possible values for SlrxTriggerCompareFunction_t */ -#define TRIGGER_COMPARE_FUNC_EQUAL (0) -/* arg1 == protocolVal ,not supported in current release */ -#define TRIGGER_COMPARE_FUNC_NOT_EQUAL_TO (1) -/* arg1 == protocolVal */ -#define TRIGGER_COMPARE_FUNC_SMALLER_THAN (2) -/* arg1 == protocolVal */ -#define TRIGGER_COMPARE_FUNC_BIGGER_THAN (3) -/* definition */ -#define TRIGGER_COMPARE_FUNC_NUM_OF_FILTER_COMPARE_FUNC (4) - - -/*! \typedef SlrxFilterHdrField_t - * Provides list of possible header types which may be defined as part of the rule - * - */ -typedef _u8 SlrxFilterHdrField_t; -/* Possible values for SlrxFilterHdrField_t */ -#define NULL_FIELD_ID_TYPE (0) -/* 802.11 control\data\management */ -#define FRAME_TYPE_FIELD (1) -/* 802.11 beacon\probe\.. */ -#define FRAME_SUBTYPE_FIELD (2) - /* 802.11 bssid type */ -#define BSSID_FIELD (3) - /* */ -#define MAC_SRC_ADDRESS_FIELD (4) - /* */ -#define MAC_DST_ADDRESS_FIELD (5) -/* */ -#define FRAME_LENGTH_FIELD (6) -/* */ -#define PROTOCOL_TYPE_FIELD (7) - /* */ -#define IP_VERSION_FIELD (8) - /* TCP / UDP */ -#define IP_PROTOCOL_FIELD (9) - /* */ -#define IPV4_SRC_ADRRESS_FIELD (10) -/* */ -#define IPV4_DST_ADDRESS_FIELD (11) -/* */ -#define IPV6_SRC_ADRRESS_FIELD (12) -/* */ -#define IPV6_DST_ADDRESS_FIELD (13) - /* */ -#define SRC_PORT_FIELD (14) - /* */ -#define DST_PORT_FIELD (15) - /* Definition */ -#define NUM_OF_FIELD_NAME_FIELD (16) - -/*! \union SlrxFilterHeaderArg_t - * The structure holds the header ARGS which are used in case of HDR rule. - */ -/* -- 36 bytes */ -typedef union SlrxFilterHeaderArg_t -{ - /*----------------------------- Large size ---------------------------------*/ - /*! buffer for binary arguments, number of argument may be up to SL_RX_FILTER_NUM_OF_FILTER_HEADER_ARGS - * example : IPV6 16 bytes, 39 characters - * ipv6 Ascii address: 2001:0db8:3c4d:0015:0000:0000:abcd:ef12 - */ - - SlrxFilterBinaryArg_t RxFilterDB16BytesRuleArgs[SL_RX_FILTER_NUM_OF_FILTER_HEADER_ARGS][16 ]; /* Binary Values for comparition */ - /*! buffer for ASCII arguments, number of argument may be up to SL_RX_FILTER_NUM_OF_FILTER_HEADER_ARGS - * example : IPV6 16 bytes, 39 characters - * ipv6 Ascii address: 2001:0db8:3c4d:0015:0000:0000:abcd:ef12 - * Ascii format for ipV6 is not supported - */ - /*----------------------------- Medium size ---------------------------------*/ - /*! buffer for binary arguments, number of argument may be up to SL_RX_FILTER_NUM_OF_FILTER_HEADER_ARGS - * MAC address: 6 bytes, 17 chars - */ - SlrxFilterBinaryArg_t RxFilterDB6BytesRuleArgs[SL_RX_FILTER_NUM_OF_FILTER_HEADER_ARGS][6]; /* Binary Values for comparition */ - /*! - * ! buffer for ASCII arguments, number of argument may be up to SL_RX_FILTER_NUM_OF_FILTER_HEADER_ARGS - * IP address: 4 bytes, 15 chars - * 2 bytes are added for padding - */ - SlrxFilterAsciiArg_t RxFilterDB18BytesAsciiRuleArgs[SL_RX_FILTER_NUM_OF_FILTER_HEADER_ARGS][18]; /* Ascii Values for comparison */ - /*----------------------------- Small size ---------------------------------*/ - /*! buffer for binary arguments, number of argument may be up to SL_RX_FILTER_NUM_OF_FILTER_HEADER_ARGS - * IP address: 4 bytes, 15 chars - * Port: 2 bytes, chars: 5 chars - */ - SlrxFilterBinaryArg_t RxFilterDB4BytesRuleArgs[SL_RX_FILTER_NUM_OF_FILTER_HEADER_ARGS][4]; /* Binary Values for comparison */ - /*! buffer for ASCII arguments, number of argument may be up to SL_RX_FILTER_NUM_OF_FILTER_HEADER_ARGS - * Port: 2 bytes, chars: 5 chars - */ - SlrxFilterAsciiArg_t RxFilterDB5BytesRuleAsciiArgs[SL_RX_FILTER_NUM_OF_FILTER_HEADER_ARGS][5]; /* Ascii Values for comparison */ - /*----------------------------- 1 byte size ---------------------------------*/ - /*! buffer for binary arguments, number of argument may be up to SL_RX_FILTER_NUM_OF_FILTER_HEADER_ARGS - */ - SlrxFilterBinaryArg_t RxFilterDB1BytesRuleArgs[SL_RX_FILTER_NUM_OF_FILTER_HEADER_ARGS][1]; /* Binary Values for comparison */ -}SlrxFilterHeaderArg_t; - - - -/*! \typedef SlrxFilterRuleHeaderArgsAndMask_t - * Structure which defines the Header Args and mask - */ -/* -- 52 bytes */ -typedef struct SlrxFilterRuleHeaderArgsAndMask_t -{ - /*! Argument for the comparison function */ - /* -- 36 byte */ - SlrxFilterHeaderArg_t RuleHeaderArgs; - - /*! the mask is used in order to enable partial comparison, - * Use the 0xFFFFFFFF in case you don't want to use mask - */ - /* -- 16 bytes */ - SlrxFilterCompareMask_t RuleHeaderArgsMask[16]; - -}SlrxFilterRuleHeaderArgsAndMask_t; - -/*! \typedef SlrxFilterHeaderType_t - * Structure which defines the Header rule - * The header rule defines compare function on the protocol header - * For example destMacAddre is between ( 12:6::78:77, 12:6::78:90 ) - * - */ -/* -- 56 byte */ -typedef struct SlrxFilterHeaderType_t -{ - /*! see :: SlrxFilterRuleHeaderArgsAndMask_t */ - /* -- 52 bytes */ - SlrxFilterRuleHeaderArgsAndMask_t RuleHeaderArgsAndMask; - - /*! Packet HDR field which will be compared to the argument */ - /* -- 1 byte */ - SlrxFilterHdrField_t RuleHeaderfield; - - /* -- 1 byte */ - /*! type of the comparison function - * see :: SlrxFilterCompareFunction_t - */ - SlrxFilterCompareFunction_t RuleCompareFunc; - - /*! padding */ - /* -- 2 bytes */ - _u8 RulePadding[2]; - -}SlrxFilterHeaderType_t; - -/*! \typedef SlrxFilterPayloadType_t - * Structure which defines payload rule. - * Not supported on current release. - */ -/* -- 40 byte */ -typedef struct SlrxFilterPayloadType_t -{ - /*! Not supported on current release */ - /* -- 32 byte */ - SlrxFilterRegxPattern_t RegxPattern; - /*! Not supported on current release */ - /* -- 4 byte */ - SlrxFilterOffset_t LowerOffset; - /*! Not supported on current release */ - /* -- 4 byte */ - SlrxFilterOffset_t UpperOffset; -}SlrxFilterPayloadType_t; - -/*! \typedef SlrxFilterCombinationTypeOperator_t - * Enumerate the optional operators for the combination type - * filterID1 is located in the first arg , filterId2 is the second arg,see ::SlrxFilterCombinationType_t.CombinationFilterId - */ -typedef _u8 SlrxFilterCombinationTypeOperator_t; -/* Possible values for SlrxFilterCombinationTypeOperator_t */ -/*! !filterID1 */ -#define COMBINED_FUNC_NOT (0) -/*! filterID1 && filterID2 */ -#define COMBINED_FUNC_AND (1) -/*! filterID1 && filterID2 */ -#define COMBINED_FUNC_OR (2) - -/*! \typedef SlrxFilterCombinationType_t - * Defines the structure which define the combination type filter - * The combined filter enable to make operation on one or two filter, - * for example !filterId1 or and(filterId2,filterId3). - * - */ -/* -- 4 byte */ -typedef struct SlrxFilterCombinationType_t -{ - /* ! combination operator */ - /* -- 1 byte */ - SlrxFilterCombinationTypeOperator_t CombinationTypeOperator; - /* ! filterID, may be one or two depends on the combination operator type */ - /* -- 2 byte */ - SlrxFilterID_t CombinationFilterId[SL_RX_FILTER_NUM_OF_COMBINATION_TYPE_ARGS]; - /* ! Padding */ - /* -- 1 byte */ - _u8 Padding; -}SlrxFilterCombinationType_t; - - -/*! \typedef SlrxFilterRule_t - * Rule structure composed of behavioral flags and the filter rule definitions - * - */ -/* -- 56 byte */ -typedef union SlrxFilterRule_t -{ - /* ! Header type rule , see explanation on the ::SlrxFilterHeaderType_t structure */ - /* -- 56 byte */ - SlrxFilterHeaderType_t HeaderType; - /* ! Payload rule, not supported in current release */ - /* -- 40 byte */ - SlrxFilterPayloadType_t PayLoadHeaderType; /* future for exact pattern or like hood pattern */ - /* ! Combined type rule , see explanation in ::SlrxFilterCombinationType_t structure */ - /* -- 4 byte */ - SlrxFilterCombinationType_t CombinationType; -}SlrxFilterRule_t; - -/*! \typedef SlrxFilterTriggerRoles_t - * Bit field which represents the roleId possible values - * In the current release only Station/AP roles are supported. - */ -#define RX_FILTER_ROLE_AP (1) -#define RX_FILTER_ROLE_STA (2) -#define RX_FILTER_ROLE_PROMISCUOUS (4) -#define RX_FILTER_ROLE_NULL (0) - -typedef union SlrxFilterTriggerRoles_t -{ -/* struct */ -/* { */ -/* _u8 RoleAP :1; */ -/* _u8 RoleStation :1; */ - /* The filter is activated only in Promiscuous mode */ -/* _u8 PromiscuousMode :1; */ -/* _u8 RoleReserved :5; */ -/* }; */ - /* ! Bit fiels of the Filter role */ - _u8 IntRepresentation; - -}SlrxFilterTriggerRoles_t; - -/*! \typedef SlrxFilterTriggerConnectionStates_t - * Bit field representing the possible values of the When section of the rule - * - */ -#define RX_FILTER_CONNECTION_STATE_STA_CONNECTED (1) -#define RX_FILTER_CONNECTION_STATE_STA_NOT_CONNECTED (2) -#define RX_FILTER_CONNECTION_STATE_STA_HAS_IP (4) -#define RX_FILTER_CONNECTION_STATE_STA_HAS_NO_IP (8) - -typedef union SlrxFilterTriggerConnectionStates_t -{ -/* struct */ -/* { */ -/* _u8 RoleStationWiFiConnected :1; */ -/* _u8 RoleStationWiFiDisconneted:1; */ -/* _u8 RoleStationWiFiHasIp:1; */ -/* _u8 RoleStationWiFiHasNoIp:1; */ -/* _u8 RoleStationWiFiSocketOpened:1; */ -/* _u8 RoleStationWiFiSocketclosed:1; */ -/* }; */ -/* */ - /* ! */ - _u8 IntRepresentation; - -}SlrxFilterTriggerConnectionStates_t; - -/*! \typedef SlrxFilterDBTriggerArg_t - * Provides container for entering the filter 'when' argument. - * The current release support 'When rules' which has no arguments. - * For example : - * When connect to specific AP -- the AP bssid is the argument. - * - */ -typedef _u32 SlrxFilterDBTriggerArg_t; - - - -/*! \typedef SlrxFilterCounterId_t - * the counter ID we have 4 counters - */ -typedef _u8 SlrxFilterCounterId_t; -/* Possible values for SlrxFilterCounterId_t */ -#define NO_TRIGGER (0) -#define RX_FILTER_COUNTER1 (1) -#define RX_FILTER_COUNTER2 (2) -#define RX_FILTER_COUNTER3 (3) -#define RX_FILTER_COUNTER4 (4) -#define RX_FILTER_COUNTER5 (5) -#define RX_FILTER_COUNTER6 (6) -#define RX_FILTER_COUNTER7 (7) -#define RX_FILTER_COUNTER8 (8) -#define MAX_RX_FILTER_COUNTER (9) - - - -/*! \typedef SlrxFilterActionArgs_t - * Possible value for filter action args - * - */ - -typedef _u8 SlrxFilterActionArgs_t; -/* Possible values for SlrxFilterActionArgs_t */ -#define ACTION_ARG_REG_1_4 (0) - /* ! Can be use as counter */ -#define ACTION_ARG_TEMPLATE (1) - /* ! Can be use as counter */ -#define ACTION_ARG_EVENT (2) - -/* ! GPIO number */ -#define ACTION_ARG_GPIO (4) -/*! - * \def SL_RX_FILTER_NUM_OF_BYTES_FOR_ACTIONS_ARGS - * - */ -#define SL_RX_FILTER_NUM_OF_BYTES_FOR_ACTIONS_ARGS (5) - - - - -/*! \typedef SlrxFilterTrigger_t - * The filter trigger, determine when the filter is triggered, - * The filter is triggered in the following condition :\n - * 1. The filter parent is triggered\n - * 2. The requested connection type exists, i.e. wlan_connect\n - * 3. The filter role is the same as the system role\n - * - */ -/* -- 12 byte */ -typedef struct SlrxFilterTrigger_t -{ - /*! The parent filter ID, this is the way to build filter tree. */ - /* NULL value means tree root. - */ - /* -- 1 byte */ - SlrxFilterID_t ParentFilterID; - /* ! See ::SlrxFilterCounterId_t explanation */ - /* -- 1 byte */ - SlrxFilterCounterId_t Trigger; - /* ! See :: SlrxFilterTriggerConnectionStates_t */ - /* -- 1 byte */ - SlrxFilterTriggerConnectionStates_t TriggerArgConnectionState; - /* ! See ::SlrxFilterTriggerRoles_t */ - /* -- 1 byte */ - SlrxFilterTriggerRoles_t TriggerArgRoleStatus; - /* ! The Trigger arguments are in the same order as the Trigger bit field order. */ - /* -- 4 byte */ - SlrxFilterDBTriggerArg_t TriggerArg; - /** The compare function which will be operate for each bit that is turned on in the ::SlrxFilterTrigger_t.Trigger field, - * for example , in case the second bit in the Trigger function is on the second function in the list will be executed. - * - */ - /* -- 1 byte */ - SlrxTriggerCompareFunction_t TriggerCompareFunction; - - /* ! padding */ - /* -- 3 byte */ - _u8 Padding[3]; -} SlrxFilterTrigger_t; - -/*! \typedef SlrxFilterActionType_t - * The actions are executed only if the filter is matched,\n - * In case of false match the packet is transfered to the HOST. \n - * The action is composed of bit field structure, - * up to 2 actions can be defined per filter. - * - */ -#define RX_FILTER_ACTION_NULL (0x0) -#define RX_FILTER_ACTION_DROP (0x1) -#define RX_FILTER_ACTION_GPIO (0x2) -#define RX_FILTER_ACTION_ON_REG_INCREASE (0x4) -#define RX_FILTER_ACTION_ON_REG_DECREASE (0x8) -#define RX_FILTER_ACTION_ON_REG_RESET (0x10) -#define RX_FILTER_ACTION_SEND_TEMPLATE (0x20) /* unsupported */ -#define RX_FILTER_ACTION_EVENT_TO_HOST (0x40) /* unsupported */ - -typedef union SlrxFilterActionType_t -{ -/* struct */ -/* { */ - /* ! No action to execute the packet is dropped,drop is always on leaf. */ - /* ! If not dropped ,The packet is passed to the next filter or in case it is the last filter to the host */ -/* _u8 ActionDrop : 1; */ - /* ! Not Supported in the current release */ -/* _u8 ActionGpio : 1; */ - /*! action can increase counter registers. - * 1 = Increase - * 2 = decrease - * 3 = reset - */ -/* _u8 ActionOnREGIncrease : 1; */ -/* _u8 ActionOnREGDecrease : 1; */ -/* _u8 ActionOnREGReset : 1; */ - - /* ! Not Supported in the current release */ -/* _u8 ActionSendTemplate : 1; */ - /* ! Not Supported in the current release */ -/* _u8 ActionEventToHost: 1; */ -/* _u8 padding: 1; */ -/* }; */ - - _u8 IntRepresentation; - -}SlrxFilterActionType_t; - -/*! \typedef SlrxFilterAction_t - * Several actions can be defined,\n - * The action is executed in case the filter rule is matched. - */ -/* -- 8 byte */ -typedef struct SlrxFilterAction_t -{ - /* -- 1 byte */ - /* ! Determine which actions are supported */ - SlrxFilterActionType_t ActionType; - /* ! Buffer for the action arguments */ - /** - * location 0 - The counter to increase - * In case the action is of type "increase" the arg will contain the counter number, - * The counter number values are as in ::SlrxFilterCounterId_t.\n - * location 1 - The template arg.\n - * location 2 - The event arg.\n - * - */ - /* -- 5 byte */ - SlrxFilterActionArg_t ActionArg[SL_RX_FILTER_NUM_OF_BYTES_FOR_ACTIONS_ARGS]; - - /* ! Padding */ - /* - 2 Bytes */ - _u8 Padding[2]; - -} SlrxFilterAction_t; - - -/*! \struct _WlanRxFilterOperationCommandBuff_t - * The structure is used for the interface HOST NWP.\n - * The supported operation : \n - * ::ENABLE_DISABLE_RX_FILTER,\n - * ::REMOVE_RX_FILTER,\n - * - */ -/* 20 bytes */ -typedef struct _WlanRxFilterOperationCommandBuff_t -{ - /* -- 16 bytes */ - SlrxFilterIdMask_t FilterIdMask; - /* 4 bytes */ - _u8 Padding[4]; -}_WlanRxFilterOperationCommandBuff_t; - - - -/* -- 56 bytes */ -typedef struct _WlanRxFilterUpdateArgsCommandBuff_t -{ - /* -- 1 bytes */ - _u8 FilterId; - - /* -- 1 bytes */ - /* ! the args representation */ - _u8 BinaryRepresentation; - - /* -- 52 byte */ - SlrxFilterRuleHeaderArgsAndMask_t FilterRuleHeaderArgsAndMask; - - /* -- 2 bytes */ - _u8 Padding[2]; -}_WlanRxFilterUpdateArgsCommandBuff_t; - - -/*! \typedef _WlanRxFilterRetrieveEnableStatusCommandResponseBuff_t - * The structure is used for the interface HOST NWP.\n - * - */ -/* -- 16 bytes */ -typedef struct _WlanRxFilterRetrieveEnableStatusCommandResponseBuff_t -{ - - /* ! the filter set bit map */ - /* -- 16 bytes */ - SlrxFilterIdMask_t FilterIdMask; - -}_WlanRxFilterRetrieveEnableStatusCommandResponseBuff_t; - - -/*! \struct _WlanRxFilterPrePreparedFiltersCommandBuff_t - * The function enables to perform operations on pre-prepared filters - * - */ -typedef struct _WlanRxFilterPrePreparedFiltersCommandBuff_t -{ - /* ! the filter set bit map */ - /* -- 4 bytes */ - SlrxFilterPrePreparedFiltersMask_t FilterPrePreparedFiltersMask; - -}_WlanRxFilterPrePreparedFiltersCommandBuff_t; - - -/*! \typedef sl_protocol_WlanRxFilterPrePreparedFiltersCommandResponseBuff_t - * - */ -/*-- 4 bytes */ -typedef struct _WlanRxFilterPrePreparedFiltersCommandResponseBuff_t -{ - /* -- 4 bytes */ - /* ! the filter set bit map */ - SlrxFilterPrePreparedFiltersMask_t FilterPrePreparedFiltersMask; - -}_WlanRxFilterPrePreparedFiltersCommandResponseBuff_t; - - - -typedef _u8 SLrxFilterOperation_t; -#define SL_ENABLE_DISABLE_RX_FILTER (0) -#define SL_REMOVE_RX_FILTER (1) -#define SL_STORE_RX_FILTERS (2) -#define SL_UPDATE_RX_FILTER_ARGS (3) -#define SL_FILTER_RETRIEVE_ENABLE_STATE (4) -#define SL_FILTER_PRE_PREPARED_RETRIEVE_CREATE_REMOVE_STATE (5) -#define SL_FILTER_PRE_PREPARED_SET_CREATE_REMOVE_STATE (6) - - -/* Bit manipulation for 8 bit */ -#define ISBITSET8(x,i) ((x[i>>3] & (0x80>>(i&7)))!=0) /* < Is bit set, 8 bit unsigned numbers = x , location = i */ -#define SETBIT8(x,i) x[i>>3]|=(0x80>>(i&7)); /* < Set bit,8 bit unsigned numbers = x , location = i */ -#define CLEARBIT8(x,i) x[i>>3]&=(0x80>>(i&7))^0xFF; /* < Clear bit,8 bit unsigned numbers = x , location = i */ - - -/*********************************************************************************************/ -/* Function prototypes */ -/*********************************************************************************************/ - -/*! - - \addtogroup wlan - @{ - -*/ - - -/*! - \brief Adds new filter rule to the system - - \param[in] RuleType The rule type - \param[in] FilterFlags Flags which set the type of header rule Args and sets the persistent flag - \param[in] pRule Determine the filter rule logic - \param[in] pTrigger Determine when the rule is triggered also sets rule parent. - \param[in] pAction Sets the action to be executed in case the match functions pass - \param[out] pFilterId The filterId which was created - - \return On success, zero is returned. Otherwise error code is returned - */ -#if _SL_INCLUDE_FUNC(sl_WlanRxFilterAdd) -SlrxFilterID_t sl_WlanRxFilterAdd( SlrxFilterRuleType_t RuleType, - SlrxFilterFlags_t FilterFlags, - const SlrxFilterRule_t* const Rule, - const SlrxFilterTrigger_t* const Trigger, - const SlrxFilterAction_t* const Action, - SlrxFilterID_t* pFilterId); - -#endif - - - - - -/*! - \brief Sets parameters to Rx filters - - \param[in] RxFilterOperation - possible operations : - - SL_ENABLE_DISABLE_RX_FILTER - Enables\disables filter in a filter list - - SL_REMOVE_RX_FILTER - Removes filter from memory ( to remove from flash call SL_STORE_RX_FILTERS after this command) - - SL_STORE_RX_FILTERS - Save the filters for persistent - - SL_UPDATE_RX_FILTER_ARGS - Update the arguments of existing filter - - SL_FILTER_PRE_PREPARED_SET_CREATE_REMOVE_STATE - Change the default creation of the pre-prepared filters - - \param[in] pInputBuffer options: - The buffer input is _WlanRxFilterOperationCommandBuff_t: - - SL_ENABLE_DISABLE_RX_FILTER - - SL_REMOVE_RX_FILTER - - SL_STORE_RX_FILTERS - The buffer input is _WlanRxFilterUpdateArgsCommandBuff_t: - - SL_UPDATE_RX_FILTER_ARGS - The buffer input is _WlanRxFilterPrePreparedFiltersCommandBuff_t: - - SL_FILTER_PRE_PREPARED_SET_CREATE_REMOVE_STATE - - \param[in] InputbufferLength The length in byte of the input buffer - - \return On success, zero is returned. Otherwise error code is returned - */ - -#if _SL_INCLUDE_FUNC(sl_WlanRxFilterSet) -_i16 sl_WlanRxFilterSet( const SLrxFilterOperation_t RxFilterOperation, - const _u8* const pInputBuffer, - _u16 InputbufferLength); -#endif - -/*! - \brief Gets parameters of Rx filters - - \param[in] RxFilterOperation - possible operations : - - SL_FILTER_RETRIEVE_ENABLE_STATE - Retrieves the enable disable status - - SL_FILTER_PRE_PREPARED_RETRIEVE_CREATE_REMOVE_STATE - Retrieves the pre-prepared filters creation status - - \param[in] pOutputBuffer - The buffer input is _WlanRxFilterRetrieveEnableStatusCommandResponseBuff_t: - - SL_FILTER_RETRIEVE_ENABLE_STATE - The buffer input is _WlanRxFilterPrePreparedFiltersCommandResponseBuff_t: - - SL_FILTER_PRE_PREPARED_RETRIEVE_CREATE_REMOVE_STATE - - \param[in] OutputbufferLength The length in byte of the output buffer - - \return On success, zero is returned. Otherwise error code is returned -*/ - -#if _SL_INCLUDE_FUNC(sl_WlanRxFilterGet) -_i16 sl_WlanRxFilterGet(const SLrxFilterOperation_t RxFilterOperation, - _u8* pOutputBuffer, - _u16 OutputbufferLength); -#endif - - -/*! - - Close the Doxygen group. - @} - - */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* RX_FILTERS_PREPROCESSOR_CLI_IF_H_ */ - - diff --git a/drivers/cc3100/src/device.c b/drivers/cc3100/src/device.c deleted file mode 100644 index 3d4028fb4ab..00000000000 --- a/drivers/cc3100/src/device.c +++ /dev/null @@ -1,557 +0,0 @@ -/* -* device.c - CC31xx/CC32xx Host Driver Implementation -* -* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ -* -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*/ - - - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ -#include "simplelink.h" -#include "protocol.h" -#include "flowcont.h" -#include "driver.h" - - -/*****************************************************************************/ -/* Internal functions */ -/*****************************************************************************/ - -const _i8 StartResponseLUT[8] = -{ - ROLE_UNKNOWN_ERR, - ROLE_STA, - ROLE_STA_ERR, - ROLE_AP, - ROLE_AP_ERR, - ROLE_P2P, - ROLE_P2P_ERR, - ROLE_UNKNOWN_ERR -}; - - - -_i16 _sl_GetStartResponseConvert(_u32 Status) -{ - return (_i16)StartResponseLUT[Status & 0x7]; -} - -/*****************************************************************************/ -/* API Functions */ -/*****************************************************************************/ - - - -/*****************************************************************************/ -/* sl_Task */ -/*****************************************************************************/ -#if _SL_INCLUDE_FUNC(sl_Task) -void sl_Task(void) -{ -#ifdef _SlTaskEntry - _SlTaskEntry(); -#endif -} -#endif - -/*****************************************************************************/ -/* sl_Start */ -/*****************************************************************************/ -#if _SL_INCLUDE_FUNC(sl_Start) -_i16 sl_Start(const void* pIfHdl, _i8* pDevName, const P_INIT_CALLBACK pInitCallBack) -{ - _i16 ObjIdx = MAX_CONCURRENT_ACTIONS; - InitComplete_t AsyncRsp; - - /* Perform any preprocessing before enable networking services */ - sl_DeviceEnablePreamble(); - - /* ControlBlock init */ - _SlDrvDriverCBInit(); - - /* open the interface: usually SPI or UART */ - if (NULL == pIfHdl) - { - g_pCB->FD = sl_IfOpen((void *)pDevName, 0); - } - else - { - g_pCB->FD = (_SlFd_t)pIfHdl; - } - - ObjIdx = _SlDrvProtectAsyncRespSetting((_u8 *)&AsyncRsp, START_STOP_ID, SL_MAX_SOCKETS); - - if (MAX_CONCURRENT_ACTIONS == ObjIdx) - { - return SL_POOL_IS_EMPTY; - } - - if( g_pCB->FD >= (_SlFd_t)0) - { - sl_DeviceDisable(); - - sl_IfRegIntHdlr((SL_P_EVENT_HANDLER)_SlDrvRxIrqHandler, NULL); - - g_pCB->pInitCallback = pInitCallBack; - sl_DeviceEnable(); - - if (NULL == pInitCallBack) - { - _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj); - - /* release Pool Object */ - _SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex); - return _sl_GetStartResponseConvert(AsyncRsp.Status); - } - else - { - return SL_RET_CODE_OK; - } - } - return SL_BAD_INTERFACE; -} -#endif - -/*************************************************************************** -_sl_HandleAsync_InitComplete - handles init complete signalling to -a waiting object -****************************************************************************/ -void _sl_HandleAsync_InitComplete(void *pVoidBuf) -{ - InitComplete_t *pMsgArgs = (InitComplete_t *)_SL_RESP_ARGS_START(pVoidBuf); - - _SlDrvProtectionObjLockWaitForever(); - - if(g_pCB->pInitCallback) - { - g_pCB->pInitCallback(_sl_GetStartResponseConvert(pMsgArgs->Status)); - } - else - { - sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(InitComplete_t)); - _SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); - } - - _SlDrvProtectionObjUnLock(); - - if(g_pCB->pInitCallback) - { - _SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex); - } - -} - -/*************************************************************************** -_sl_HandleAsync_Stop - handles stop signalling to -a waiting object -****************************************************************************/ -void _sl_HandleAsync_Stop(void *pVoidBuf) -{ - _BasicResponse_t *pMsgArgs = (_BasicResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); - - VERIFY_SOCKET_CB(NULL != g_pCB->StopCB.pAsyncRsp); - - _SlDrvProtectionObjLockWaitForever(); - - sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_BasicResponse_t)); - - _SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); - _SlDrvProtectionObjUnLock(); - - return; -} - - -/***************************************************************************** -sl_stop -******************************************************************************/ -typedef union -{ - _DevStopCommand_t Cmd; - _BasicResponse_t Rsp; -}_SlStopMsg_u; - -const _SlCmdCtrl_t _SlStopCmdCtrl = -{ - SL_OPCODE_DEVICE_STOP_COMMAND, - sizeof(_DevStopCommand_t), - sizeof(_BasicResponse_t) -}; - -#if _SL_INCLUDE_FUNC(sl_Stop) -_i16 sl_Stop(const _u16 timeout) -{ - _i16 RetVal=0; - _SlStopMsg_u Msg; - _BasicResponse_t AsyncRsp; - _i8 ObjIdx = MAX_CONCURRENT_ACTIONS; - /* if timeout is 0 the shutdown is forced immediately */ - if( 0 == timeout ) - { - sl_IfRegIntHdlr(NULL, NULL); - sl_DeviceDisable(); - RetVal = sl_IfClose(g_pCB->FD); - - } - else - { - /* let the device make the shutdown using the defined timeout */ - Msg.Cmd.Timeout = timeout; - - ObjIdx = _SlDrvProtectAsyncRespSetting((_u8 *)&AsyncRsp, START_STOP_ID, SL_MAX_SOCKETS); - if (MAX_CONCURRENT_ACTIONS == ObjIdx) - { - return SL_POOL_IS_EMPTY; - } - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlStopCmdCtrl, &Msg, NULL)); - - if(SL_OS_RET_CODE_OK == (_i16)Msg.Rsp.status) - { - _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj); - Msg.Rsp.status = AsyncRsp.status; - RetVal = Msg.Rsp.status; - } - - _SlDrvReleasePoolObj(ObjIdx); - sl_IfRegIntHdlr(NULL, NULL); - sl_DeviceDisable(); - sl_IfClose(g_pCB->FD); - } - _SlDrvDriverCBDeinit(); - - return RetVal; -} -#endif - - -/***************************************************************************** -sl_EventMaskSet -*****************************************************************************/ -typedef union -{ - _DevMaskEventSetCommand_t Cmd; - _BasicResponse_t Rsp; -}_SlEventMaskSetMsg_u; - - - - -#if _SL_INCLUDE_FUNC(sl_EventMaskSet) - -const _SlCmdCtrl_t _SlEventMaskSetCmdCtrl = -{ - SL_OPCODE_DEVICE_EVENTMASKSET, - sizeof(_DevMaskEventSetCommand_t), - sizeof(_BasicResponse_t) -}; - - -_i16 sl_EventMaskSet(const _u8 EventClass ,const _u32 Mask) -{ - _SlEventMaskSetMsg_u Msg; - - Msg.Cmd.group = EventClass; - Msg.Cmd.mask = Mask; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskSetCmdCtrl, &Msg, NULL)); - - return (_i16)Msg.Rsp.status; -} -#endif - -/****************************************************************************** -sl_EventMaskGet -******************************************************************************/ -typedef union -{ - _DevMaskEventGetCommand_t Cmd; - _DevMaskEventGetResponse_t Rsp; -}_SlEventMaskGetMsg_u; - - - -#if _SL_INCLUDE_FUNC(sl_EventMaskGet) - -const _SlCmdCtrl_t _SlEventMaskGetCmdCtrl = -{ - SL_OPCODE_DEVICE_EVENTMASKGET, - sizeof(_DevMaskEventGetCommand_t), - sizeof(_DevMaskEventGetResponse_t) -}; - - -_i16 sl_EventMaskGet(const _u8 EventClass,_u32 *pMask) -{ - _SlEventMaskGetMsg_u Msg; - - Msg.Cmd.group = EventClass; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskGetCmdCtrl, &Msg, NULL)); - - *pMask = Msg.Rsp.mask; - return SL_RET_CODE_OK; -} -#endif - - - -/****************************************************************************** -sl_DevGet -******************************************************************************/ - -typedef union -{ - _DeviceSetGet_t Cmd; - _DeviceSetGet_t Rsp; -}_SlDeviceMsgGet_u; - - - -#if _SL_INCLUDE_FUNC(sl_DevGet) - -const _SlCmdCtrl_t _SlDeviceGetCmdCtrl = -{ - SL_OPCODE_DEVICE_DEVICEGET, - sizeof(_DeviceSetGet_t), - sizeof(_DeviceSetGet_t) -}; - -_i32 sl_DevGet(const _u8 DeviceGetId,_u8 *pOption,_u8 *pConfigLen, _u8 *pValues) -{ - _SlDeviceMsgGet_u Msg; - _SlCmdExt_t CmdExt; - - if (*pConfigLen == 0) - { - return SL_EZEROLEN; - } - - if( pOption ) - { - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.RxPayloadLen = *pConfigLen; - CmdExt.pRxPayload = (_u8 *)pValues; - - Msg.Cmd.DeviceSetId = DeviceGetId; - - Msg.Cmd.Option = (_u16)*pOption; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceGetCmdCtrl, &Msg, &CmdExt)); - - if( pOption ) - { - *pOption = (_u8)Msg.Rsp.Option; - } - - if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) - { - *pConfigLen = (_u8)CmdExt.RxPayloadLen; - return SL_ESMALLBUF; - } - else - { - *pConfigLen = (_u8)CmdExt.ActualRxPayloadLen; - } - - return (_i16)Msg.Rsp.Status; - } - else - { - return -1; - } -} -#endif - -/****************************************************************************** -sl_DevSet -******************************************************************************/ -typedef union -{ - _DeviceSetGet_t Cmd; - _BasicResponse_t Rsp; -}_SlDeviceMsgSet_u; - - - -#if _SL_INCLUDE_FUNC(sl_DevSet) - -const _SlCmdCtrl_t _SlDeviceSetCmdCtrl = -{ - SL_OPCODE_DEVICE_DEVICESET, - sizeof(_DeviceSetGet_t), - sizeof(_BasicResponse_t) -}; - -_i32 sl_DevSet(const _u8 DeviceSetId ,const _u8 Option,const _u8 ConfigLen,const _u8 *pValues) -{ - _SlDeviceMsgSet_u Msg; - _SlCmdExt_t CmdExt; - - - _SlDrvResetCmdExt(&CmdExt); - - CmdExt.TxPayloadLen = (ConfigLen+3) & (~3); - CmdExt.pTxPayload = (_u8 *)pValues; - - Msg.Cmd.DeviceSetId = DeviceSetId; - Msg.Cmd.ConfigLen = ConfigLen; - Msg.Cmd.Option = Option; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceSetCmdCtrl, &Msg, &CmdExt)); - - return (_i16)Msg.Rsp.status; -} -#endif - - -/****************************************************************************** -_SlDrvDeviceEventHandler - handles internally device async events -******************************************************************************/ -void _SlDrvDeviceEventHandler(void* pArgs) -{ - _SlResponseHeader_t *pHdr = (_SlResponseHeader_t *)pArgs; - - switch(pHdr->GenHeader.Opcode) - { - case SL_OPCODE_DEVICE_INITCOMPLETE: - _sl_HandleAsync_InitComplete(pHdr); - break; - case SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE: - _sl_HandleAsync_Stop(pHdr); - break; - - - case SL_OPCODE_DEVICE_ABORT: - { -#if defined (sl_GeneralEvtHdlr) || defined(EXT_LIB_REGISTERED_GENERAL_EVENTS) - SlDeviceEvent_t devHandler; - devHandler.Event = SL_DEVICE_ABORT_ERROR_EVENT; - devHandler.EventData.deviceReport.AbortType = *((_u32*)pArgs + 2); - devHandler.EventData.deviceReport.AbortData = *((_u32*)pArgs + 3); - _SlDrvHandleGeneralEvents(&devHandler); -#endif - } - break; - - case SL_OPCODE_DEVICE_DEVICEASYNCFATALERROR: -#if defined (sl_GeneralEvtHdlr) || defined(EXT_LIB_REGISTERED_GENERAL_EVENTS) - { - _BasicResponse_t *pMsgArgs = (_BasicResponse_t *)_SL_RESP_ARGS_START(pHdr); - SlDeviceEvent_t devHandler; - devHandler.Event = SL_DEVICE_FATAL_ERROR_EVENT; - devHandler.EventData.deviceEvent.status = pMsgArgs->status & 0xFF; - devHandler.EventData.deviceEvent.sender = (SlErrorSender_e)((pMsgArgs->status >> 8) & 0xFF); - _SlDrvHandleGeneralEvents(&devHandler); - } -#endif - break; - default: - SL_ERROR_TRACE2(MSG_306, "ASSERT: _SlDrvDeviceEventHandler : invalid opcode = 0x%x = %1", pHdr->GenHeader.Opcode, pHdr->GenHeader.Opcode); - } -} - - -/****************************************************************************** -sl_UartSetMode -******************************************************************************/ -#ifdef SL_IF_TYPE_UART -typedef union -{ - _DevUartSetModeCommand_t Cmd; - _DevUartSetModeResponse_t Rsp; -}_SlUartSetModeMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_UartSetMode) - - -const _SlCmdCtrl_t _SlUartSetModeCmdCtrl = -{ - SL_OPCODE_DEVICE_SETUARTMODECOMMAND, - sizeof(_DevUartSetModeCommand_t), - sizeof(_DevUartSetModeResponse_t) -}; - -_i16 sl_UartSetMode(const SlUartIfParams_t* pUartParams) -{ - _SlUartSetModeMsg_u Msg; - _u32 magicCode = 0xFFFFFFFF; - - Msg.Cmd.BaudRate = pUartParams->BaudRate; - Msg.Cmd.FlowControlEnable = pUartParams->FlowControlEnable; - - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlUartSetModeCmdCtrl, &Msg, NULL)); - - /* cmd response OK, we can continue with the handshake */ - if (SL_RET_CODE_OK == Msg.Rsp.status) - { - sl_IfMaskIntHdlr(); - - /* Close the comm port */ - sl_IfClose(g_pCB->FD); - - /* Re-open the comm port */ - sl_IfOpen((void * )pUartParams, UART_IF_OPEN_FLAG_RE_OPEN); - - sl_IfUnMaskIntHdlr(); - - /* send the magic code and wait for the response */ - sl_IfWrite(g_pCB->FD, (_u8* )&magicCode, 4); - - magicCode = UART_SET_MODE_MAGIC_CODE; - sl_IfWrite(g_pCB->FD, (_u8* )&magicCode, 4); - - /* clear magic code */ - magicCode = 0; - - /* wait (blocking) till the magic code to be returned from device */ - sl_IfRead(g_pCB->FD, (_u8* )&magicCode, 4); - - /* check for the received magic code matching */ - if (UART_SET_MODE_MAGIC_CODE != magicCode) - { - _SL_ASSERT(0); - } - } - - return (_i16)Msg.Rsp.status; -} -#endif -#endif - - diff --git a/drivers/cc3100/src/driver.c b/drivers/cc3100/src/driver.c deleted file mode 100644 index 817ff0edc67..00000000000 --- a/drivers/cc3100/src/driver.c +++ /dev/null @@ -1,1843 +0,0 @@ -/* -* driver.c - CC31xx/CC32xx Host Driver Implementation -* -* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ -* -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*/ - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ -#include "simplelink.h" -#include "protocol.h" -#include "driver.h" -#include "flowcont.h" - -/*****************************************************************************/ -/* Macro declarations */ -/*****************************************************************************/ - -#define _SL_PENDING_RX_MSG(pDriverCB) (RxIrqCnt != (pDriverCB)->RxDoneCnt) - -/* 2 LSB of the N2H_SYNC_PATTERN are for sequence number -only in SPI interface -support backward sync pattern */ -#define N2H_SYNC_PATTERN_SEQ_NUM_BITS ((_u32)0x00000003) /* Bits 0..1 - use the 2 LBS for seq num */ -#define N2H_SYNC_PATTERN_SEQ_NUM_EXISTS ((_u32)0x00000004) /* Bit 2 - sign that sequence number exists in the sync pattern */ -#define N2H_SYNC_PATTERN_MASK ((_u32)0xFFFFFFF8) /* Bits 3..31 - constant SYNC PATTERN */ -#define N2H_SYNC_SPI_BUGS_MASK ((_u32)0x7FFF7F7F) /* Bits 7,15,31 - ignore the SPI (8,16,32 bites bus) error bits */ -#define BUF_SYNC_SPIM(pBuf) ((*(_u32 *)(pBuf)) & N2H_SYNC_SPI_BUGS_MASK) - -_u8 _SlDrvProtectAsyncRespSetting(_u8 *pAsyncRsp, _u8 ActionID, _u8 SocketID); -#define N2H_SYNC_SPIM (N2H_SYNC_PATTERN & N2H_SYNC_SPI_BUGS_MASK) -#define N2H_SYNC_SPIM_WITH_SEQ(TxSeqNum) ((N2H_SYNC_SPIM & N2H_SYNC_PATTERN_MASK) | N2H_SYNC_PATTERN_SEQ_NUM_EXISTS | ((TxSeqNum) & (N2H_SYNC_PATTERN_SEQ_NUM_BITS))) -#define MATCH_WOUT_SEQ_NUM(pBuf) ( BUF_SYNC_SPIM(pBuf) == N2H_SYNC_SPIM ) -#define MATCH_WITH_SEQ_NUM(pBuf, TxSeqNum) ( BUF_SYNC_SPIM(pBuf) == (N2H_SYNC_SPIM_WITH_SEQ(TxSeqNum)) ) -#define N2H_SYNC_PATTERN_MATCH(pBuf, TxSeqNum) \ - ( \ - ( (*((_u32 *)pBuf) & N2H_SYNC_PATTERN_SEQ_NUM_EXISTS) && ( MATCH_WITH_SEQ_NUM(pBuf, TxSeqNum) ) ) || \ - ( !(*((_u32 *)pBuf) & N2H_SYNC_PATTERN_SEQ_NUM_EXISTS) && ( MATCH_WOUT_SEQ_NUM(pBuf ) ) ) \ - ) - -#define OPCODE(_ptr) (((_SlResponseHeader_t *)(_ptr))->GenHeader.Opcode) -#define RSP_PAYLOAD_LEN(_ptr) (((_SlResponseHeader_t *)(_ptr))->GenHeader.Len - _SL_RESP_SPEC_HDR_SIZE) -#define SD(_ptr) (((_SocketAddrResponse_u *)(_ptr))->IpV4.sd) -/* Actual size of Recv/Recvfrom response data */ -#define ACT_DATA_SIZE(_ptr) (((_SocketAddrResponse_u *)(_ptr))->IpV4.statusOrLen) - - - - -/* General Events handling*/ -#if defined (EXT_LIB_REGISTERED_GENERAL_EVENTS) - -typedef _SlEventPropogationStatus_e (*general_callback) (SlDeviceEvent_t *); - -static const general_callback general_callbacks[] = -{ -#ifdef SlExtLib1GeneralEventHandler - SlExtLib1GeneralEventHandler, -#endif - -#ifdef SlExtLib2GeneralEventHandler - SlExtLib2GeneralEventHandler, -#endif - -#ifdef SlExtLib3GeneralEventHandler - SlExtLib3GeneralEventHandler, -#endif - -#ifdef SlExtLib4GeneralEventHandler - SlExtLib4GeneralEventHandler, -#endif - -#ifdef SlExtLib5GeneralEventHandler - SlExtLib5GeneralEventHandler, -#endif -}; - -#undef _SlDrvHandleGeneralEvents - -/******************************************************************** - _SlDrvHandleGeneralEvents - Iterates through all the general(device) event handlers which are - registered by the external libs/user application. -*********************************************************************/ -void _SlDrvHandleGeneralEvents(SlDeviceEvent_t *slGeneralEvent) -{ - _u8 i; - - /* Iterate over all the extenal libs handlers */ - for ( i = 0 ; i < sizeof(general_callbacks)/sizeof(general_callbacks[0]) ; i++ ) - { - if (EVENT_PROPAGATION_BLOCK == general_callbacks[i](slGeneralEvent) ) - { - /* exit immediately and do not call the user specific handler as well */ - return; - } - } - -/* At last call the Application specific handler if registered */ -#ifdef sl_GeneralEvtHdlr - sl_GeneralEvtHdlr(slGeneralEvent); -#endif - -} -#endif - - - -/* WLAN Events handling*/ - -#if defined (EXT_LIB_REGISTERED_WLAN_EVENTS) - -typedef _SlEventPropogationStatus_e (*wlan_callback) (SlWlanEvent_t *); - -static wlan_callback wlan_callbacks[] = -{ -#ifdef SlExtLib1WlanEventHandler - SlExtLib1WlanEventHandler, -#endif - -#ifdef SlExtLib2WlanEventHandler - SlExtLib2WlanEventHandler, -#endif - -#ifdef SlExtLib3WlanEventHandler - SlExtLib3WlanEventHandler, -#endif - -#ifdef SlExtLib4WlanEventHandler - SlExtLib4WlanEventHandler, -#endif - -#ifdef SlExtLib5WlanEventHandler - SlExtLib5WlanEventHandler, -#endif -}; - -#undef _SlDrvHandleWlanEvents - -/*********************************************************** - _SlDrvHandleWlanEvents - Iterates through all the wlan event handlers which are - registered by the external libs/user application. -************************************************************/ -void _SlDrvHandleWlanEvents(SlWlanEvent_t *slWlanEvent) -{ - _u8 i; - - /* Iterate over all the extenal libs handlers */ - for ( i = 0 ; i < sizeof(wlan_callbacks)/sizeof(wlan_callbacks[0]) ; i++ ) - { - if ( EVENT_PROPAGATION_BLOCK == wlan_callbacks[i](slWlanEvent) ) - { - /* exit immediately and do not call the user specific handler as well */ - return; - } - } - -/* At last call the Application specific handler if registered */ -#ifdef sl_WlanEvtHdlr - sl_WlanEvtHdlr(slWlanEvent); -#endif - -} -#endif - - -/* NetApp Events handling */ -#if defined (EXT_LIB_REGISTERED_NETAPP_EVENTS) - -typedef _SlEventPropogationStatus_e (*netApp_callback) (SlNetAppEvent_t *); - -static const netApp_callback netApp_callbacks[] = -{ -#ifdef SlExtLib1NetAppEventHandler - SlExtLib1NetAppEventHandler, -#endif - -#ifdef SlExtLib2NetAppEventHandler - SlExtLib2NetAppEventHandler, -#endif - -#ifdef SlExtLib3NetAppEventHandler - SlExtLib3NetAppEventHandler, -#endif - -#ifdef SlExtLib4NetAppEventHandler - SlExtLib4NetAppEventHandler, -#endif - -#ifdef SlExtLib5NetAppEventHandler - SlExtLib5NetAppEventHandler, -#endif -}; - -#undef _SlDrvHandleNetAppEvents - -/************************************************************ - _SlDrvHandleNetAppEvents - Iterates through all the net app event handlers which are - registered by the external libs/user application. -************************************************************/ -void _SlDrvHandleNetAppEvents(SlNetAppEvent_t *slNetAppEvent) -{ - _u8 i; - - /* Iterate over all the extenal libs handlers */ - for ( i = 0 ; i < sizeof(netApp_callbacks)/sizeof(netApp_callbacks[0]) ; i++ ) - { - if (EVENT_PROPAGATION_BLOCK == netApp_callbacks[i](slNetAppEvent) ) - { - /* exit immediately and do not call the user specific handler as well */ - return; - } - } - -/* At last call the Application specific handler if registered */ -#ifdef sl_NetAppEvtHdlr - sl_NetAppEvtHdlr(slNetAppEvent); -#endif - -} -#endif - - -/* Http Server Events handling */ -#if defined (EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS) - -typedef _SlEventPropogationStatus_e (*httpServer_callback) (SlHttpServerEvent_t*, SlHttpServerResponse_t*); - -static const httpServer_callback httpServer_callbacks[] = -{ -#ifdef SlExtLib1HttpServerEventHandler - SlExtLib1HttpServerEventHandler, -#endif - -#ifdef SlExtLib2HttpServerEventHandler - SlExtLib2HttpServerEventHandler, -#endif - -#ifdef SlExtLib3HttpServerEventHandler - SlExtLib3HttpServerEventHandler, -#endif - -#ifdef SlExtLib4HttpServerEventHandler - SlExtLib4HttpServerEventHandler, -#endif - -#ifdef SlExtLib5HttpServerEventHandler - SlExtLib5HttpServerEventHandler, -#endif -}; - -#undef _SlDrvHandleHttpServerEvents - -/******************************************************************* - _SlDrvHandleHttpServerEvents - Iterates through all the http server event handlers which are - registered by the external libs/user application. -********************************************************************/ -void _SlDrvHandleHttpServerEvents(SlHttpServerEvent_t *slHttpServerEvent, SlHttpServerResponse_t *slHttpServerResponse) -{ - _u8 i; - - /* Iterate over all the external libs handlers */ - for ( i = 0 ; i < sizeof(httpServer_callbacks)/sizeof(httpServer_callbacks[0]) ; i++ ) - { - if ( EVENT_PROPAGATION_BLOCK == httpServer_callbacks[i](slHttpServerEvent, slHttpServerResponse) ) - { - /* exit immediately and do not call the user specific handler as well */ - return; - } - } - -/* At last call the Application specific handler if registered */ -#ifdef sl_HttpServerCallback - sl_HttpServerCallback(slHttpServerEvent, slHttpServerResponse); -#endif - -} -#endif - - -/* Socket Events */ -#if defined (EXT_LIB_REGISTERED_SOCK_EVENTS) - -typedef _SlEventPropogationStatus_e (*sock_callback) (SlSockEvent_t *); - -static const sock_callback sock_callbacks[] = -{ -#ifdef SlExtLib1SockEventHandler - SlExtLib1SockEventHandler, -#endif - -#ifdef SlExtLib2SockEventHandler - SlExtLib2SockEventHandler, -#endif - -#ifdef SlExtLib3SockEventHandler - SlExtLib3SockEventHandler, -#endif - -#ifdef SlExtLib4SockEventHandler - SlExtLib4SockEventHandler, -#endif - -#ifdef SlExtLib5SockEventHandler - SlExtLib5SockEventHandler, -#endif -}; - -/************************************************************* - _SlDrvHandleSockEvents - Iterates through all the socket event handlers which are - registered by the external libs/user application. -**************************************************************/ -void _SlDrvHandleSockEvents(SlSockEvent_t *slSockEvent) -{ - _u8 i; - - /* Iterate over all the external libs handlers */ - for ( i = 0 ; i < sizeof(sock_callbacks)/sizeof(sock_callbacks[0]) ; i++ ) - { - if ( EVENT_PROPAGATION_BLOCK == sock_callbacks[i](slSockEvent) ) - { - /* exit immediately and do not call the user specific handler as well */ - return; - } - } - -/* At last call the Application specific handler if registered */ -#ifdef sl_SockEvtHdlr - sl_SockEvtHdlr(slSockEvent); -#endif - -} - -#endif - - -#if (SL_MEMORY_MGMT != SL_MEMORY_MGMT_DYNAMIC) -typedef struct -{ - _u32 Align; - _SlDriverCb_t DriverCB; - _u8 AsyncRespBuf[SL_ASYNC_MAX_MSG_LEN]; -}_SlStatMem_t; - -_SlStatMem_t g_StatMem; -#endif - -_u8 _SlDrvProtectAsyncRespSetting(_u8 *pAsyncRsp, _u8 ActionID, _u8 SocketID) -{ - _u8 ObjIdx; - - - /* Use Obj to issue the command, if not available try later */ - ObjIdx = _SlDrvWaitForPoolObj(ActionID, SocketID); - - if (MAX_CONCURRENT_ACTIONS != ObjIdx) - { - _SlDrvProtectionObjLockWaitForever(); - g_pCB->ObjPool[ObjIdx].pRespArgs = pAsyncRsp; - _SlDrvProtectionObjUnLock(); - } - - return ObjIdx; -} - - -/*****************************************************************************/ -/* Variables */ -/*****************************************************************************/ -const _SlSyncPattern_t g_H2NSyncPattern = H2N_SYNC_PATTERN; -const _SlSyncPattern_t g_H2NCnysPattern = H2N_CNYS_PATTERN; -_volatile _u8 RxIrqCnt; - -#ifndef SL_TINY_EXT -const _SlActionLookup_t _SlActionLookupTable[] = -{ - {ACCEPT_ID, SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE, (_SlSpawnEntryFunc_t)_sl_HandleAsync_Accept}, - {CONNECT_ID, SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Connect}, - {SELECT_ID, SL_OPCODE_SOCKET_SELECTASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Select}, - {GETHOSYBYNAME_ID, SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_DnsGetHostByName}, - {GETHOSYBYSERVICE_ID, SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_DnsGetHostByService}, - {PING_ID, SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE, (_SlSpawnEntryFunc_t)_sl_HandleAsync_PingResponse}, - {START_STOP_ID, SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Stop} -}; -#else -const _SlActionLookup_t _SlActionLookupTable[] = -{ - {CONNECT_ID, SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Connect}, - {GETHOSYBYNAME_ID, SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_DnsGetHostByName}, - {START_STOP_ID, SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Stop} -}; -#endif - - - -typedef struct -{ - _u16 opcode; - _u8 event; -} OpcodeKeyVal_t; - -/* The table translates opcode to user's event type */ -const OpcodeKeyVal_t OpcodeTranslateTable[] = -{ -{SL_OPCODE_WLAN_SMART_CONFIG_START_ASYNC_RESPONSE, SL_WLAN_SMART_CONFIG_COMPLETE_EVENT}, -{SL_OPCODE_WLAN_SMART_CONFIG_STOP_ASYNC_RESPONSE,SL_WLAN_SMART_CONFIG_STOP_EVENT}, -{SL_OPCODE_WLAN_STA_CONNECTED, SL_WLAN_STA_CONNECTED_EVENT}, -{SL_OPCODE_WLAN_STA_DISCONNECTED,SL_WLAN_STA_DISCONNECTED_EVENT}, -{SL_OPCODE_WLAN_P2P_DEV_FOUND,SL_WLAN_P2P_DEV_FOUND_EVENT}, -{SL_OPCODE_WLAN_P2P_NEG_REQ_RECEIVED, SL_WLAN_P2P_NEG_REQ_RECEIVED_EVENT}, -{SL_OPCODE_WLAN_CONNECTION_FAILED, SL_WLAN_CONNECTION_FAILED_EVENT}, -{SL_OPCODE_WLAN_WLANASYNCCONNECTEDRESPONSE, SL_WLAN_CONNECT_EVENT}, -{SL_OPCODE_WLAN_WLANASYNCDISCONNECTEDRESPONSE, SL_WLAN_DISCONNECT_EVENT}, -{SL_OPCODE_NETAPP_IPACQUIRED, SL_NETAPP_IPV4_IPACQUIRED_EVENT}, -{SL_OPCODE_NETAPP_IPACQUIRED_V6, SL_NETAPP_IPV6_IPACQUIRED_EVENT}, -{SL_OPCODE_NETAPP_IP_LEASED, SL_NETAPP_IP_LEASED_EVENT}, -{SL_OPCODE_NETAPP_IP_RELEASED, SL_NETAPP_IP_RELEASED_EVENT}, -{SL_OPCODE_SOCKET_TXFAILEDASYNCRESPONSE, SL_SOCKET_TX_FAILED_EVENT}, -{SL_OPCODE_SOCKET_SOCKETASYNCEVENT, SL_SOCKET_ASYNC_EVENT} -}; - - - -_SlDriverCb_t* g_pCB = NULL; -P_SL_DEV_PING_CALLBACK pPingCallBackFunc = NULL; -_u8 gFirstCmdMode = 0; - -/*****************************************************************************/ -/* Function prototypes */ -/*****************************************************************************/ -_SlReturnVal_t _SlDrvMsgRead(void); -_SlReturnVal_t _SlDrvMsgWrite(_SlCmdCtrl_t *pCmdCtrl,_SlCmdExt_t *pCmdExt, _u8 *pTxRxDescBuff); -_SlReturnVal_t _SlDrvMsgReadCmdCtx(void); -_SlReturnVal_t _SlDrvMsgReadSpawnCtx(void *pValue); -void _SlDrvClassifyRxMsg(_SlOpcode_t Opcode ); -_SlReturnVal_t _SlDrvRxHdrRead(_u8 *pBuf, _u8 *pAlignSize); -void _SlDrvShiftDWord(_u8 *pBuf); -void _SlDrvDriverCBInit(void); -void _SlAsyncEventGenericHandler(void); -_u8 _SlDrvWaitForPoolObj(_u8 ActionID, _u8 SocketID); -void _SlDrvReleasePoolObj(_u8 pObj); -void _SlRemoveFromList(_u8* ListIndex, _u8 ItemIndex); -_SlReturnVal_t _SlFindAndSetActiveObj(_SlOpcode_t Opcode, _u8 Sd); - - -/*****************************************************************************/ -/* Internal functions */ -/*****************************************************************************/ - - -/***************************************************************************** -_SlDrvDriverCBInit - init Driver Control Block -*****************************************************************************/ - -void _SlDrvDriverCBInit(void) -{ - _u8 Idx =0; - -#if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_DYNAMIC) - g_pCB = sl_Malloc(sizeof(_SlDriverCb_t)); -#else - g_pCB = &(g_StatMem.DriverCB); -#endif - MALLOC_OK_CHECK(g_pCB); - - - _SlDrvMemZero(g_pCB, sizeof(_SlDriverCb_t)); - RxIrqCnt = 0; - OSI_RET_OK_CHECK( sl_SyncObjCreate(&g_pCB->CmdSyncObj, "CmdSyncObj") ); - sl_SyncObjClear(&g_pCB->CmdSyncObj); - - OSI_RET_OK_CHECK( sl_LockObjCreate(&g_pCB->GlobalLockObj, "GlobalLockObj") ); - OSI_RET_OK_CHECK( sl_LockObjCreate(&g_pCB->ProtectionLockObj, "ProtectionLockObj") ); - - /* Init Drv object */ - _SlDrvMemZero(&g_pCB->ObjPool[0], MAX_CONCURRENT_ACTIONS*sizeof(_SlPoolObj_t)); - - /* place all Obj in the free list*/ - g_pCB->FreePoolIdx = 0; - - for (Idx = 0 ; Idx < MAX_CONCURRENT_ACTIONS ; Idx++) - { - g_pCB->ObjPool[Idx].NextIndex = Idx + 1; - g_pCB->ObjPool[Idx].AdditionalData = SL_MAX_SOCKETS; - - OSI_RET_OK_CHECK( sl_SyncObjCreate(&g_pCB->ObjPool[Idx].SyncObj, "SyncObj")); - sl_SyncObjClear(&g_pCB->ObjPool[Idx].SyncObj); - } - - g_pCB->ActivePoolIdx = MAX_CONCURRENT_ACTIONS; - g_pCB->PendingPoolIdx = MAX_CONCURRENT_ACTIONS; - - /* Flow control init */ - g_pCB->FlowContCB.TxPoolCnt = FLOW_CONT_MIN; - OSI_RET_OK_CHECK(sl_LockObjCreate(&g_pCB->FlowContCB.TxLockObj, "TxLockObj")); - OSI_RET_OK_CHECK(sl_SyncObjCreate(&g_pCB->FlowContCB.TxSyncObj, "TxSyncObj")); - - gFirstCmdMode = 0; - -} - -/***************************************************************************** -_SlDrvDriverCBDeinit - De init Driver Control Block -*****************************************************************************/ -void _SlDrvDriverCBDeinit() -{ - _u8 Idx =0; - - /* Flow control de-init */ - g_pCB->FlowContCB.TxPoolCnt = 0; - OSI_RET_OK_CHECK(sl_LockObjDelete(&g_pCB->FlowContCB.TxLockObj)); - OSI_RET_OK_CHECK(sl_SyncObjDelete(&g_pCB->FlowContCB.TxSyncObj)); - - OSI_RET_OK_CHECK( sl_SyncObjDelete(&g_pCB->CmdSyncObj) ); - OSI_RET_OK_CHECK( sl_LockObjDelete(&g_pCB->GlobalLockObj) ); - OSI_RET_OK_CHECK( sl_LockObjDelete(&g_pCB->ProtectionLockObj) ); - - #ifndef SL_TINY_EXT - for (Idx = 0; Idx < MAX_CONCURRENT_ACTIONS; Idx++) - #endif - { - OSI_RET_OK_CHECK( sl_SyncObjDelete(&g_pCB->ObjPool[Idx].SyncObj) ); - } - - g_pCB->FreePoolIdx = 0; - g_pCB->PendingPoolIdx = MAX_CONCURRENT_ACTIONS; - g_pCB->ActivePoolIdx = MAX_CONCURRENT_ACTIONS; - -#if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_DYNAMIC) - sl_Free(g_pCB); -#else - g_pCB = NULL; -#endif - - - g_pCB = NULL; -} - -/***************************************************************************** -_SlDrvRxIrqHandler - Interrupt handler -*****************************************************************************/ -void _SlDrvRxIrqHandler(void *pValue) -{ - sl_IfMaskIntHdlr(); - - RxIrqCnt++; - - if (TRUE == g_pCB->IsCmdRespWaited) - { - OSI_RET_OK_CHECK( sl_SyncObjSignalFromIRQ(&g_pCB->CmdSyncObj) ); - } - else - { - sl_Spawn((_SlSpawnEntryFunc_t)_SlDrvMsgReadSpawnCtx, NULL, 0); - } -} - -/***************************************************************************** -_SlDrvCmdOp -*****************************************************************************/ -_SlReturnVal_t _SlDrvCmdOp( - _SlCmdCtrl_t *pCmdCtrl , - void *pTxRxDescBuff , - _SlCmdExt_t *pCmdExt) -{ - _SlReturnVal_t RetVal; - - - _SlDrvObjLockWaitForever(&g_pCB->GlobalLockObj); - - g_pCB->IsCmdRespWaited = TRUE; - - SL_TRACE0(DBG_MSG, MSG_312, "_SlDrvCmdOp: call _SlDrvMsgWrite"); - - - /* send the message */ - RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, pTxRxDescBuff); - - if(SL_OS_RET_CODE_OK == RetVal) - { - -#ifndef SL_IF_TYPE_UART - /* Waiting for SPI to stabilize after first command */ - if( 0 == gFirstCmdMode ) - { - volatile _u32 CountVal = 0; - gFirstCmdMode = 1; - CountVal = CPU_FREQ_IN_MHZ*USEC_DELAY; - while( CountVal-- ); - } -#endif - /* wait for respond */ - RetVal = _SlDrvMsgReadCmdCtx(); /* will free global lock */ - SL_TRACE0(DBG_MSG, MSG_314, "_SlDrvCmdOp: exited _SlDrvMsgReadCmdCtx"); - } - else - { - _SlDrvObjUnLock(&g_pCB->GlobalLockObj); - } - - return RetVal; -} - - - -/***************************************************************************** -_SlDrvDataReadOp -*****************************************************************************/ -_SlReturnVal_t _SlDrvDataReadOp( - _SlSd_t Sd, - _SlCmdCtrl_t *pCmdCtrl , - void *pTxRxDescBuff , - _SlCmdExt_t *pCmdExt) -{ - _SlReturnVal_t RetVal; - _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; - _SlArgsData_t pArgsData; - - /* Validate input arguments */ - VERIFY_PROTOCOL(NULL != pCmdExt->pRxPayload); - - /* If zero bytes is requested, return error. */ - /* This allows us not to fill remote socket's IP address in return arguments */ - VERIFY_PROTOCOL(0 != pCmdExt->RxPayloadLen); - - /* Validate socket */ - if((Sd & BSD_SOCKET_ID_MASK) >= SL_MAX_SOCKETS) - { - return SL_EBADF; - } - - /*Use Obj to issue the command, if not available try later*/ - ObjIdx = (_u8)_SlDrvWaitForPoolObj(RECV_ID, Sd & BSD_SOCKET_ID_MASK); - - if (MAX_CONCURRENT_ACTIONS == ObjIdx) - { - return SL_POOL_IS_EMPTY; - } - - _SlDrvProtectionObjLockWaitForever(); - - pArgsData.pData = pCmdExt->pRxPayload; - pArgsData.pArgs = (_u8 *)pTxRxDescBuff; - g_pCB->ObjPool[ObjIdx].pRespArgs = (_u8 *)&pArgsData; - - _SlDrvProtectionObjUnLock(); - - - /* Do Flow Control check/update for DataWrite operation */ - _SlDrvObjLockWaitForever(&g_pCB->FlowContCB.TxLockObj); - - - /* Clear SyncObj for the case it was signalled before TxPoolCnt */ - /* dropped below '1' (last Data buffer was taken) */ - /* OSI_RET_OK_CHECK( sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj) ); */ - sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj); - - if(g_pCB->FlowContCB.TxPoolCnt <= FLOW_CONT_MIN) - { - - /* If TxPoolCnt was increased by other thread at this moment, - TxSyncObj won't wait here */ - _SlDrvSyncObjWaitForever(&g_pCB->FlowContCB.TxSyncObj); - - } - - _SlDrvObjLockWaitForever(&g_pCB->GlobalLockObj); - - - VERIFY_PROTOCOL(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN); - g_pCB->FlowContCB.TxPoolCnt--; - - _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj); - - /* send the message */ - RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, (_u8 *)pTxRxDescBuff); - - _SlDrvObjUnLock(&g_pCB->GlobalLockObj); - - - if(SL_OS_RET_CODE_OK == RetVal) - { - /* Wait for response message. Will be signaled by _SlDrvMsgRead. */ - _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj); - } - - _SlDrvReleasePoolObj(ObjIdx); - return RetVal; -} - -/* ******************************************************************************/ -/* _SlDrvDataWriteOp */ -/* ******************************************************************************/ -_SlReturnVal_t _SlDrvDataWriteOp( - _SlSd_t Sd, - _SlCmdCtrl_t *pCmdCtrl , - void *pTxRxDescBuff , - _SlCmdExt_t *pCmdExt) -{ - _SlReturnVal_t RetVal = SL_EAGAIN; /* initiated as SL_EAGAIN for the non blocking mode */ - while( 1 ) - { - /* Do Flow Control check/update for DataWrite operation */ - _SlDrvObjLockWaitForever(&g_pCB->FlowContCB.TxLockObj); - - /* Clear SyncObj for the case it was signalled before TxPoolCnt */ - /* dropped below '1' (last Data buffer was taken) */ - /* OSI_RET_OK_CHECK( sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj) ); */ - sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj); - - /* we have indication that the last send has failed - socket is no longer valid for operations */ - if(g_pCB->SocketTXFailure & (1<<(Sd & BSD_SOCKET_ID_MASK))) - { - _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj); - return SL_SOC_ERROR; - } - if(g_pCB->FlowContCB.TxPoolCnt <= FLOW_CONT_MIN + 1) - { - /* we have indication that this socket is set as blocking and we try to */ - /* unblock it - return an error */ - if( g_pCB->SocketNonBlocking & (1<< (Sd & BSD_SOCKET_ID_MASK))) - { - _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj); - return RetVal; - } - /* If TxPoolCnt was increased by other thread at this moment, */ - /* TxSyncObj won't wait here */ - _SlDrvSyncObjWaitForever(&g_pCB->FlowContCB.TxSyncObj); - } - if(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN + 1 ) - { - break; - } - else - { - _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj); - } - } - - _SlDrvObjLockWaitForever(&g_pCB->GlobalLockObj); - - - VERIFY_PROTOCOL(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN + 1 ); - g_pCB->FlowContCB.TxPoolCnt--; - - _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj); - - /* send the message */ - RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, pTxRxDescBuff); - - _SlDrvObjUnLock(&g_pCB->GlobalLockObj); - - return RetVal; -} - -/* ******************************************************************************/ -/* _SlDrvMsgWrite */ -/* ******************************************************************************/ -_SlReturnVal_t _SlDrvMsgWrite(_SlCmdCtrl_t *pCmdCtrl,_SlCmdExt_t *pCmdExt, _u8 *pTxRxDescBuff) -{ - _u8 sendRxPayload = FALSE; - VERIFY_PROTOCOL(NULL != pCmdCtrl); - - g_pCB->FunctionParams.pCmdCtrl = pCmdCtrl; - g_pCB->FunctionParams.pTxRxDescBuff = pTxRxDescBuff; - g_pCB->FunctionParams.pCmdExt = pCmdExt; - - g_pCB->TempProtocolHeader.Opcode = pCmdCtrl->Opcode; - g_pCB->TempProtocolHeader.Len = _SL_PROTOCOL_CALC_LEN(pCmdCtrl, pCmdExt); - - if (pCmdExt && pCmdExt->RxPayloadLen < 0 && pCmdExt->TxPayloadLen) - { - pCmdExt->RxPayloadLen = pCmdExt->RxPayloadLen * (-1); /* change sign */ - sendRxPayload = TRUE; - g_pCB->TempProtocolHeader.Len = g_pCB->TempProtocolHeader.Len + pCmdExt->RxPayloadLen; - } - -#ifdef SL_START_WRITE_STAT - sl_IfStartWriteSequence(g_pCB->FD); -#endif - -#ifdef SL_IF_TYPE_UART - /* Write long sync pattern */ - NWP_IF_WRITE_CHECK(g_pCB->FD, (_u8 *)&g_H2NSyncPattern.Long, 2*SYNC_PATTERN_LEN); -#else - /* Write short sync pattern */ - NWP_IF_WRITE_CHECK(g_pCB->FD, (_u8 *)&g_H2NSyncPattern.Short, SYNC_PATTERN_LEN); -#endif - - /* Header */ - NWP_IF_WRITE_CHECK(g_pCB->FD, (_u8 *)&g_pCB->TempProtocolHeader, _SL_CMD_HDR_SIZE); - - /* Descriptors */ - if (pTxRxDescBuff && pCmdCtrl->TxDescLen > 0) - { - NWP_IF_WRITE_CHECK(g_pCB->FD, pTxRxDescBuff, - _SL_PROTOCOL_ALIGN_SIZE(pCmdCtrl->TxDescLen)); - } - - /* A special mode where Rx payload and Rx length are used as Tx as well */ - /* This mode requires no Rx payload on the response and currently used by fs_Close and sl_Send on */ - /* transceiver mode */ - if (sendRxPayload == TRUE ) - { - NWP_IF_WRITE_CHECK(g_pCB->FD, pCmdExt->pRxPayload, - _SL_PROTOCOL_ALIGN_SIZE(pCmdExt->RxPayloadLen)); - } - - /* Payload */ - if (pCmdExt && pCmdExt->TxPayloadLen > 0) - { - /* If the message has payload, it is mandatory that the message's arguments are protocol aligned. */ - /* Otherwise the aligning of arguments will create a gap between arguments and payload. */ - VERIFY_PROTOCOL(_SL_IS_PROTOCOL_ALIGNED_SIZE(pCmdCtrl->TxDescLen)); - - NWP_IF_WRITE_CHECK(g_pCB->FD, pCmdExt->pTxPayload, - _SL_PROTOCOL_ALIGN_SIZE(pCmdExt->TxPayloadLen)); - } - - - _SL_DBG_CNT_INC(MsgCnt.Write); - -#ifdef SL_START_WRITE_STAT - sl_IfEndWriteSequence(g_pCB->FD); -#endif - - return SL_OS_RET_CODE_OK; -} - -/* ******************************************************************************/ -/* _SlDrvMsgRead */ -/* ******************************************************************************/ -_SlReturnVal_t _SlDrvMsgRead(void) -{ - /* alignment for small memory models */ - union - { - _u8 TempBuf[_SL_RESP_HDR_SIZE]; - _u32 DummyBuf[2]; - } uBuf; - _u8 TailBuffer[4]; - _u16 LengthToCopy; - _u16 AlignedLengthRecv; - _u8 AlignSize; - _u8 *pAsyncBuf = NULL; - _u16 OpCode; - _u16 RespPayloadLen; - _u8 sd = SL_MAX_SOCKETS; - _SlRxMsgClass_e RxMsgClass; - - - /* save params in global CB */ - g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL; - g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler= NULL; - - - VERIFY_RET_OK(_SlDrvRxHdrRead((_u8*)(uBuf.TempBuf), &AlignSize)); - - OpCode = OPCODE(uBuf.TempBuf); - RespPayloadLen = RSP_PAYLOAD_LEN(uBuf.TempBuf); - - - /* 'Init Compelete' message bears no valid FlowControl info */ - if(SL_OPCODE_DEVICE_INITCOMPLETE != OpCode) - { - g_pCB->FlowContCB.TxPoolCnt = ((_SlResponseHeader_t *)uBuf.TempBuf)->TxPoolCnt; - g_pCB->SocketNonBlocking = ((_SlResponseHeader_t *)uBuf.TempBuf)->SocketNonBlocking; - g_pCB->SocketTXFailure = ((_SlResponseHeader_t *)uBuf.TempBuf)->SocketTXFailure; - - if(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN) - { - _SlDrvSyncObjSignal(&g_pCB->FlowContCB.TxSyncObj); - } - } - - /* Find the RX messaage class and set its async event handler */ - _SlDrvClassifyRxMsg(OpCode); - - RxMsgClass = g_pCB->FunctionParams.AsyncExt.RxMsgClass; - - - switch(RxMsgClass) - { - case ASYNC_EVT_CLASS: - - VERIFY_PROTOCOL(NULL == pAsyncBuf); - -#if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_DYNAMIC) - g_pCB->FunctionParams.AsyncExt.pAsyncBuf = sl_Malloc(SL_ASYNC_MAX_MSG_LEN); -#else - g_pCB->FunctionParams.AsyncExt.pAsyncBuf = g_StatMem.AsyncRespBuf; -#endif - /* set the local pointer to the allocated one */ - pAsyncBuf = g_pCB->FunctionParams.AsyncExt.pAsyncBuf; - - /* clear the async buffer */ - _SlDrvMemZero(pAsyncBuf, SL_ASYNC_MAX_MSG_LEN); - - MALLOC_OK_CHECK(pAsyncBuf); - - sl_Memcpy(pAsyncBuf, uBuf.TempBuf, _SL_RESP_HDR_SIZE); - if (_SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen) <= SL_ASYNC_MAX_PAYLOAD_LEN) - { - AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen); - } - else - { - AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(SL_ASYNC_MAX_PAYLOAD_LEN); - } - if (RespPayloadLen > 0) - { - NWP_IF_READ_CHECK(g_pCB->FD, - pAsyncBuf + _SL_RESP_HDR_SIZE, - AlignedLengthRecv); - } - /* In case ASYNC RX buffer length is smaller then the received data length, dump the rest */ - if ((_SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen) > SL_ASYNC_MAX_PAYLOAD_LEN)) - { - AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen) - SL_ASYNC_MAX_PAYLOAD_LEN; - while (AlignedLengthRecv > 0) - { - NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer,4); - AlignedLengthRecv = AlignedLengthRecv - 4; - } - } - - _SlDrvProtectionObjLockWaitForever(); - - if ( -#ifndef SL_TINY_EXT - (SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE == OpCode) || - (SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE_V6 == OpCode) || -#endif - (SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE == OpCode) - ) - { - /* go over the active list if exist to find obj waiting for this Async event */ - sd = ((((_SocketResponse_t *)(pAsyncBuf + _SL_RESP_HDR_SIZE))->sd) & BSD_SOCKET_ID_MASK); - } - _SlFindAndSetActiveObj(OpCode, sd); - - _SlDrvProtectionObjUnLock(); - - break; - case RECV_RESP_CLASS: - { - _u8 ExpArgSize; /* Expected size of Recv/Recvfrom arguments */ - - switch(OpCode) - { - case SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE: - ExpArgSize = RECVFROM_IPV4_ARGS_SIZE; - break; -#ifndef SL_TINY_EXT - case SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6: - ExpArgSize = RECVFROM_IPV6_ARGS_SIZE; - break; -#endif - default: - /* SL_OPCODE_SOCKET_RECVASYNCRESPONSE: */ - ExpArgSize = RECV_ARGS_SIZE; - } - - /* Read first 4 bytes of Recv/Recvfrom response to get SocketId and actual */ - /* response data length */ - NWP_IF_READ_CHECK(g_pCB->FD, &uBuf.TempBuf[4], RECV_ARGS_SIZE); - - /* Validate Socket ID and Received Length value. */ - VERIFY_PROTOCOL((SD(&uBuf.TempBuf[4])& BSD_SOCKET_ID_MASK) < SL_MAX_SOCKETS); - - _SlDrvProtectionObjLockWaitForever(); - - /* go over the active list if exist to find obj waiting for this Async event */ - VERIFY_RET_OK(_SlFindAndSetActiveObj(OpCode,SD(&uBuf.TempBuf[4]) & BSD_SOCKET_ID_MASK)); - - /* Verify data is waited on this socket. The pArgs should have been set by _SlDrvDataReadOp(). */ - VERIFY_SOCKET_CB(NULL != ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pData))->pArgs); - - sl_Memcpy( ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pArgs, &uBuf.TempBuf[4], RECV_ARGS_SIZE); - - if(ExpArgSize > RECV_ARGS_SIZE) - { - NWP_IF_READ_CHECK(g_pCB->FD, - ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pArgs + RECV_ARGS_SIZE, - ExpArgSize - RECV_ARGS_SIZE); - } - - /* Here g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pData contains requested(expected) Recv/Recvfrom DataSize. */ - /* Overwrite requested DataSize with actual one. */ - /* If error is received, this information will be read from arguments. */ - if(ACT_DATA_SIZE(&uBuf.TempBuf[4]) > 0) - { - VERIFY_SOCKET_CB(NULL != ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData); - - /* Read 4 bytes aligned from interface */ - /* therefore check the requested length and read only */ - /* 4 bytes aligned data. The rest unaligned (if any) will be read */ - /* and copied to a TailBuffer */ - LengthToCopy = ACT_DATA_SIZE(&uBuf.TempBuf[4]) & (3); - AlignedLengthRecv = ACT_DATA_SIZE(&uBuf.TempBuf[4]) & (~3); - if( AlignedLengthRecv >= 4) - { - NWP_IF_READ_CHECK(g_pCB->FD,((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData,AlignedLengthRecv ); - } - /* copy the unaligned part, if any */ - if( LengthToCopy > 0) - { - NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer,4); - /* copy TailBuffer unaligned part (1/2/3 bytes) */ - sl_Memcpy(((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData + AlignedLengthRecv,TailBuffer,LengthToCopy); - } - } - _SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); - _SlDrvProtectionObjUnLock(); - } - break; - - case CMD_RESP_CLASS: - - /* Some commands pass a maximum arguments size. */ - /* In this case Driver will send extra dummy patterns to NWP if */ - /* the response message is smaller than maximum. */ - /* When RxDescLen is not exact, using RxPayloadLen is forbidden! */ - /* If such case cannot be avoided - parse message here to detect */ - /* arguments/payload border. */ - NWP_IF_READ_CHECK(g_pCB->FD, - g_pCB->FunctionParams.pTxRxDescBuff, - _SL_PROTOCOL_ALIGN_SIZE(g_pCB->FunctionParams.pCmdCtrl->RxDescLen)); - - if((NULL != g_pCB->FunctionParams.pCmdExt) && (0 != g_pCB->FunctionParams.pCmdExt->RxPayloadLen)) - { - /* Actual size of command's response payload: - */ - _i16 ActDataSize = RSP_PAYLOAD_LEN(uBuf.TempBuf) - g_pCB->FunctionParams.pCmdCtrl->RxDescLen; - - g_pCB->FunctionParams.pCmdExt->ActualRxPayloadLen = ActDataSize; - - /* Check that the space prepared by user for the response data is sufficient. */ - if(ActDataSize <= 0) - { - g_pCB->FunctionParams.pCmdExt->RxPayloadLen = 0; - } - else - { - /* In case the user supplied Rx buffer length which is smaller then the received data length, copy according to user length */ - if (ActDataSize > g_pCB->FunctionParams.pCmdExt->RxPayloadLen) - { - LengthToCopy = g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (3); - AlignedLengthRecv = g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (~3); - } - else - { - LengthToCopy = ActDataSize & (3); - AlignedLengthRecv = ActDataSize & (~3); - } - /* Read 4 bytes aligned from interface */ - /* therefore check the requested length and read only */ - /* 4 bytes aligned data. The rest unaligned (if any) will be read */ - /* and copied to a TailBuffer */ - - if( AlignedLengthRecv >= 4) - { - NWP_IF_READ_CHECK(g_pCB->FD, - g_pCB->FunctionParams.pCmdExt->pRxPayload, - AlignedLengthRecv ); - - } - /* copy the unaligned part, if any */ - if( LengthToCopy > 0) - { - NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer,4); - /* copy TailBuffer unaligned part (1/2/3 bytes) */ - sl_Memcpy(g_pCB->FunctionParams.pCmdExt->pRxPayload + AlignedLengthRecv, - TailBuffer, - LengthToCopy); - ActDataSize = ActDataSize-4; - } - /* In case the user supplied Rx buffer length which is smaller then the received data length, dump the rest */ - if (ActDataSize > g_pCB->FunctionParams.pCmdExt->RxPayloadLen) - { - /* calculate the rest of the data size to dump */ - AlignedLengthRecv = ActDataSize - (g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (~3)); - while( AlignedLengthRecv > 0) - { - NWP_IF_READ_CHECK(g_pCB->FD,TailBuffer, 4 ); - AlignedLengthRecv = AlignedLengthRecv - 4; - } - } - } - } - break; - - default: - /* DUMMY_MSG_CLASS: Flow control message has no payload. */ - break; - } - - if(AlignSize > 0) - { - NWP_IF_READ_CHECK(g_pCB->FD, uBuf.TempBuf, AlignSize); - } - - _SL_DBG_CNT_INC(MsgCnt.Read); - - /* Unmask Interrupt call */ - sl_IfUnMaskIntHdlr(); - - return SL_OS_RET_CODE_OK; -} - - -/* ******************************************************************************/ -/* _SlAsyncEventGenericHandler */ -/* ******************************************************************************/ -void _SlAsyncEventGenericHandler(void) -{ - _u32 SlAsyncEvent = 0; - _u8 OpcodeFound = FALSE; - _u8 i; - - _u32* pEventLocation = NULL; /* This pointer will override the async buffer with the translated event type */ - _SlResponseHeader_t *pHdr = (_SlResponseHeader_t *)g_pCB->FunctionParams.AsyncExt.pAsyncBuf; - - - /* if no async event registered nothing to do..*/ - if (g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler == NULL) - return; - - /* Iterate through all the opcode in the table */ - for (i=0; i< (sizeof(OpcodeTranslateTable) / sizeof(OpcodeKeyVal_t)); i++) - { - if (OpcodeTranslateTable[i].opcode == pHdr->GenHeader.Opcode) - { - SlAsyncEvent = OpcodeTranslateTable[i].event; - OpcodeFound = TRUE; - break; - } - } - - /* No Async event found in the table */ - if (OpcodeFound == FALSE) - { - /* This case handles all the async events handlers of the DEVICE & SOCK Silos which are handled internally. - For these cases we send the async even buffer as is */ - g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); - } - else - { - /* calculate the event type location to be filled in the async buffer */ - pEventLocation = (_u32*)(g_pCB->FunctionParams.AsyncExt.pAsyncBuf + sizeof (_SlResponseHeader_t) - sizeof(SlAsyncEvent) ); - - /* Override the async buffer (before the data starts ) with our event type */ - *pEventLocation = SlAsyncEvent; - - /* call the event handler registered by the user with our async buffer which now holds - the User's event type and its related data */ - g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(pEventLocation); - } - - -} - - -/* ******************************************************************************/ -/* _SlDrvMsgReadCmdCtx */ -/* ******************************************************************************/ -_SlReturnVal_t _SlDrvMsgReadCmdCtx(void) -{ - - /* after command response is received and isCmdRespWaited */ - /* flag is set FALSE, it is necessary to read out all */ - /* Async messages in Commands context, because ssiDma_IsrHandleSignalFromSlave */ - /* could have dispatched some Async messages to g_NwpIf.CmdSyncObj */ - /* after command response but before this response has been processed */ - /* by spi_singleRead and isCmdRespWaited was set FALSE. */ - while (TRUE == g_pCB->IsCmdRespWaited) - { - if(_SL_PENDING_RX_MSG(g_pCB)) - { - VERIFY_RET_OK(_SlDrvMsgRead()); - g_pCB->RxDoneCnt++; - - if (CMD_RESP_CLASS == g_pCB->FunctionParams.AsyncExt.RxMsgClass) - { - g_pCB->IsCmdRespWaited = FALSE; - - /* In case CmdResp has been read without waiting on CmdSyncObj - that */ - /* Sync object. That to prevent old signal to be processed. */ - sl_SyncObjClear(&g_pCB->CmdSyncObj); - } - else if (ASYNC_EVT_CLASS == g_pCB->FunctionParams.AsyncExt.RxMsgClass) - { - /* If Async event has been read in CmdResp context, check whether */ - /* there is a handler for this event. If there is, spawn specific */ - /* handler. Otherwise free the event's buffer. */ - /* This way there will be no "dry shots" from CmdResp context to */ - /* temporary context, i.e less waste of CPU and faster buffer */ - /* release. */ - _SlAsyncEventGenericHandler(); - - -#if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_DYNAMIC) - sl_Free(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); -#else - g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL; -#endif - } - } - else - { - /* CmdSyncObj will be signaled by IRQ */ - _SlDrvSyncObjWaitForever(&g_pCB->CmdSyncObj); - } - } - - /* If there are more pending Rx Msgs after CmdResp is received, */ - /* that means that these are Async, Dummy or Read Data Msgs. */ - /* Spawn _SlDrvMsgReadSpawnCtx to trigger reading these messages from */ - /* Temporary context. */ - /* sl_Spawn is activated, using a different context */ - - _SlDrvObjUnLock(&g_pCB->GlobalLockObj); - - if(_SL_PENDING_RX_MSG(g_pCB)) - { - sl_Spawn((_SlSpawnEntryFunc_t)_SlDrvMsgReadSpawnCtx, NULL, 0); - } - - return SL_OS_RET_CODE_OK; -} - -/* ******************************************************************************/ -/* _SlDrvMsgReadSpawnCtx */ -/* ******************************************************************************/ -_SlReturnVal_t _SlDrvMsgReadSpawnCtx(void *pValue) -{ -#ifdef SL_POLLING_MODE_USED - _i16 retCode = OSI_OK; - /* for polling based systems */ - do - { - retCode = sl_LockObjLock(&g_pCB->GlobalLockObj, 0); - if ( OSI_OK != retCode ) - { - if (TRUE == g_pCB->IsCmdRespWaited) - { - _SlDrvSyncObjSignal(&g_pCB->CmdSyncObj); - return SL_RET_CODE_OK; - } - } - - } - while (OSI_OK != retCode); - -#else - _SlDrvObjLockWaitForever(&g_pCB->GlobalLockObj); -#endif - - - /* Messages might have been read by CmdResp context. Therefore after */ - /* getting LockObj, check again where the Pending Rx Msg is still present. */ - if(FALSE == (_SL_PENDING_RX_MSG(g_pCB))) - { - _SlDrvObjUnLock(&g_pCB->GlobalLockObj); - - return SL_RET_CODE_OK; - } - - VERIFY_RET_OK(_SlDrvMsgRead()); - - g_pCB->RxDoneCnt++; - - switch(g_pCB->FunctionParams.AsyncExt.RxMsgClass) - { - case ASYNC_EVT_CLASS: - /* If got here and protected by LockObj a message is waiting */ - /* to be read */ - VERIFY_PROTOCOL(NULL != g_pCB->FunctionParams.AsyncExt.pAsyncBuf); - - _SlAsyncEventGenericHandler(); - -#if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_DYNAMIC) - sl_Free(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); -#else - g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL; -#endif - break; - case DUMMY_MSG_CLASS: - case RECV_RESP_CLASS: - /* These types are legal in this context. Do nothing */ - break; - case CMD_RESP_CLASS: - /* Command response is illegal in this context. */ - /* No 'break' here: Assert! */ - default: - VERIFY_PROTOCOL(0); - } - - _SlDrvObjUnLock(&g_pCB->GlobalLockObj); - - return(SL_RET_CODE_OK); -} - - - -/* - -#define SL_OPCODE_SILO_DEVICE ( 0x0 << SL_OPCODE_SILO_OFFSET ) -#define SL_OPCODE_SILO_WLAN ( 0x1 << SL_OPCODE_SILO_OFFSET ) -#define SL_OPCODE_SILO_SOCKET ( 0x2 << SL_OPCODE_SILO_OFFSET ) -#define SL_OPCODE_SILO_NETAPP ( 0x3 << SL_OPCODE_SILO_OFFSET ) -#define SL_OPCODE_SILO_NVMEM ( 0x4 << SL_OPCODE_SILO_OFFSET ) -#define SL_OPCODE_SILO_NETCFG ( 0x5 << SL_OPCODE_SILO_OFFSET ) - - -*/ - -/* The Lookup table below holds the event handlers to be called according to the incoming - RX message SILO type */ -const _SlSpawnEntryFunc_t RxMsgClassLUT[] = { - (_SlSpawnEntryFunc_t)_SlDrvDeviceEventHandler, /* SL_OPCODE_SILO_DEVICE */ -#if defined(sl_WlanEvtHdlr) || defined(EXT_LIB_REGISTERED_WLAN_EVENTS) - (_SlSpawnEntryFunc_t)_SlDrvHandleWlanEvents, /* SL_OPCODE_SILO_WLAN */ -#else - NULL, -#endif -#if defined (sl_SockEvtHdlr) || defined(EXT_LIB_REGISTERED_SOCK_EVENTS) - (_SlSpawnEntryFunc_t)_SlDrvHandleSockEvents, /* SL_OPCODE_SILO_SOCKET */ -#else - NULL, -#endif - -#if defined(sl_NetAppEvtHdlr) || defined(EXT_LIB_REGISTERED_NETAPP_EVENTS) - (_SlSpawnEntryFunc_t)_SlDrvHandleNetAppEvents, /* SL_OPCODE_SILO_NETAPP */ -#else - NULL, -#endif - NULL, /* SL_OPCODE_SILO_NVMEM */ - NULL, /* SL_OPCODE_SILO_NETCFG */ - NULL, - NULL -}; - - -/* ******************************************************************************/ -/* _SlDrvClassifyRxMsg */ -/* ******************************************************************************/ -void _SlDrvClassifyRxMsg( - _SlOpcode_t Opcode) -{ - _SlSpawnEntryFunc_t AsyncEvtHandler = NULL; - _SlRxMsgClass_e RxMsgClass = CMD_RESP_CLASS; - _u8 Silo; - - - if (0 == (SL_OPCODE_SYNC & Opcode)) - { /* Async event has received */ - - if (SL_OPCODE_DEVICE_DEVICEASYNCDUMMY == Opcode) - { - RxMsgClass = DUMMY_MSG_CLASS; - } - else if ( (SL_OPCODE_SOCKET_RECVASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE == Opcode) -#ifndef SL_TINY_EXT - || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6 == Opcode) -#endif - ) - { - RxMsgClass = RECV_RESP_CLASS; - } - else - { - /* This is Async Event class message */ - RxMsgClass = ASYNC_EVT_CLASS; - - /* Despite the fact that 4 bits are allocated in the SILO field, we actually have only 6 SILOs - So we can use the 8 options of SILO in look up table */ - Silo = ((Opcode >> SL_OPCODE_SILO_OFFSET) & 0x7); - - VERIFY_PROTOCOL(Silo < (sizeof(RxMsgClassLUT)/sizeof(_SlSpawnEntryFunc_t))); - - /* Set the async event hander according to the LUT */ - AsyncEvtHandler = RxMsgClassLUT[Silo]; - - if ((SL_OPCODE_NETAPP_HTTPGETTOKENVALUE == Opcode) || (SL_OPCODE_NETAPP_HTTPPOSTTOKENVALUE == Opcode)) - { - AsyncEvtHandler = _SlDrvNetAppEventHandler; - } -#ifndef SL_TINY_EXT - else if (SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE == Opcode) - { - AsyncEvtHandler = (_SlSpawnEntryFunc_t)_sl_HandleAsync_PingResponse; - } -#endif - } - } - - g_pCB->FunctionParams.AsyncExt.RxMsgClass = RxMsgClass; - g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = AsyncEvtHandler; - -} - - -/* ******************************************************************************/ -/* _SlDrvRxHdrRead */ -/* ******************************************************************************/ -_SlReturnVal_t _SlDrvRxHdrRead(_u8 *pBuf, _u8 *pAlignSize) -{ - _u32 SyncCnt = 0; - _u8 ShiftIdx; - -#ifndef SL_IF_TYPE_UART - /* 1. Write CNYS pattern to NWP when working in SPI mode only */ - NWP_IF_WRITE_CHECK(g_pCB->FD, (_u8 *)&g_H2NCnysPattern.Short, SYNC_PATTERN_LEN); -#endif - - /* 2. Read 4 bytes (protocol aligned) */ - NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[0], 4); - _SL_DBG_SYNC_LOG(SyncCnt,pBuf); - - /* Wait for SYNC_PATTERN_LEN from the device */ - while ( ! N2H_SYNC_PATTERN_MATCH(pBuf, g_pCB->TxSeqNum) ) - { - /* 3. Debug limit of scan */ - VERIFY_PROTOCOL(SyncCnt < SL_SYNC_SCAN_THRESHOLD); - - /* 4. Read next 4 bytes to Low 4 bytes of buffer */ - if(0 == (SyncCnt % (_u32)SYNC_PATTERN_LEN)) - { - NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[4], 4); - _SL_DBG_SYNC_LOG(SyncCnt,pBuf); - } - - /* 5. Shift Buffer Up for checking if the sync is shifted */ - for(ShiftIdx = 0; ShiftIdx< 7; ShiftIdx++) - { - pBuf[ShiftIdx] = pBuf[ShiftIdx+1]; - } - pBuf[7] = 0; - - SyncCnt++; - } - - /* 5. Sync pattern found. If needed, complete number of read bytes to multiple of 4 (protocol align) */ - SyncCnt %= SYNC_PATTERN_LEN; - - if(SyncCnt > 0) - { - *(_u32 *)&pBuf[0] = *(_u32 *)&pBuf[4]; - NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[SYNC_PATTERN_LEN - SyncCnt], (_u16)SyncCnt); - } - else - { - NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[0], 4); - } - - /* 6. Scan for Double pattern. */ - while ( N2H_SYNC_PATTERN_MATCH(pBuf, g_pCB->TxSeqNum) ) - { - _SL_DBG_CNT_INC(Work.DoubleSyncPattern); - NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[0], SYNC_PATTERN_LEN); - } - g_pCB->TxSeqNum++; - - /* 7. Here we've read Generic Header (4 bytes). Read the Resp Specific header (4 more bytes). */ - NWP_IF_READ_CHECK(g_pCB->FD, &pBuf[SYNC_PATTERN_LEN], _SL_RESP_SPEC_HDR_SIZE); - - /* 8. Here we've read the entire Resp Header. */ - /* Return number bytes needed to be sent after read for NWP Rx 4-byte alignment (protocol alignment) */ - *pAlignSize = (_u8)((SyncCnt > 0) ? (SYNC_PATTERN_LEN - SyncCnt) : 0); - - return SL_RET_CODE_OK; -} - -/* ***************************************************************************** */ -/* _SlDrvBasicCmd */ -/* ***************************************************************************** */ -typedef union -{ - _BasicResponse_t Rsp; -}_SlBasicCmdMsg_u; - - -#ifndef SL_TINY_EXT -_i16 _SlDrvBasicCmd(_SlOpcode_t Opcode) -{ - _SlBasicCmdMsg_u Msg = {{0, 0}}; - _SlCmdCtrl_t CmdCtrl; - - CmdCtrl.Opcode = Opcode; - CmdCtrl.TxDescLen = 0; - CmdCtrl.RxDescLen = sizeof(_BasicResponse_t); - - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL)); - - return (_i16)Msg.Rsp.status; -} - -/***************************************************************************** - _SlDrvCmdSend - Send SL command without waiting for command response - This function is unprotected and the caller should make - sure global lock is active -*****************************************************************************/ -_SlReturnVal_t _SlDrvCmdSend( - _SlCmdCtrl_t *pCmdCtrl , - void *pTxRxDescBuff , - _SlCmdExt_t *pCmdExt) -{ - _SlReturnVal_t RetVal; - _u8 IsCmdRespWaitedOriginalVal; - - _SlFunctionParams_t originalFuncParms; - - /* save the current RespWait flag before clearing it */ - IsCmdRespWaitedOriginalVal = g_pCB->IsCmdRespWaited; - - /* save the current command parameters */ - sl_Memcpy(&originalFuncParms, &g_pCB->FunctionParams, sizeof(_SlFunctionParams_t)); - - g_pCB->IsCmdRespWaited = FALSE; - - SL_TRACE0(DBG_MSG, MSG_312, "_SlDrvCmdSend: call _SlDrvMsgWrite"); - - /* send the message */ - RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, pTxRxDescBuff); - - /* restore the original RespWait flag */ - g_pCB->IsCmdRespWaited = IsCmdRespWaitedOriginalVal; - - /* restore the original command parameters */ - sl_Memcpy(&g_pCB->FunctionParams, &originalFuncParms, sizeof(_SlFunctionParams_t)); - - return RetVal; - - -} -#endif - -/* ***************************************************************************** */ -/* _SlDrvWaitForPoolObj */ -/* ***************************************************************************** */ -_u8 _SlDrvWaitForPoolObj(_u8 ActionID, _u8 SocketID) -{ - _u8 CurrObjIndex = MAX_CONCURRENT_ACTIONS; - - /* Get free object */ - _SlDrvProtectionObjLockWaitForever(); - if (MAX_CONCURRENT_ACTIONS > g_pCB->FreePoolIdx) - { - /* save the current obj index */ - CurrObjIndex = g_pCB->FreePoolIdx; - /* set the new free index */ -#ifndef SL_TINY_EXT - if (MAX_CONCURRENT_ACTIONS > g_pCB->ObjPool[CurrObjIndex].NextIndex) - { - g_pCB->FreePoolIdx = g_pCB->ObjPool[CurrObjIndex].NextIndex; - } - else -#endif - { - /* No further free actions available */ - g_pCB->FreePoolIdx = MAX_CONCURRENT_ACTIONS; - } - } - else - { - _SlDrvProtectionObjUnLock(); - return CurrObjIndex; - } - g_pCB->ObjPool[CurrObjIndex].ActionID = (_u8)ActionID; - if (SL_MAX_SOCKETS > SocketID) - { - g_pCB->ObjPool[CurrObjIndex].AdditionalData = SocketID; - } -#ifndef SL_TINY_EXT - /*In case this action is socket related, SocketID bit will be on - In case SocketID is set to SL_MAX_SOCKETS, the socket is not relevant to the action. In that case ActionID bit will be on */ - while ( ( (SL_MAX_SOCKETS > SocketID) && (g_pCB->ActiveActionsBitmap & (1<ActiveActionsBitmap & (1<ObjPool[CurrObjIndex].NextIndex = g_pCB->PendingPoolIdx; - g_pCB->PendingPoolIdx = CurrObjIndex; - _SlDrvProtectionObjUnLock(); - - /* wait for action to be free */ - _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[CurrObjIndex].SyncObj); - - /* set params and move to active (remove from pending list at _SlDrvReleasePoolObj) */ - _SlDrvProtectionObjLockWaitForever(); - } -#endif - /* mark as active. Set socket as active if action is on socket, otherwise mark action as active */ - if (SL_MAX_SOCKETS > SocketID) - { - g_pCB->ActiveActionsBitmap |= (1<ActiveActionsBitmap |= (1<ObjPool[CurrObjIndex].NextIndex = g_pCB->ActivePoolIdx; - g_pCB->ActivePoolIdx = CurrObjIndex; - /* unlock */ - _SlDrvProtectionObjUnLock(); - return CurrObjIndex; -} - -/* ******************************************************************************/ -/* _SlDrvReleasePoolObj */ -/* ******************************************************************************/ -void _SlDrvReleasePoolObj(_u8 ObjIdx) -{ -#ifndef SL_TINY_EXT - _u8 PendingIndex; -#endif - - _SlDrvProtectionObjLockWaitForever(); - - /* In Tiny mode, there is only one object pool so no pending actions are available */ -#ifndef SL_TINY_EXT - /* go over the pending list and release other pending action if needed */ - PendingIndex = g_pCB->PendingPoolIdx; - - while(MAX_CONCURRENT_ACTIONS > PendingIndex) - { - /* In case this action is socket related, SocketID is in use, otherwise will be set to SL_MAX_SOCKETS */ - if ( (g_pCB->ObjPool[PendingIndex].ActionID == g_pCB->ObjPool[ObjIdx].ActionID) && - ( (SL_MAX_SOCKETS == (g_pCB->ObjPool[PendingIndex].AdditionalData & BSD_SOCKET_ID_MASK)) || - ((SL_MAX_SOCKETS > (g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK)) && ( (g_pCB->ObjPool[PendingIndex].AdditionalData & BSD_SOCKET_ID_MASK) == (g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK) ))) ) - { - /* remove from pending list */ - _SlRemoveFromList(&g_pCB->PendingPoolIdx, PendingIndex); - _SlDrvSyncObjSignal(&g_pCB->ObjPool[PendingIndex].SyncObj); - break; - } - PendingIndex = g_pCB->ObjPool[PendingIndex].NextIndex; - } -#endif - - if (SL_MAX_SOCKETS > (g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK)) - { - /* unset socketID */ - g_pCB->ActiveActionsBitmap &= ~(1<<(g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK)); - } - else - { - /* unset actionID */ - g_pCB->ActiveActionsBitmap &= ~(1<ObjPool[ObjIdx].ActionID); - } - - /* delete old data */ - g_pCB->ObjPool[ObjIdx].pRespArgs = NULL; - g_pCB->ObjPool[ObjIdx].ActionID = 0; - g_pCB->ObjPool[ObjIdx].AdditionalData = SL_MAX_SOCKETS; - - /* remove from active list */ - _SlRemoveFromList(&g_pCB->ActivePoolIdx, ObjIdx); - /* move to free list */ - g_pCB->ObjPool[ObjIdx].NextIndex = g_pCB->FreePoolIdx; - g_pCB->FreePoolIdx = ObjIdx; - _SlDrvProtectionObjUnLock(); -} - - -/* ******************************************************************************/ -/* _SlRemoveFromList */ -/* ******************************************************************************/ -void _SlRemoveFromList(_u8 *ListIndex, _u8 ItemIndex) -{ -#ifndef SL_TINY_EXT - _u8 Idx; -#endif - - if (MAX_CONCURRENT_ACTIONS == g_pCB->ObjPool[*ListIndex].NextIndex) - { - *ListIndex = MAX_CONCURRENT_ACTIONS; - } - /* As MAX_CONCURRENT_ACTIONS is equal to 1 in Tiny mode */ -#ifndef SL_TINY_EXT - /* need to remove the first item in the list and therefore update the global which holds this index */ - else if (*ListIndex == ItemIndex) - { - *ListIndex = g_pCB->ObjPool[ItemIndex].NextIndex; - } - else - { - Idx = *ListIndex; - - while(MAX_CONCURRENT_ACTIONS > Idx) - { - /* remove from list */ - if (g_pCB->ObjPool[Idx].NextIndex == ItemIndex) - { - g_pCB->ObjPool[Idx].NextIndex = g_pCB->ObjPool[ItemIndex].NextIndex; - break; - } - - Idx = g_pCB->ObjPool[Idx].NextIndex; - } - } -#endif -} - - -/* ******************************************************************************/ -/* _SlFindAndSetActiveObj */ -/* ******************************************************************************/ -_SlReturnVal_t _SlFindAndSetActiveObj(_SlOpcode_t Opcode, _u8 Sd) -{ - _u8 ActiveIndex; - - ActiveIndex = g_pCB->ActivePoolIdx; - /* go over the active list if exist to find obj waiting for this Async event */ -#ifndef SL_TINY_EXT - while (MAX_CONCURRENT_ACTIONS > ActiveIndex) -#else - /* Only one Active action is availabe in tiny mode, so we can replace the loop with if condition */ - if (MAX_CONCURRENT_ACTIONS > ActiveIndex) -#endif - { - /* unset the Ipv4\IPv6 bit in the opcode if family bit was set */ - if (g_pCB->ObjPool[ActiveIndex].AdditionalData & SL_NETAPP_FAMILY_MASK) - { - Opcode &= ~SL_OPCODE_IPV6; - } - - if ((g_pCB->ObjPool[ActiveIndex].ActionID == RECV_ID) && (Sd == g_pCB->ObjPool[ActiveIndex].AdditionalData) && - ( (SL_OPCODE_SOCKET_RECVASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE == Opcode) -#ifndef SL_TINY_EXT - || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6 == Opcode) -#endif - ) - - ) - { - g_pCB->FunctionParams.AsyncExt.ActionIndex = ActiveIndex; - return SL_RET_CODE_OK; - } - /* In case this action is socket related, SocketID is in use, otherwise will be set to SL_MAX_SOCKETS */ - if ( (_SlActionLookupTable[ g_pCB->ObjPool[ActiveIndex].ActionID - MAX_SOCKET_ENUM_IDX].ActionAsyncOpcode == Opcode) && - ( ((Sd == (g_pCB->ObjPool[ActiveIndex].AdditionalData & BSD_SOCKET_ID_MASK) ) && (SL_MAX_SOCKETS > Sd)) || (SL_MAX_SOCKETS == (g_pCB->ObjPool[ActiveIndex].AdditionalData & BSD_SOCKET_ID_MASK)) ) ) - { - /* set handler */ - g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = _SlActionLookupTable[ g_pCB->ObjPool[ActiveIndex].ActionID - MAX_SOCKET_ENUM_IDX].AsyncEventHandler; - g_pCB->FunctionParams.AsyncExt.ActionIndex = ActiveIndex; - return SL_RET_CODE_OK; - } - ActiveIndex = g_pCB->ObjPool[ActiveIndex].NextIndex; - } - - return SL_RET_CODE_SELF_ERROR; - - - -} - - -/* Wrappers for the object functions */ - -void _SlDrvSyncObjWaitForever(_SlSyncObj_t *pSyncObj) -{ - OSI_RET_OK_CHECK(sl_SyncObjWait(pSyncObj, SL_OS_WAIT_FOREVER)); -} - -void _SlDrvSyncObjSignal(_SlSyncObj_t *pSyncObj) -{ - OSI_RET_OK_CHECK(sl_SyncObjSignal(pSyncObj)); -} - -void _SlDrvObjLockWaitForever(_SlLockObj_t *pLockObj) -{ - OSI_RET_OK_CHECK(sl_LockObjLock(pLockObj, SL_OS_WAIT_FOREVER)); -} - -void _SlDrvProtectionObjLockWaitForever() -{ - OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); - -} - -void _SlDrvObjUnLock(_SlLockObj_t *pLockObj) -{ - OSI_RET_OK_CHECK(sl_LockObjUnlock(pLockObj)); - -} - -void _SlDrvProtectionObjUnLock() -{ - OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); -} - - -void _SlDrvMemZero(void* Addr, _u16 size) -{ - sl_Memset(Addr, 0, size); -} - - -void _SlDrvResetCmdExt(_SlCmdExt_t* pCmdExt) -{ - _SlDrvMemZero(pCmdExt, sizeof (_SlCmdExt_t)); -} - - - - diff --git a/drivers/cc3100/src/flowcont.c b/drivers/cc3100/src/flowcont.c deleted file mode 100644 index 889241ea2be..00000000000 --- a/drivers/cc3100/src/flowcont.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * flowcont.c - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - - - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ -#include "simplelink.h" -#include "protocol.h" -#include "driver.h" -#include "flowcont.h" - - -/*****************************************************************************/ -/* _SlDrvFlowContInit */ -/*****************************************************************************/ -void _SlDrvFlowContInit(void) -{ - g_pCB->FlowContCB.TxPoolCnt = FLOW_CONT_MIN; - - OSI_RET_OK_CHECK(sl_LockObjCreate(&g_pCB->FlowContCB.TxLockObj, "TxLockObj")); - - OSI_RET_OK_CHECK(sl_SyncObjCreate(&g_pCB->FlowContCB.TxSyncObj, "TxSyncObj")); -} - -/*****************************************************************************/ -/* _SlDrvFlowContDeinit */ -/*****************************************************************************/ -void _SlDrvFlowContDeinit(void) -{ - g_pCB->FlowContCB.TxPoolCnt = 0; - - OSI_RET_OK_CHECK(sl_LockObjDelete(&g_pCB->FlowContCB.TxLockObj)); - - OSI_RET_OK_CHECK(sl_SyncObjDelete(&g_pCB->FlowContCB.TxSyncObj)); -} - diff --git a/drivers/cc3100/src/fs.c b/drivers/cc3100/src/fs.c deleted file mode 100644 index cc2e9987d02..00000000000 --- a/drivers/cc3100/src/fs.c +++ /dev/null @@ -1,424 +0,0 @@ -/* - * fs.c - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - - - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ -#include "simplelink.h" -#include "protocol.h" -#include "driver.h" - -/*****************************************************************************/ -/* Macro declarations */ -/*****************************************************************************/ -#define sl_min(a,b) (((a) < (b)) ? (a) : (b)) -#define MAX_NVMEM_CHUNK_SIZE 1460 - -/*****************************************************************************/ -/* Internal functions */ -/*****************************************************************************/ - -/*****************************************************************************/ -/* _sl_Strlen */ -/*****************************************************************************/ -_u16 _sl_Strlen(const _u8 *buffer) -{ - _u16 len = 0; - if( buffer != NULL ) - { - while(*buffer++) len++; - } - return len; -} - -/*****************************************************************************/ -/* _sl_GetCreateFsMode */ -/*****************************************************************************/ -_u32 _sl_GetCreateFsMode(_u32 maxSizeInBytes,_u32 accessFlags) -{ - _u32 granIdx = 0; - _u32 granNum = 0; - _u32 granTable[_FS_MAX_MODE_SIZE_GRAN] = {256,1024,4096,16384,65536}; - for(granIdx= _FS_MODE_SIZE_GRAN_256B ;granIdx< _FS_MAX_MODE_SIZE_GRAN;granIdx++) - { - if( granTable[granIdx]*255 >= maxSizeInBytes ) - break; - } - granNum = maxSizeInBytes/granTable[granIdx]; - if( maxSizeInBytes % granTable[granIdx] != 0 ) - granNum++; - - return _FS_MODE(_FS_MODE_OPEN_WRITE_CREATE_IF_NOT_EXIST, granIdx, granNum, accessFlags); -} - -/*****************************************************************************/ -/* API functions */ -/*****************************************************************************/ - -/*****************************************************************************/ -/* sl_FsOpen */ -/*****************************************************************************/ -typedef union -{ - _FsOpenCommand_t Cmd; - _FsOpenResponse_t Rsp; -}_SlFsOpenMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_FsOpen) - -const _SlCmdCtrl_t _SlFsOpenCmdCtrl = -{ - SL_OPCODE_NVMEM_FILEOPEN, - sizeof(_FsOpenCommand_t), - sizeof(_FsOpenResponse_t) -}; - -_i32 sl_FsOpen(const _u8 *pFileName,const _u32 AccessModeAndMaxSize, _u32 *pToken,_i32 *pFileHandle) -{ - _SlReturnVal_t RetVal; - _SlFsOpenMsg_u Msg; - _SlCmdExt_t CmdExt; - - CmdExt.TxPayloadLen = (_sl_Strlen(pFileName)+4) & (~3); /* add 4: 1 for NULL and the 3 for align */ - CmdExt.RxPayloadLen = 0; - CmdExt.pTxPayload = (_u8*)pFileName; - CmdExt.pRxPayload = NULL; - - Msg.Cmd.Mode = AccessModeAndMaxSize; - - if(pToken != NULL) - { - Msg.Cmd.Token = *pToken; - } - else - { - Msg.Cmd.Token = 0; - } - - RetVal = _SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsOpenCmdCtrl, &Msg, &CmdExt); - *pFileHandle = Msg.Rsp.FileHandle; - if (pToken != NULL) - { - *pToken = Msg.Rsp.Token; - } - - /* in case of an error, return the erros file handler as an error code */ - if( *pFileHandle < 0 ) - { - return *pFileHandle; - } - return (_i32)RetVal; -} -#endif - -/*****************************************************************************/ -/* sl_FsClose */ -/*****************************************************************************/ -typedef union -{ - _FsCloseCommand_t Cmd; - _BasicResponse_t Rsp; -}_SlFsCloseMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_FsClose) - -const _SlCmdCtrl_t _SlFsCloseCmdCtrl = -{ - SL_OPCODE_NVMEM_FILECLOSE, - sizeof(_FsCloseCommand_t), - sizeof(_FsCloseResponse_t) -}; - -_i16 sl_FsClose(const _i32 FileHdl, const _u8* pCeritificateFileName,const _u8* pSignature ,const _u32 SignatureLen) -{ - _SlFsCloseMsg_u Msg = {{0, 0}}; - _SlCmdExt_t ExtCtrl; - - Msg.Cmd.FileHandle = FileHdl; - if( pCeritificateFileName != NULL ) - { - Msg.Cmd.CertificFileNameLength = (_sl_Strlen(pCeritificateFileName)+4) & (~3); /* add 4: 1 for NULL and the 3 for align */ - } - Msg.Cmd.SignatureLen = SignatureLen; - - ExtCtrl.TxPayloadLen = ((SignatureLen+3) & (~3)); /* align */ - ExtCtrl.pTxPayload = (_u8*)pSignature; - ExtCtrl.RxPayloadLen = (_i16)Msg.Cmd.CertificFileNameLength; - ExtCtrl.pRxPayload = (_u8*)pCeritificateFileName; /* Add signature */ - - if(ExtCtrl.pRxPayload != NULL && ExtCtrl.RxPayloadLen != 0) - { - ExtCtrl.RxPayloadLen = ExtCtrl.RxPayloadLen * (-1); - } - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsCloseCmdCtrl, &Msg, &ExtCtrl)); - - return (_i16)((_i16)Msg.Rsp.status); -} -#endif - - -/*****************************************************************************/ -/* sl_FsRead */ -/*****************************************************************************/ -typedef union -{ - _FsReadCommand_t Cmd; - _FsReadResponse_t Rsp; -}_SlFsReadMsg_u; - -#if _SL_INCLUDE_FUNC(sl_FsRead) - - -const _SlCmdCtrl_t _SlFsReadCmdCtrl = -{ - SL_OPCODE_NVMEM_FILEREADCOMMAND, - sizeof(_FsReadCommand_t), - sizeof(_FsReadResponse_t) -}; - -_i32 sl_FsRead(const _i32 FileHdl,_u32 Offset, _u8* pData,_u32 Len) -{ - _SlFsReadMsg_u Msg; - _SlCmdExt_t ExtCtrl; - _u16 ChunkLen; - _SlReturnVal_t RetVal =0; - _i32 RetCount = 0; - - ExtCtrl.TxPayloadLen = 0; - ExtCtrl.pTxPayload = NULL; - - ChunkLen = (_u16)sl_min(MAX_NVMEM_CHUNK_SIZE,Len); - ExtCtrl.RxPayloadLen = ChunkLen; - ExtCtrl.pRxPayload = (_u8 *)(pData); - Msg.Cmd.Offset = Offset; - Msg.Cmd.Len = ChunkLen; - Msg.Cmd.FileHandle = FileHdl; - do - { - RetVal = _SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsReadCmdCtrl, &Msg, &ExtCtrl); - if(SL_OS_RET_CODE_OK == RetVal) - { - if( Msg.Rsp.status < 0) - { - if( RetCount > 0) - { - return RetCount; - } - else - { - return Msg.Rsp.status; - } - } - RetCount += (_i32)Msg.Rsp.status; - Len -= ChunkLen; - Offset += ChunkLen; - Msg.Cmd.Offset = Offset; - ExtCtrl.pRxPayload += ChunkLen; - ChunkLen = (_u16)sl_min(MAX_NVMEM_CHUNK_SIZE,Len); - ExtCtrl.RxPayloadLen = ChunkLen; - Msg.Cmd.Len = ChunkLen; - Msg.Cmd.FileHandle = FileHdl; - } - else - { - return RetVal; - } - }while(ChunkLen > 0); - - return (_i32)RetCount; -} -#endif - -/*****************************************************************************/ -/* sl_FsWrite */ -/*****************************************************************************/ -typedef union -{ - _FsWriteCommand_t Cmd; - _FsWriteResponse_t Rsp; -}_SlFsWriteMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_FsWrite) - -const _SlCmdCtrl_t _SlFsWriteCmdCtrl = -{ - SL_OPCODE_NVMEM_FILEWRITECOMMAND, - sizeof(_FsWriteCommand_t), - sizeof(_FsWriteResponse_t) -}; - -_i32 sl_FsWrite(const _i32 FileHdl,_u32 Offset, _u8* pData,_u32 Len) -{ - _SlFsWriteMsg_u Msg; - _SlCmdExt_t ExtCtrl; - _u16 ChunkLen; - _SlReturnVal_t RetVal; - _i32 RetCount = 0; - - ExtCtrl.RxPayloadLen = 0; - ExtCtrl.pRxPayload = NULL; - - ChunkLen = (_u16)sl_min(MAX_NVMEM_CHUNK_SIZE,Len); - ExtCtrl.TxPayloadLen = ChunkLen; - ExtCtrl.pTxPayload = (_u8 *)(pData); - Msg.Cmd.Offset = Offset; - Msg.Cmd.Len = ChunkLen; - Msg.Cmd.FileHandle = FileHdl; - - do - { - - RetVal = _SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsWriteCmdCtrl, &Msg, &ExtCtrl); - if(SL_OS_RET_CODE_OK == RetVal) - { - if( Msg.Rsp.status < 0) - { - if( RetCount > 0) - { - return RetCount; - } - else - { - return Msg.Rsp.status; - } - } - - RetCount += (_i32)Msg.Rsp.status; - Len -= ChunkLen; - Offset += ChunkLen; - Msg.Cmd.Offset = Offset; - ExtCtrl.pTxPayload += ChunkLen; - ChunkLen = (_u16)sl_min(MAX_NVMEM_CHUNK_SIZE,Len); - ExtCtrl.TxPayloadLen = ChunkLen; - Msg.Cmd.Len = ChunkLen; - Msg.Cmd.FileHandle = FileHdl; - } - else - { - return RetVal; - } - }while(ChunkLen > 0); - - return (_i32)RetCount; -} -#endif - -/*****************************************************************************/ -/* sl_FsGetInfo */ -/*****************************************************************************/ -typedef union -{ - _FsGetInfoCommand_t Cmd; - _FsGetInfoResponse_t Rsp; -}_SlFsGetInfoMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_FsGetInfo) - - -const _SlCmdCtrl_t _SlFsGetInfoCmdCtrl = -{ - SL_OPCODE_NVMEM_FILEGETINFOCOMMAND, - sizeof(_FsGetInfoCommand_t), - sizeof(_FsGetInfoResponse_t) -}; - -_i16 sl_FsGetInfo(const _u8 *pFileName,const _u32 Token,SlFsFileInfo_t* pFsFileInfo) -{ - _SlFsGetInfoMsg_u Msg; - _SlCmdExt_t CmdExt; - - CmdExt.TxPayloadLen = (_sl_Strlen(pFileName)+4) & (~3); /* add 4: 1 for NULL and the 3 for align */ - CmdExt.RxPayloadLen = 0; - CmdExt.pTxPayload = (_u8*)pFileName; - CmdExt.pRxPayload = NULL; - Msg.Cmd.Token = Token; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsGetInfoCmdCtrl, &Msg, &CmdExt)); - - pFsFileInfo->flags = Msg.Rsp.flags; - pFsFileInfo->FileLen = Msg.Rsp.FileLen; - pFsFileInfo->AllocatedLen = Msg.Rsp.AllocatedLen; - pFsFileInfo->Token[0] = Msg.Rsp.Token[0]; - pFsFileInfo->Token[1] = Msg.Rsp.Token[1]; - pFsFileInfo->Token[2] = Msg.Rsp.Token[2]; - pFsFileInfo->Token[3] = Msg.Rsp.Token[3]; - return (_i16)((_i16)Msg.Rsp.Status); -} -#endif - -/*****************************************************************************/ -/* sl_FsDel */ -/*****************************************************************************/ -typedef union -{ - _FsDeleteCommand_t Cmd; - _FsDeleteResponse_t Rsp; -}_SlFsDeleteMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_FsDel) - -const _SlCmdCtrl_t _SlFsDeleteCmdCtrl = -{ - SL_OPCODE_NVMEM_FILEDELCOMMAND, - sizeof(_FsDeleteCommand_t), - sizeof(_FsDeleteResponse_t) -}; - -_i16 sl_FsDel(const _u8 *pFileName,const _u32 Token) -{ - _SlFsDeleteMsg_u Msg; - _SlCmdExt_t CmdExt; - - CmdExt.TxPayloadLen = (_sl_Strlen(pFileName)+4) & (~3); /* add 4: 1 for NULL and the 3 for align */ - CmdExt.RxPayloadLen = 0; - CmdExt.pTxPayload = (_u8*)pFileName; - CmdExt.pRxPayload = NULL; - Msg.Cmd.Token = Token; - - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlFsDeleteCmdCtrl, &Msg, &CmdExt)); - - return (_i16)((_i16)Msg.Rsp.status); -} -#endif diff --git a/drivers/cc3100/src/netapp.c b/drivers/cc3100/src/netapp.c deleted file mode 100644 index 11bcdefadff..00000000000 --- a/drivers/cc3100/src/netapp.c +++ /dev/null @@ -1,1304 +0,0 @@ -/* - * netapp.c - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - - - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ -#include "simplelink.h" -#include "protocol.h" -#include "driver.h" - -/*****************************************************************************/ -/* Macro declarations */ -/*****************************************************************************/ -#define NETAPP_MDNS_OPTIONS_ADD_SERVICE_BIT ((_u32)0x1 << 31) - -#ifdef SL_TINY -#define NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH 63 -#else -#define NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH 255 -#endif - - -/*****************************************************************************/ -/* Functions prototypes */ -/*****************************************************************************/ -void _sl_HandleAsync_DnsGetHostByName(void *pVoidBuf); - -#ifndef SL_TINY_EXT -void _sl_HandleAsync_DnsGetHostByService(void *pVoidBuf); -void _sl_HandleAsync_PingResponse(void *pVoidBuf); -#endif - -void CopyPingResultsToReport(_PingReportResponse_t *pResults,SlPingReport_t *pReport); -_i16 sl_NetAppMDNSRegisterUnregisterService(const _i8* pServiceName, - const _u8 ServiceNameLen, - const _i8* pText, - const _u8 TextLen, - const _u16 Port, - const _u32 TTL, - const _u32 Options); - -#if defined(sl_HttpServerCallback) || defined(EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS) -_u16 _sl_NetAppSendTokenValue(slHttpServerData_t * Token); -#endif -typedef union -{ - _NetAppStartStopCommand_t Cmd; - _NetAppStartStopResponse_t Rsp; -}_SlNetAppStartStopMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_NetAppStart) - -const _SlCmdCtrl_t _SlNetAppStartCtrl = -{ - SL_OPCODE_NETAPP_START_COMMAND, - sizeof(_NetAppStartStopCommand_t), - sizeof(_NetAppStartStopResponse_t) -}; - -_i16 sl_NetAppStart(const _u32 AppBitMap) -{ - _SlNetAppStartStopMsg_u Msg; - Msg.Cmd.appId = AppBitMap; - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlNetAppStartCtrl, &Msg, NULL)); - - return Msg.Rsp.status; -} -#endif - -/***************************************************************************** - sl_NetAppStop -*****************************************************************************/ -#if _SL_INCLUDE_FUNC(sl_NetAppStop) - - -const _SlCmdCtrl_t _SlNetAppStopCtrl = -{ - SL_OPCODE_NETAPP_STOP_COMMAND, - sizeof(_NetAppStartStopCommand_t), - sizeof(_NetAppStartStopResponse_t) -}; - - - -_i16 sl_NetAppStop(const _u32 AppBitMap) -{ - _SlNetAppStartStopMsg_u Msg; - Msg.Cmd.appId = AppBitMap; - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlNetAppStopCtrl, &Msg, NULL)); - - return Msg.Rsp.status; -} -#endif - - -/******************************************************************************/ -/* sl_NetAppGetServiceList */ -/******************************************************************************/ -typedef struct -{ - _u8 IndexOffest; - _u8 MaxServiceCount; - _u8 Flags; - _i8 Padding; -}NetappGetServiceListCMD_t; - -typedef union -{ - NetappGetServiceListCMD_t Cmd; - _BasicResponse_t Rsp; -}_SlNetappGetServiceListMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_NetAppGetServiceList) - -const _SlCmdCtrl_t _SlGetServiceListeCtrl = -{ - SL_OPCODE_NETAPP_NETAPP_MDNS_LOOKUP_SERVICE, - sizeof(NetappGetServiceListCMD_t), - sizeof(_BasicResponse_t) -}; - -_i16 sl_NetAppGetServiceList(const _u8 IndexOffest, - const _u8 MaxServiceCount, - const _u8 Flags, - _i8 *pBuffer, - const _u32 RxBufferLength - ) -{ - - _i32 retVal= 0; - _SlNetappGetServiceListMsg_u Msg; - _SlCmdExt_t CmdExt; - _u16 ServiceSize = 0; - _u16 BufferSize = 0; - - /* - Calculate RX pBuffer size - WARNING: - if this size is BufferSize than 1480 error should be returned because there - is no place in the RX packet. - */ - switch(Flags) - { - case SL_NET_APP_FULL_SERVICE_WITH_TEXT_IPV4_TYPE: - ServiceSize = sizeof(SlNetAppGetFullServiceWithTextIpv4List_t); - break; - - case SL_NET_APP_FULL_SERVICE_IPV4_TYPE: - ServiceSize = sizeof(SlNetAppGetFullServiceIpv4List_t); - break; - - case SL_NET_APP_SHORT_SERVICE_IPV4_TYPE: - ServiceSize = sizeof(SlNetAppGetShortServiceIpv4List_t); - break; - - default: - ServiceSize = sizeof(_BasicResponse_t); - break; - } - - - - BufferSize = MaxServiceCount * ServiceSize; - - /*Check the size of the requested services is smaller than size of the user buffer. - If not an error is returned in order to avoid overwriting memory. */ - if(RxBufferLength <= BufferSize) - { - return SL_ERROR_NETAPP_RX_BUFFER_LENGTH_ERROR; - } - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.RxPayloadLen = BufferSize; - CmdExt.pRxPayload = (_u8 *)pBuffer; - - Msg.Cmd.IndexOffest = IndexOffest; - Msg.Cmd.MaxServiceCount = MaxServiceCount; - Msg.Cmd.Flags = Flags; - Msg.Cmd.Padding = 0; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetServiceListeCtrl, &Msg, &CmdExt)); - retVal = Msg.Rsp.status; - - return (_i16)retVal; -} - -#endif - -/*****************************************************************************/ -/* sl_mDNSRegisterService */ -/*****************************************************************************/ -/* - * The below struct depicts the constant parameters of the command/API RegisterService. - * - 1. ServiceLen - The length of the service should be smaller than NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH. - 2. TextLen - The length of the text should be smaller than NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH. - 3. port - The port on this target host. - 4. TTL - The TTL of the service - 5. Options - bitwise parameters: - bit 0 - is unique (means if the service needs to be unique) - bit 31 - for internal use if the service should be added or deleted (set means ADD). - bit 1-30 for future. - - NOTE: - - 1. There are another variable parameter is this API which is the service name and the text. - 2. According to now there is no warning and Async event to user on if the service is a unique. -* - */ - - -typedef struct -{ - _u8 ServiceNameLen; - _u8 TextLen; - _u16 Port; - _u32 TTL; - _u32 Options; -}NetappMdnsSetService_t; - -typedef union -{ - NetappMdnsSetService_t Cmd; - _BasicResponse_t Rsp; -}_SlNetappMdnsRegisterServiceMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_NetAppMDNSRegisterUnregisterService) - -const _SlCmdCtrl_t _SlRegisterServiceCtrl = -{ - SL_OPCODE_NETAPP_MDNSREGISTERSERVICE, - sizeof(NetappMdnsSetService_t), - sizeof(_BasicResponse_t) -}; - -/****************************************************************************** - - sl_NetAppMDNSRegisterService - - CALLER user from its host - - - DESCRIPTION: - Add/delete service - The function manipulates the command that register the service and call - to the NWP in order to add/delete the service to/from the mDNS package and to/from the DB. - - This register service is a service offered by the application. - This unregister service is a service offered by the application before. - - The service name should be full service name according to RFC - of the DNS-SD - means the value in name field in SRV answer. - - Example for service name: - 1. PC1._ipp._tcp.local - 2. PC2_server._ftp._tcp.local - - If the option is_unique is set, mDNS probes the service name to make sure - it is unique before starting to announce the service on the network. - Instance is the instance portion of the service name. - - - - - PARAMETERS: - - The command is from constant parameters and variables parameters. - - Constant parameters are: - - ServiceLen - The length of the service. - TextLen - The length of the service should be smaller than 64. - port - The port on this target host. - TTL - The TTL of the service - Options - bitwise parameters: - bit 0 - is unique (means if the service needs to be unique) - bit 31 - for internal use if the service should be added or deleted (set means ADD). - bit 1-30 for future. - - The variables parameters are: - - Service name(full service name) - The service name. - Example for service name: - 1. PC1._ipp._tcp.local - 2. PC2_server._ftp._tcp.local - - Text - The description of the service. - should be as mentioned in the RFC - (according to type of the service IPP,FTP...) - - NOTE - pay attention - - 1. Temporary - there is an allocation on stack of internal buffer. - Its size is NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH. - It means that the sum of the text length and service name length cannot be bigger than - NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH. - If it is - An error is returned. - - 2. According to now from certain constraints the variables parameters are set in the - attribute part (contain constant parameters) - - - - RETURNS: Status - the immediate response of the command status. - 0 means success. - - - -******************************************************************************/ -_i16 sl_NetAppMDNSRegisterUnregisterService( const _i8* pServiceName, - const _u8 ServiceNameLen, - const _i8* pText, - const _u8 TextLen, - const _u16 Port, - const _u32 TTL, - const _u32 Options) - -{ - _SlNetappMdnsRegisterServiceMsg_u Msg; - _SlCmdExt_t CmdExt ; - _i8 ServiceNameAndTextBuffer[NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH]; - _i8 *TextPtr; - - /* - - NOTE - pay attention - - 1. Temporary - there is an allocation on stack of internal buffer. - Its size is NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH. - It means that the sum of the text length and service name length cannot be bigger than - NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH. - If it is - An error is returned. - - 2. According to now from certain constraints the variables parameters are set in the - attribute part (contain constant parameters) - - - */ - - /*build the attribute part of the command. - It contains the constant parameters of the command*/ - - Msg.Cmd.ServiceNameLen = ServiceNameLen; - Msg.Cmd.Options = Options; - Msg.Cmd.Port = Port; - Msg.Cmd.TextLen = TextLen; - Msg.Cmd.TTL = TTL; - - /*Build the payload part of the command - Copy the service name and text to one buffer. - NOTE - pay attention - The size of the service length + the text length should be smaller than 255, - Until the simplelink drive supports to variable length through SPI command. */ - if(TextLen + ServiceNameLen > (NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH - 1 )) /*-1 is for giving a place to set null termination at the end of the text*/ - { - return -1; - } - - _SlDrvMemZero(ServiceNameAndTextBuffer, NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH); - - - /*Copy the service name*/ - sl_Memcpy(ServiceNameAndTextBuffer, - pServiceName, - ServiceNameLen); - - if(TextLen > 0 ) - { - - TextPtr = &ServiceNameAndTextBuffer[ServiceNameLen]; - /*Copy the text just after the service name*/ - sl_Memcpy(TextPtr, - pText, - TextLen); - - - } - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.TxPayloadLen = (TextLen + ServiceNameLen); - CmdExt.pTxPayload = (_u8 *)ServiceNameAndTextBuffer; - - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlRegisterServiceCtrl, &Msg, &CmdExt)); - - return (_i16)Msg.Rsp.status; - - -} -#endif - -/**********************************************************************************************/ -#if _SL_INCLUDE_FUNC(sl_NetAppMDNSRegisterService) - -_i16 sl_NetAppMDNSRegisterService( const _i8* pServiceName, - const _u8 ServiceNameLen, - const _i8* pText, - const _u8 TextLen, - const _u16 Port, - const _u32 TTL, - _u32 Options) - -{ - - /* - - NOTE - pay attention - - 1. Temporary - there is an allocation on stack of internal buffer. - Its size is NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH. - It means that the sum of the text length and service name length cannot be bigger than - NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH. - If it is - An error is returned. - - 2. According to now from certain constraints the variables parameters are set in the - attribute part (contain constant parameters) - - */ - - /*Set the add service bit in the options parameter. - In order not use different opcodes for the register service and unregister service - bit 31 in option is taken for this purpose. if it is set it means in NWP that the service should be added - if it is cleared it means that the service should be deleted and there is only meaning to pServiceName - and ServiceNameLen values. */ - Options |= NETAPP_MDNS_OPTIONS_ADD_SERVICE_BIT; - - return sl_NetAppMDNSRegisterUnregisterService( pServiceName, - ServiceNameLen, - pText, - TextLen, - Port, - TTL, - Options); - - -} -#endif -/**********************************************************************************************/ - - - -/**********************************************************************************************/ -#if _SL_INCLUDE_FUNC(sl_NetAppMDNSUnRegisterService) - -_i16 sl_NetAppMDNSUnRegisterService( const _i8* pServiceName, - const _u8 ServiceNameLen) - - -{ - _u32 Options = 0; - - /* - - NOTE - pay attention - - The size of the service length should be smaller than 255, - Until the simplelink drive supports to variable length through SPI command. - - - */ - - /*Clear the add service bit in the options parameter. - In order not use different opcodes for the register service and unregister service - bit 31 in option is taken for this purpose. if it is set it means in NWP that the service should be added - if it is cleared it means that the service should be deleted and there is only meaning to pServiceName - and ServiceNameLen values.*/ - - Options &= (~NETAPP_MDNS_OPTIONS_ADD_SERVICE_BIT); - - return sl_NetAppMDNSRegisterUnregisterService( pServiceName, - ServiceNameLen, - NULL, - 0, - 0, - 0, - Options); - - -} -#endif -/**********************************************************************************************/ - - - -/*****************************************************************************/ -/* sl_DnsGetHostByService */ -/*****************************************************************************/ -/* - * The below struct depicts the constant parameters of the command/API sl_DnsGetHostByService. - * - 1. ServiceLen - The length of the service should be smaller than 255. - 2. AddrLen - TIPv4 or IPv6 (SL_AF_INET , SL_AF_INET6). -* - */ - -typedef struct -{ - _u8 ServiceLen; - _u8 AddrLen; - _u16 Padding; -}_GetHostByServiceCommand_t; - - - -/* - * The below structure depict the constant parameters that are returned in the Async event answer - * according to command/API sl_DnsGetHostByService for IPv4 and IPv6. - * - 1Status - The status of the response. - 2.Address - Contains the IP address of the service. - 3.Port - Contains the port of the service. - 4.TextLen - Contains the max length of the text that the user wants to get. - it means that if the test of service is bigger that its value than - the text is cut to inout_TextLen value. - Output: Contain the length of the text that is returned. Can be full text or part - of the text (see above). - -* - */ -typedef struct -{ - _u16 Status; - _u16 TextLen; - _u32 Port; - _u32 Address; -}_GetHostByServiceIPv4AsyncResponse_t; - - -typedef struct -{ - _u16 Status; - _u16 TextLen; - _u32 Port; - _u32 Address[4]; -}_GetHostByServiceIPv6AsyncResponse_t; - - -typedef union -{ - _GetHostByServiceIPv4AsyncResponse_t IpV4; - _GetHostByServiceIPv6AsyncResponse_t IpV6; -}_GetHostByServiceAsyncResponseAttribute_u; - -/* - * The below struct contains pointers to the output parameters that the user gives - * - */ -typedef struct -{ - _i16 Status; - _u32 *out_pAddr; - _u32 *out_pPort; - _u16 *inout_TextLen; /* in: max len , out: actual len */ - _i8 *out_pText; -}_GetHostByServiceAsyncResponse_t; - - -typedef union -{ - _GetHostByServiceCommand_t Cmd; - _BasicResponse_t Rsp; -}_SlGetHostByServiceMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_NetAppDnsGetHostByService) - -const _SlCmdCtrl_t _SlGetHostByServiceCtrl = -{ - SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICE, - sizeof(_GetHostByServiceCommand_t), - sizeof(_BasicResponse_t) -}; - -/******************************************************************************/ - -_i32 sl_NetAppDnsGetHostByService(_i8 *pServiceName, /* string containing all (or only part): name + subtype + service */ - const _u8 ServiceLen, - const _u8 Family, /* 4-IPv4 , 16-IPv6 */ - _u32 pAddr[], - _u32 *pPort, - _u16 *pTextLen, /* in: max len , out: actual len */ - _i8 *pText - ) -{ - _SlGetHostByServiceMsg_u Msg; - _SlCmdExt_t CmdExt ; - _GetHostByServiceAsyncResponse_t AsyncRsp; - _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; - -/* - Note: - 1. The return's attributes are belonged to first service that is found. - It can be other services with the same service name will response to - the query. The results of these responses are saved in the peer cache of the NWP, and - should be read by another API. - - 2. Text length can be 120 bytes only - not more - It is because of constraints in the NWP on the buffer that is allocated for the Async event. - - 3.The API waits to Async event by blocking. It means that the API is finished only after an Async event - is sent by the NWP. - - 4.No rolling option!!! - only PTR type is sent. - - -*/ - /*build the attribute part of the command. - It contains the constant parameters of the command */ - - Msg.Cmd.ServiceLen = ServiceLen; - Msg.Cmd.AddrLen = Family; - - /*Build the payload part of the command - Copy the service name and text to one buffer.*/ - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.TxPayloadLen = ServiceLen; - CmdExt.pTxPayload = (_u8 *)pServiceName; - - /*set pointers to the output parameters (the returned parameters). - This pointers are belonged to local struct that is set to global Async response parameter. - It is done in order not to run more than one sl_DnsGetHostByService at the same time. - The API should be run only if global parameter is pointed to NULL. */ - AsyncRsp.out_pText = pText; - AsyncRsp.inout_TextLen = (_u16* )pTextLen; - AsyncRsp.out_pPort = pPort; - AsyncRsp.out_pAddr = (_u32 *)pAddr; - - - ObjIdx = _SlDrvProtectAsyncRespSetting((_u8*)&AsyncRsp, GETHOSYBYSERVICE_ID, SL_MAX_SOCKETS); - - if (MAX_CONCURRENT_ACTIONS == ObjIdx) - { - return SL_POOL_IS_EMPTY; - } - - - if (SL_AF_INET6 == Family) - { - g_pCB->ObjPool[ObjIdx].AdditionalData |= SL_NETAPP_FAMILY_MASK; - } - /* Send the command */ - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetHostByServiceCtrl, &Msg, &CmdExt)); - - - - /* If the immediate reponse is O.K. than wait for aSYNC event response. */ - if(SL_RET_CODE_OK == Msg.Rsp.status) - { - _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj); - - /* If we are - it means that Async event was sent. - The results are copied in the Async handle return functions */ - - Msg.Rsp.status = AsyncRsp.Status; - } - - _SlDrvReleasePoolObj(ObjIdx); - return Msg.Rsp.status; -} -#endif - -/******************************************************************************/ - -/****************************************************************************** - _sl_HandleAsync_DnsGetHostByService - - CALLER NWP - Async event on sl_DnsGetHostByService with IPv4 Family - - - DESCRIPTION: - - Async event on sl_DnsGetHostByService command with IPv4 Family. - Return service attributes like IP address, port and text according to service name. - The user sets a service name Full/Part (see example below), and should get the: - 1. IP of the service - 2. The port of service. - 3. The text of service. - - Hence it can make a connection to the specific service and use it. - It is similar to get host by name method. - - It is done by a single shot query with PTR type on the service name. - - - - Note: - 1. The return's attributes are belonged to first service that is found. - It can be other services with the same service name will response to - the query. The results of these responses are saved in the peer cache of the NWP, and - should be read by another API. - - - PARAMETERS: - - pVoidBuf - is point to opcode of the event. - it contains the outputs that are given to the user - - outputs description: - - 1.out_pAddr[] - output: Contain the IP address of the service. - 2.out_pPort - output: Contain the port of the service. - 3.inout_TextLen - Input: Contain the max length of the text that the user wants to get. - it means that if the test of service is bigger that its value than - the text is cut to inout_TextLen value. - Output: Contain the length of the text that is returned. Can be full text or part - of the text (see above). - - 4.out_pText - Contain the text of the service (full or part see above- inout_TextLen description). - - * - - - RETURNS: success or fail. - - - - - -******************************************************************************/ -#ifndef SL_TINY_EXT -void _sl_HandleAsync_DnsGetHostByService(void *pVoidBuf) -{ - - _GetHostByServiceAsyncResponse_t* Res; - _u16 TextLen; - _u16 UserTextLen; - - - /*pVoidBuf - is point to opcode of the event.*/ - - /*set pMsgArgs to point to the attribute of the event.*/ - _GetHostByServiceIPv4AsyncResponse_t *pMsgArgs = (_GetHostByServiceIPv4AsyncResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); - - VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); - - /*IPv6*/ - if(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].AdditionalData & SL_NETAPP_FAMILY_MASK) - { - return; - } - /*IPv4*/ - else - { - /************************************************************************************************* - - 1. Copy the attribute part of the evnt to the attribute part of the response - sl_Memcpy(g_pCB->GetHostByServiceCB.pAsyncRsp, pMsgArgs, sizeof(_GetHostByServiceIPv4AsyncResponse_t)); - - set to TextLen the text length of the service.*/ - TextLen = pMsgArgs->TextLen; - - /*Res pointed to mDNS global object struct */ - Res = (_GetHostByServiceAsyncResponse_t*)g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs; - - - - /*It is 4 bytes so we avoid from memcpy*/ - Res->out_pAddr[0] = pMsgArgs->Address; - Res->out_pPort[0] = pMsgArgs->Port; - Res->Status = pMsgArgs->Status; - - /*set to TextLen the text length of the user (input fromthe user).*/ - UserTextLen = Res->inout_TextLen[0]; - - /*Cut the service text if the user requested for smaller text.*/ - UserTextLen = (TextLen <= UserTextLen) ? TextLen : UserTextLen; - Res->inout_TextLen[0] = UserTextLen ; - - /************************************************************************************************** - - 2. Copy the payload part of the evnt (the text) to the payload part of the response - the lenght of the copy is according to the text length in the attribute part. */ - - - sl_Memcpy(Res->out_pText , - (_i8 *)(& pMsgArgs[1]) , /* & pMsgArgs[1] -> 1st byte after the fixed header = 1st byte of variable text.*/ - UserTextLen ); - - - /**************************************************************************************************/ - - _SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); - return; - } -} - -/*****************************************************************************/ -/* _sl_HandleAsync_DnsGetHostByAddr */ -/*****************************************************************************/ -void _sl_HandleAsync_DnsGetHostByAddr(void *pVoidBuf) -{ - SL_TRACE0(DBG_MSG, MSG_303, "STUB: _sl_HandleAsync_DnsGetHostByAddr not implemented yet!"); - return; -} -#endif - -/*****************************************************************************/ -/* sl_DnsGetHostByName */ -/*****************************************************************************/ -typedef union -{ - _GetHostByNameIPv4AsyncResponse_t IpV4; - _GetHostByNameIPv6AsyncResponse_t IpV6; -}_GetHostByNameAsyncResponse_u; - -typedef union -{ - _GetHostByNameCommand_t Cmd; - _BasicResponse_t Rsp; -}_SlGetHostByNameMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_NetAppDnsGetHostByName) -const _SlCmdCtrl_t _SlGetHostByNameCtrl = -{ - SL_OPCODE_NETAPP_DNSGETHOSTBYNAME, - sizeof(_GetHostByNameCommand_t), - sizeof(_BasicResponse_t) -}; - -_i16 sl_NetAppDnsGetHostByName(_i8 * hostname,const _u16 usNameLen, _u32* out_ip_addr,const _u8 family) -{ - _SlGetHostByNameMsg_u Msg; - _SlCmdExt_t ExtCtrl; - _GetHostByNameAsyncResponse_u AsyncRsp; - _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; - - - _SlDrvResetCmdExt(&ExtCtrl); - ExtCtrl.TxPayloadLen = usNameLen; - ExtCtrl.pTxPayload = (_u8 *)hostname; - - Msg.Cmd.Len = usNameLen; - Msg.Cmd.family = family; - - /*Use Obj to issue the command, if not available try later */ - ObjIdx = (_u8)_SlDrvWaitForPoolObj(GETHOSYBYNAME_ID,SL_MAX_SOCKETS); - if (MAX_CONCURRENT_ACTIONS == ObjIdx) - { - return SL_POOL_IS_EMPTY; - } - - _SlDrvProtectionObjLockWaitForever(); - - g_pCB->ObjPool[ObjIdx].pRespArgs = (_u8 *)&AsyncRsp; - /*set bit to indicate IPv6 address is expected */ - if (SL_AF_INET6 == family) - { - g_pCB->ObjPool[ObjIdx].AdditionalData |= SL_NETAPP_FAMILY_MASK; - } - - _SlDrvProtectionObjUnLock(); - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetHostByNameCtrl, &Msg, &ExtCtrl)); - - if(SL_RET_CODE_OK == Msg.Rsp.status) - { - _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj); - - Msg.Rsp.status = AsyncRsp.IpV4.status; - - if(SL_OS_RET_CODE_OK == (_i16)Msg.Rsp.status) - { - sl_Memcpy((_i8 *)out_ip_addr, - (_i8 *)&AsyncRsp.IpV4.ip0, - (SL_AF_INET == family) ? SL_IPV4_ADDRESS_SIZE : SL_IPV6_ADDRESS_SIZE); - } - } - _SlDrvReleasePoolObj(ObjIdx); - return Msg.Rsp.status; -} -#endif - - -/******************************************************************************/ -/* _sl_HandleAsync_DnsGetHostByName */ -/******************************************************************************/ -void _sl_HandleAsync_DnsGetHostByName(void *pVoidBuf) -{ - _GetHostByNameIPv4AsyncResponse_t *pMsgArgs = (_GetHostByNameIPv4AsyncResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); - - _SlDrvProtectionObjLockWaitForever(); - - VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); - - /*IPv6 */ - if(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].AdditionalData & SL_NETAPP_FAMILY_MASK) - { - sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_GetHostByNameIPv6AsyncResponse_t)); - } - /*IPv4 */ - else - { - sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_GetHostByNameIPv4AsyncResponse_t)); - } - _SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); - _SlDrvProtectionObjUnLock(); - return; -} - - -#ifndef SL_TINY_EXT -void CopyPingResultsToReport(_PingReportResponse_t *pResults,SlPingReport_t *pReport) -{ - pReport->PacketsSent = pResults->numSendsPings; - pReport->PacketsReceived = pResults->numSuccsessPings; - pReport->MinRoundTime = pResults->rttMin; - pReport->MaxRoundTime = pResults->rttMax; - pReport->AvgRoundTime = pResults->rttAvg; - pReport->TestTime = pResults->testTime; -} - -/*****************************************************************************/ -/* _sl_HandleAsync_PingResponse */ -/*****************************************************************************/ -void _sl_HandleAsync_PingResponse(void *pVoidBuf) -{ - _PingReportResponse_t *pMsgArgs = (_PingReportResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); - SlPingReport_t pingReport; - - if(pPingCallBackFunc) - { - CopyPingResultsToReport(pMsgArgs,&pingReport); - pPingCallBackFunc(&pingReport); - } - else - { - - _SlDrvProtectionObjLockWaitForever(); - - VERIFY_SOCKET_CB(NULL != g_pCB->PingCB.PingAsync.pAsyncRsp); - - if (NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs) - { - sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_PingReportResponse_t)); - _SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); - } - _SlDrvProtectionObjUnLock(); - } - return; -} -#endif - -/*****************************************************************************/ -/* sl_PingStart */ -/*****************************************************************************/ -typedef union -{ - _PingStartCommand_t Cmd; - _PingReportResponse_t Rsp; -}_SlPingStartMsg_u; - - -typedef enum -{ - CMD_PING_TEST_RUNNING = 0, - CMD_PING_TEST_STOPPED -}_SlPingStatus_e; - - -#if _SL_INCLUDE_FUNC(sl_NetAppPingStart) -_i16 sl_NetAppPingStart(const SlPingStartCommand_t* pPingParams,const _u8 family,SlPingReport_t *pReport,const P_SL_DEV_PING_CALLBACK pPingCallback) -{ - _SlCmdCtrl_t CmdCtrl = {0, sizeof(_PingStartCommand_t), sizeof(_BasicResponse_t)}; - _SlPingStartMsg_u Msg; - _PingReportResponse_t PingRsp; - _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; - - if( 0 == pPingParams->Ip ) - {/* stop any ongoing ping */ - return _SlDrvBasicCmd(SL_OPCODE_NETAPP_PINGSTOP); - } - - if(SL_AF_INET == family) - { - CmdCtrl.Opcode = SL_OPCODE_NETAPP_PINGSTART; - sl_Memcpy(&Msg.Cmd.ip0, &pPingParams->Ip, SL_IPV4_ADDRESS_SIZE); - } - else - { - CmdCtrl.Opcode = SL_OPCODE_NETAPP_PINGSTART_V6; - sl_Memcpy(&Msg.Cmd.ip0, &pPingParams->Ip, SL_IPV6_ADDRESS_SIZE); - } - - Msg.Cmd.pingIntervalTime = pPingParams->PingIntervalTime; - Msg.Cmd.PingSize = pPingParams->PingSize; - Msg.Cmd.pingRequestTimeout = pPingParams->PingRequestTimeout; - Msg.Cmd.totalNumberOfAttempts = pPingParams->TotalNumberOfAttempts; - Msg.Cmd.flags = pPingParams->Flags; - - - if( pPingCallback ) - { - pPingCallBackFunc = pPingCallback; - } - else - { - /*Use Obj to issue the command, if not available try later */ - ObjIdx = (_u8)_SlDrvWaitForPoolObj(PING_ID,SL_MAX_SOCKETS); - if (MAX_CONCURRENT_ACTIONS == ObjIdx) - { - return SL_POOL_IS_EMPTY; - } - OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); - /* async response handler for non callback mode */ - g_pCB->ObjPool[ObjIdx].pRespArgs = (_u8 *)&PingRsp; - pPingCallBackFunc = NULL; - OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); - } - - - VERIFY_RET_OK(_SlDrvCmdOp(&CmdCtrl, &Msg, NULL)); - /*send the command*/ - if(CMD_PING_TEST_RUNNING == (_i16)Msg.Rsp.status || CMD_PING_TEST_STOPPED == (_i16)Msg.Rsp.status ) - { - /* block waiting for results if no callback function is used */ - if( NULL == pPingCallback ) - { - _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj); - - if( SL_OS_RET_CODE_OK == (_i16)PingRsp.status ) - { - CopyPingResultsToReport(&PingRsp,pReport); - } - _SlDrvReleasePoolObj(ObjIdx); - } - } - else - { /* ping failure, no async response */ - if( NULL == pPingCallback ) - { - _SlDrvReleasePoolObj(ObjIdx); - } - } - - return Msg.Rsp.status; -} -#endif - -/*****************************************************************************/ -/* sl_NetAppSet */ -/*****************************************************************************/ -typedef union -{ - _NetAppSetGet_t Cmd; - _BasicResponse_t Rsp; -}_SlNetAppMsgSet_u; - - -#if _SL_INCLUDE_FUNC(sl_NetAppSet) - -const _SlCmdCtrl_t _SlNetAppSetCmdCtrl = -{ - SL_OPCODE_NETAPP_NETAPPSET, - sizeof(_NetAppSetGet_t), - sizeof(_BasicResponse_t) -}; - -_i32 sl_NetAppSet(const _u8 AppId ,const _u8 Option,const _u8 OptionLen,const _u8 *pOptionValue) -{ - _SlNetAppMsgSet_u Msg; - _SlCmdExt_t CmdExt; - - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.TxPayloadLen = (OptionLen+3) & (~3); - CmdExt.pTxPayload = (_u8 *)pOptionValue; - - - Msg.Cmd.AppId = AppId; - Msg.Cmd.ConfigLen = OptionLen; - Msg.Cmd.ConfigOpt = Option; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlNetAppSetCmdCtrl, &Msg, &CmdExt)); - - return (_i16)Msg.Rsp.status; -} -#endif - -/*****************************************************************************/ -/* sl_NetAppSendTokenValue */ -/*****************************************************************************/ -typedef union -{ - sl_NetAppHttpServerSendToken_t Cmd; - _BasicResponse_t Rsp; -}_SlNetAppMsgSendTokenValue_u; - - - -#if defined(sl_HttpServerCallback) || defined(EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS) -const _SlCmdCtrl_t _SlNetAppSendTokenValueCmdCtrl = -{ - SL_OPCODE_NETAPP_HTTPSENDTOKENVALUE, - sizeof(sl_NetAppHttpServerSendToken_t), - sizeof(_BasicResponse_t) -}; - -_u16 _sl_NetAppSendTokenValue(slHttpServerData_t * Token_value) -{ - _SlNetAppMsgSendTokenValue_u Msg; - _SlCmdExt_t CmdExt; - - CmdExt.TxPayloadLen = (Token_value->value_len+3) & (~3); - CmdExt.RxPayloadLen = 0; - CmdExt.pTxPayload = (_u8 *) Token_value->token_value; - CmdExt.pRxPayload = NULL; - - Msg.Cmd.token_value_len = Token_value->value_len; - Msg.Cmd.token_name_len = Token_value->name_len; - sl_Memcpy(&Msg.Cmd.token_name[0], Token_value->token_name, Token_value->name_len); - - - VERIFY_RET_OK(_SlDrvCmdSend((_SlCmdCtrl_t *)&_SlNetAppSendTokenValueCmdCtrl, &Msg, &CmdExt)); - - return Msg.Rsp.status; -} -#endif - - -/*****************************************************************************/ -/* sl_NetAppGet */ -/*****************************************************************************/ -typedef union -{ - _NetAppSetGet_t Cmd; - _NetAppSetGet_t Rsp; -}_SlNetAppMsgGet_u; - - -#if _SL_INCLUDE_FUNC(sl_NetAppGet) -const _SlCmdCtrl_t _SlNetAppGetCmdCtrl = -{ - SL_OPCODE_NETAPP_NETAPPGET, - sizeof(_NetAppSetGet_t), - sizeof(_NetAppSetGet_t) -}; - -_i32 sl_NetAppGet(const _u8 AppId,const _u8 Option,_u8 *pOptionLen, _u8 *pOptionValue) -{ - _SlNetAppMsgGet_u Msg; - _SlCmdExt_t CmdExt; - - if (*pOptionLen == 0) - { - return SL_EZEROLEN; - } - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.RxPayloadLen = *pOptionLen; - CmdExt.pRxPayload = (_u8 *)pOptionValue; - - Msg.Cmd.AppId = AppId; - Msg.Cmd.ConfigOpt = Option; - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlNetAppGetCmdCtrl, &Msg, &CmdExt)); - - - if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) - { - *pOptionLen = (_u8)CmdExt.RxPayloadLen; - return SL_ESMALLBUF; - } - else - { - *pOptionLen = (_u8)CmdExt.ActualRxPayloadLen; - } - - return (_i16)Msg.Rsp.Status; -} -#endif - - -/*****************************************************************************/ -/* _SlDrvNetAppEventHandler */ -/*****************************************************************************/ -void _SlDrvNetAppEventHandler(void* pArgs) -{ - _SlResponseHeader_t *pHdr = (_SlResponseHeader_t *)pArgs; -#if defined(sl_HttpServerCallback) || defined(EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS) - SlHttpServerEvent_t httpServerEvent; - SlHttpServerResponse_t httpServerResponse; -#endif - - switch(pHdr->GenHeader.Opcode) - { - case SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE: - case SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE_V6: - _sl_HandleAsync_DnsGetHostByName(pArgs); - break; -#ifndef SL_TINY_EXT - case SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE: - case SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE_V6: - _sl_HandleAsync_DnsGetHostByService(pArgs); - break; - case SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE: - _sl_HandleAsync_PingResponse(pArgs); - break; -#endif - -#if defined(sl_HttpServerCallback) || defined(EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS) - case SL_OPCODE_NETAPP_HTTPGETTOKENVALUE: - { - _u8 *pTokenName; - slHttpServerData_t Token_value; - sl_NetAppHttpServerGetToken_t *httpGetToken = (sl_NetAppHttpServerGetToken_t *)_SL_RESP_ARGS_START(pHdr); - pTokenName = (_u8 *)((sl_NetAppHttpServerGetToken_t *)httpGetToken + 1); - - httpServerResponse.Response = SL_NETAPP_HTTPSETTOKENVALUE; - httpServerResponse.ResponseData.token_value.len = MAX_TOKEN_VALUE_LEN; - - /* Reuse the async buffer for getting the token value response from the user */ - httpServerResponse.ResponseData.token_value.data = (_u8 *)_SL_RESP_ARGS_START(pHdr) + MAX_TOKEN_NAME_LEN; - - httpServerEvent.Event = SL_NETAPP_HTTPGETTOKENVALUE_EVENT; - httpServerEvent.EventData.httpTokenName.len = httpGetToken->token_name_len; - httpServerEvent.EventData.httpTokenName.data = pTokenName; - - Token_value.token_name = pTokenName; - - _SlDrvHandleHttpServerEvents (&httpServerEvent, &httpServerResponse); - - Token_value.value_len = httpServerResponse.ResponseData.token_value.len; - Token_value.name_len = httpServerEvent.EventData.httpTokenName.len; - Token_value.token_value = httpServerResponse.ResponseData.token_value.data; - - - _sl_NetAppSendTokenValue(&Token_value); - } - break; - - case SL_OPCODE_NETAPP_HTTPPOSTTOKENVALUE: - { - _u8 *pPostParams; - - sl_NetAppHttpServerPostToken_t *httpPostTokenArgs = (sl_NetAppHttpServerPostToken_t *)_SL_RESP_ARGS_START(pHdr); - pPostParams = (_u8 *)((sl_NetAppHttpServerPostToken_t *)httpPostTokenArgs + 1); - - httpServerEvent.Event = SL_NETAPP_HTTPPOSTTOKENVALUE_EVENT; - - httpServerEvent.EventData.httpPostData.action.len = httpPostTokenArgs->post_action_len; - httpServerEvent.EventData.httpPostData.action.data = pPostParams; - pPostParams+=httpPostTokenArgs->post_action_len; - - httpServerEvent.EventData.httpPostData.token_name.len = httpPostTokenArgs->token_name_len; - httpServerEvent.EventData.httpPostData.token_name.data = pPostParams; - pPostParams+=httpPostTokenArgs->token_name_len; - - httpServerEvent.EventData.httpPostData.token_value.len = httpPostTokenArgs->token_value_len; - httpServerEvent.EventData.httpPostData.token_value.data = pPostParams; - - httpServerResponse.Response = SL_NETAPP_RESPONSE_NONE; - - _SlDrvHandleHttpServerEvents (&httpServerEvent, &httpServerResponse); - - } - break; -#endif - - - default: - SL_ERROR_TRACE2(MSG_305, "ASSERT: _SlDrvNetAppEventHandler : invalid opcode = 0x%x = %1", pHdr->GenHeader.Opcode, pHdr->GenHeader.Opcode); - VERIFY_PROTOCOL(0); - } -} - diff --git a/drivers/cc3100/src/netcfg.c b/drivers/cc3100/src/netcfg.c deleted file mode 100644 index 3674e0720e7..00000000000 --- a/drivers/cc3100/src/netcfg.c +++ /dev/null @@ -1,150 +0,0 @@ -/* -* netcfg.c - CC31xx/CC32xx Host Driver Implementation -* -* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ -* -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*/ - - - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ -#include "simplelink.h" -#include "protocol.h" -#include "driver.h" - -/*****************************************************************************/ -/* sl_NetCfgSet */ -/*****************************************************************************/ -typedef union -{ - _NetCfgSetGet_t Cmd; - _BasicResponse_t Rsp; -}_SlNetCfgMsgSet_u; - -#if _SL_INCLUDE_FUNC(sl_NetCfgSet) - -const _SlCmdCtrl_t _SlNetCfgSetCmdCtrl = -{ - SL_OPCODE_DEVICE_NETCFG_SET_COMMAND, - sizeof(_NetCfgSetGet_t), - sizeof(_BasicResponse_t) -}; - -_i32 sl_NetCfgSet(const _u8 ConfigId ,const _u8 ConfigOpt,const _u8 ConfigLen,const _u8 *pValues) -{ - _SlNetCfgMsgSet_u Msg; - _SlCmdExt_t CmdExt; - - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.TxPayloadLen = (ConfigLen+3) & (~3); - CmdExt.pTxPayload = (_u8 *)pValues; - - - Msg.Cmd.ConfigId = ConfigId; - Msg.Cmd.ConfigLen = ConfigLen; - Msg.Cmd.ConfigOpt = ConfigOpt; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlNetCfgSetCmdCtrl, &Msg, &CmdExt)); - - return (_i16)Msg.Rsp.status; -} -#endif - - -/*****************************************************************************/ -/* sl_NetCfgGet */ -/*****************************************************************************/ -typedef union -{ - _NetCfgSetGet_t Cmd; - _NetCfgSetGet_t Rsp; -}_SlNetCfgMsgGet_u; - -#if _SL_INCLUDE_FUNC(sl_NetCfgGet) - -const _SlCmdCtrl_t _SlNetCfgGetCmdCtrl = -{ - SL_OPCODE_DEVICE_NETCFG_GET_COMMAND, - sizeof(_NetCfgSetGet_t), - sizeof(_NetCfgSetGet_t) -}; - -_i32 sl_NetCfgGet(const _u8 ConfigId, _u8 *pConfigOpt,_u8 *pConfigLen, _u8 *pValues) -{ - _SlNetCfgMsgGet_u Msg; - _SlCmdExt_t CmdExt; - - if (*pConfigLen == 0) - { - return SL_EZEROLEN; - } - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.RxPayloadLen = *pConfigLen; - CmdExt.pRxPayload = (_u8 *)pValues; - Msg.Cmd.ConfigLen = *pConfigLen; - Msg.Cmd.ConfigId = ConfigId; - - if( pConfigOpt ) - { - Msg.Cmd.ConfigOpt = (_u16)*pConfigOpt; - } - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlNetCfgGetCmdCtrl, &Msg, &CmdExt)); - - if( pConfigOpt ) - { - *pConfigOpt = (_u8)Msg.Rsp.ConfigOpt; - } - if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) - { - *pConfigLen = (_u8)CmdExt.RxPayloadLen; - if( SL_MAC_ADDRESS_GET == ConfigId ) - { - return SL_RET_CODE_OK; /* sp fix */ - } - else - { - return SL_ESMALLBUF; - } - } - else - { - *pConfigLen = (_u8)CmdExt.ActualRxPayloadLen; - } - - return (_i16)Msg.Rsp.Status; -} -#endif - diff --git a/drivers/cc3100/src/nonos.c b/drivers/cc3100/src/nonos.c deleted file mode 100644 index a20e895765f..00000000000 --- a/drivers/cc3100/src/nonos.c +++ /dev/null @@ -1,171 +0,0 @@ -/* -* nonos.c - CC31xx/CC32xx Host Driver Implementation -* -* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ -* -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*/ - - - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ -#include "simplelink.h" -#include "protocol.h" -#include "driver.h" - -#ifndef SL_PLATFORM_MULTI_THREADED - -#include "nonos.h" - -#ifndef SL_TINY_EXT -#define NONOS_MAX_SPAWN_ENTRIES 5 -#else -#define NONOS_MAX_SPAWN_ENTRIES 1 -#endif - - -typedef struct -{ - _SlSpawnEntryFunc_t pEntry; - void* pValue; -}_SlNonOsSpawnEntry_t; - -typedef struct -{ - _SlNonOsSpawnEntry_t SpawnEntries[NONOS_MAX_SPAWN_ENTRIES]; -}_SlNonOsCB_t; - -_SlNonOsCB_t g__SlNonOsCB; - - -_SlNonOsRetVal_t _SlNonOsSemSet(_SlNonOsSemObj_t* pSemObj , _SlNonOsSemObj_t Value) -{ - *pSemObj = Value; - return NONOS_RET_OK; -} - -_SlNonOsRetVal_t _SlNonOsSemGet(_SlNonOsSemObj_t* pSyncObj, _SlNonOsSemObj_t WaitValue, _SlNonOsSemObj_t SetValue, _SlNonOsTime_t Timeout) -{ -#ifdef _SlSyncWaitLoopCallback - _SlNonOsTime_t timeOutRequest = Timeout; -#endif - while (Timeout>0) - { - if (WaitValue == *pSyncObj) - { - *pSyncObj = SetValue; - break; - } - if (Timeout != NONOS_WAIT_FOREVER) - { - Timeout--; - } - _SlNonOsMainLoopTask(); -#ifdef _SlSyncWaitLoopCallback - if( (__NON_OS_SYNC_OBJ_SIGNAL_VALUE == WaitValue) && (timeOutRequest != NONOS_NO_WAIT) ) - { - if (WaitValue == *pSyncObj) - { - *pSyncObj = SetValue; - break; - } - _SlSyncWaitLoopCallback(); - } -#endif - } - - if (0 == Timeout) - { - return NONOS_RET_ERR; - } - else - { - return NONOS_RET_OK; - } -} - - -_SlNonOsRetVal_t _SlNonOsSpawn(_SlSpawnEntryFunc_t pEntry , void* pValue , _u32 flags) -{ - _i8 i = 0; - -#ifndef SL_TINY_EXT - for (i=0 ; ipEntry) - { - pE->pValue = pValue; - pE->pEntry = pEntry; -#ifndef SL_TINY_EXT - break; -#endif - } - } - - - return NONOS_RET_OK; -} - - -_SlNonOsRetVal_t _SlNonOsMainLoopTask(void) -{ - _i8 i=0; - - -#ifndef SL_TINY_EXT - for (i=0 ; ipEntry; - - if (NULL != pF) - { - if(RxIrqCnt != (g_pCB)->RxDoneCnt) - { - pF(0); /* (pValue) */ - } - - pE->pEntry = NULL; - pE->pValue = NULL; - } - } - - return NONOS_RET_OK; -} - - -#endif /*(SL_PLATFORM != SL_PLATFORM_NON_OS)*/ diff --git a/drivers/cc3100/src/socket.c b/drivers/cc3100/src/socket.c deleted file mode 100644 index 8ef9e097452..00000000000 --- a/drivers/cc3100/src/socket.c +++ /dev/null @@ -1,1150 +0,0 @@ -/* - * socket.c - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - - - - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ -#include "simplelink.h" -#include "protocol.h" -#include "driver.h" - - -void _sl_BuildAddress(const SlSockAddr_t *addr, _SocketAddrCommand_u *pCmd); -void _sl_HandleAsync_Connect(void *pVoidBuf); - -#ifndef SL_TINY_EXT -void _sl_ParseAddress(_SocketAddrResponse_u *pRsp, SlSockAddr_t *addr, SlSocklen_t *addrlen); -void _sl_HandleAsync_Accept(void *pVoidBuf); -void _sl_HandleAsync_Select(void *pVoidBuf); -#endif -_u16 _sl_TruncatePayloadByProtocol(const _i16 pSd, const _u16 length); - -/*******************************************************************************/ -/* Functions */ -/*******************************************************************************/ - - - /* Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48 */ - /* is possible as _i32 as these parameters are in the same offset and size for these */ - /* three families. */ -#define SL_SOCKET_PAYLOAD_BASE (1350) - -const _u8 _SlPayloadByProtocolLUT[16] = -{ - (1472 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV4 */ - (1460 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV4 */ - (1452 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV6 */ - (1440 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV6 */ - (1386 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV4_SECURE */ - (1386 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV4_SECURE */ - (1396 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_UDP_IPV6_SECURE */ - (1396 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_TCP_IPV6_SECURE */ - (1476 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_TRANCEIVER */ - (1514 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_PACKET */ - (1480 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_IP4 */ - (1480 - SL_SOCKET_PAYLOAD_BASE), /* SL_SOCKET_PAYLOAD_TYPE_RAW_IP6 */ - (1440 - SL_SOCKET_PAYLOAD_BASE), /* Default */ - (1440 - SL_SOCKET_PAYLOAD_BASE), /* Default */ - (1440 - SL_SOCKET_PAYLOAD_BASE), /* Default */ - (1440 - SL_SOCKET_PAYLOAD_BASE) /* Default */ -}; - - - -/* ******************************************************************************/ -/* _sl_BuildAddress */ -/* ******************************************************************************/ -void _sl_BuildAddress(const SlSockAddr_t *addr, _SocketAddrCommand_u *pCmd) -{ - - /* Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48 - is possible as long as these parameters are in the same offset and size for these - three families. */ - pCmd->IpV4.FamilyAndFlags = (addr->sa_family << 4) & 0xF0; - pCmd->IpV4.port = ((SlSockAddrIn_t *)addr)->sin_port; - - if(SL_AF_INET == addr->sa_family) - { - pCmd->IpV4.address = ((SlSockAddrIn_t *)addr)->sin_addr.s_addr; - } - else if (SL_AF_INET6_EUI_48 == addr->sa_family ) - { - sl_Memcpy( pCmd->IpV6EUI48.address,((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, 6); - } -#ifdef SL_SUPPORT_IPV6 - else - { - sl_Memcpy(pCmd->IpV6.address, ((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, 16 ); - } -#endif -} - - -/***************************************************************************** - _sl_TruncatePayloadByProtocol -*****************************************************************************/ -_u16 _sl_TruncatePayloadByProtocol(const _i16 sd, const _u16 length) -{ - unsigned int maxLength; - - - maxLength = SL_SOCKET_PAYLOAD_BASE + _SlPayloadByProtocolLUT[((sd & SL_SOCKET_PAYLOAD_TYPE_MASK) >> 4)]; - - - - if( length > maxLength ) - { - return maxLength; - } - else - { - return length; - } -} - -/*******************************************************************************/ -/* _sl_ParseAddress */ -/*******************************************************************************/ - -#ifndef SL_TINY_EXT -void _sl_ParseAddress(_SocketAddrResponse_u *pRsp, SlSockAddr_t *addr, SlSocklen_t *addrlen) -{ - /* Note: parsing of family and port in the generic way for all IPV4, IPV6 and EUI48 */ - /* is possible as long as these parameters are in the same offset and size for these */ - /* three families. */ - addr->sa_family = pRsp->IpV4.family; - ((SlSockAddrIn_t *)addr)->sin_port = pRsp->IpV4.port; - - *addrlen = (SL_AF_INET == addr->sa_family) ? sizeof(SlSockAddrIn_t) : sizeof(SlSockAddrIn6_t); - - if(SL_AF_INET == addr->sa_family) - { - ((SlSockAddrIn_t *)addr)->sin_addr.s_addr = pRsp->IpV4.address; - } - else if (SL_AF_INET6_EUI_48 == addr->sa_family ) - { - sl_Memcpy(((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, pRsp->IpV6EUI48.address, 6); - } -#ifdef SL_SUPPORT_IPV6 - else - { - sl_Memcpy(((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, pRsp->IpV6.address, 16); - } -#endif -} - -#endif - -/*******************************************************************************/ -/* sl_Socket */ -/*******************************************************************************/ -typedef union -{ - _u32 Dummy; - _SocketCommand_t Cmd; - _SocketResponse_t Rsp; -}_SlSockSocketMsg_u; - - - -#if _SL_INCLUDE_FUNC(sl_Socket) - -const _SlCmdCtrl_t _SlSockSocketCmdCtrl = -{ - SL_OPCODE_SOCKET_SOCKET, - sizeof(_SocketCommand_t), - sizeof(_SocketResponse_t) -}; - -_i16 sl_Socket(_i16 Domain, _i16 Type, _i16 Protocol) -{ - _SlSockSocketMsg_u Msg; - - Msg.Cmd.Domain = (_u8)Domain; - Msg.Cmd.Type = (_u8)Type; - Msg.Cmd.Protocol = (_u8)Protocol; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSockSocketCmdCtrl, &Msg, NULL)); - - if( Msg.Rsp.statusOrLen < 0 ) - { - return( Msg.Rsp.statusOrLen ); - } - else - { - return (_i16)((_u8)Msg.Rsp.sd); -} -} -#endif - -/*******************************************************************************/ -/* sl_Close */ -/*******************************************************************************/ -typedef union -{ - _CloseCommand_t Cmd; - _SocketResponse_t Rsp; -}_SlSockCloseMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_Close) - -const _SlCmdCtrl_t _SlSockCloseCmdCtrl = -{ - SL_OPCODE_SOCKET_CLOSE, - sizeof(_CloseCommand_t), - sizeof(_SocketResponse_t) -}; - -_i16 sl_Close(_i16 sd) -{ - _SlSockCloseMsg_u Msg; - - Msg.Cmd.sd = (_u8)sd; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSockCloseCmdCtrl, &Msg, NULL)); - - return Msg.Rsp.statusOrLen; -} -#endif - -/*******************************************************************************/ -/* sl_Bind */ -/*******************************************************************************/ -typedef union -{ - _SocketAddrCommand_u Cmd; - _SocketResponse_t Rsp; -}_SlSockBindMsg_u; - -#if _SL_INCLUDE_FUNC(sl_Bind) -_i16 sl_Bind(_i16 sd, const SlSockAddr_t *addr, _i16 addrlen) -{ - _SlSockBindMsg_u Msg; - _SlCmdCtrl_t CmdCtrl = {0, 0, sizeof(_SocketResponse_t)}; - - switch(addr->sa_family) - { - case SL_AF_INET : - CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND; - CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv4Command_t); - break; -#ifndef SL_TINY_EXT - case SL_AF_INET6_EUI_48: - CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6; - CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6EUI48Command_t); - break; - -#ifdef SL_SUPPORT_IPV6 - case AF_INET6: - CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6; - CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6Command_t); - break; -#endif -#endif - - - case SL_AF_RF : - default: - return SL_RET_CODE_INVALID_INPUT; - } - - Msg.Cmd.IpV4.lenOrPadding = 0; - Msg.Cmd.IpV4.sd = (_u8)sd; - - _sl_BuildAddress(addr, &Msg.Cmd); - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL)); - - return Msg.Rsp.statusOrLen; -} -#endif - -/*******************************************************************************/ -/* sl_Sendto */ -/*******************************************************************************/ -typedef union -{ - _SocketAddrCommand_u Cmd; - /* no response for 'sendto' commands*/ -}_SlSendtoMsg_u; - -#if _SL_INCLUDE_FUNC(sl_SendTo) -_i16 sl_SendTo(_i16 sd, const void *pBuf, _i16 Len, _i16 flags, const SlSockAddr_t *to, SlSocklen_t tolen) -{ - _SlSendtoMsg_u Msg; - _SlCmdCtrl_t CmdCtrl = {0, 0, 0}; - _SlCmdExt_t CmdExt; - _u16 ChunkLen; - _i16 RetVal; - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.TxPayloadLen = (_u16)Len; - CmdExt.pTxPayload = (_u8 *)pBuf; - - switch(to->sa_family) - { - case SL_AF_INET: - CmdCtrl.Opcode = SL_OPCODE_SOCKET_SENDTO; - CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv4Command_t); - break; -#ifndef SL_TINY_EXT - case SL_AF_INET6_EUI_48: - CmdCtrl.Opcode = SL_OPCODE_SOCKET_BIND_V6; - CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6EUI48Command_t); - break; -#ifdef SL_SUPPORT_IPV6 - case AF_INET6: - CmdCtrl.Opcode = SL_OPCODE_SOCKET_SENDTO_V6; - CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6Command_t); - break; -#endif -#endif - case SL_AF_RF: - default: - return SL_RET_CODE_INVALID_INPUT; - } - - ChunkLen = _sl_TruncatePayloadByProtocol(sd,Len); - Msg.Cmd.IpV4.lenOrPadding = ChunkLen; - CmdExt.TxPayloadLen = ChunkLen; - - Msg.Cmd.IpV4.sd = (_u8)sd; - - _sl_BuildAddress(to, &Msg.Cmd); - - Msg.Cmd.IpV4.FamilyAndFlags |= flags & 0x0F; - - do - { - RetVal = _SlDrvDataWriteOp((_SlSd_t)sd, &CmdCtrl, &Msg, &CmdExt); - - if(SL_OS_RET_CODE_OK == RetVal) - { - CmdExt.pTxPayload += ChunkLen; - ChunkLen = (_u16)((_u8 *)pBuf + Len - CmdExt.pTxPayload); - ChunkLen = _sl_TruncatePayloadByProtocol(sd,ChunkLen); - CmdExt.TxPayloadLen = ChunkLen; - Msg.Cmd.IpV4.lenOrPadding = ChunkLen; - } - else - { - return RetVal; - } - }while(ChunkLen > 0); - - return (_i16)Len; -} -#endif - -/*******************************************************************************/ -/* sl_Recvfrom */ -/*******************************************************************************/ -typedef union -{ - _sendRecvCommand_t Cmd; - _SocketAddrResponse_u Rsp; -}_SlRecvfromMsg_u; - -const _SlCmdCtrl_t _SlRecvfomCmdCtrl = -{ - SL_OPCODE_SOCKET_RECVFROM, - sizeof(_sendRecvCommand_t), - sizeof(_SocketAddrResponse_u) -}; - - - -#if _SL_INCLUDE_FUNC(sl_RecvFrom) -_i16 sl_RecvFrom(_i16 sd, void *buf, _i16 Len, _i16 flags, SlSockAddr_t *from, SlSocklen_t *fromlen) -{ - _SlRecvfromMsg_u Msg; - _SlCmdExt_t CmdExt; - _i16 RetVal; - - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.RxPayloadLen = Len; - CmdExt.pRxPayload = (_u8 *)buf; - - Msg.Cmd.sd = (_u8)sd; - Msg.Cmd.StatusOrLen = Len; - /* no size truncation in recv path */ - CmdExt.RxPayloadLen = Msg.Cmd.StatusOrLen; - - - Msg.Cmd.FamilyAndFlags = flags & 0x0F; - - - if(sizeof(SlSockAddrIn_t) == *fromlen) - { - Msg.Cmd.FamilyAndFlags |= (SL_AF_INET << 4); - } - else if (sizeof(SlSockAddrIn6_t) == *fromlen) - { - Msg.Cmd.FamilyAndFlags |= (SL_AF_INET6 << 4); - } - else - { - return SL_RET_CODE_INVALID_INPUT; - } - - RetVal = _SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvfomCmdCtrl, &Msg, &CmdExt); - if( RetVal != SL_OS_RET_CODE_OK ) - { - return RetVal; - } - - RetVal = Msg.Rsp.IpV4.statusOrLen; - - if(RetVal >= 0) - { - VERIFY_PROTOCOL(sd == Msg.Rsp.IpV4.sd); -#if 0 - _sl_ParseAddress(&Msg.Rsp, from, fromlen); -#else - from->sa_family = Msg.Rsp.IpV4.family; - if(SL_AF_INET == from->sa_family) - { - ((SlSockAddrIn_t *)from)->sin_port = Msg.Rsp.IpV4.port; - ((SlSockAddrIn_t *)from)->sin_addr.s_addr = Msg.Rsp.IpV4.address; - *fromlen = sizeof(SlSockAddrIn_t); - } - else if (SL_AF_INET6_EUI_48 == from->sa_family ) - { - ((SlSockAddrIn6_t *)from)->sin6_port = Msg.Rsp.IpV6EUI48.port; - sl_Memcpy(((SlSockAddrIn6_t *)from)->sin6_addr._S6_un._S6_u8, Msg.Rsp.IpV6EUI48.address, 6); - } -#ifdef SL_SUPPORT_IPV6 - else if(AF_INET6 == from->sa_family) - { - VERIFY_PROTOCOL(*fromlen >= sizeof(sockaddr_in6)); - - ((sockaddr_in6 *)from)->sin6_port = Msg.Rsp.IpV6.port; - sl_Memcpy(((sockaddr_in6 *)from)->sin6_addr._S6_un._S6_u32, Msg.Rsp.IpV6.address, 16); - *fromlen = sizeof(sockaddr_in6); - } -#endif -#endif - } - - return (_i16)RetVal; -} -#endif - -/*******************************************************************************/ -/* sl_Connect */ -/*******************************************************************************/ -typedef union -{ - _SocketAddrCommand_u Cmd; - _SocketResponse_t Rsp; -}_SlSockConnectMsg_u; - -#if _SL_INCLUDE_FUNC(sl_Connect) -_i16 sl_Connect(_i16 sd, const SlSockAddr_t *addr, _i16 addrlen) -{ - _SlSockConnectMsg_u Msg; - _SlReturnVal_t RetVal; - _SlCmdCtrl_t CmdCtrl = {0, 0, sizeof(_SocketResponse_t)}; - _SocketResponse_t AsyncRsp; - _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; - - - switch(addr->sa_family) - { - case SL_AF_INET : - CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT; - CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv4Command_t); - /* Do nothing - cmd already initialized to this type */ - break; - case SL_AF_INET6_EUI_48: - CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT_V6; - CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6EUI48Command_t); - break; -#ifdef SL_SUPPORT_IPV6 - case AF_INET6: - CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT_V6; - CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6Command_t); - break; -#endif - case SL_AF_RF: - default: - return SL_RET_CODE_INVALID_INPUT; - } - - Msg.Cmd.IpV4.lenOrPadding = 0; - Msg.Cmd.IpV4.sd = (_u8)sd; - - _sl_BuildAddress(addr, &Msg.Cmd); - - - ObjIdx = _SlDrvProtectAsyncRespSetting((_u8*)&AsyncRsp, CONNECT_ID, sd & BSD_SOCKET_ID_MASK); - - if (MAX_CONCURRENT_ACTIONS == ObjIdx) - { - return SL_POOL_IS_EMPTY; - } - - /* send the command */ - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL)); - VERIFY_PROTOCOL(Msg.Rsp.sd == sd) - - RetVal = Msg.Rsp.statusOrLen; - - if(SL_RET_CODE_OK == RetVal) - { - /* wait for async and get Data Read parameters */ - _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj); - - VERIFY_PROTOCOL(AsyncRsp.sd == sd); - - RetVal = AsyncRsp.statusOrLen; - } - - - - _SlDrvReleasePoolObj(ObjIdx); - return RetVal; -} - -#endif - - -/*******************************************************************************/ -/* _sl_HandleAsync_Connect */ -/*******************************************************************************/ -void _sl_HandleAsync_Connect(void *pVoidBuf) -{ - _SocketResponse_t *pMsgArgs = (_SocketResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); - - _SlDrvProtectionObjLockWaitForever(); - - VERIFY_PROTOCOL((pMsgArgs->sd & BSD_SOCKET_ID_MASK) <= SL_MAX_SOCKETS); - VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); - - - ((_SocketResponse_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->sd = pMsgArgs->sd; - ((_SocketResponse_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->statusOrLen = pMsgArgs->statusOrLen; - - - _SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); - _SlDrvProtectionObjUnLock(); - return; -} - -/*******************************************************************************/ -/* sl_Send */ -/*******************************************************************************/ -typedef union -{ - _sendRecvCommand_t Cmd; - /* no response for 'sendto' commands*/ -}_SlSendMsg_u; - -const _SlCmdCtrl_t _SlSendCmdCtrl = -{ - SL_OPCODE_SOCKET_SEND, - sizeof(_sendRecvCommand_t), - 0 -}; - -#if _SL_INCLUDE_FUNC(sl_Send) -_i16 sl_Send(_i16 sd, const void *pBuf, _i16 Len, _i16 flags) -{ - _SlSendMsg_u Msg; - _SlCmdExt_t CmdExt; - _u16 ChunkLen; - _i16 RetVal; - _u32 tempVal; - _u8 runSingleChunk = FALSE; - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.TxPayloadLen = Len; - CmdExt.pTxPayload = (_u8 *)pBuf; - - /* Only for RAW transceiver type socket, relay the flags parameter in the 2 bytes (4 byte aligned) before the actual payload */ - if ((sd & SL_SOCKET_PAYLOAD_TYPE_MASK) == SL_SOCKET_PAYLOAD_TYPE_RAW_TRANCEIVER) - { - tempVal = flags; - CmdExt.pRxPayload = (_u8 *)&tempVal; - CmdExt.RxPayloadLen = -4; /* mark as Rx data to send */ - runSingleChunk = TRUE; - } - else - { - CmdExt.pRxPayload = NULL; - } - - ChunkLen = _sl_TruncatePayloadByProtocol(sd,Len); - CmdExt.TxPayloadLen = ChunkLen; - Msg.Cmd.StatusOrLen = ChunkLen; - Msg.Cmd.sd = (_u8)sd; - Msg.Cmd.FamilyAndFlags |= flags & 0x0F; - - do - { - RetVal = _SlDrvDataWriteOp((_u8)sd, (_SlCmdCtrl_t *)&_SlSendCmdCtrl, &Msg, &CmdExt); - if(SL_OS_RET_CODE_OK == RetVal) - { - CmdExt.pTxPayload += ChunkLen; - ChunkLen = (_u8 *)pBuf + Len - CmdExt.pTxPayload; - ChunkLen = _sl_TruncatePayloadByProtocol(sd,ChunkLen); - CmdExt.TxPayloadLen = ChunkLen; - Msg.Cmd.StatusOrLen = ChunkLen; - } - else - { - return RetVal; - } - }while((ChunkLen > 0) && (runSingleChunk==FALSE)); - - return (_i16)Len; -} -#endif - -/*******************************************************************************/ -/* sl_Listen */ -/*******************************************************************************/ -typedef union -{ - _ListenCommand_t Cmd; - _BasicResponse_t Rsp; -}_SlListenMsg_u; - - - -#if _SL_INCLUDE_FUNC(sl_Listen) - -const _SlCmdCtrl_t _SlListenCmdCtrl = -{ - SL_OPCODE_SOCKET_LISTEN, - sizeof(_ListenCommand_t), - sizeof(_BasicResponse_t), -}; - -_i16 sl_Listen(_i16 sd, _i16 backlog) -{ - _SlListenMsg_u Msg; - - Msg.Cmd.sd = (_u8)sd; - Msg.Cmd.backlog = (_u8)backlog; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlListenCmdCtrl, &Msg, NULL)); - - return (_i16)Msg.Rsp.status; -} -#endif - -/*******************************************************************************/ -/* sl_Accept */ -/*******************************************************************************/ -typedef union -{ - _AcceptCommand_t Cmd; - _SocketResponse_t Rsp; -}_SlSockAcceptMsg_u; - - - -#if _SL_INCLUDE_FUNC(sl_Accept) - -const _SlCmdCtrl_t _SlAcceptCmdCtrl = -{ - SL_OPCODE_SOCKET_ACCEPT, - sizeof(_AcceptCommand_t), - sizeof(_BasicResponse_t), -}; - -_i16 sl_Accept(_i16 sd, SlSockAddr_t *addr, SlSocklen_t *addrlen) -{ - _SlSockAcceptMsg_u Msg; - _SlReturnVal_t RetVal; - _SocketAddrResponse_u AsyncRsp; - - _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; - - - Msg.Cmd.sd = (_u8)sd; - Msg.Cmd.family = (sizeof(SlSockAddrIn_t) == *addrlen) ? SL_AF_INET : SL_AF_INET6; - - - ObjIdx = _SlDrvProtectAsyncRespSetting((_u8*)&AsyncRsp, ACCEPT_ID, sd & BSD_SOCKET_ID_MASK ); - - if (MAX_CONCURRENT_ACTIONS == ObjIdx) - { - return SL_POOL_IS_EMPTY; - } - - /* send the command */ - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlAcceptCmdCtrl, &Msg, NULL)); - VERIFY_PROTOCOL(Msg.Rsp.sd == sd); - - RetVal = Msg.Rsp.statusOrLen; - - if(SL_OS_RET_CODE_OK == RetVal) - { - /* wait for async and get Data Read parameters */ - _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj); - - VERIFY_PROTOCOL(AsyncRsp.IpV4.sd == sd); - - RetVal = AsyncRsp.IpV4.statusOrLen; - if( (NULL != addr) && (NULL != addrlen) ) - { -#if 0 /* Kept for backup */ - _sl_ParseAddress(&AsyncRsp, addr, addrlen); -#else - addr->sa_family = AsyncRsp.IpV4.family; - - if(SL_AF_INET == addr->sa_family) - { - if( *addrlen == sizeof( SlSockAddrIn_t ) ) - { - ((SlSockAddrIn_t *)addr)->sin_port = AsyncRsp.IpV4.port; - ((SlSockAddrIn_t *)addr)->sin_addr.s_addr = AsyncRsp.IpV4.address; - } - else - { - *addrlen = 0; - } - } - else if (SL_AF_INET6_EUI_48 == addr->sa_family ) - { - if( *addrlen == sizeof( SlSockAddrIn6_t ) ) - { - ((SlSockAddrIn6_t *)addr)->sin6_port = AsyncRsp.IpV6EUI48.port ; - /* will be called from here and from _sl_BuildAddress*/ - sl_Memcpy(((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, AsyncRsp.IpV6EUI48.address, 6); - } - else - { - *addrlen = 0; - } - } -#ifdef SL_SUPPORT_IPV6 - else - { - if( *addrlen == sizeof( sockaddr_in6 ) ) - { - ((sockaddr_in6 *)addr)->sin6_port = AsyncRsp.IpV6.port ; - sl_Memcpy(((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, AsyncRsp.IpV6.address, 16); - } - else - { - *addrlen = 0; - } - } -#endif -#endif - } - } - - _SlDrvReleasePoolObj(ObjIdx); - return (_i16)RetVal; -} -#endif - - -/*******************************************************************************/ -/* sl_Htonl */ -/*******************************************************************************/ -_u32 sl_Htonl( _u32 val ) -{ - _u32 i = 1; - _i8 *p = (_i8 *)&i; - if (p[0] == 1) /* little endian */ - { - p[0] = ((_i8* )&val)[3]; - p[1] = ((_i8* )&val)[2]; - p[2] = ((_i8* )&val)[1]; - p[3] = ((_i8* )&val)[0]; - return i; - } - else /* big endian */ - { - return val; - } -} - -/*******************************************************************************/ -/* sl_Htonl */ -/*******************************************************************************/ -_u16 sl_Htons( _u16 val ) -{ - _i16 i = 1; - _i8 *p = (_i8 *)&i; - if (p[0] == 1) /* little endian */ - { - p[0] = ((_i8* )&val)[1]; - p[1] = ((_i8* )&val)[0]; - return i; - } - else /* big endian */ - { - return val; - } -} - -/*******************************************************************************/ -/* _sl_HandleAsync_Accept */ -/*******************************************************************************/ -#ifndef SL_TINY_EXT -void _sl_HandleAsync_Accept(void *pVoidBuf) -{ - _SocketAddrResponse_u *pMsgArgs = (_SocketAddrResponse_u *)_SL_RESP_ARGS_START(pVoidBuf); - - _SlDrvProtectionObjLockWaitForever(); - - VERIFY_PROTOCOL(( pMsgArgs->IpV4.sd & BSD_SOCKET_ID_MASK) <= SL_MAX_SOCKETS); - VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); - - sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs,sizeof(_SocketAddrResponse_u)); - _SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); - - _SlDrvProtectionObjUnLock(); - return; -} - -/*******************************************************************************/ -/* _sl_HandleAsync_Select */ -/*******************************************************************************/ -void _sl_HandleAsync_Select(void *pVoidBuf) -{ - _SelectAsyncResponse_t *pMsgArgs = (_SelectAsyncResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); - - _SlDrvProtectionObjLockWaitForever(); - - VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); - - sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_SelectAsyncResponse_t)); - - _SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); - _SlDrvProtectionObjUnLock(); - - return; -} - -#endif - -/*******************************************************************************/ -/* sl_Recv */ -/*******************************************************************************/ -typedef union -{ - _sendRecvCommand_t Cmd; - _SocketResponse_t Rsp; -}_SlRecvMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_Recv) - -const _SlCmdCtrl_t _SlRecvCmdCtrl = -{ - SL_OPCODE_SOCKET_RECV, - sizeof(_sendRecvCommand_t), - sizeof(_SocketResponse_t) -}; - - -_i16 sl_Recv(_i16 sd, void *pBuf, _i16 Len, _i16 flags) -{ - _SlRecvMsg_u Msg; - _SlCmdExt_t CmdExt; - _SlReturnVal_t status; - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.RxPayloadLen = Len; - CmdExt.pRxPayload = (_u8 *)pBuf; - - Msg.Cmd.sd = (_u8)sd; - Msg.Cmd.StatusOrLen = Len; - - /* no size truncation in recv path */ - CmdExt.RxPayloadLen = Msg.Cmd.StatusOrLen; - - Msg.Cmd.FamilyAndFlags = flags & 0x0F; - - status = _SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvCmdCtrl, &Msg, &CmdExt); - if( status != SL_OS_RET_CODE_OK ) - { - return status; - } - - /* if the Device side sends less than expected it is not the Driver's role */ - /* the returned value could be smaller than the requested size */ - return (_i16)Msg.Rsp.statusOrLen; -} -#endif - -/*******************************************************************************/ -/* sl_SetSockOpt */ -/*******************************************************************************/ -typedef union -{ - _setSockOptCommand_t Cmd; - _SocketResponse_t Rsp; -}_SlSetSockOptMsg_u; - -const _SlCmdCtrl_t _SlSetSockOptCmdCtrl = -{ - SL_OPCODE_SOCKET_SETSOCKOPT, - sizeof(_setSockOptCommand_t), - sizeof(_SocketResponse_t) -}; - -#if _SL_INCLUDE_FUNC(sl_SetSockOpt) -_i16 sl_SetSockOpt(_i16 sd, _i16 level, _i16 optname, const void *optval, SlSocklen_t optlen) -{ - _SlSetSockOptMsg_u Msg; - _SlCmdExt_t CmdExt; - - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.TxPayloadLen = optlen; - CmdExt.pTxPayload = (_u8 *)optval; - - Msg.Cmd.sd = (_u8)sd; - Msg.Cmd.level = (_u8)level; - Msg.Cmd.optionLen = (_u8)optlen; - Msg.Cmd.optionName = (_u8)optname; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSetSockOptCmdCtrl, &Msg, &CmdExt)); - - return (_i16)Msg.Rsp.statusOrLen; -} -#endif - -/*******************************************************************************/ -/* sl_GetSockOpt */ -/*******************************************************************************/ -typedef union -{ - _getSockOptCommand_t Cmd; - _getSockOptResponse_t Rsp; -}_SlGetSockOptMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_GetSockOpt) - -const _SlCmdCtrl_t _SlGetSockOptCmdCtrl = -{ - SL_OPCODE_SOCKET_GETSOCKOPT, - sizeof(_getSockOptCommand_t), - sizeof(_getSockOptResponse_t) -}; - -_i16 sl_GetSockOpt(_i16 sd, _i16 level, _i16 optname, void *optval, SlSocklen_t *optlen) -{ - _SlGetSockOptMsg_u Msg; - _SlCmdExt_t CmdExt; - - if (*optlen == 0) - { - return SL_EZEROLEN; - } - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.RxPayloadLen = *optlen; - CmdExt.pRxPayload = optval; - - Msg.Cmd.sd = (_u8)sd; - Msg.Cmd.level = (_u8)level; - Msg.Cmd.optionLen = (_u8)(*optlen); - Msg.Cmd.optionName = (_u8)optname; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetSockOptCmdCtrl, &Msg, &CmdExt)); - - if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) - { - *optlen = Msg.Rsp.optionLen; - return SL_ESMALLBUF; - } - else - { - *optlen = (_u8)CmdExt.ActualRxPayloadLen; - } - return (_i16)Msg.Rsp.status; -} -#endif - -/*******************************************************************************/ -/* sl_Select */ -/* ******************************************************************************/ -typedef union -{ - _SelectCommand_t Cmd; - _BasicResponse_t Rsp; -}_SlSelectMsg_u; - - - -#ifndef SL_TINY_EXT -#if _SL_INCLUDE_FUNC(sl_Select) - -const _SlCmdCtrl_t _SlSelectCmdCtrl = -{ - SL_OPCODE_SOCKET_SELECT, - sizeof(_SelectCommand_t), - sizeof(_BasicResponse_t) -}; - - -_i16 sl_Select(_i16 nfds, SlFdSet_t *readsds, SlFdSet_t *writesds, SlFdSet_t *exceptsds, struct SlTimeval_t *timeout) -{ - _SlSelectMsg_u Msg; - _SelectAsyncResponse_t AsyncRsp; - _u8 ObjIdx = MAX_CONCURRENT_ACTIONS; - - Msg.Cmd.nfds = (_u8)nfds; - Msg.Cmd.readFdsCount = 0; - Msg.Cmd.writeFdsCount = 0; - - Msg.Cmd.readFds = 0; - Msg.Cmd.writeFds = 0; - - - if( readsds ) - { - Msg.Cmd.readFds = (_u16)readsds->fd_array[0]; - } - if( writesds ) - { - Msg.Cmd.writeFds = (_u16)writesds->fd_array[0]; - } - if( NULL == timeout ) - { - Msg.Cmd.tv_sec = 0xffff; - Msg.Cmd.tv_usec = 0xffff; - } - else - { - if( 0xffff <= timeout->tv_sec ) - { - Msg.Cmd.tv_sec = 0xffff; - } - else - { - Msg.Cmd.tv_sec = (_u16)timeout->tv_sec; - } - timeout->tv_usec = timeout->tv_usec >> 10; /* convert to milliseconds */ - if( 0xffff <= timeout->tv_usec ) - { - Msg.Cmd.tv_usec = 0xffff; - } - else - { - Msg.Cmd.tv_usec = (_u16)timeout->tv_usec; - } - } - - /* Use Obj to issue the command, if not available try later */ - ObjIdx = _SlDrvProtectAsyncRespSetting((_u8*)&AsyncRsp, SELECT_ID, SL_MAX_SOCKETS); - - if (MAX_CONCURRENT_ACTIONS == ObjIdx) - { - return SL_POOL_IS_EMPTY; - } - - - /* send the command */ - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSelectCmdCtrl, &Msg, NULL)); - - if(SL_OS_RET_CODE_OK == (_i16)Msg.Rsp.status) - { - _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj); - - Msg.Rsp.status = AsyncRsp.status; - - if( ((_i16)Msg.Rsp.status) >= 0 ) - { - if( readsds ) - { - readsds->fd_array[0] = AsyncRsp.readFds; - } - if( writesds ) - { - writesds->fd_array[0] = AsyncRsp.writeFds; - } - } - } - - _SlDrvReleasePoolObj(ObjIdx); - return (_i16)Msg.Rsp.status; -} - -/* Select helper functions */ -/*******************************************************************************/ -/* SL_FD_SET */ -/* ******************************************************************************/ -void SL_FD_SET(_i16 fd, SlFdSet_t *fdset) -{ - fdset->fd_array[0] |= (1<< (fd & BSD_SOCKET_ID_MASK)); -} -/*******************************************************************************/ -/* SL_FD_CLR */ -/*******************************************************************************/ -void SL_FD_CLR(_i16 fd, SlFdSet_t *fdset) -{ - fdset->fd_array[0] &= ~(1<< (fd & BSD_SOCKET_ID_MASK)); -} -/*******************************************************************************/ -/* SL_FD_ISSET */ -/*******************************************************************************/ -_i16 SL_FD_ISSET(_i16 fd, SlFdSet_t *fdset) -{ - if( fdset->fd_array[0] & (1<< (fd & BSD_SOCKET_ID_MASK)) ) - { - return 1; - } - return 0; -} -/*******************************************************************************/ -/* SL_FD_ZERO */ -/*******************************************************************************/ -void SL_FD_ZERO(SlFdSet_t *fdset) -{ - fdset->fd_array[0] = 0; -} - -#endif -#endif - - - diff --git a/drivers/cc3100/src/spawn.c b/drivers/cc3100/src/spawn.c deleted file mode 100644 index bb5575818ba..00000000000 --- a/drivers/cc3100/src/spawn.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * spawn.c - CC31xx/CC32xx Host Driver Implementation - * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - - - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ -#include "simplelink.h" - - -#if (defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN)) - -#define _SL_MAX_INTERNAL_SPAWN_ENTRIES 10 - -typedef struct _SlInternalSpawnEntry_t -{ - _SlSpawnEntryFunc_t pEntry; - void* pValue; - struct _SlInternalSpawnEntry_t* pNext; -}_SlInternalSpawnEntry_t; - -typedef struct -{ - _SlInternalSpawnEntry_t SpawnEntries[_SL_MAX_INTERNAL_SPAWN_ENTRIES]; - _SlInternalSpawnEntry_t* pFree; - _SlInternalSpawnEntry_t* pWaitForExe; - _SlInternalSpawnEntry_t* pLastInWaitList; - _SlSyncObj_t SyncObj; - _SlLockObj_t LockObj; -}_SlInternalSpawnCB_t; - -_SlInternalSpawnCB_t g_SlInternalSpawnCB; - - -void _SlInternalSpawnTaskEntry() -{ - _i16 i; - _SlInternalSpawnEntry_t* pEntry; - _u8 LastEntry; - - /* create and lock the locking object. lock in order to avoid race condition - on the first creation */ - sl_LockObjCreate(&g_SlInternalSpawnCB.LockObj,"SlSpawnProtect"); - sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_NO_WAIT); - - /* create and clear the sync object */ - sl_SyncObjCreate(&g_SlInternalSpawnCB.SyncObj,"SlSpawnSync"); - sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj,SL_OS_NO_WAIT); - - g_SlInternalSpawnCB.pFree = &g_SlInternalSpawnCB.SpawnEntries[0]; - g_SlInternalSpawnCB.pWaitForExe = NULL; - g_SlInternalSpawnCB.pLastInWaitList = NULL; - - /* create the link list between the entries */ - for (i=0 ; i<_SL_MAX_INTERNAL_SPAWN_ENTRIES - 1 ; i++) - { - g_SlInternalSpawnCB.SpawnEntries[i].pNext = &g_SlInternalSpawnCB.SpawnEntries[i+1]; - g_SlInternalSpawnCB.SpawnEntries[i].pEntry = NULL; - } - g_SlInternalSpawnCB.SpawnEntries[i].pNext = NULL; - - _SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj); - - /* here we ready to execute entries */ - - while (TRUE) - { - sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj,SL_OS_WAIT_FOREVER); - /* go over all entries that already waiting for execution */ - LastEntry = FALSE; - do - { - /* get entry to execute */ - _SlDrvObjLockWaitForever(&g_SlInternalSpawnCB.LockObj); - - pEntry = g_SlInternalSpawnCB.pWaitForExe; - if ( NULL == pEntry ) - { - _SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj); - break; - } - g_SlInternalSpawnCB.pWaitForExe = pEntry->pNext; - if (pEntry == g_SlInternalSpawnCB.pLastInWaitList) - { - g_SlInternalSpawnCB.pLastInWaitList = NULL; - LastEntry = TRUE; - } - - _SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj); - - /* pEntry could be null in case that the sync was already set by some - of the entries during execution of earlier entry */ - if (NULL != pEntry) - { - pEntry->pEntry(pEntry->pValue); - /* free the entry */ - - _SlDrvObjLockWaitForever(&g_SlInternalSpawnCB.LockObj); - - pEntry->pNext = g_SlInternalSpawnCB.pFree; - g_SlInternalSpawnCB.pFree = pEntry; - - - if (NULL != g_SlInternalSpawnCB.pWaitForExe) - { - /* new entry received meanwhile */ - LastEntry = FALSE; - } - - _SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj); - - } - - }while (!LastEntry); - } -} - - -_i16 _SlInternalSpawn(_SlSpawnEntryFunc_t pEntry , void* pValue , _u32 flags) -{ - _i16 Res = 0; - _SlInternalSpawnEntry_t* pSpawnEntry; - - if (NULL == pEntry) - { - Res = -1; - } - else - { - _SlDrvObjLockWaitForever(&g_SlInternalSpawnCB.LockObj); - - pSpawnEntry = g_SlInternalSpawnCB.pFree; - g_SlInternalSpawnCB.pFree = pSpawnEntry->pNext; - - pSpawnEntry->pEntry = pEntry; - pSpawnEntry->pValue = pValue; - pSpawnEntry->pNext = NULL; - - if (NULL == g_SlInternalSpawnCB.pWaitForExe) - { - g_SlInternalSpawnCB.pWaitForExe = pSpawnEntry; - g_SlInternalSpawnCB.pLastInWaitList = pSpawnEntry; - } - else - { - g_SlInternalSpawnCB.pLastInWaitList->pNext = pSpawnEntry; - g_SlInternalSpawnCB.pLastInWaitList = pSpawnEntry; - } - - _SlDrvObjUnLock(&g_SlInternalSpawnCB.LockObj); - - /* this sync is called after releasing the lock object to avoid unnecessary context switches */ - _SlDrvSyncObjSignal(&g_SlInternalSpawnCB.SyncObj); - } - - return Res; -} - - - - - -#endif diff --git a/drivers/cc3100/src/wlan.c b/drivers/cc3100/src/wlan.c deleted file mode 100644 index 59adf02f022..00000000000 --- a/drivers/cc3100/src/wlan.c +++ /dev/null @@ -1,1006 +0,0 @@ -/* -* wlan.c - CC31xx/CC32xx Host Driver Implementation -* -* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ -* -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the -* distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*/ - - - -/*****************************************************************************/ -/* Include files */ -/*****************************************************************************/ -#include "simplelink.h" -#include "protocol.h" -#include "driver.h" - -/*****************************************************************************/ -/* Macro declarations */ -/*****************************************************************************/ -#define MAX_SSID_LEN (32) -#define MAX_KEY_LEN (63) -#define MAX_USER_LEN (32) -#define MAX_ANON_USER_LEN (32) -#define MAX_SMART_CONFIG_KEY (16) - - -/***************************************************************************** -sl_WlanConnect -*****************************************************************************/ -typedef struct -{ - _WlanConnectEapCommand_t Args; - _i8 Strings[MAX_SSID_LEN + MAX_KEY_LEN + MAX_USER_LEN + MAX_ANON_USER_LEN]; -}_WlanConnectCmd_t; - -typedef union -{ - _WlanConnectCmd_t Cmd; - _BasicResponse_t Rsp; -}_SlWlanConnectMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_WlanConnect) -_i16 sl_WlanConnect(const _i8* pName,const _i16 NameLen,const _u8 *pMacAddr,const SlSecParams_t* pSecParams ,const SlSecParamsExt_t* pSecExtParams) -{ - _SlWlanConnectMsg_u Msg; - _SlCmdCtrl_t CmdCtrl; - - sl_Memset (&Msg, 0, sizeof(Msg)); - - CmdCtrl.TxDescLen = 0;/* init */ - CmdCtrl.RxDescLen = sizeof(_BasicResponse_t); - - /* verify SSID length */ - VERIFY_PROTOCOL(NameLen <= MAX_SSID_LEN); - /* verify SSID is not NULL */ - if( NULL == pName ) - { - return SL_INVALPARAM; - } - /* update SSID length */ - Msg.Cmd.Args.Common.SsidLen = (_u8)NameLen; - - /* Profile with no security */ - /* Enterprise security profile */ - if (NULL != pSecExtParams) - { - /* Update command opcode */ - CmdCtrl.Opcode = SL_OPCODE_WLAN_WLANCONNECTEAPCOMMAND; - CmdCtrl.TxDescLen += sizeof(_WlanConnectEapCommand_t); - /* copy SSID */ - sl_Memcpy(EAP_SSID_STRING(&Msg), pName, NameLen); - CmdCtrl.TxDescLen += NameLen; - /* Copy password if supplied */ - if ((NULL != pSecParams) && (pSecParams->KeyLen > 0)) - { - /* update security type */ - Msg.Cmd.Args.Common.SecType = pSecParams->Type; - /* verify key length */ - if (pSecParams->KeyLen > MAX_KEY_LEN) - { - return SL_INVALPARAM; - } - /* update key length */ - Msg.Cmd.Args.Common.PasswordLen = pSecParams->KeyLen; - ARG_CHECK_PTR(pSecParams->Key); - /* copy key */ - sl_Memcpy(EAP_PASSWORD_STRING(&Msg), pSecParams->Key, pSecParams->KeyLen); - CmdCtrl.TxDescLen += pSecParams->KeyLen; - } - else - { - Msg.Cmd.Args.Common.PasswordLen = 0; - } - - ARG_CHECK_PTR(pSecExtParams); - /* Update Eap bitmask */ - Msg.Cmd.Args.EapBitmask = pSecExtParams->EapMethod; - /* Update Certificate file ID index - currently not supported */ - Msg.Cmd.Args.CertIndex = pSecExtParams->CertIndex; - /* verify user length */ - if (pSecExtParams->UserLen > MAX_USER_LEN) - { - return SL_INVALPARAM; - } - Msg.Cmd.Args.UserLen = pSecExtParams->UserLen; - /* copy user name (identity) */ - if(pSecExtParams->UserLen > 0) - { - sl_Memcpy(EAP_USER_STRING(&Msg), pSecExtParams->User, pSecExtParams->UserLen); - CmdCtrl.TxDescLen += pSecExtParams->UserLen; - } - /* verify Anonymous user length */ - if (pSecExtParams->AnonUserLen > MAX_ANON_USER_LEN) - { - return SL_INVALPARAM; - } - Msg.Cmd.Args.AnonUserLen = pSecExtParams->AnonUserLen; - /* copy Anonymous user */ - if(pSecExtParams->AnonUserLen > 0) - { - sl_Memcpy(EAP_ANON_USER_STRING(&Msg), pSecExtParams->AnonUser, pSecExtParams->AnonUserLen); - CmdCtrl.TxDescLen += pSecExtParams->AnonUserLen; - } - - } - - /* Regular or open security profile */ - else - { - /* Update command opcode */ - CmdCtrl.Opcode = SL_OPCODE_WLAN_WLANCONNECTCOMMAND; - CmdCtrl.TxDescLen += sizeof(_WlanConnectCommon_t); - /* copy SSID */ - sl_Memcpy(SSID_STRING(&Msg), pName, NameLen); - CmdCtrl.TxDescLen += NameLen; - /* Copy password if supplied */ - if( NULL != pSecParams ) - { - /* update security type */ - Msg.Cmd.Args.Common.SecType = pSecParams->Type; - /* verify key length is valid */ - if (pSecParams->KeyLen > MAX_KEY_LEN) - { - return SL_INVALPARAM; - } - /* update key length */ - Msg.Cmd.Args.Common.PasswordLen = pSecParams->KeyLen; - CmdCtrl.TxDescLen += pSecParams->KeyLen; - /* copy key (could be no key in case of WPS pin) */ - if( NULL != pSecParams->Key ) - { - sl_Memcpy(PASSWORD_STRING(&Msg), pSecParams->Key, pSecParams->KeyLen); - } - } - /* Profile with no security */ - else - { - Msg.Cmd.Args.Common.PasswordLen = 0; - Msg.Cmd.Args.Common.SecType = SL_SEC_TYPE_OPEN; - } - } - /* If BSSID is not null, copy to buffer, otherwise set to 0 */ - if(NULL != pMacAddr) - { - sl_Memcpy(Msg.Cmd.Args.Common.Bssid, pMacAddr, sizeof(Msg.Cmd.Args.Common.Bssid)); - } - else - { - _SlDrvMemZero(Msg.Cmd.Args.Common.Bssid, sizeof(Msg.Cmd.Args.Common.Bssid)); - } - - - VERIFY_RET_OK ( _SlDrvCmdOp(&CmdCtrl, &Msg, NULL)); - - return (_i16)Msg.Rsp.status; -} -#endif - -/*******************************************************************************/ -/* sl_Disconnect */ -/* ******************************************************************************/ -#if _SL_INCLUDE_FUNC(sl_WlanDisconnect) -_i16 sl_WlanDisconnect(void) -{ - return _SlDrvBasicCmd(SL_OPCODE_WLAN_WLANDISCONNECTCOMMAND); -} -#endif - -/******************************************************************************/ -/* sl_PolicySet */ -/******************************************************************************/ -typedef union -{ - _WlanPoliciySetGet_t Cmd; - _BasicResponse_t Rsp; -}_SlPolicyMsg_u; - -#if _SL_INCLUDE_FUNC(sl_WlanPolicySet) - -const _SlCmdCtrl_t _SlPolicySetCmdCtrl = -{ - SL_OPCODE_WLAN_POLICYSETCOMMAND, - sizeof(_WlanPoliciySetGet_t), - sizeof(_BasicResponse_t) -}; - -_i16 sl_WlanPolicySet(const _u8 Type , const _u8 Policy, _u8 *pVal,const _u8 ValLen) -{ - _SlPolicyMsg_u Msg; - _SlCmdExt_t CmdExt; - - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.TxPayloadLen = ValLen; - CmdExt.pTxPayload = (_u8 *)pVal; - - - Msg.Cmd.PolicyType = Type; - Msg.Cmd.PolicyOption = Policy; - Msg.Cmd.PolicyOptionLen = ValLen; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlPolicySetCmdCtrl, &Msg, &CmdExt)); - - return (_i16)Msg.Rsp.status; -} -#endif - - -/******************************************************************************/ -/* sl_PolicyGet */ -/******************************************************************************/ -typedef union -{ - _WlanPoliciySetGet_t Cmd; - _WlanPoliciySetGet_t Rsp; -}_SlPolicyGetMsg_u; - -#if _SL_INCLUDE_FUNC(sl_WlanPolicyGet) - -const _SlCmdCtrl_t _SlPolicyGetCmdCtrl = -{ - SL_OPCODE_WLAN_POLICYGETCOMMAND, - sizeof(_WlanPoliciySetGet_t), - sizeof(_WlanPoliciySetGet_t) -}; - -_i16 sl_WlanPolicyGet(const _u8 Type ,_u8 Policy,_u8 *pVal,_u8 *pValLen) -{ - _SlPolicyGetMsg_u Msg; - _SlCmdExt_t CmdExt; - - if (*pValLen == 0) - { - return SL_EZEROLEN; - } - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.RxPayloadLen = *pValLen; - CmdExt.pRxPayload = pVal; - - Msg.Cmd.PolicyType = Type; - Msg.Cmd.PolicyOption = Policy; - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlPolicyGetCmdCtrl, &Msg, &CmdExt)); - - - if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) - { - *pValLen = Msg.Rsp.PolicyOptionLen; - return SL_ESMALLBUF; - } - else - { - /* no pointer valus, fill the results into _i8 */ - *pValLen = (_u8)CmdExt.ActualRxPayloadLen; - if( 0 == CmdExt.ActualRxPayloadLen ) - { - *pValLen = 1; - pVal[0] = Msg.Rsp.PolicyOption; - } - } - return (_i16)SL_OS_RET_CODE_OK; -} -#endif - - -/*******************************************************************************/ -/* sl_ProfileAdd */ -/*******************************************************************************/ -typedef struct -{ - _WlanAddGetEapProfile_t Args; - _i8 Strings[MAX_SSID_LEN + MAX_KEY_LEN + MAX_USER_LEN + MAX_ANON_USER_LEN]; -}_SlProfileParams_t; - -typedef union -{ - _SlProfileParams_t Cmd; - _BasicResponse_t Rsp; -}_SlProfileAddMsg_u; - - - -#if _SL_INCLUDE_FUNC(sl_WlanProfileAdd) -_i16 sl_WlanProfileAdd(const _i8* pName,const _i16 NameLen,const _u8 *pMacAddr,const SlSecParams_t* pSecParams ,const SlSecParamsExt_t* pSecExtParams,const _u32 Priority,const _u32 Options) -{ - _SlProfileAddMsg_u Msg; - _SlCmdCtrl_t CmdCtrl = {0}; - CmdCtrl.TxDescLen = 0;/* init */ - CmdCtrl.RxDescLen = sizeof(_BasicResponse_t); - - /* update priority */ - Msg.Cmd.Args.Common.Priority = (_u8)Priority; - /* verify SSID is not NULL */ - if( NULL == pName ) - { - return SL_INVALPARAM; - } - /* verify SSID length */ - VERIFY_PROTOCOL(NameLen <= MAX_SSID_LEN); - /* update SSID length */ - Msg.Cmd.Args.Common.SsidLen = (_u8)NameLen; - - - /* Enterprise security profile */ - if (NULL != pSecExtParams) - { - /* Update command opcode */ - CmdCtrl.Opcode = SL_OPCODE_WLAN_EAP_PROFILEADDCOMMAND; - CmdCtrl.TxDescLen += sizeof(_WlanAddGetEapProfile_t); - - /* copy SSID */ - sl_Memcpy(EAP_PROFILE_SSID_STRING(&Msg), pName, NameLen); - CmdCtrl.TxDescLen += NameLen; - - /* Copy password if supplied */ - if ((NULL != pSecParams) && (pSecParams->KeyLen > 0)) - { - /* update security type */ - Msg.Cmd.Args.Common.SecType = pSecParams->Type; - - if( SL_SEC_TYPE_WEP == Msg.Cmd.Args.Common.SecType ) - { - Msg.Cmd.Args.Common.WepKeyId = 0; - } - - /* verify key length */ - if (pSecParams->KeyLen > MAX_KEY_LEN) - { - return SL_INVALPARAM; - } - VERIFY_PROTOCOL(pSecParams->KeyLen <= MAX_KEY_LEN); - /* update key length */ - Msg.Cmd.Args.Common.PasswordLen = pSecParams->KeyLen; - CmdCtrl.TxDescLen += pSecParams->KeyLen; - ARG_CHECK_PTR(pSecParams->Key); - /* copy key */ - sl_Memcpy(EAP_PROFILE_PASSWORD_STRING(&Msg), pSecParams->Key, pSecParams->KeyLen); - } - else - { - Msg.Cmd.Args.Common.PasswordLen = 0; - } - - ARG_CHECK_PTR(pSecExtParams); - /* Update Eap bitmask */ - Msg.Cmd.Args.EapBitmask = pSecExtParams->EapMethod; - /* Update Certificate file ID index - currently not supported */ - Msg.Cmd.Args.CertIndex = pSecExtParams->CertIndex; - /* verify user length */ - if (pSecExtParams->UserLen > MAX_USER_LEN) - { - return SL_INVALPARAM; - } - Msg.Cmd.Args.UserLen = pSecExtParams->UserLen; - /* copy user name (identity) */ - if(pSecExtParams->UserLen > 0) - { - sl_Memcpy(EAP_PROFILE_USER_STRING(&Msg), pSecExtParams->User, pSecExtParams->UserLen); - CmdCtrl.TxDescLen += pSecExtParams->UserLen; - } - - /* verify Anonymous user length (for tunneled) */ - if (pSecExtParams->AnonUserLen > MAX_ANON_USER_LEN) - { - return SL_INVALPARAM; - } - Msg.Cmd.Args.AnonUserLen = pSecExtParams->AnonUserLen; - - /* copy Anonymous user */ - if(pSecExtParams->AnonUserLen > 0) - { - sl_Memcpy(EAP_PROFILE_ANON_USER_STRING(&Msg), pSecExtParams->AnonUser, pSecExtParams->AnonUserLen); - CmdCtrl.TxDescLen += pSecExtParams->AnonUserLen; - } - - } - /* Regular or open security profile */ - else - { - /* Update command opcode */ - CmdCtrl.Opcode = SL_OPCODE_WLAN_PROFILEADDCOMMAND; - /* update commnad length */ - CmdCtrl.TxDescLen += sizeof(_WlanAddGetProfile_t); - - if (NULL != pName) - { - /* copy SSID */ - sl_Memcpy(PROFILE_SSID_STRING(&Msg), pName, NameLen); - CmdCtrl.TxDescLen += NameLen; - } - - /* Copy password if supplied */ - if( NULL != pSecParams ) - { - /* update security type */ - Msg.Cmd.Args.Common.SecType = pSecParams->Type; - - if( SL_SEC_TYPE_WEP == Msg.Cmd.Args.Common.SecType ) - { - Msg.Cmd.Args.Common.WepKeyId = 0; - } - - /* verify key length */ - if (pSecParams->KeyLen > MAX_KEY_LEN) - { - return SL_INVALPARAM; - } - /* update key length */ - Msg.Cmd.Args.Common.PasswordLen = pSecParams->KeyLen; - CmdCtrl.TxDescLen += pSecParams->KeyLen; - /* copy key (could be no key in case of WPS pin) */ - if( NULL != pSecParams->Key ) - { - sl_Memcpy(PROFILE_PASSWORD_STRING(&Msg), pSecParams->Key, pSecParams->KeyLen); - } - } - else - { - Msg.Cmd.Args.Common.SecType = SL_SEC_TYPE_OPEN; - Msg.Cmd.Args.Common.PasswordLen = 0; - } - - } - - - /* If BSSID is not null, copy to buffer, otherwise set to 0 */ - if(NULL != pMacAddr) - { - sl_Memcpy(Msg.Cmd.Args.Common.Bssid, pMacAddr, sizeof(Msg.Cmd.Args.Common.Bssid)); - } - else - { - _SlDrvMemZero(Msg.Cmd.Args.Common.Bssid, sizeof(Msg.Cmd.Args.Common.Bssid)); - } - - VERIFY_RET_OK(_SlDrvCmdOp(&CmdCtrl, &Msg, NULL)); - - return (_i16)Msg.Rsp.status; -} -#endif -/*******************************************************************************/ -/* sl_ProfileGet */ -/*******************************************************************************/ -typedef union -{ - _WlanProfileDelGetCommand_t Cmd; - _SlProfileParams_t Rsp; -}_SlProfileGetMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_WlanProfileGet) - -const _SlCmdCtrl_t _SlProfileGetCmdCtrl = -{ - SL_OPCODE_WLAN_PROFILEGETCOMMAND, - sizeof(_WlanProfileDelGetCommand_t), - sizeof(_SlProfileParams_t) -}; - -_i16 sl_WlanProfileGet(const _i16 Index,_i8* pName, _i16 *pNameLen, _u8 *pMacAddr, SlSecParams_t* pSecParams, SlGetSecParamsExt_t* pEntParams, _u32 *pPriority) -{ - _SlProfileGetMsg_u Msg; - Msg.Cmd.index = (_u8)Index; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlProfileGetCmdCtrl, &Msg, NULL)); - - pSecParams->Type = Msg.Rsp.Args.Common.SecType; - /* since password is not transferred in getprofile, password length should always be zero */ - pSecParams->KeyLen = Msg.Rsp.Args.Common.PasswordLen; - if (NULL != pEntParams) - { - pEntParams->UserLen = Msg.Rsp.Args.UserLen; - /* copy user name */ - if (pEntParams->UserLen > 0) - { - sl_Memcpy(pEntParams->User, EAP_PROFILE_USER_STRING(&Msg), pEntParams->UserLen); - } - pEntParams->AnonUserLen = Msg.Rsp.Args.AnonUserLen; - /* copy anonymous user name */ - if (pEntParams->AnonUserLen > 0) - { - sl_Memcpy(pEntParams->AnonUser, EAP_PROFILE_ANON_USER_STRING(&Msg), pEntParams->AnonUserLen); - } - } - - *pNameLen = Msg.Rsp.Args.Common.SsidLen; - *pPriority = Msg.Rsp.Args.Common.Priority; - - if (NULL != Msg.Rsp.Args.Common.Bssid) - { - sl_Memcpy(pMacAddr, Msg.Rsp.Args.Common.Bssid, sizeof(Msg.Rsp.Args.Common.Bssid)); - } - - sl_Memcpy(pName, EAP_PROFILE_SSID_STRING(&Msg), *pNameLen); - - return (_i16)Msg.Rsp.Args.Common.SecType; - -} -#endif -/*******************************************************************************/ -/* sl_ProfileDel */ -/*******************************************************************************/ -typedef union -{ - _WlanProfileDelGetCommand_t Cmd; - _BasicResponse_t Rsp; -}_SlProfileDelMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_WlanProfileDel) - -const _SlCmdCtrl_t _SlProfileDelCmdCtrl = -{ - SL_OPCODE_WLAN_PROFILEDELCOMMAND, - sizeof(_WlanProfileDelGetCommand_t), - sizeof(_BasicResponse_t) -}; - -_i16 sl_WlanProfileDel(const _i16 Index) -{ - _SlProfileDelMsg_u Msg; - - Msg.Cmd.index = (_u8)Index; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlProfileDelCmdCtrl, &Msg, NULL)); - - return (_i16)Msg.Rsp.status; -} -#endif - - -/******************************************************************************/ -/* sl_WlanGetNetworkList */ -/******************************************************************************/ -typedef union -{ - _WlanGetNetworkListCommand_t Cmd; - _WlanGetNetworkListResponse_t Rsp; -}_SlWlanGetNetworkListMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_WlanGetNetworkList) - -const _SlCmdCtrl_t _SlWlanGetNetworkListCtrl = -{ - SL_OPCODE_WLAN_SCANRESULTSGETCOMMAND, - sizeof(_WlanGetNetworkListCommand_t), - sizeof(_WlanGetNetworkListResponse_t) -}; - -_i16 sl_WlanGetNetworkList(const _u8 Index,const _u8 Count, Sl_WlanNetworkEntry_t *pEntries) -{ - _i16 retVal = 0; - _SlWlanGetNetworkListMsg_u Msg; - _SlCmdExt_t CmdExt; - - if (Count == 0) - { - return SL_EZEROLEN; - } - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.RxPayloadLen = sizeof(Sl_WlanNetworkEntry_t)*(Count); - CmdExt.pRxPayload = (_u8 *)pEntries; - - Msg.Cmd.index = Index; - Msg.Cmd.count = Count; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlWlanGetNetworkListCtrl, &Msg, &CmdExt)); - retVal = Msg.Rsp.status; - - return (_i16)retVal; -} -#endif - - - - - -/******************************************************************************/ -/* RX filters message command response structures */ -/******************************************************************************/ - -/* Set command */ -typedef union -{ - _WlanRxFilterAddCommand_t Cmd; - _WlanRxFilterAddCommandReponse_t Rsp; -}_SlrxFilterAddMsg_u; - - -/* Set command */ -typedef union _SlRxFilterSetMsg_u -{ - _WlanRxFilterSetCommand_t Cmd; - _WlanRxFilterSetCommandReponse_t Rsp; -}_SlRxFilterSetMsg_u; - - -/* Get command */ -typedef union _SlRxFilterGetMsg_u -{ - _WlanRxFilterGetCommand_t Cmd; - _WlanRxFilterGetCommandReponse_t Rsp; -}_SlRxFilterGetMsg_u; - -#if _SL_INCLUDE_FUNC(sl_WlanRxFilterAdd) - -const _SlCmdCtrl_t _SlRxFilterAddtCmdCtrl = -{ - SL_OPCODE_WLAN_WLANRXFILTERADDCOMMAND, - sizeof(_WlanRxFilterAddCommand_t), - sizeof(_WlanRxFilterAddCommandReponse_t) -}; - - -/***************************************************************************** - RX filters -*****************************************************************************/ -SlrxFilterID_t sl_WlanRxFilterAdd( SlrxFilterRuleType_t RuleType, - SlrxFilterFlags_t FilterFlags, - const SlrxFilterRule_t* const Rule, - const SlrxFilterTrigger_t* const Trigger, - const SlrxFilterAction_t* const Action, - SlrxFilterID_t* pFilterId) -{ - - - _SlrxFilterAddMsg_u Msg; - Msg.Cmd.RuleType = RuleType; - /* filterId is zero */ - Msg.Cmd.FilterId = 0; - Msg.Cmd.FilterFlags = FilterFlags; - sl_Memcpy( &(Msg.Cmd.Rule), Rule, sizeof(SlrxFilterRule_t) ); - sl_Memcpy( &(Msg.Cmd.Trigger), Trigger, sizeof(SlrxFilterTrigger_t) ); - sl_Memcpy( &(Msg.Cmd.Action), Action, sizeof(SlrxFilterAction_t) ); - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlRxFilterAddtCmdCtrl, &Msg, NULL) ); - *pFilterId = Msg.Rsp.FilterId; - return (_i16)Msg.Rsp.Status; - -} -#endif - - - -/*******************************************************************************/ -/* RX filters */ -/*******************************************************************************/ -#if _SL_INCLUDE_FUNC(sl_WlanRxFilterSet) - -const _SlCmdCtrl_t _SlRxFilterSetCmdCtrl = -{ - SL_OPCODE_WLAN_WLANRXFILTERSETCOMMAND, - sizeof(_WlanRxFilterSetCommand_t), - sizeof(_WlanRxFilterSetCommandReponse_t) -}; - -_i16 sl_WlanRxFilterSet(const SLrxFilterOperation_t RxFilterOperation, - const _u8* const pInputBuffer, - _u16 InputbufferLength) -{ - _SlRxFilterSetMsg_u Msg; - _SlCmdExt_t CmdExt; - - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.TxPayloadLen = InputbufferLength; - CmdExt.pTxPayload = (_u8 *)pInputBuffer; - - Msg.Cmd.RxFilterOperation = RxFilterOperation; - Msg.Cmd.InputBufferLength = InputbufferLength; - - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlRxFilterSetCmdCtrl, &Msg, &CmdExt) ); - - - return (_i16)Msg.Rsp.Status; -} -#endif - -/******************************************************************************/ -/* RX filters */ -/******************************************************************************/ -#if _SL_INCLUDE_FUNC(sl_WlanRxFilterGet) - -const _SlCmdCtrl_t _SlRxFilterGetCmdCtrl = -{ - SL_OPCODE_WLAN_WLANRXFILTERGETCOMMAND, - sizeof(_WlanRxFilterGetCommand_t), - sizeof(_WlanRxFilterGetCommandReponse_t) -}; - - -_i16 sl_WlanRxFilterGet(const SLrxFilterOperation_t RxFilterOperation, - _u8* pOutputBuffer, - _u16 OutputbufferLength) -{ - _SlRxFilterGetMsg_u Msg; - _SlCmdExt_t CmdExt; - - if (OutputbufferLength == 0) - { - return SL_EZEROLEN; - } - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.RxPayloadLen = OutputbufferLength; - CmdExt.pRxPayload = (_u8 *)pOutputBuffer; - - Msg.Cmd.RxFilterOperation = RxFilterOperation; - Msg.Cmd.OutputBufferLength = OutputbufferLength; - - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlRxFilterGetCmdCtrl, &Msg, &CmdExt) ); - - if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) - { - return SL_ESMALLBUF; - } - - return (_i16)Msg.Rsp.Status; -} -#endif - -/*******************************************************************************/ -/* sl_WlanRxStatStart */ -/*******************************************************************************/ -#if _SL_INCLUDE_FUNC(sl_WlanRxStatStart) -_i16 sl_WlanRxStatStart(void) -{ - return _SlDrvBasicCmd(SL_OPCODE_WLAN_STARTRXSTATCOMMAND); -} -#endif - -#if _SL_INCLUDE_FUNC(sl_WlanRxStatStop) -_i16 sl_WlanRxStatStop(void) -{ - return _SlDrvBasicCmd(SL_OPCODE_WLAN_STOPRXSTATCOMMAND); -} -#endif - -#if _SL_INCLUDE_FUNC(sl_WlanRxStatGet) -_i16 sl_WlanRxStatGet(SlGetRxStatResponse_t *pRxStat,const _u32 Flags) -{ - _SlCmdCtrl_t CmdCtrl = {SL_OPCODE_WLAN_GETRXSTATCOMMAND, 0, sizeof(SlGetRxStatResponse_t)}; - - _SlDrvMemZero(pRxStat, sizeof(SlGetRxStatResponse_t)); - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, pRxStat, NULL)); - - return 0; -} -#endif - - - -/******************************************************************************/ -/* sl_WlanSmartConfigStop */ -/******************************************************************************/ -#if _SL_INCLUDE_FUNC(sl_WlanSmartConfigStop) -_i16 sl_WlanSmartConfigStop(void) -{ - return _SlDrvBasicCmd(SL_OPCODE_WLAN_SMART_CONFIG_STOP_COMMAND); -} -#endif - - -/******************************************************************************/ -/* sl_WlanSmartConfigStart */ -/******************************************************************************/ - - -typedef struct -{ - _WlanSmartConfigStartCommand_t Args; - _i8 Strings[3 * MAX_SMART_CONFIG_KEY]; /* public key + groupId1 key + groupId2 key */ -}_SlSmartConfigStart_t; - -typedef union -{ - _SlSmartConfigStart_t Cmd; - _BasicResponse_t Rsp; -}_SlSmartConfigStartMsg_u; - -#if _SL_INCLUDE_FUNC(sl_WlanSmartConfigStart) - -const _SlCmdCtrl_t _SlSmartConfigStartCmdCtrl = -{ - SL_OPCODE_WLAN_SMART_CONFIG_START_COMMAND, - sizeof(_SlSmartConfigStart_t), - sizeof(_BasicResponse_t) -}; - -_i16 sl_WlanSmartConfigStart( const _u32 groupIdBitmask, - const _u8 cipher, - const _u8 publicKeyLen, - const _u8 group1KeyLen, - const _u8 group2KeyLen, - const _u8* pPublicKey, - const _u8* pGroup1Key, - const _u8* pGroup2Key) -{ - _SlSmartConfigStartMsg_u Msg; - - Msg.Cmd.Args.groupIdBitmask = (_u8)groupIdBitmask; - Msg.Cmd.Args.cipher = (_u8)cipher; - Msg.Cmd.Args.publicKeyLen = (_u8)publicKeyLen; - Msg.Cmd.Args.group1KeyLen = (_u8)group1KeyLen; - Msg.Cmd.Args.group2KeyLen = (_u8)group2KeyLen; - - /* copy keys (if exist) after command (one after another) */ - sl_Memcpy(SMART_CONFIG_START_PUBLIC_KEY_STRING(&Msg), pPublicKey, publicKeyLen); - sl_Memcpy(SMART_CONFIG_START_GROUP1_KEY_STRING(&Msg), pGroup1Key, group1KeyLen); - sl_Memcpy(SMART_CONFIG_START_GROUP2_KEY_STRING(&Msg), pGroup2Key, group2KeyLen); - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSmartConfigStartCmdCtrl , &Msg, NULL)); - - return (_i16)Msg.Rsp.status; - - -} -#endif - - -/*******************************************************************************/ -/* sl_WlanSetMode */ -/*******************************************************************************/ -typedef union -{ - _WlanSetMode_t Cmd; - _BasicResponse_t Rsp; -}_SlwlanSetModeMsg_u; - -#if _SL_INCLUDE_FUNC(sl_WlanSetMode) - -const _SlCmdCtrl_t _SlWlanSetModeCmdCtrl = -{ - SL_OPCODE_WLAN_SET_MODE, - sizeof(_WlanSetMode_t), - sizeof(_BasicResponse_t) -}; - -/* possible values are: -WLAN_SET_STA_MODE = 1 -WLAN_SET_AP_MODE = 2 -WLAN_SET_P2P_MODE = 3 */ -_i16 sl_WlanSetMode(const _u8 mode) -{ - _SlwlanSetModeMsg_u Msg; - - Msg.Cmd.mode = mode; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlWlanSetModeCmdCtrl , &Msg, NULL)); - - return (_i16)Msg.Rsp.status; -} -#endif - - - - -/*******************************************************************************/ -/* sl_WlanSet */ -/* ******************************************************************************/ -typedef union -{ - _WlanCfgSetGet_t Cmd; - _BasicResponse_t Rsp; -}_SlWlanCfgSetMsg_u; - - -#if _SL_INCLUDE_FUNC(sl_WlanSet) - -const _SlCmdCtrl_t _SlWlanCfgSetCmdCtrl = -{ - SL_OPCODE_WLAN_CFG_SET, - sizeof(_WlanCfgSetGet_t), - sizeof(_BasicResponse_t) -}; - -_i16 sl_WlanSet(const _u16 ConfigId ,const _u16 ConfigOpt,const _u16 ConfigLen,const _u8 *pValues) -{ - _SlWlanCfgSetMsg_u Msg; - _SlCmdExt_t CmdExt; - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.TxPayloadLen = (ConfigLen+3) & (~3); - CmdExt.pTxPayload = (_u8 *)pValues; - - Msg.Cmd.ConfigId = ConfigId; - Msg.Cmd.ConfigLen = ConfigLen; - Msg.Cmd.ConfigOpt = ConfigOpt; - - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlWlanCfgSetCmdCtrl, &Msg, &CmdExt)); - - return (_i16)Msg.Rsp.status; -} -#endif - - -/******************************************************************************/ -/* sl_WlanGet */ -/******************************************************************************/ -typedef union -{ - _WlanCfgSetGet_t Cmd; - _WlanCfgSetGet_t Rsp; -}_SlWlanCfgMsgGet_u; - -#if _SL_INCLUDE_FUNC(sl_WlanGet) - -const _SlCmdCtrl_t _SlWlanCfgGetCmdCtrl = -{ - SL_OPCODE_WLAN_CFG_GET, - sizeof(_WlanCfgSetGet_t), - sizeof(_WlanCfgSetGet_t) -}; - -_i16 sl_WlanGet(const _u16 ConfigId, _u16 *pConfigOpt,_u16 *pConfigLen, _u8 *pValues) -{ - _SlWlanCfgMsgGet_u Msg; - _SlCmdExt_t CmdExt; - - if (*pConfigLen == 0) - { - return SL_EZEROLEN; - } - - _SlDrvResetCmdExt(&CmdExt); - CmdExt.RxPayloadLen = *pConfigLen; - CmdExt.pRxPayload = (_u8 *)pValues; - - Msg.Cmd.ConfigId = ConfigId; - if( pConfigOpt ) - { - Msg.Cmd.ConfigOpt = (_u16)*pConfigOpt; - } - VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlWlanCfgGetCmdCtrl, &Msg, &CmdExt)); - - if( pConfigOpt ) - { - *pConfigOpt = (_u8)Msg.Rsp.ConfigOpt; - } - if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) - { - *pConfigLen = (_u8)CmdExt.RxPayloadLen; - return SL_ESMALLBUF; - } - else - { - *pConfigLen = (_u8)CmdExt.ActualRxPayloadLen; - } - - - return (_i16)Msg.Rsp.Status; -} -#endif diff --git a/drivers/dht/dht.c b/drivers/dht/dht.c deleted file mode 100644 index 5d92ae39a33..00000000000 --- a/drivers/dht/dht.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 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 - -#include "py/runtime.h" -#include "py/mperrno.h" -#include "py/mphal.h" -#include "extmod/machine_pulse.h" -#include "drivers/dht/dht.h" - -STATIC mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in) { - mp_hal_pin_obj_t pin = mp_hal_get_pin_obj(pin_in); - mp_hal_pin_open_drain(pin); - - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE); - - if (bufinfo.len < 5) { - mp_raise_ValueError("buffer too small"); - } - - // issue start command - mp_hal_pin_od_high(pin); - mp_hal_delay_ms(250); - mp_hal_pin_od_low(pin); - mp_hal_delay_ms(18); - - mp_uint_t irq_state = mp_hal_quiet_timing_enter(); - - // release the line so the device can respond - mp_hal_pin_od_high(pin); - mp_hal_delay_us_fast(10); - - // wait for device to respond - mp_uint_t ticks = mp_hal_ticks_us(); - while (mp_hal_pin_read(pin) != 0) { - if ((mp_uint_t)(mp_hal_ticks_us() - ticks) > 100) { - goto timeout; - } - } - - // time pulse, should be 80us - ticks = machine_time_pulse_us(pin, 1, 150); - if ((mp_int_t)ticks < 0) { - goto timeout; - } - - // time 40 pulses for data (either 26us or 70us) - uint8_t *buf = bufinfo.buf; - for (int i = 0; i < 40; ++i) { - ticks = machine_time_pulse_us(pin, 1, 100); - if ((mp_int_t)ticks < 0) { - goto timeout; - } - buf[i / 8] = (buf[i / 8] << 1) | (ticks > 48); - } - - mp_hal_quiet_timing_exit(irq_state); - return mp_const_none; - -timeout: - mp_hal_quiet_timing_exit(irq_state); - mp_raise_OSError(MP_ETIMEDOUT); -} -MP_DEFINE_CONST_FUN_OBJ_2(dht_readinto_obj, dht_readinto); diff --git a/drivers/dht/dht.h b/drivers/dht/dht.h deleted file mode 100644 index 883e0779619..00000000000 --- a/drivers/dht/dht.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef MICROPY_INCLUDED_DRIVERS_DHT_DHT_H -#define MICROPY_INCLUDED_DRIVERS_DHT_DHT_H - -#include "py/obj.h" - -MP_DECLARE_CONST_FUN_OBJ_2(dht_readinto_obj); - -#endif // MICROPY_INCLUDED_DRIVERS_DHT_DHT_H diff --git a/drivers/dht/dht.py b/drivers/dht/dht.py deleted file mode 100644 index eed61df7c9c..00000000000 --- a/drivers/dht/dht.py +++ /dev/null @@ -1,35 +0,0 @@ -# DHT11/DHT22 driver for MicroPython on ESP8266 -# MIT license; Copyright (c) 2016 Damien P. George - -try: - from esp import dht_readinto -except: - from pyb import dht_readinto - -class DHTBase: - def __init__(self, pin): - self.pin = pin - self.buf = bytearray(5) - - def measure(self): - buf = self.buf - dht_readinto(self.pin, buf) - if (buf[0] + buf[1] + buf[2] + buf[3]) & 0xff != buf[4]: - raise Exception("checksum error") - -class DHT11(DHTBase): - def humidity(self): - return self.buf[0] - - def temperature(self): - return self.buf[2] - -class DHT22(DHTBase): - def humidity(self): - return (self.buf[0] << 8 | self.buf[1]) * 0.1 - - def temperature(self): - t = ((self.buf[2] & 0x7f) << 8 | self.buf[3]) * 0.1 - if self.buf[2] & 0x80: - t = -t - return t diff --git a/drivers/display/lcd160cr.py b/drivers/display/lcd160cr.py deleted file mode 100644 index dd9ab9985b2..00000000000 --- a/drivers/display/lcd160cr.py +++ /dev/null @@ -1,474 +0,0 @@ -# Driver for official MicroPython LCD160CR display -# MIT license; Copyright (c) 2017 Damien P. George - -from micropython import const -from utime import sleep_ms -from ustruct import calcsize, pack_into -import uerrno, machine - -# for set_orient -PORTRAIT = const(0) -LANDSCAPE = const(1) -PORTRAIT_UPSIDEDOWN = const(2) -LANDSCAPE_UPSIDEDOWN = const(3) - -# for set_startup_deco; can be or'd -STARTUP_DECO_NONE = const(0) -STARTUP_DECO_MLOGO = const(1) -STARTUP_DECO_INFO = const(2) - -_uart_baud_table = { - 2400: 0, - 4800: 1, - 9600: 2, - 19200: 3, - 38400: 4, - 57600: 5, - 115200: 6, - 230400: 7, - 460800: 8, -} - -class LCD160CR: - def __init__(self, connect=None, *, pwr=None, i2c=None, spi=None, i2c_addr=98): - if connect in ('X', 'Y', 'XY', 'YX'): - i = connect[-1] - j = connect[0] - y = j + '4' - elif connect == 'C': - i = 2 - j = 2 - y = 'A7' - else: - if pwr is None or i2c is None or spi is None: - raise ValueError('must specify valid "connect" or all of "pwr", "i2c" and "spi"') - - if pwr is None: - pwr = machine.Pin(y, machine.Pin.OUT) - if i2c is None: - i2c = machine.I2C(i, freq=1000000) - if spi is None: - spi = machine.SPI(j, baudrate=13500000, polarity=0, phase=0) - - if not pwr.value(): - pwr(1) - sleep_ms(10) - # else: - # alread have power - # lets be optimistic... - - # set connections - self.pwr = pwr - self.i2c = i2c - self.spi = spi - self.i2c_addr = i2c_addr - - # create temp buffers and memoryviews - self.buf16 = bytearray(16) - self.buf19 = bytearray(19) - self.buf = [None] * 10 - for i in range(1, 10): - self.buf[i] = memoryview(self.buf16)[0:i] - self.buf1 = self.buf[1] - self.array4 = [0, 0, 0, 0] - - # set default orientation and window - self.set_orient(PORTRAIT) - self._fcmd2b('= n: - self.i2c.readfrom_into(self.i2c_addr, buf) - return - t -= 1 - sleep_ms(1) - raise OSError(uerrno.ETIMEDOUT) - - def oflush(self, n=255): - t = 5000 - while t: - self.i2c.readfrom_into(self.i2c_addr + 1, self.buf1) - r = self.buf1[0] - if r >= n: - return - t -= 1 - machine.idle() - raise OSError(uerrno.ETIMEDOUT) - - def iflush(self): - t = 5000 - while t: - self.i2c.readfrom_into(self.i2c_addr, self.buf16) - if self.buf16[0] == 0: - return - t -= 1 - sleep_ms(1) - raise OSError(uerrno.ETIMEDOUT) - - #### MISC METHODS #### - - @staticmethod - def rgb(r, g, b): - return ((b & 0xf8) << 8) | ((g & 0xfc) << 3) | (r >> 3) - - @staticmethod - def clip_line(c, w, h): - while True: - ca = ce = 0 - if c[1] < 0: - ca |= 8 - elif c[1] > h: - ca |= 4 - if c[0] < 0: - ca |= 1 - elif c[0] > w: - ca |= 2 - if c[3] < 0: - ce |= 8 - elif c[3] > h: - ce |= 4 - if c[2] < 0: - ce |= 1 - elif c[2] > w: - ce |= 2 - if ca & ce: - return False - elif ca | ce: - ca |= ce - if ca & 1: - if c[2] < c[0]: - c[0], c[2] = c[2], c[0] - c[1], c[3] = c[3], c[1] - c[1] += ((-c[0]) * (c[3] - c[1])) // (c[2] - c[0]) - c[0] = 0 - elif ca & 2: - if c[2] < c[0]: - c[0], c[2] = c[2], c[0] - c[1], c[3] = c[3], c[1] - c[3] += ((w - 1 - c[2]) * (c[3] - c[1])) // (c[2] - c[0]) - c[2] = w - 1 - elif ca & 4: - if c[0] == c[2]: - if c[1] >= h: - c[1] = h - 1 - if c[3] >= h: - c[3] = h - 1 - else: - if c[3] < c[1]: - c[0], c[2] = c[2], c[0] - c[1], c[3] = c[3], c[1] - c[2] += ((h - 1 - c[3]) * (c[2] - c[0])) // (c[3] - c[1]) - c[3] = h - 1 - else: - if c[0] == c[2]: - if c[1] < 0: - c[1] = 0 - if c[3] < 0: - c[3] = 0 - else: - if c[3] < c[1]: - c[0], c[2] = c[2], c[0] - c[1], c[3] = c[3], c[1] - c[0] += ((-c[1]) * (c[2] - c[0])) // (c[3] - c[1]) - c[1] = 0 - else: - return True - - #### SETUP COMMANDS #### - - def set_power(self, on): - self.pwr(on) - sleep_ms(15) - - def set_orient(self, orient): - self._fcmd2('= 2: - self.i2c.readfrom_into(self.i2c_addr, self.buf[3]) - return self.buf[3][1] | self.buf[3][2] << 8 - t -= 1 - sleep_ms(1) - raise OSError(uerrno.ETIMEDOUT) - - def get_line(self, x, y, buf): - l = len(buf) // 2 - self._fcmd2b('= l: - self.i2c.readfrom_into(self.i2c_addr, buf) - return - t -= 1 - sleep_ms(1) - raise OSError(uerrno.ETIMEDOUT) - - def screen_dump(self, buf, x=0, y=0, w=None, h=None): - if w is None: - w = self.w - x - if h is None: - h = self.h - y - if w <= 127: - line = bytearray(2 * w + 1) - line2 = None - else: - # split line if more than 254 bytes needed - buflen = (w + 1) // 2 - line = bytearray(2 * buflen + 1) - line2 = memoryview(line)[:2 * (w - buflen) + 1] - for i in range(min(len(buf) // (2 * w), h)): - ix = i * w * 2 - self.get_line(x, y + i, line) - buf[ix:ix + len(line) - 1] = memoryview(line)[1:] - ix += len(line) - 1 - if line2: - self.get_line(x + buflen, y + i, line2) - buf[ix:ix + len(line2) - 1] = memoryview(line2)[1:] - ix += len(line2) - 1 - - def screen_load(self, buf): - l = self.w * self.h * 2+2 - self._fcmd2b('= 0x200: - self._send(ar[n:n + 0x200]) - n += 0x200 - else: - self._send(ar[n:]) - while n < self.w * self.h * 2: - self._send(b'\x00') - n += 1 - - #### TEXT COMMANDS #### - - def set_pos(self, x, y): - self._fcmd2('= self.w or y >= self.h: - return - elif x < 0 or y < 0: - left = top = True - if x < 0: - left = False - w += x - x = 0 - if y < 0: - top = False - h += y - y = 0 - if cmd == 0x51 or cmd == 0x72: - # draw interior - self._fcmd2b('> 7 != 0 - - def get_touch(self): - self._send(b'\x02T') # implicit LCD output flush - b = self.buf[4] - self._waitfor(3, b) - return b[1] >> 7, b[2], b[3] - - #### ADVANCED COMMANDS #### - - def set_spi_win(self, x, y, w, h): - pack_into(' 32: - raise ValueError('length must be 32 or less') - self._fcmd2(' 0xffff: - raise ValueError('length must be 65535 or less') - self.oflush() - self._fcmd2(' 0: - s = '%6.3fV' % data[i] - else: - s = '%5.1f°C' % data[i] - if lcd.h == 160: - lcd.set_font(1, bold=0, scale=1) - else: - lcd.set_font(1, bold=0, scale=1, trans=1) - lcd.set_pos(45, lcd.h-60 + i * 16) - lcd.write(s) - -def test_features(lcd, orient=lcd160cr.PORTRAIT): - # if we run on pyboard then use ADC and RTC features - try: - import pyb - adc = pyb.ADCAll(12, 0xf0000) - rtc = pyb.RTC() - except: - adc = None - rtc = None - - # set orientation and clear screen - lcd = get_lcd(lcd) - lcd.set_orient(orient) - lcd.set_pen(0, 0) - lcd.erase() - - # create M-logo - mlogo = framebuf.FrameBuffer(bytearray(17 * 17 * 2), 17, 17, framebuf.RGB565) - mlogo.fill(0) - mlogo.fill_rect(1, 1, 15, 15, 0xffffff) - mlogo.vline(4, 4, 12, 0) - mlogo.vline(8, 1, 12, 0) - mlogo.vline(12, 4, 12, 0) - mlogo.vline(14, 13, 2, 0) - - # create inline framebuf - offx = 14 - offy = 19 - w = 100 - h = 75 - fbuf = framebuf.FrameBuffer(bytearray(w * h * 2), w, h, framebuf.RGB565) - lcd.set_spi_win(offx, offy, w, h) - - # initialise loop parameters - tx = ty = 0 - t0 = time.ticks_us() - - for i in range(300): - # update position of cross-hair - t, tx2, ty2 = lcd.get_touch() - if t: - tx2 -= offx - ty2 -= offy - if tx2 >= 0 and ty2 >= 0 and tx2 < w and ty2 < h: - tx, ty = tx2, ty2 - else: - tx = (tx + 1) % w - ty = (ty + 1) % h - - # create and show the inline framebuf - fbuf.fill(lcd.rgb(128 + int(64 * math.cos(0.1 * i)), 128, 192)) - fbuf.line(w // 2, h // 2, - w // 2 + int(40 * math.cos(0.2 * i)), - h // 2 + int(40 * math.sin(0.2 * i)), - lcd.rgb(128, 255, 64)) - fbuf.hline(0, ty, w, lcd.rgb(64, 64, 64)) - fbuf.vline(tx, 0, h, lcd.rgb(64, 64, 64)) - fbuf.rect(tx - 3, ty - 3, 7, 7, lcd.rgb(64, 64, 64)) - for phase in (-0.2, 0, 0.2): - x = w // 2 - 8 + int(50 * math.cos(0.05 * i + phase)) - y = h // 2 - 8 + int(32 * math.sin(0.05 * i + phase)) - fbuf.blit(mlogo, x, y) - for j in range(-3, 3): - fbuf.text('MicroPython', - 5, h // 2 + 9 * j + int(20 * math.sin(0.1 * (i + j))), - lcd.rgb(128 + 10 * j, 0, 128 - 10 * j)) - lcd.show_framebuf(fbuf) - - # show results from the ADC - if adc: - show_adc(lcd, adc) - - # show the time - if rtc: - lcd.set_pos(2, 0) - lcd.set_font(1) - t = rtc.datetime() - lcd.write('%4d-%02d-%02d %2d:%02d:%02d.%01d' % (t[0], t[1], t[2], t[4], t[5], t[6], t[7] // 100000)) - - # compute the frame rate - t1 = time.ticks_us() - dt = time.ticks_diff(t1, t0) - t0 = t1 - - # show the frame rate - lcd.set_pos(2, 9) - lcd.write('%.2f fps' % (1000000 / dt)) - -def test_mandel(lcd, orient=lcd160cr.PORTRAIT): - # set orientation and clear screen - lcd = get_lcd(lcd) - lcd.set_orient(orient) - lcd.set_pen(0, 0xffff) - lcd.erase() - - # function to compute Mandelbrot pixels - def in_set(c): - z = 0 - for i in range(32): - z = z * z + c - if abs(z) > 100: - return i - return 0 - - # cache width and height of LCD - w = lcd.w - h = lcd.h - - # create the buffer for each line and set SPI parameters - line = bytearray(w * 2) - lcd.set_spi_win(0, 0, w, h) - spi = lcd.fast_spi() - - # draw the Mandelbrot set line-by-line - hh = ((h - 1) / 3.2) - ww = ((w - 1) / 2.4) - for v in range(h): - for u in range(w): - c = in_set((v / hh - 2.3) + (u / ww - 1.2) * 1j) - if c < 16: - rgb = c << 12 | c << 6 - else: - rgb = 0xf800 | c << 6 - line[2 * u] = rgb - line[2 * u + 1] = rgb >> 8 - spi.write(line) - -def test_all(lcd, orient=lcd160cr.PORTRAIT): - lcd = get_lcd(lcd) - test_features(lcd, orient) - test_mandel(lcd, orient) - -print('To run all tests: test_all()') -print('Individual tests are: test_features, test_mandel') -print(' argument should be a connection, eg "X", or an LCD160CR object') diff --git a/drivers/display/ssd1306.py b/drivers/display/ssd1306.py deleted file mode 100644 index 178b4911d71..00000000000 --- a/drivers/display/ssd1306.py +++ /dev/null @@ -1,147 +0,0 @@ -# MicroPython SSD1306 OLED driver, I2C and SPI interfaces - -from micropython import const -import framebuf - - -# register definitions -SET_CONTRAST = const(0x81) -SET_ENTIRE_ON = const(0xa4) -SET_NORM_INV = const(0xa6) -SET_DISP = const(0xae) -SET_MEM_ADDR = const(0x20) -SET_COL_ADDR = const(0x21) -SET_PAGE_ADDR = const(0x22) -SET_DISP_START_LINE = const(0x40) -SET_SEG_REMAP = const(0xa0) -SET_MUX_RATIO = const(0xa8) -SET_COM_OUT_DIR = const(0xc0) -SET_DISP_OFFSET = const(0xd3) -SET_COM_PIN_CFG = const(0xda) -SET_DISP_CLK_DIV = const(0xd5) -SET_PRECHARGE = const(0xd9) -SET_VCOM_DESEL = const(0xdb) -SET_CHARGE_PUMP = const(0x8d) - -# Subclassing FrameBuffer provides support for graphics primitives -# http://docs.micropython.org/en/latest/pyboard/library/framebuf.html -class SSD1306(framebuf.FrameBuffer): - def __init__(self, width, height, external_vcc): - self.width = width - self.height = height - self.external_vcc = external_vcc - self.pages = self.height // 8 - self.buffer = bytearray(self.pages * self.width) - super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB) - self.init_display() - - def init_display(self): - for cmd in ( - SET_DISP | 0x00, # off - # address setting - SET_MEM_ADDR, 0x00, # horizontal - # resolution and layout - SET_DISP_START_LINE | 0x00, - SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0 - SET_MUX_RATIO, self.height - 1, - SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0 - SET_DISP_OFFSET, 0x00, - SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12, - # timing and driving scheme - SET_DISP_CLK_DIV, 0x80, - SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1, - SET_VCOM_DESEL, 0x30, # 0.83*Vcc - # display - SET_CONTRAST, 0xff, # maximum - SET_ENTIRE_ON, # output follows RAM contents - SET_NORM_INV, # not inverted - # charge pump - SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14, - SET_DISP | 0x01): # on - self.write_cmd(cmd) - self.fill(0) - self.show() - - def poweroff(self): - self.write_cmd(SET_DISP | 0x00) - - def poweron(self): - self.write_cmd(SET_DISP | 0x01) - - def contrast(self, contrast): - self.write_cmd(SET_CONTRAST) - self.write_cmd(contrast) - - def invert(self, invert): - self.write_cmd(SET_NORM_INV | (invert & 1)) - - def show(self): - x0 = 0 - x1 = self.width - 1 - if self.width == 64: - # displays with width of 64 pixels are shifted by 32 - x0 += 32 - x1 += 32 - self.write_cmd(SET_COL_ADDR) - self.write_cmd(x0) - self.write_cmd(x1) - self.write_cmd(SET_PAGE_ADDR) - self.write_cmd(0) - self.write_cmd(self.pages - 1) - self.write_data(self.buffer) - - -class SSD1306_I2C(SSD1306): - def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False): - self.i2c = i2c - self.addr = addr - self.temp = bytearray(2) - super().__init__(width, height, external_vcc) - - def write_cmd(self, cmd): - self.temp[0] = 0x80 # Co=1, D/C#=0 - self.temp[1] = cmd - self.i2c.writeto(self.addr, self.temp) - - def write_data(self, buf): - self.temp[0] = self.addr << 1 - self.temp[1] = 0x40 # Co=0, D/C#=1 - self.i2c.start() - self.i2c.write(self.temp) - self.i2c.write(buf) - self.i2c.stop() - - -class SSD1306_SPI(SSD1306): - def __init__(self, width, height, spi, dc, res, cs, external_vcc=False): - self.rate = 10 * 1024 * 1024 - dc.init(dc.OUT, value=0) - res.init(res.OUT, value=0) - cs.init(cs.OUT, value=1) - self.spi = spi - self.dc = dc - self.res = res - self.cs = cs - import time - self.res(1) - time.sleep_ms(1) - self.res(0) - time.sleep_ms(10) - self.res(1) - super().__init__(width, height, external_vcc) - - def write_cmd(self, cmd): - self.spi.init(baudrate=self.rate, polarity=0, phase=0) - self.cs(1) - self.dc(0) - self.cs(0) - self.spi.write(bytearray([cmd])) - self.cs(1) - - def write_data(self, buf): - self.spi.init(baudrate=self.rate, polarity=0, phase=0) - self.cs(1) - self.dc(1) - self.cs(0) - self.spi.write(buf) - self.cs(1) diff --git a/drivers/memory/spiflash.c b/drivers/memory/spiflash.c deleted file mode 100644 index c0b55591bee..00000000000 --- a/drivers/memory/spiflash.c +++ /dev/null @@ -1,489 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016-2018 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 -#include - -#include "py/mperrno.h" -#include "py/mphal.h" -#include "drivers/memory/spiflash.h" - -#define QSPI_QE_MASK (0x02) -#define USE_WR_DELAY (1) - -#define CMD_WRSR (0x01) -#define CMD_WRITE (0x02) -#define CMD_READ (0x03) -#define CMD_RDSR (0x05) -#define CMD_WREN (0x06) -#define CMD_SEC_ERASE (0x20) -#define CMD_RDCR (0x35) -#define CMD_RD_DEVID (0x9f) -#define CMD_CHIP_ERASE (0xc7) -#define CMD_C4READ (0xeb) - -#define WAIT_SR_TIMEOUT (1000000) - -#define PAGE_SIZE (256) // maximum bytes we can write in one SPI transfer -#define SECTOR_SIZE MP_SPIFLASH_ERASE_BLOCK_SIZE - -STATIC void mp_spiflash_acquire_bus(mp_spiflash_t *self) { - const mp_spiflash_config_t *c = self->config; - if (c->bus_kind == MP_SPIFLASH_BUS_QSPI) { - c->bus.u_qspi.proto->ioctl(c->bus.u_qspi.data, MP_QSPI_IOCTL_BUS_ACQUIRE); - } -} - -STATIC void mp_spiflash_release_bus(mp_spiflash_t *self) { - const mp_spiflash_config_t *c = self->config; - if (c->bus_kind == MP_SPIFLASH_BUS_QSPI) { - c->bus.u_qspi.proto->ioctl(c->bus.u_qspi.data, MP_QSPI_IOCTL_BUS_RELEASE); - } -} - -STATIC void mp_spiflash_write_cmd_data(mp_spiflash_t *self, uint8_t cmd, size_t len, uint32_t data) { - const mp_spiflash_config_t *c = self->config; - if (c->bus_kind == MP_SPIFLASH_BUS_SPI) { - // Note: len/data are unused for standard SPI - mp_hal_pin_write(c->bus.u_spi.cs, 0); - c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 1, &cmd, NULL); - mp_hal_pin_write(c->bus.u_spi.cs, 1); - } else { - c->bus.u_qspi.proto->write_cmd_data(c->bus.u_qspi.data, cmd, len, data); - } -} - -STATIC void mp_spiflash_write_cmd_addr_data(mp_spiflash_t *self, uint8_t cmd, uint32_t addr, size_t len, const uint8_t *src) { - const mp_spiflash_config_t *c = self->config; - if (c->bus_kind == MP_SPIFLASH_BUS_SPI) { - uint8_t buf[4] = {cmd, addr >> 16, addr >> 8, addr}; - mp_hal_pin_write(c->bus.u_spi.cs, 0); - c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 4, buf, NULL); - if (len) { - c->bus.u_spi.proto->transfer(c->bus.u_spi.data, len, src, NULL); - } - mp_hal_pin_write(c->bus.u_spi.cs, 1); - } else { - c->bus.u_qspi.proto->write_cmd_addr_data(c->bus.u_qspi.data, cmd, addr, len, src); - } -} - -STATIC uint32_t mp_spiflash_read_cmd(mp_spiflash_t *self, uint8_t cmd, size_t len) { - const mp_spiflash_config_t *c = self->config; - if (c->bus_kind == MP_SPIFLASH_BUS_SPI) { - uint32_t buf; - mp_hal_pin_write(c->bus.u_spi.cs, 0); - c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 1, &cmd, NULL); - c->bus.u_spi.proto->transfer(c->bus.u_spi.data, len, (void*)&buf, (void*)&buf); - mp_hal_pin_write(c->bus.u_spi.cs, 1); - return buf; - } else { - return c->bus.u_qspi.proto->read_cmd(c->bus.u_qspi.data, cmd, len); - } -} - -STATIC void mp_spiflash_read_data(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) { - const mp_spiflash_config_t *c = self->config; - if (c->bus_kind == MP_SPIFLASH_BUS_SPI) { - uint8_t buf[4] = {CMD_READ, addr >> 16, addr >> 8, addr}; - mp_hal_pin_write(c->bus.u_spi.cs, 0); - c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 4, buf, NULL); - c->bus.u_spi.proto->transfer(c->bus.u_spi.data, len, dest, dest); - mp_hal_pin_write(c->bus.u_spi.cs, 1); - } else { - c->bus.u_qspi.proto->read_cmd_qaddr_qdata(c->bus.u_qspi.data, CMD_C4READ, addr, len, dest); - } -} - -STATIC void mp_spiflash_write_cmd(mp_spiflash_t *self, uint8_t cmd) { - mp_spiflash_write_cmd_data(self, cmd, 0, 0); -} - -STATIC void mp_spiflash_write_cmd_addr(mp_spiflash_t *self, uint8_t cmd, uint32_t addr) { - mp_spiflash_write_cmd_addr_data(self, cmd, addr, 0, NULL); -} - -STATIC int mp_spiflash_wait_sr(mp_spiflash_t *self, uint8_t mask, uint8_t val, uint32_t timeout) { - uint8_t sr; - for (; timeout; --timeout) { - sr = mp_spiflash_read_cmd(self, CMD_RDSR, 1); - if ((sr & mask) == val) { - break; - } - } - if ((sr & mask) == val) { - return 0; // success - } else if (timeout == 0) { - return -MP_ETIMEDOUT; - } else { - return -MP_EIO; - } -} - -STATIC int mp_spiflash_wait_wel1(mp_spiflash_t *self) { - return mp_spiflash_wait_sr(self, 2, 2, WAIT_SR_TIMEOUT); -} - -STATIC int mp_spiflash_wait_wip0(mp_spiflash_t *self) { - return mp_spiflash_wait_sr(self, 1, 0, WAIT_SR_TIMEOUT); -} - -void mp_spiflash_init(mp_spiflash_t *self) { - self->flags = 0; - - if (self->config->bus_kind == MP_SPIFLASH_BUS_SPI) { - mp_hal_pin_write(self->config->bus.u_spi.cs, 1); - mp_hal_pin_output(self->config->bus.u_spi.cs); - self->config->bus.u_spi.proto->ioctl(self->config->bus.u_spi.data, MP_SPI_IOCTL_INIT); - } else { - self->config->bus.u_qspi.proto->ioctl(self->config->bus.u_qspi.data, MP_QSPI_IOCTL_INIT); - } - - mp_spiflash_acquire_bus(self); - - #if defined(CHECK_DEVID) - // Validate device id - uint32_t devid = mp_spiflash_read_cmd(self, CMD_RD_DEVID, 3); - if (devid != CHECK_DEVID) { - return 0; - } - #endif - - if (self->config->bus_kind == MP_SPIFLASH_BUS_QSPI) { - // Set QE bit - uint32_t data = (mp_spiflash_read_cmd(self, CMD_RDSR, 1) & 0xff) - | (mp_spiflash_read_cmd(self, CMD_RDCR, 1) & 0xff) << 8; - if (!(data & (QSPI_QE_MASK << 8))) { - data |= QSPI_QE_MASK << 8; - mp_spiflash_write_cmd(self, CMD_WREN); - mp_spiflash_write_cmd_data(self, CMD_WRSR, 2, data); - mp_spiflash_wait_wip0(self); - } - } - - mp_spiflash_release_bus(self); -} - -STATIC int mp_spiflash_erase_block_internal(mp_spiflash_t *self, uint32_t addr) { - // enable writes - mp_spiflash_write_cmd(self, CMD_WREN); - - // wait WEL=1 - int ret = mp_spiflash_wait_wel1(self); - if (ret != 0) { - return ret; - } - - // erase the sector - mp_spiflash_write_cmd_addr(self, CMD_SEC_ERASE, addr); - - // wait WIP=0 - return mp_spiflash_wait_wip0(self); -} - -STATIC int mp_spiflash_write_page(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src) { - // enable writes - mp_spiflash_write_cmd(self, CMD_WREN); - - // wait WEL=1 - int ret = mp_spiflash_wait_wel1(self); - if (ret != 0) { - return ret; - } - - // write the page - mp_spiflash_write_cmd_addr_data(self, CMD_WRITE, addr, len, src); - - // wait WIP=0 - return mp_spiflash_wait_wip0(self); -} - -/******************************************************************************/ -// Interface functions that go direct to the SPI flash device - -int mp_spiflash_erase_block(mp_spiflash_t *self, uint32_t addr) { - mp_spiflash_acquire_bus(self); - int ret = mp_spiflash_erase_block_internal(self, addr); - mp_spiflash_release_bus(self); - return ret; -} - -void mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) { - if (len == 0) { - return; - } - mp_spiflash_acquire_bus(self); - mp_spiflash_read_data(self, addr, len, dest); - mp_spiflash_release_bus(self); -} - -int mp_spiflash_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src) { - mp_spiflash_acquire_bus(self); - int ret = 0; - uint32_t offset = addr & (PAGE_SIZE - 1); - while (len) { - size_t rest = PAGE_SIZE - offset; - if (rest > len) { - rest = len; - } - ret = mp_spiflash_write_page(self, addr, rest, src); - if (ret != 0) { - break; - } - len -= rest; - addr += rest; - src += rest; - offset = 0; - } - mp_spiflash_release_bus(self); - return ret; -} - -/******************************************************************************/ -// Interface functions that use the cache - -void mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) { - if (len == 0) { - return; - } - mp_spiflash_acquire_bus(self); - mp_spiflash_cache_t *cache = self->config->cache; - if (cache->user == self && cache->block != 0xffffffff) { - uint32_t bis = addr / SECTOR_SIZE; - uint32_t bie = (addr + len - 1) / SECTOR_SIZE; - if (bis <= cache->block && cache->block <= bie) { - // Read straddles current buffer - size_t rest = 0; - if (bis < cache->block) { - // Read direct from flash for first part - rest = cache->block * SECTOR_SIZE - addr; - mp_spiflash_read_data(self, addr, rest, dest); - len -= rest; - dest += rest; - addr += rest; - } - uint32_t offset = addr & (SECTOR_SIZE - 1); - rest = SECTOR_SIZE - offset; - if (rest > len) { - rest = len; - } - memcpy(dest, &cache->buf[offset], rest); - len -= rest; - if (len == 0) { - mp_spiflash_release_bus(self); - return; - } - dest += rest; - addr += rest; - } - } - // Read rest direct from flash - mp_spiflash_read_data(self, addr, len, dest); - mp_spiflash_release_bus(self); -} - -STATIC void mp_spiflash_cache_flush_internal(mp_spiflash_t *self) { - #if USE_WR_DELAY - if (!(self->flags & 1)) { - return; - } - - self->flags &= ~1; - - mp_spiflash_cache_t *cache = self->config->cache; - - // Erase sector - int ret = mp_spiflash_erase_block_internal(self, cache->block * SECTOR_SIZE); - if (ret != 0) { - return; - } - - // Write - for (int i = 0; i < 16; i += 1) { - uint32_t addr = cache->block * SECTOR_SIZE + i * PAGE_SIZE; - int ret = mp_spiflash_write_page(self, addr, PAGE_SIZE, cache->buf + i * PAGE_SIZE); - if (ret != 0) { - return; - } - } - #endif -} - -void mp_spiflash_cache_flush(mp_spiflash_t *self) { - mp_spiflash_acquire_bus(self); - mp_spiflash_cache_flush_internal(self); - mp_spiflash_release_bus(self); -} - -STATIC int mp_spiflash_cached_write_part(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src) { - // Align to 4096 sector - uint32_t offset = addr & 0xfff; - uint32_t sec = addr >> 12; - addr = sec << 12; - - // Restriction for now, so we don't need to erase multiple pages - if (offset + len > SECTOR_SIZE) { - printf("mp_spiflash_cached_write_part: len is too large\n"); - return -MP_EIO; - } - - mp_spiflash_cache_t *cache = self->config->cache; - - // Acquire the sector buffer - if (cache->user != self) { - if (cache->user != NULL) { - mp_spiflash_cache_flush(cache->user); - } - cache->user = self; - cache->block = 0xffffffff; - } - - if (cache->block != sec) { - // Read sector - #if USE_WR_DELAY - if (cache->block != 0xffffffff) { - mp_spiflash_cache_flush_internal(self); - } - #endif - mp_spiflash_read_data(self, addr, SECTOR_SIZE, cache->buf); - } - - #if USE_WR_DELAY - - cache->block = sec; - // Just copy to buffer - memcpy(cache->buf + offset, src, len); - // And mark dirty - self->flags |= 1; - - #else - - uint32_t dirty = 0; - for (size_t i = 0; i < len; ++i) { - if (cache->buf[offset + i] != src[i]) { - if (cache->buf[offset + i] != 0xff) { - // Erase sector - int ret = mp_spiflash_erase_block_internal(self, addr); - if (ret != 0) { - return ret; - } - dirty = 0xffff; - break; - } else { - dirty |= (1 << ((offset + i) >> 8)); - } - } - } - - cache->block = sec; - // Copy new block into buffer - memcpy(cache->buf + offset, src, len); - - // Write sector in pages of 256 bytes - for (size_t i = 0; i < 16; ++i) { - if (dirty & (1 << i)) { - int ret = mp_spiflash_write_page(self, addr + i * PAGE_SIZE, PAGE_SIZE, cache->buf + i * PAGE_SIZE); - if (ret != 0) { - return ret; - } - } - } - - #endif - - return 0; // success -} - -int mp_spiflash_cached_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src) { - uint32_t bis = addr / SECTOR_SIZE; - uint32_t bie = (addr + len - 1) / SECTOR_SIZE; - - mp_spiflash_acquire_bus(self); - - mp_spiflash_cache_t *cache = self->config->cache; - if (cache->user == self && bis <= cache->block && bie >= cache->block) { - // Write straddles current buffer - uint32_t pre; - uint32_t offset; - if (cache->block * SECTOR_SIZE >= addr) { - pre = cache->block * SECTOR_SIZE - addr; - offset = 0; - } else { - pre = 0; - offset = addr - cache->block * SECTOR_SIZE; - } - - // Write buffered part first - uint32_t len_in_buf = len - pre; - len = 0; - if (len_in_buf > SECTOR_SIZE - offset) { - len = len_in_buf - (SECTOR_SIZE - offset); - len_in_buf = SECTOR_SIZE - offset; - } - memcpy(&cache->buf[offset], &src[pre], len_in_buf); - self->flags |= 1; // Mark dirty - - // Write part before buffer sector - while (pre) { - int rest = pre & (SECTOR_SIZE - 1); - if (rest == 0) { - rest = SECTOR_SIZE; - } - int ret = mp_spiflash_cached_write_part(self, addr, rest, src); - if (ret != 0) { - mp_spiflash_release_bus(self); - return ret; - } - src += rest; - addr += rest; - pre -= rest; - } - src += len_in_buf; - addr += len_in_buf; - - // Fall through to write remaining part - } - - uint32_t offset = addr & (SECTOR_SIZE - 1); - while (len) { - int rest = SECTOR_SIZE - offset; - if (rest > len) { - rest = len; - } - int ret = mp_spiflash_cached_write_part(self, addr, rest, src); - if (ret != 0) { - mp_spiflash_release_bus(self); - return ret; - } - len -= rest; - addr += rest; - src += rest; - offset = 0; - } - - mp_spiflash_release_bus(self); - return 0; -} diff --git a/drivers/memory/spiflash.h b/drivers/memory/spiflash.h deleted file mode 100644 index a5b8a1dcaeb..00000000000 --- a/drivers/memory/spiflash.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016-2018 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. - */ -#ifndef MICROPY_INCLUDED_DRIVERS_MEMORY_SPIFLASH_H -#define MICROPY_INCLUDED_DRIVERS_MEMORY_SPIFLASH_H - -#include "drivers/bus/spi.h" -#include "drivers/bus/qspi.h" - -#define MP_SPIFLASH_ERASE_BLOCK_SIZE (4096) // must be a power of 2 - -enum { - MP_SPIFLASH_BUS_SPI, - MP_SPIFLASH_BUS_QSPI, -}; - -struct _mp_spiflash_t; - -// A cache must be provided by the user in the config struct. The same cache -// struct can be shared by multiple SPI flash instances. -typedef struct _mp_spiflash_cache_t { - uint8_t buf[MP_SPIFLASH_ERASE_BLOCK_SIZE] __attribute__((aligned(4))); - struct _mp_spiflash_t *user; // current user of buf, for shared use - uint32_t block; // current block stored in buf; 0xffffffff if invalid -} mp_spiflash_cache_t; - -typedef struct _mp_spiflash_config_t { - uint32_t bus_kind; - union { - struct { - mp_hal_pin_obj_t cs; - void *data; - const mp_spi_proto_t *proto; - } u_spi; - struct { - void *data; - const mp_qspi_proto_t *proto; - } u_qspi; - } bus; - mp_spiflash_cache_t *cache; // can be NULL if cache functions not used -} mp_spiflash_config_t; - -typedef struct _mp_spiflash_t { - const mp_spiflash_config_t *config; - volatile uint32_t flags; -} mp_spiflash_t; - -void mp_spiflash_init(mp_spiflash_t *self); - -// These functions go direct to the SPI flash device -int mp_spiflash_erase_block(mp_spiflash_t *self, uint32_t addr); -void mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest); -int mp_spiflash_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src); - -// These functions use the cache (which must already be configured) -void mp_spiflash_cache_flush(mp_spiflash_t *self); -void mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest); -int mp_spiflash_cached_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src); - -#endif // MICROPY_INCLUDED_DRIVERS_MEMORY_SPIFLASH_H diff --git a/drivers/nrf24l01/nrf24l01.py b/drivers/nrf24l01/nrf24l01.py deleted file mode 100644 index a95d2b5cac3..00000000000 --- a/drivers/nrf24l01/nrf24l01.py +++ /dev/null @@ -1,251 +0,0 @@ -"""NRF24L01 driver for MicroPython -""" - -from micropython import const -import utime - -# nRF24L01+ registers -CONFIG = const(0x00) -EN_RXADDR = const(0x02) -SETUP_AW = const(0x03) -SETUP_RETR = const(0x04) -RF_CH = const(0x05) -RF_SETUP = const(0x06) -STATUS = const(0x07) -RX_ADDR_P0 = const(0x0a) -TX_ADDR = const(0x10) -RX_PW_P0 = const(0x11) -FIFO_STATUS = const(0x17) -DYNPD = const(0x1c) - -# CONFIG register -EN_CRC = const(0x08) # enable CRC -CRCO = const(0x04) # CRC encoding scheme; 0=1 byte, 1=2 bytes -PWR_UP = const(0x02) # 1=power up, 0=power down -PRIM_RX = const(0x01) # RX/TX control; 0=PTX, 1=PRX - -# RF_SETUP register -POWER_0 = const(0x00) # -18 dBm -POWER_1 = const(0x02) # -12 dBm -POWER_2 = const(0x04) # -6 dBm -POWER_3 = const(0x06) # 0 dBm -SPEED_1M = const(0x00) -SPEED_2M = const(0x08) -SPEED_250K = const(0x20) - -# STATUS register -RX_DR = const(0x40) # RX data ready; write 1 to clear -TX_DS = const(0x20) # TX data sent; write 1 to clear -MAX_RT = const(0x10) # max retransmits reached; write 1 to clear - -# FIFO_STATUS register -RX_EMPTY = const(0x01) # 1 if RX FIFO is empty - -# constants for instructions -R_RX_PL_WID = const(0x60) # read RX payload width -R_RX_PAYLOAD = const(0x61) # read RX payload -W_TX_PAYLOAD = const(0xa0) # write TX payload -FLUSH_TX = const(0xe1) # flush TX FIFO -FLUSH_RX = const(0xe2) # flush RX FIFO -NOP = const(0xff) # use to read STATUS register - -class NRF24L01: - def __init__(self, spi, cs, ce, channel=46, payload_size=16): - assert payload_size <= 32 - - self.buf = bytearray(1) - - # store the pins - self.spi = spi - self.cs = cs - self.ce = ce - - # init the SPI bus and pins - self.init_spi(4000000) - - # reset everything - ce.init(ce.OUT, value=0) - cs.init(cs.OUT, value=1) - - self.payload_size = payload_size - self.pipe0_read_addr = None - utime.sleep_ms(5) - - # set address width to 5 bytes and check for device present - self.reg_write(SETUP_AW, 0b11) - if self.reg_read(SETUP_AW) != 0b11: - raise OSError("nRF24L01+ Hardware not responding") - - # disable dynamic payloads - self.reg_write(DYNPD, 0) - - # auto retransmit delay: 1750us - # auto retransmit count: 8 - self.reg_write(SETUP_RETR, (6 << 4) | 8) - - # set rf power and speed - self.set_power_speed(POWER_3, SPEED_250K) # Best for point to point links - - # init CRC - self.set_crc(2) - - # clear status flags - self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT) - - # set channel - self.set_channel(channel) - - # flush buffers - self.flush_rx() - self.flush_tx() - - def init_spi(self, baudrate): - try: - master = self.spi.MASTER - except AttributeError: - self.spi.init(baudrate=baudrate, polarity=0, phase=0) - else: - self.spi.init(master, baudrate=baudrate, polarity=0, phase=0) - - def reg_read(self, reg): - self.cs(0) - self.spi.readinto(self.buf, reg) - self.spi.readinto(self.buf) - self.cs(1) - return self.buf[0] - - def reg_write_bytes(self, reg, buf): - self.cs(0) - self.spi.readinto(self.buf, 0x20 | reg) - self.spi.write(buf) - self.cs(1) - return self.buf[0] - - def reg_write(self, reg, value): - self.cs(0) - self.spi.readinto(self.buf, 0x20 | reg) - ret = self.buf[0] - self.spi.readinto(self.buf, value) - self.cs(1) - return ret - - def flush_rx(self): - self.cs(0) - self.spi.readinto(self.buf, FLUSH_RX) - self.cs(1) - - def flush_tx(self): - self.cs(0) - self.spi.readinto(self.buf, FLUSH_TX) - self.cs(1) - - # power is one of POWER_x defines; speed is one of SPEED_x defines - def set_power_speed(self, power, speed): - setup = self.reg_read(RF_SETUP) & 0b11010001 - self.reg_write(RF_SETUP, setup | power | speed) - - # length in bytes: 0, 1 or 2 - def set_crc(self, length): - config = self.reg_read(CONFIG) & ~(CRCO | EN_CRC) - if length == 0: - pass - elif length == 1: - config |= EN_CRC - else: - config |= EN_CRC | CRCO - self.reg_write(CONFIG, config) - - def set_channel(self, channel): - self.reg_write(RF_CH, min(channel, 125)) - - # address should be a bytes object 5 bytes long - def open_tx_pipe(self, address): - assert len(address) == 5 - self.reg_write_bytes(RX_ADDR_P0, address) - self.reg_write_bytes(TX_ADDR, address) - self.reg_write(RX_PW_P0, self.payload_size) - - # address should be a bytes object 5 bytes long - # pipe 0 and 1 have 5 byte address - # pipes 2-5 use same 4 most-significant bytes as pipe 1, plus 1 extra byte - def open_rx_pipe(self, pipe_id, address): - assert len(address) == 5 - assert 0 <= pipe_id <= 5 - if pipe_id == 0: - self.pipe0_read_addr = address - if pipe_id < 2: - self.reg_write_bytes(RX_ADDR_P0 + pipe_id, address) - else: - self.reg_write(RX_ADDR_P0 + pipe_id, address[0]) - self.reg_write(RX_PW_P0 + pipe_id, self.payload_size) - self.reg_write(EN_RXADDR, self.reg_read(EN_RXADDR) | (1 << pipe_id)) - - def start_listening(self): - self.reg_write(CONFIG, self.reg_read(CONFIG) | PWR_UP | PRIM_RX) - self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT) - - if self.pipe0_read_addr is not None: - self.reg_write_bytes(RX_ADDR_P0, self.pipe0_read_addr) - - self.flush_rx() - self.flush_tx() - self.ce(1) - utime.sleep_us(130) - - def stop_listening(self): - self.ce(0) - self.flush_tx() - self.flush_rx() - - # returns True if any data available to recv - def any(self): - return not bool(self.reg_read(FIFO_STATUS) & RX_EMPTY) - - def recv(self): - # get the data - self.cs(0) - self.spi.readinto(self.buf, R_RX_PAYLOAD) - buf = self.spi.read(self.payload_size) - self.cs(1) - # clear RX ready flag - self.reg_write(STATUS, RX_DR) - - return buf - - # blocking wait for tx complete - def send(self, buf, timeout=500): - self.send_start(buf) - start = utime.ticks_ms() - result = None - while result is None and utime.ticks_diff(utime.ticks_ms(), start) < timeout: - result = self.send_done() # 1 == success, 2 == fail - if result == 2: - raise OSError("send failed") - - # non-blocking tx - def send_start(self, buf): - # power up - self.reg_write(CONFIG, (self.reg_read(CONFIG) | PWR_UP) & ~PRIM_RX) - utime.sleep_us(150) - # send the data - self.cs(0) - self.spi.readinto(self.buf, W_TX_PAYLOAD) - self.spi.write(buf) - if len(buf) < self.payload_size: - self.spi.write(b'\x00' * (self.payload_size - len(buf))) # pad out data - self.cs(1) - - # enable the chip so it can send the data - self.ce(1) - utime.sleep_us(15) # needs to be >10us - self.ce(0) - - # returns None if send still in progress, 1 for success, 2 for fail - def send_done(self): - if not (self.reg_read(STATUS) & (TX_DS | MAX_RT)): - return None # tx not finished - - # either finished or failed: get and clear status flags, power down - status = self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT) - self.reg_write(CONFIG, self.reg_read(CONFIG) & ~PWR_UP) - return 1 if status & TX_DS else 2 diff --git a/drivers/nrf24l01/nrf24l01test.py b/drivers/nrf24l01/nrf24l01test.py deleted file mode 100644 index 876b2bbfa20..00000000000 --- a/drivers/nrf24l01/nrf24l01test.py +++ /dev/null @@ -1,138 +0,0 @@ -"""Test for nrf24l01 module. Portable between MicroPython targets.""" - -import sys -import ustruct as struct -import utime -from machine import Pin, SPI -from nrf24l01 import NRF24L01 -from micropython import const - -# Slave pause between receiving data and checking for further packets. -_RX_POLL_DELAY = const(15) -# Slave pauses an additional _SLAVE_SEND_DELAY ms after receiving data and before -# transmitting to allow the (remote) master time to get into receive mode. The -# master may be a slow device. Value tested with Pyboard, ESP32 and ESP8266. -_SLAVE_SEND_DELAY = const(10) - -if sys.platform == 'pyboard': - cfg = {'spi': 2, 'miso': 'Y7', 'mosi': 'Y8', 'sck': 'Y6', 'csn': 'Y5', 'ce': 'Y4'} -elif sys.platform == 'esp8266': # Hardware SPI - cfg = {'spi': 1, 'miso': 12, 'mosi': 13, 'sck': 14, 'csn': 4, 'ce': 5} -elif sys.platform == 'esp32': # Software SPI - cfg = {'spi': -1, 'miso': 32, 'mosi': 33, 'sck': 25, 'csn': 26, 'ce': 27} -else: - raise ValueError('Unsupported platform {}'.format(sys.platform)) - -pipes = (b'\xf0\xf0\xf0\xf0\xe1', b'\xf0\xf0\xf0\xf0\xd2') - -def master(): - csn = Pin(cfg['csn'], mode=Pin.OUT, value=1) - ce = Pin(cfg['ce'], mode=Pin.OUT, value=0) - if cfg['spi'] == -1: - spi = SPI(-1, sck=Pin(cfg['sck']), mosi=Pin(cfg['mosi']), miso=Pin(cfg['miso'])) - nrf = NRF24L01(spi, csn, ce, payload_size=8) - else: - nrf = NRF24L01(SPI(cfg['spi']), csn, ce, payload_size=8) - - nrf.open_tx_pipe(pipes[0]) - nrf.open_rx_pipe(1, pipes[1]) - nrf.start_listening() - - num_needed = 16 - num_successes = 0 - num_failures = 0 - led_state = 0 - - print('NRF24L01 master mode, sending %d packets...' % num_needed) - - while num_successes < num_needed and num_failures < num_needed: - # stop listening and send packet - nrf.stop_listening() - millis = utime.ticks_ms() - led_state = max(1, (led_state << 1) & 0x0f) - print('sending:', millis, led_state) - try: - nrf.send(struct.pack('ii', millis, led_state)) - except OSError: - pass - - # start listening again - nrf.start_listening() - - # wait for response, with 250ms timeout - start_time = utime.ticks_ms() - timeout = False - while not nrf.any() and not timeout: - if utime.ticks_diff(utime.ticks_ms(), start_time) > 250: - timeout = True - - if timeout: - print('failed, response timed out') - num_failures += 1 - - else: - # recv packet - got_millis, = struct.unpack('i', nrf.recv()) - - # print response and round-trip delay - print('got response:', got_millis, '(delay', utime.ticks_diff(utime.ticks_ms(), got_millis), 'ms)') - num_successes += 1 - - # delay then loop - utime.sleep_ms(250) - - print('master finished sending; successes=%d, failures=%d' % (num_successes, num_failures)) - -def slave(): - csn = Pin(cfg['csn'], mode=Pin.OUT, value=1) - ce = Pin(cfg['ce'], mode=Pin.OUT, value=0) - if cfg['spi'] == -1: - spi = SPI(-1, sck=Pin(cfg['sck']), mosi=Pin(cfg['mosi']), miso=Pin(cfg['miso'])) - nrf = NRF24L01(spi, csn, ce, payload_size=8) - else: - nrf = NRF24L01(SPI(cfg['spi']), csn, ce, payload_size=8) - - nrf.open_tx_pipe(pipes[1]) - nrf.open_rx_pipe(1, pipes[0]) - nrf.start_listening() - - print('NRF24L01 slave mode, waiting for packets... (ctrl-C to stop)') - - while True: - if nrf.any(): - while nrf.any(): - buf = nrf.recv() - millis, led_state = struct.unpack('ii', buf) - print('received:', millis, led_state) - for led in leds: - if led_state & 1: - led.on() - else: - led.off() - led_state >>= 1 - utime.sleep_ms(_RX_POLL_DELAY) - - # Give master time to get into receive mode. - utime.sleep_ms(_SLAVE_SEND_DELAY) - nrf.stop_listening() - try: - nrf.send(struct.pack('i', millis)) - except OSError: - pass - print('sent response') - nrf.start_listening() - -try: - import pyb - leds = [pyb.LED(i + 1) for i in range(4)] -except: - leds = [] - -print('NRF24L01 test module loaded') -print('NRF24L01 pinout for test:') -print(' CE on', cfg['ce']) -print(' CSN on', cfg['csn']) -print(' SCK on', cfg['sck']) -print(' MISO on', cfg['miso']) -print(' MOSI on', cfg['mosi']) -print('run nrf24l01test.slave() on slave, then nrf24l01test.master() on master') diff --git a/drivers/onewire/ds18x20.py b/drivers/onewire/ds18x20.py deleted file mode 100644 index bf060948359..00000000000 --- a/drivers/onewire/ds18x20.py +++ /dev/null @@ -1,51 +0,0 @@ -# DS18x20 temperature sensor driver for MicroPython. -# MIT license; Copyright (c) 2016 Damien P. George - -from micropython import const - -_CONVERT = const(0x44) -_RD_SCRATCH = const(0xbe) -_WR_SCRATCH = const(0x4e) - -class DS18X20: - def __init__(self, onewire): - self.ow = onewire - self.buf = bytearray(9) - - def scan(self): - return [rom for rom in self.ow.scan() if rom[0] == 0x10 or rom[0] == 0x28] - - def convert_temp(self): - self.ow.reset(True) - self.ow.writebyte(self.ow.SKIP_ROM) - self.ow.writebyte(_CONVERT) - - def read_scratch(self, rom): - self.ow.reset(True) - self.ow.select_rom(rom) - self.ow.writebyte(_RD_SCRATCH) - self.ow.readinto(self.buf) - if self.ow.crc8(self.buf): - raise Exception('CRC error') - return self.buf - - def write_scratch(self, rom, buf): - self.ow.reset(True) - self.ow.select_rom(rom) - self.ow.writebyte(_WR_SCRATCH) - self.ow.write(buf) - - def read_temp(self, rom): - buf = self.read_scratch(rom) - if rom[0] == 0x10: - if buf[1]: - t = buf[0] >> 1 | 0x80 - t = -((~t + 1) & 0xff) - else: - t = buf[0] >> 1 - return t - 0.25 + (buf[7] - buf[6]) / buf[7] - else: - t = buf[1] << 8 | buf[0] - if t & 0x8000: # sign bit set - t = -((t ^ 0xffff) + 1) - return t / 16 diff --git a/drivers/onewire/onewire.py b/drivers/onewire/onewire.py deleted file mode 100644 index 3309ba0d274..00000000000 --- a/drivers/onewire/onewire.py +++ /dev/null @@ -1,91 +0,0 @@ -# 1-Wire driver for MicroPython -# MIT license; Copyright (c) 2016 Damien P. George - -from micropython import const -import _onewire as _ow - -class OneWireError(Exception): - pass - -class OneWire: - SEARCH_ROM = const(0xf0) - MATCH_ROM = const(0x55) - SKIP_ROM = const(0xcc) - - def __init__(self, pin): - self.pin = pin - self.pin.init(pin.OPEN_DRAIN, pin.PULL_UP) - - def reset(self, required=False): - reset = _ow.reset(self.pin) - if required and not reset: - raise OneWireError - return reset - - def readbit(self): - return _ow.readbit(self.pin) - - def readbyte(self): - return _ow.readbyte(self.pin) - - def readinto(self, buf): - for i in range(len(buf)): - buf[i] = _ow.readbyte(self.pin) - - def writebit(self, value): - return _ow.writebit(self.pin, value) - - def writebyte(self, value): - return _ow.writebyte(self.pin, value) - - def write(self, buf): - for b in buf: - _ow.writebyte(self.pin, b) - - def select_rom(self, rom): - self.reset() - self.writebyte(MATCH_ROM) - self.write(rom) - - def scan(self): - devices = [] - diff = 65 - rom = False - for i in range(0xff): - rom, diff = self._search_rom(rom, diff) - if rom: - devices += [rom] - if diff == 0: - break - return devices - - def _search_rom(self, l_rom, diff): - if not self.reset(): - return None, 0 - self.writebyte(SEARCH_ROM) - if not l_rom: - l_rom = bytearray(8) - rom = bytearray(8) - next_diff = 0 - i = 64 - for byte in range(8): - r_b = 0 - for bit in range(8): - b = self.readbit() - if self.readbit(): - if b: # there are no devices or there is an error on the bus - return None, 0 - else: - if not b: # collision, two devices with different bit meaning - if diff > i or ((l_rom[byte] & (1 << bit)) and diff != i): - b = 1 - next_diff = i - self.writebit(b) - if b: - r_b |= 1 << bit - i -= 1 - rom[byte] = r_b - return rom, next_diff - - def crc8(self, data): - return _ow.crc8(data) diff --git a/drivers/sdcard/sdcard.py b/drivers/sdcard/sdcard.py deleted file mode 100644 index fe402f74576..00000000000 --- a/drivers/sdcard/sdcard.py +++ /dev/null @@ -1,274 +0,0 @@ -""" -MicroPython driver for SD cards using SPI bus. - -Requires an SPI bus and a CS pin. Provides readblocks and writeblocks -methods so the device can be mounted as a filesystem. - -Example usage on pyboard: - - import pyb, sdcard, os - sd = sdcard.SDCard(pyb.SPI(1), pyb.Pin.board.X5) - pyb.mount(sd, '/sd2') - os.listdir('/') - -Example usage on ESP8266: - - import machine, sdcard, os - sd = sdcard.SDCard(machine.SPI(1), machine.Pin(15)) - os.mount(sd, '/sd') - os.listdir('/') - -""" - -from micropython import const -import time - - -_CMD_TIMEOUT = const(100) - -_R1_IDLE_STATE = const(1 << 0) -#R1_ERASE_RESET = const(1 << 1) -_R1_ILLEGAL_COMMAND = const(1 << 2) -#R1_COM_CRC_ERROR = const(1 << 3) -#R1_ERASE_SEQUENCE_ERROR = const(1 << 4) -#R1_ADDRESS_ERROR = const(1 << 5) -#R1_PARAMETER_ERROR = const(1 << 6) -_TOKEN_CMD25 = const(0xfc) -_TOKEN_STOP_TRAN = const(0xfd) -_TOKEN_DATA = const(0xfe) - - -class SDCard: - def __init__(self, spi, cs): - self.spi = spi - self.cs = cs - - self.cmdbuf = bytearray(6) - self.dummybuf = bytearray(512) - self.tokenbuf = bytearray(1) - for i in range(512): - self.dummybuf[i] = 0xff - self.dummybuf_memoryview = memoryview(self.dummybuf) - - # initialise the card - self.init_card() - - def init_spi(self, baudrate): - try: - master = self.spi.MASTER - except AttributeError: - # on ESP8266 - self.spi.init(baudrate=baudrate, phase=0, polarity=0) - else: - # on pyboard - self.spi.init(master, baudrate=baudrate, phase=0, polarity=0) - - def init_card(self): - # init CS pin - self.cs.init(self.cs.OUT, value=1) - - # init SPI bus; use low data rate for initialisation - self.init_spi(100000) - - # clock card at least 100 cycles with cs high - for i in range(16): - self.spi.write(b'\xff') - - # CMD0: init card; should return _R1_IDLE_STATE (allow 5 attempts) - for _ in range(5): - if self.cmd(0, 0, 0x95) == _R1_IDLE_STATE: - break - else: - raise OSError("no SD card") - - # CMD8: determine card version - r = self.cmd(8, 0x01aa, 0x87, 4) - if r == _R1_IDLE_STATE: - self.init_card_v2() - elif r == (_R1_IDLE_STATE | _R1_ILLEGAL_COMMAND): - self.init_card_v1() - else: - raise OSError("couldn't determine SD card version") - - # get the number of sectors - # CMD9: response R2 (R1 byte + 16-byte block read) - if self.cmd(9, 0, 0, 0, False) != 0: - raise OSError("no response from SD card") - csd = bytearray(16) - self.readinto(csd) - if csd[0] & 0xc0 == 0x40: # CSD version 2.0 - self.sectors = ((csd[8] << 8 | csd[9]) + 1) * 1024 - elif csd[0] & 0xc0 == 0x00: # CSD version 1.0 (old, <=2GB) - c_size = csd[6] & 0b11 | csd[7] << 2 | (csd[8] & 0b11000000) << 4 - c_size_mult = ((csd[9] & 0b11) << 1) | csd[10] >> 7 - self.sectors = (c_size + 1) * (2 ** (c_size_mult + 2)) - else: - raise OSError("SD card CSD format not supported") - #print('sectors', self.sectors) - - # CMD16: set block length to 512 bytes - if self.cmd(16, 512, 0) != 0: - raise OSError("can't set 512 block size") - - # set to high data rate now that it's initialised - self.init_spi(1320000) - - def init_card_v1(self): - for i in range(_CMD_TIMEOUT): - self.cmd(55, 0, 0) - if self.cmd(41, 0, 0) == 0: - self.cdv = 512 - #print("[SDCard] v1 card") - return - raise OSError("timeout waiting for v1 card") - - def init_card_v2(self): - for i in range(_CMD_TIMEOUT): - time.sleep_ms(50) - self.cmd(58, 0, 0, 4) - self.cmd(55, 0, 0) - if self.cmd(41, 0x40000000, 0) == 0: - self.cmd(58, 0, 0, 4) - self.cdv = 1 - #print("[SDCard] v2 card") - return - raise OSError("timeout waiting for v2 card") - - def cmd(self, cmd, arg, crc, final=0, release=True, skip1=False): - self.cs(0) - - # create and send the command - buf = self.cmdbuf - buf[0] = 0x40 | cmd - buf[1] = arg >> 24 - buf[2] = arg >> 16 - buf[3] = arg >> 8 - buf[4] = arg - buf[5] = crc - self.spi.write(buf) - - if skip1: - self.spi.readinto(self.tokenbuf, 0xff) - - # wait for the response (response[7] == 0) - for i in range(_CMD_TIMEOUT): - self.spi.readinto(self.tokenbuf, 0xff) - response = self.tokenbuf[0] - if not (response & 0x80): - # this could be a big-endian integer that we are getting here - for j in range(final): - self.spi.write(b'\xff') - if release: - self.cs(1) - self.spi.write(b'\xff') - return response - - # timeout - self.cs(1) - self.spi.write(b'\xff') - return -1 - - def readinto(self, buf): - self.cs(0) - - # read until start byte (0xff) - while True: - self.spi.readinto(self.tokenbuf, 0xff) - if self.tokenbuf[0] == 0xfe: - break - - # read data - mv = self.dummybuf_memoryview - if len(buf) != len(mv): - mv = mv[:len(buf)] - self.spi.write_readinto(mv, buf) - - # read checksum - self.spi.write(b'\xff') - self.spi.write(b'\xff') - - self.cs(1) - self.spi.write(b'\xff') - - def write(self, token, buf): - self.cs(0) - - # send: start of block, data, checksum - self.spi.read(1, token) - self.spi.write(buf) - self.spi.write(b'\xff') - self.spi.write(b'\xff') - - # check the response - if (self.spi.read(1, 0xff)[0] & 0x1f) != 0x05: - self.cs(1) - self.spi.write(b'\xff') - return - - # wait for write to finish - while self.spi.read(1, 0xff)[0] == 0: - pass - - self.cs(1) - self.spi.write(b'\xff') - - def write_token(self, token): - self.cs(0) - self.spi.read(1, token) - self.spi.write(b'\xff') - # wait for write to finish - while self.spi.read(1, 0xff)[0] == 0x00: - pass - - self.cs(1) - self.spi.write(b'\xff') - - def readblocks(self, block_num, buf): - nblocks = len(buf) // 512 - assert nblocks and not len(buf) % 512, 'Buffer length is invalid' - if nblocks == 1: - # CMD17: set read address for single block - if self.cmd(17, block_num * self.cdv, 0) != 0: - raise OSError(5) # EIO - # receive the data - self.readinto(buf) - else: - # CMD18: set read address for multiple blocks - if self.cmd(18, block_num * self.cdv, 0) != 0: - raise OSError(5) # EIO - offset = 0 - mv = memoryview(buf) - while nblocks: - self.readinto(mv[offset : offset + 512]) - offset += 512 - nblocks -= 1 - if self.cmd(12, 0, 0xff, skip1=True): - raise OSError(5) # EIO - - def writeblocks(self, block_num, buf): - nblocks, err = divmod(len(buf), 512) - assert nblocks and not err, 'Buffer length is invalid' - if nblocks == 1: - # CMD24: set write address for single block - if self.cmd(24, block_num * self.cdv, 0) != 0: - raise OSError(5) # EIO - - # send the data - self.write(_TOKEN_DATA, buf) - else: - # CMD25: set write address for first block - if self.cmd(25, block_num * self.cdv, 0) != 0: - raise OSError(5) # EIO - # send the data - offset = 0 - mv = memoryview(buf) - while nblocks: - self.write(_TOKEN_CMD25, mv[offset : offset + 512]) - offset += 512 - nblocks -= 1 - self.write_token(_TOKEN_STOP_TRAN) - - def ioctl(self, op, arg): - print('ioctl', op, arg) - if op == 4: # get number of blocks - return self.sectors diff --git a/drivers/sdcard/sdtest.py b/drivers/sdcard/sdtest.py deleted file mode 100644 index 438baa245d0..00000000000 --- a/drivers/sdcard/sdtest.py +++ /dev/null @@ -1,57 +0,0 @@ -# Test for sdcard block protocol -# Peter hinch 30th Jan 2016 -import os, sdcard, pyb - -def sdtest(): - sd = sdcard.SDCard(pyb.SPI(1), pyb.Pin.board.X21) # Compatible with PCB - pyb.mount(sd, '/fc') - print('Filesystem check') - print(os.listdir('/fc')) - - line = 'abcdefghijklmnopqrstuvwxyz\n' - lines = line * 200 # 5400 chars - short = '1234567890\n' - - fn = '/fc/rats.txt' - print() - print('Multiple block read/write') - with open(fn,'w') as f: - n = f.write(lines) - print(n, 'bytes written') - n = f.write(short) - print(n, 'bytes written') - n = f.write(lines) - print(n, 'bytes written') - - with open(fn,'r') as f: - result1 = f.read() - print(len(result1), 'bytes read') - - fn = '/fc/rats1.txt' - print() - print('Single block read/write') - with open(fn,'w') as f: - n = f.write(short) # one block - print(n, 'bytes written') - - with open(fn,'r') as f: - result2 = f.read() - print(len(result2), 'bytes read') - - pyb.mount(None, '/fc') - - print() - print('Verifying data read back') - success = True - if result1 == ''.join((lines, short, lines)): - print('Large file Pass') - else: - print('Large file Fail') - success = False - if result2 == short: - print('Small file Pass') - else: - print('Small file Fail') - success = False - print() - print('Tests', 'passed' if success else 'failed') diff --git a/drivers/wiznet5k/ethernet/socket.c b/drivers/wiznet5k/ethernet/socket.c index 3ffda3a722d..bea98601de7 100644 --- a/drivers/wiznet5k/ethernet/socket.c +++ b/drivers/wiznet5k/ethernet/socket.c @@ -6,6 +6,7 @@ //! \version 1.0.3 //! \date 2013/10/21 //! \par Revision history +//! <2018/10/09> Nick Moore fixes for CircuitPython //! <2014/05/01> V1.0.3. Refer to M20140501 //! 1. Implicit type casting -> Explicit type casting. //! 2. replace 0x01 with PACK_REMAINED in recvfrom() @@ -286,7 +287,7 @@ int32_t WIZCHIP_EXPORT(send)(uint8_t sn, uint8_t * buf, uint16_t len) if(tmp & Sn_IR_SENDOK) { setSn_IR(sn, Sn_IR_SENDOK); - #if _WZICHIP_ == 5200 + #if _WIZCHIP_ == 5200 if(getSn_TX_RD(sn) != sock_next_rd[sn]) { setSn_CR(sn,Sn_CR_SEND); @@ -393,15 +394,7 @@ int32_t WIZCHIP_EXPORT(sendto)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t CHECK_SOCKDATA(); //M20140501 : For avoiding fatal error on memory align mismatched //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; - { - uint32_t taddr; - taddr = ((uint32_t)addr[0]) & 0x000000FF; - taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); - taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); - taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); - if (taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID; - } - // + if ((addr[0] | addr[1] | addr[2] | addr[3]) == 0) return SOCKERR_IPINVALID; if(port == 0) return SOCKERR_PORTZERO; tmp = getSn_SR(sn); if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS; diff --git a/drivers/wiznet5k/ethernet/wizchip_conf.h b/drivers/wiznet5k/ethernet/wizchip_conf.h index 4a7a7bd6914..10f12a79475 100644 --- a/drivers/wiznet5k/ethernet/wizchip_conf.h +++ b/drivers/wiznet5k/ethernet/wizchip_conf.h @@ -130,7 +130,7 @@ */ #define _WIZCHIP_IO_BASE_ 0x00000000 // -#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ #ifndef _WIZCHIP_IO_BASE_ #error "You should be define _WIZCHIP_IO_BASE to fit your system memory map." #endif diff --git a/drivers/wiznet5k/internet/dhcp/dhcp.c b/drivers/wiznet5k/internet/dhcp/dhcp.c index 5747582599d..00f41c3c723 100644 --- a/drivers/wiznet5k/internet/dhcp/dhcp.c +++ b/drivers/wiznet5k/internet/dhcp/dhcp.c @@ -6,11 +6,12 @@ //! \version 1.1.0 //! \date 2013/11/18 //! \par Revision history +//! <2018/10/09> Modified by Nick Moore for CircuitPython //! <2013/11/18> 1st Release //! <2012/12/20> V1.1.0 //! 1. Optimize code //! 2. Add reg_dhcp_cbfunc() -//! 3. Add DHCP_stop() +//! 3. Add DHCP_stop() //! 4. Integrate check_DHCP_state() & DHCP_run() to DHCP_run() //! 5. Don't care system endian //! 6. Add comments @@ -21,44 +22,44 @@ //! //! Copyright (c) 2013, WIZnet Co., LTD. //! All rights reserved. -//! -//! Redistribution and use in source and binary forms, with or without -//! modification, are permitted provided that the following conditions -//! are met: -//! -//! * Redistributions of source code must retain the above copyright -//! notice, this list of conditions and the following disclaimer. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. //! * Redistributions in binary form must reproduce the above copyright //! notice, this list of conditions and the following disclaimer in the -//! documentation and/or other materials provided with the distribution. -//! * Neither the name of the nor the names of its -//! contributors may be used to endorse or promote products derived -//! from this software without specific prior written permission. -//! +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! //! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE //! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF //! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF //! THE POSSIBILITY OF SUCH DAMAGE. // //***************************************************************************** //#include "Ethernet/socket.h" //#include "Internet/DHCP/dhcp.h" -#include "../../Ethernet/socket.h" +#include "../../ethernet/socket.h" #include "dhcp.h" /* If you want to display debug & processing message, Define _DHCP_DEBUG_ in dhcp.h */ #ifdef _DHCP_DEBUG_ #include -#endif +#endif /* DHCP state machine. */ #define STATE_DHCP_INIT 0 ///< Initialize @@ -69,7 +70,7 @@ #define STATE_DHCP_RELEASE 5 ///< No use #define STATE_DHCP_STOP 6 ///< Stop processing DHCP -#define DHCP_FLAGSBROADCAST 0x8000 ///< The broadcast value of flags in @ref RIP_MSG +#define DHCP_FLAGSBROADCAST 0x8000 ///< The broadcast value of flags in @ref RIP_MSG #define DHCP_FLAGSUNICAST 0x0000 ///< The unicast value of flags in @ref RIP_MSG /* DHCP message OP code */ @@ -98,7 +99,7 @@ #define OPT_SIZE 312 /// Max OPT size of @ref RIP_MSG #define RIP_MSG_SIZE (236+OPT_SIZE) /// Max size of @ref RIP_MSG -/* +/* * @brief DHCP option and value (cf. RFC1533) */ enum @@ -170,7 +171,7 @@ enum /* * @brief DHCP message format - */ + */ typedef struct { uint8_t op; ///< @ref DHCP_BOOTREQUEST or @ref DHCP_BOOTREPLY uint8_t htype; ///< @ref DHCP_HTYPE10MB or @ref DHCP_HTYPE100MB @@ -181,7 +182,7 @@ typedef struct { uint16_t flags; ///< @ref DHCP_FLAGSBROADCAST or @ref DHCP_FLAGSUNICAST uint8_t ciaddr[4]; ///< @ref Request IP to DHCP sever uint8_t yiaddr[4]; ///< @ref Offered IP from DHCP server - uint8_t siaddr[4]; ///< No use + uint8_t siaddr[4]; ///< No use uint8_t giaddr[4]; ///< No use uint8_t chaddr[16]; ///< DHCP client 6bytes MAC address. Others is filled to zero uint8_t sname[64]; ///< No use @@ -204,7 +205,7 @@ uint8_t DHCP_allocated_dns[4] = {0, }; // DNS address from DHCP int8_t dhcp_state = STATE_DHCP_INIT; // DHCP state -int8_t dhcp_retry_count = 0; +int8_t dhcp_retry_count = 0; uint32_t dhcp_lease_time = INFINITE_LEASETIME; volatile uint32_t dhcp_tick_1s = 0; // unit 1 second @@ -214,7 +215,7 @@ uint32_t DHCP_XID; // Any number RIP_MSG* pDHCPMSG; // Buffer pointer for DHCP processing -uint8_t HOST_NAME[] = DCHP_HOST_NAME; +uint8_t HOST_NAME[] = DCHP_HOST_NAME; uint8_t DHCP_CHADDR[6]; // DHCP Client MAC address. @@ -305,9 +306,9 @@ void makeDHCPMSG(void) *(ptmp+0) = (uint8_t)((DHCP_XID & 0xFF000000) >> 24); *(ptmp+1) = (uint8_t)((DHCP_XID & 0x00FF0000) >> 16); *(ptmp+2) = (uint8_t)((DHCP_XID & 0x0000FF00) >> 8); - *(ptmp+3) = (uint8_t)((DHCP_XID & 0x000000FF) >> 0); + *(ptmp+3) = (uint8_t)((DHCP_XID & 0x000000FF) >> 0); pDHCPMSG->secs = DHCP_SECS; - ptmp = (uint8_t*)(&pDHCPMSG->flags); + ptmp = (uint8_t*)(&pDHCPMSG->flags); *(ptmp+0) = (uint8_t)((DHCP_FLAGSBROADCAST & 0xFF00) >> 8); *(ptmp+1) = (uint8_t)((DHCP_FLAGSBROADCAST & 0x00FF) >> 0); @@ -355,16 +356,16 @@ void send_DHCP_DISCOVER(void) uint16_t i; uint8_t ip[4]; uint16_t k = 0; - + makeDHCPMSG(); k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() - + // Option Request Param pDHCPMSG->OPT[k++] = dhcpMessageType; pDHCPMSG->OPT[k++] = 0x01; pDHCPMSG->OPT[k++] = DHCP_DISCOVER; - + // Client identifier pDHCPMSG->OPT[k++] = dhcpClientIdentifier; pDHCPMSG->OPT[k++] = 0x07; @@ -375,10 +376,10 @@ void send_DHCP_DISCOVER(void) pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; - + // host name pDHCPMSG->OPT[k++] = hostName; - pDHCPMSG->OPT[k++] = 0; // fill zero length of hostname + pDHCPMSG->OPT[k++] = 0; // fill zero length of hostname for(i = 0 ; HOST_NAME[i] != 0; i++) pDHCPMSG->OPT[k++] = HOST_NAME[i]; pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; @@ -408,7 +409,7 @@ void send_DHCP_DISCOVER(void) printf("> Send DHCP_DISCOVER\r\n"); #endif - sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); + WIZCHIP_EXPORT(sendto)(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); } /* SEND DHCP REQUEST */ @@ -431,18 +432,18 @@ void send_DHCP_REQUEST(void) ip[0] = DHCP_SIP[0]; ip[1] = DHCP_SIP[1]; ip[2] = DHCP_SIP[2]; - ip[3] = DHCP_SIP[3]; + ip[3] = DHCP_SIP[3]; } else { ip[0] = 255; ip[1] = 255; ip[2] = 255; - ip[3] = 255; + ip[3] = 255; } - + k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() - + // Option Request Param. pDHCPMSG->OPT[k++] = dhcpMessageType; pDHCPMSG->OPT[k++] = 0x01; @@ -466,7 +467,7 @@ void send_DHCP_REQUEST(void) pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1]; pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2]; pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3]; - + pDHCPMSG->OPT[k++] = dhcpServerIdentifier; pDHCPMSG->OPT[k++] = 0x04; pDHCPMSG->OPT[k++] = DHCP_SIP[0]; @@ -484,7 +485,7 @@ void send_DHCP_REQUEST(void) pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; pDHCPMSG->OPT[k - (i+3+1)] = i+3; // length of hostname - + pDHCPMSG->OPT[k++] = dhcpParamRequest; pDHCPMSG->OPT[k++] = 0x08; pDHCPMSG->OPT[k++] = subnetMask; @@ -502,8 +503,8 @@ void send_DHCP_REQUEST(void) #ifdef _DHCP_DEBUG_ printf("> Send DHCP_REQUEST\r\n"); #endif - - sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); + + WIZCHIP_EXPORT(sendto)(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); } @@ -513,11 +514,11 @@ void send_DHCP_DECLINE(void) int i; uint8_t ip[4]; uint16_t k = 0; - + makeDHCPMSG(); k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() - + *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8); *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF); @@ -564,7 +565,7 @@ void send_DHCP_DECLINE(void) printf("\r\n> Send DHCP_DECLINE\r\n"); #endif - sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); + WIZCHIP_EXPORT(sendto)(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); } /* PARSE REPLY pDHCPMSG */ @@ -576,18 +577,18 @@ int8_t parseDHCPMSG(void) uint8_t * p; uint8_t * e; - uint8_t type; + uint8_t type = 0; uint8_t opt_len; - + if((len = getSn_RX_RSR(DHCP_SOCKET)) > 0) { - len = recvfrom(DHCP_SOCKET, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port); - #ifdef _DHCP_DEBUG_ + len = WIZCHIP_EXPORT(recvfrom)(DHCP_SOCKET, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port); + #ifdef _DHCP_DEBUG_ printf("DHCP message : %d.%d.%d.%d(%d) %d received. \r\n",svr_addr[0],svr_addr[1],svr_addr[2], svr_addr[3],svr_port, len); - #endif + #endif } else return 0; - if (svr_port == DHCP_SERVER_PORT) { + if (svr_port == DHCP_SERVER_PORT) { // compare mac address if ( (pDHCPMSG->chaddr[0] != DHCP_CHADDR[0]) || (pDHCPMSG->chaddr[1] != DHCP_CHADDR[1]) || (pDHCPMSG->chaddr[2] != DHCP_CHADDR[2]) || (pDHCPMSG->chaddr[3] != DHCP_CHADDR[3]) || @@ -623,7 +624,7 @@ int8_t parseDHCPMSG(void) break; case routersOnSubnet : p++; - opt_len = *p++; + opt_len = *p++; DHCP_allocated_gw[0] = *p++; DHCP_allocated_gw[1] = *p++; DHCP_allocated_gw[2] = *p++; @@ -631,8 +632,8 @@ int8_t parseDHCPMSG(void) p = p + (opt_len - 4); break; case dns : - p++; - opt_len = *p++; + p++; + opt_len = *p++; DHCP_allocated_dns[0] = *p++; DHCP_allocated_dns[1] = *p++; DHCP_allocated_dns[2] = *p++; @@ -646,7 +647,7 @@ int8_t parseDHCPMSG(void) dhcp_lease_time = (dhcp_lease_time << 8) + *p++; dhcp_lease_time = (dhcp_lease_time << 8) + *p++; dhcp_lease_time = (dhcp_lease_time << 8) + *p++; - #ifdef _DHCP_DEBUG_ + #ifdef _DHCP_DEBUG_ dhcp_lease_time = 10; #endif break; @@ -677,7 +678,7 @@ uint8_t DHCP_run(void) if(dhcp_state == STATE_DHCP_STOP) return DHCP_STOPPED; if(getSn_SR(DHCP_SOCKET) != SOCK_UDP) - socket(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00); + WIZCHIP_EXPORT(socket)(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00); ret = DHCP_RUNNING; type = parseDHCPMSG(); @@ -739,7 +740,7 @@ uint8_t DHCP_run(void) case STATE_DHCP_LEASED : ret = DHCP_IP_LEASED; if ((dhcp_lease_time != INFINITE_LEASETIME) && ((dhcp_lease_time/2) < dhcp_tick_1s)) { - + #ifdef _DHCP_DEBUG_ printf("> Maintains the IP address \r\n"); #endif @@ -749,7 +750,7 @@ uint8_t DHCP_run(void) OLD_allocated_ip[1] = DHCP_allocated_ip[1]; OLD_allocated_ip[2] = DHCP_allocated_ip[2]; OLD_allocated_ip[3] = DHCP_allocated_ip[3]; - + DHCP_XID++; send_DHCP_REQUEST(); @@ -764,21 +765,21 @@ uint8_t DHCP_run(void) ret = DHCP_IP_LEASED; if (type == DHCP_ACK) { dhcp_retry_count = 0; - if (OLD_allocated_ip[0] != DHCP_allocated_ip[0] || + if (OLD_allocated_ip[0] != DHCP_allocated_ip[0] || OLD_allocated_ip[1] != DHCP_allocated_ip[1] || OLD_allocated_ip[2] != DHCP_allocated_ip[2] || - OLD_allocated_ip[3] != DHCP_allocated_ip[3]) + OLD_allocated_ip[3] != DHCP_allocated_ip[3]) { ret = DHCP_IP_CHANGED; dhcp_ip_update(); #ifdef _DHCP_DEBUG_ printf(">IP changed.\r\n"); #endif - + } #ifdef _DHCP_DEBUG_ else printf(">IP is continued.\r\n"); - #endif + #endif reset_DHCP_timeout(); dhcp_state = STATE_DHCP_LEASED; } else if (type == DHCP_NAK) { @@ -801,14 +802,14 @@ uint8_t DHCP_run(void) void DHCP_stop(void) { - close(DHCP_SOCKET); + WIZCHIP_EXPORT(close)(DHCP_SOCKET); dhcp_state = STATE_DHCP_STOP; } uint8_t check_DHCP_timeout(void) { uint8_t ret = DHCP_RUNNING; - + if (dhcp_retry_count < MAX_DHCP_RETRY) { if (dhcp_tick_next < dhcp_tick_1s) { @@ -817,7 +818,7 @@ uint8_t check_DHCP_timeout(void) // printf("<> state : STATE_DHCP_DISCOVER\r\n"); send_DHCP_DISCOVER(); break; - + case STATE_DHCP_REQUEST : // printf("<> state : STATE_DHCP_REQUEST\r\n"); @@ -826,10 +827,10 @@ uint8_t check_DHCP_timeout(void) case STATE_DHCP_REREQUEST : // printf("<> state : STATE_DHCP_REREQUEST\r\n"); - + send_DHCP_REQUEST(); break; - + default : break; } @@ -869,7 +870,7 @@ int8_t check_DHCP_leasedIP(void) // IP conflict detection : ARP request - ARP reply // Broadcasting ARP Request for check the IP conflict using UDP sendto() function - ret = sendto(DHCP_SOCKET, (uint8_t *)"CHECK_IP_CONFLICT", 17, DHCP_allocated_ip, 5000); + ret = WIZCHIP_EXPORT(sendto)(DHCP_SOCKET, (uint8_t *)"CHECK_IP_CONFLICT", 17, DHCP_allocated_ip, 5000); // RCR value restore setRCR(tmp); @@ -891,9 +892,9 @@ int8_t check_DHCP_leasedIP(void) return 0; } -} +} -void DHCP_init(uint8_t s, uint8_t * buf) +void DHCP_init(uint8_t s, DHCP_INIT_BUFFER_TYPE* buf) { uint8_t zeroip[4] = {0,0,0,0}; getSHAR(DHCP_CHADDR); @@ -902,11 +903,11 @@ void DHCP_init(uint8_t s, uint8_t * buf) // assign temporary mac address, you should be set SHAR before call this function. DHCP_CHADDR[0] = 0x00; DHCP_CHADDR[1] = 0x08; - DHCP_CHADDR[2] = 0xdc; + DHCP_CHADDR[2] = 0xdc; DHCP_CHADDR[3] = 0x00; DHCP_CHADDR[4] = 0x00; - DHCP_CHADDR[5] = 0x00; - setSHAR(DHCP_CHADDR); + DHCP_CHADDR[5] = 0x00; + setSHAR(DHCP_CHADDR); } DHCP_SOCKET = s; // SOCK_DHCP @@ -940,7 +941,7 @@ void getIPfromDHCP(uint8_t* ip) { ip[0] = DHCP_allocated_ip[0]; ip[1] = DHCP_allocated_ip[1]; - ip[2] = DHCP_allocated_ip[2]; + ip[2] = DHCP_allocated_ip[2]; ip[3] = DHCP_allocated_ip[3]; } @@ -949,7 +950,7 @@ void getGWfromDHCP(uint8_t* ip) ip[0] =DHCP_allocated_gw[0]; ip[1] =DHCP_allocated_gw[1]; ip[2] =DHCP_allocated_gw[2]; - ip[3] =DHCP_allocated_gw[3]; + ip[3] =DHCP_allocated_gw[3]; } void getSNfromDHCP(uint8_t* ip) @@ -957,7 +958,7 @@ void getSNfromDHCP(uint8_t* ip) ip[0] = DHCP_allocated_sn[0]; ip[1] = DHCP_allocated_sn[1]; ip[2] = DHCP_allocated_sn[2]; - ip[3] = DHCP_allocated_sn[3]; + ip[3] = DHCP_allocated_sn[3]; } void getDNSfromDHCP(uint8_t* ip) @@ -965,14 +966,10 @@ void getDNSfromDHCP(uint8_t* ip) ip[0] = DHCP_allocated_dns[0]; ip[1] = DHCP_allocated_dns[1]; ip[2] = DHCP_allocated_dns[2]; - ip[3] = DHCP_allocated_dns[3]; + ip[3] = DHCP_allocated_dns[3]; } uint32_t getDHCPLeasetime(void) { return dhcp_lease_time; } - - - - diff --git a/drivers/wiznet5k/internet/dhcp/dhcp.h b/drivers/wiznet5k/internet/dhcp/dhcp.h index ee154d506ac..881bf5a6c1c 100644 --- a/drivers/wiznet5k/internet/dhcp/dhcp.h +++ b/drivers/wiznet5k/internet/dhcp/dhcp.h @@ -55,7 +55,7 @@ /* Retry to processing DHCP */ #define MAX_DHCP_RETRY 2 ///< Maximum retry count -#define DHCP_WAIT_TIME 10 ///< Wait Time 10s +#define DHCP_WAIT_TIME 3 ///< Wait Time 3s (was 10s) /* UDP port numbers for DHCP */ #define DHCP_SERVER_PORT 67 ///< DHCP server port number @@ -78,12 +78,14 @@ enum DHCP_STOPPED ///< Stop processing DHCP protocol }; +#define DHCP_INIT_BUFFER_TYPE uint32_t +#define DHCP_INIT_BUFFER_SIZE (137) /* * @brief DHCP client initialization (outside of the main loop) * @param s - socket number * @param buf - buffer for processing DHCP message */ -void DHCP_init(uint8_t s, uint8_t * buf); +void DHCP_init(uint8_t s, DHCP_INIT_BUFFER_TYPE* buf); /* * @brief DHCP 1s Tick Timer handler diff --git a/drivers/wiznet5k/internet/dns/dns.c b/drivers/wiznet5k/internet/dns/dns.c index c0ad570c009..daf4db1230a 100644 --- a/drivers/wiznet5k/internet/dns/dns.c +++ b/drivers/wiznet5k/internet/dns/dns.c @@ -15,6 +15,7 @@ //! 3. Remove the unused define //! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c //! <2013/12/20> V1.1.0 +//! <2018/10/04> Modified HAL_GetTick for use with CircuitPython by Nick Moore //! //! \author Eric Jung & MidnightCow //! \copyright @@ -51,6 +52,7 @@ #include #include +#include "tick.h" //#include "Ethernet/socket.h" //#include "Internet/DNS/dns.h" @@ -121,7 +123,11 @@ uint8_t* pDNSMSG; // DNS message buffer uint8_t DNS_SOCKET; // SOCKET number for DNS uint16_t DNS_MSGID; // DNS message ID -extern uint32_t HAL_GetTick(void); + +uint32_t HAL_GetTick(void) { + return ticks_ms; +} + uint32_t hal_sys_tick; /* converts uint16_t from network buffer to a host byte order integer. */ diff --git a/examples/SDdatalogger/README.md b/examples/SDdatalogger/README.md deleted file mode 100644 index 24e69c87e00..00000000000 --- a/examples/SDdatalogger/README.md +++ /dev/null @@ -1,4 +0,0 @@ -This is a SDdatalogger, to log data from the accelerometer to the SD-card. It also functions as card reader, so you can easily get the data on your PC. - -To run, put the boot.py, cardreader.py and datalogger.py files on either the flash or the SD-card of your pyboard. -Upon reset, the datalogger script is run and logs the data. If you press the user button after reset and hold it until the orange LED goes out, you enter the cardreader mode and the filesystem is mounted to your PC. diff --git a/examples/SDdatalogger/boot.py b/examples/SDdatalogger/boot.py deleted file mode 100644 index 4ac94bbaa4e..00000000000 --- a/examples/SDdatalogger/boot.py +++ /dev/null @@ -1,25 +0,0 @@ -# boot.py -- runs on boot-up -# Let's you choose which script to run. -# > To run 'datalogger.py': -# * press reset and do nothing else -# > To run 'cardreader.py': -# * press reset -# * press user switch and hold until orange LED goes out - -import pyb - -pyb.LED(3).on() # indicate we are waiting for switch press -pyb.delay(2000) # wait for user to maybe press the switch -switch_value = pyb.Switch()() # sample the switch at end of delay -pyb.LED(3).off() # indicate that we finished waiting for the switch - -pyb.LED(4).on() # indicate that we are selecting the mode - -if switch_value: - pyb.usb_mode('VCP+MSC') - pyb.main('cardreader.py') # if switch was pressed, run this -else: - pyb.usb_mode('VCP+HID') - pyb.main('datalogger.py') # if switch wasn't pressed, run this - -pyb.LED(4).off() # indicate that we finished selecting the mode diff --git a/examples/SDdatalogger/cardreader.py b/examples/SDdatalogger/cardreader.py deleted file mode 100644 index 98d7a379256..00000000000 --- a/examples/SDdatalogger/cardreader.py +++ /dev/null @@ -1,2 +0,0 @@ -# cardread.py -# This is called when the user enters cardreader mode. It does nothing. diff --git a/examples/SDdatalogger/datalogger.py b/examples/SDdatalogger/datalogger.py deleted file mode 100644 index 0690c20bb9c..00000000000 --- a/examples/SDdatalogger/datalogger.py +++ /dev/null @@ -1,33 +0,0 @@ -# datalogger.py -# Logs the data from the acceleromter to a file on the SD-card - -import pyb - -# creating objects -accel = pyb.Accel() -blue = pyb.LED(4) -switch = pyb.Switch() - -# loop -while True: - - # wait for interrupt - # this reduces power consumption while waiting for switch press - pyb.wfi() - - # start if switch is pressed - if switch(): - pyb.delay(200) # delay avoids detection of multiple presses - blue.on() # blue LED indicates file open - log = open('/sd/log.csv', 'w') # open file on SD (SD: '/sd/', flash: '/flash/) - - # until switch is pressed again - while not switch(): - t = pyb.millis() # get time - x, y, z = accel.filtered_xyz() # get acceleration data - log.write('{},{},{},{}\n'.format(t,x,y,z)) # write data to file - - # end after switch is pressed again - log.close() # close file - blue.off() # blue LED indicates file closed - pyb.delay(200) # delay avoids detection of multiple presses diff --git a/examples/accel_i2c.py b/examples/accel_i2c.py deleted file mode 100644 index d635e3ccc1f..00000000000 --- a/examples/accel_i2c.py +++ /dev/null @@ -1,34 +0,0 @@ -# This is an example on how to access accelerometer on -# PyBoard directly using I2C bus. As such, it's more -# intended to be an I2C example, rather than accelerometer -# example. For the latter, using pyb.Accel class is -# much easier. - -from machine import Pin -from machine import I2C -import time - -# Accelerometer needs to be powered on first. Even -# though signal is called "AVDD", and there's separate -# "DVDD", without AVDD, it won't event talk on I2C bus. -accel_pwr = Pin("MMA_AVDD") -accel_pwr.value(1) - -i2c = I2C(1, baudrate=100000) -addrs = i2c.scan() -print("Scanning devices:", [hex(x) for x in addrs]) -if 0x4c not in addrs: - print("Accelerometer is not detected") - -ACCEL_ADDR = 0x4c -ACCEL_AXIS_X_REG = 0 -ACCEL_MODE_REG = 7 - -# Now activate measurements -i2c.mem_write(b"\x01", ACCEL_ADDR, ACCEL_MODE_REG) - -print("Try to move accelerometer and watch the values") -while True: - val = i2c.mem_read(1, ACCEL_ADDR, ACCEL_AXIS_X_REG) - print(val[0]) - time.sleep(1) diff --git a/examples/accellog.py b/examples/accellog.py deleted file mode 100644 index b1f289f8ad2..00000000000 --- a/examples/accellog.py +++ /dev/null @@ -1,17 +0,0 @@ -# log the accelerometer values to a .csv-file on the SD-card - -import pyb - -accel = pyb.Accel() # create object of accelerometer -blue = pyb.LED(4) # create object of blue LED - -log = open('/sd/log.csv', 'w') # open file to write data - /sd/ is the SD-card, /flash/ the internal memory -blue.on() # turn on blue LED - -for i in range(100): # do 100 times (if the board is connected via USB, you can't write longer because the PC tries to open the filesystem which messes up your file.) - t = pyb.millis() # get time since reset - x, y, z = accel.filtered_xyz() # get acceleration data - log.write('{},{},{},{}\n'.format(t,x,y,z)) # write data to file - -log.close() # close file -blue.off() # turn off LED diff --git a/examples/asmled.py b/examples/asmled.py deleted file mode 100644 index 917d9ba03cd..00000000000 --- a/examples/asmled.py +++ /dev/null @@ -1,85 +0,0 @@ -# flash LED #1 using inline assembler -# this version is overly verbose and uses word stores -@micropython.asm_thumb -def flash_led(r0): - movw(r1, (stm.GPIOA + stm.GPIO_BSRRL) & 0xffff) - movt(r1, ((stm.GPIOA + stm.GPIO_BSRRL) >> 16) & 0x7fff) - movw(r2, 1 << 13) - movt(r2, 0) - movw(r3, 0) - movt(r3, 1 << 13) - - b(loop_entry) - - label(loop1) - - # turn LED on - str(r2, [r1, 0]) - - # delay for a bit - movw(r4, 5599900 & 0xffff) - movt(r4, (5599900 >> 16) & 0xffff) - label(delay_on) - sub(r4, r4, 1) - cmp(r4, 0) - bgt(delay_on) - - # turn LED off - str(r3, [r1, 0]) - - # delay for a bit - movw(r4, 5599900 & 0xffff) - movt(r4, (5599900 >> 16) & 0xffff) - label(delay_off) - sub(r4, r4, 1) - cmp(r4, 0) - bgt(delay_off) - - # loop r0 times - sub(r0, r0, 1) - label(loop_entry) - cmp(r0, 0) - bgt(loop1) - -# flash LED #2 using inline assembler -# this version uses half-word sortes, and the convenience assembler operation 'movwt' -@micropython.asm_thumb -def flash_led_v2(r0): - # get the GPIOA address in r1 - movwt(r1, stm.GPIOA) - - # get the bit mask for PA14 (the pin LED #2 is on) - movw(r2, 1 << 14) - - b(loop_entry) - - label(loop1) - - # turn LED on - strh(r2, [r1, stm.GPIO_BSRRL]) - - # delay for a bit - movwt(r4, 5599900) - label(delay_on) - sub(r4, r4, 1) - cmp(r4, 0) - bgt(delay_on) - - # turn LED off - strh(r2, [r1, stm.GPIO_BSRRH]) - - # delay for a bit - movwt(r4, 5599900) - label(delay_off) - sub(r4, r4, 1) - cmp(r4, 0) - bgt(delay_off) - - # loop r0 times - sub(r0, r0, 1) - label(loop_entry) - cmp(r0, 0) - bgt(loop1) - -flash_led(5) -flash_led_v2(5) diff --git a/examples/asmsum.py b/examples/asmsum.py deleted file mode 100644 index 07e71c73849..00000000000 --- a/examples/asmsum.py +++ /dev/null @@ -1,57 +0,0 @@ -@micropython.asm_thumb -def asm_sum_words(r0, r1): - - # r0 = len - # r1 = ptr - # r2 = sum - # r3 = dummy - mov(r2, 0) - - b(loop_entry) - - label(loop1) - ldr(r3, [r1, 0]) - add(r2, r2, r3) - - add(r1, r1, 4) - sub(r0, r0, 1) - - label(loop_entry) - cmp(r0, 0) - bgt(loop1) - - mov(r0, r2) - -@micropython.asm_thumb -def asm_sum_bytes(r0, r1): - - # r0 = len - # r1 = ptr - # r2 = sum - # r3 = dummy - mov(r2, 0) - - b(loop_entry) - - label(loop1) - ldrb(r3, [r1, 0]) - add(r2, r2, r3) - - add(r1, r1, 1) - sub(r0, r0, 1) - - label(loop_entry) - cmp(r0, 0) - bgt(loop1) - - mov(r0, r2) - -import array - -b = array.array('l', (100, 200, 300, 400)) -n = asm_sum_words(len(b), b) -print(b, n) - -b = array.array('b', (10, 20, 30, 40, 50, 60, 70, 80)) -n = asm_sum_bytes(len(b), b) -print(b, n) diff --git a/examples/conwaylife.py b/examples/conwaylife.py deleted file mode 100644 index 323f42e850e..00000000000 --- a/examples/conwaylife.py +++ /dev/null @@ -1,46 +0,0 @@ -#import essential libraries -import pyb - -lcd = pyb.LCD('x') -lcd.light(1) - -# do 1 iteration of Conway's Game of Life -def conway_step(): - for x in range(128): # loop over x coordinates - for y in range(32): # loop over y coordinates - # count number of neighbours - num_neighbours = (lcd.get(x - 1, y - 1) + - lcd.get(x, y - 1) + - lcd.get(x + 1, y - 1) + - lcd.get(x - 1, y) + - lcd.get(x + 1, y) + - lcd.get(x + 1, y + 1) + - lcd.get(x, y + 1) + - lcd.get(x - 1, y + 1)) - - # check if the centre cell is alive or not - self = lcd.get(x, y) - - # apply the rules of life - if self and not (2 <= num_neighbours <= 3): - lcd.pixel(x, y, 0) # not enough, or too many neighbours: cell dies - elif not self and num_neighbours == 3: - lcd.pixel(x, y, 1) # exactly 3 neighbours around an empty cell: cell is born - -# randomise the start -def conway_rand(): - lcd.fill(0) # clear the LCD - for x in range(128): # loop over x coordinates - for y in range(32): # loop over y coordinates - lcd.pixel(x, y, pyb.rng() & 1) # set the pixel randomly - -# loop for a certain number of frames, doing iterations of Conway's Game of Life -def conway_go(num_frames): - for i in range(num_frames): - conway_step() # do 1 iteration - lcd.show() # update the LCD - pyb.delay(50) - -# testing -conway_rand() -conway_go(100) diff --git a/examples/embedding/Makefile b/examples/embedding/Makefile deleted file mode 100644 index 99f239a7c5a..00000000000 --- a/examples/embedding/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -MPTOP = ../.. -CFLAGS = -std=c99 -I. -I$(MPTOP) -DNO_QSTR -LDFLAGS = -L. - -hello-embed: hello-embed.o -lmicropython - --lmicropython: - $(MAKE) -f $(MPTOP)/examples/embedding/Makefile.upylib MPTOP=$(MPTOP) diff --git a/examples/embedding/Makefile.upylib b/examples/embedding/Makefile.upylib deleted file mode 100644 index 6d6302050cf..00000000000 --- a/examples/embedding/Makefile.upylib +++ /dev/null @@ -1,198 +0,0 @@ -MPTOP = ../.. --include mpconfigport.mk -include $(MPTOP)/py/mkenv.mk - -all: lib - -# OS name, for simple autoconfig -UNAME_S := $(shell uname -s) - -# include py core make definitions -include $(MPTOP)/py/py.mk - -INC += -I. -INC += -I.. -INC += -I$(MPTOP) -INC += -I$(MPTOP)/ports/unix -INC += -I$(BUILD) - -# compiler settings -CWARN = -Wall -Werror -CWARN += -Wpointer-arith -Wuninitialized -CFLAGS = $(INC) $(CWARN) -std=gnu99 -DUNIX $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA) - -# Debugging/Optimization -ifdef DEBUG -CFLAGS += -g -COPT = -O0 -else -COPT = -Os #-DNDEBUG -# _FORTIFY_SOURCE is a feature in gcc/glibc which is intended to provide extra -# security for detecting buffer overflows. Some distros (Ubuntu at the very least) -# have it enabled by default. -# -# gcc already optimizes some printf calls to call puts and/or putchar. When -# _FORTIFY_SOURCE is enabled and compiling with -O1 or greater, then some -# printf calls will also be optimized to call __printf_chk (in glibc). Any -# printfs which get redirected to __printf_chk are then no longer synchronized -# with printfs that go through mp_printf. -# -# In MicroPython, we don't want to use the runtime library's printf but rather -# go through mp_printf, so that stdout is properly tied into streams, etc. -# This means that we either need to turn off _FORTIFY_SOURCE or provide our -# own implementation of __printf_chk. We've chosen to turn off _FORTIFY_SOURCE. -# It should also be noted that the use of printf in MicroPython is typically -# quite limited anyways (primarily for debug and some error reporting, etc -# in the unix version). -# -# Information about _FORTIFY_SOURCE seems to be rather scarce. The best I could -# find was this: https://securityblog.redhat.com/2014/03/26/fortify-and-you/ -# Original patchset was introduced by -# https://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html . -# -# Turning off _FORTIFY_SOURCE is only required when compiling with -O1 or greater -CFLAGS += -U _FORTIFY_SOURCE -endif - -# On OSX, 'gcc' is a symlink to clang unless a real gcc is installed. -# The unix port of MicroPython on OSX must be compiled with clang, -# while cross-compile ports require gcc, so we test here for OSX and -# if necessary override the value of 'CC' set in py/mkenv.mk -ifeq ($(UNAME_S),Darwin) -CC = clang -# Use clang syntax for map file -LDFLAGS_ARCH = -Wl,-map,$@.map -else -# Use gcc syntax for map file -LDFLAGS_ARCH = -Wl,-Map=$@.map,--cref -endif -LDFLAGS = $(LDFLAGS_MOD) $(LDFLAGS_ARCH) -lm $(LDFLAGS_EXTRA) - -ifeq ($(MICROPY_FORCE_32BIT),1) -# Note: you may need to install i386 versions of dependency packages, -# starting with linux-libc-dev:i386 -ifeq ($(MICROPY_PY_FFI),1) -ifeq ($(UNAME_S),Linux) -CFLAGS_MOD += -I/usr/include/i686-linux-gnu -endif -endif -endif - -ifeq ($(MICROPY_USE_READLINE),1) -INC += -I$(MPTOP)/lib/mp-readline -CFLAGS_MOD += -DMICROPY_USE_READLINE=1 -LIB_SRC_C_EXTRA += mp-readline/readline.c -endif -ifeq ($(MICROPY_USE_READLINE),2) -CFLAGS_MOD += -DMICROPY_USE_READLINE=2 -LDFLAGS_MOD += -lreadline -# the following is needed for BSD -#LDFLAGS_MOD += -ltermcap -endif -ifeq ($(MICROPY_PY_TIME),1) -CFLAGS_MOD += -DMICROPY_PY_TIME=1 -SRC_MOD += modtime.c -endif -ifeq ($(MICROPY_PY_TERMIOS),1) -CFLAGS_MOD += -DMICROPY_PY_TERMIOS=1 -SRC_MOD += modtermios.c -endif -ifeq ($(MICROPY_PY_SOCKET),1) -CFLAGS_MOD += -DMICROPY_PY_SOCKET=1 -SRC_MOD += modsocket.c -endif - -ifeq ($(MICROPY_PY_FFI),1) - -ifeq ($(MICROPY_STANDALONE),1) -LIBFFI_CFLAGS_MOD := -I$(shell ls -1d $(MPTOP)/lib/libffi/build_dir/out/lib/libffi-*/include) - ifeq ($(MICROPY_FORCE_32BIT),1) - LIBFFI_LDFLAGS_MOD = $(MPTOP)/lib/libffi/build_dir/out/lib32/libffi.a - else - LIBFFI_LDFLAGS_MOD = $(MPTOP)/lib/libffi/build_dir/out/lib/libffi.a - endif -else -LIBFFI_CFLAGS_MOD := $(shell pkg-config --cflags libffi) -LIBFFI_LDFLAGS_MOD := $(shell pkg-config --libs libffi) -endif - -ifeq ($(UNAME_S),Linux) -LIBFFI_LDFLAGS_MOD += -ldl -endif - -CFLAGS_MOD += $(LIBFFI_CFLAGS_MOD) -DMICROPY_PY_FFI=1 -LDFLAGS_MOD += $(LIBFFI_LDFLAGS_MOD) -SRC_MOD += modffi.c -endif - -MAIN_C = main.c - -# source files -SRC_C = $(addprefix ports/unix/,\ - $(MAIN_C) \ - gccollect.c \ - unix_mphal.c \ - input.c \ - file.c \ - modmachine.c \ - modos.c \ - moduselect.c \ - alloc.c \ - coverage.c \ - fatfs_port.c \ - $(SRC_MOD) \ - ) - -LIB_SRC_C = $(addprefix lib/,\ - $(LIB_SRC_C_EXTRA) \ - utils/printf.c \ - timeutils/timeutils.c \ - ) - -ifeq ($(MICROPY_FATFS),1) -LIB_SRC_C += $(addprefix lib/,\ - fatfs/ff.c \ - fatfs/option/ccsbcs.c \ - ) -endif - -OBJ = $(PY_O) -OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o)) - -# List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(LIB_SRC_C) -# Append any auto-generated sources that are needed by sources listed in -# SRC_QSTR -SRC_QSTR_AUTO_DEPS += - -include $(MPTOP)/py/mkrules.mk - -# Value of configure's --host= option (required for cross-compilation). -# Deduce it from CROSS_COMPILE by default, but can be overridden. -ifneq ($(CROSS_COMPILE),) -CROSS_COMPILE_HOST = --host=$(patsubst %-,%,$(CROSS_COMPILE)) -else -CROSS_COMPILE_HOST = -endif - -deplibs: libffi axtls - -# install-exec-recursive & install-data-am targets are used to avoid building -# docs and depending on makeinfo -libffi: - cd $(MPTOP)/lib/libffi; git clean -d -x -f - cd $(MPTOP)/lib/libffi; ./autogen.sh - mkdir -p $(MPTOP)/lib/libffi/build_dir; cd $(MPTOP)/lib/libffi/build_dir; \ - ../configure $(CROSS_COMPILE_HOST) --prefix=$$PWD/out CC="$(CC)" CXX="$(CXX)" LD="$(LD)"; \ - make install-exec-recursive; make -C include install-data-am - -axtls: $(MPTOP)/lib/axtls/README - cd $(MPTOP)/lib/axtls; cp config/upyconfig config/.config - cd $(MPTOP)/lib/axtls; make oldconfig -B - cd $(MPTOP)/lib/axtls; make clean - cd $(MPTOP)/lib/axtls; make all CC="$(CC)" LD="$(LD)" - -$(MPTOP)/lib/axtls/README: - @echo "You cloned without --recursive, fetching submodules for you." - (cd $(MPTOP); git submodule update --init --recursive) diff --git a/examples/embedding/README.md b/examples/embedding/README.md deleted file mode 100644 index 0dfc52e1dca..00000000000 --- a/examples/embedding/README.md +++ /dev/null @@ -1,67 +0,0 @@ -Example of embedding MicroPython in a standalone C application -============================================================== - -This directory contains a (very simple!) example of how to embed a MicroPython -in an existing C application. - -A C application is represented by the file `hello-embed.c`. It executes a simple -Python statement which prints to the standard output. - - -Building the example --------------------- - -Building the example is as simple as running: - - make - -It's worth to trace what's happening behind the scenes though: - -1. As a first step, a MicroPython library is built. This is handled by a -separate makefile, `Makefile.upylib`. It is more or less complex, but the -good news is that you won't need to change anything in it, just use it -as is, the main `Makefile` shows how. What may require editing though is -a MicroPython configuration file. MicroPython is highly configurable, so -you would need to build a library suiting your application well, while -not bloating its size. Check the options in the file `mpconfigport.h`. -Included is a copy of the "minimal" Unix port, which should be a good start -for minimal embedding. For the list of all available options, see -`py/mpconfig.h`. - -2. Once the MicroPython library is built, your application is compiled -and linked it. The main Makefile is very simple and shows that the changes -you would need to do to your application's `Makefile` (or other build -configuration) are also simple: - -a) You would need to use C99 standard (you're using this 15+ years old -standard already, not a 25+ years old one, right?). - -b) You need to provide a path to MicroPython's top-level dir, for includes. - -c) You need to include `-DNO_QSTR` compile-time flag. - -d) Otherwise, just link with the MicroPython library produced in step 1. - - -Out of tree build ------------------ - -This example is set up to work out of the box, being part of the MicroPython -tree. Your application of course will be outside of its tree, but the -only thing you need to do is to pass `MPTOP` variable pointing to -MicroPython directory to both Makefiles (in this example, the main Makefile -automatically passes it to `Makefile.upylib`; in your own Makefile, don't forget -to use a suitable value). - -A practical way to embed MicroPython in your application is to include it -as a git submodule. Suppose you included it as `libs/micropython`. Then in -your main Makefile you would have something like: - -~~~ -MPTOP = libs/micropython - -my_app: $(MY_OBJS) -lmicropython - --lmicropython: - $(MAKE) -f $(MPTOP)/examples/embedding/Makefile.upylib MPTOP=$(MPTOP) -~~~ diff --git a/examples/embedding/hello-embed.c b/examples/embedding/hello-embed.c deleted file mode 100644 index 3473e5bcd8c..00000000000 --- a/examples/embedding/hello-embed.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Paul Sokolovsky - * - * 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 -#include -#include - -#include "py/compile.h" -#include "py/runtime.h" -#include "py/gc.h" -#include "py/stackctrl.h" - -static char heap[16384]; - -mp_obj_t execute_from_str(const char *str) { - nlr_buf_t nlr; - if (nlr_push(&nlr) == 0) { - mp_lexer_t *lex = mp_lexer_new_from_str_len(0/*MP_QSTR_*/, str, strlen(str), false); - mp_parse_tree_t pt = mp_parse(lex, MP_PARSE_FILE_INPUT); - mp_obj_t module_fun = mp_compile(&pt, lex->source_name, MP_EMIT_OPT_NONE, false); - mp_call_function_0(module_fun); - nlr_pop(); - return 0; - } else { - // uncaught exception - return (mp_obj_t)nlr.ret_val; - } -} - -int main() { - // Initialized stack limit - mp_stack_set_limit(40000 * (BYTES_PER_WORD / 4)); - // Initialize heap - gc_init(heap, heap + sizeof(heap)); - // Initialize interpreter - mp_init(); - - const char str[] = "print('Hello world of easy embedding!')"; - if (execute_from_str(str)) { - printf("Error\n"); - } -} - -uint mp_import_stat(const char *path) { - return MP_IMPORT_STAT_NO_EXIST; -} - -void nlr_jump_fail(void *val) { - printf("FATAL: uncaught NLR %p\n", val); - exit(1); -} diff --git a/examples/embedding/mpconfigport.h b/examples/embedding/mpconfigport.h deleted file mode 120000 index 142e5d6f431..00000000000 --- a/examples/embedding/mpconfigport.h +++ /dev/null @@ -1 +0,0 @@ -mpconfigport_minimal.h \ No newline at end of file diff --git a/examples/embedding/mpconfigport_minimal.h b/examples/embedding/mpconfigport_minimal.h deleted file mode 100644 index fa52be4ad77..00000000000 --- a/examples/embedding/mpconfigport_minimal.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2015 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. - */ - -// options to control how MicroPython is built - -#define MICROPY_ALLOC_PATH_MAX (PATH_MAX) -#define MICROPY_ENABLE_GC (1) -#define MICROPY_ENABLE_FINALISER (0) -#define MICROPY_STACK_CHECK (0) -#define MICROPY_COMP_CONST (0) -#define MICROPY_MEM_STATS (0) -#define MICROPY_DEBUG_PRINTERS (0) -#define MICROPY_READER_POSIX (1) -#define MICROPY_KBD_EXCEPTION (1) -#define MICROPY_HELPER_REPL (1) -#define MICROPY_HELPER_LEXER_UNIX (1) -#define MICROPY_ENABLE_SOURCE_LINE (0) -#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) -#define MICROPY_WARNINGS (0) -#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (0) -#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE) -#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE) -#define MICROPY_STREAMS_NON_BLOCK (0) -#define MICROPY_OPT_COMPUTED_GOTO (0) -#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0) -#define MICROPY_CAN_OVERRIDE_BUILTINS (0) -#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0) -#define MICROPY_CPYTHON_COMPAT (0) -#define MICROPY_PY_BUILTINS_BYTEARRAY (0) -#define MICROPY_PY_BUILTINS_MEMORYVIEW (0) -#define MICROPY_PY_BUILTINS_COMPILE (0) -#define MICROPY_PY_BUILTINS_ENUMERATE (0) -#define MICROPY_PY_BUILTINS_FILTER (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_STR_UNICODE (0) -#define MICROPY_PY_BUILTINS_PROPERTY (0) -#define MICROPY_PY_BUILTINS_MIN_MAX (0) -#define MICROPY_PY___FILE__ (0) -#define MICROPY_PY_MICROPYTHON_MEM_INFO (0) -#define MICROPY_PY_GC (0) -#define MICROPY_PY_GC_COLLECT_RETVAL (0) -#define MICROPY_PY_ARRAY (0) -#define MICROPY_PY_COLLECTIONS (0) -#define MICROPY_PY_MATH (0) -#define MICROPY_PY_CMATH (0) -#define MICROPY_PY_IO (0) -#define MICROPY_PY_IO_FILEIO (0) -#define MICROPY_PY_STRUCT (0) -#define MICROPY_PY_SYS (1) -#define MICROPY_PY_SYS_EXIT (0) -#define MICROPY_PY_SYS_PLATFORM "linux" -#define MICROPY_PY_SYS_MAXSIZE (0) -#define MICROPY_PY_SYS_STDFILES (0) -#define MICROPY_PY_CMATH (0) -#define MICROPY_PY_UCTYPES (0) -#define MICROPY_PY_UZLIB (0) -#define MICROPY_PY_UJSON (0) -#define MICROPY_PY_URE (0) -#define MICROPY_PY_UHEAPQ (0) -#define MICROPY_PY_UHASHLIB (0) -#define MICROPY_PY_UBINASCII (0) - -extern const struct _mp_obj_module_t mp_module_os; - -#define MICROPY_PORT_BUILTIN_MODULES \ - { MP_ROM_QSTR(MP_QSTR_uos), MP_ROM_PTR(&mp_module_os) }, \ - -#define MICROPY_PORT_ROOT_POINTERS \ - -////////////////////////////////////////// -// Do not change anything beyond this line -////////////////////////////////////////// - -// Define to 1 to use undertested inefficient GC helper implementation -// (if more efficient arch-specific one is not available). -#ifndef MICROPY_GCREGS_SETJMP - #ifdef __mips__ - #define MICROPY_GCREGS_SETJMP (1) - #else - #define MICROPY_GCREGS_SETJMP (0) - #endif -#endif - -// type definitions for the specific machine - -#ifdef __LP64__ -typedef long mp_int_t; // must be pointer size -typedef unsigned long mp_uint_t; // must be pointer size -#else -// These are definitions for machines where sizeof(int) == sizeof(void*), -// regardless for actual size. -typedef int mp_int_t; // must be pointer size -typedef unsigned int mp_uint_t; // must be pointer size -#endif - -// Cannot include , as it may lead to symbol name clashes -#if _FILE_OFFSET_BITS == 64 && !defined(__LP64__) -typedef long long mp_off_t; -#else -typedef long mp_off_t; -#endif - -// We need to provide a declaration/definition of alloca() -#ifdef __FreeBSD__ -#include -#else -#include -#endif diff --git a/examples/hwapi/README.md b/examples/hwapi/README.md deleted file mode 100644 index 1992eb66094..00000000000 --- a/examples/hwapi/README.md +++ /dev/null @@ -1,126 +0,0 @@ -This directory shows the best practices for using MicroPython hardware API -(`machine` module). `machine` module strives to provide consistent API -across various boards, with the aim to enable writing portable applications, -which would work from a board to board, from a system to another systems. -This is inherently a hard problem, because hardware is different from one -board type to another, and even from examplar of board to another. For -example, if your app requires an external LED, one user may connect it -to one GPIO pin, while another user may find it much more convinient to -use another pin. This of course applies to relays, buzzers, sensors, etc. - -With complications above in mind, it's still possible to write portable -applications by using "low[est] denominator" subset of hardware API and -following simple rules outlined below. The applications won't be able -to rely on advanced hardware capabilities of a particular board and -will be limited to generic capabilities, but it's still possible to -write many useful applications in such a way, with the obvious benefit of -"write once - run everywhere" approach (only configuration for a particular -board is required). - -The key to this approach is splitting your application into (at least) -2 parts: - -* main application logic -* hardware configuration - -The key point is that hardware configuration should be a separate file -(module in Python terms). A good name would be `hwconfig.py`, and that's -how we'll call it from now on. Another key point is that main application -should never instantiate (construct) hardware objects directly. Instead, -they should be defined in `hwconfig.py`, and main application should -import and reference hardware objects via this module. The simplest -application of this idea would look like: - -`hwconfig.py`: - - from machine import Pin - - LED = Pin("A3", Pin.OUT) - -`app.py`: - - from hwconfig import * - import utime - - while True: - LED.value(1) - utime.sleep_ms(500) - LED.value(0) - utime.sleep_ms(500) - - -To deploy this application to a particular board, a user will need: - -1. Edit `hwconfig.py` to adjust Pin and other hardware peripheral - parameters and locations. -2. Actually deploy `hwconfig.py` and `app.py` to a board (e.g. copy to - board's filesystem, or build new firmware with these modules frozen - into it). - -Note that there's no need to edit the main application code! (Which may -be complex, while `hwconfig.py` should usually remain short enough, and -focused solely on hardware configuration). - -An obvious improvement to this approach is the following. There're few -well-known boards which run MicroPython, and most of them include an -onboard LED. So, to help users of these boards to do configuration -quickly (that's especially important for novice users, for who may -be stumped by the need to reach out to a board reference to find LED -pin assignments), `hwconfig.py` your application ships may include -commented out sections with working configurations for different -boards. The step 1 above then will be: - -1. Look thru `hwconfig.py` to find a section which either exactly - matches your board, or the closest to it. Uncomment, and if any - adjustments required, apply them. - -It's important to keep in mind that adjustments may be always required, -and that there may be users whose configuration doesn't match any of -the available. So, always include a section or instructions for them. -Consider for example that even on a supported board, user may want to -blink not an on-board LED, but the one they connected externally. -MicroPython's Hardware API offers portability not just among "supported" -boards, but to any board at all, so make sure users can enjoy it. - -There's next step of improvement to make. While having one `hwconfig.py` -with many sections would work for smaller projects with few hardware -objects, it may become more cumbersome to maintain both on programmer's -and user's sides for larger projects. Then instead of single -`hwconfig.py` file, you can provide few "template" ones for well-known -boards: - -* `hwconfig_pyboard.py` -* `hwconfig_wipy.py` -* `hwconfig_esp8266.py` -* etc. - -Then step 1 above will be: - -1. Look thru available `hwconfig_*.py` files and find one which matches - your board the best, then rename to `hwconfig.py` and make adjustments, - if any. - -Again, please keep in mind that there may be users whose hardware will be -completely unlike you heard of. Give them some helpful hints too, perhaps -provide `hwconfig_custom.py` with some instructions. - -That's where we stop with improvements to the "separate file for hardware -configuration" idea, as it is already pretty flexible and viable. An -application in this directory shows it in practice, using slightly less -trivial example than just a blinking LED: `soft_pwm.py` implements a -software PWM (pulse width modulation) to produce an LED fade-in/fade-out -effect - without any dependence on hardware PWM availability. - -Note that improvements to board configuration handling may continue further. -For example, one may invent a "configuration manager" helper module which will -try to detect current board (among well-known ones), and load appropriate -`hwconfig_*.py` - this assumes that a user would lazily deploy them all -(or that application will be automatically installed, e.g. using MicroPython's -`upip` package manager). The key point in this case remains the same as -elaborated above - always assume there can, and will be a custom configuration, -and it should be well supported. So, any automatic detection should be -overridable by a user, and instructions how to do so are among the most -important you may provide for your application. - -By following these best practices, you will use MicroPython at its full -potential, and let users enjoy it too. Good luck! diff --git a/examples/hwapi/button_led.py b/examples/hwapi/button_led.py deleted file mode 100644 index bd6fe017298..00000000000 --- a/examples/hwapi/button_led.py +++ /dev/null @@ -1,9 +0,0 @@ -import utime -from hwconfig import LED, BUTTON - -# Light LED when (and while) a BUTTON is pressed - -while 1: - LED.value(BUTTON.value()) - # Don't burn CPU - utime.sleep_ms(10) diff --git a/examples/hwapi/button_reaction.py b/examples/hwapi/button_reaction.py deleted file mode 100644 index b72e813e4c6..00000000000 --- a/examples/hwapi/button_reaction.py +++ /dev/null @@ -1,19 +0,0 @@ -import utime -import machine -from hwconfig import LED, BUTTON - -# machine.time_pulse_us() function demo - -print("""\ -Let's play an interesting game: -You click button as fast as you can, and I tell you how slow you are. -Ready? Cliiiiick! -""") - -while 1: - delay = machine.time_pulse_us(BUTTON, 1, 10*1000*1000) - if delay < 0: - print("Well, you're *really* slow") - else: - print("You are as slow as %d microseconds!" % delay) - utime.sleep_ms(10) diff --git a/examples/hwapi/hwconfig_console.py b/examples/hwapi/hwconfig_console.py deleted file mode 100644 index bbcc0e816ef..00000000000 --- a/examples/hwapi/hwconfig_console.py +++ /dev/null @@ -1,19 +0,0 @@ -# This is hwconfig for "emulation" for cases when there's no real hardware. -# It just prints information to console. -class LEDClass: - - def __init__(self, id): - self.id = "LED(%d):" % id - - def value(self, v): - print(self.id, v) - - def on(self): - self.value(1) - - def off(self): - self.value(0) - - -LED = LEDClass(1) -LED2 = LEDClass(12) diff --git a/examples/hwapi/hwconfig_dragonboard410c.py b/examples/hwapi/hwconfig_dragonboard410c.py deleted file mode 100644 index eec3582039c..00000000000 --- a/examples/hwapi/hwconfig_dragonboard410c.py +++ /dev/null @@ -1,22 +0,0 @@ -from machine import Pin, Signal - -# 96Boards/Qualcomm DragonBoard 410c -# -# By default, on-board LEDs are controlled by kernel LED driver. -# To make corresponding pins be available as normal GPIO, -# corresponding driver needs to be unbound first (as root): -# echo -n "soc:leds" >/sys/class/leds/apq8016-sbc:green:user1/device/driver/unbind -# Note that application also either should be run as root, or -# /sys/class/gpio ownership needs to be changed. -# Likewise, onboard buttons are controlled by gpio_keys driver. -# To release corresponding GPIOs: -# echo -n "gpio_keys" >/sys/class/input/input1/device/driver/unbind - -# User LED 1 on gpio21 -LED = Signal(Pin(21, Pin.OUT)) - -# User LED 2 on gpio120 -LED2 = Signal(Pin(120, Pin.OUT)) - -# Button S3 on gpio107 -BUTTON = Pin(107, Pin.IN) diff --git a/examples/hwapi/hwconfig_esp8266_esp12.py b/examples/hwapi/hwconfig_esp8266_esp12.py deleted file mode 100644 index 2e855ee3d38..00000000000 --- a/examples/hwapi/hwconfig_esp8266_esp12.py +++ /dev/null @@ -1,5 +0,0 @@ -from machine import Pin, Signal - -# ESP12 module as used by many boards -# Blue LED on pin 2, active low (inverted) -LED = Signal(2, Pin.OUT, invert=True) diff --git a/examples/hwapi/hwconfig_pyboard.py b/examples/hwapi/hwconfig_pyboard.py deleted file mode 100644 index fb260033e56..00000000000 --- a/examples/hwapi/hwconfig_pyboard.py +++ /dev/null @@ -1,13 +0,0 @@ -from machine import Pin, Signal - -# Red LED on pin LED_RED also kown as A13 -LED = Signal('LED_RED', Pin.OUT) - -# Green LED on pin LED_GREEN also known as A14 -LED2 = Signal('LED_GREEN', Pin.OUT) - -# Yellow LED on pin LED_YELLOW also known as A15 -LED3 = Signal('LED_YELLOW', Pin.OUT) - -# Blue LED on pin LED_BLUE also known as B4 -LED4 = Signal('LED_BLUE', Pin.OUT) diff --git a/examples/hwapi/hwconfig_z_96b_carbon.py b/examples/hwapi/hwconfig_z_96b_carbon.py deleted file mode 100644 index 97fd57a07ff..00000000000 --- a/examples/hwapi/hwconfig_z_96b_carbon.py +++ /dev/null @@ -1,9 +0,0 @@ -from machine import Signal - -# 96Boards Carbon board -# USR1 - User controlled led, connected to PD2 -# USR2 - User controlled led, connected to PA15 -# BT - Bluetooth indicator, connected to PB5. -# Note - 96b_carbon uses (at the time of writing) non-standard -# for Zephyr port device naming convention. -LED = Signal(("GPIOA", 15), Pin.OUT) diff --git a/examples/hwapi/hwconfig_z_frdm_k64f.py b/examples/hwapi/hwconfig_z_frdm_k64f.py deleted file mode 100644 index 377c6387877..00000000000 --- a/examples/hwapi/hwconfig_z_frdm_k64f.py +++ /dev/null @@ -1,5 +0,0 @@ -from machine import Pin, Signal - -# Freescale/NXP FRDM-K64F board -# Blue LED on port B, pin 21 -LED = Signal(("GPIO_1", 21), Pin.OUT) diff --git a/examples/hwapi/soft_pwm.py b/examples/hwapi/soft_pwm.py deleted file mode 100644 index 72291b0ecde..00000000000 --- a/examples/hwapi/soft_pwm.py +++ /dev/null @@ -1,38 +0,0 @@ -import utime -from hwconfig import LED - - -# Using sleep_ms() gives pretty poor PWM resolution and -# brightness control, but we use it in the attempt to -# make this demo portable to even more boards (e.g. to -# those which don't provide sleep_us(), or provide, but -# it's not precise, like would be on non realtime OSes). -# We otherwise use 20ms period, to make frequency not less -# than 50Hz to avoid visible flickering (you may still see -# if you're unlucky). -def pwm_cycle(led, duty, cycles): - duty_off = 20 - duty - for i in range(cycles): - if duty: - led.on() - utime.sleep_ms(duty) - if duty_off: - led.off() - utime.sleep_ms(duty_off) - - -# At the duty setting of 1, an LED is still pretty bright, then -# at duty 0, it's off. This makes rather unsmooth transition, and -# breaks fade effect. So, we avoid value of 0 and oscillate between -# 1 and 20. Actually, highest values like 19 and 20 are also -# barely distinguishible (like, both of them too bright and burn -# your eye). So, improvement to the visible effect would be to use -# more steps (at least 10x), and then higher frequency, and use -# range which includes 1 but excludes values at the top. -while True: - # Fade in - for i in range(1, 21): - pwm_cycle(LED, i, 2) - # Fade out - for i in range(20, 0, -1): - pwm_cycle(LED, i, 2) diff --git a/examples/hwapi/soft_pwm2_uasyncio.py b/examples/hwapi/soft_pwm2_uasyncio.py deleted file mode 100644 index 908ef2d8ac2..00000000000 --- a/examples/hwapi/soft_pwm2_uasyncio.py +++ /dev/null @@ -1,31 +0,0 @@ -# Like soft_pwm_uasyncio.py, but fading 2 LEDs with different phase. -# Also see original soft_pwm.py. -import uasyncio -from hwconfig import LED, LED2 - - -async def pwm_cycle(led, duty, cycles): - duty_off = 20 - duty - for i in range(cycles): - if duty: - led.value(1) - await uasyncio.sleep_ms(duty) - if duty_off: - led.value(0) - await uasyncio.sleep_ms(duty_off) - - -async def fade_in_out(LED): - while True: - # Fade in - for i in range(1, 21): - await pwm_cycle(LED, i, 2) - # Fade out - for i in range(20, 0, -1): - await pwm_cycle(LED, i, 2) - - -loop = uasyncio.get_event_loop() -loop.create_task(fade_in_out(LED)) -loop.call_later_ms(800, fade_in_out(LED2)) -loop.run_forever() diff --git a/examples/hwapi/soft_pwm_uasyncio.py b/examples/hwapi/soft_pwm_uasyncio.py deleted file mode 100644 index 8d7ad8c9e07..00000000000 --- a/examples/hwapi/soft_pwm_uasyncio.py +++ /dev/null @@ -1,28 +0,0 @@ -# See original soft_pwm.py for detailed comments. -import uasyncio -from hwconfig import LED - - -async def pwm_cycle(led, duty, cycles): - duty_off = 20 - duty - for i in range(cycles): - if duty: - led.value(1) - await uasyncio.sleep_ms(duty) - if duty_off: - led.value(0) - await uasyncio.sleep_ms(duty_off) - - -async def fade_in_out(LED): - while True: - # Fade in - for i in range(1, 21): - await pwm_cycle(LED, i, 2) - # Fade out - for i in range(20, 0, -1): - await pwm_cycle(LED, i, 2) - - -loop = uasyncio.get_event_loop() -loop.run_until_complete(fade_in_out(LED)) diff --git a/examples/ledangle.py b/examples/ledangle.py deleted file mode 100644 index 8c8d9e99d95..00000000000 --- a/examples/ledangle.py +++ /dev/null @@ -1,25 +0,0 @@ -import pyb - -def led_angle(seconds_to_run_for): - # make LED objects - l1 = pyb.LED(1) - l2 = pyb.LED(2) - accel = pyb.Accel() - - for i in range(20 * seconds_to_run_for): - # get x-axis - x = accel.x() - - # turn on LEDs depending on angle - if x < -10: - l1.on() - l2.off() - elif x > 10: - l1.off() - l2.on() - else: - l1.off() - l2.off() - - # delay so that loop runs at at 1/50ms = 20Hz - pyb.delay(50) diff --git a/examples/mandel.py b/examples/mandel.py deleted file mode 100644 index bbb80864702..00000000000 --- a/examples/mandel.py +++ /dev/null @@ -1,27 +0,0 @@ -try: - import micropython -except: - pass - -def mandelbrot(): - # returns True if c, complex, is in the Mandelbrot set - #@micropython.native - def in_set(c): - z = 0 - for i in range(40): - z = z*z + c - if abs(z) > 60: - return False - return True - - lcd.clear() - for u in range(91): - for v in range(31): - if in_set((u / 30 - 2) + (v / 15 - 1) * 1j): - lcd.set(u, v) - lcd.show() - -# PC testing -import lcd -lcd = lcd.LCD(128, 32) -mandelbrot() diff --git a/examples/micropython.py b/examples/micropython.py deleted file mode 100644 index f91da94f41e..00000000000 --- a/examples/micropython.py +++ /dev/null @@ -1,8 +0,0 @@ -# micropython module placeholder for CPython - -# Dummy function decorators - -def nodecor(x): - return x - -bytecode = native = viper = nodecor diff --git a/examples/network/http_client.py b/examples/network/http_client.py deleted file mode 100644 index 0791c8066b6..00000000000 --- a/examples/network/http_client.py +++ /dev/null @@ -1,30 +0,0 @@ -try: - import usocket as socket -except: - import socket - - -def main(use_stream=False): - s = socket.socket() - - ai = socket.getaddrinfo("google.com", 80) - print("Address infos:", ai) - addr = ai[0][-1] - - print("Connect address:", addr) - s.connect(addr) - - if use_stream: - # MicroPython socket objects support stream (aka file) interface - # directly, but the line below is needed for CPython. - s = s.makefile("rwb", 0) - s.write(b"GET / HTTP/1.0\r\n\r\n") - print(s.read()) - else: - s.send(b"GET / HTTP/1.0\r\n\r\n") - print(s.recv(4096)) - - s.close() - - -main() diff --git a/examples/network/http_client_ssl.py b/examples/network/http_client_ssl.py deleted file mode 100644 index 83f685fdf35..00000000000 --- a/examples/network/http_client_ssl.py +++ /dev/null @@ -1,38 +0,0 @@ -try: - import usocket as _socket -except: - import _socket -try: - import ussl as ssl -except: - import ssl - - -def main(use_stream=True): - s = _socket.socket() - - ai = _socket.getaddrinfo("google.com", 443) - print("Address infos:", ai) - addr = ai[0][-1] - - print("Connect address:", addr) - s.connect(addr) - - s = ssl.wrap_socket(s) - print(s) - - if use_stream: - # Both CPython and MicroPython SSLSocket objects support read() and - # write() methods. - s.write(b"GET / HTTP/1.0\r\n\r\n") - print(s.read(4096)) - else: - # MicroPython SSLSocket objects implement only stream interface, not - # socket interface - s.send(b"GET / HTTP/1.0\r\n\r\n") - print(s.recv(4096)) - - s.close() - - -main() diff --git a/examples/network/http_server.py b/examples/network/http_server.py deleted file mode 100644 index e3a66e82838..00000000000 --- a/examples/network/http_server.py +++ /dev/null @@ -1,64 +0,0 @@ -try: - import usocket as socket -except: - import socket - - -CONTENT = b"""\ -HTTP/1.0 200 OK - -Hello #%d from MicroPython! -""" - -def main(micropython_optimize=False): - s = socket.socket() - - # Binding to all interfaces - server will be accessible to other hosts! - ai = socket.getaddrinfo("0.0.0.0", 8080) - print("Bind address info:", ai) - addr = ai[0][-1] - - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - s.bind(addr) - s.listen(5) - print("Listening, connect your browser to http://:8080/") - - counter = 0 - while True: - res = s.accept() - client_sock = res[0] - client_addr = res[1] - print("Client address:", client_addr) - print("Client socket:", client_sock) - - if not micropython_optimize: - # To read line-oriented protocol (like HTTP) from a socket (and - # avoid short read problem), it must be wrapped in a stream (aka - # file-like) object. That's how you do it in CPython: - client_stream = client_sock.makefile("rwb") - else: - # .. but MicroPython socket objects support stream interface - # directly, so calling .makefile() method is not required. If - # you develop application which will run only on MicroPython, - # especially on a resource-constrained embedded device, you - # may take this shortcut to save resources. - client_stream = client_sock - - print("Request:") - req = client_stream.readline() - print(req) - while True: - h = client_stream.readline() - if h == b"" or h == b"\r\n": - break - print(h) - client_stream.write(CONTENT % counter) - - client_stream.close() - if not micropython_optimize: - client_sock.close() - counter += 1 - print() - - -main() diff --git a/examples/network/http_server_simplistic.py b/examples/network/http_server_simplistic.py deleted file mode 100644 index 67ecb1ad7ad..00000000000 --- a/examples/network/http_server_simplistic.py +++ /dev/null @@ -1,40 +0,0 @@ -# Do not use this code in real projects! Read -# http_server_simplistic_commented.py for details. -try: - import usocket as socket -except: - import socket - - -CONTENT = b"""\ -HTTP/1.0 200 OK - -Hello #%d from MicroPython! -""" - -def main(): - s = socket.socket() - ai = socket.getaddrinfo("0.0.0.0", 8080) - addr = ai[0][-1] - - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - - s.bind(addr) - s.listen(5) - print("Listening, connect your browser to http://:8080/") - - counter = 0 - while True: - res = s.accept() - client_s = res[0] - client_addr = res[1] - req = client_s.recv(4096) - print("Request:") - print(req) - client_s.send(CONTENT % counter) - client_s.close() - counter += 1 - print() - - -main() diff --git a/examples/network/http_server_simplistic_commented.py b/examples/network/http_server_simplistic_commented.py deleted file mode 100644 index b58e9eeb60e..00000000000 --- a/examples/network/http_server_simplistic_commented.py +++ /dev/null @@ -1,76 +0,0 @@ -# -# MicroPython http_server_simplistic.py example -# -# This example shows how to write the smallest possible HTTP -# server in MicroPython. With comments and convenience code -# removed, this example can be compressed literally to ten -# lines. There's a catch though - read comments below for -# details, and use this code only for quick hacks, preferring -# http_server.py for "real thing". -# -try: - import usocket as socket -except: - import socket - - -CONTENT = b"""\ -HTTP/1.0 200 OK - -Hello #%d from MicroPython! -""" - -def main(): - s = socket.socket() - - # Bind to (allow to be connected on ) all interfaces. This means - # this server will be accessible to other hosts on your local - # network, and if your server has direct (non-firewalled) connection - # to the Internet, then to anyone on the Internet. We bind to all - # interfaces to let this example work easily on embedded MicroPython - # targets, which you will likely access from another machine on your - # local network. Take care when running this on an Internet-connected - # machine though! Replace "0.0.0.0" with "127.0.0.1" if in doubt, to - # make the server accessible only on the machine it runs on. - ai = socket.getaddrinfo("0.0.0.0", 8080) - print("Bind address info:", ai) - addr = ai[0][-1] - - # A port on which a socket listened remains inactive during some time. - # This means that if you run this sample, terminate it, and run again - # you will likely get an error. To avoid this timeout, set SO_REUSEADDR - # socket option. - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - - s.bind(addr) - s.listen(5) - print("Listening, connect your browser to http://:8080/") - - counter = 0 - while True: - res = s.accept() - client_s = res[0] - client_addr = res[1] - print("Client address:", client_addr) - print("Client socket:", client_s) - # We assume here that .recv() call will read entire HTTP request - # from client. This is usually true, at least on "big OS" systems - # like Linux/MacOS/Windows. But that doesn't have to be true in - # all cases, in particular on embedded systems, when there can - # easily be "short recv", where it returns much less than requested - # data size. That's why this example is called "simplistic" - it - # shows that writing a web server in Python that *usually works* is - # ten lines of code, and you can use this technique for quick hacks - # and experimentation. But don't do it like that in production - # applications - instead, parse HTTP request properly, as shown - # by http_server.py example. - req = client_s.recv(4096) - print("Request:") - print(req) - client_s.send(CONTENT % counter) - client_s.close() - counter += 1 - print() - - -main() diff --git a/examples/network/http_server_ssl.py b/examples/network/http_server_ssl.py deleted file mode 100644 index 9a69ca9d417..00000000000 --- a/examples/network/http_server_ssl.py +++ /dev/null @@ -1,64 +0,0 @@ -try: - import usocket as socket -except: - import socket -import ussl as ssl - - -CONTENT = b"""\ -HTTP/1.0 200 OK - -Hello #%d from MicroPython! -""" - -def main(use_stream=True): - s = socket.socket() - - # Binding to all interfaces - server will be accessible to other hosts! - ai = socket.getaddrinfo("0.0.0.0", 8443) - print("Bind address info:", ai) - addr = ai[0][-1] - - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - s.bind(addr) - s.listen(5) - print("Listening, connect your browser to https://:8443/") - - counter = 0 - while True: - res = s.accept() - client_s = res[0] - client_addr = res[1] - print("Client address:", client_addr) - print("Client socket:", client_s) - client_s = ssl.wrap_socket(client_s, server_side=True) - print(client_s) - print("Request:") - if use_stream: - # Both CPython and MicroPython SSLSocket objects support read() and - # write() methods. - # Browsers are prone to terminate SSL connection abruptly if they - # see unknown certificate, etc. We must continue in such case - - # next request they issue will likely be more well-behaving and - # will succeed. - try: - req = client_s.readline() - print(req) - while True: - h = client_s.readline() - if h == b"" or h == b"\r\n": - break - print(h) - if req: - client_s.write(CONTENT % counter) - except Exception as e: - print("Exception serving request:", e) - else: - print(client_s.recv(4096)) - client_s.send(CONTENT % counter) - client_s.close() - counter += 1 - print() - - -main() diff --git a/examples/pins.py b/examples/pins.py deleted file mode 100644 index aafdb481339..00000000000 --- a/examples/pins.py +++ /dev/null @@ -1,58 +0,0 @@ -# Print a nice list of pins, their current settings, and available afs. -# Requires pins_af.py from ports/stm32/build-PYBV10/ directory. - -import pyb -import pins_af - -def af(): - max_name_width = 0 - max_af_width = 0 - for pin_entry in pins_af.PINS_AF: - max_name_width = max(max_name_width, len(pin_entry[0])) - for af_entry in pin_entry[1:]: - max_af_width = max(max_af_width, len(af_entry[1])) - for pin_entry in pins_af.PINS_AF: - pin_name = pin_entry[0] - print('%-*s ' % (max_name_width, pin_name), end='') - for af_entry in pin_entry[1:]: - print('%2d: %-*s ' % (af_entry[0], max_af_width, af_entry[1]), end='') - print('') - -def pins(): - mode_str = { pyb.Pin.IN : 'IN', - pyb.Pin.OUT_PP : 'OUT_PP', - pyb.Pin.OUT_OD : 'OUT_OD', - pyb.Pin.AF_PP : 'AF_PP', - pyb.Pin.AF_OD : 'AF_OD', - pyb.Pin.ANALOG : 'ANALOG' } - pull_str = { pyb.Pin.PULL_NONE : '', - pyb.Pin.PULL_UP : 'PULL_UP', - pyb.Pin.PULL_DOWN : 'PULL_DOWN' } - width = [0, 0, 0, 0] - rows = [] - for pin_entry in pins_af.PINS_AF: - row = [] - pin_name = pin_entry[0] - pin = pyb.Pin(pin_name) - pin_mode = pin.mode() - row.append(pin_name) - row.append(mode_str[pin_mode]) - row.append(pull_str[pin.pull()]) - if pin_mode == pyb.Pin.AF_PP or pin_mode == pyb.Pin.AF_OD: - pin_af = pin.af() - for af_entry in pin_entry[1:]: - if pin_af == af_entry[0]: - af_str = '%d: %s' % (pin_af, af_entry[1]) - break - else: - af_str = '%d' % pin_af - else: - af_str = '' - row.append(af_str) - for col in range(len(width)): - width[col] = max(width[col], len(row[col])) - rows.append(row) - for row in rows: - for col in range(len(width)): - print('%-*s ' % (width[col], row[col]), end='') - print('') diff --git a/examples/pyb.py b/examples/pyb.py deleted file mode 100644 index b303777e5a8..00000000000 --- a/examples/pyb.py +++ /dev/null @@ -1,49 +0,0 @@ -# pyboard testing functions for CPython -import time - -def delay(n): - #time.sleep(float(n) / 1000) - pass - -rand_seed = 1 -def rng(): - global rand_seed - # for these choice of numbers, see P L'Ecuyer, "Tables of linear congruential generators of different sizes and good lattice structure" - rand_seed = (rand_seed * 653276) % 8388593 - return rand_seed - -# LCD testing object for PC -# uses double buffering -class LCD: - def __init__(self, port): - self.width = 128 - self.height = 32 - self.buf1 = [[0 for x in range(self.width)] for y in range(self.height)] - self.buf2 = [[0 for x in range(self.width)] for y in range(self.height)] - - def light(self, value): - pass - - def fill(self, value): - for y in range(self.height): - for x in range(self.width): - self.buf1[y][x] = self.buf2[y][x] = value - - def show(self): - print('') # blank line to separate frames - for y in range(self.height): - for x in range(self.width): - self.buf1[y][x] = self.buf2[y][x] - for y in range(self.height): - row = ''.join(['*' if self.buf1[y][x] else ' ' for x in range(self.width)]) - print(row) - - def get(self, x, y): - if 0 <= x < self.width and 0 <= y < self.height: - return self.buf1[y][x] - else: - return 0 - - def pixel(self, x, y, value): - if 0 <= x < self.width and 0 <= y < self.height: - self.buf2[y][x] = value diff --git a/examples/switch.py b/examples/switch.py deleted file mode 100644 index 0efaf226759..00000000000 --- a/examples/switch.py +++ /dev/null @@ -1,45 +0,0 @@ -""" -switch.py -========= - -Light up some leds when the USR switch on the pyboard is pressed. - -Example Usage:: - - Micro Python v1.0.1 on 2014-05-12; PYBv1.0 with STM32F405RG - Type "help()" for more information. - >>> import switch - >>> switch.run_loop() - Loop started. - Press Ctrl+C to break out of the loop. - -""" - -import pyb - -switch = pyb.Switch() -red_led = pyb.LED(1) -green_led = pyb.LED(2) -orange_led = pyb.LED(3) -blue_led = pyb.LED(4) -all_leds = (red_led, green_led, orange_led, blue_led) - -def run_loop(leds=all_leds): - """ - Start the loop. - - :param `leds`: Which LEDs to light up upon switch press. - :type `leds`: sequence of LED objects - """ - print('Loop started.\nPress Ctrl+C to break out of the loop.') - while 1: - try: - if switch(): - [led.on() for led in leds] - else: - [led.off() for led in leds] - except OSError: # VCPInterrupt # Ctrl+C in interpreter mode. - break - -if __name__ == '__main__': - run_loop() diff --git a/examples/unix/ffi_example.py b/examples/unix/ffi_example.py deleted file mode 100644 index f650e33708e..00000000000 --- a/examples/unix/ffi_example.py +++ /dev/null @@ -1,38 +0,0 @@ -import ffi - -libc = ffi.open("libc.so.6") -print("libc:", libc) -print() - -# Declare few functions -perror = libc.func("v", "perror", "s") -time = libc.func("i", "time", "p") -open = libc.func("i", "open", "si") -qsort = libc.func("v", "qsort", "piip") -# And one variable -errno = libc.var("i", "errno") - -print("time:", time) -print("UNIX time is:", time(None)) -print() - -perror("ffi before error") -open("somethingnonexistent__", 0) -print("errno object:", errno) -print("errno value:", errno.get()) -perror("ffi after error") -print() - -def cmp(pa, pb): - a = ffi.as_bytearray(pa, 1) - b = ffi.as_bytearray(pb, 1) - print("cmp:", a, b) - return a[0] - b[0] - -cmp_c = ffi.callback("i", cmp, "pp") -print("callback:", cmp_c) - -s = bytearray(b"foobar") -print("org string:", s) -qsort(s, len(s), 1, cmp_c) -print("qsort'ed string:", s) diff --git a/examples/unix/machine_bios.py b/examples/unix/machine_bios.py deleted file mode 100644 index f62e4dbdb45..00000000000 --- a/examples/unix/machine_bios.py +++ /dev/null @@ -1,9 +0,0 @@ -# This example shows how to access Video BIOS memory area via machine.mem -# It requires root privilege and x86 legacy harfware (which has mentioned -# Video BIOS at all). -# It is expected to print 0xaa55, which is a signature at the start of -# Video BIOS. - -import umachine as machine - -print(hex(machine.mem16[0xc0000])) diff --git a/extmod/lwip-include/lwipopts.h b/extmod/lwip-include/lwipopts.h index 2122f30f044..805bec2230d 100644 --- a/extmod/lwip-include/lwipopts.h +++ b/extmod/lwip-include/lwipopts.h @@ -23,7 +23,7 @@ typedef uint32_t sys_prot_t; #define LWIP_NETCONN 0 #define LWIP_SOCKET 0 -#ifdef MICROPY_PY_LWIP_SLIP +#if MICROPY_PY_LWIP_SLIP #define LWIP_HAVE_SLIPIF 1 #endif diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c index 5d441b1ba77..85b46a9f6bd 100644 --- a/extmod/machine_i2c.c +++ b/extmod/machine_i2c.c @@ -33,6 +33,8 @@ #include "py/runtime.h" #include "extmod/machine_i2c.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_MACHINE_I2C typedef mp_machine_soft_i2c_obj_t machine_i2c_obj_t; @@ -285,16 +287,16 @@ STATIC void machine_i2c_obj_init_helper(machine_i2c_obj_t *self, size_t n_args, mp_hal_i2c_init(self, args[ARG_freq].u_int); } -STATIC mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { // check the id argument, if given if (n_args > 0) { if (args[0] != MP_OBJ_NEW_SMALL_INT(-1)) { #if defined(MICROPY_PY_MACHINE_I2C_MAKE_NEW) // dispatch to port-specific constructor - extern mp_obj_t MICROPY_PY_MACHINE_I2C_MAKE_NEW(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args); - return MICROPY_PY_MACHINE_I2C_MAKE_NEW(type, n_args, n_kw, args); + extern mp_obj_t MICROPY_PY_MACHINE_I2C_MAKE_NEW(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *all_args, mp_map_t *kw_args); + return MICROPY_PY_MACHINE_I2C_MAKE_NEW(type, n_args, args, kw_args); #else - mp_raise_ValueError("invalid I2C peripheral"); + mp_raise_ValueError(translate("invalid I2C peripheral")); #endif } --n_args; @@ -304,9 +306,7 @@ STATIC mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, s // create new soft I2C object machine_i2c_obj_t *self = m_new_obj(machine_i2c_obj_t); self->base.type = &machine_i2c_type; - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); - machine_i2c_obj_init_helper(self, n_args, args, &kw_args); + machine_i2c_obj_init_helper(self, n_args, args, kw_args); return (mp_obj_t)self; } @@ -335,7 +335,7 @@ STATIC mp_obj_t machine_i2c_start(mp_obj_t self_in) { mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(self_in); mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol; if (i2c_p->start == NULL) { - mp_raise_msg(&mp_type_OSError, "I2C operation not supported"); + mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported")); } int ret = i2c_p->start(self); if (ret != 0) { @@ -349,7 +349,7 @@ STATIC mp_obj_t machine_i2c_stop(mp_obj_t self_in) { mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(self_in); mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol; if (i2c_p->stop == NULL) { - mp_raise_msg(&mp_type_OSError, "I2C operation not supported"); + mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported")); } int ret = i2c_p->stop(self); if (ret != 0) { @@ -363,7 +363,7 @@ STATIC mp_obj_t machine_i2c_readinto(size_t n_args, const mp_obj_t *args) { mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(args[0]); mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol; if (i2c_p->read == NULL) { - mp_raise_msg(&mp_type_OSError, "I2C operation not supported"); + mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported")); } // get the buffer to read into @@ -387,7 +387,7 @@ STATIC mp_obj_t machine_i2c_write(mp_obj_t self_in, mp_obj_t buf_in) { mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(self_in); mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol; if (i2c_p->write == NULL) { - mp_raise_msg(&mp_type_OSError, "I2C operation not supported"); + mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported")); } // get the buffer to write from diff --git a/extmod/machine_mem.c b/extmod/machine_mem.c index b9f16507c4b..e0649290ef2 100644 --- a/extmod/machine_mem.c +++ b/extmod/machine_mem.c @@ -42,7 +42,7 @@ STATIC uintptr_t machine_mem_get_addr(mp_obj_t addr_o, uint align) { uintptr_t addr = mp_obj_int_get_truncated(addr_o); if ((addr & (align - 1)) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "address %08x is not aligned to %d bytes", addr, align)); + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, translate("address %08x is not aligned to %d bytes"), addr, align)); } return addr; } diff --git a/extmod/machine_pinbase.c b/extmod/machine_pinbase.c index 070c5cde9d3..997a6fd991d 100644 --- a/extmod/machine_pinbase.c +++ b/extmod/machine_pinbase.c @@ -45,11 +45,11 @@ STATIC const mp_pinbase_t pinbase_singleton = { .base = { &machine_pinbase_type }, }; -STATIC mp_obj_t pinbase_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t pinbase_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type; (void)n_args; - (void)n_kw; (void)args; + (void)kw_args; return MP_OBJ_FROM_PTR(&pinbase_singleton); } diff --git a/extmod/machine_signal.c b/extmod/machine_signal.c index 3f9f5af9477..62658cbb172 100644 --- a/extmod/machine_signal.c +++ b/extmod/machine_signal.c @@ -42,7 +42,7 @@ typedef struct _machine_signal_t { bool invert; } machine_signal_t; -STATIC mp_obj_t signal_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t signal_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { mp_obj_t pin = args[0]; bool invert = false; @@ -96,9 +96,9 @@ STATIC mp_obj_t signal_make_new(const mp_obj_type_t *type, size_t n_args, size_t // Otherwise there should be 1 or 2 args { if (n_args == 1) { - if (n_kw == 0) { - } else if (n_kw == 1 && args[1] == MP_OBJ_NEW_QSTR(MP_QSTR_invert)) { - invert = mp_obj_is_true(args[2]); + if (kw_args == NULL || kw_args->used == 0) { + } else if (kw_args->used == 1 && kw_args->table[0].key == MP_OBJ_NEW_QSTR(MP_QSTR_invert)) { + invert = mp_obj_is_true(kw_args->table[0].value); } else { goto error; } @@ -133,7 +133,7 @@ STATIC mp_uint_t signal_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg // fast method for getting/setting signal value STATIC mp_obj_t signal_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 1, false); + mp_arg_check_num_kw_array(n_args, n_kw, 0, 1, false); if (n_args == 0) { // get pin return MP_OBJ_NEW_SMALL_INT(mp_virtual_pin_read(self_in)); diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c index f0c4896c2e5..c5707a3d0b0 100644 --- a/extmod/machine_spi.c +++ b/extmod/machine_spi.c @@ -30,6 +30,8 @@ #include "py/runtime.h" #include "extmod/machine_spi.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_MACHINE_SPI // if a port didn't define MSB/LSB constants then provide them @@ -41,18 +43,18 @@ /******************************************************************************/ // MicroPython bindings for generic machine.SPI -STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args); +STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); -mp_obj_t mp_machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +mp_obj_t mp_machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { // check the id argument, if given if (n_args > 0) { if (args[0] != MP_OBJ_NEW_SMALL_INT(-1)) { #if defined(MICROPY_PY_MACHINE_SPI_MAKE_NEW) // dispatch to port-specific constructor - extern mp_obj_t MICROPY_PY_MACHINE_SPI_MAKE_NEW(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args); - return MICROPY_PY_MACHINE_SPI_MAKE_NEW(type, n_args, n_kw, args); + extern mp_obj_t MICROPY_PY_MACHINE_SPI_MAKE_NEW(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); + return MICROPY_PY_MACHINE_SPI_MAKE_NEW(type, n_args, args, kw_args); #else - mp_raise_ValueError("invalid SPI peripheral"); + mp_raise_ValueError(translate("invalid SPI peripheral")); #endif } --n_args; @@ -60,7 +62,7 @@ mp_obj_t mp_machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_ } // software SPI - return mp_machine_soft_spi_make_new(type, n_args, n_kw, args); + return mp_machine_soft_spi_make_new(type, n_args, args, kw_args); } STATIC mp_obj_t machine_spi_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { @@ -119,7 +121,7 @@ STATIC mp_obj_t mp_machine_spi_write_readinto(mp_obj_t self, mp_obj_t wr_buf, mp mp_buffer_info_t dest; mp_get_buffer_raise(rd_buf, &dest, MP_BUFFER_WRITE); if (src.len != dest.len) { - mp_raise_ValueError("buffers must be the same length"); + mp_raise_ValueError(translate("buffers must be the same length")); } mp_machine_spi_transfer(self, src.len, src.buf, dest.buf); return mp_const_none; @@ -178,7 +180,7 @@ STATIC void mp_machine_soft_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_hal_pin_name(self->spi.sck), mp_hal_pin_name(self->spi.mosi), mp_hal_pin_name(self->spi.miso)); } -STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { +STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *all_args, mp_map_t *kw_args) { enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_sck, ARG_mosi, ARG_miso }; static const mp_arg_t allowed_args[] = { { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 500000} }, @@ -191,7 +193,7 @@ STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n { MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + mp_arg_parse_all(n_args, all_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); // create new object mp_machine_soft_spi_obj_t *self = m_new_obj(mp_machine_soft_spi_obj_t); @@ -202,15 +204,15 @@ STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n self->spi.polarity = args[ARG_polarity].u_int; self->spi.phase = args[ARG_phase].u_int; if (args[ARG_bits].u_int != 8) { - mp_raise_ValueError("bits must be 8"); + mp_raise_ValueError(translate("bits must be 8")); } if (args[ARG_firstbit].u_int != MICROPY_PY_MACHINE_SPI_MSB) { - mp_raise_ValueError("firstbit must be MSB"); + mp_raise_ValueError(translate("firstbit must be MSB")); } if (args[ARG_sck].u_obj == MP_OBJ_NULL || args[ARG_mosi].u_obj == MP_OBJ_NULL || args[ARG_miso].u_obj == MP_OBJ_NULL) { - mp_raise_ValueError("must specify all of sck/mosi/miso"); + mp_raise_ValueError(translate("must specify all of sck/mosi/miso")); } self->spi.sck = mp_hal_get_pin_obj(args[ARG_sck].u_obj); self->spi.mosi = mp_hal_get_pin_obj(args[ARG_mosi].u_obj); diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index a7f6ba905fb..f92312a231b 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -259,8 +259,8 @@ STATIC void fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, u formats[fb->format].fill_rect(fb, x, y, xend - x, yend - y, col); } -STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 4, 5, false); +STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 4, 5, false); mp_obj_framebuf_t *o = m_new_obj(mp_obj_framebuf_t); o->base.type = type; @@ -296,7 +296,7 @@ STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size case FRAMEBUF_GS8: break; default: - mp_raise_ValueError("invalid format"); + mp_raise_ValueError(translate("invalid format")); } return MP_OBJ_FROM_PTR(o); diff --git a/extmod/modlwip.c b/extmod/modlwip.c index dfb5de9e40d..e5e92c42b5d 100644 --- a/extmod/modlwip.c +++ b/extmod/modlwip.c @@ -69,12 +69,12 @@ #define ip_reset_option(pcb, opt) ((pcb)->so_options &= ~(opt)) #endif -#ifdef MICROPY_PY_LWIP_SLIP +#if MICROPY_PY_LWIP_SLIP #include "netif/slipif.h" #include "lwip/sio.h" #endif -#ifdef MICROPY_PY_LWIP_SLIP +#if MICROPY_PY_LWIP_SLIP /******************************************************************************/ // Slip object for modlwip. Requires a serial driver for the port that supports // the lwip serial callback functions. @@ -1419,7 +1419,7 @@ STATIC mp_obj_t lwip_print_pcbs() { } MP_DEFINE_CONST_FUN_OBJ_0(lwip_print_pcbs_obj, lwip_print_pcbs); -#ifdef MICROPY_PY_LWIP +#if MICROPY_PY_LWIP STATIC const mp_rom_map_elem_t mp_module_lwip_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_lwip) }, @@ -1429,7 +1429,7 @@ STATIC const mp_rom_map_elem_t mp_module_lwip_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_print_pcbs), MP_ROM_PTR(&lwip_print_pcbs_obj) }, // objects { MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&lwip_socket_type) }, -#ifdef MICROPY_PY_LWIP_SLIP +#if MICROPY_PY_LWIP_SLIP { MP_ROM_QSTR(MP_QSTR_slip), MP_ROM_PTR(&lwip_slip_type) }, #endif // class constants diff --git a/extmod/modubinascii.c b/extmod/modubinascii.c index 8256a50cf20..0f64b271517 100644 --- a/extmod/modubinascii.c +++ b/extmod/modubinascii.c @@ -32,11 +32,20 @@ #include "py/binary.h" #include "extmod/modubinascii.h" +static void check_not_unicode(const mp_obj_t arg) { +#if MICROPY_CPYTHON_COMPAT + if (MP_OBJ_IS_STR(arg)) { + mp_raise_TypeError(translate("a bytes-like object is required")); + } +#endif +} + mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) { // Second argument is for an extension to allow a separator to be used // between values. const char *sep = NULL; mp_buffer_info_t bufinfo; + check_not_unicode(args[0]); mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ); // Code below assumes non-zero buffer length when computing size with @@ -78,7 +87,7 @@ mp_obj_t mod_binascii_unhexlify(mp_obj_t data) { mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); if ((bufinfo.len & 1) != 0) { - mp_raise_ValueError("odd-length string"); + mp_raise_ValueError(translate("odd-length string")); } vstr_t vstr; vstr_init_len(&vstr, bufinfo.len / 2); @@ -89,7 +98,7 @@ mp_obj_t mod_binascii_unhexlify(mp_obj_t data) { if (unichar_isxdigit(hex_ch)) { hex_byte += unichar_xdigit_value(hex_ch); } else { - mp_raise_ValueError("non-hex digit found"); + mp_raise_ValueError(translate("non-hex digit found")); } if (i & 1) { hex_byte <<= 4; @@ -157,7 +166,7 @@ mp_obj_t mod_binascii_a2b_base64(mp_obj_t data) { } if (nbits) { - mp_raise_ValueError("incorrect padding"); + mp_raise_ValueError(translate("incorrect padding")); } return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); @@ -165,6 +174,7 @@ mp_obj_t mod_binascii_a2b_base64(mp_obj_t data) { MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_a2b_base64_obj, mod_binascii_a2b_base64); mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) { + check_not_unicode(data); mp_buffer_info_t bufinfo; mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); @@ -218,10 +228,11 @@ mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) { MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_b2a_base64_obj, mod_binascii_b2a_base64); #if MICROPY_PY_UBINASCII_CRC32 -#include "uzlib/tinf.h" +#include "../../lib/uzlib/src/tinf.h" mp_obj_t mod_binascii_crc32(size_t n_args, const mp_obj_t *args) { mp_buffer_info_t bufinfo; + check_not_unicode(args[0]); mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ); uint32_t crc = (n_args > 1) ? mp_obj_get_int_truncated(args[1]) : 0; crc = uzlib_crc32(bufinfo.buf, bufinfo.len, crc ^ 0xffffffff); @@ -233,7 +244,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_binascii_crc32_obj, 1, 2, mod_binascii_c #if MICROPY_PY_UBINASCII STATIC const mp_rom_map_elem_t mp_module_binascii_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ubinascii) }, + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_binascii) }, { MP_ROM_QSTR(MP_QSTR_hexlify), MP_ROM_PTR(&mod_binascii_hexlify_obj) }, { MP_ROM_QSTR(MP_QSTR_unhexlify), MP_ROM_PTR(&mod_binascii_unhexlify_obj) }, { MP_ROM_QSTR(MP_QSTR_a2b_base64), MP_ROM_PTR(&mod_binascii_a2b_base64_obj) }, diff --git a/extmod/moductypes.c b/extmod/moductypes.c index c3da083cf65..9eea30bf3ea 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -32,6 +32,8 @@ #include "py/objtuple.h" #include "py/binary.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_UCTYPES /// \module uctypes - Access data structures in memory @@ -117,11 +119,11 @@ typedef struct _mp_obj_uctypes_struct_t { } mp_obj_uctypes_struct_t; STATIC NORETURN void syntax_error(void) { - mp_raise_TypeError("syntax error in uctypes descriptor"); + mp_raise_TypeError(translate("syntax error in uctypes descriptor")); } -STATIC mp_obj_t uctypes_struct_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 2, 3, false); +STATIC mp_obj_t uctypes_struct_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 2, 3, false); mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t); o->base.type = type; o->addr = (void*)(uintptr_t)mp_obj_int_get_truncated(args[0]); @@ -214,7 +216,7 @@ STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, int layout_type, mp_uint_ // but scalar structure field is lowered into native Python int, so all // type info is lost. So, we cannot say if it's scalar type description, // or such lowered scalar. - mp_raise_TypeError("Cannot unambiguously get sizeof scalar"); + mp_raise_TypeError(translate("Cannot unambiguously get sizeof scalar")); } syntax_error(); } @@ -337,7 +339,7 @@ STATIC mp_obj_t get_aligned(uint val_type, void *p, mp_int_t index) { return mp_obj_new_int_from_ll(((int64_t*)p)[index]); #if MICROPY_PY_BUILTINS_FLOAT case FLOAT32: - return mp_obj_new_float(((float*)p)[index]); + return mp_obj_new_float((mp_float_t)((float*)p)[index]); case FLOAT64: return mp_obj_new_float(((double*)p)[index]); #endif @@ -392,7 +394,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set // TODO: Support at least OrderedDict in addition if (!MP_OBJ_IS_TYPE(self->desc, &mp_type_dict)) { - mp_raise_TypeError("struct: no fields"); + mp_raise_TypeError(translate("struct: no fields")); } mp_obj_t deref = mp_obj_dict_get(self->desc, MP_OBJ_NEW_QSTR(attr)); @@ -525,7 +527,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_ob } else { // load / store if (!MP_OBJ_IS_TYPE(self->desc, &mp_type_tuple)) { - mp_raise_TypeError("struct: cannot index"); + mp_raise_TypeError(translate("struct: cannot index")); } mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->desc); @@ -539,7 +541,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_ob uint val_type = GET_TYPE(arr_sz, VAL_TYPE_BITS); arr_sz &= VALUE_MASK(VAL_TYPE_BITS); if (index >= arr_sz) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "struct: index out of range")); + nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, translate("struct: index out of range"))); } if (t->len == 2) { diff --git a/extmod/moduhashlib.c b/extmod/moduhashlib.c index b3feb23bc75..970c63da82a 100644 --- a/extmod/moduhashlib.c +++ b/extmod/moduhashlib.c @@ -29,6 +29,8 @@ #include "py/runtime.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_UHASHLIB #if MICROPY_PY_UHASHLIB_SHA256 @@ -53,6 +55,7 @@ #endif + typedef struct _mp_obj_hash_t { mp_obj_base_t base; char state[0]; @@ -63,8 +66,8 @@ STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg); #if MICROPY_SSL_MBEDTLS -STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 1, false); +STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context)); o->base.type = type; mbedtls_sha256_init((mbedtls_sha256_context*)&o->state); @@ -93,8 +96,16 @@ STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) { #else -STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 1, false); +static void check_not_unicode(const mp_obj_t arg) { +#if MICROPY_CPYTHON_COMPAT + if (MP_OBJ_IS_STR(arg)) { + mp_raise_TypeError(translate("a bytes-like object is required")); + } +#endif +} + +STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX)); o->base.type = type; sha256_init((CRYAL_SHA256_CTX*)o->state); @@ -105,6 +116,7 @@ STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_arg } STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) { + check_not_unicode(arg); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_buffer_info_t bufinfo; mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); @@ -143,8 +155,8 @@ STATIC const mp_obj_type_t uhashlib_sha256_type = { STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg); #if MICROPY_SSL_AXTLS -STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 1, false); +STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(SHA1_CTX)); o->base.type = type; SHA1_Init((SHA1_CTX*)o->state); @@ -155,6 +167,7 @@ STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, } STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) { + check_not_unicode(arg); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_buffer_info_t bufinfo; mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); @@ -220,7 +233,7 @@ STATIC const mp_obj_type_t uhashlib_sha1_type = { #endif STATIC const mp_rom_map_elem_t mp_module_uhashlib_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uhashlib) }, + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_hashlib) }, #if MICROPY_PY_UHASHLIB_SHA256 { MP_ROM_QSTR(MP_QSTR_sha256), MP_ROM_PTR(&uhashlib_sha256_type) }, #endif diff --git a/extmod/moduheapq.c b/extmod/moduheapq.c index 71c15368bfe..db17e8ca21e 100644 --- a/extmod/moduheapq.c +++ b/extmod/moduheapq.c @@ -27,13 +27,15 @@ #include "py/objlist.h" #include "py/runtime.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_UHEAPQ // the algorithm here is modelled on CPython's heapq.py STATIC mp_obj_list_t *get_heap(mp_obj_t heap_in) { if (!MP_OBJ_IS_TYPE(heap_in, &mp_type_list)) { - mp_raise_TypeError("heap must be a list"); + mp_raise_TypeError(translate("heap must be a list")); } return MP_OBJ_TO_PTR(heap_in); } @@ -81,7 +83,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_uheapq_heappush_obj, mod_uheapq_heappush); STATIC mp_obj_t mod_uheapq_heappop(mp_obj_t heap_in) { mp_obj_list_t *heap = get_heap(heap_in); if (heap->len == 0) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "empty heap")); + nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, translate("empty heap"))); } mp_obj_t item = heap->items[0]; heap->len -= 1; diff --git a/extmod/modujson.c b/extmod/modujson.c index 830b588fdc9..6b24bf5781a 100644 --- a/extmod/modujson.c +++ b/extmod/modujson.c @@ -32,6 +32,8 @@ #include "py/runtime.h" #include "py/stream.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_UJSON STATIC mp_obj_t mod_ujson_dump(mp_obj_t obj, mp_obj_t stream) { @@ -276,7 +278,7 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) { return stack_top; fail: - mp_raise_ValueError("syntax error in JSON"); + mp_raise_ValueError(translate("syntax error in JSON")); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_load_obj, mod_ujson_load); @@ -290,7 +292,11 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_loads_obj, mod_ujson_loads); STATIC const mp_rom_map_elem_t mp_module_ujson_globals_table[] = { +#if CIRCUITPY + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_json) }, +#else { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ujson) }, +#endif { MP_ROM_QSTR(MP_QSTR_dump), MP_ROM_PTR(&mod_ujson_dump_obj) }, { MP_ROM_QSTR(MP_QSTR_dumps), MP_ROM_PTR(&mod_ujson_dumps_obj) }, { MP_ROM_QSTR(MP_QSTR_load), MP_ROM_PTR(&mod_ujson_load_obj) }, diff --git a/extmod/modure.c b/extmod/modure.c index 31c2b98647b..125afef4d3b 100644 --- a/extmod/modure.c +++ b/extmod/modure.c @@ -77,8 +77,83 @@ STATIC mp_obj_t match_group(mp_obj_t self_in, mp_obj_t no_in) { } MP_DEFINE_CONST_FUN_OBJ_2(match_group_obj, match_group); +#if MICROPY_PY_URE_MATCH_GROUPS + +STATIC mp_obj_t match_groups(mp_obj_t self_in) { + mp_obj_match_t *self = MP_OBJ_TO_PTR(self_in); + if (self->num_matches <= 1) { + return mp_const_empty_tuple; + } + mp_obj_tuple_t *groups = MP_OBJ_TO_PTR(mp_obj_new_tuple(self->num_matches - 1, NULL)); + for (int i = 1; i < self->num_matches; ++i) { + groups->items[i - 1] = match_group(self_in, MP_OBJ_NEW_SMALL_INT(i)); + } + return MP_OBJ_FROM_PTR(groups); +} +MP_DEFINE_CONST_FUN_OBJ_1(match_groups_obj, match_groups); + +#endif + +#if MICROPY_PY_URE_MATCH_SPAN_START_END + +STATIC void match_span_helper(size_t n_args, const mp_obj_t *args, mp_obj_t span[2]) { + mp_obj_match_t *self = MP_OBJ_TO_PTR(args[0]); + + mp_int_t no = 0; + if (n_args == 2) { + no = mp_obj_get_int(args[1]); + if (no < 0 || no >= self->num_matches) { + nlr_raise(mp_obj_new_exception_arg1(&mp_type_IndexError, args[1])); + } + } + + mp_int_t s = -1; + mp_int_t e = -1; + const char *start = self->caps[no * 2]; + if (start != NULL) { + // have a match for this group + const char *begin = mp_obj_str_get_str(self->str); + s = start - begin; + e = self->caps[no * 2 + 1] - begin; + } + + span[0] = mp_obj_new_int(s); + span[1] = mp_obj_new_int(e); +} + +STATIC mp_obj_t match_span(size_t n_args, const mp_obj_t *args) { + mp_obj_t span[2]; + match_span_helper(n_args, args, span); + return mp_obj_new_tuple(2, span); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(match_span_obj, 1, 2, match_span); + +STATIC mp_obj_t match_start(size_t n_args, const mp_obj_t *args) { + mp_obj_t span[2]; + match_span_helper(n_args, args, span); + return span[0]; +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(match_start_obj, 1, 2, match_start); + +STATIC mp_obj_t match_end(size_t n_args, const mp_obj_t *args) { + mp_obj_t span[2]; + match_span_helper(n_args, args, span); + return span[1]; +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(match_end_obj, 1, 2, match_end); + +#endif + STATIC const mp_rom_map_elem_t match_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_group), MP_ROM_PTR(&match_group_obj) }, + #if MICROPY_PY_URE_MATCH_GROUPS + { MP_ROM_QSTR(MP_QSTR_groups), MP_ROM_PTR(&match_groups_obj) }, + #endif + #if MICROPY_PY_URE_MATCH_SPAN_START_END + { MP_ROM_QSTR(MP_QSTR_span), MP_ROM_PTR(&match_span_obj) }, + { MP_ROM_QSTR(MP_QSTR_start), MP_ROM_PTR(&match_start_obj) }, + { MP_ROM_QSTR(MP_QSTR_end), MP_ROM_PTR(&match_end_obj) }, + #endif }; STATIC MP_DEFINE_CONST_DICT(match_locals_dict, match_locals_dict_table); @@ -103,6 +178,35 @@ STATIC mp_obj_t ure_exec(bool is_anchored, uint n_args, const mp_obj_t *args) { size_t len; subj.begin = mp_obj_str_get_data(args[1], &len); subj.end = subj.begin + len; +#if MICROPY_PY_URE_MATCH_SPAN_START_END + if (n_args > 2) { + const mp_obj_type_t *self_type = mp_obj_get_type(args[1]); + mp_int_t str_len = MP_OBJ_SMALL_INT_VALUE(mp_obj_len_maybe(args[1])); + const byte *begin = (const byte *)subj.begin; + + int pos = mp_obj_get_int(args[2]); + if (pos >= str_len) { + return mp_const_none; + } + if (pos < 0) { + pos = 0; + } + const byte *pos_ptr = str_index_to_ptr(self_type, begin, len, MP_OBJ_NEW_SMALL_INT(pos), true); + + const byte *endpos_ptr = (const byte *)subj.end; + if (n_args > 3) { + int endpos = mp_obj_get_int(args[3]); + if (endpos <= pos) { + return mp_const_none; + } + // Will cap to length + endpos_ptr = str_index_to_ptr(self_type, begin, len, args[3], true); + } + + subj.begin = (const char *)pos_ptr; + subj.end = (const char *)endpos_ptr; + } +#endif int caps_num = (self->re.sub + 1) * 2; mp_obj_match_t *match = m_new_obj_var(mp_obj_match_t, char*, caps_num); // cast is a workaround for a bug in msvc: it treats const char** as a const pointer instead of a pointer to pointer to const char @@ -158,7 +262,7 @@ STATIC mp_obj_t re_split(size_t n_args, const mp_obj_t *args) { mp_obj_t s = mp_obj_new_str_of_type(str_type, (const byte*)subj.begin, caps[0] - subj.begin); mp_obj_list_append(retval, s); if (self->re.sub > 0) { - mp_raise_NotImplementedError("Splitting with sub-captures"); + mp_raise_NotImplementedError(translate("Splitting with sub-captures")); } subj.begin = caps[1]; if (maxsplit > 0 && --maxsplit == 0) { @@ -174,17 +278,138 @@ STATIC mp_obj_t re_split(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_split_obj, 2, 3, re_split); +#if MICROPY_PY_URE_SUB + +STATIC mp_obj_t re_sub_helper(mp_obj_t self_in, size_t n_args, const mp_obj_t *args) { + mp_obj_re_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_t replace = args[1]; + mp_obj_t where = args[2]; + mp_int_t count = 0; + if (n_args > 3) { + count = mp_obj_get_int(args[3]); + // Note: flags are currently ignored + } + + size_t where_len; + const char *where_str = mp_obj_str_get_data(where, &where_len); + Subject subj; + subj.begin = where_str; + subj.end = subj.begin + where_len; + int caps_num = (self->re.sub + 1) * 2; + + vstr_t vstr_return; + vstr_return.buf = NULL; // We'll init the vstr after the first match + mp_obj_match_t *match = mp_local_alloc(sizeof(mp_obj_match_t) + caps_num * sizeof(char*)); + match->base.type = &match_type; + match->num_matches = caps_num / 2; // caps_num counts start and end pointers + match->str = where; + + for (;;) { + // cast is a workaround for a bug in msvc: it treats const char** as a const pointer instead of a pointer to pointer to const char + memset((char*)match->caps, 0, caps_num * sizeof(char*)); + int res = re1_5_recursiveloopprog(&self->re, &subj, match->caps, caps_num, false); + + // If we didn't have a match, or had an empty match, it's time to stop + if (!res || match->caps[0] == match->caps[1]) { + break; + } + + // Initialise the vstr if it's not already + if (vstr_return.buf == NULL) { + vstr_init(&vstr_return, match->caps[0] - subj.begin); + } + + // Add pre-match string + vstr_add_strn(&vstr_return, subj.begin, match->caps[0] - subj.begin); + + // Get replacement string + const char* repl = mp_obj_str_get_str((mp_obj_is_callable(replace) ? mp_call_function_1(replace, MP_OBJ_FROM_PTR(match)) : replace)); + + // Append replacement string to result, substituting any regex groups + while (*repl != '\0') { + if (*repl == '\\') { + ++repl; + bool is_g_format = false; + if (*repl == 'g' && repl[1] == '<') { + // Group specified with syntax "\g" + repl += 2; + is_g_format = true; + } + + if ('0' <= *repl && *repl <= '9') { + // Group specified with syntax "\g" or "\number" + unsigned int match_no = 0; + do { + match_no = match_no * 10 + (*repl++ - '0'); + } while ('0' <= *repl && *repl <= '9'); + if (is_g_format && *repl == '>') { + ++repl; + } + + if (match_no >= (unsigned int)match->num_matches) { + nlr_raise(mp_obj_new_exception_arg1(&mp_type_IndexError, MP_OBJ_NEW_SMALL_INT(match_no))); + } + + const char *start_match = match->caps[match_no * 2]; + if (start_match != NULL) { + // Add the substring matched by group + const char *end_match = match->caps[match_no * 2 + 1]; + vstr_add_strn(&vstr_return, start_match, end_match - start_match); + } + } + } else { + // Just add the current byte from the replacement string + vstr_add_byte(&vstr_return, *repl++); + } + } + + // Move start pointer to end of last match + subj.begin = match->caps[1]; + + // Stop substitutions if count was given and gets to 0 + if (count > 0 && --count == 0) { + break; + } + } + + mp_local_free(match); + + if (vstr_return.buf == NULL) { + // Optimisation for case of no substitutions + return where; + } + + // Add post-match string + vstr_add_strn(&vstr_return, subj.begin, subj.end - subj.begin); + + return mp_obj_new_str_from_vstr(mp_obj_get_type(where), &vstr_return); +} + +STATIC mp_obj_t re_sub(size_t n_args, const mp_obj_t *args) { + return re_sub_helper(args[0], n_args, args); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_sub_obj, 3, 5, re_sub); + +#endif + STATIC const mp_rom_map_elem_t re_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_match), MP_ROM_PTR(&re_match_obj) }, { MP_ROM_QSTR(MP_QSTR_search), MP_ROM_PTR(&re_search_obj) }, { MP_ROM_QSTR(MP_QSTR_split), MP_ROM_PTR(&re_split_obj) }, + #if MICROPY_PY_URE_SUB + { MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&re_sub_obj) }, + #endif }; STATIC MP_DEFINE_CONST_DICT(re_locals_dict, re_locals_dict_table); STATIC const mp_obj_type_t re_type = { { &mp_type_type }, +#if CIRCUITPY + .name = MP_QSTR_re, +#else .name = MP_QSTR_ure, +#endif .print = re_print, .locals_dict = (void*)&re_locals_dict, }; @@ -204,7 +429,7 @@ STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) { int error = re1_5_compilecode(&o->re, re_str); if (error != 0) { error: - mp_raise_ValueError("Error in regex"); + mp_raise_ValueError(translate("Error in regex")); } if (flags & FLAG_DEBUG) { re1_5_dumpcode(&o->re); @@ -232,11 +457,26 @@ STATIC mp_obj_t mod_re_search(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_search_obj, 2, 4, mod_re_search); +#if MICROPY_PY_URE_SUB +STATIC mp_obj_t mod_re_sub(size_t n_args, const mp_obj_t *args) { + mp_obj_t self = mod_re_compile(1, args); + return re_sub_helper(self, n_args, args); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_sub_obj, 3, 5, mod_re_sub); +#endif + STATIC const mp_rom_map_elem_t mp_module_re_globals_table[] = { +#if CIRCUITPY + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_re) }, +#else { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ure) }, +#endif { MP_ROM_QSTR(MP_QSTR_compile), MP_ROM_PTR(&mod_re_compile_obj) }, { MP_ROM_QSTR(MP_QSTR_match), MP_ROM_PTR(&mod_re_match_obj) }, { MP_ROM_QSTR(MP_QSTR_search), MP_ROM_PTR(&mod_re_search_obj) }, + #if MICROPY_PY_URE_SUB + { MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&mod_re_sub_obj) }, + #endif { MP_ROM_QSTR(MP_QSTR_DEBUG), MP_ROM_INT(FLAG_DEBUG) }, }; diff --git a/extmod/moduselect.c b/extmod/moduselect.c index a9f25c1954e..6c9d18e50bf 100644 --- a/extmod/moduselect.c +++ b/extmod/moduselect.c @@ -29,6 +29,7 @@ #include +#include "py/ioctl.h" #include "py/runtime.h" #include "py/obj.h" #include "py/objlist.h" diff --git a/extmod/modussl_axtls.c b/extmod/modussl_axtls.c index 475d3f0ea4f..cfa65258534 100644 --- a/extmod/modussl_axtls.c +++ b/extmod/modussl_axtls.c @@ -30,6 +30,8 @@ #include "py/runtime.h" #include "py/stream.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_USSL && MICROPY_SSL_AXTLS #include "ssl.h" @@ -76,13 +78,13 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) { const byte *data = (const byte*)mp_obj_str_get_data(args->key.u_obj, &len); int res = ssl_obj_memory_load(o->ssl_ctx, SSL_OBJ_RSA_KEY, data, len, NULL); if (res != SSL_OK) { - mp_raise_ValueError("invalid key"); + mp_raise_ValueError(translate("invalid key")); } data = (const byte*)mp_obj_str_get_data(args->cert.u_obj, &len); res = ssl_obj_memory_load(o->ssl_ctx, SSL_OBJ_X509_CERT, data, len, NULL); if (res != SSL_OK) { - mp_raise_ValueError("invalid cert"); + mp_raise_ValueError(translate("invalid cert")); } } diff --git a/extmod/modutimeq.c b/extmod/modutimeq.c index 620e7484b95..99b51016d82 100644 --- a/extmod/modutimeq.c +++ b/extmod/modutimeq.c @@ -31,6 +31,8 @@ #include "py/runtime.h" #include "py/smallint.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_UTIMEQ #define MODULO MICROPY_PY_UTIME_TICKS_PERIOD @@ -74,8 +76,8 @@ STATIC bool time_less_than(struct qentry *item, struct qentry *parent) { return res && res < (MODULO / 2); } -STATIC mp_obj_t utimeq_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 1, false); +STATIC mp_obj_t utimeq_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); mp_uint_t alloc = mp_obj_get_int(args[0]); mp_obj_utimeq_t *o = m_new_obj_var(mp_obj_utimeq_t, struct qentry, alloc); o->base.type = type; @@ -126,7 +128,7 @@ STATIC mp_obj_t mod_utimeq_heappush(size_t n_args, const mp_obj_t *args) { mp_obj_t heap_in = args[0]; mp_obj_utimeq_t *heap = get_heap(heap_in); if (heap->len == heap->alloc) { - mp_raise_msg(&mp_type_IndexError, "queue overflow"); + mp_raise_IndexError(translate("queue overflow")); } mp_uint_t l = heap->len; heap->items[l].time = MP_OBJ_SMALL_INT_VALUE(args[1]); @@ -142,7 +144,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_utimeq_heappush_obj, 4, 4, mod_ut STATIC mp_obj_t mod_utimeq_heappop(mp_obj_t heap_in, mp_obj_t list_ref) { mp_obj_utimeq_t *heap = get_heap(heap_in); if (heap->len == 0) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "empty heap")); + mp_raise_IndexError(translate("empty heap")); } mp_obj_list_t *ret = MP_OBJ_TO_PTR(list_ref); if (!MP_OBJ_IS_TYPE(list_ref, &mp_type_list) || ret->len < 3) { @@ -167,7 +169,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_utimeq_heappop_obj, mod_utimeq_heappop); STATIC mp_obj_t mod_utimeq_peektime(mp_obj_t heap_in) { mp_obj_utimeq_t *heap = get_heap(heap_in); if (heap->len == 0) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "empty heap")); + mp_raise_IndexError(translate("empty heap")); } struct qentry *item = &heap->items[0]; diff --git a/extmod/moduzlib.c b/extmod/moduzlib.c index 940b72805d6..7f15d02a8e3 100644 --- a/extmod/moduzlib.c +++ b/extmod/moduzlib.c @@ -31,9 +31,12 @@ #include "py/stream.h" #include "py/mperrno.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_UZLIB -#include "uzlib/tinf.h" +#define UZLIB_CONF_PARANOID_CHECKS (1) +#include "../../lib/uzlib/src/tinf.h" #if 0 // print debugging info #define DEBUG_printf DEBUG_printf @@ -48,7 +51,7 @@ typedef struct _mp_obj_decompio_t { bool eof; } mp_obj_decompio_t; -STATIC unsigned char read_src_stream(TINF_DATA *data) { +STATIC int read_src_stream(TINF_DATA *data) { byte *p = (void*)data; p -= offsetof(mp_obj_decompio_t, decomp); mp_obj_decompio_t *self = (mp_obj_decompio_t*)p; @@ -66,8 +69,8 @@ STATIC unsigned char read_src_stream(TINF_DATA *data) { return c; } -STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 2, false); +STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 2, false); mp_get_stream_raise(args[0], MP_STREAM_OP_READ); mp_obj_decompio_t *o = m_new_obj(mp_obj_decompio_t); o->base.type = type; @@ -92,7 +95,7 @@ STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size dict_opt = uzlib_zlib_parse_header(&o->decomp); if (dict_opt < 0) { header_error: - mp_raise_ValueError("compression header"); + mp_raise_ValueError(translate("compression header")); } dict_sz = 1 << dict_opt; } else { @@ -110,7 +113,7 @@ STATIC mp_uint_t decompio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *er } o->decomp.dest = buf; - o->decomp.destSize = size; + o->decomp.dest_limit = (unsigned char*)buf+size; int st = uzlib_uncompress_chksum(&o->decomp); if (st == TINF_DONE) { o->eof = true; @@ -155,10 +158,10 @@ STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) { byte *dest_buf = m_new(byte, dest_buf_size); decomp->dest = dest_buf; - decomp->destSize = dest_buf_size; + decomp->dest_limit = dest_buf+dest_buf_size; DEBUG_printf("uzlib: Initial out buffer: " UINT_FMT " bytes\n", decomp->destSize); decomp->source = bufinfo.buf; - + decomp->source_limit = (unsigned char *)bufinfo.buf + bufinfo.len; int st; bool is_zlib = true; @@ -185,7 +188,7 @@ STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) { dest_buf = m_renew(byte, dest_buf, dest_buf_size, dest_buf_size + 256); dest_buf_size += 256; decomp->dest = dest_buf + offset; - decomp->destSize = 256; + decomp->dest_limit = dest_buf + offset + 256; } mp_uint_t final_sz = decomp->dest - dest_buf; @@ -216,10 +219,11 @@ const mp_obj_module_t mp_module_uzlib = { // Source files #include'd here to make sure they're compiled in // only if module is enabled by config setting. -#include "uzlib/tinflate.c" -#include "uzlib/tinfzlib.c" -#include "uzlib/tinfgzip.c" -#include "uzlib/adler32.c" -#include "uzlib/crc32.c" +#pragma GCC diagnostic ignored "-Wsign-compare" +#include "../../lib/uzlib/src/tinflate.c" +#include "../../lib/uzlib/src/tinfzlib.c" +#include "../../lib/uzlib/src/tinfgzip.c" +#include "../../lib/uzlib/src/adler32.c" +#include "../../lib/uzlib/src/crc32.c" #endif // MICROPY_PY_UZLIB diff --git a/extmod/modwebsocket.c b/extmod/modwebsocket.c index c556f2b7706..997c7e26259 100644 --- a/extmod/modwebsocket.c +++ b/extmod/modwebsocket.c @@ -57,8 +57,8 @@ typedef struct _mp_obj_websocket_t { STATIC mp_uint_t websocket_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode); -STATIC mp_obj_t websocket_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 2, false); +STATIC mp_obj_t websocket_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 2, false); mp_get_stream_raise(args[0], MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL); mp_obj_websocket_t *o = m_new_obj(mp_obj_websocket_t); o->base.type = type; diff --git a/extmod/re1.5/compilecode.c b/extmod/re1.5/compilecode.c index a685a508a04..01d3d149884 100644 --- a/extmod/re1.5/compilecode.c +++ b/extmod/re1.5/compilecode.c @@ -10,6 +10,29 @@ #define EMIT(at, byte) (code ? (code[at] = byte) : (at)) #define PC (prog->bytelen) + +static char unescape(char c) { + switch (c) { + case 'a': + return '\a'; + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 'v': + return '\v'; + case 'x': + return '\\'; + default: + return c; + } +} + + static const char *_compilecode(const char *re, ByteProg *prog, int sizecode) { char *code = sizecode ? NULL : prog->insts; @@ -22,13 +45,16 @@ static const char *_compilecode(const char *re, ByteProg *prog, int sizecode) case '\\': re++; if (!*re) return NULL; // Trailing backslash + term = PC; if ((*re | 0x20) == 'd' || (*re | 0x20) == 's' || (*re | 0x20) == 'w') { - term = PC; EMIT(PC++, NamedClass); EMIT(PC++, *re); - prog->len++; - break; + } else { + EMIT(PC++, Char); + EMIT(PC++, unescape(*re)); } + prog->len++; + break; default: term = PC; EMIT(PC++, Char); @@ -54,11 +80,21 @@ static const char *_compilecode(const char *re, ByteProg *prog, int sizecode) prog->len++; for (cnt = 0; *re != ']'; re++, cnt++) { if (!*re) return NULL; - EMIT(PC++, *re); + if (*re == '\\') { + re += 1; + EMIT(PC++, unescape(*re)); + } else { + EMIT(PC++, *re); + } if (re[1] == '-' && re[2] != ']') { re += 2; } - EMIT(PC++, *re); + if (*re == '\\') { + re += 1; + EMIT(PC++, unescape(*re)); + } else { + EMIT(PC++, *re); + } } EMIT(term + 1, cnt); break; diff --git a/extmod/uos_dupterm.c b/extmod/uos_dupterm.c index cc6d97f4198..781ec0d46be 100644 --- a/extmod/uos_dupterm.c +++ b/extmod/uos_dupterm.c @@ -34,6 +34,8 @@ #include "py/stream.h" #include "lib/utils/interrupt_char.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_OS_DUPTERM void mp_uos_deactivate(size_t dupterm_idx, const char *msg, mp_obj_t exc) { @@ -115,7 +117,7 @@ STATIC mp_obj_t mp_uos_dupterm(size_t n_args, const mp_obj_t *args) { } if (idx < 0 || idx >= MICROPY_PY_OS_DUPTERM) { - mp_raise_ValueError("invalid dupterm index"); + mp_raise_ValueError(translate("invalid dupterm index")); } mp_obj_t previous_obj = MP_STATE_VM(dupterm_objs[idx]); diff --git a/extmod/uzlib/adler32.c b/extmod/uzlib/adler32.c deleted file mode 100644 index 1f1759493bb..00000000000 --- a/extmod/uzlib/adler32.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Adler-32 checksum - * - * Copyright (c) 2003 by Joergen Ibsen / Jibz - * All Rights Reserved - * - * http://www.ibsensoftware.com/ - * - * This software is provided 'as-is', without any express - * or implied warranty. In no event will the authors be - * held liable for any damages arising from the use of - * this software. - * - * Permission is granted to anyone to use this software - * for any purpose, including commercial applications, - * and to alter it and redistribute it freely, subject to - * the following restrictions: - * - * 1. The origin of this software must not be - * misrepresented; you must not claim that you - * wrote the original software. If you use this - * software in a product, an acknowledgment in - * the product documentation would be appreciated - * but is not required. - * - * 2. Altered source versions must be plainly marked - * as such, and must not be misrepresented as - * being the original software. - * - * 3. This notice may not be removed or altered from - * any source distribution. - */ - -/* - * Adler-32 algorithm taken from the zlib source, which is - * Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler - */ - -#include "tinf.h" - -#define A32_BASE 65521 -#define A32_NMAX 5552 - -uint32_t uzlib_adler32(const void *data, unsigned int length, uint32_t prev_sum /* 1 */) -{ - const unsigned char *buf = (const unsigned char *)data; - - unsigned int s1 = prev_sum & 0xffff; - unsigned int s2 = prev_sum >> 16; - - while (length > 0) - { - int k = length < A32_NMAX ? length : A32_NMAX; - int i; - - for (i = k / 16; i; --i, buf += 16) - { - s1 += buf[0]; s2 += s1; s1 += buf[1]; s2 += s1; - s1 += buf[2]; s2 += s1; s1 += buf[3]; s2 += s1; - s1 += buf[4]; s2 += s1; s1 += buf[5]; s2 += s1; - s1 += buf[6]; s2 += s1; s1 += buf[7]; s2 += s1; - - s1 += buf[8]; s2 += s1; s1 += buf[9]; s2 += s1; - s1 += buf[10]; s2 += s1; s1 += buf[11]; s2 += s1; - s1 += buf[12]; s2 += s1; s1 += buf[13]; s2 += s1; - s1 += buf[14]; s2 += s1; s1 += buf[15]; s2 += s1; - } - - for (i = k % 16; i; --i) { s1 += *buf++; s2 += s1; } - - s1 %= A32_BASE; - s2 %= A32_BASE; - - length -= k; - } - - return (s2 << 16) | s1; -} diff --git a/extmod/uzlib/crc32.c b/extmod/uzlib/crc32.c deleted file mode 100644 index e24c643b6ac..00000000000 --- a/extmod/uzlib/crc32.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * CRC32 checksum - * - * Copyright (c) 1998-2003 by Joergen Ibsen / Jibz - * All Rights Reserved - * - * http://www.ibsensoftware.com/ - * - * This software is provided 'as-is', without any express - * or implied warranty. In no event will the authors be - * held liable for any damages arising from the use of - * this software. - * - * Permission is granted to anyone to use this software - * for any purpose, including commercial applications, - * and to alter it and redistribute it freely, subject to - * the following restrictions: - * - * 1. The origin of this software must not be - * misrepresented; you must not claim that you - * wrote the original software. If you use this - * software in a product, an acknowledgment in - * the product documentation would be appreciated - * but is not required. - * - * 2. Altered source versions must be plainly marked - * as such, and must not be misrepresented as - * being the original software. - * - * 3. This notice may not be removed or altered from - * any source distribution. - */ - -/* - * CRC32 algorithm taken from the zlib source, which is - * Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler - */ - -#include "tinf.h" - -static const unsigned int tinf_crc32tab[16] = { - 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, - 0x6b6b51f4, 0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344, - 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, - 0xbdbdf21c -}; - -/* crc is previous value for incremental computation, 0xffffffff initially */ -uint32_t uzlib_crc32(const void *data, unsigned int length, uint32_t crc) -{ - const unsigned char *buf = (const unsigned char *)data; - unsigned int i; - - for (i = 0; i < length; ++i) - { - crc ^= buf[i]; - crc = tinf_crc32tab[crc & 0x0f] ^ (crc >> 4); - crc = tinf_crc32tab[crc & 0x0f] ^ (crc >> 4); - } - - // return value suitable for passing in next time, for final value invert it - return crc/* ^ 0xffffffff*/; -} diff --git a/extmod/uzlib/tinf.h b/extmod/uzlib/tinf.h deleted file mode 100644 index 106203a099e..00000000000 --- a/extmod/uzlib/tinf.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * uzlib - tiny deflate/inflate library (deflate, gzip, zlib) - * - * Copyright (c) 2003 by Joergen Ibsen / Jibz - * All Rights Reserved - * http://www.ibsensoftware.com/ - * - * Copyright (c) 2014-2016 by Paul Sokolovsky - */ - -#ifndef TINF_H_INCLUDED -#define TINF_H_INCLUDED - -#include - -/* calling convention */ -#ifndef TINFCC - #ifdef __WATCOMC__ - #define TINFCC __cdecl - #else - #define TINFCC - #endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* ok status, more data produced */ -#define TINF_OK 0 -/* end of compressed stream reached */ -#define TINF_DONE 1 -#define TINF_DATA_ERROR (-3) -#define TINF_CHKSUM_ERROR (-4) -#define TINF_DICT_ERROR (-5) - -/* checksum types */ -#define TINF_CHKSUM_NONE 0 -#define TINF_CHKSUM_ADLER 1 -#define TINF_CHKSUM_CRC 2 - -/* data structures */ - -typedef struct { - unsigned short table[16]; /* table of code length counts */ - unsigned short trans[288]; /* code -> symbol translation table */ -} TINF_TREE; - -struct TINF_DATA; -typedef struct TINF_DATA { - const unsigned char *source; - /* If source above is NULL, this function will be used to read - next byte from source stream */ - unsigned char (*readSource)(struct TINF_DATA *data); - - unsigned int tag; - unsigned int bitcount; - - /* Buffer start */ - unsigned char *destStart; - /* Buffer total size */ - unsigned int destSize; - /* Current pointer in buffer */ - unsigned char *dest; - /* Remaining bytes in buffer */ - unsigned int destRemaining; - - /* Accumulating checksum */ - unsigned int checksum; - char checksum_type; - - int btype; - int bfinal; - unsigned int curlen; - int lzOff; - unsigned char *dict_ring; - unsigned int dict_size; - unsigned int dict_idx; - - TINF_TREE ltree; /* dynamic length/symbol tree */ - TINF_TREE dtree; /* dynamic distance tree */ -} TINF_DATA; - -#define TINF_PUT(d, c) \ - { \ - *d->dest++ = c; \ - if (d->dict_ring) { d->dict_ring[d->dict_idx++] = c; if (d->dict_idx == d->dict_size) d->dict_idx = 0; } \ - } - -unsigned char TINFCC uzlib_get_byte(TINF_DATA *d); - -/* Decompression API */ - -void TINFCC uzlib_init(void); -void TINFCC uzlib_uncompress_init(TINF_DATA *d, void *dict, unsigned int dictLen); -int TINFCC uzlib_uncompress(TINF_DATA *d); -int TINFCC uzlib_uncompress_chksum(TINF_DATA *d); - -int TINFCC uzlib_zlib_parse_header(TINF_DATA *d); -int TINFCC uzlib_gzip_parse_header(TINF_DATA *d); - -/* Compression API */ - -void TINFCC uzlib_compress(void *data, const uint8_t *src, unsigned slen); - -/* Checksum API */ - -/* prev_sum is previous value for incremental computation, 1 initially */ -uint32_t TINFCC uzlib_adler32(const void *data, unsigned int length, uint32_t prev_sum); -/* crc is previous value for incremental computation, 0xffffffff initially */ -uint32_t TINFCC uzlib_crc32(const void *data, unsigned int length, uint32_t crc); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* TINF_H_INCLUDED */ diff --git a/extmod/uzlib/tinfgzip.c b/extmod/uzlib/tinfgzip.c deleted file mode 100644 index f1afdd0b8d8..00000000000 --- a/extmod/uzlib/tinfgzip.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * tinfgzip - tiny gzip decompressor - * - * Copyright (c) 2003 by Joergen Ibsen / Jibz - * All Rights Reserved - * - * http://www.ibsensoftware.com/ - * - * Copyright (c) 2014-2016 by Paul Sokolovsky - * - * This software is provided 'as-is', without any express - * or implied warranty. In no event will the authors be - * held liable for any damages arising from the use of - * this software. - * - * Permission is granted to anyone to use this software - * for any purpose, including commercial applications, - * and to alter it and redistribute it freely, subject to - * the following restrictions: - * - * 1. The origin of this software must not be - * misrepresented; you must not claim that you - * wrote the original software. If you use this - * software in a product, an acknowledgment in - * the product documentation would be appreciated - * but is not required. - * - * 2. Altered source versions must be plainly marked - * as such, and must not be misrepresented as - * being the original software. - * - * 3. This notice may not be removed or altered from - * any source distribution. - */ - -#include "tinf.h" - -#define FTEXT 1 -#define FHCRC 2 -#define FEXTRA 4 -#define FNAME 8 -#define FCOMMENT 16 - -void tinf_skip_bytes(TINF_DATA *d, int num); -uint16_t tinf_get_uint16(TINF_DATA *d); - -void tinf_skip_bytes(TINF_DATA *d, int num) -{ - while (num--) uzlib_get_byte(d); -} - -uint16_t tinf_get_uint16(TINF_DATA *d) -{ - unsigned int v = uzlib_get_byte(d); - v = (uzlib_get_byte(d) << 8) | v; - return v; -} - -int uzlib_gzip_parse_header(TINF_DATA *d) -{ - unsigned char flg; - - /* -- check format -- */ - - /* check id bytes */ - if (uzlib_get_byte(d) != 0x1f || uzlib_get_byte(d) != 0x8b) return TINF_DATA_ERROR; - - /* check method is deflate */ - if (uzlib_get_byte(d) != 8) return TINF_DATA_ERROR; - - /* get flag byte */ - flg = uzlib_get_byte(d); - - /* check that reserved bits are zero */ - if (flg & 0xe0) return TINF_DATA_ERROR; - - /* -- find start of compressed data -- */ - - /* skip rest of base header of 10 bytes */ - tinf_skip_bytes(d, 6); - - /* skip extra data if present */ - if (flg & FEXTRA) - { - unsigned int xlen = tinf_get_uint16(d); - tinf_skip_bytes(d, xlen); - } - - /* skip file name if present */ - if (flg & FNAME) { while (uzlib_get_byte(d)); } - - /* skip file comment if present */ - if (flg & FCOMMENT) { while (uzlib_get_byte(d)); } - - /* check header crc if present */ - if (flg & FHCRC) - { - /*unsigned int hcrc =*/ tinf_get_uint16(d); - - // TODO: Check! -// if (hcrc != (tinf_crc32(src, start - src) & 0x0000ffff)) -// return TINF_DATA_ERROR; - } - - /* initialize for crc32 checksum */ - d->checksum_type = TINF_CHKSUM_CRC; - d->checksum = ~0; - - return TINF_OK; -} diff --git a/extmod/uzlib/tinflate.c b/extmod/uzlib/tinflate.c deleted file mode 100644 index 21558af5bf4..00000000000 --- a/extmod/uzlib/tinflate.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - * tinflate - tiny inflate - * - * Copyright (c) 2003 by Joergen Ibsen / Jibz - * All Rights Reserved - * http://www.ibsensoftware.com/ - * - * Copyright (c) 2014-2016 by Paul Sokolovsky - * - * This software is provided 'as-is', without any express - * or implied warranty. In no event will the authors be - * held liable for any damages arising from the use of - * this software. - * - * Permission is granted to anyone to use this software - * for any purpose, including commercial applications, - * and to alter it and redistribute it freely, subject to - * the following restrictions: - * - * 1. The origin of this software must not be - * misrepresented; you must not claim that you - * wrote the original software. If you use this - * software in a product, an acknowledgment in - * the product documentation would be appreciated - * but is not required. - * - * 2. Altered source versions must be plainly marked - * as such, and must not be misrepresented as - * being the original software. - * - * 3. This notice may not be removed or altered from - * any source distribution. - */ - -#include -#include "tinf.h" - -uint32_t tinf_get_le_uint32(TINF_DATA *d); -uint32_t tinf_get_be_uint32(TINF_DATA *d); - -/* --------------------------------------------------- * - * -- uninitialized global data (static structures) -- * - * --------------------------------------------------- */ - -#ifdef RUNTIME_BITS_TABLES - -/* extra bits and base tables for length codes */ -unsigned char length_bits[30]; -unsigned short length_base[30]; - -/* extra bits and base tables for distance codes */ -unsigned char dist_bits[30]; -unsigned short dist_base[30]; - -#else - -const unsigned char length_bits[30] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, - 5, 5, 5, 5 -}; -const unsigned short length_base[30] = { - 3, 4, 5, 6, 7, 8, 9, 10, - 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, - 131, 163, 195, 227, 258 -}; - -const unsigned char dist_bits[30] = { - 0, 0, 0, 0, 1, 1, 2, 2, - 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, - 11, 11, 12, 12, 13, 13 -}; -const unsigned short dist_base[30] = { - 1, 2, 3, 4, 5, 7, 9, 13, - 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, - 4097, 6145, 8193, 12289, 16385, 24577 -}; - -#endif - -/* special ordering of code length codes */ -const unsigned char clcidx[] = { - 16, 17, 18, 0, 8, 7, 9, 6, - 10, 5, 11, 4, 12, 3, 13, 2, - 14, 1, 15 -}; - -/* ----------------------- * - * -- utility functions -- * - * ----------------------- */ - -#ifdef RUNTIME_BITS_TABLES -/* build extra bits and base tables */ -static void tinf_build_bits_base(unsigned char *bits, unsigned short *base, int delta, int first) -{ - int i, sum; - - /* build bits table */ - for (i = 0; i < delta; ++i) bits[i] = 0; - for (i = 0; i < 30 - delta; ++i) bits[i + delta] = i / delta; - - /* build base table */ - for (sum = first, i = 0; i < 30; ++i) - { - base[i] = sum; - sum += 1 << bits[i]; - } -} -#endif - -/* build the fixed huffman trees */ -static void tinf_build_fixed_trees(TINF_TREE *lt, TINF_TREE *dt) -{ - int i; - - /* build fixed length tree */ - for (i = 0; i < 7; ++i) lt->table[i] = 0; - - lt->table[7] = 24; - lt->table[8] = 152; - lt->table[9] = 112; - - for (i = 0; i < 24; ++i) lt->trans[i] = 256 + i; - for (i = 0; i < 144; ++i) lt->trans[24 + i] = i; - for (i = 0; i < 8; ++i) lt->trans[24 + 144 + i] = 280 + i; - for (i = 0; i < 112; ++i) lt->trans[24 + 144 + 8 + i] = 144 + i; - - /* build fixed distance tree */ - for (i = 0; i < 5; ++i) dt->table[i] = 0; - - dt->table[5] = 32; - - for (i = 0; i < 32; ++i) dt->trans[i] = i; -} - -/* given an array of code lengths, build a tree */ -static void tinf_build_tree(TINF_TREE *t, const unsigned char *lengths, unsigned int num) -{ - unsigned short offs[16]; - unsigned int i, sum; - - /* clear code length count table */ - for (i = 0; i < 16; ++i) t->table[i] = 0; - - /* scan symbol lengths, and sum code length counts */ - for (i = 0; i < num; ++i) t->table[lengths[i]]++; - - t->table[0] = 0; - - /* compute offset table for distribution sort */ - for (sum = 0, i = 0; i < 16; ++i) - { - offs[i] = sum; - sum += t->table[i]; - } - - /* create code->symbol translation table (symbols sorted by code) */ - for (i = 0; i < num; ++i) - { - if (lengths[i]) t->trans[offs[lengths[i]]++] = i; - } -} - -/* ---------------------- * - * -- decode functions -- * - * ---------------------- */ - -unsigned char uzlib_get_byte(TINF_DATA *d) -{ - if (d->source) { - return *d->source++; - } - return d->readSource(d); -} - -uint32_t tinf_get_le_uint32(TINF_DATA *d) -{ - uint32_t val = 0; - int i; - for (i = 4; i--;) { - val = val >> 8 | uzlib_get_byte(d) << 24; - } - return val; -} - -uint32_t tinf_get_be_uint32(TINF_DATA *d) -{ - uint32_t val = 0; - int i; - for (i = 4; i--;) { - val = val << 8 | uzlib_get_byte(d); - } - return val; -} - -/* get one bit from source stream */ -static int tinf_getbit(TINF_DATA *d) -{ - unsigned int bit; - - /* check if tag is empty */ - if (!d->bitcount--) - { - /* load next tag */ - d->tag = uzlib_get_byte(d); - d->bitcount = 7; - } - - /* shift bit out of tag */ - bit = d->tag & 0x01; - d->tag >>= 1; - - return bit; -} - -/* read a num bit value from a stream and add base */ -static unsigned int tinf_read_bits(TINF_DATA *d, int num, int base) -{ - unsigned int val = 0; - - /* read num bits */ - if (num) - { - unsigned int limit = 1 << (num); - unsigned int mask; - - for (mask = 1; mask < limit; mask *= 2) - if (tinf_getbit(d)) val += mask; - } - - return val + base; -} - -/* given a data stream and a tree, decode a symbol */ -static int tinf_decode_symbol(TINF_DATA *d, TINF_TREE *t) -{ - int sum = 0, cur = 0, len = 0; - - /* get more bits while code value is above sum */ - do { - - cur = 2*cur + tinf_getbit(d); - - ++len; - - sum += t->table[len]; - cur -= t->table[len]; - - } while (cur >= 0); - - return t->trans[sum + cur]; -} - -/* given a data stream, decode dynamic trees from it */ -static void tinf_decode_trees(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt) -{ - unsigned char lengths[288+32]; - unsigned int hlit, hdist, hclen; - unsigned int i, num, length; - - /* get 5 bits HLIT (257-286) */ - hlit = tinf_read_bits(d, 5, 257); - - /* get 5 bits HDIST (1-32) */ - hdist = tinf_read_bits(d, 5, 1); - - /* get 4 bits HCLEN (4-19) */ - hclen = tinf_read_bits(d, 4, 4); - - for (i = 0; i < 19; ++i) lengths[i] = 0; - - /* read code lengths for code length alphabet */ - for (i = 0; i < hclen; ++i) - { - /* get 3 bits code length (0-7) */ - unsigned int clen = tinf_read_bits(d, 3, 0); - - lengths[clcidx[i]] = clen; - } - - /* build code length tree, temporarily use length tree */ - tinf_build_tree(lt, lengths, 19); - - /* decode code lengths for the dynamic trees */ - for (num = 0; num < hlit + hdist; ) - { - int sym = tinf_decode_symbol(d, lt); - - switch (sym) - { - case 16: - /* copy previous code length 3-6 times (read 2 bits) */ - { - unsigned char prev = lengths[num - 1]; - for (length = tinf_read_bits(d, 2, 3); length; --length) - { - lengths[num++] = prev; - } - } - break; - case 17: - /* repeat code length 0 for 3-10 times (read 3 bits) */ - for (length = tinf_read_bits(d, 3, 3); length; --length) - { - lengths[num++] = 0; - } - break; - case 18: - /* repeat code length 0 for 11-138 times (read 7 bits) */ - for (length = tinf_read_bits(d, 7, 11); length; --length) - { - lengths[num++] = 0; - } - break; - default: - /* values 0-15 represent the actual code lengths */ - lengths[num++] = sym; - break; - } - } - - /* build dynamic trees */ - tinf_build_tree(lt, lengths, hlit); - tinf_build_tree(dt, lengths + hlit, hdist); -} - -/* ----------------------------- * - * -- block inflate functions -- * - * ----------------------------- */ - -/* given a stream and two trees, inflate a block of data */ -static int tinf_inflate_block_data(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt) -{ - if (d->curlen == 0) { - unsigned int offs; - int dist; - int sym = tinf_decode_symbol(d, lt); - //printf("huff sym: %02x\n", sym); - - /* literal byte */ - if (sym < 256) { - TINF_PUT(d, sym); - return TINF_OK; - } - - /* end of block */ - if (sym == 256) { - return TINF_DONE; - } - - /* substring from sliding dictionary */ - sym -= 257; - /* possibly get more bits from length code */ - d->curlen = tinf_read_bits(d, length_bits[sym], length_base[sym]); - - dist = tinf_decode_symbol(d, dt); - /* possibly get more bits from distance code */ - offs = tinf_read_bits(d, dist_bits[dist], dist_base[dist]); - if (d->dict_ring) { - if (offs > d->dict_size) { - return TINF_DICT_ERROR; - } - d->lzOff = d->dict_idx - offs; - if (d->lzOff < 0) { - d->lzOff += d->dict_size; - } - } else { - d->lzOff = -offs; - } - } - - /* copy next byte from dict substring */ - if (d->dict_ring) { - TINF_PUT(d, d->dict_ring[d->lzOff]); - if ((unsigned)++d->lzOff == d->dict_size) { - d->lzOff = 0; - } - } else { - d->dest[0] = d->dest[d->lzOff]; - d->dest++; - } - d->curlen--; - return TINF_OK; -} - -/* inflate an uncompressed block of data */ -static int tinf_inflate_uncompressed_block(TINF_DATA *d) -{ - if (d->curlen == 0) { - unsigned int length, invlength; - - /* get length */ - length = uzlib_get_byte(d); - length += 256 * uzlib_get_byte(d); - /* get one's complement of length */ - invlength = uzlib_get_byte(d); - invlength += 256 * uzlib_get_byte(d); - /* check length */ - if (length != (~invlength & 0x0000ffff)) return TINF_DATA_ERROR; - - /* increment length to properly return TINF_DONE below, without - producing data at the same time */ - d->curlen = length + 1; - - /* make sure we start next block on a byte boundary */ - d->bitcount = 0; - } - - if (--d->curlen == 0) { - return TINF_DONE; - } - - unsigned char c = uzlib_get_byte(d); - TINF_PUT(d, c); - return TINF_OK; -} - -/* ---------------------- * - * -- public functions -- * - * ---------------------- */ - -/* initialize global (static) data */ -void uzlib_init(void) -{ -#ifdef RUNTIME_BITS_TABLES - /* build extra bits and base tables */ - tinf_build_bits_base(length_bits, length_base, 4, 3); - tinf_build_bits_base(dist_bits, dist_base, 2, 1); - - /* fix a special case */ - length_bits[28] = 0; - length_base[28] = 258; -#endif -} - -/* initialize decompression structure */ -void uzlib_uncompress_init(TINF_DATA *d, void *dict, unsigned int dictLen) -{ - d->bitcount = 0; - d->bfinal = 0; - d->btype = -1; - d->dict_size = dictLen; - d->dict_ring = dict; - d->dict_idx = 0; - d->curlen = 0; -} - -/* inflate next byte of compressed stream */ -int uzlib_uncompress(TINF_DATA *d) -{ - do { - int res; - - /* start a new block */ - if (d->btype == -1) { -next_blk: - /* read final block flag */ - d->bfinal = tinf_getbit(d); - /* read block type (2 bits) */ - d->btype = tinf_read_bits(d, 2, 0); - - //printf("Started new block: type=%d final=%d\n", d->btype, d->bfinal); - - if (d->btype == 1) { - /* build fixed huffman trees */ - tinf_build_fixed_trees(&d->ltree, &d->dtree); - } else if (d->btype == 2) { - /* decode trees from stream */ - tinf_decode_trees(d, &d->ltree, &d->dtree); - } - } - - /* process current block */ - switch (d->btype) - { - case 0: - /* decompress uncompressed block */ - res = tinf_inflate_uncompressed_block(d); - break; - case 1: - case 2: - /* decompress block with fixed/dyanamic huffman trees */ - /* trees were decoded previously, so it's the same routine for both */ - res = tinf_inflate_block_data(d, &d->ltree, &d->dtree); - break; - default: - return TINF_DATA_ERROR; - } - - if (res == TINF_DONE && !d->bfinal) { - /* the block has ended (without producing more data), but we - can't return without data, so start procesing next block */ - goto next_blk; - } - - if (res != TINF_OK) { - return res; - } - - } while (--d->destSize); - - return TINF_OK; -} - -int uzlib_uncompress_chksum(TINF_DATA *d) -{ - int res; - unsigned char *data = d->dest; - - res = uzlib_uncompress(d); - - if (res < 0) return res; - - switch (d->checksum_type) { - - case TINF_CHKSUM_ADLER: - d->checksum = uzlib_adler32(data, d->dest - data, d->checksum); - break; - - case TINF_CHKSUM_CRC: - d->checksum = uzlib_crc32(data, d->dest - data, d->checksum); - break; - } - - if (res == TINF_DONE) { - unsigned int val; - - switch (d->checksum_type) { - - case TINF_CHKSUM_ADLER: - val = tinf_get_be_uint32(d); - if (d->checksum != val) { - return TINF_CHKSUM_ERROR; - } - break; - - case TINF_CHKSUM_CRC: - val = tinf_get_le_uint32(d); - if (~d->checksum != val) { - return TINF_CHKSUM_ERROR; - } - // Uncompressed size. TODO: Check - val = tinf_get_le_uint32(d); - break; - } - } - - return res; -} diff --git a/extmod/uzlib/tinfzlib.c b/extmod/uzlib/tinfzlib.c deleted file mode 100644 index 74fade3b9d4..00000000000 --- a/extmod/uzlib/tinfzlib.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * tinfzlib - tiny zlib decompressor - * - * Copyright (c) 2003 by Joergen Ibsen / Jibz - * All Rights Reserved - * - * http://www.ibsensoftware.com/ - * - * Copyright (c) 2014-2016 by Paul Sokolovsky - * - * This software is provided 'as-is', without any express - * or implied warranty. In no event will the authors be - * held liable for any damages arising from the use of - * this software. - * - * Permission is granted to anyone to use this software - * for any purpose, including commercial applications, - * and to alter it and redistribute it freely, subject to - * the following restrictions: - * - * 1. The origin of this software must not be - * misrepresented; you must not claim that you - * wrote the original software. If you use this - * software in a product, an acknowledgment in - * the product documentation would be appreciated - * but is not required. - * - * 2. Altered source versions must be plainly marked - * as such, and must not be misrepresented as - * being the original software. - * - * 3. This notice may not be removed or altered from - * any source distribution. - */ - -#include "tinf.h" - -int uzlib_zlib_parse_header(TINF_DATA *d) -{ - unsigned char cmf, flg; - - /* -- get header bytes -- */ - - cmf = uzlib_get_byte(d); - flg = uzlib_get_byte(d); - - /* -- check format -- */ - - /* check checksum */ - if ((256*cmf + flg) % 31) return TINF_DATA_ERROR; - - /* check method is deflate */ - if ((cmf & 0x0f) != 8) return TINF_DATA_ERROR; - - /* check window size is valid */ - if ((cmf >> 4) > 7) return TINF_DATA_ERROR; - - /* check there is no preset dictionary */ - if (flg & 0x20) return TINF_DATA_ERROR; - - /* initialize for adler32 checksum */ - d->checksum_type = TINF_CHKSUM_ADLER; - d->checksum = 1; - - return cmf >> 4; -} diff --git a/extmod/vfs.c b/extmod/vfs.c index 77531b87424..7d6e6999bdf 100644 --- a/extmod/vfs.c +++ b/extmod/vfs.c @@ -176,7 +176,7 @@ mp_obj_t mp_vfs_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args // auto-detect the filesystem and create the corresponding VFS entity. // (At the moment we only support FAT filesystems.) #if MICROPY_VFS_FAT - vfs_obj = mp_fat_vfs_type.make_new(&mp_fat_vfs_type, 1, 0, &vfs_obj); + vfs_obj = mp_fat_vfs_type.make_new(&mp_fat_vfs_type, 1, &vfs_obj, NULL); #endif } @@ -311,18 +311,7 @@ mp_obj_t mp_vfs_getcwd(void) { } MP_DEFINE_CONST_FUN_OBJ_0(mp_vfs_getcwd_obj, mp_vfs_getcwd); -typedef struct _mp_vfs_ilistdir_it_t { - mp_obj_base_t base; - mp_fun_1_t iternext; - union { - mp_vfs_mount_t *vfs; - mp_obj_t iter; - } cur; - bool is_str; - bool is_iter; -} mp_vfs_ilistdir_it_t; - -STATIC mp_obj_t mp_vfs_ilistdir_it_iternext(mp_obj_t self_in) { +mp_obj_t mp_vfs_ilistdir_it_iternext(mp_obj_t self_in) { mp_vfs_ilistdir_it_t *self = MP_OBJ_TO_PTR(self_in); if (self->is_iter) { // continue delegating to root dir diff --git a/extmod/vfs.h b/extmod/vfs.h index 730dea04311..38c77943c7f 100644 --- a/extmod/vfs.h +++ b/extmod/vfs.h @@ -57,6 +57,19 @@ typedef struct _mp_vfs_mount_t { struct _mp_vfs_mount_t *next; } mp_vfs_mount_t; +typedef struct _mp_vfs_ilistdir_it_t { + mp_obj_base_t base; + mp_fun_1_t iternext; + union { + mp_vfs_mount_t *vfs; + mp_obj_t iter; + } cur; + bool is_str; + bool is_iter; +} mp_vfs_ilistdir_it_t; + +mp_obj_t mp_vfs_ilistdir_it_iternext(mp_obj_t self_in); + mp_vfs_mount_t *mp_vfs_lookup_path(const char *path, const char **path_out); mp_import_stat_t mp_vfs_import_stat(const char *path); mp_obj_t mp_vfs_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); @@ -73,6 +86,8 @@ mp_obj_t mp_vfs_rmdir(mp_obj_t path_in); mp_obj_t mp_vfs_stat(mp_obj_t path_in); mp_obj_t mp_vfs_statvfs(mp_obj_t path_in); +mp_obj_t mp_vfs_ilistdir_it_iternext(mp_obj_t self_in); + MP_DECLARE_CONST_FUN_OBJ_KW(mp_vfs_mount_obj); MP_DECLARE_CONST_FUN_OBJ_1(mp_vfs_umount_obj); MP_DECLARE_CONST_FUN_OBJ_KW(mp_vfs_open_obj); diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index 4af836b2d0d..20d3e3e5ce7 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -33,11 +33,14 @@ #endif #include +#include "py/objproperty.h" #include "py/runtime.h" #include "py/mperrno.h" #include "lib/oofatfs/ff.h" #include "extmod/vfs_fat.h" #include "lib/timeutils/timeutils.h" +#include "supervisor/filesystem.h" +#include "supervisor/shared/translate.h" #if _MAX_SS == _MIN_SS #define SECSIZE(fs) (_MIN_SS) @@ -47,7 +50,7 @@ #define mp_obj_fat_vfs_t fs_user_mount_t -STATIC mp_import_stat_t fat_vfs_import_stat(void *vfs_in, const char *path) { +mp_import_stat_t fat_vfs_import_stat(void *vfs_in, const char *path) { fs_user_mount_t *vfs = vfs_in; FILINFO fno; assert(vfs != NULL); @@ -62,8 +65,8 @@ STATIC mp_import_stat_t fat_vfs_import_stat(void *vfs_in, const char *path) { return MP_IMPORT_STAT_NO_EXIST; } -STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 1, false); +STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); // create new object fs_user_mount_t *vfs = m_new_obj(fs_user_mount_t); @@ -96,6 +99,12 @@ STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, size_ return MP_OBJ_FROM_PTR(vfs); } +STATIC void verify_fs_writable(fs_user_mount_t *vfs) { + if (!filesystem_is_writable_by_python(vfs)) { + mp_raise_OSError(MP_EROFS); + } +} + #if _FS_REENTRANT STATIC mp_obj_t fat_vfs_del(mp_obj_t self_in) { mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(self_in); @@ -108,7 +117,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_del_obj, fat_vfs_del); STATIC mp_obj_t fat_vfs_mkfs(mp_obj_t bdev_in) { // create new object - fs_user_mount_t *vfs = MP_OBJ_TO_PTR(fat_vfs_make_new(&mp_fat_vfs_type, 1, 0, &bdev_in)); + fs_user_mount_t *vfs = MP_OBJ_TO_PTR(fat_vfs_make_new(&mp_fat_vfs_type, 1, &bdev_in, NULL)); // make the filesystem uint8_t working_buf[_MAX_SS]; @@ -198,6 +207,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fat_vfs_ilistdir_obj, 1, 2, fat_vfs_i STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t vfs_in, mp_obj_t path_in, mp_int_t attr) { mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in); + verify_fs_writable(self); const char *path = mp_obj_str_get_str(path_in); FILINFO fno; @@ -232,9 +242,26 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_rmdir_obj, fat_vfs_rmdir); STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_out) { mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in); + verify_fs_writable(self); const char *old_path = mp_obj_str_get_str(path_in); const char *new_path = mp_obj_str_get_str(path_out); - FRESULT res = f_rename(&self->fatfs, old_path, new_path); + + // Check to see if we're moving a directory into itself. This occurs when we're moving a + // directory where the old path is a prefix of the new and the next character is a "/" and thus + // preserves the original directory name. + FILINFO fno; + FRESULT res = f_stat(&self->fatfs, old_path, &fno); + if (res != FR_OK) { + mp_raise_OSError(fresult_to_errno_table[res]); + } + if ((fno.fattrib & AM_DIR) != 0 && + strlen(new_path) > strlen(old_path) && + new_path[strlen(old_path)] == '/' && + strncmp(old_path, new_path, strlen(old_path)) == 0) { + mp_raise_OSError(MP_EINVAL); + } + + res = f_rename(&self->fatfs, old_path, new_path); if (res == FR_EXIST) { // if new_path exists then try removing it (but only if it's a file) fat_vfs_remove_internal(vfs_in, path_out, 0); // 0 == file attribute @@ -252,6 +279,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(fat_vfs_rename_obj, fat_vfs_rename); STATIC mp_obj_t fat_vfs_mkdir(mp_obj_t vfs_in, mp_obj_t path_o) { mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in); + verify_fs_writable(self); const char *path = mp_obj_str_get_str(path_o); FRESULT res = f_mkdir(&self->fatfs, path); if (res == FR_OK) { @@ -317,7 +345,7 @@ STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) { } else { mode |= MP_S_IFREG; } - mp_int_t seconds = timeutils_seconds_since_2000( + mp_uint_t seconds = timeutils_seconds_since_epoch( 1980 + ((fno.fdate >> 9) & 0x7f), (fno.fdate >> 5) & 0x0f, fno.fdate & 0x1f, @@ -332,9 +360,9 @@ STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) { t->items[4] = MP_OBJ_NEW_SMALL_INT(0); // st_uid t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // st_gid t->items[6] = mp_obj_new_int_from_uint(fno.fsize); // st_size - t->items[7] = MP_OBJ_NEW_SMALL_INT(seconds); // st_atime - t->items[8] = MP_OBJ_NEW_SMALL_INT(seconds); // st_mtime - t->items[9] = MP_OBJ_NEW_SMALL_INT(seconds); // st_ctime + t->items[7] = mp_obj_new_int_from_uint(seconds); // st_atime + t->items[8] = mp_obj_new_int_from_uint(seconds); // st_mtime + t->items[9] = mp_obj_new_int_from_uint(seconds); // st_ctime return MP_OBJ_FROM_PTR(t); } @@ -402,6 +430,40 @@ STATIC mp_obj_t vfs_fat_umount(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_umount_obj, vfs_fat_umount); +#if MICROPY_FATFS_USE_LABEL +STATIC mp_obj_t vfs_fat_getlabel(mp_obj_t self_in) { + fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in); + char working_buf[12]; + FRESULT res = f_getlabel(&self->fatfs, working_buf, NULL); + if (res != FR_OK) { + mp_raise_OSError(fresult_to_errno_table[res]); + } + return mp_obj_new_str(working_buf, strlen(working_buf)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_getlabel_obj, vfs_fat_getlabel); + +STATIC mp_obj_t vfs_fat_setlabel(mp_obj_t self_in, mp_obj_t label_in) { + fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in); + verify_fs_writable(self); + const char *label_str = mp_obj_str_get_str(label_in); + FRESULT res = f_setlabel(&self->fatfs, label_str); + if (res != FR_OK) { + if(res == FR_WRITE_PROTECTED) { + mp_raise_msg(&mp_type_OSError, translate("Read-only filesystem")); + } + mp_raise_OSError(fresult_to_errno_table[res]); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_setlabel_obj, vfs_fat_setlabel); +STATIC const mp_obj_property_t fat_vfs_label_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&fat_vfs_getlabel_obj, + (mp_obj_t)&fat_vfs_setlabel_obj, + (mp_obj_t)&mp_const_none_obj}, +}; +#endif + STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = { #if _FS_REENTRANT { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&fat_vfs_del_obj) }, @@ -419,6 +481,9 @@ STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&fat_vfs_statvfs_obj) }, { MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&vfs_fat_mount_obj) }, { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&fat_vfs_umount_obj) }, +#if MICROPY_FATFS_USE_LABEL + { MP_ROM_QSTR(MP_QSTR_label), MP_ROM_PTR(&fat_vfs_label_obj) }, +#endif }; STATIC MP_DEFINE_CONST_DICT(fat_vfs_locals_dict, fat_vfs_locals_dict_table); diff --git a/extmod/vfs_fat.h b/extmod/vfs_fat.h index ba2915386fd..08b03d0d186 100644 --- a/extmod/vfs_fat.h +++ b/extmod/vfs_fat.h @@ -32,10 +32,14 @@ #include "extmod/vfs.h" // these are the values for fs_user_mount_t.flags -#define FSUSER_NATIVE (0x0001) // readblocks[2]/writeblocks[2] contain native func -#define FSUSER_FREE_OBJ (0x0002) // fs_user_mount_t obj should be freed on umount -#define FSUSER_HAVE_IOCTL (0x0004) // new protocol with ioctl +#define FSUSER_NATIVE (0x0001) // readblocks[2]/writeblocks[2] contain native func +#define FSUSER_FREE_OBJ (0x0002) // fs_user_mount_t obj should be freed on umount +#define FSUSER_HAVE_IOCTL (0x0004) // new protocol with ioctl #define FSUSER_NO_FILESYSTEM (0x0008) // the block device has no filesystem on it +// Device is writable over USB and read-only to MicroPython. +#define FSUSER_USB_WRITABLE (0x0010) +// Bit set when the above flag is checked before opening a file for write. +#define FSUSER_CONCURRENT_WRITE_PROTECTED (0x0020) typedef struct _fs_user_mount_t { mp_obj_base_t base; @@ -53,11 +57,24 @@ typedef struct _fs_user_mount_t { FATFS fatfs; } fs_user_mount_t; +typedef struct _pyb_file_obj_t { + mp_obj_base_t base; + FIL fp; +} pyb_file_obj_t; + extern const byte fresult_to_errno_table[20]; extern const mp_obj_type_t mp_fat_vfs_type; extern const mp_obj_type_t mp_type_vfs_fat_fileio; extern const mp_obj_type_t mp_type_vfs_fat_textio; +mp_import_stat_t fat_vfs_import_stat(void *vfs, const char *path); + MP_DECLARE_CONST_FUN_OBJ_3(fat_vfs_open_obj); -#endif // MICROPY_INCLUDED_EXTMOD_VFS_FAT_H +mp_obj_t fat_vfs_ilistdir2(struct _fs_user_mount_t *vfs, const char *path, bool is_str_type); + +MP_DECLARE_CONST_FUN_OBJ_KW(fsuser_mount_obj); +MP_DECLARE_CONST_FUN_OBJ_1(fsuser_umount_obj); +MP_DECLARE_CONST_FUN_OBJ_KW(fsuser_mkfs_obj); + +#endif // MICROPY_INCLUDED_EXTMOD_VFS_FAT_H diff --git a/extmod/vfs_fat_diskio.c b/extmod/vfs_fat_diskio.c index fa013d2786c..0e442d8fa96 100644 --- a/extmod/vfs_fat_diskio.c +++ b/extmod/vfs_fat_diskio.c @@ -78,8 +78,17 @@ DRESULT disk_read ( mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, count * SECSIZE(&vfs->fatfs), buff}; vfs->readblocks[2] = MP_OBJ_NEW_SMALL_INT(sector); vfs->readblocks[3] = MP_OBJ_FROM_PTR(&ar); - mp_call_method_n_kw(2, 0, vfs->readblocks); - // TODO handle error return + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + mp_obj_t ret = mp_call_method_n_kw(2, 0, vfs->readblocks); + nlr_pop(); + if (ret != mp_const_none && MP_OBJ_SMALL_INT_VALUE(ret) != 0) { + return RES_ERROR; + } + } else { + // Exception thrown by readblocks or something it calls. + return RES_ERROR; + } } return RES_OK; @@ -115,8 +124,17 @@ DRESULT disk_write ( mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, count * SECSIZE(&vfs->fatfs), (void*)buff}; vfs->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(sector); vfs->writeblocks[3] = MP_OBJ_FROM_PTR(&ar); - mp_call_method_n_kw(2, 0, vfs->writeblocks); - // TODO handle error return + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + mp_obj_t ret = mp_call_method_n_kw(2, 0, vfs->writeblocks); + nlr_pop(); + if (ret != mp_const_none && MP_OBJ_SMALL_INT_VALUE(ret) != 0) { + return RES_ERROR; + } + } else { + // Exception thrown by writeblocks or something it calls. + return RES_ERROR; + } } return RES_OK; diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c index f7b9331b82e..6aad1884cb0 100644 --- a/extmod/vfs_fat_file.c +++ b/extmod/vfs_fat_file.c @@ -34,6 +34,7 @@ #include "py/mperrno.h" #include "lib/oofatfs/ff.h" #include "extmod/vfs_fat.h" +#include "supervisor/filesystem.h" // this table converts from FRESULT to POSIX errno const byte fresult_to_errno_table[20] = { @@ -59,11 +60,6 @@ const byte fresult_to_errno_table[20] = { [FR_INVALID_PARAMETER] = MP_EINVAL, }; -typedef struct _pyb_file_obj_t { - mp_obj_base_t base; - FIL fp; -} pyb_file_obj_t; - STATIC void file_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; mp_printf(print, "", mp_obj_get_type_str(self_in), MP_OBJ_TO_PTR(self_in)); @@ -191,17 +187,37 @@ STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_ar break; } } + assert(vfs != NULL); + if ((mode & FA_WRITE) != 0 && !filesystem_is_writable_by_python(vfs)) { + mp_raise_OSError(MP_EROFS); + } pyb_file_obj_t *o = m_new_obj_with_finaliser(pyb_file_obj_t); o->base.type = type; const char *fname = mp_obj_str_get_str(args[0].u_obj); - assert(vfs != NULL); FRESULT res = f_open(&vfs->fatfs, &o->fp, fname, mode); if (res != FR_OK) { m_del_obj(pyb_file_obj_t, o); mp_raise_OSError(fresult_to_errno_table[res]); } + // If we're reading, turn on fast seek. + if (mode == FA_READ) { + // one call to determine how much space we need. + DWORD temp_table[2]; + temp_table[0] = 2; + o->fp.cltbl = temp_table; + f_lseek(&o->fp, CREATE_LINKMAP); + DWORD size = (temp_table[0] + 1) * 2; + o->fp.cltbl = m_malloc_maybe(size * sizeof(DWORD), false); + if (o->fp.cltbl != NULL) { + o->fp.cltbl[0] = size; + res = f_lseek(&o->fp, CREATE_LINKMAP); + if (res != FR_OK) { + o->fp.cltbl = NULL; + } + } + } // for 'a' mode, we must begin at the end of the file if ((mode & FA_OPEN_ALWAYS) != 0) { @@ -211,9 +227,9 @@ STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_ar return MP_OBJ_FROM_PTR(o); } -STATIC mp_obj_t file_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t file_obj_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS]; - mp_arg_parse_all_kw_array(n_args, n_kw, args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals); + mp_arg_parse_all(n_args, args, kw_args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals); return file_open(NULL, type, arg_vals); } diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c index 6e3bb2c5bd1..d28dfe45165 100644 --- a/extmod/vfs_posix.c +++ b/extmod/vfs_posix.c @@ -29,8 +29,9 @@ #include "extmod/vfs.h" #include "extmod/vfs_posix.h" -#if MICROPY_VFS_POSIX +#if defined(MICROPY_VFS_POSIX) && MICROPY_VFS_POSIX +#include #include #include #include @@ -89,8 +90,8 @@ STATIC mp_import_stat_t mp_vfs_posix_import_stat(void *self_in, const char *path return MP_IMPORT_STAT_NO_EXIST; } -STATIC mp_obj_t vfs_posix_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 1, false); +STATIC mp_obj_t vfs_posix_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 1, false); mp_obj_vfs_posix_t *vfs = m_new_obj(mp_obj_vfs_posix_t); vfs->base.type = type; diff --git a/extmod/vfs_posix.h b/extmod/vfs_posix.h index 00756b4c9d6..32299b8269f 100644 --- a/extmod/vfs_posix.h +++ b/extmod/vfs_posix.h @@ -27,6 +27,7 @@ #define MICROPY_INCLUDED_EXTMOD_VFS_POSIX_H #include "py/lexer.h" +#include "py/mpconfig.h" #include "py/obj.h" extern const mp_obj_type_t mp_type_vfs_posix; diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c index 435ac65cd40..b760b384741 100644 --- a/extmod/vfs_posix_file.c +++ b/extmod/vfs_posix_file.c @@ -27,8 +27,9 @@ #include "py/runtime.h" #include "py/stream.h" #include "extmod/vfs_posix.h" +#include "supervisor/shared/translate.h" -#if MICROPY_VFS_POSIX +#if defined(MICROPY_VFS_POSIX) && MICROPY_VFS_POSIX #include @@ -44,7 +45,7 @@ typedef struct _mp_obj_vfs_posix_file_t { #ifdef MICROPY_CPYTHON_COMPAT STATIC void check_fd_is_open(const mp_obj_vfs_posix_file_t *o) { if (o->fd < 0) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "I/O operation on closed file")); + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, translate("I/O operation on closed file"))); } } #else @@ -108,14 +109,14 @@ mp_obj_t mp_vfs_posix_file_open(const mp_obj_type_t *type, mp_obj_t file_in, mp_ return MP_OBJ_FROM_PTR(o); } -STATIC mp_obj_t vfs_posix_file_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t vfs_posix_file_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { static const mp_arg_t allowed_args[] = { { MP_QSTR_file, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} }, { MP_QSTR_mode, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_QSTR(MP_QSTR_r)} }, }; mp_arg_val_t arg_vals[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, arg_vals); + mp_arg_parse_all(n_args, args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, arg_vals); return mp_vfs_posix_file_open(type, arg_vals[0].u_obj, arg_vals[1].u_obj); } diff --git a/frozen/Adafruit_CircuitPython_BusDevice b/frozen/Adafruit_CircuitPython_BusDevice new file mode 160000 index 00000000000..b9280af5142 --- /dev/null +++ b/frozen/Adafruit_CircuitPython_BusDevice @@ -0,0 +1 @@ +Subproject commit b9280af5142fc41639229544678e23b5cca07c3a diff --git a/frozen/Adafruit_CircuitPython_CircuitPlayground b/frozen/Adafruit_CircuitPython_CircuitPlayground new file mode 160000 index 00000000000..154b74de020 --- /dev/null +++ b/frozen/Adafruit_CircuitPython_CircuitPlayground @@ -0,0 +1 @@ +Subproject commit 154b74de020764597ba49f0d1e8cc18d55b3643b diff --git a/frozen/Adafruit_CircuitPython_Crickit b/frozen/Adafruit_CircuitPython_Crickit new file mode 160000 index 00000000000..617bb0787f2 --- /dev/null +++ b/frozen/Adafruit_CircuitPython_Crickit @@ -0,0 +1 @@ +Subproject commit 617bb0787f2c61283d248632a62b27be80f64b29 diff --git a/frozen/Adafruit_CircuitPython_DotStar b/frozen/Adafruit_CircuitPython_DotStar new file mode 160000 index 00000000000..409e90902ac --- /dev/null +++ b/frozen/Adafruit_CircuitPython_DotStar @@ -0,0 +1 @@ +Subproject commit 409e90902ac49720c4add985e8e1a1660bbe63a0 diff --git a/frozen/Adafruit_CircuitPython_HID b/frozen/Adafruit_CircuitPython_HID new file mode 160000 index 00000000000..89faee0eb08 --- /dev/null +++ b/frozen/Adafruit_CircuitPython_HID @@ -0,0 +1 @@ +Subproject commit 89faee0eb08a6855e14f117c514fecf2dd90769d diff --git a/frozen/Adafruit_CircuitPython_IRRemote b/frozen/Adafruit_CircuitPython_IRRemote new file mode 160000 index 00000000000..70865ac6e09 --- /dev/null +++ b/frozen/Adafruit_CircuitPython_IRRemote @@ -0,0 +1 @@ +Subproject commit 70865ac6e09f821b26ec727e2df300a6d9ebf6b3 diff --git a/frozen/Adafruit_CircuitPython_LIS3DH b/frozen/Adafruit_CircuitPython_LIS3DH new file mode 160000 index 00000000000..bd7ddc67dc8 --- /dev/null +++ b/frozen/Adafruit_CircuitPython_LIS3DH @@ -0,0 +1 @@ +Subproject commit bd7ddc67dc86f7ad0115f58ab80d5605739c6482 diff --git a/frozen/Adafruit_CircuitPython_Motor b/frozen/Adafruit_CircuitPython_Motor new file mode 160000 index 00000000000..ddc74844983 --- /dev/null +++ b/frozen/Adafruit_CircuitPython_Motor @@ -0,0 +1 @@ +Subproject commit ddc74844983b35b027bd45091c7b8bb3c8d7a2d1 diff --git a/frozen/Adafruit_CircuitPython_NeoPixel b/frozen/Adafruit_CircuitPython_NeoPixel new file mode 160000 index 00000000000..c0bdd8b1038 --- /dev/null +++ b/frozen/Adafruit_CircuitPython_NeoPixel @@ -0,0 +1 @@ +Subproject commit c0bdd8b10383725ee9293f5d88fb8d47eb1272bd diff --git a/frozen/Adafruit_CircuitPython_Thermistor b/frozen/Adafruit_CircuitPython_Thermistor new file mode 160000 index 00000000000..893c5ec6a9a --- /dev/null +++ b/frozen/Adafruit_CircuitPython_Thermistor @@ -0,0 +1 @@ +Subproject commit 893c5ec6a9aeef38284985074c2058e87754ad3d diff --git a/frozen/Adafruit_CircuitPython_seesaw b/frozen/Adafruit_CircuitPython_seesaw new file mode 160000 index 00000000000..f1171f94083 --- /dev/null +++ b/frozen/Adafruit_CircuitPython_seesaw @@ -0,0 +1 @@ +Subproject commit f1171f94083ba64d153ff3f90eeb07500331d6e1 diff --git a/frozen/circuitpython-stage b/frozen/circuitpython-stage new file mode 160000 index 00000000000..0d2d660e886 --- /dev/null +++ b/frozen/circuitpython-stage @@ -0,0 +1 @@ +Subproject commit 0d2d660e886de8a1b96778c865c7fa48df5f4ea6 diff --git a/frozen/pew-pewpew-standalone-10.x b/frozen/pew-pewpew-standalone-10.x new file mode 160000 index 00000000000..87755e08815 --- /dev/null +++ b/frozen/pew-pewpew-standalone-10.x @@ -0,0 +1 @@ +Subproject commit 87755e088150cc9bce42f4104cbd74d91b923c6f diff --git a/lib/embed/abort_.c b/lib/embed/abort_.c index 2fba0de4eaf..3eeb42d9e48 100644 --- a/lib/embed/abort_.c +++ b/lib/embed/abort_.c @@ -1,7 +1,9 @@ #include +#include "supervisor/shared/translate.h" + NORETURN void abort_(void); NORETURN void abort_(void) { - mp_raise_msg(&mp_type_RuntimeError, "abort() called"); + mp_raise_msg(&mp_type_RuntimeError, translate("abort() called")); } diff --git a/lib/libc/string0.c b/lib/libc/string0.c index c2f2abd0f95..a2f936237d0 100644 --- a/lib/libc/string0.c +++ b/lib/libc/string0.c @@ -29,6 +29,8 @@ #define likely(x) __builtin_expect((x), 1) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" void *memcpy(void *dst, const void *src, size_t n) { if (likely(!(((uintptr_t)dst) & 3) && !(((uintptr_t)src) & 3))) { // pointers aligned @@ -102,6 +104,8 @@ void *memset(void *s, int c, size_t n) { return s; } +#pragma GCC diagnostic pop + int memcmp(const void *s1, const void *s2, size_t n) { const uint8_t *s1_8 = s1; const uint8_t *s2_8 = s2; diff --git a/lib/libm/ef_rem_pio2.c b/lib/libm/ef_rem_pio2.c index ca55243fb4f..601f3bac4e9 100644 --- a/lib/libm/ef_rem_pio2.c +++ b/lib/libm/ef_rem_pio2.c @@ -151,7 +151,7 @@ pio2_3t = 6.1232342629e-17; /* 0x248d3132 */ fn = (float)n; r = t-fn*pio2_1; w = fn*pio2_1t; /* 1st round good to 40 bit */ - if(n<32&&(ix&0xffffff00)!=npio2_hw[n-1]) { + if(n<32&&(__int32_t)(ix&0xffffff00)!=npio2_hw[n-1]) { y[0] = r-w; /* quick check no cancellation */ } else { __uint32_t high; @@ -195,7 +195,10 @@ pio2_3t = 6.1232342629e-17; /* 0x248d3132 */ } tx[2] = z; nx = 3; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" while(tx[nx-1]==zero) nx--; /* skip zero term */ +#pragma GCC diagnostic pop n = __kernel_rem_pio2f(tx,y,e0,nx,2,two_over_pi); if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} return n; diff --git a/lib/libm/kf_rem_pio2.c b/lib/libm/kf_rem_pio2.c index c7e9479571e..3b09de5fd0e 100644 --- a/lib/libm/kf_rem_pio2.c +++ b/lib/libm/kf_rem_pio2.c @@ -138,7 +138,10 @@ twon8 = 3.9062500000e-03; /* 0x3b800000 */ } /* check if recomputation is needed */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" if(z==zero) { +#pragma GCC diagnostic pop j = 0; for (i=jz-1;i>=jk;i--) j |= iq[i]; if(j==0) { /* need recomputation */ @@ -155,7 +158,10 @@ twon8 = 3.9062500000e-03; /* 0x3b800000 */ } /* chop off zero terms */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" if(z==(float)0.0) { +#pragma GCC diagnostic pop jz -= 1; q0 -= 8; while(iq[jz]==0) { jz--; q0-=8;} } else { /* break z into 8-bit if necessary */ diff --git a/lib/libm/math.c b/lib/libm/math.c index 6b65202cf0e..39c6a68a5e9 100644 --- a/lib/libm/math.c +++ b/lib/libm/math.c @@ -333,7 +333,7 @@ float powf(float x, float y) return sn*huge*huge; /* overflow */ } else if ((j&0x7fffffff) > 0x43160000) /* z < -150 */ // FIXME: check should be (uint32_t)j > 0xc3160000 return sn*tiny*tiny; /* underflow */ - else if (j == 0xc3160000) { /* z == -150 */ + else if (j == (int32_t) 0xc3160000) { /* z == -150 */ if (p_l <= z-p_h) return sn*tiny*tiny; /* underflow */ } @@ -580,13 +580,13 @@ float expm1f(float x) /*****************************************************************************/ /*****************************************************************************/ -/* k is such that k*ln2 has minimal relative error and x - kln2 > log(FLT_MIN) */ -static const int k = 235; -static const float kln2 = 0x1.45c778p+7f; /* expf(x)/2 for x >= log(FLT_MAX), slightly better than 0.5f*expf(x/2)*expf(x/2) */ float __expo2f(float x) { + /* k is such that k*ln2 has minimal relative error and x - kln2 > log(FLT_MIN) */ + static const int k = 235; + static const float kln2 = 0x1.45c778p+7f; float scale; /* note that k is odd and scale*scale overflows */ diff --git a/lib/libm/nearbyintf.c b/lib/libm/nearbyintf.c index 1c3545945d0..5ac3178b51c 100644 --- a/lib/libm/nearbyintf.c +++ b/lib/libm/nearbyintf.c @@ -15,7 +15,10 @@ float nearbyintf(float x) y = x - 0x1p23f + 0x1p23f; else y = x + 0x1p23f - 0x1p23f; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" if (y == 0) return s ? -0.0f : 0.0f; +#pragma GCC diagnostic pop return y; } diff --git a/lib/libm/sf_ldexp.c b/lib/libm/sf_ldexp.c index 37968d475ae..75cb8b72750 100644 --- a/lib/libm/sf_ldexp.c +++ b/lib/libm/sf_ldexp.c @@ -32,7 +32,10 @@ float value; int exp; #endif { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" if(!isfinite(value)||value==(float)0.0) return value; +#pragma GCC diagnostic pop value = scalbnf(value,exp); //if(!finitef(value)||value==(float)0.0) errno = ERANGE; return value; diff --git a/lib/libm_dbl/pow.c b/lib/libm_dbl/pow.c index 3ddc1b6ff8e..4aef8a5b3e0 100644 --- a/lib/libm_dbl/pow.c +++ b/lib/libm_dbl/pow.c @@ -125,13 +125,13 @@ double pow(double x, double y) else if (iy >= 0x3ff00000) { k = (iy>>20) - 0x3ff; /* exponent */ if (k > 20) { - uint32_t j = ly>>(52-k); - if ((j<<(52-k)) == ly) - yisint = 2 - (j&1); + uint32_t j2 = ly>>(52-k); + if ((j2<<(52-k)) == ly) + yisint = 2 - (j2&1); } else if (ly == 0) { - uint32_t j = iy>>(20-k); - if ((j<<(20-k)) == iy) - yisint = 2 - (j&1); + uint32_t j2 = iy>>(20-k); + if ((j2<<(20-k)) == (uint32_t)iy) + yisint = 2 - (j2&1); } } } diff --git a/lib/lwip b/lib/lwip deleted file mode 160000 index 92f23d6ca09..00000000000 --- a/lib/lwip +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 92f23d6ca0971a32f2085b9480e738d34174417b diff --git a/lib/mp-readline/readline.h b/lib/mp-readline/readline.h index 00aa9622a80..17d4ec60eda 100644 --- a/lib/mp-readline/readline.h +++ b/lib/mp-readline/readline.h @@ -26,6 +26,8 @@ #ifndef MICROPY_INCLUDED_LIB_MP_READLINE_READLINE_H #define MICROPY_INCLUDED_LIB_MP_READLINE_READLINE_H +#include "py/misc.h" + #define CHAR_CTRL_A (1) #define CHAR_CTRL_B (2) #define CHAR_CTRL_C (3) diff --git a/lib/netutils/netutils.c b/lib/netutils/netutils.c index 073f46b1993..03418d7e663 100644 --- a/lib/netutils/netutils.c +++ b/lib/netutils/netutils.c @@ -31,6 +31,7 @@ #include "py/runtime.h" #include "lib/netutils/netutils.h" +#include "supervisor/shared/translate.h" // Takes an array with a raw IPv4 address and returns something like '192.168.0.1'. mp_obj_t netutils_format_ipv4_addr(uint8_t *ip, netutils_endian_t endian) { @@ -79,7 +80,7 @@ void netutils_parse_ipv4_addr(mp_obj_t addr_in, uint8_t *out_ip, netutils_endian } else if (i > 0 && s < s_top && *s == '.') { s++; } else { - mp_raise_ValueError("invalid arguments"); + mp_raise_ValueError(translate("invalid arguments")); } } } diff --git a/lib/nrfutil b/lib/nrfutil new file mode 160000 index 00000000000..9e7dfb28a5c --- /dev/null +++ b/lib/nrfutil @@ -0,0 +1 @@ +Subproject commit 9e7dfb28a5c6f3d7a19340971b32e0c2b4128ecf diff --git a/lib/oofatfs/ffconf.h b/lib/oofatfs/ffconf.h index 315101f0e4a..214311b4c22 100644 --- a/lib/oofatfs/ffconf.h +++ b/lib/oofatfs/ffconf.h @@ -74,7 +74,7 @@ /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ -#define _USE_FASTSEEK 0 +#define _USE_FASTSEEK 1 /* This option switches fast seek function. (0:Disable or 1:Enable) */ diff --git a/lib/stm32lib b/lib/stm32lib index 1fe30d1446f..d2bcfda543d 160000 --- a/lib/stm32lib +++ b/lib/stm32lib @@ -1 +1 @@ -Subproject commit 1fe30d1446f2eba3730dc4b05e9ac0cf03bcf9bf +Subproject commit d2bcfda543d3b99361e44112aca929225bdcc07f diff --git a/lib/timeutils/timeutils.c b/lib/timeutils/timeutils.c index eb3dc80d4b5..b93a85dee9f 100644 --- a/lib/timeutils/timeutils.c +++ b/lib/timeutils/timeutils.c @@ -158,6 +158,17 @@ mp_uint_t timeutils_seconds_since_2000(mp_uint_t year, mp_uint_t month, + (year - 2000) * 31536000; } +void timeutils_seconds_since_epoch_to_struct_time(mp_uint_t t, timeutils_struct_time_t *tm) { + t -= EPOCH1970_EPOCH2000_DIFF_SECS; + timeutils_seconds_since_2000_to_struct_time(t, tm); +} + +mp_uint_t timeutils_seconds_since_epoch(mp_uint_t year, mp_uint_t month, mp_uint_t date, + mp_uint_t hour, mp_uint_t minute, mp_uint_t second) { + mp_uint_t t = timeutils_seconds_since_2000(year, month, date, hour, minute, second); + return t + EPOCH1970_EPOCH2000_DIFF_SECS; +} + mp_uint_t timeutils_mktime(mp_uint_t year, mp_int_t month, mp_int_t mday, mp_int_t hours, mp_int_t minutes, mp_int_t seconds) { @@ -211,5 +222,5 @@ mp_uint_t timeutils_mktime(mp_uint_t year, mp_int_t month, mp_int_t mday, year++; } } - return timeutils_seconds_since_2000(year, month, mday, hours, minutes, seconds); + return timeutils_seconds_since_epoch(year, month, mday, hours, minutes, seconds); } diff --git a/lib/timeutils/timeutils.h b/lib/timeutils/timeutils.h index 9b1abeb8f3d..0ca6bb1679e 100644 --- a/lib/timeutils/timeutils.h +++ b/lib/timeutils/timeutils.h @@ -27,6 +27,8 @@ #ifndef MICROPY_INCLUDED_LIB_TIMEUTILS_TIMEUTILS_H #define MICROPY_INCLUDED_LIB_TIMEUTILS_TIMEUTILS_H +#define EPOCH1970_EPOCH2000_DIFF_SECS 946684800 + typedef struct _timeutils_struct_time_t { uint16_t tm_year; // i.e. 2014 uint8_t tm_mon; // 1..12 @@ -48,6 +50,11 @@ void timeutils_seconds_since_2000_to_struct_time(mp_uint_t t, mp_uint_t timeutils_seconds_since_2000(mp_uint_t year, mp_uint_t month, mp_uint_t date, mp_uint_t hour, mp_uint_t minute, mp_uint_t second); +void timeutils_seconds_since_epoch_to_struct_time(mp_uint_t t, timeutils_struct_time_t *tm); + +mp_uint_t timeutils_seconds_since_epoch(mp_uint_t year, mp_uint_t month, mp_uint_t date, + mp_uint_t hour, mp_uint_t minute, mp_uint_t second); + mp_uint_t timeutils_mktime(mp_uint_t year, mp_int_t month, mp_int_t mday, mp_int_t hours, mp_int_t minutes, mp_int_t seconds); diff --git a/lib/tinyusb b/lib/tinyusb new file mode 160000 index 00000000000..00c440cb26f --- /dev/null +++ b/lib/tinyusb @@ -0,0 +1 @@ +Subproject commit 00c440cb26fbea7fd367623454d8b67855f1372f diff --git a/lib/utils/buffer_helper.c b/lib/utils/buffer_helper.c new file mode 100644 index 00000000000..694952e3d2c --- /dev/null +++ b/lib/utils/buffer_helper.c @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "lib/utils/buffer_helper.h" + +void normalize_buffer_bounds(int32_t* start, int32_t end, size_t* length) { + if (end < 0) { + end += *length; + } else if (((size_t) end) > *length) { + end = *length; + } + if (*start < 0) { + *start += *length; + } + if (end < *start) { + *length = 0; + } else { + *length = end - *start; + } +} diff --git a/lib/utils/buffer_helper.h b/lib/utils/buffer_helper.h new file mode 100644 index 00000000000..7487b9df533 --- /dev/null +++ b/lib/utils/buffer_helper.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_LIB_UTILS_BUFFER_HELPER_H +#define MICROPY_INCLUDED_LIB_UTILS_BUFFER_HELPER_H + +#include +#include + +void normalize_buffer_bounds(int32_t* start, int32_t end, size_t* length); + +#endif // MICROPY_INCLUDED_LIB_UTILS_BUFFER_HELPER_H diff --git a/lib/utils/context_manager_helpers.c b/lib/utils/context_manager_helpers.c new file mode 100644 index 00000000000..901c27030f7 --- /dev/null +++ b/lib/utils/context_manager_helpers.c @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "lib/utils/context_manager_helpers.h" + +#include "py/obj.h" + +STATIC mp_obj_t default___enter__(mp_obj_t self_in) { + return self_in; +} +MP_DEFINE_CONST_FUN_OBJ_1(default___enter___obj, default___enter__); diff --git a/lib/utils/context_manager_helpers.h b/lib/utils/context_manager_helpers.h new file mode 100644 index 00000000000..286ab750eef --- /dev/null +++ b/lib/utils/context_manager_helpers.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_LIB_UTILS_CONTEXT_MANAGER_HELPERS_H +#define MICROPY_INCLUDED_LIB_UTILS_CONTEXT_MANAGER_HELPERS_H + +#include "py/obj.h" + +MP_DECLARE_CONST_FUN_OBJ_1(default___enter___obj); + +#endif // MICROPY_INCLUDED_LIB_UTILS_CONTEXT_MANAGER_HELPERS_H diff --git a/lib/utils/interrupt_char.c b/lib/utils/interrupt_char.c index fca0f95b5bf..91ee5c80efa 100644 --- a/lib/utils/interrupt_char.c +++ b/lib/utils/interrupt_char.c @@ -47,4 +47,9 @@ void mp_keyboard_interrupt(void) { #endif } +// Check to see if we've been CTRL-C'ed by autoreload or the user. +bool mp_hal_is_interrupted(void) { + return MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)); +} + #endif diff --git a/lib/utils/interrupt_char.h b/lib/utils/interrupt_char.h index ca50d4d5676..e0b1db52985 100644 --- a/lib/utils/interrupt_char.h +++ b/lib/utils/interrupt_char.h @@ -26,8 +26,11 @@ #ifndef MICROPY_INCLUDED_LIB_UTILS_INTERRUPT_CHAR_H #define MICROPY_INCLUDED_LIB_UTILS_INTERRUPT_CHAR_H +#include + extern int mp_interrupt_char; void mp_hal_set_interrupt_char(int c); void mp_keyboard_interrupt(void); +bool mp_hal_is_interrupted(void); #endif // MICROPY_INCLUDED_LIB_UTILS_INTERRUPT_CHAR_H diff --git a/lib/utils/printf.c b/lib/utils/printf.c index 51dfa5b9634..3a4cc254946 100644 --- a/lib/utils/printf.c +++ b/lib/utils/printf.c @@ -60,13 +60,13 @@ int vprintf(const char *fmt, va_list ap) { } #if MICROPY_DEBUG_PRINTERS +extern const mp_print_t MICROPY_DEBUG_PRINTER_DEST; int DEBUG_printf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); #ifndef MICROPY_DEBUG_PRINTER_DEST #define MICROPY_DEBUG_PRINTER_DEST mp_plat_print #endif - extern const mp_print_t MICROPY_DEBUG_PRINTER_DEST; int ret = mp_vprintf(&MICROPY_DEBUG_PRINTER_DEST, fmt, ap); va_end(ap); return ret; @@ -103,9 +103,11 @@ STATIC void strn_print_strn(void *data, const char *str, size_t len) { strn_print_env->remain -= len; } -#if defined(__GNUC__) && !defined(__clang__) +#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 9 // uClibc requires this alias to be defined, or there may be link errors // when linkings against it statically. +// GCC 9 gives a warning about missing attributes so it's excluded until +// uClibc+GCC9 support is needed. int __GI_vsnprintf(char *str, size_t size, const char *fmt, va_list ap) __attribute__((weak, alias ("vsnprintf"))); #endif diff --git a/lib/utils/pyexec.c b/lib/utils/pyexec.c old mode 100644 new mode 100755 index 0522de79734..c8e369e791f --- a/lib/utils/pyexec.c +++ b/lib/utils/pyexec.c @@ -33,6 +33,7 @@ #include "py/runtime.h" #include "py/repl.h" #include "py/gc.h" +#include "py/gc_long_lived.h" #include "py/frozenmod.h" #include "py/mphal.h" #if MICROPY_HW_ENABLE_USB @@ -59,7 +60,7 @@ STATIC bool repl_display_debugging_info = 0; // EXEC_FLAG_PRINT_EOF prints 2 EOF chars: 1 after normal output, 1 after exception output // EXEC_FLAG_ALLOW_DEBUGGING allows debugging info to be printed after executing the code // EXEC_FLAG_IS_REPL is used for REPL inputs (flag passed on to mp_compile) -STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input_kind, int exec_flags) { +STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input_kind, int exec_flags, pyexec_result_t *result) { int ret = 0; uint32_t start = 0; @@ -88,20 +89,32 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input } // source is a lexer, parse and compile the script qstr source_name = lex->source_name; + if (input_kind == MP_PARSE_FILE_INPUT) { + mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); + } mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, exec_flags & EXEC_FLAG_IS_REPL); + // Clear the parse tree because it has a heap pointer we don't need anymore. + *((uint32_t volatile*) &parse_tree.chunk) = 0; #else - mp_raise_msg(&mp_type_RuntimeError, "script compilation not supported"); + mp_raise_msg(&mp_type_RuntimeError, translate("script compilation not supported")); #endif } + // If the code was loaded from a file its likely to be running for a while so we'll long + // live it and collect any garbage before running. + if (input_kind == MP_PARSE_FILE_INPUT) { + module_fun = make_obj_long_lived(module_fun, 6); + gc_collect(); + } + // execute code mp_hal_set_interrupt_char(CHAR_CTRL_C); // allow ctrl-C to interrupt us start = mp_hal_ticks_ms(); mp_call_function_0(module_fun); mp_hal_set_interrupt_char(-1); // disable interrupt nlr_pop(); - ret = 1; + ret = 0; if (exec_flags & EXEC_FLAG_PRINT_EOF) { mp_hal_stdout_tx_strn("\x04", 1); } @@ -118,8 +131,26 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input // at the moment, the value of SystemExit is unused ret = pyexec_system_exit; } else { - mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); - ret = 0; + if ((mp_obj_t) nlr.ret_val != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { + mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); + } + ret = PYEXEC_EXCEPTION; + } + } + if (result != NULL) { + result->return_code = ret; + if (ret != 0) { + mp_obj_t return_value = (mp_obj_t)nlr.ret_val; + result->exception_type = mp_obj_get_type(return_value); + result->exception_line = -1; + + if (mp_obj_is_exception_instance(return_value)) { + size_t n, *values; + mp_obj_exception_get_traceback(return_value, &n, &values); + if (values != NULL) { + result->exception_line = values[n - 2]; + } + } } } @@ -213,7 +244,7 @@ STATIC int pyexec_raw_repl_process_char(int c) { return PYEXEC_FORCED_EXIT; } - int ret = parse_compile_execute(MP_STATE_VM(repl_line), MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF | EXEC_FLAG_SOURCE_IS_VSTR); + int ret = parse_compile_execute(MP_STATE_VM(repl_line), MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF | EXEC_FLAG_SOURCE_IS_VSTR, NULL); if (ret & PYEXEC_FORCED_EXIT) { return ret; } @@ -239,10 +270,9 @@ STATIC int pyexec_friendly_repl_process_char(int c) { } else if (ret == CHAR_CTRL_B) { // reset friendly REPL mp_hal_stdout_tx_str("\r\n"); - mp_hal_stdout_tx_str("MicroPython " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE "; " MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME "\r\n"); - #if MICROPY_PY_BUILTINS_HELP - mp_hal_stdout_tx_str("Type \"help()\" for more information.\r\n"); - #endif + mp_hal_stdout_tx_str(MICROPY_FULL_VERSION_INFO); + mp_hal_stdout_tx_str("\r\n"); + // mp_hal_stdout_tx_str("Type \"help()\" for more information.\r\n"); goto input_restart; } else if (ret == CHAR_CTRL_C) { // break @@ -291,7 +321,7 @@ STATIC int pyexec_friendly_repl_process_char(int c) { } exec: ; - int ret = parse_compile_execute(MP_STATE_VM(repl_line), MP_PARSE_SINGLE_INPUT, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR); + int ret = parse_compile_execute(MP_STATE_VM(repl_line), MP_PARSE_SINGLE_INPUT, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR, NULL); if (ret & PYEXEC_FORCED_EXIT) { return ret; } @@ -362,7 +392,7 @@ int pyexec_raw_repl(void) { return PYEXEC_FORCED_EXIT; } - int ret = parse_compile_execute(&line, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF | EXEC_FLAG_SOURCE_IS_VSTR); + int ret = parse_compile_execute(&line, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF | EXEC_FLAG_SOURCE_IS_VSTR, NULL); if (ret & PYEXEC_FORCED_EXIT) { return ret; } @@ -380,10 +410,10 @@ int pyexec_friendly_repl(void) { #endif friendly_repl_reset: - mp_hal_stdout_tx_str("MicroPython " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE "; " MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME "\r\n"); - #if MICROPY_PY_BUILTINS_HELP - mp_hal_stdout_tx_str("Type \"help()\" for more information.\r\n"); - #endif + mp_hal_stdout_tx_str("\r\n"); + mp_hal_stdout_tx_str(MICROPY_FULL_VERSION_INFO); + mp_hal_stdout_tx_str("\r\n"); + // mp_hal_stdout_tx_str("Type \"help()\" for more information.\r\n"); // to test ctrl-C /* @@ -485,7 +515,7 @@ int pyexec_friendly_repl(void) { } } - ret = parse_compile_execute(&line, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR); + ret = parse_compile_execute(&line, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR, NULL); if (ret & PYEXEC_FORCED_EXIT) { return ret; } @@ -495,8 +525,8 @@ int pyexec_friendly_repl(void) { #endif // MICROPY_REPL_EVENT_DRIVEN #endif // MICROPY_ENABLE_COMPILER -int pyexec_file(const char *filename) { - return parse_compile_execute(filename, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_FILENAME); +int pyexec_file(const char *filename, pyexec_result_t *result) { + return parse_compile_execute(filename, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_FILENAME, result); } #if MICROPY_MODULE_FROZEN @@ -507,12 +537,12 @@ int pyexec_frozen_module(const char *name) { switch (frozen_type) { #if MICROPY_MODULE_FROZEN_STR case MP_FROZEN_STR: - return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, 0); + return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, 0, NULL); #endif #if MICROPY_MODULE_FROZEN_MPY case MP_FROZEN_MPY: - return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_RAW_CODE); + return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_RAW_CODE, NULL); #endif default: diff --git a/lib/utils/pyexec.h b/lib/utils/pyexec.h index 678c56cf480..bde516c593b 100644 --- a/lib/utils/pyexec.h +++ b/lib/utils/pyexec.h @@ -33,6 +33,12 @@ typedef enum { PYEXEC_MODE_FRIENDLY_REPL, } pyexec_mode_kind_t; +typedef struct { + int return_code; + const mp_obj_type_t * exception_type; + int exception_line; +} pyexec_result_t; + extern pyexec_mode_kind_t pyexec_mode_kind; // Set this to the value (eg PYEXEC_FORCED_EXIT) that will be propagated through @@ -42,14 +48,16 @@ extern int pyexec_system_exit; #define PYEXEC_FORCED_EXIT (0x100) #define PYEXEC_SWITCH_MODE (0x200) +#define PYEXEC_EXCEPTION (0x400) int pyexec_raw_repl(void); int pyexec_friendly_repl(void); -int pyexec_file(const char *filename); +int pyexec_file(const char *filename, pyexec_result_t *result); int pyexec_frozen_module(const char *name); void pyexec_event_repl_init(void); int pyexec_event_repl_process_char(int c); extern uint8_t pyexec_repl_active; +mp_obj_t pyb_set_repl_info(mp_obj_t o_value); MP_DECLARE_CONST_FUN_OBJ_1(pyb_set_repl_info_obj); diff --git a/lib/utils/stdout_helpers.c b/lib/utils/stdout_helpers.c index 3de11975719..4323e8a083b 100644 --- a/lib/utils/stdout_helpers.c +++ b/lib/utils/stdout_helpers.c @@ -12,11 +12,21 @@ // Send "cooked" string of given length, where every occurrence of // LF character is replaced with CR LF. void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) { - while (len--) { - if (*str == '\n') { + bool last_cr = false; + while (len > 0) { + size_t i = 0; + if (str[0] == '\n' && !last_cr) { mp_hal_stdout_tx_strn("\r", 1); + i = 1; } - mp_hal_stdout_tx_strn(str++, 1); + // Lump all characters on the next line together. + while((last_cr || str[i] != '\n') && i < len) { + last_cr = str[i] == '\r'; + i++; + } + mp_hal_stdout_tx_strn(str, i); + str = &str[i]; + len -= i; } } diff --git a/lib/utils/sys_stdio_mphal.c b/lib/utils/sys_stdio_mphal.c index fc8a74e7d6d..266783f376e 100644 --- a/lib/utils/sys_stdio_mphal.c +++ b/lib/utils/sys_stdio_mphal.c @@ -53,12 +53,12 @@ STATIC const sys_stdio_obj_t stdio_buffer_obj; #endif void stdio_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - sys_stdio_obj_t *self = self_in; + sys_stdio_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "", self->fd); } STATIC mp_uint_t stdio_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) { - sys_stdio_obj_t *self = self_in; + sys_stdio_obj_t *self = MP_OBJ_TO_PTR(self_in); if (self->fd == STDIO_FD_IN) { for (uint i = 0; i < size; i++) { int c = mp_hal_stdin_rx_chr(); @@ -75,7 +75,7 @@ STATIC mp_uint_t stdio_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *er } STATIC mp_uint_t stdio_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) { - sys_stdio_obj_t *self = self_in; + sys_stdio_obj_t *self = MP_OBJ_TO_PTR(self_in); if (self->fd == STDIO_FD_OUT || self->fd == STDIO_FD_ERR) { mp_hal_stdout_tx_strn_cooked(buf, size); return size; @@ -85,6 +85,19 @@ STATIC mp_uint_t stdio_write(mp_obj_t self_in, const void *buf, mp_uint_t size, } } +STATIC mp_uint_t stdio_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { + sys_stdio_obj_t *self = MP_OBJ_TO_PTR(self_in); + (void) self; + + // For now, pretend we actually flush the stdio stream. + if (request == MP_STREAM_FLUSH) { + return 0; + } else { + *errcode = MP_EINVAL; + return MP_STREAM_ERROR; + } +} + STATIC mp_obj_t stdio_obj___exit__(size_t n_args, const mp_obj_t *args) { return mp_const_none; } @@ -112,6 +125,7 @@ STATIC MP_DEFINE_CONST_DICT(stdio_locals_dict, stdio_locals_dict_table); STATIC const mp_stream_p_t stdio_obj_stream_p = { .read = stdio_read, .write = stdio_write, + .ioctl = stdio_ioctl, .is_text = true, }; diff --git a/lib/uzlib b/lib/uzlib new file mode 160000 index 00000000000..f966da0fab1 --- /dev/null +++ b/lib/uzlib @@ -0,0 +1 @@ +Subproject commit f966da0fab121e910ea74f037f074538a2e6dbbb diff --git a/docs/license.rst b/license.rst similarity index 91% rename from docs/license.rst rename to license.rst index 73caa903513..7e97341cda7 100644 --- a/docs/license.rst +++ b/license.rst @@ -1,5 +1,5 @@ -MicroPython license information -=============================== +MicroPython & CircuitPython license information +=============================================== The MIT License (MIT) diff --git a/locale/ID.po b/locale/ID.po new file mode 100644 index 00000000000..9c96fd32716 --- /dev/null +++ b/locale/ID.po @@ -0,0 +1,2947 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: main.c +msgid "" +"\n" +"Code done running. Waiting for reload.\n" +msgstr "" + +#: py/obj.c +msgid " File \"%q\"" +msgstr "" + +#: py/obj.c +msgid " File \"%q\", line %d" +msgstr "" + +#: main.c +msgid " output:\n" +msgstr "output:\n" + +#: py/objstr.c +#, c-format +msgid "%%c requires int or char" +msgstr "" + +#: shared-bindings/microcontroller/Pin.c +msgid "%q in use" +msgstr "" + +#: py/obj.c +msgid "%q index out of range" +msgstr "" + +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c +#, fuzzy +msgid "%q must be >= 1" +msgstr "buffers harus mempunyai panjang yang sama" + +#: shared-bindings/fontio/BuiltinFont.c +msgid "%q should be an int" +msgstr "" + +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" +msgstr "%q() mengambil posisi argumen %d tapi %d yang diberikan" + +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "'%q' argumen dibutuhkan" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" +msgstr "" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" +msgstr "'%s' mengharapkan sebuah register" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects a special register" +msgstr "'%s' mengharapkan sebuah register spesial" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an FPU register" +msgstr "'%s' mengharapkan sebuah FPU register" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "'%s' mengharapkan sebuah alamat dengan bentuk [a, b]" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" +msgstr "'%s' mengharapkan integer" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects at most r%d" +msgstr "'%s' mengharapkan setidaknya r%d" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "'%s' mengharapkan {r0, r1, ...}" + +#: py/emitinlinextensa.c +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "'%s' integer 0x%x tidak cukup didalam mask 0x%x" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item assignment" +msgstr "" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item deletion" +msgstr "" + +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not an iterator" +msgstr "" + +#: py/objtype.c py/runtime.c +#, c-format +msgid "'%s' object is not callable" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not iterable" +msgstr "" + +#: py/obj.c +#, c-format +msgid "'%s' object is not subscriptable" +msgstr "" + +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" +msgstr "" + +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" +msgstr "" + +#: py/compile.c +msgid "'align' requires 1 argument" +msgstr "'align' membutuhkan 1 argumen" + +#: py/compile.c +msgid "'await' outside function" +msgstr "'await' diluar fungsi" + +#: py/compile.c +msgid "'break' outside loop" +msgstr "'break' diluar loop" + +#: py/compile.c +msgid "'continue' outside loop" +msgstr "'continue' diluar loop" + +#: py/compile.c +msgid "'data' requires at least 2 arguments" +msgstr "'data' membutuhkan setidaknya 2 argumen" + +#: py/compile.c +msgid "'data' requires integer arguments" +msgstr "'data' membutuhkan argumen integer" + +#: py/compile.c +msgid "'label' requires 1 argument" +msgstr "'label' membutuhkan 1 argumen" + +#: py/compile.c +msgid "'return' outside function" +msgstr "'return' diluar fungsi" + +#: py/compile.c +msgid "'yield' outside function" +msgstr "'yield' diluar fungsi" + +#: py/compile.c +msgid "*x must be assignment target" +msgstr "*x harus menjadi target assignment" + +#: py/obj.c +msgid ", in %q\n" +msgstr "" + +#: py/objcomplex.c +msgid "0.0 to a complex power" +msgstr "" + +#: py/modbuiltins.c +msgid "3-arg pow() not supported" +msgstr "" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "A hardware interrupt channel is already in use" +msgstr "Sebuah channel hardware interrupt sedang digunakan" + +#: shared-bindings/_bleio/Address.c +#, fuzzy, c-format +msgid "Address must be %d bytes long" +msgstr "buffers harus mempunyai panjang yang sama" + +#: shared-bindings/_bleio/Address.c +msgid "Address type out of range" +msgstr "" + +#: ports/nrf/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" +msgstr "Semua perangkat I2C sedang digunakan" + +#: ports/nrf/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" +msgstr "Semua perangkat SPI sedang digunakan" + +#: ports/nrf/common-hal/busio/UART.c +#, fuzzy +msgid "All UART peripherals are in use" +msgstr "Semua perangkat I2C sedang digunakan" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "Semua channel event sedang digunakan" + +#: ports/atmel-samd/audio_dma.c ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "All sync event channels in use" +msgstr "Semua channel event yang disinkronisasi sedang digunakan" + +#: shared-bindings/pulseio/PWMOut.c +msgid "All timers for this pin are in use" +msgstr "Semua timer untuk pin ini sedang digunakan" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: shared-module/_pew/PewPew.c +msgid "All timers in use" +msgstr "Semua timer sedang digunakan" + +#: ports/nrf/common-hal/analogio/AnalogOut.c +msgid "AnalogOut functionality not supported" +msgstr "fungsionalitas AnalogOut tidak didukung" + +#: shared-bindings/analogio/AnalogOut.c +msgid "AnalogOut is only 16 bits. Value must be less than 65536." +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "AnalogOut not supported on given pin" +msgstr "pin yang dipakai tidak mendukung AnalogOut" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" +msgstr "Send yang lain sudah aktif" + +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "Attempted heap allocation when MicroPython VM not running.\n" +msgstr "" + +#: main.c +msgid "Auto-reload is off.\n" +msgstr "Auto-reload tidak aktif.\n" + +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "" +"Auto-reload aktif. Silahkan simpan data-data (files) melalui USB untuk " +"menjalankannya atau masuk ke REPL untukmenonaktifkan.\n" + +#: shared-module/displayio/Display.c +msgid "Below minimum frame rate" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Bit clock and word select must share a clock unit" +msgstr "Bit clock dan word harus memiliki kesamaan pada clock unit" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Bit depth must be multiple of 8." +msgstr "" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "Both pins must support hardware interrupts" +msgstr "Kedua pin harus mendukung hardware interrut" + +#: shared-bindings/displayio/Display.c +msgid "Brightness must be 0-1.0" +msgstr "" + +#: shared-bindings/supervisor/__init__.c +msgid "Brightness must be between 0 and 255" +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Brightness not adjustable" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Buffer is not a bytearray." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Buffer is too small" +msgstr "" + +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Buffer length %d too big. It must be less than %d" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c +msgid "Buffer must be at least length 1" +msgstr "" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +#, fuzzy, c-format +msgid "Bus pin %d is already in use" +msgstr "DAC sudah digunakan" + +#: shared-bindings/_bleio/UUID.c +#, fuzzy +msgid "Byte buffer must be 16 bytes." +msgstr "buffers harus mempunyai panjang yang sama" + +#: shared-bindings/nvm/ByteArray.c +msgid "Bytes must be between 0 and 255." +msgstr "" + +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Can not use dotstar with %s" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" +msgstr "" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/nrf/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "Tidak bisa mendapatkan pull pada saat mode output" + +#: ports/nrf/common-hal/microcontroller/Processor.c +#, fuzzy +msgid "Cannot get temperature" +msgstr "Tidak bisa mendapatkan temperatur. status: 0x%02x" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Cannot output both channels on the same pin" +msgstr "" +"Tidak dapat menggunakan output di kedua channel dengan menggunakan pin yang " +"sama" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot read without MISO pin." +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Cannot record to a file" +msgstr "" + +#: shared-module/storage/__init__.c +msgid "Cannot remount '/' when USB is active." +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +msgid "Cannot reset into bootloader because no bootloader is present." +msgstr "" +"Tidak dapat melakukan reset ke bootloader karena tidak ada bootloader yang " +"terisi" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Cannot set value when direction is input." +msgstr "" + +#: py/objslice.c +msgid "Cannot subclass slice" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot transfer without MOSI and MISO pins." +msgstr "" + +#: extmod/moductypes.c +msgid "Cannot unambiguously get sizeof scalar" +msgstr "tidak dapat mendapatkan ukuran scalar secara tidak ambigu" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot write without MOSI pin." +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Clock pin init failed." +msgstr "" + +#: shared-module/bitbangio/I2C.c +msgid "Clock stretch too long" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" +msgstr "Clock unit sedang digunakan" + +#: shared-bindings/_pew/PewPew.c +msgid "Column entry must be digitalio.DigitalInOut" +msgstr "" + +#: shared-bindings/displayio/I2CDisplay.c +msgid "Command must be 0-255" +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +msgid "Command must be an int between 0 and 255" +msgstr "" + +#: py/persistentcode.c +msgid "Corrupt .mpy file" +msgstr "" + +#: py/emitglue.c +msgid "Corrupt raw code" +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "Could not initialize UART" +msgstr "Tidak dapat menginisialisasi UART" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate first buffer" +msgstr "" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate second buffer" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "Crash into the HardFault_Handler.\n" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "DAC already in use" +msgstr "DAC sudah digunakan" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +msgid "Data 0 pin must be byte aligned" +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Data chunk must follow fmt chunk" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy +msgid "Data too large for advertisement packet" +msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Destination capacity is smaller than destination_length." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Display must have a 16 bit colorspace." +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Display rotation must be in 90 degree increments" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Drive mode not used when direction is input." +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "EXTINT channel already in use" +msgstr "Channel EXTINT sedang digunakan" + +#: extmod/modure.c +msgid "Error in regex" +msgstr "Error pada regex" + +#: shared-bindings/microcontroller/Pin.c +#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c +#: shared-bindings/terminalio/Terminal.c +msgid "Expected a %q" +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c +msgid "Expected a Characteristic" +msgstr "" + +#: shared-bindings/_bleio/Service.c +msgid "Expected a Peripheral" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Expected a Service" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c +#: shared-bindings/_bleio/Service.c +msgid "Expected a UUID" +msgstr "" + +#: shared-bindings/_bleio/Central.c +msgid "Expected an Address" +msgstr "" + +#: shared-module/_pixelbuf/PixelBuf.c +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "" + +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + +#: ports/nrf/sd_mutex.c +#, fuzzy, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Service.c +#, fuzzy, c-format +msgid "Failed to add characteristic, err 0x%04x" +msgstr "Gagal untuk menambahkan karakteristik, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to add descriptor, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy, c-format +msgid "Failed to add service, err 0x%04x" +msgstr "Gagal untuk menambahkan layanan, status: 0x%08lX" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "Failed to allocate RX buffer" +msgstr "Gagal untuk mengalokasikan buffer RX" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +#, c-format +msgid "Failed to allocate RX buffer of %d bytes" +msgstr "Gagal untuk megalokasikan buffer RX dari %d byte" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, fuzzy +msgid "Failed to change softdevice state" +msgstr "Gagal untuk merubah status softdevice, error: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to configure advertising, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Central.c +msgid "Failed to connect: timeout" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, fuzzy, c-format +msgid "Failed to continue scanning, err 0x%04x" +msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy +msgid "Failed to discover services" +msgstr "Gagal untuk menemukan layanan, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, fuzzy +msgid "Failed to get local address" +msgstr "Gagal untuk mendapatkan alamat lokal, error: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, fuzzy +msgid "Failed to get softdevice state" +msgstr "Gagal untuk mendapatkan status softdevice, error: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to notify or indicate attribute value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, fuzzy, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "Gagal untuk membaca nilai atribut, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "Failed to read attribute value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy, c-format +msgid "Failed to read gatts value, err 0x%04x" +msgstr "Gagal untuk menulis nilai gatts, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, fuzzy, c-format +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" +msgstr "Gagal untuk menambahkan Vendor Spesific UUID, status: 0x%08lX" + +#: ports/nrf/sd_mutex.c +#, fuzzy, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "Gagal untuk melepaskan mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to set device name, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "Gagal untuk memulai advertisement, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Central.c +#, c-format +msgid "Failed to start connecting, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, fuzzy, c-format +msgid "Failed to start scanning, err 0x%04x" +msgstr "Gagal untuk melakukan scanning, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to write CCCD, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy, c-format +msgid "Failed to write attribute value, err 0x%04x" +msgstr "Gagal untuk menulis nilai atribut, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy, c-format +msgid "Failed to write gatts value, err 0x%04x" +msgstr "Gagal untuk menulis nilai gatts, status: 0x%08lX" + +#: py/moduerrno.c +msgid "File exists" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash erase failed" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash erase failed to start, err 0x%04x" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash write failed" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash write failed to start, err 0x%04x" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Frequency captured is above capability. Capture Paused." +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c +msgid "Function requires lock" +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Group already used" +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Group full" +msgstr "" + +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" +msgstr "operasi I/O pada file tertutup" + +#: extmod/machine_i2c.c +msgid "I2C operation not supported" +msgstr "operasi I2C tidak didukung" + +#: py/persistentcode.c +msgid "" +"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" +"mpy-update for more info." +msgstr "" + +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" +msgstr "" + +#: py/moduerrno.c +msgid "Input/output error" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Invalid %q pin" +msgstr "%q pada tidak valid" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Invalid BMP file" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c +#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c +msgid "Invalid PWM frequency" +msgstr "Frekuensi PWM tidak valid" + +#: py/moduerrno.c +msgid "Invalid argument" +msgstr "" + +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +msgid "Invalid buffer size" +msgstr "Ukuran buffer tidak valid" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Invalid capture period. Valid range: 1 - 500" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid channel count" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Invalid direction." +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid file" +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid number of bits" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid phase" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +#: shared-bindings/pulseio/PWMOut.c +msgid "Invalid pin" +msgstr "Pin tidak valid" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for left channel" +msgstr "Pin untuk channel kiri tidak valid" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for right channel" +msgstr "Pin untuk channel kanan tidak valid" + +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/atmel-samd/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c +#: ports/nrf/common-hal/busio/I2C.c +msgid "Invalid pins" +msgstr "Pin-pin tidak valid" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid polarity" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + +#: shared-bindings/microcontroller/__init__.c +msgid "Invalid run mode." +msgstr "" + +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid voice count" +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid wave file" +msgstr "" + +#: py/compile.c +msgid "LHS of keyword arg must be an id" +msgstr "LHS dari keyword arg harus menjadi sebuah id" + +#: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass." +msgstr "" + +#: py/objslice.c +msgid "Length must be an int" +msgstr "" + +#: py/objslice.c +msgid "Length must be non-negative" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Looks like our core CircuitPython code crashed hard. Whoops!\n" +"Please file an issue at https://github.com/adafruit/circuitpython/issues\n" +" with the contents of your CIRCUITPY drive and this message:\n" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "MISO pin init failed." +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "MOSI pin init failed." +msgstr "" + +#: shared-module/displayio/Shape.c +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython NLR jump failed. Likely memory corruption.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython fatal error.\n" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Microphone startup delay must be in range 0.0 to 1.0" +msgstr "" + +#: shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "No DAC on chip" +msgstr "Tidak ada DAC (Digital Analog Converter) di dalam chip" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "No DMA channel found" +msgstr "tidak ada channel DMA ditemukan" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No RX pin" +msgstr "Tidak pin RX" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No TX pin" +msgstr "Tidak ada pin TX" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "No available clocks" +msgstr "" + +#: shared-bindings/board/__init__.c +msgid "No default %q bus" +msgstr "Tidak ada standar bus %q" + +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" +msgstr "Tidak ada GCLK yang kosong" + +#: shared-bindings/os/__init__.c +msgid "No hardware random available" +msgstr "" + +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "No hardware support on pin" +msgstr "Tidak ada dukungan hardware untuk pin" + +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" +msgstr "" + +#: py/moduerrno.c +msgid "No space left on device" +msgstr "" + +#: py/moduerrno.c +msgid "No such file/directory" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Peripheral.c +#, fuzzy +msgid "Not connected" +msgstr "Tidak dapat menyambungkan ke AP" + +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c +msgid "Not playing" +msgstr "" + +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +msgid "Odd parity is not supported" +msgstr "Parity ganjil tidak didukung" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Only 8 or 16 bit mono with " +msgstr "Hanya 8 atau 16 bit mono dengan " + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Only slices with step=1 (aka None) are supported" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Oversample must be multiple of 8." +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM frequency not writable when variable_frequency is False on construction." +msgstr "" + +#: py/moduerrno.c +msgid "Permission denied" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogIn.c +#: ports/nrf/common-hal/analogio/AnalogIn.c +msgid "Pin does not have ADC capabilities" +msgstr "Pin tidak mempunya kemampuan untuk ADC (Analog Digital Converter)" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Pixel beyond bounds of buffer" +msgstr "" + +#: py/builtinhelp.c +msgid "Plus any modules on the filesystem\n" +msgstr "Tambahkan module apapun pada filesystem\n" + +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload." +msgstr "" +"Tekan tombol apa saja untuk masuk ke dalam REPL. Gunakan CTRL+D untuk reset " +"(Reload)" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Pull not used when direction is output." +msgstr "" + +#: ports/nrf/common-hal/rtc/RTC.c +msgid "RTC calibration is not supported on this board" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Range out of bounds" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c +msgid "Read-only" +msgstr "" + +#: extmod/vfs_fat.c py/moduerrno.c +msgid "Read-only filesystem" +msgstr "sistem file (filesystem) bersifat Read-only" + +#: shared-module/displayio/Bitmap.c +#, fuzzy +msgid "Read-only object" +msgstr "sistem file (filesystem) bersifat Read-only" + +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Refresh too soon" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" +msgstr "Channel Kanan tidak didukung" + +#: shared-bindings/_pew/PewPew.c +msgid "Row entry must be digitalio.DigitalInOut" +msgstr "" + +#: main.c +msgid "Running in safe mode! Auto-reload is off.\n" +msgstr "Berjalan di mode aman(safe mode)! Auto-reload tidak aktif.\n" + +#: main.c +msgid "Running in safe mode! Not running saved code.\n" +msgstr "" +"Berjalan di mode aman(safe mode)! tidak menjalankan kode yang tersimpan.\n" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "SDA or SCL needs a pull up" +msgstr "SDA atau SCL membutuhkan pull up" + +#: shared-bindings/audiocore/Mixer.c +msgid "Sample rate must be positive" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Sample rate too high. It must be less than %d" +msgstr "Nilai sampel terlalu tinggi. Nilai harus kurang dari %d" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" +msgstr "Serializer sedang digunakan" + +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/pulseio/PulseIn.c +msgid "Slices not supported" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, fuzzy, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "Dukungan soft device, id: 0x%08lX, pc: 0x%08l" + +#: extmod/modure.c +msgid "Splitting with sub-captures" +msgstr "Memisahkan dengan menggunakan sub-captures" + +#: shared-bindings/supervisor/__init__.c +msgid "Stack size must be at least 256" +msgstr "" + +#: shared-bindings/multiterminal/__init__.c +msgid "Stream missing readinto() or write() method." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The CircuitPython heap was corrupted because the stack was too small.\n" +"Please increase stack size limits and press reset (after ejecting " +"CIRCUITPY).\n" +"If you didn't change the stack, then file an issue here with the contents of " +"your CIRCUITPY drive:\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The `microcontroller` module was used to boot into safe mode. Press reset to " +"exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +#, fuzzy +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" +"Tegangan dari mikrokontroler turun atau mati. Pastikan sumber tegangan " +"memberikan daya\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"The reset button was pressed while booting CircuitPython. Press again to " +"exit safe mode.\n" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's signedness does not match the mixer's" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile value out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "Untuk keluar, silahkan reset board tanpa " + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample." +msgstr "Terlalu banyak channel dalam sampel" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "Too many display busses" +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Too many displays" +msgstr "" + +#: py/obj.c +msgid "Traceback (most recent call last):\n" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "Tuple or struct_time argument required" +msgstr "" + +#: shared-module/usb_hid/Device.c +msgid "USB Busy" +msgstr "" + +#: shared-module/usb_hid/Device.c +msgid "USB Error" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID integer value must be 0-0xffff" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Unable to allocate buffers for signed conversion" +msgstr "Tidak dapat mengalokasikan buffer untuk signed conversion" + +#: shared-module/displayio/I2CDisplay.c +#, c-format +msgid "Unable to find I2C Display at %x" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Unable to find free GCLK" +msgstr "Tidak dapat menemukan GCLK yang kosong" + +#: py/parse.c +msgid "Unable to init parser" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +msgid "Unexpected nrfx uuid type" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "Unsupported baudrate" +msgstr "Baudrate tidak didukung" + +#: shared-module/displayio/display_core.c +#, fuzzy +msgid "Unsupported display bus type" +msgstr "Baudrate tidak didukung" + +#: shared-module/audiocore/WaveFile.c +msgid "Unsupported format" +msgstr "" + +#: py/moduerrno.c +msgid "Unsupported operation" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Unsupported pull value." +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + +#: py/emitnative.c +msgid "Viper functions don't currently support more than 4 arguments" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "Voice index too high" +msgstr "" + +#: main.c +msgid "WARNING: Your code filename has two extensions\n" +msgstr "PERINGATAN: Nama file kode anda mempunyai dua ekstensi\n" + +#: py/builtinhelp.c +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" +"Selamat datang ke Adafruit CircuitPython %s!\n" +"\n" +"Silahkan kunjungi learn.adafruit.com/category/circuitpython untuk panduan " +"project.\n" +"\n" +"Untuk menampilkan modul built-in silahkan ketik `help(\"modules\")`.\n" + +#: supervisor/shared/safe_mode.c +#, fuzzy +msgid "" +"You are running in safe mode which means something unanticipated happened.\n" +msgstr "" +"Anda sedang menjalankan mode aman (safe mode) yang berarti sesuatu yang " +"sangat buruk telah terjadi.\n" + +#: supervisor/shared/safe_mode.c +msgid "You requested starting safe mode by " +msgstr "Anda mengajukan untuk memulai mode aman pada (safe mode) pada " + +#: py/objtype.c +msgid "__init__() should return None" +msgstr "" + +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "" + +#: py/objobject.c +msgid "__new__ arg must be a user-type" +msgstr "" + +#: extmod/modubinascii.c extmod/moduhashlib.c +msgid "a bytes-like object is required" +msgstr "sebuah objek menyerupai byte (bytes-like) dibutuhkan" + +#: lib/embed/abort_.c +msgid "abort() called" +msgstr "abort() dipanggil" + +#: extmod/machine_mem.c +#, c-format +msgid "address %08x is not aligned to %d bytes" +msgstr "alamat %08x tidak selaras dengan %d bytes" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "address out of bounds" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "addresses is empty" +msgstr "" + +#: py/modbuiltins.c +msgid "arg is an empty sequence" +msgstr "" + +#: py/runtime.c +msgid "argument has wrong type" +msgstr "" + +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +msgid "argument num/types mismatch" +msgstr "argumen num/types tidak cocok" + +#: py/runtime.c +msgid "argument should be a '%q' not a '%q'" +msgstr "" + +#: py/objarray.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" +msgstr "" + +#: py/objstr.c +msgid "attributes not supported yet" +msgstr "" + +#: py/builtinevex.c +msgid "bad compile mode" +msgstr "mode compile buruk" + +#: py/objstr.c +msgid "bad conversion specifier" +msgstr "" + +#: py/objstr.c +msgid "bad format string" +msgstr "" + +#: py/binary.c +msgid "bad typecode" +msgstr "typecode buruk" + +#: py/emitnative.c +msgid "binary op %q not implemented" +msgstr "" + +#: shared-bindings/busio/UART.c +msgid "bits must be 7, 8 or 9" +msgstr "" + +#: extmod/machine_spi.c +msgid "bits must be 8" +msgstr "bits harus memilki nilai 8" + +#: shared-bindings/audiocore/Mixer.c +msgid "bits_per_sample must be 8 or 16" +msgstr "" + +#: py/emitinlinethumb.c +msgid "branch not in range" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "" + +#: shared-bindings/audiocore/RawSample.c +msgid "buffer must be a bytes-like object" +msgstr "" + +#: shared-module/struct/__init__.c +#, fuzzy +msgid "buffer size must match format" +msgstr "buffers harus mempunyai panjang yang sama" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" +msgstr "" + +#: py/modstruct.c shared-bindings/struct/__init__.c +#: shared-module/struct/__init__.c +msgid "buffer too small" +msgstr "" + +#: extmod/machine_spi.c +msgid "buffers must be the same length" +msgstr "buffers harus mempunyai panjang yang sama" + +#: shared-bindings/_pew/PewPew.c +msgid "buttons must be digitalio.DigitalInOut" +msgstr "" + +#: py/vm.c +msgid "byte code not implemented" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "bytes > 8 bits not supported" +msgstr "byte > 8 bit tidak didukung" + +#: py/objstr.c +msgid "bytes value out of range" +msgstr "" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" +msgstr "kalibrasi keluar dari jangkauan" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" +msgstr "kalibrasi adalah read only" + +#: ports/atmel-samd/common-hal/rtc/RTC.c +msgid "calibration value out of range +/-127" +msgstr "nilai kalibrasi keluar dari jangkauan +/-127" + +#: py/emitinlinethumb.c +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "hanya mampu memiliki hingga 4 parameter untuk Thumb assembly" + +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "" + +#: py/persistentcode.c +msgid "can only save bytecode" +msgstr "" + +#: py/objtype.c +msgid "can't add special method to already-subclassed class" +msgstr "" + +#: py/compile.c +msgid "can't assign to expression" +msgstr "tidak dapat menetapkan ke ekspresi" + +#: py/obj.c +#, c-format +msgid "can't convert %s to complex" +msgstr "" + +#: py/obj.c +#, c-format +msgid "can't convert %s to float" +msgstr "" + +#: py/obj.c +#, c-format +msgid "can't convert %s to int" +msgstr "" + +#: py/objstr.c +msgid "can't convert '%q' object to %q implicitly" +msgstr "" + +#: py/objint.c +msgid "can't convert NaN to int" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "can't convert address to int" +msgstr "" + +#: py/objint.c +msgid "can't convert inf to int" +msgstr "" + +#: py/obj.c +msgid "can't convert to complex" +msgstr "" + +#: py/obj.c +msgid "can't convert to float" +msgstr "" + +#: py/obj.c +msgid "can't convert to int" +msgstr "" + +#: py/objstr.c +msgid "can't convert to str implicitly" +msgstr "" + +#: py/compile.c +msgid "can't declare nonlocal in outer code" +msgstr "tidak dapat mendeklarasikan nonlocal diluar jangkauan kode" + +#: py/compile.c +msgid "can't delete expression" +msgstr "tidak bisa menghapus ekspresi" + +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" +msgstr "" + +#: py/objcomplex.c +msgid "can't do truncated division of a complex number" +msgstr "" + +#: py/compile.c +msgid "can't have multiple **x" +msgstr "tidak bisa memiliki **x ganda" + +#: py/compile.c +msgid "can't have multiple *x" +msgstr "tidak bisa memiliki *x ganda" + +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "" + +#: py/emitnative.c +msgid "can't load from '%q'" +msgstr "" + +#: py/emitnative.c +msgid "can't load with '%q' index" +msgstr "" + +#: py/objgenerator.c +msgid "can't pend throw to just-started generator" +msgstr "" + +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" +msgstr "" + +#: py/objnamedtuple.c +msgid "can't set attribute" +msgstr "" + +#: py/emitnative.c +msgid "can't store '%q'" +msgstr "" + +#: py/emitnative.c +msgid "can't store to '%q'" +msgstr "" + +#: py/emitnative.c +msgid "can't store with '%q' index" +msgstr "" + +#: py/objstr.c +msgid "" +"can't switch from automatic field numbering to manual field specification" +msgstr "" + +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "" + +#: py/objtype.c +msgid "cannot create '%q' instances" +msgstr "" + +#: py/objtype.c +msgid "cannot create instance" +msgstr "" + +#: py/runtime.c +msgid "cannot import name %q" +msgstr "" + +#: py/builtinimport.c +msgid "cannot perform relative import" +msgstr "tidak dapat melakukan relative import" + +#: py/emitnative.c +msgid "casting" +msgstr "" + +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" +msgstr "" + +#: py/modbuiltins.c +msgid "chr() arg not in range(0x110000)" +msgstr "" + +#: py/modbuiltins.c +msgid "chr() arg not in range(256)" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer or int" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" +msgstr "" + +#: shared-bindings/displayio/ColorConverter.c +msgid "color should be an int" +msgstr "" + +#: py/objcomplex.c +msgid "complex division by zero" +msgstr "" + +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" +msgstr "" + +#: extmod/moduzlib.c +msgid "compression header" +msgstr "kompresi header" + +#: py/parse.c +msgid "constant must be an integer" +msgstr "" + +#: py/emitnative.c +msgid "conversion to object" +msgstr "" + +#: py/parsenum.c +msgid "decimal numbers not supported" +msgstr "" + +#: py/compile.c +msgid "default 'except' must be last" +msgstr "'except' standar harus terakhir" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination_length must be an int >= 0" +msgstr "" + +#: py/objdict.c +msgid "dict update sequence has wrong length" +msgstr "" + +#: py/modmath.c py/objfloat.c py/objint_longlong.c py/objint_mpz.c py/runtime.c +#: shared-bindings/math/__init__.c +msgid "division by zero" +msgstr "" + +#: py/objdeque.c +msgid "empty" +msgstr "" + +#: extmod/moduheapq.c extmod/modutimeq.c +msgid "empty heap" +msgstr "heap kosong" + +#: py/objstr.c +msgid "empty separator" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "empty sequence" +msgstr "" + +#: py/objstr.c +msgid "end of format while looking for conversion specifier" +msgstr "" + +#: shared-bindings/displayio/Shape.c +msgid "end_x should be an int" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +#, c-format +msgid "error = 0x%08lX" +msgstr "error = 0x%08lX" + +#: py/runtime.c +msgid "exceptions must derive from BaseException" +msgstr "" + +#: py/objstr.c +msgid "expected ':' after format specifier" +msgstr "" + +#: py/obj.c +msgid "expected tuple/list" +msgstr "" + +#: py/modthread.c +msgid "expecting a dict for keyword args" +msgstr "" + +#: py/compile.c +msgid "expecting an assembler instruction" +msgstr "sebuah instruksi assembler diharapkan" + +#: py/compile.c +msgid "expecting just a value for set" +msgstr "hanya mengharapkan sebuah nilai (value) untuk set" + +#: py/compile.c +msgid "expecting key:value for dict" +msgstr "key:value diharapkan untuk dict" + +#: py/argcheck.c +msgid "extra keyword arguments given" +msgstr "argumen keyword ekstra telah diberikan" + +#: py/argcheck.c +msgid "extra positional arguments given" +msgstr "argumen posisi ekstra telah diberikan" + +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c +msgid "file must be a file opened in byte mode" +msgstr "" + +#: shared-bindings/storage/__init__.c +msgid "filesystem must provide mount method" +msgstr "" + +#: py/objtype.c +msgid "first argument to super() must be type" +msgstr "" + +#: extmod/machine_spi.c +msgid "firstbit must be MSB" +msgstr "bit pertama(firstbit) harus berupa MSB" + +#: py/objint.c +msgid "float too big" +msgstr "" + +#: shared-bindings/_stage/Text.c +msgid "font must be 2048 bytes long" +msgstr "" + +#: py/objstr.c +msgid "format requires a dict" +msgstr "" + +#: py/objdeque.c +msgid "full" +msgstr "" + +#: py/argcheck.c +msgid "function does not take keyword arguments" +msgstr "fungsi tidak dapat mengambil argumen keyword" + +#: py/argcheck.c +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "fungsi diharapkan setidaknya %d argumen, hanya mendapatkan %d" + +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" +msgstr "fungsi mendapatkan nilai ganda untuk argumen '%q'" + +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" +msgstr "fungsi kehilangan %d argumen posisi yang dibutuhkan" + +#: py/bc.c +msgid "function missing keyword-only argument" +msgstr "fungsi kehilangan argumen keyword-only" + +#: py/bc.c +msgid "function missing required keyword argument '%q'" +msgstr "fungsi kehilangan argumen keyword '%q' yang dibutuhkan" + +#: py/bc.c +#, c-format +msgid "function missing required positional argument #%d" +msgstr "fungsi kehilangan argumen posisi #%d yang dibutuhkan" + +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "fungsi mengambil posisi argumen %d tapi %d yang diberikan" + +#: shared-bindings/time/__init__.c +msgid "function takes exactly 9 arguments" +msgstr "" + +#: py/objgenerator.c +msgid "generator already executing" +msgstr "" + +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" +msgstr "" + +#: shared-bindings/_stage/Layer.c +msgid "graphic must be 2048 bytes long" +msgstr "" + +#: extmod/moduheapq.c +msgid "heap must be a list" +msgstr "heap harus berupa sebuah list" + +#: py/compile.c +msgid "identifier redefined as global" +msgstr "identifier didefinisi ulang sebagai global" + +#: py/compile.c +msgid "identifier redefined as nonlocal" +msgstr "identifier didefinisi ulang sebagai nonlocal" + +#: py/objstr.c +msgid "incomplete format" +msgstr "" + +#: py/objstr.c +msgid "incomplete format key" +msgstr "" + +#: extmod/modubinascii.c +msgid "incorrect padding" +msgstr "lapisan (padding) tidak benar" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c py/obj.c +msgid "index out of range" +msgstr "index keluar dari jangkauan" + +#: py/obj.c +msgid "indices must be integers" +msgstr "" + +#: py/compile.c +msgid "inline assembler must be a function" +msgstr "inline assembler harus sebuah fungsi" + +#: py/parsenum.c +msgid "int() arg 2 must be >= 2 and <= 36" +msgstr "" + +#: py/objstr.c +msgid "integer required" +msgstr "" + +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c +#, c-format +msgid "interval must be in range %s-%s" +msgstr "" + +#: extmod/machine_i2c.c +msgid "invalid I2C peripheral" +msgstr "perangkat I2C tidak valid" + +#: extmod/machine_spi.c +msgid "invalid SPI peripheral" +msgstr "perangkat SPI tidak valid" + +#: lib/netutils/netutils.c +msgid "invalid arguments" +msgstr "argumen-argumen tidak valid" + +#: extmod/modussl_axtls.c +msgid "invalid cert" +msgstr "cert tidak valid" + +#: extmod/uos_dupterm.c +msgid "invalid dupterm index" +msgstr "indeks dupterm tidak valid" + +#: extmod/modframebuf.c +msgid "invalid format" +msgstr "format tidak valid" + +#: py/objstr.c +msgid "invalid format specifier" +msgstr "" + +#: extmod/modussl_axtls.c +msgid "invalid key" +msgstr "key tidak valid" + +#: py/compile.c +msgid "invalid micropython decorator" +msgstr "micropython decorator tidak valid" + +#: shared-bindings/random/__init__.c +msgid "invalid step" +msgstr "" + +#: py/compile.c py/parse.c +msgid "invalid syntax" +msgstr "syntax tidak valid" + +#: py/parsenum.c +msgid "invalid syntax for integer" +msgstr "" + +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "" + +#: py/parsenum.c +msgid "invalid syntax for number" +msgstr "" + +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" +msgstr "" + +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "" + +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "" + +#: py/argcheck.c +msgid "keyword argument(s) not yet implemented - use normal args instead" +msgstr "argumen keyword belum diimplementasi - gunakan args normal" + +#: py/bc.c +msgid "keywords must be strings" +msgstr "keyword harus berupa string" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" +msgstr "" + +#: py/compile.c +msgid "label redefined" +msgstr "label didefinis ulang" + +#: py/stream.c +msgid "length argument not allowed for this type" +msgstr "" + +#: py/objarray.c +msgid "lhs and rhs should be compatible" +msgstr "" + +#: py/emitnative.c +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "" + +#: py/emitnative.c +msgid "local '%q' used before type known" +msgstr "" + +#: py/vm.c +msgid "local variable referenced before assignment" +msgstr "" + +#: py/objint.c +msgid "long int not supported in this build" +msgstr "" + +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" +msgstr "" + +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + +#: py/runtime.c +msgid "maximum recursion depth exceeded" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "" + +#: py/runtime.c +msgid "memory allocation failed, heap is locked" +msgstr "" + +#: py/builtinimport.c +msgid "module not found" +msgstr "modul tidak ditemukan" + +#: py/compile.c +msgid "multiple *x in assignment" +msgstr "perkalian *x dalam assignment" + +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" +msgstr "" + +#: py/objtype.c +msgid "multiple inheritance not supported" +msgstr "" + +#: py/emitnative.c +msgid "must raise an object" +msgstr "" + +#: extmod/machine_spi.c +msgid "must specify all of sck/mosi/miso" +msgstr "harus menentukan semua pin sck/mosi/miso" + +#: py/modbuiltins.c +msgid "must use keyword argument for key function" +msgstr "" + +#: py/runtime.c +msgid "name '%q' is not defined" +msgstr "" + +#: shared-bindings/_bleio/Peripheral.c +#, fuzzy +msgid "name must be a string" +msgstr "keyword harus berupa string" + +#: py/runtime.c +msgid "name not defined" +msgstr "" + +#: py/compile.c +msgid "name reused for argument" +msgstr "nama digunakan kembali untuk argumen" + +#: py/emitnative.c +msgid "native yield" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "need more than %d values to unpack" +msgstr "" + +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" +msgstr "" + +#: py/objint_mpz.c py/runtime.c +msgid "negative shift count" +msgstr "" + +#: py/vm.c +msgid "no active exception to reraise" +msgstr "" + +#: shared-bindings/socket/__init__.c shared-module/network/__init__.c +msgid "no available NIC" +msgstr "" + +#: py/compile.c +msgid "no binding for nonlocal found" +msgstr "tidak ada ikatan/bind pada temuan nonlocal" + +#: py/builtinimport.c +msgid "no module named '%q'" +msgstr "tidak ada modul yang bernama '%q'" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "no reset pin available" +msgstr "" + +#: py/runtime.c shared-bindings/_pixelbuf/__init__.c +msgid "no such attribute" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" +msgstr "" + +#: py/compile.c +msgid "non-default argument follows default argument" +msgstr "argumen non-default mengikuti argumen standar(default)" + +#: extmod/modubinascii.c +msgid "non-hex digit found" +msgstr "digit non-hex ditemukan" + +#: py/compile.c +msgid "non-keyword arg after */**" +msgstr "non-keyword arg setelah */**" + +#: py/compile.c +msgid "non-keyword arg after keyword arg" +msgstr "non-keyword arg setelah keyword arg" + +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" +msgstr "" + +#: py/objstr.c +msgid "not all arguments converted during string formatting" +msgstr "" + +#: py/objstr.c +msgid "not enough arguments for format string" +msgstr "" + +#: py/obj.c +#, c-format +msgid "object '%s' is not a tuple or list" +msgstr "" + +#: py/obj.c +msgid "object does not support item assignment" +msgstr "" + +#: py/obj.c +msgid "object does not support item deletion" +msgstr "" + +#: py/obj.c +msgid "object has no len" +msgstr "" + +#: py/obj.c +msgid "object is not subscriptable" +msgstr "" + +#: py/runtime.c +msgid "object not an iterator" +msgstr "" + +#: py/objtype.c py/runtime.c +msgid "object not callable" +msgstr "" + +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" +msgstr "" + +#: py/runtime.c +msgid "object not iterable" +msgstr "" + +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" +msgstr "" + +#: py/obj.c +msgid "object with buffer protocol required" +msgstr "" + +#: extmod/modubinascii.c +msgid "odd-length string" +msgstr "panjang data string memiliki keganjilan (odd-length)" + +#: py/objstr.c py/objstrunicode.c +#, fuzzy +msgid "offset out of bounds" +msgstr "modul tidak ditemukan" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" +msgstr "" + +#: py/modbuiltins.c +msgid "ord expects a character" +msgstr "" + +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "" + +#: py/objint_mpz.c +msgid "overflow converting long int to machine word" +msgstr "" + +#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c +msgid "palette must be 32 bytes long" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "palette_index should be an int" +msgstr "" + +#: py/compile.c +msgid "parameter annotation must be an identifier" +msgstr "anotasi parameter haruse sebuah identifier" + +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" +msgstr "" + +#: py/emitinlinethumb.c +msgid "parameters must be registers in sequence r0 to r3" +msgstr "parameter harus menjadi register dalam urutan r0 sampai r3" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel coordinates out of bounds" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel value requires too many bits" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" +msgstr "Muncul dari PulseIn yang kosong" + +#: py/objset.c +msgid "pop from an empty set" +msgstr "" + +#: py/objlist.c +msgid "pop from empty list" +msgstr "" + +#: py/objdict.c +msgid "popitem(): dictionary is empty" +msgstr "" + +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" +msgstr "" + +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" +msgstr "" + +#: extmod/modutimeq.c +msgid "queue overflow" +msgstr "antrian meluap (overflow)" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "rawbuf is not the same size as buf" +msgstr "" + +#: shared-bindings/_pixelbuf/__init__.c +msgid "readonly attribute" +msgstr "" + +#: py/builtinimport.c +msgid "relative import" +msgstr "relative import" + +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" +msgstr "" + +#: py/compile.c +msgid "return annotation must be an identifier" +msgstr "anotasi return harus sebuah identifier" + +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" +msgstr "" + +#: py/objstr.c +msgid "rsplit(None,n)" +msgstr "" + +#: shared-bindings/audiocore/RawSample.c +msgid "" +"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " +"'B'" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" +msgstr "nilai sampling keluar dari jangkauan" + +#: py/modmicropython.c +msgid "schedule stack full" +msgstr "" + +#: lib/utils/pyexec.c py/builtinimport.c +msgid "script compilation not supported" +msgstr "kompilasi script tidak didukung" + +#: py/objstr.c +msgid "sign not allowed in string format specifier" +msgstr "" + +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" +msgstr "" + +#: py/objstr.c +msgid "single '}' encountered in format string" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "sleep length must be non-negative" +msgstr "" + +#: py/objslice.c py/sequence.c +msgid "slice step cannot be zero" +msgstr "" + +#: py/objint.c py/sequence.c +msgid "small int overflow" +msgstr "" + +#: main.c +msgid "soft reboot\n" +msgstr "memulai ulang software(soft reboot)\n" + +#: py/objstr.c +msgid "start/end indices" +msgstr "" + +#: shared-bindings/displayio/Shape.c +msgid "start_x should be an int" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "step must be non-zero" +msgstr "" + +#: shared-bindings/busio/UART.c +msgid "stop must be 1 or 2" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" +msgstr "" + +#: py/stream.c +msgid "stream operation not supported" +msgstr "" + +#: py/objstrunicode.c +msgid "string index out of range" +msgstr "" + +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" +msgstr "" + +#: py/stream.c +msgid "string not supported; use bytes or bytearray" +msgstr "" + +#: extmod/moductypes.c +msgid "struct: cannot index" +msgstr "struct: tidak bisa melakukan index" + +#: extmod/moductypes.c +msgid "struct: index out of range" +msgstr "struct: index keluar dari jangkauan" + +#: extmod/moductypes.c +msgid "struct: no fields" +msgstr "struct: tidak ada fields" + +#: py/objstr.c +msgid "substring not found" +msgstr "" + +#: py/compile.c +msgid "super() can't find self" +msgstr "super() tidak dapat menemukan dirinya sendiri" + +#: extmod/modujson.c +msgid "syntax error in JSON" +msgstr "sintaksis error pada JSON" + +#: extmod/moductypes.c +msgid "syntax error in uctypes descriptor" +msgstr "sintaksis error pada pendeskripsi uctypes" + +#: shared-bindings/touchio/TouchIn.c +msgid "threshold must be in the range 0-65536" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes a 9-sequence" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes exactly 1 argument" +msgstr "" + +#: shared-bindings/busio/UART.c +msgid "timeout >100 (units are now seconds, not msecs)" +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#, fuzzy +msgid "timeout must be >= 0.0" +msgstr "bits harus memilki nilai 8" + +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" +msgstr "" + +#: shared-module/struct/__init__.c +msgid "too many arguments provided with the given format" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "" + +#: py/objstr.c +msgid "tuple index out of range" +msgstr "" + +#: py/obj.c +msgid "tuple/list has wrong length" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "tuple/list required on RHS" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "tx and rx cannot both be None" +msgstr "tx dan rx keduanya tidak boleh kosong" + +#: py/objtype.c +msgid "type '%q' is not an acceptable base type" +msgstr "" + +#: py/objtype.c +msgid "type is not an acceptable base type" +msgstr "" + +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" +msgstr "" + +#: py/objtype.c +msgid "type takes 1 or 3 arguments" +msgstr "" + +#: py/objint_longlong.c +msgid "ulonglong too large" +msgstr "" + +#: py/emitnative.c +msgid "unary op %q not implemented" +msgstr "" + +#: py/parse.c +msgid "unexpected indent" +msgstr "" + +#: py/bc.c +msgid "unexpected keyword argument" +msgstr "argumen keyword tidak diharapkan" + +#: py/bc.c py/objnamedtuple.c +msgid "unexpected keyword argument '%q'" +msgstr "keyword argumen '%q' tidak diharapkan" + +#: py/lexer.c +msgid "unicode name escapes" +msgstr "" + +#: py/parse.c +msgid "unindent does not match any outer indentation level" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown conversion specifier %c" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type '%s'" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'float'" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'str'" +msgstr "" + +#: py/compile.c +msgid "unknown type" +msgstr "tipe tidak diketahui" + +#: py/emitnative.c +msgid "unknown type '%q'" +msgstr "" + +#: py/objstr.c +msgid "unmatched '{' in format" +msgstr "" + +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "unsupported %q type" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "" + +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "" + +#: py/runtime.c +msgid "unsupported type for %q: '%s'" +msgstr "" + +#: py/runtime.c +msgid "unsupported type for operator" +msgstr "" + +#: py/runtime.c +msgid "unsupported types for %q: '%s', '%s'" +msgstr "" + +#: py/objint.c +#, c-format +msgid "value must fit in %d byte(s)" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "value_count must be > 0" +msgstr "" + +#: shared-bindings/_bleio/Scanner.c +msgid "window must be <= interval" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "write_args must be a list, tuple, or None" +msgstr "" + +#: py/objstr.c +msgid "wrong number of arguments" +msgstr "" + +#: py/runtime.c +msgid "wrong number of values to unpack" +msgstr "" + +#: shared-module/displayio/Shape.c +msgid "x value out of bounds" +msgstr "" + +#: shared-bindings/displayio/Shape.c +msgid "y should be an int" +msgstr "" + +#: shared-module/displayio/Shape.c +msgid "y value out of bounds" +msgstr "" + +#: py/objrange.c +msgid "zero step" +msgstr "" + +#~ msgid "AP required" +#~ msgstr "AP dibutuhkan" + +#~ msgid "C-level assert" +#~ msgstr "Dukungan C-level" + +#~ msgid "Cannot connect to AP" +#~ msgstr "Tidak dapat menyambungkan ke AP" + +#~ msgid "Cannot disconnect from AP" +#~ msgstr "Tidak dapat memutuskna dari AP" + +#~ msgid "Cannot set STA config" +#~ msgstr "Tidak dapat mengatur konfigurasi STA" + +#~ msgid "Cannot update i/f status" +#~ msgstr "Tidak dapat memperbarui status i/f" + +#, fuzzy +#~ msgid "Data too large for the advertisement packet" +#~ msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment" + +#~ msgid "Don't know how to pass object to native function" +#~ msgstr "Tidak tahu cara meloloskan objek ke fungsi native" + +#~ msgid "ESP8226 does not support safe mode." +#~ msgstr "ESP8266 tidak mendukung safe mode" + +#~ msgid "ESP8266 does not support pull down." +#~ msgstr "ESP866 tidak mendukung pull down" + +#~ msgid "Error in ffi_prep_cif" +#~ msgstr "Errod pada ffi_prep_cif" + +#, fuzzy +#~ msgid "Failed to acquire mutex" +#~ msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to add service" +#~ msgstr "Gagal untuk menambahkan layanan, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to connect:" +#~ msgstr "Gagal untuk menyambungkan, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to continue scanning" +#~ msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to create mutex" +#~ msgstr "Gagal untuk membuat mutex, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to notify or indicate attribute value, err %0x04x" +#~ msgstr "Gagal untuk melaporkan nilai atribut, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to read attribute value, err %0x04x" +#~ msgstr "Gagal untuk membaca nilai atribut, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to release mutex" +#~ msgstr "Gagal untuk melepaskan mutex, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to start advertising" +#~ msgstr "Gagal untuk memulai advertisement, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to start scanning" +#~ msgstr "Gagal untuk melakukan scanning, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to stop advertising" +#~ msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX" + +#~ msgid "GPIO16 does not support pull up." +#~ msgstr "GPIO16 tidak mendukung pull up" + +#~ msgid "Invalid bit clock pin" +#~ msgstr "Bit clock pada pin tidak valid" + +#~ msgid "Invalid clock pin" +#~ msgstr "Clock pada pin tidak valid" + +#~ msgid "Invalid data pin" +#~ msgstr "data pin tidak valid" + +#~ msgid "Maximum PWM frequency is %dhz." +#~ msgstr "Nilai maksimum frekuensi PWM adalah %dhz" + +#~ msgid "Minimum PWM frequency is 1hz." +#~ msgstr "Nilai minimum frekuensi PWM is 1hz" + +#~ msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." +#~ msgstr "" +#~ "Nilai Frekuensi PWM ganda tidak didukung. PWM sudah diatur pada %dhz" + +#~ msgid "No PulseIn support for %q" +#~ msgstr "Tidak ada dukungan PulseIn untuk %q" + +#~ msgid "No hardware support for analog out." +#~ msgstr "Tidak dukungan hardware untuk analog out." + +#~ msgid "Only tx supported on UART1 (GPIO2)." +#~ msgstr "Hanya tx yang mendukung pada UART1 (GPIO2)." + +#~ msgid "PWM not supported on pin %d" +#~ msgstr "PWM tidak didukung pada pin %d" + +#~ msgid "Pin %q does not have ADC capabilities" +#~ msgstr "Pin %q tidak memiliki kemampuan ADC" + +#~ msgid "Pin(16) doesn't support pull" +#~ msgstr "Pin(16) tidak mendukung pull" + +#~ msgid "Pins not valid for SPI" +#~ msgstr "Pin-pin tidak valid untuk SPI" + +#~ msgid "STA must be active" +#~ msgstr "STA harus aktif" + +#~ msgid "STA required" +#~ msgstr "STA dibutuhkan" + +#~ msgid "UART(%d) does not exist" +#~ msgstr "UART(%d) tidak ada" + +#~ msgid "UART(1) can't read" +#~ msgstr "UART(1) tidak dapat dibaca" + +#~ msgid "Unable to remount filesystem" +#~ msgstr "Tidak dapat memasang filesystem kembali" + +#~ msgid "Unknown type" +#~ msgstr "Tipe tidak diketahui" + +#~ msgid "Use esptool to erase flash and re-upload Python instead" +#~ msgstr "" +#~ "Gunakan esptool untuk menghapus flash dan upload ulang Python sebagai " +#~ "gantinya" + +#~ msgid "[addrinfo error %d]" +#~ msgstr "[addrinfo error %d]" + +#~ msgid "buffer too long" +#~ msgstr "buffer terlalu panjang" + +#~ msgid "can query only one param" +#~ msgstr "hanya bisa melakukan query satu param" + +#~ msgid "can't get AP config" +#~ msgstr "tidak bisa mendapatkan konfigurasi AP" + +#~ msgid "can't get STA config" +#~ msgstr "tidak bisa mendapatkan konfigurasi STA" + +#~ msgid "can't set AP config" +#~ msgstr "tidak bisa mendapatkan konfigurasi AP" + +#~ msgid "can't set STA config" +#~ msgstr "tidak bisa mendapatkan konfigurasi STA" + +#~ msgid "either pos or kw args are allowed" +#~ msgstr "hanya antar pos atau kw args yang diperbolehkan" + +#~ msgid "expecting a pin" +#~ msgstr "mengharapkan sebuah pin" + +#~ msgid "ffi_prep_closure_loc" +#~ msgstr "ffi_prep_closure_loc" + +#~ msgid "flash location must be below 1MByte" +#~ msgstr "alokasi flash harus dibawah 1MByte" + +#~ msgid "frequency can only be either 80Mhz or 160MHz" +#~ msgstr "frekuensi hanya bisa didefinisikan 80Mhz atau 160Mhz" + +#~ msgid "impossible baudrate" +#~ msgstr "baudrate tidak memungkinkan" + +#~ msgid "invalid alarm" +#~ msgstr "alarm tidak valid" + +#~ msgid "invalid buffer length" +#~ msgstr "panjang buffer tidak valid" + +#~ msgid "invalid data bits" +#~ msgstr "bit data tidak valid" + +#~ msgid "invalid pin" +#~ msgstr "pin tidak valid" + +#~ msgid "invalid stop bits" +#~ msgstr "stop bit tidak valid" + +#~ msgid "len must be multiple of 4" +#~ msgstr "len harus kelipatan dari 4" + +#~ msgid "memory allocation failed, allocating %u bytes for native code" +#~ msgstr "alokasi memori gagal, mengalokasikan %u byte untuk kode native" + +#~ msgid "not a valid ADC Channel: %d" +#~ msgstr "tidak valid channel ADC: %d" + +#~ msgid "pin does not have IRQ capabilities" +#~ msgstr "pin tidak memiliki kemampuan IRQ" + +#~ msgid "scan failed" +#~ msgstr "scan gagal" + +#~ msgid "unknown config param" +#~ msgstr "konfigurasi param tidak diketahui" + +#~ msgid "unknown status param" +#~ msgstr "status param tidak diketahui" + +#~ msgid "wifi_set_ip_info() failed" +#~ msgstr "wifi_set_ip_info() gagal" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot new file mode 100644 index 00000000000..272f0814800 --- /dev/null +++ b/locale/circuitpython.pot @@ -0,0 +1,2688 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: main.c +msgid "" +"\n" +"Code done running. Waiting for reload.\n" +msgstr "" + +#: py/obj.c +msgid " File \"%q\"" +msgstr "" + +#: py/obj.c +msgid " File \"%q\", line %d" +msgstr "" + +#: main.c +msgid " output:\n" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "%%c requires int or char" +msgstr "" + +#: shared-bindings/microcontroller/Pin.c +msgid "%q in use" +msgstr "" + +#: py/obj.c +msgid "%q index out of range" +msgstr "" + +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c +msgid "%q must be >= 1" +msgstr "" + +#: shared-bindings/fontio/BuiltinFont.c +msgid "%q should be an int" +msgstr "" + +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" +msgstr "" + +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" +msgstr "" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects a special register" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an FPU register" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects at most r%d" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "" + +#: py/emitinlinextensa.c +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item assignment" +msgstr "" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item deletion" +msgstr "" + +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not an iterator" +msgstr "" + +#: py/objtype.c py/runtime.c +#, c-format +msgid "'%s' object is not callable" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not iterable" +msgstr "" + +#: py/obj.c +#, c-format +msgid "'%s' object is not subscriptable" +msgstr "" + +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" +msgstr "" + +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" +msgstr "" + +#: py/compile.c +msgid "'align' requires 1 argument" +msgstr "" + +#: py/compile.c +msgid "'await' outside function" +msgstr "" + +#: py/compile.c +msgid "'break' outside loop" +msgstr "" + +#: py/compile.c +msgid "'continue' outside loop" +msgstr "" + +#: py/compile.c +msgid "'data' requires at least 2 arguments" +msgstr "" + +#: py/compile.c +msgid "'data' requires integer arguments" +msgstr "" + +#: py/compile.c +msgid "'label' requires 1 argument" +msgstr "" + +#: py/compile.c +msgid "'return' outside function" +msgstr "" + +#: py/compile.c +msgid "'yield' outside function" +msgstr "" + +#: py/compile.c +msgid "*x must be assignment target" +msgstr "" + +#: py/obj.c +msgid ", in %q\n" +msgstr "" + +#: py/objcomplex.c +msgid "0.0 to a complex power" +msgstr "" + +#: py/modbuiltins.c +msgid "3-arg pow() not supported" +msgstr "" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "A hardware interrupt channel is already in use" +msgstr "" + +#: shared-bindings/_bleio/Address.c +#, c-format +msgid "Address must be %d bytes long" +msgstr "" + +#: shared-bindings/_bleio/Address.c +msgid "Address type out of range" +msgstr "" + +#: ports/nrf/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" +msgstr "" + +#: ports/nrf/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +msgid "All UART peripherals are in use" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "" + +#: ports/atmel-samd/audio_dma.c ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "All sync event channels in use" +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c +msgid "All timers for this pin are in use" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: shared-module/_pew/PewPew.c +msgid "All timers in use" +msgstr "" + +#: ports/nrf/common-hal/analogio/AnalogOut.c +msgid "AnalogOut functionality not supported" +msgstr "" + +#: shared-bindings/analogio/AnalogOut.c +msgid "AnalogOut is only 16 bits. Value must be less than 65536." +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "AnalogOut not supported on given pin" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" +msgstr "" + +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "Attempted heap allocation when MicroPython VM not running.\n" +msgstr "" + +#: main.c +msgid "Auto-reload is off.\n" +msgstr "" + +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "" + +#: shared-module/displayio/Display.c +msgid "Below minimum frame rate" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Bit clock and word select must share a clock unit" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Bit depth must be multiple of 8." +msgstr "" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "Both pins must support hardware interrupts" +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Brightness must be 0-1.0" +msgstr "" + +#: shared-bindings/supervisor/__init__.c +msgid "Brightness must be between 0 and 255" +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Brightness not adjustable" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Buffer is not a bytearray." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Buffer is too small" +msgstr "" + +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Buffer length %d too big. It must be less than %d" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c +msgid "Buffer must be at least length 1" +msgstr "" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +#, c-format +msgid "Bus pin %d is already in use" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "Byte buffer must be 16 bytes." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Bytes must be between 0 and 255." +msgstr "" + +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Can not use dotstar with %s" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" +msgstr "" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/nrf/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "" + +#: ports/nrf/common-hal/microcontroller/Processor.c +msgid "Cannot get temperature" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Cannot output both channels on the same pin" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot read without MISO pin." +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Cannot record to a file" +msgstr "" + +#: shared-module/storage/__init__.c +msgid "Cannot remount '/' when USB is active." +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +msgid "Cannot reset into bootloader because no bootloader is present." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Cannot set value when direction is input." +msgstr "" + +#: py/objslice.c +msgid "Cannot subclass slice" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot transfer without MOSI and MISO pins." +msgstr "" + +#: extmod/moductypes.c +msgid "Cannot unambiguously get sizeof scalar" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot write without MOSI pin." +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Clock pin init failed." +msgstr "" + +#: shared-module/bitbangio/I2C.c +msgid "Clock stretch too long" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" +msgstr "" + +#: shared-bindings/_pew/PewPew.c +msgid "Column entry must be digitalio.DigitalInOut" +msgstr "" + +#: shared-bindings/displayio/I2CDisplay.c +msgid "Command must be 0-255" +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +msgid "Command must be an int between 0 and 255" +msgstr "" + +#: py/persistentcode.c +msgid "Corrupt .mpy file" +msgstr "" + +#: py/emitglue.c +msgid "Corrupt raw code" +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "Could not initialize UART" +msgstr "" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate first buffer" +msgstr "" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate second buffer" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "Crash into the HardFault_Handler.\n" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "DAC already in use" +msgstr "" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +msgid "Data 0 pin must be byte aligned" +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Data chunk must follow fmt chunk" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Data too large for advertisement packet" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Destination capacity is smaller than destination_length." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Display must have a 16 bit colorspace." +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Display rotation must be in 90 degree increments" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Drive mode not used when direction is input." +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "EXTINT channel already in use" +msgstr "" + +#: extmod/modure.c +msgid "Error in regex" +msgstr "" + +#: shared-bindings/microcontroller/Pin.c +#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c +#: shared-bindings/terminalio/Terminal.c +msgid "Expected a %q" +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c +msgid "Expected a Characteristic" +msgstr "" + +#: shared-bindings/_bleio/Service.c +msgid "Expected a Peripheral" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Expected a Service" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c +#: shared-bindings/_bleio/Service.c +msgid "Expected a UUID" +msgstr "" + +#: shared-bindings/_bleio/Central.c +msgid "Expected an Address" +msgstr "" + +#: shared-module/_pixelbuf/PixelBuf.c +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "" + +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + +#: ports/nrf/sd_mutex.c +#, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Service.c +#, c-format +msgid "Failed to add characteristic, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to add descriptor, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to add service, err 0x%04x" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "Failed to allocate RX buffer" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +#, c-format +msgid "Failed to allocate RX buffer of %d bytes" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to change softdevice state" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to configure advertising, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Central.c +msgid "Failed to connect: timeout" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, c-format +msgid "Failed to continue scanning, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "Failed to discover services" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to get local address" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to get softdevice state" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to notify or indicate attribute value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "Failed to read attribute value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to read gatts value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" +msgstr "" + +#: ports/nrf/sd_mutex.c +#, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to set device name, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Central.c +#, c-format +msgid "Failed to start connecting, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, c-format +msgid "Failed to start scanning, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to write CCCD, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to write attribute value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to write gatts value, err 0x%04x" +msgstr "" + +#: py/moduerrno.c +msgid "File exists" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash erase failed" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash erase failed to start, err 0x%04x" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash write failed" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash write failed to start, err 0x%04x" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Frequency captured is above capability. Capture Paused." +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c +msgid "Function requires lock" +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Group already used" +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Group full" +msgstr "" + +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" +msgstr "" + +#: extmod/machine_i2c.c +msgid "I2C operation not supported" +msgstr "" + +#: py/persistentcode.c +msgid "" +"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" +"mpy-update for more info." +msgstr "" + +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" +msgstr "" + +#: py/moduerrno.c +msgid "Input/output error" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Invalid %q pin" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Invalid BMP file" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c +#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c +msgid "Invalid PWM frequency" +msgstr "" + +#: py/moduerrno.c +msgid "Invalid argument" +msgstr "" + +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +msgid "Invalid buffer size" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Invalid capture period. Valid range: 1 - 500" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid channel count" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Invalid direction." +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid file" +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid number of bits" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid phase" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +#: shared-bindings/pulseio/PWMOut.c +msgid "Invalid pin" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for left channel" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for right channel" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/atmel-samd/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c +#: ports/nrf/common-hal/busio/I2C.c +msgid "Invalid pins" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid polarity" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + +#: shared-bindings/microcontroller/__init__.c +msgid "Invalid run mode." +msgstr "" + +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid voice count" +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid wave file" +msgstr "" + +#: py/compile.c +msgid "LHS of keyword arg must be an id" +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass." +msgstr "" + +#: py/objslice.c +msgid "Length must be an int" +msgstr "" + +#: py/objslice.c +msgid "Length must be non-negative" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Looks like our core CircuitPython code crashed hard. Whoops!\n" +"Please file an issue at https://github.com/adafruit/circuitpython/issues\n" +" with the contents of your CIRCUITPY drive and this message:\n" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "MISO pin init failed." +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "MOSI pin init failed." +msgstr "" + +#: shared-module/displayio/Shape.c +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython NLR jump failed. Likely memory corruption.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython fatal error.\n" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Microphone startup delay must be in range 0.0 to 1.0" +msgstr "" + +#: shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "No DAC on chip" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "No DMA channel found" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No RX pin" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No TX pin" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "No available clocks" +msgstr "" + +#: shared-bindings/board/__init__.c +msgid "No default %q bus" +msgstr "" + +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" +msgstr "" + +#: shared-bindings/os/__init__.c +msgid "No hardware random available" +msgstr "" + +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "No hardware support on pin" +msgstr "" + +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" +msgstr "" + +#: py/moduerrno.c +msgid "No space left on device" +msgstr "" + +#: py/moduerrno.c +msgid "No such file/directory" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Peripheral.c +msgid "Not connected" +msgstr "" + +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c +msgid "Not playing" +msgstr "" + +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +msgid "Odd parity is not supported" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Only 8 or 16 bit mono with " +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Only slices with step=1 (aka None) are supported" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Oversample must be multiple of 8." +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM frequency not writable when variable_frequency is False on construction." +msgstr "" + +#: py/moduerrno.c +msgid "Permission denied" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogIn.c +#: ports/nrf/common-hal/analogio/AnalogIn.c +msgid "Pin does not have ADC capabilities" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Pixel beyond bounds of buffer" +msgstr "" + +#: py/builtinhelp.c +msgid "Plus any modules on the filesystem\n" +msgstr "" + +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Pull not used when direction is output." +msgstr "" + +#: ports/nrf/common-hal/rtc/RTC.c +msgid "RTC calibration is not supported on this board" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Range out of bounds" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c +msgid "Read-only" +msgstr "" + +#: extmod/vfs_fat.c py/moduerrno.c +msgid "Read-only filesystem" +msgstr "" + +#: shared-module/displayio/Bitmap.c +msgid "Read-only object" +msgstr "" + +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Refresh too soon" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" +msgstr "" + +#: shared-bindings/_pew/PewPew.c +msgid "Row entry must be digitalio.DigitalInOut" +msgstr "" + +#: main.c +msgid "Running in safe mode! Auto-reload is off.\n" +msgstr "" + +#: main.c +msgid "Running in safe mode! Not running saved code.\n" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "SDA or SCL needs a pull up" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Sample rate must be positive" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Sample rate too high. It must be less than %d" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/pulseio/PulseIn.c +msgid "Slices not supported" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: extmod/modure.c +msgid "Splitting with sub-captures" +msgstr "" + +#: shared-bindings/supervisor/__init__.c +msgid "Stack size must be at least 256" +msgstr "" + +#: shared-bindings/multiterminal/__init__.c +msgid "Stream missing readinto() or write() method." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The CircuitPython heap was corrupted because the stack was too small.\n" +"Please increase stack size limits and press reset (after ejecting " +"CIRCUITPY).\n" +"If you didn't change the stack, then file an issue here with the contents of " +"your CIRCUITPY drive:\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The `microcontroller` module was used to boot into safe mode. Press reset to " +"exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The reset button was pressed while booting CircuitPython. Press again to " +"exit safe mode.\n" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's signedness does not match the mixer's" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile value out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample." +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "Too many display busses" +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Too many displays" +msgstr "" + +#: py/obj.c +msgid "Traceback (most recent call last):\n" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "Tuple or struct_time argument required" +msgstr "" + +#: shared-module/usb_hid/Device.c +msgid "USB Busy" +msgstr "" + +#: shared-module/usb_hid/Device.c +msgid "USB Error" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID integer value must be 0-0xffff" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Unable to allocate buffers for signed conversion" +msgstr "" + +#: shared-module/displayio/I2CDisplay.c +#, c-format +msgid "Unable to find I2C Display at %x" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Unable to find free GCLK" +msgstr "" + +#: py/parse.c +msgid "Unable to init parser" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +msgid "Unexpected nrfx uuid type" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "Unsupported baudrate" +msgstr "" + +#: shared-module/displayio/display_core.c +msgid "Unsupported display bus type" +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Unsupported format" +msgstr "" + +#: py/moduerrno.c +msgid "Unsupported operation" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Unsupported pull value." +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + +#: py/emitnative.c +msgid "Viper functions don't currently support more than 4 arguments" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "Voice index too high" +msgstr "" + +#: main.c +msgid "WARNING: Your code filename has two extensions\n" +msgstr "" + +#: py/builtinhelp.c +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"You are running in safe mode which means something unanticipated happened.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "You requested starting safe mode by " +msgstr "" + +#: py/objtype.c +msgid "__init__() should return None" +msgstr "" + +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "" + +#: py/objobject.c +msgid "__new__ arg must be a user-type" +msgstr "" + +#: extmod/modubinascii.c extmod/moduhashlib.c +msgid "a bytes-like object is required" +msgstr "" + +#: lib/embed/abort_.c +msgid "abort() called" +msgstr "" + +#: extmod/machine_mem.c +#, c-format +msgid "address %08x is not aligned to %d bytes" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "address out of bounds" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "addresses is empty" +msgstr "" + +#: py/modbuiltins.c +msgid "arg is an empty sequence" +msgstr "" + +#: py/runtime.c +msgid "argument has wrong type" +msgstr "" + +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +msgid "argument num/types mismatch" +msgstr "" + +#: py/runtime.c +msgid "argument should be a '%q' not a '%q'" +msgstr "" + +#: py/objarray.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" +msgstr "" + +#: py/objstr.c +msgid "attributes not supported yet" +msgstr "" + +#: py/builtinevex.c +msgid "bad compile mode" +msgstr "" + +#: py/objstr.c +msgid "bad conversion specifier" +msgstr "" + +#: py/objstr.c +msgid "bad format string" +msgstr "" + +#: py/binary.c +msgid "bad typecode" +msgstr "" + +#: py/emitnative.c +msgid "binary op %q not implemented" +msgstr "" + +#: shared-bindings/busio/UART.c +msgid "bits must be 7, 8 or 9" +msgstr "" + +#: extmod/machine_spi.c +msgid "bits must be 8" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "bits_per_sample must be 8 or 16" +msgstr "" + +#: py/emitinlinethumb.c +msgid "branch not in range" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "" + +#: shared-bindings/audiocore/RawSample.c +msgid "buffer must be a bytes-like object" +msgstr "" + +#: shared-module/struct/__init__.c +msgid "buffer size must match format" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" +msgstr "" + +#: py/modstruct.c shared-bindings/struct/__init__.c +#: shared-module/struct/__init__.c +msgid "buffer too small" +msgstr "" + +#: extmod/machine_spi.c +msgid "buffers must be the same length" +msgstr "" + +#: shared-bindings/_pew/PewPew.c +msgid "buttons must be digitalio.DigitalInOut" +msgstr "" + +#: py/vm.c +msgid "byte code not implemented" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "bytes > 8 bits not supported" +msgstr "" + +#: py/objstr.c +msgid "bytes value out of range" +msgstr "" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" +msgstr "" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" +msgstr "" + +#: ports/atmel-samd/common-hal/rtc/RTC.c +msgid "calibration value out of range +/-127" +msgstr "" + +#: py/emitinlinethumb.c +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "" + +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "" + +#: py/persistentcode.c +msgid "can only save bytecode" +msgstr "" + +#: py/objtype.c +msgid "can't add special method to already-subclassed class" +msgstr "" + +#: py/compile.c +msgid "can't assign to expression" +msgstr "" + +#: py/obj.c +#, c-format +msgid "can't convert %s to complex" +msgstr "" + +#: py/obj.c +#, c-format +msgid "can't convert %s to float" +msgstr "" + +#: py/obj.c +#, c-format +msgid "can't convert %s to int" +msgstr "" + +#: py/objstr.c +msgid "can't convert '%q' object to %q implicitly" +msgstr "" + +#: py/objint.c +msgid "can't convert NaN to int" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "can't convert address to int" +msgstr "" + +#: py/objint.c +msgid "can't convert inf to int" +msgstr "" + +#: py/obj.c +msgid "can't convert to complex" +msgstr "" + +#: py/obj.c +msgid "can't convert to float" +msgstr "" + +#: py/obj.c +msgid "can't convert to int" +msgstr "" + +#: py/objstr.c +msgid "can't convert to str implicitly" +msgstr "" + +#: py/compile.c +msgid "can't declare nonlocal in outer code" +msgstr "" + +#: py/compile.c +msgid "can't delete expression" +msgstr "" + +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" +msgstr "" + +#: py/objcomplex.c +msgid "can't do truncated division of a complex number" +msgstr "" + +#: py/compile.c +msgid "can't have multiple **x" +msgstr "" + +#: py/compile.c +msgid "can't have multiple *x" +msgstr "" + +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "" + +#: py/emitnative.c +msgid "can't load from '%q'" +msgstr "" + +#: py/emitnative.c +msgid "can't load with '%q' index" +msgstr "" + +#: py/objgenerator.c +msgid "can't pend throw to just-started generator" +msgstr "" + +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" +msgstr "" + +#: py/objnamedtuple.c +msgid "can't set attribute" +msgstr "" + +#: py/emitnative.c +msgid "can't store '%q'" +msgstr "" + +#: py/emitnative.c +msgid "can't store to '%q'" +msgstr "" + +#: py/emitnative.c +msgid "can't store with '%q' index" +msgstr "" + +#: py/objstr.c +msgid "" +"can't switch from automatic field numbering to manual field specification" +msgstr "" + +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "" + +#: py/objtype.c +msgid "cannot create '%q' instances" +msgstr "" + +#: py/objtype.c +msgid "cannot create instance" +msgstr "" + +#: py/runtime.c +msgid "cannot import name %q" +msgstr "" + +#: py/builtinimport.c +msgid "cannot perform relative import" +msgstr "" + +#: py/emitnative.c +msgid "casting" +msgstr "" + +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" +msgstr "" + +#: py/modbuiltins.c +msgid "chr() arg not in range(0x110000)" +msgstr "" + +#: py/modbuiltins.c +msgid "chr() arg not in range(256)" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer or int" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" +msgstr "" + +#: shared-bindings/displayio/ColorConverter.c +msgid "color should be an int" +msgstr "" + +#: py/objcomplex.c +msgid "complex division by zero" +msgstr "" + +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" +msgstr "" + +#: extmod/moduzlib.c +msgid "compression header" +msgstr "" + +#: py/parse.c +msgid "constant must be an integer" +msgstr "" + +#: py/emitnative.c +msgid "conversion to object" +msgstr "" + +#: py/parsenum.c +msgid "decimal numbers not supported" +msgstr "" + +#: py/compile.c +msgid "default 'except' must be last" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination_length must be an int >= 0" +msgstr "" + +#: py/objdict.c +msgid "dict update sequence has wrong length" +msgstr "" + +#: py/modmath.c py/objfloat.c py/objint_longlong.c py/objint_mpz.c py/runtime.c +#: shared-bindings/math/__init__.c +msgid "division by zero" +msgstr "" + +#: py/objdeque.c +msgid "empty" +msgstr "" + +#: extmod/moduheapq.c extmod/modutimeq.c +msgid "empty heap" +msgstr "" + +#: py/objstr.c +msgid "empty separator" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "empty sequence" +msgstr "" + +#: py/objstr.c +msgid "end of format while looking for conversion specifier" +msgstr "" + +#: shared-bindings/displayio/Shape.c +msgid "end_x should be an int" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +#, c-format +msgid "error = 0x%08lX" +msgstr "" + +#: py/runtime.c +msgid "exceptions must derive from BaseException" +msgstr "" + +#: py/objstr.c +msgid "expected ':' after format specifier" +msgstr "" + +#: py/obj.c +msgid "expected tuple/list" +msgstr "" + +#: py/modthread.c +msgid "expecting a dict for keyword args" +msgstr "" + +#: py/compile.c +msgid "expecting an assembler instruction" +msgstr "" + +#: py/compile.c +msgid "expecting just a value for set" +msgstr "" + +#: py/compile.c +msgid "expecting key:value for dict" +msgstr "" + +#: py/argcheck.c +msgid "extra keyword arguments given" +msgstr "" + +#: py/argcheck.c +msgid "extra positional arguments given" +msgstr "" + +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c +msgid "file must be a file opened in byte mode" +msgstr "" + +#: shared-bindings/storage/__init__.c +msgid "filesystem must provide mount method" +msgstr "" + +#: py/objtype.c +msgid "first argument to super() must be type" +msgstr "" + +#: extmod/machine_spi.c +msgid "firstbit must be MSB" +msgstr "" + +#: py/objint.c +msgid "float too big" +msgstr "" + +#: shared-bindings/_stage/Text.c +msgid "font must be 2048 bytes long" +msgstr "" + +#: py/objstr.c +msgid "format requires a dict" +msgstr "" + +#: py/objdeque.c +msgid "full" +msgstr "" + +#: py/argcheck.c +msgid "function does not take keyword arguments" +msgstr "" + +#: py/argcheck.c +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "" + +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" +msgstr "" + +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" +msgstr "" + +#: py/bc.c +msgid "function missing keyword-only argument" +msgstr "" + +#: py/bc.c +msgid "function missing required keyword argument '%q'" +msgstr "" + +#: py/bc.c +#, c-format +msgid "function missing required positional argument #%d" +msgstr "" + +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "function takes exactly 9 arguments" +msgstr "" + +#: py/objgenerator.c +msgid "generator already executing" +msgstr "" + +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" +msgstr "" + +#: shared-bindings/_stage/Layer.c +msgid "graphic must be 2048 bytes long" +msgstr "" + +#: extmod/moduheapq.c +msgid "heap must be a list" +msgstr "" + +#: py/compile.c +msgid "identifier redefined as global" +msgstr "" + +#: py/compile.c +msgid "identifier redefined as nonlocal" +msgstr "" + +#: py/objstr.c +msgid "incomplete format" +msgstr "" + +#: py/objstr.c +msgid "incomplete format key" +msgstr "" + +#: extmod/modubinascii.c +msgid "incorrect padding" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c py/obj.c +msgid "index out of range" +msgstr "" + +#: py/obj.c +msgid "indices must be integers" +msgstr "" + +#: py/compile.c +msgid "inline assembler must be a function" +msgstr "" + +#: py/parsenum.c +msgid "int() arg 2 must be >= 2 and <= 36" +msgstr "" + +#: py/objstr.c +msgid "integer required" +msgstr "" + +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c +#, c-format +msgid "interval must be in range %s-%s" +msgstr "" + +#: extmod/machine_i2c.c +msgid "invalid I2C peripheral" +msgstr "" + +#: extmod/machine_spi.c +msgid "invalid SPI peripheral" +msgstr "" + +#: lib/netutils/netutils.c +msgid "invalid arguments" +msgstr "" + +#: extmod/modussl_axtls.c +msgid "invalid cert" +msgstr "" + +#: extmod/uos_dupterm.c +msgid "invalid dupterm index" +msgstr "" + +#: extmod/modframebuf.c +msgid "invalid format" +msgstr "" + +#: py/objstr.c +msgid "invalid format specifier" +msgstr "" + +#: extmod/modussl_axtls.c +msgid "invalid key" +msgstr "" + +#: py/compile.c +msgid "invalid micropython decorator" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "invalid step" +msgstr "" + +#: py/compile.c py/parse.c +msgid "invalid syntax" +msgstr "" + +#: py/parsenum.c +msgid "invalid syntax for integer" +msgstr "" + +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "" + +#: py/parsenum.c +msgid "invalid syntax for number" +msgstr "" + +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" +msgstr "" + +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "" + +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "" + +#: py/argcheck.c +msgid "keyword argument(s) not yet implemented - use normal args instead" +msgstr "" + +#: py/bc.c +msgid "keywords must be strings" +msgstr "" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" +msgstr "" + +#: py/compile.c +msgid "label redefined" +msgstr "" + +#: py/stream.c +msgid "length argument not allowed for this type" +msgstr "" + +#: py/objarray.c +msgid "lhs and rhs should be compatible" +msgstr "" + +#: py/emitnative.c +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "" + +#: py/emitnative.c +msgid "local '%q' used before type known" +msgstr "" + +#: py/vm.c +msgid "local variable referenced before assignment" +msgstr "" + +#: py/objint.c +msgid "long int not supported in this build" +msgstr "" + +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" +msgstr "" + +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + +#: py/runtime.c +msgid "maximum recursion depth exceeded" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "" + +#: py/runtime.c +msgid "memory allocation failed, heap is locked" +msgstr "" + +#: py/builtinimport.c +msgid "module not found" +msgstr "" + +#: py/compile.c +msgid "multiple *x in assignment" +msgstr "" + +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" +msgstr "" + +#: py/objtype.c +msgid "multiple inheritance not supported" +msgstr "" + +#: py/emitnative.c +msgid "must raise an object" +msgstr "" + +#: extmod/machine_spi.c +msgid "must specify all of sck/mosi/miso" +msgstr "" + +#: py/modbuiltins.c +msgid "must use keyword argument for key function" +msgstr "" + +#: py/runtime.c +msgid "name '%q' is not defined" +msgstr "" + +#: shared-bindings/_bleio/Peripheral.c +msgid "name must be a string" +msgstr "" + +#: py/runtime.c +msgid "name not defined" +msgstr "" + +#: py/compile.c +msgid "name reused for argument" +msgstr "" + +#: py/emitnative.c +msgid "native yield" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "need more than %d values to unpack" +msgstr "" + +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" +msgstr "" + +#: py/objint_mpz.c py/runtime.c +msgid "negative shift count" +msgstr "" + +#: py/vm.c +msgid "no active exception to reraise" +msgstr "" + +#: shared-bindings/socket/__init__.c shared-module/network/__init__.c +msgid "no available NIC" +msgstr "" + +#: py/compile.c +msgid "no binding for nonlocal found" +msgstr "" + +#: py/builtinimport.c +msgid "no module named '%q'" +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "no reset pin available" +msgstr "" + +#: py/runtime.c shared-bindings/_pixelbuf/__init__.c +msgid "no such attribute" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" +msgstr "" + +#: py/compile.c +msgid "non-default argument follows default argument" +msgstr "" + +#: extmod/modubinascii.c +msgid "non-hex digit found" +msgstr "" + +#: py/compile.c +msgid "non-keyword arg after */**" +msgstr "" + +#: py/compile.c +msgid "non-keyword arg after keyword arg" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" +msgstr "" + +#: py/objstr.c +msgid "not all arguments converted during string formatting" +msgstr "" + +#: py/objstr.c +msgid "not enough arguments for format string" +msgstr "" + +#: py/obj.c +#, c-format +msgid "object '%s' is not a tuple or list" +msgstr "" + +#: py/obj.c +msgid "object does not support item assignment" +msgstr "" + +#: py/obj.c +msgid "object does not support item deletion" +msgstr "" + +#: py/obj.c +msgid "object has no len" +msgstr "" + +#: py/obj.c +msgid "object is not subscriptable" +msgstr "" + +#: py/runtime.c +msgid "object not an iterator" +msgstr "" + +#: py/objtype.c py/runtime.c +msgid "object not callable" +msgstr "" + +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" +msgstr "" + +#: py/runtime.c +msgid "object not iterable" +msgstr "" + +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" +msgstr "" + +#: py/obj.c +msgid "object with buffer protocol required" +msgstr "" + +#: extmod/modubinascii.c +msgid "odd-length string" +msgstr "" + +#: py/objstr.c py/objstrunicode.c +msgid "offset out of bounds" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" +msgstr "" + +#: py/modbuiltins.c +msgid "ord expects a character" +msgstr "" + +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "" + +#: py/objint_mpz.c +msgid "overflow converting long int to machine word" +msgstr "" + +#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c +msgid "palette must be 32 bytes long" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "palette_index should be an int" +msgstr "" + +#: py/compile.c +msgid "parameter annotation must be an identifier" +msgstr "" + +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" +msgstr "" + +#: py/emitinlinethumb.c +msgid "parameters must be registers in sequence r0 to r3" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel coordinates out of bounds" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel value requires too many bits" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" +msgstr "" + +#: py/objset.c +msgid "pop from an empty set" +msgstr "" + +#: py/objlist.c +msgid "pop from empty list" +msgstr "" + +#: py/objdict.c +msgid "popitem(): dictionary is empty" +msgstr "" + +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" +msgstr "" + +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" +msgstr "" + +#: extmod/modutimeq.c +msgid "queue overflow" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "rawbuf is not the same size as buf" +msgstr "" + +#: shared-bindings/_pixelbuf/__init__.c +msgid "readonly attribute" +msgstr "" + +#: py/builtinimport.c +msgid "relative import" +msgstr "" + +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" +msgstr "" + +#: py/compile.c +msgid "return annotation must be an identifier" +msgstr "" + +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" +msgstr "" + +#: py/objstr.c +msgid "rsplit(None,n)" +msgstr "" + +#: shared-bindings/audiocore/RawSample.c +msgid "" +"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " +"'B'" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" +msgstr "" + +#: py/modmicropython.c +msgid "schedule stack full" +msgstr "" + +#: lib/utils/pyexec.c py/builtinimport.c +msgid "script compilation not supported" +msgstr "" + +#: py/objstr.c +msgid "sign not allowed in string format specifier" +msgstr "" + +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" +msgstr "" + +#: py/objstr.c +msgid "single '}' encountered in format string" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "sleep length must be non-negative" +msgstr "" + +#: py/objslice.c py/sequence.c +msgid "slice step cannot be zero" +msgstr "" + +#: py/objint.c py/sequence.c +msgid "small int overflow" +msgstr "" + +#: main.c +msgid "soft reboot\n" +msgstr "" + +#: py/objstr.c +msgid "start/end indices" +msgstr "" + +#: shared-bindings/displayio/Shape.c +msgid "start_x should be an int" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "step must be non-zero" +msgstr "" + +#: shared-bindings/busio/UART.c +msgid "stop must be 1 or 2" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" +msgstr "" + +#: py/stream.c +msgid "stream operation not supported" +msgstr "" + +#: py/objstrunicode.c +msgid "string index out of range" +msgstr "" + +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" +msgstr "" + +#: py/stream.c +msgid "string not supported; use bytes or bytearray" +msgstr "" + +#: extmod/moductypes.c +msgid "struct: cannot index" +msgstr "" + +#: extmod/moductypes.c +msgid "struct: index out of range" +msgstr "" + +#: extmod/moductypes.c +msgid "struct: no fields" +msgstr "" + +#: py/objstr.c +msgid "substring not found" +msgstr "" + +#: py/compile.c +msgid "super() can't find self" +msgstr "" + +#: extmod/modujson.c +msgid "syntax error in JSON" +msgstr "" + +#: extmod/moductypes.c +msgid "syntax error in uctypes descriptor" +msgstr "" + +#: shared-bindings/touchio/TouchIn.c +msgid "threshold must be in the range 0-65536" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes a 9-sequence" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes exactly 1 argument" +msgstr "" + +#: shared-bindings/busio/UART.c +msgid "timeout >100 (units are now seconds, not msecs)" +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "timeout must be >= 0.0" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" +msgstr "" + +#: shared-module/struct/__init__.c +msgid "too many arguments provided with the given format" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "" + +#: py/objstr.c +msgid "tuple index out of range" +msgstr "" + +#: py/obj.c +msgid "tuple/list has wrong length" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "tuple/list required on RHS" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "tx and rx cannot both be None" +msgstr "" + +#: py/objtype.c +msgid "type '%q' is not an acceptable base type" +msgstr "" + +#: py/objtype.c +msgid "type is not an acceptable base type" +msgstr "" + +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" +msgstr "" + +#: py/objtype.c +msgid "type takes 1 or 3 arguments" +msgstr "" + +#: py/objint_longlong.c +msgid "ulonglong too large" +msgstr "" + +#: py/emitnative.c +msgid "unary op %q not implemented" +msgstr "" + +#: py/parse.c +msgid "unexpected indent" +msgstr "" + +#: py/bc.c +msgid "unexpected keyword argument" +msgstr "" + +#: py/bc.c py/objnamedtuple.c +msgid "unexpected keyword argument '%q'" +msgstr "" + +#: py/lexer.c +msgid "unicode name escapes" +msgstr "" + +#: py/parse.c +msgid "unindent does not match any outer indentation level" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown conversion specifier %c" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type '%s'" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'float'" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'str'" +msgstr "" + +#: py/compile.c +msgid "unknown type" +msgstr "" + +#: py/emitnative.c +msgid "unknown type '%q'" +msgstr "" + +#: py/objstr.c +msgid "unmatched '{' in format" +msgstr "" + +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "unsupported %q type" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "" + +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "" + +#: py/runtime.c +msgid "unsupported type for %q: '%s'" +msgstr "" + +#: py/runtime.c +msgid "unsupported type for operator" +msgstr "" + +#: py/runtime.c +msgid "unsupported types for %q: '%s', '%s'" +msgstr "" + +#: py/objint.c +#, c-format +msgid "value must fit in %d byte(s)" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "value_count must be > 0" +msgstr "" + +#: shared-bindings/_bleio/Scanner.c +msgid "window must be <= interval" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "write_args must be a list, tuple, or None" +msgstr "" + +#: py/objstr.c +msgid "wrong number of arguments" +msgstr "" + +#: py/runtime.c +msgid "wrong number of values to unpack" +msgstr "" + +#: shared-module/displayio/Shape.c +msgid "x value out of bounds" +msgstr "" + +#: shared-bindings/displayio/Shape.c +msgid "y should be an int" +msgstr "" + +#: shared-module/displayio/Shape.c +msgid "y value out of bounds" +msgstr "" + +#: py/objrange.c +msgid "zero step" +msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po new file mode 100644 index 00000000000..071ec43ab2e --- /dev/null +++ b/locale/de_DE.po @@ -0,0 +1,2980 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"PO-Revision-Date: 2018-07-27 11:55-0700\n" +"Last-Translator: Pascal Deneaux\n" +"Language-Team: Sebastian Plamauer, Pascal Deneaux\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.1.1\n" + +#: main.c +msgid "" +"\n" +"Code done running. Waiting for reload.\n" +msgstr "" +"\n" +"Der Code wurde ausgeführt. Warte auf reload.\n" + +#: py/obj.c +msgid " File \"%q\"" +msgstr " Datei \"%q\"" + +#: py/obj.c +msgid " File \"%q\", line %d" +msgstr " Datei \"%q\", Zeile %d" + +#: main.c +msgid " output:\n" +msgstr " Ausgabe:\n" + +#: py/objstr.c +#, c-format +msgid "%%c requires int or char" +msgstr "%%c erwartet int oder char" + +#: shared-bindings/microcontroller/Pin.c +msgid "%q in use" +msgstr "%q in Benutzung" + +#: py/obj.c +msgid "%q index out of range" +msgstr "Der Index %q befindet sich außerhalb der Reihung" + +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "%q Indizes müssen ganze Zahlen sein, nicht %s" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c +msgid "%q must be >= 1" +msgstr "%q muss >= 1 sein" + +#: shared-bindings/fontio/BuiltinFont.c +msgid "%q should be an int" +msgstr "%q sollte ein int sein" + +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" +msgstr "%q() nimmt %d Argumente ohne Keyword an, aber es wurden %d angegeben" + +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "'%q' Argument erforderlich" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" +msgstr "'%s' erwartet ein Label" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" +msgstr "'%s' erwartet ein Register" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects a special register" +msgstr "'%s' erwartet ein Spezialregister" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an FPU register" +msgstr "'%s' erwartet ein FPU-Register" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "'%s' erwartet eine Adresse in der Form [a, b]" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" +msgstr "'%s' erwartet ein Integer" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects at most r%d" +msgstr "'%s' erwartet höchstens r%d" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "'%s' erwartet {r0, r1, ...}" + +#: py/emitinlinextensa.c +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "'%s' integer %d ist nicht im Bereich %d..%d" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "'%s' Integer 0x%x passt nicht in Maske 0x%x" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item assignment" +msgstr "'%s' Objekt unterstützt keine item assignment" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item deletion" +msgstr "'%s' Objekt unterstützt das Löschen von Elementen nicht" + +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" +msgstr "'%s' Objekt hat kein Attribut '%q'" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not an iterator" +msgstr "'%s' Objekt ist kein Iterator" + +#: py/objtype.c py/runtime.c +#, c-format +msgid "'%s' object is not callable" +msgstr "'%s' object ist nicht callable" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not iterable" +msgstr "'%s' Objekt nicht iterierbar" + +#: py/obj.c +#, c-format +msgid "'%s' object is not subscriptable" +msgstr "'%s' Objekt hat keine '__getitem__'-Methode (not subscriptable)" + +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" +msgstr "'='-Ausrichtung ist im String-Formatbezeichner nicht zulässig" + +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" +msgstr "'S' und 'O' sind keine unterstützten Formattypen" + +#: py/compile.c +msgid "'align' requires 1 argument" +msgstr "'align' erfordert genau ein Argument" + +#: py/compile.c +msgid "'await' outside function" +msgstr "'await' außerhalb einer Funktion" + +#: py/compile.c +msgid "'break' outside loop" +msgstr "'break' außerhalb einer Schleife" + +#: py/compile.c +msgid "'continue' outside loop" +msgstr "'continue' außerhalb einer Schleife" + +#: py/compile.c +msgid "'data' requires at least 2 arguments" +msgstr "'data' erfordert mindestens zwei Argumente" + +#: py/compile.c +msgid "'data' requires integer arguments" +msgstr "'data' erfordert Integer-Argumente" + +#: py/compile.c +msgid "'label' requires 1 argument" +msgstr "'label' erfordert genau ein Argument" + +#: py/compile.c +msgid "'return' outside function" +msgstr "'return' außerhalb einer Funktion" + +#: py/compile.c +msgid "'yield' outside function" +msgstr "'yield' außerhalb einer Funktion" + +#: py/compile.c +msgid "*x must be assignment target" +msgstr "*x muss Zuordnungsziel sein" + +#: py/obj.c +msgid ", in %q\n" +msgstr "" + +#: py/objcomplex.c +msgid "0.0 to a complex power" +msgstr "" + +#: py/modbuiltins.c +msgid "3-arg pow() not supported" +msgstr "3-arg pow() wird nicht unterstützt" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "A hardware interrupt channel is already in use" +msgstr "Ein Hardware Interrupt Kanal wird schon benutzt" + +#: shared-bindings/_bleio/Address.c +#, c-format +msgid "Address must be %d bytes long" +msgstr "Die Adresse muss %d Bytes lang sein" + +#: shared-bindings/_bleio/Address.c +msgid "Address type out of range" +msgstr "" + +#: ports/nrf/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" +msgstr "Alle I2C-Peripheriegeräte sind in Benutzung" + +#: ports/nrf/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" +msgstr "Alle SPI-Peripheriegeräte sind in Benutzung" + +#: ports/nrf/common-hal/busio/UART.c +msgid "All UART peripherals are in use" +msgstr "Alle UART-Peripheriegeräte sind in Benutzung" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "Alle event Kanäle werden benutzt" + +#: ports/atmel-samd/audio_dma.c ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "All sync event channels in use" +msgstr "Alle sync event Kanäle werden benutzt" + +#: shared-bindings/pulseio/PWMOut.c +msgid "All timers for this pin are in use" +msgstr "Alle timer für diesen Pin werden bereits benutzt" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: shared-module/_pew/PewPew.c +msgid "All timers in use" +msgstr "Alle timer werden benutzt" + +#: ports/nrf/common-hal/analogio/AnalogOut.c +msgid "AnalogOut functionality not supported" +msgstr "AnalogOut-Funktion wird nicht unterstützt" + +#: shared-bindings/analogio/AnalogOut.c +msgid "AnalogOut is only 16 bits. Value must be less than 65536." +msgstr "AnalogOut kann nur 16 Bit. Der Wert muss unter 65536 liegen." + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "AnalogOut not supported on given pin" +msgstr "AnalogOut ist an diesem Pin nicht unterstützt" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" +msgstr "Ein anderer Sendevorgang ist schon aktiv" + +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" +msgstr "Array muss Halbwörter enthalten (type 'H')" + +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." +msgstr "Array-Werte sollten aus Einzelbytes bestehen." + +#: supervisor/shared/safe_mode.c +msgid "Attempted heap allocation when MicroPython VM not running.\n" +msgstr "" + +#: main.c +msgid "Auto-reload is off.\n" +msgstr "Automatisches Neuladen ist deaktiviert.\n" + +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "" +"Automatisches Neuladen ist aktiv. Speichere Dateien über USB um sie " +"auszuführen oder verbinde dich mit der REPL zum Deaktivieren.\n" + +#: shared-module/displayio/Display.c +msgid "Below minimum frame rate" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Bit clock and word select must share a clock unit" +msgstr "Bit clock und word select müssen eine clock unit teilen" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Bit depth must be multiple of 8." +msgstr "Bit depth muss ein Vielfaches von 8 sein." + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "Both pins must support hardware interrupts" +msgstr "Beide pins müssen Hardware Interrupts unterstützen" + +#: shared-bindings/displayio/Display.c +msgid "Brightness must be 0-1.0" +msgstr "" + +#: shared-bindings/supervisor/__init__.c +msgid "Brightness must be between 0 and 255" +msgstr "Die Helligkeit muss zwischen 0 und 255 liegen" + +#: shared-bindings/displayio/Display.c +msgid "Brightness not adjustable" +msgstr "Die Helligkeit ist nicht einstellbar" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "Der Puffergröße ist inkorrekt. Sie sollte %d bytes haben." + +#: shared-bindings/displayio/Display.c +msgid "Buffer is not a bytearray." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Buffer is too small" +msgstr "" + +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Buffer length %d too big. It must be less than %d" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c +msgid "Buffer must be at least length 1" +msgstr "Der Puffer muss eine Mindestenslänge von 1 haben" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +#, c-format +msgid "Bus pin %d is already in use" +msgstr "Bus pin %d wird schon benutzt" + +#: shared-bindings/_bleio/UUID.c +msgid "Byte buffer must be 16 bytes." +msgstr "Der Puffer muss 16 Bytes lang sein" + +#: shared-bindings/nvm/ByteArray.c +msgid "Bytes must be between 0 and 255." +msgstr "Ein Bytes kann nur Werte zwischen 0 und 255 annehmen." + +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Can not use dotstar with %s" +msgstr "Kann dotstar nicht mit %s verwenden" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" +msgstr "Kann Werte nicht löschen" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/nrf/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "Pull up im Ausgabemodus nicht möglich" + +#: ports/nrf/common-hal/microcontroller/Processor.c +msgid "Cannot get temperature" +msgstr "Kann Temperatur nicht holen" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Cannot output both channels on the same pin" +msgstr "Kann nicht beite Kanäle auf dem gleichen Pin ausgeben" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot read without MISO pin." +msgstr "Kann ohne MISO-Pin nicht lesen." + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Cannot record to a file" +msgstr "Aufnahme in eine Datei nicht möglich" + +#: shared-module/storage/__init__.c +msgid "Cannot remount '/' when USB is active." +msgstr "Kann '/' nicht remounten when USB aktiv ist" + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +msgid "Cannot reset into bootloader because no bootloader is present." +msgstr "Reset zum bootloader nicht möglich da bootloader nicht vorhanden" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Cannot set value when direction is input." +msgstr "Der Wert kann nicht gesetzt werden, wenn die Richtung input ist." + +#: py/objslice.c +msgid "Cannot subclass slice" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot transfer without MOSI and MISO pins." +msgstr "Übertragung ohne MOSI- und MISO-Pins nicht möglich." + +#: extmod/moductypes.c +msgid "Cannot unambiguously get sizeof scalar" +msgstr "sizeof scalar kann nicht eindeutig bestimmt werden" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot write without MOSI pin." +msgstr "Kann nicht ohne MOSI-Pin schreiben." + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" +msgstr "Schreiben von CharacteristicBuffer ist nicht vorgesehen" + +#: shared-module/bitbangio/SPI.c +msgid "Clock pin init failed." +msgstr "Clock pin init fehlgeschlagen." + +#: shared-module/bitbangio/I2C.c +msgid "Clock stretch too long" +msgstr "Clock stretch zu lang" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" +msgstr "Clock unit wird benutzt" + +#: shared-bindings/_pew/PewPew.c +msgid "Column entry must be digitalio.DigitalInOut" +msgstr "" + +#: shared-bindings/displayio/I2CDisplay.c +msgid "Command must be 0-255" +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +msgid "Command must be an int between 0 and 255" +msgstr "Der Befehl muss ein int zwischen 0 und 255 sein" + +#: py/persistentcode.c +msgid "Corrupt .mpy file" +msgstr "" + +#: py/emitglue.c +msgid "Corrupt raw code" +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "Konnte ble_uuid nicht decodieren. Status: 0x%04x" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "Could not initialize UART" +msgstr "Konnte UART nicht initialisieren" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate first buffer" +msgstr "Konnte first buffer nicht zuteilen" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate second buffer" +msgstr "Konnte second buffer nicht zuteilen" + +#: supervisor/shared/safe_mode.c +msgid "Crash into the HardFault_Handler.\n" +msgstr "Absturz in HardFault_Handler.\n" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "DAC already in use" +msgstr "DAC wird schon benutzt" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +msgid "Data 0 pin must be byte aligned" +msgstr "Data 0 pin muss am Byte ausgerichtet sein" + +#: shared-module/audiocore/WaveFile.c +msgid "Data chunk must follow fmt chunk" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Data too large for advertisement packet" +msgstr "Zu vielen Daten für das advertisement packet" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Destination capacity is smaller than destination_length." +msgstr "Die Zielkapazität ist kleiner als destination_length." + +#: shared-bindings/displayio/Display.c +msgid "Display must have a 16 bit colorspace." +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Display rotation must be in 90 degree increments" +msgstr "Die Rotation der Anzeige muss in 90-Grad-Schritten erfolgen" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Drive mode not used when direction is input." +msgstr "Drive mode wird nicht verwendet, wenn die Richtung input ist." + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "EXTINT channel already in use" +msgstr "EXTINT Kanal ist schon in Benutzung" + +#: extmod/modure.c +msgid "Error in regex" +msgstr "Fehler in regex" + +#: shared-bindings/microcontroller/Pin.c +#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c +#: shared-bindings/terminalio/Terminal.c +msgid "Expected a %q" +msgstr "Erwartet ein(e) %q" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c +msgid "Expected a Characteristic" +msgstr "Characteristic wird erwartet" + +#: shared-bindings/_bleio/Service.c +msgid "Expected a Peripheral" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Expected a Service" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c +#: shared-bindings/_bleio/Service.c +msgid "Expected a UUID" +msgstr "Eine UUID wird erwartet" + +#: shared-bindings/_bleio/Central.c +msgid "Expected an Address" +msgstr "" + +#: shared-module/_pixelbuf/PixelBuf.c +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "Habe ein Tupel der Länge %d erwartet aber %d erhalten" + +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + +#: ports/nrf/sd_mutex.c +#, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "Mutex konnte nicht akquiriert werden. Status: 0x%04x" + +#: ports/nrf/common-hal/_bleio/Service.c +#, c-format +msgid "Failed to add characteristic, err 0x%04x" +msgstr "Hinzufügen des Characteristic ist gescheitert. Status: 0x%04x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to add descriptor, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to add service, err 0x%04x" +msgstr "Dienst konnte nicht hinzugefügt werden. Status: 0x%04x" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "Failed to allocate RX buffer" +msgstr "Konnte keinen RX Buffer allozieren" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +#, c-format +msgid "Failed to allocate RX buffer of %d bytes" +msgstr "Konnte keine RX Buffer mit %d allozieren" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to change softdevice state" +msgstr "Fehler beim Ändern des Softdevice-Status" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to configure advertising, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Central.c +msgid "Failed to connect: timeout" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, c-format +msgid "Failed to continue scanning, err 0x%04x" +msgstr "Der Scanvorgang kann nicht fortgesetzt werden. Status: 0x%04x" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "Failed to discover services" +msgstr "Es konnten keine Dienste gefunden werden" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to get local address" +msgstr "Lokale Adresse konnte nicht abgerufen werden" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to get softdevice state" +msgstr "Fehler beim Abrufen des Softdevice-Status" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to notify or indicate attribute value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "Kann CCCD value nicht lesen. Status: 0x%04x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "Failed to read attribute value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to read gatts value, err 0x%04x" +msgstr "gatts value konnte nicht gelesen werden. Status: 0x%04x" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" +msgstr "Kann keine herstellerspezifische UUID hinzufügen. Status: 0x%04x" + +#: ports/nrf/sd_mutex.c +#, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "Mutex konnte nicht freigegeben werden. Status: 0x%04x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to set device name, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "Kann advertisement nicht starten. Status: 0x%04x" + +#: ports/nrf/common-hal/_bleio/Central.c +#, c-format +msgid "Failed to start connecting, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, c-format +msgid "Failed to start scanning, err 0x%04x" +msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%04x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "Kann advertisement nicht stoppen. Status: 0x%04x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to write CCCD, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to write attribute value, err 0x%04x" +msgstr "Kann den Attributwert nicht schreiben. Status: 0x%04x" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to write gatts value, err 0x%04x" +msgstr "gatts value konnte nicht geschrieben werden. Status: 0x%04x" + +#: py/moduerrno.c +msgid "File exists" +msgstr "Datei existiert" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash erase failed" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash erase failed to start, err 0x%04x" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash write failed" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash write failed to start, err 0x%04x" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Frequency captured is above capability. Capture Paused." +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c +msgid "Function requires lock" +msgstr "Die Funktion erwartet, dass der 'lock'-Befehl zuvor ausgeführt wurde" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Group already used" +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Group full" +msgstr "Gruppe voll" + +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" +msgstr "Lese/Schreibe-operation an geschlossener Datei" + +#: extmod/machine_i2c.c +msgid "I2C operation not supported" +msgstr "I2C-operation nicht unterstützt" + +#: py/persistentcode.c +msgid "" +"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" +"mpy-update for more info." +msgstr "" +"Inkompatible mpy-Datei. Bitte aktualisieren Sie alle mpy-Dateien. Siehe " +"http://adafru.it/mpy-update für weitere Informationen." + +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" +msgstr "" + +#: py/moduerrno.c +msgid "Input/output error" +msgstr "Eingabe-/Ausgabefehler" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Invalid %q pin" +msgstr "Ungültiger %q pin" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Invalid BMP file" +msgstr "Ungültige BMP-Datei" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c +#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c +msgid "Invalid PWM frequency" +msgstr "Ungültige PWM Frequenz" + +#: py/moduerrno.c +msgid "Invalid argument" +msgstr "Ungültiges Argument" + +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +msgid "Invalid buffer size" +msgstr "Ungültige Puffergröße" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Invalid capture period. Valid range: 1 - 500" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid channel count" +msgstr "Ungültige Anzahl von Kanälen" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Invalid direction." +msgstr "Ungültige Richtung" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid file" +msgstr "Ungültige Datei" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" +msgstr "Ungültige format chunk size" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid number of bits" +msgstr "Ungültige Anzahl von Bits" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid phase" +msgstr "Ungültige Phase" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +#: shared-bindings/pulseio/PWMOut.c +msgid "Invalid pin" +msgstr "Ungültiger Pin" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for left channel" +msgstr "Ungültiger Pin für linken Kanal" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for right channel" +msgstr "Ungültiger Pin für rechten Kanal" + +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/atmel-samd/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c +#: ports/nrf/common-hal/busio/I2C.c +msgid "Invalid pins" +msgstr "Ungültige Pins" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid polarity" +msgstr "Ungültige Polarität" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + +#: shared-bindings/microcontroller/__init__.c +msgid "Invalid run mode." +msgstr "Ungültiger Ausführungsmodus" + +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid voice count" +msgstr "Ungültige Anzahl von Stimmen" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid wave file" +msgstr "Ungültige wave Datei" + +#: py/compile.c +msgid "LHS of keyword arg must be an id" +msgstr "LHS des Schlüsselwortarguments muss eine id sein" + +#: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass." +msgstr "Layer muss eine Group- oder TileGrid-Unterklasse sein." + +#: py/objslice.c +msgid "Length must be an int" +msgstr "Länge muss ein int sein" + +#: py/objslice.c +msgid "Length must be non-negative" +msgstr "Länge darf nicht negativ sein" + +#: supervisor/shared/safe_mode.c +msgid "" +"Looks like our core CircuitPython code crashed hard. Whoops!\n" +"Please file an issue at https://github.com/adafruit/circuitpython/issues\n" +" with the contents of your CIRCUITPY drive and this message:\n" +msgstr "" +"Sieht aus, als wäre der CircuitPython-Kernel-Code abgestürzt. Uups!\n" +"Bitte melde das Problem unter https://github.com/adafruit/circuitpython/" +"issues\n" +"mit dem Inhalt deines CIRCUITPY-Laufwerks und dieser Nachricht:\n" + +#: shared-module/bitbangio/SPI.c +msgid "MISO pin init failed." +msgstr "MISO pin Initialisierung fehlgeschlagen" + +#: shared-module/bitbangio/SPI.c +msgid "MOSI pin init failed." +msgstr "MOSI pin Initialisierung fehlgeschlagen" + +#: shared-module/displayio/Shape.c +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "Maximaler x-Wert beim Spiegeln ist %d" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython NLR jump failed. Likely memory corruption.\n" +msgstr "" +"MicroPython-NLR-Sprung ist fehlgeschlagen. Wahrscheinlich " +"Speicherbeschädigung.\n" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython fatal error.\n" +msgstr "Schwerwiegender MicroPython-Fehler\n" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Microphone startup delay must be in range 0.0 to 1.0" +msgstr "" +"Die Startverzögerung des Mikrofons muss im Bereich von 0,0 bis 1,0 liegen" + +#: shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "No DAC on chip" +msgstr "Kein DAC im Chip vorhanden" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "No DMA channel found" +msgstr "Kein DMA Kanal gefunden" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No RX pin" +msgstr "Kein RX Pin" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No TX pin" +msgstr "Kein TX Pin" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "No available clocks" +msgstr "" + +#: shared-bindings/board/__init__.c +msgid "No default %q bus" +msgstr "Kein Standard %q Bus" + +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" +msgstr "Keine freien GCLKs" + +#: shared-bindings/os/__init__.c +msgid "No hardware random available" +msgstr "Kein hardware random verfügbar" + +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "No hardware support on pin" +msgstr "Keine Hardwareunterstützung an diesem Pin" + +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" +msgstr "" + +#: py/moduerrno.c +msgid "No space left on device" +msgstr "Kein Speicherplatz auf Gerät" + +#: py/moduerrno.c +msgid "No such file/directory" +msgstr "Keine solche Datei/Verzeichnis" + +#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Peripheral.c +msgid "Not connected" +msgstr "Nicht verbunden" + +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c +msgid "Not playing" +msgstr "Spielt nicht" + +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "" +"Objekt wurde deinitialisiert und kann nicht mehr verwendet werden. Erstelle " +"ein neues Objekt." + +#: ports/nrf/common-hal/busio/UART.c +msgid "Odd parity is not supported" +msgstr "Eine ungerade Parität wird nicht unterstützt" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Only 8 or 16 bit mono with " +msgstr "Nur 8 oder 16 bit mono mit " + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Only slices with step=1 (aka None) are supported" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Oversample must be multiple of 8." +msgstr "Oversample muss ein Vielfaches von 8 sein." + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" +msgstr "PWM duty_cycle muss zwischen 0 und 65535 (16 Bit Auflösung) liegen" + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM frequency not writable when variable_frequency is False on construction." +msgstr "Die PWM-Frequenz ist nicht schreibbar wenn variable_Frequenz = False." + +#: py/moduerrno.c +msgid "Permission denied" +msgstr "Zugang verweigert" + +#: ports/atmel-samd/common-hal/analogio/AnalogIn.c +#: ports/nrf/common-hal/analogio/AnalogIn.c +msgid "Pin does not have ADC capabilities" +msgstr "Pin hat keine ADC Funktionalität" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Pixel beyond bounds of buffer" +msgstr "Pixel außerhalb der Puffergrenzen" + +#: py/builtinhelp.c +msgid "Plus any modules on the filesystem\n" +msgstr "und alle Module im Dateisystem \n" + +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload." +msgstr "" +"Drücke eine Taste um dich mit der REPL zu verbinden. Drücke Strg-D zum neu " +"laden" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Pull not used when direction is output." +msgstr "Pull wird nicht verwendet, wenn die Richtung output ist." + +#: ports/nrf/common-hal/rtc/RTC.c +msgid "RTC calibration is not supported on this board" +msgstr "Die RTC-Kalibrierung wird auf diesem Board nicht unterstützt" + +#: shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" +msgstr "Eine RTC wird auf diesem Board nicht unterstützt" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Range out of bounds" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c +msgid "Read-only" +msgstr "Nur lesen möglich, da Schreibgeschützt" + +#: extmod/vfs_fat.c py/moduerrno.c +msgid "Read-only filesystem" +msgstr "Schreibgeschützte Dateisystem" + +#: shared-module/displayio/Bitmap.c +msgid "Read-only object" +msgstr "Schreibgeschützte Objekt" + +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Refresh too soon" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" +msgstr "Rechter Kanal wird nicht unterstützt" + +#: shared-bindings/_pew/PewPew.c +msgid "Row entry must be digitalio.DigitalInOut" +msgstr "" + +#: main.c +msgid "Running in safe mode! Auto-reload is off.\n" +msgstr "Sicherheitsmodus aktiv! Automatisches Neuladen ist deaktiviert.\n" + +#: main.c +msgid "Running in safe mode! Not running saved code.\n" +msgstr "Sicherheitsmodus aktiv! Gespeicherter Code wird nicht ausgeführt\n" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "SDA or SCL needs a pull up" +msgstr "SDA oder SCL brauchen pull up" + +#: shared-bindings/audiocore/Mixer.c +msgid "Sample rate must be positive" +msgstr "Abtastrate muss positiv sein" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Sample rate too high. It must be less than %d" +msgstr "Abtastrate zu hoch. Wert muss unter %d liegen" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" +msgstr "Serializer wird benutzt" + +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." +msgstr "Slice und Wert (value) haben unterschiedliche Längen." + +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/pulseio/PulseIn.c +msgid "Slices not supported" +msgstr "Slices werden nicht unterstützt" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: extmod/modure.c +msgid "Splitting with sub-captures" +msgstr "Splitting mit sub-captures" + +#: shared-bindings/supervisor/__init__.c +msgid "Stack size must be at least 256" +msgstr "Die Stackgröße sollte mindestens 256 sein" + +#: shared-bindings/multiterminal/__init__.c +msgid "Stream missing readinto() or write() method." +msgstr "Stream fehlt readinto() oder write() Methode." + +#: supervisor/shared/safe_mode.c +msgid "" +"The CircuitPython heap was corrupted because the stack was too small.\n" +"Please increase stack size limits and press reset (after ejecting " +"CIRCUITPY).\n" +"If you didn't change the stack, then file an issue here with the contents of " +"your CIRCUITPY drive:\n" +msgstr "" +"Der CircuitPython-Heap war beschädigt, weil der Stack zu klein war.\n" +"Bitte erhöhe die stack size limits und drücke die Reset-Taste (nach Auswurf " +"des CIRCUITPY-Laufwerks)\n" +"Wenn du den Stack nicht geändert hast, melde bitte das Problem unter https://" +"github.com/adafruit/circuitpython/issues\n" +"mit dem Inhalt deines CIRCUITPY-Laufwerks.\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"The `microcontroller` module was used to boot into safe mode. Press reset to " +"exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" +"Die Stromversorgung des Mikrocontrollers ist eingebrochen. Stelle sicher, " +"dass deine Stromversorgung genug Leistung für die gesamte Schaltung zur " +"Verfügung stellt und drücke die Reset-Taste (nach Auswurf des CIRCUITPY-" +"Laufwerks)\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"The reset button was pressed while booting CircuitPython. Press again to " +"exit safe mode.\n" +msgstr "" +"Die Reset-Taste wurde beim Booten von CircuitPython gedrückt. Drücke sie " +"erneut um den abgesicherten Modus zu verlassen. \n" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's signedness does not match the mixer's" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile value out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "Zum beenden, resette bitte das board ohne " + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample." +msgstr "Zu viele Kanäle im sample" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "Too many display busses" +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Too many displays" +msgstr "Zu viele displays" + +#: py/obj.c +msgid "Traceback (most recent call last):\n" +msgstr "Zurückverfolgung (jüngste Aufforderung zuletzt):\n" + +#: shared-bindings/time/__init__.c +msgid "Tuple or struct_time argument required" +msgstr "Tuple- oder struct_time-Argument erforderlich" + +#: shared-module/usb_hid/Device.c +msgid "USB Busy" +msgstr "USB beschäftigt" + +#: shared-module/usb_hid/Device.c +msgid "USB Error" +msgstr "USB Fehler" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID integer value must be 0-0xffff" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "UUID Zeichenfolge ist nicht 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" +msgstr "Der UUID-Wert ist kein str-, int- oder Byte-Puffer" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Unable to allocate buffers for signed conversion" +msgstr "Konnte keine Buffer für Vorzeichenumwandlung allozieren" + +#: shared-module/displayio/I2CDisplay.c +#, c-format +msgid "Unable to find I2C Display at %x" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Unable to find free GCLK" +msgstr "Konnte keinen freien GCLK finden" + +#: py/parse.c +msgid "Unable to init parser" +msgstr "Parser konnte nicht gestartet werden" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." +msgstr "Schreiben in nvm nicht möglich." + +#: ports/nrf/common-hal/_bleio/UUID.c +msgid "Unexpected nrfx uuid type" +msgstr "Unerwarteter nrfx uuid-Typ" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" +"Nicht übereinstimmende Anzahl von Elementen auf der rechten Seite (erwartet " +"%d, %d erhalten)." + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "Unsupported baudrate" +msgstr "Baudrate wird nicht unterstützt" + +#: shared-module/displayio/display_core.c +msgid "Unsupported display bus type" +msgstr "Nicht unterstützter display bus type" + +#: shared-module/audiocore/WaveFile.c +msgid "Unsupported format" +msgstr "Nicht unterstütztes Format" + +#: py/moduerrno.c +msgid "Unsupported operation" +msgstr "Nicht unterstützte Operation" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Unsupported pull value." +msgstr "Nicht unterstützter Pull-Wert" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + +#: py/emitnative.c +msgid "Viper functions don't currently support more than 4 arguments" +msgstr "Viper-Funktionen unterstützen derzeit nicht mehr als 4 Argumente" + +#: shared-module/audiocore/Mixer.c +msgid "Voice index too high" +msgstr "Voice index zu hoch" + +#: main.c +msgid "WARNING: Your code filename has two extensions\n" +msgstr "" +"WARNUNG: Der Dateiname deines Programms hat zwei Dateityperweiterungen\n" + +#: py/builtinhelp.c +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" +"Willkommen bei Adafruit CircuitPython %s!\n" +"\n" +"Projektleitfäden findest du auf learn.adafruit.com/category/circuitpython \n" +"\n" +"Um die integrierten Module aufzulisten, führe bitte `help(\"modules\")` " +"aus.\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"You are running in safe mode which means something unanticipated happened.\n" +msgstr "" +"Sie laufen im abgesicherten Modus, was bedeutet, dass etwas Unerwartetes " +"passiert ist.\n" + +#: supervisor/shared/safe_mode.c +msgid "You requested starting safe mode by " +msgstr "Du hast das Starten im Sicherheitsmodus ausgelöst durch " + +#: py/objtype.c +msgid "__init__() should return None" +msgstr "__init__() sollte None zurückgeben" + +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "__init__() sollte None zurückgeben, nicht '%s'" + +#: py/objobject.c +msgid "__new__ arg must be a user-type" +msgstr "__new__ arg muss user-type sein" + +#: extmod/modubinascii.c extmod/moduhashlib.c +msgid "a bytes-like object is required" +msgstr "ein Byte-ähnliches Objekt ist erforderlich" + +#: lib/embed/abort_.c +msgid "abort() called" +msgstr "abort() wurde aufgerufen" + +#: extmod/machine_mem.c +#, c-format +msgid "address %08x is not aligned to %d bytes" +msgstr "Addresse %08x ist nicht an %d bytes ausgerichtet" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "address out of bounds" +msgstr "Adresse außerhalb der Grenzen" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "addresses is empty" +msgstr "adresses ist leer" + +#: py/modbuiltins.c +msgid "arg is an empty sequence" +msgstr "arg ist eine leere Sequenz" + +#: py/runtime.c +msgid "argument has wrong type" +msgstr "Argument hat falschen Typ" + +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +msgid "argument num/types mismatch" +msgstr "Anzahl/Type der Argumente passen nicht" + +#: py/runtime.c +msgid "argument should be a '%q' not a '%q'" +msgstr "Argument sollte '%q' sein, nicht '%q'" + +#: py/objarray.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" +msgstr "Array/Bytes auf der rechten Seite erforderlich" + +#: py/objstr.c +msgid "attributes not supported yet" +msgstr "Attribute werden noch nicht unterstützt" + +#: py/builtinevex.c +msgid "bad compile mode" +msgstr "" + +#: py/objstr.c +msgid "bad conversion specifier" +msgstr "" + +#: py/objstr.c +msgid "bad format string" +msgstr "" + +#: py/binary.c +msgid "bad typecode" +msgstr "" + +#: py/emitnative.c +msgid "binary op %q not implemented" +msgstr "Der binäre Operator %q ist nicht implementiert" + +#: shared-bindings/busio/UART.c +msgid "bits must be 7, 8 or 9" +msgstr "bits muss 7, 8 oder 9 sein" + +#: extmod/machine_spi.c +msgid "bits must be 8" +msgstr "bits müssen 8 sein" + +#: shared-bindings/audiocore/Mixer.c +msgid "bits_per_sample must be 8 or 16" +msgstr "Es müssen 8 oder 16 bits_per_sample sein" + +#: py/emitinlinethumb.c +msgid "branch not in range" +msgstr "Zweig ist außerhalb der Reichweite" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "buf ist zu klein. brauche %d Bytes" + +#: shared-bindings/audiocore/RawSample.c +msgid "buffer must be a bytes-like object" +msgstr "Puffer muss ein bytes-artiges Objekt sein" + +#: shared-module/struct/__init__.c +msgid "buffer size must match format" +msgstr "Die Puffergröße muss zum Format passen" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" +msgstr "Puffersegmente müssen gleich lang sein" + +#: py/modstruct.c shared-bindings/struct/__init__.c +#: shared-module/struct/__init__.c +msgid "buffer too small" +msgstr "Der Puffer ist zu klein" + +#: extmod/machine_spi.c +msgid "buffers must be the same length" +msgstr "Buffer müssen gleich lang sein" + +#: shared-bindings/_pew/PewPew.c +msgid "buttons must be digitalio.DigitalInOut" +msgstr "" + +#: py/vm.c +msgid "byte code not implemented" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "bytes > 8 bits not supported" +msgstr "bytes mit mehr als 8 bits werden nicht unterstützt" + +#: py/objstr.c +msgid "bytes value out of range" +msgstr "" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" +msgstr "Kalibrierung ist außerhalb der Reichweite" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" +msgstr "Kalibrierung ist Schreibgeschützt" + +#: ports/atmel-samd/common-hal/rtc/RTC.c +msgid "calibration value out of range +/-127" +msgstr "Kalibrierwert nicht im Bereich von +/-127" + +#: py/emitinlinethumb.c +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "" + +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "kann nur bis zu 4 Parameter für die Xtensa assembly haben" + +#: py/persistentcode.c +msgid "can only save bytecode" +msgstr "kann nur Bytecode speichern" + +#: py/objtype.c +msgid "can't add special method to already-subclassed class" +msgstr "" + +#: py/compile.c +msgid "can't assign to expression" +msgstr "kann keinem Ausdruck zuweisen" + +#: py/obj.c +#, c-format +msgid "can't convert %s to complex" +msgstr "kann %s nicht nach complex konvertieren" + +#: py/obj.c +#, c-format +msgid "can't convert %s to float" +msgstr "kann %s nicht nach float konvertieren" + +#: py/obj.c +#, c-format +msgid "can't convert %s to int" +msgstr "kann %s nicht nach int konvertieren" + +#: py/objstr.c +msgid "can't convert '%q' object to %q implicitly" +msgstr "Kann '%q' Objekt nicht implizit nach %q konvertieren" + +#: py/objint.c +msgid "can't convert NaN to int" +msgstr "kann NaN nicht nach int konvertieren" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "can't convert address to int" +msgstr "kann Adresse nicht in int konvertieren" + +#: py/objint.c +msgid "can't convert inf to int" +msgstr "kann inf nicht nach int konvertieren" + +#: py/obj.c +msgid "can't convert to complex" +msgstr "kann nicht nach complex konvertieren" + +#: py/obj.c +msgid "can't convert to float" +msgstr "kann nicht nach float konvertieren" + +#: py/obj.c +msgid "can't convert to int" +msgstr "kann nicht nach int konvertieren" + +#: py/objstr.c +msgid "can't convert to str implicitly" +msgstr "Kann nicht implizit nach str konvertieren" + +#: py/compile.c +msgid "can't declare nonlocal in outer code" +msgstr "kann im äußeren Code nicht als nonlocal deklarieren" + +#: py/compile.c +msgid "can't delete expression" +msgstr "Ausdruck kann nicht gelöscht werden" + +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" +msgstr "Eine binäre Operation zwischen '%q' und '%q' ist nicht möglich" + +#: py/objcomplex.c +msgid "can't do truncated division of a complex number" +msgstr "kann mit einer komplexen Zahl keine abgeschnittene Division ausführen" + +#: py/compile.c +msgid "can't have multiple **x" +msgstr "mehrere **x sind nicht gestattet" + +#: py/compile.c +msgid "can't have multiple *x" +msgstr "mehrere *x sind nicht gestattet" + +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "Kann '%q' nicht implizit nach 'bool' konvertieren" + +#: py/emitnative.c +msgid "can't load from '%q'" +msgstr "Laden von '%q' nicht möglich" + +#: py/emitnative.c +msgid "can't load with '%q' index" +msgstr "" + +#: py/objgenerator.c +msgid "can't pend throw to just-started generator" +msgstr "" + +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" +msgstr "" + +#: py/objnamedtuple.c +msgid "can't set attribute" +msgstr "" + +#: py/emitnative.c +msgid "can't store '%q'" +msgstr "Speichern von '%q' nicht möglich" + +#: py/emitnative.c +msgid "can't store to '%q'" +msgstr "Speichern in/nach '%q' nicht möglich" + +#: py/emitnative.c +msgid "can't store with '%q' index" +msgstr "Speichern mit '%q' Index nicht möglich" + +#: py/objstr.c +msgid "" +"can't switch from automatic field numbering to manual field specification" +msgstr "" + +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "" + +#: py/objtype.c +msgid "cannot create '%q' instances" +msgstr "" + +#: py/objtype.c +msgid "cannot create instance" +msgstr "" + +#: py/runtime.c +msgid "cannot import name %q" +msgstr "Name %q kann nicht importiert werden" + +#: py/builtinimport.c +msgid "cannot perform relative import" +msgstr "kann keinen relativen Import durchführen" + +#: py/emitnative.c +msgid "casting" +msgstr "" + +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" +msgstr "" + +#: py/modbuiltins.c +msgid "chr() arg not in range(0x110000)" +msgstr "chr() arg ist nicht in range(0x110000)" + +#: py/modbuiltins.c +msgid "chr() arg not in range(256)" +msgstr "chr() arg ist nicht in range(256)" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer or int" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" +msgstr "" + +#: shared-bindings/displayio/ColorConverter.c +msgid "color should be an int" +msgstr "" + +#: py/objcomplex.c +msgid "complex division by zero" +msgstr "" + +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" +msgstr "" + +#: extmod/moduzlib.c +msgid "compression header" +msgstr "kompression header" + +#: py/parse.c +msgid "constant must be an integer" +msgstr "" + +#: py/emitnative.c +msgid "conversion to object" +msgstr "" + +#: py/parsenum.c +msgid "decimal numbers not supported" +msgstr "" + +#: py/compile.c +msgid "default 'except' must be last" +msgstr "Die Standart-Ausnahmebehandlung muss als letztes sein" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination_length must be an int >= 0" +msgstr "" + +#: py/objdict.c +msgid "dict update sequence has wrong length" +msgstr "" + +#: py/modmath.c py/objfloat.c py/objint_longlong.c py/objint_mpz.c py/runtime.c +#: shared-bindings/math/__init__.c +msgid "division by zero" +msgstr "Division durch Null" + +#: py/objdeque.c +msgid "empty" +msgstr "leer" + +#: extmod/moduheapq.c extmod/modutimeq.c +msgid "empty heap" +msgstr "leerer heap" + +#: py/objstr.c +msgid "empty separator" +msgstr "leeres Trennzeichen" + +#: shared-bindings/random/__init__.c +msgid "empty sequence" +msgstr "leere Sequenz" + +#: py/objstr.c +msgid "end of format while looking for conversion specifier" +msgstr "" + +#: shared-bindings/displayio/Shape.c +msgid "end_x should be an int" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +#, c-format +msgid "error = 0x%08lX" +msgstr "" + +#: py/runtime.c +msgid "exceptions must derive from BaseException" +msgstr "Exceptions müssen von BaseException abgeleitet sein" + +#: py/objstr.c +msgid "expected ':' after format specifier" +msgstr "erwarte ':' nach format specifier" + +#: py/obj.c +msgid "expected tuple/list" +msgstr "erwarte tuple/list" + +#: py/modthread.c +msgid "expecting a dict for keyword args" +msgstr "erwarte ein dict als Keyword-Argumente" + +#: py/compile.c +msgid "expecting an assembler instruction" +msgstr "erwartet eine Assembler-Anweisung" + +#: py/compile.c +msgid "expecting just a value for set" +msgstr "Erwarte nur einen Wert für set" + +#: py/compile.c +msgid "expecting key:value for dict" +msgstr "Erwarte key:value für dict" + +#: py/argcheck.c +msgid "extra keyword arguments given" +msgstr "Es wurden zusätzliche Keyword-Argumente angegeben" + +#: py/argcheck.c +msgid "extra positional arguments given" +msgstr "Es wurden zusätzliche Argumente ohne Keyword angegeben" + +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c +msgid "file must be a file opened in byte mode" +msgstr "Die Datei muss eine im Byte-Modus geöffnete Datei sein" + +#: shared-bindings/storage/__init__.c +msgid "filesystem must provide mount method" +msgstr "Das Dateisystem muss eine Mount-Methode bereitstellen" + +#: py/objtype.c +msgid "first argument to super() must be type" +msgstr "Das erste Argument für super() muss type sein" + +#: extmod/machine_spi.c +msgid "firstbit must be MSB" +msgstr "Erstes Bit muss das höchstwertigste Bit (MSB) sein" + +#: py/objint.c +msgid "float too big" +msgstr "float zu groß" + +#: shared-bindings/_stage/Text.c +msgid "font must be 2048 bytes long" +msgstr "Die Schriftart (font) muss 2048 Byte lang sein" + +#: py/objstr.c +msgid "format requires a dict" +msgstr "" + +#: py/objdeque.c +msgid "full" +msgstr "voll" + +#: py/argcheck.c +msgid "function does not take keyword arguments" +msgstr "Funktion akzeptiert keine Keyword-Argumente" + +#: py/argcheck.c +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "Funktion erwartet maximal %d Argumente, aber hat %d erhalten" + +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" +msgstr "Funktion hat mehrere Werte für Argument '%q'" + +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" +msgstr "Funktion vermisst %d benötigte Argumente ohne Keyword" + +#: py/bc.c +msgid "function missing keyword-only argument" +msgstr "Funktion vermisst Keyword-only-Argument" + +#: py/bc.c +msgid "function missing required keyword argument '%q'" +msgstr "Funktion vermisst benötigtes Keyword-Argumente '%q'" + +#: py/bc.c +#, c-format +msgid "function missing required positional argument #%d" +msgstr "Funktion vermisst benötigtes Argumente ohne Keyword #%d" + +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "" +"Funktion nimmt %d Argumente ohne Keyword an, aber es wurden %d angegeben" + +#: shared-bindings/time/__init__.c +msgid "function takes exactly 9 arguments" +msgstr "Funktion benötigt genau 9 Argumente" + +#: py/objgenerator.c +msgid "generator already executing" +msgstr "Generator läuft bereits" + +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" +msgstr "Generator ignoriert GeneratorExit" + +#: shared-bindings/_stage/Layer.c +msgid "graphic must be 2048 bytes long" +msgstr "graphic muss 2048 Byte lang sein" + +#: extmod/moduheapq.c +msgid "heap must be a list" +msgstr "heap muss eine Liste sein" + +#: py/compile.c +msgid "identifier redefined as global" +msgstr "Bezeichner als global neu definiert" + +#: py/compile.c +msgid "identifier redefined as nonlocal" +msgstr "Bezeichner als nonlocal definiert" + +#: py/objstr.c +msgid "incomplete format" +msgstr "unvollständiges Format" + +#: py/objstr.c +msgid "incomplete format key" +msgstr "unvollständiger Formatschlüssel" + +#: extmod/modubinascii.c +msgid "incorrect padding" +msgstr "padding ist inkorrekt" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c py/obj.c +msgid "index out of range" +msgstr "index außerhalb der Reichweite" + +#: py/obj.c +msgid "indices must be integers" +msgstr "Indizes müssen ganze Zahlen sein" + +#: py/compile.c +msgid "inline assembler must be a function" +msgstr "inline assembler muss eine function sein" + +#: py/parsenum.c +msgid "int() arg 2 must be >= 2 and <= 36" +msgstr "int() arg 2 muss >= 2 und <= 36 sein" + +#: py/objstr.c +msgid "integer required" +msgstr "integer erforderlich" + +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c +#, c-format +msgid "interval must be in range %s-%s" +msgstr "" + +#: extmod/machine_i2c.c +msgid "invalid I2C peripheral" +msgstr "ungültige I2C Schnittstelle" + +#: extmod/machine_spi.c +msgid "invalid SPI peripheral" +msgstr "ungültige SPI Schnittstelle" + +#: lib/netutils/netutils.c +msgid "invalid arguments" +msgstr "ungültige argumente" + +#: extmod/modussl_axtls.c +msgid "invalid cert" +msgstr "ungültiges cert" + +#: extmod/uos_dupterm.c +msgid "invalid dupterm index" +msgstr "ungültiger dupterm index" + +#: extmod/modframebuf.c +msgid "invalid format" +msgstr "ungültiges Format" + +#: py/objstr.c +msgid "invalid format specifier" +msgstr "ungültiger Formatbezeichner" + +#: extmod/modussl_axtls.c +msgid "invalid key" +msgstr "ungültiger Schlüssel" + +#: py/compile.c +msgid "invalid micropython decorator" +msgstr "ungültiger micropython decorator" + +#: shared-bindings/random/__init__.c +msgid "invalid step" +msgstr "ungültiger Schritt (step)" + +#: py/compile.c py/parse.c +msgid "invalid syntax" +msgstr "ungültige Syntax" + +#: py/parsenum.c +msgid "invalid syntax for integer" +msgstr "ungültige Syntax für integer" + +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "ungültige Syntax für integer mit Basis %d" + +#: py/parsenum.c +msgid "invalid syntax for number" +msgstr "ungültige Syntax für number" + +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" +msgstr "issubclass() arg 1 muss eine Klasse sein" + +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "issubclass() arg 2 muss eine Klasse oder ein Tupel von Klassen sein" + +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "" +"join erwartet eine Liste von str/bytes-Objekten, die mit dem self-Objekt " +"übereinstimmen" + +#: py/argcheck.c +msgid "keyword argument(s) not yet implemented - use normal args instead" +msgstr "" +"Keyword-Argument(e) noch nicht implementiert - verwenden Sie stattdessen " +"normale Argumente" + +#: py/bc.c +msgid "keywords must be strings" +msgstr "Schlüsselwörter müssen Zeichenfolgen sein" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" +msgstr "Label '%q' nicht definiert" + +#: py/compile.c +msgid "label redefined" +msgstr "Label neu definiert" + +#: py/stream.c +msgid "length argument not allowed for this type" +msgstr "Für diesen Typ ist length nicht zulässig" + +#: py/objarray.c +msgid "lhs and rhs should be compatible" +msgstr "lhs und rhs sollten kompatibel sein" + +#: py/emitnative.c +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "Lokales '%q' hat den Typ '%q', aber die Quelle ist '%q'" + +#: py/emitnative.c +msgid "local '%q' used before type known" +msgstr "Lokales '%q' verwendet bevor Typ bekannt" + +#: py/vm.c +msgid "local variable referenced before assignment" +msgstr "" +"Es wurde versucht auf eine Variable zuzugreifen, die es (noch) nicht gibt. " +"Variablen immer zuerst Zuweisen!" + +#: py/objint.c +msgid "long int not supported in this build" +msgstr "long int wird in diesem Build nicht unterstützt" + +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" +msgstr "map buffer zu klein" + +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + +#: py/runtime.c +msgid "maximum recursion depth exceeded" +msgstr "maximale Rekursionstiefe überschritten" + +#: py/runtime.c +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "Speicherzuordnung fehlgeschlagen, Zuweisung von %u Bytes" + +#: py/runtime.c +msgid "memory allocation failed, heap is locked" +msgstr "Speicherzuweisung fehlgeschlagen, der Heap ist gesperrt" + +#: py/builtinimport.c +msgid "module not found" +msgstr "Modul nicht gefunden" + +#: py/compile.c +msgid "multiple *x in assignment" +msgstr "mehrere *x in Zuordnung" + +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" +msgstr "" + +#: py/objtype.c +msgid "multiple inheritance not supported" +msgstr "" + +#: py/emitnative.c +msgid "must raise an object" +msgstr "" + +#: extmod/machine_spi.c +msgid "must specify all of sck/mosi/miso" +msgstr "sck/mosi/miso müssen alle spezifiziert sein" + +#: py/modbuiltins.c +msgid "must use keyword argument for key function" +msgstr "muss Schlüsselwortargument für key function verwenden" + +#: py/runtime.c +msgid "name '%q' is not defined" +msgstr "Name '%q' ist nirgends definiert worden (Schreibweise kontrollieren)" + +#: shared-bindings/_bleio/Peripheral.c +msgid "name must be a string" +msgstr "name muss ein String sein" + +#: py/runtime.c +msgid "name not defined" +msgstr "Dieser Name ist nirgends definiert worden (Schreibweise kontrollieren)" + +#: py/compile.c +msgid "name reused for argument" +msgstr "Name für Argumente wiederverwendet" + +#: py/emitnative.c +msgid "native yield" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "need more than %d values to unpack" +msgstr "" + +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" +msgstr "" + +#: py/objint_mpz.c py/runtime.c +msgid "negative shift count" +msgstr "" + +#: py/vm.c +msgid "no active exception to reraise" +msgstr "" + +#: shared-bindings/socket/__init__.c shared-module/network/__init__.c +msgid "no available NIC" +msgstr "" + +#: py/compile.c +msgid "no binding for nonlocal found" +msgstr "" + +#: py/builtinimport.c +msgid "no module named '%q'" +msgstr "Kein Modul mit dem Namen '%q'" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "no reset pin available" +msgstr "" + +#: py/runtime.c shared-bindings/_pixelbuf/__init__.c +msgid "no such attribute" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" +msgstr "" + +#: py/compile.c +msgid "non-default argument follows default argument" +msgstr "ein non-default argument folgt auf ein default argument" + +#: extmod/modubinascii.c +msgid "non-hex digit found" +msgstr "eine nicht-hex zahl wurde gefunden" + +#: py/compile.c +msgid "non-keyword arg after */**" +msgstr "" + +#: py/compile.c +msgid "non-keyword arg after keyword arg" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" +msgstr "keine 128-bit UUID" + +#: py/objstr.c +msgid "not all arguments converted during string formatting" +msgstr "" + +#: py/objstr.c +msgid "not enough arguments for format string" +msgstr "" + +#: py/obj.c +#, c-format +msgid "object '%s' is not a tuple or list" +msgstr "Objekt '%s' ist weder tupel noch list" + +#: py/obj.c +msgid "object does not support item assignment" +msgstr "Objekt unterstützt keine item assignment" + +#: py/obj.c +msgid "object does not support item deletion" +msgstr "Objekt unterstützt das Löschen von Elementen nicht" + +#: py/obj.c +msgid "object has no len" +msgstr "Objekt hat keine len" + +#: py/obj.c +msgid "object is not subscriptable" +msgstr "Objekt hat keine '__getitem__'-Methode (not subscriptable)" + +#: py/runtime.c +msgid "object not an iterator" +msgstr "Objekt ist kein Iterator" + +#: py/objtype.c py/runtime.c +msgid "object not callable" +msgstr "" + +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" +msgstr "Objekt ist nicht in sequence" + +#: py/runtime.c +msgid "object not iterable" +msgstr "Objekt nicht iterierbar" + +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" +msgstr "Objekt vom Typ '%s' hat keine len()" + +#: py/obj.c +msgid "object with buffer protocol required" +msgstr "Objekt mit Pufferprotokoll (buffer protocol) erforderlich" + +#: extmod/modubinascii.c +msgid "odd-length string" +msgstr "String mit ungerader Länge" + +#: py/objstr.c py/objstrunicode.c +msgid "offset out of bounds" +msgstr "offset außerhalb der Grenzen" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" +msgstr "" + +#: py/modbuiltins.c +msgid "ord expects a character" +msgstr "ord erwartet ein Zeichen" + +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "" +"ord() erwartet ein Zeichen aber es wurde eine Zeichenfolge mit Länge %d " +"gefunden" + +#: py/objint_mpz.c +msgid "overflow converting long int to machine word" +msgstr "" + +#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c +msgid "palette must be 32 bytes long" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "palette_index should be an int" +msgstr "" + +#: py/compile.c +msgid "parameter annotation must be an identifier" +msgstr "parameter annotation muss ein identifier sein" + +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" +msgstr "Die Parameter müssen Register der Reihenfolge a2 bis a5 sein" + +#: py/emitinlinethumb.c +msgid "parameters must be registers in sequence r0 to r3" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel coordinates out of bounds" +msgstr "Pixelkoordinaten außerhalb der Grenzen" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel value requires too many bits" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" +msgstr "pixel_shader muss displayio.Palette oder displayio.ColorConverter sein" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" +msgstr "pop von einem leeren PulseIn" + +#: py/objset.c +msgid "pop from an empty set" +msgstr "pop von einer leeren Menge (set)" + +#: py/objlist.c +msgid "pop from empty list" +msgstr "pop von einer leeren Liste" + +#: py/objdict.c +msgid "popitem(): dictionary is empty" +msgstr "popitem(): dictionary ist leer" + +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" +msgstr "pow() drittes Argument darf nicht 0 sein" + +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" +msgstr "" + +#: extmod/modutimeq.c +msgid "queue overflow" +msgstr "Warteschlangenüberlauf" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "rawbuf is not the same size as buf" +msgstr "rawbuf hat nicht die gleiche Größe wie buf" + +#: shared-bindings/_pixelbuf/__init__.c +msgid "readonly attribute" +msgstr "Readonly-Attribut" + +#: py/builtinimport.c +msgid "relative import" +msgstr "relativer Import" + +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" +msgstr "die ersuchte Länge ist %d, aber das Objekt hat eine Länge von %d" + +#: py/compile.c +msgid "return annotation must be an identifier" +msgstr "return annotation muss ein identifier sein" + +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" +msgstr "" + +#: py/objstr.c +msgid "rsplit(None,n)" +msgstr "" + +#: shared-bindings/audiocore/RawSample.c +msgid "" +"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " +"'B'" +msgstr "" +"sample_source buffer muss ein Bytearray oder ein Array vom Typ 'h', 'H', 'b' " +"oder 'B' sein" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" +msgstr "Abtastrate außerhalb der Reichweite" + +#: py/modmicropython.c +msgid "schedule stack full" +msgstr "Der schedule stack ist voll" + +#: lib/utils/pyexec.c py/builtinimport.c +msgid "script compilation not supported" +msgstr "kompilieren von Skripten ist nicht unterstützt" + +#: py/objstr.c +msgid "sign not allowed in string format specifier" +msgstr "" + +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" +msgstr "" + +#: py/objstr.c +msgid "single '}' encountered in format string" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "sleep length must be non-negative" +msgstr "" + +#: py/objslice.c py/sequence.c +msgid "slice step cannot be zero" +msgstr "" + +#: py/objint.c py/sequence.c +msgid "small int overflow" +msgstr "small int Überlauf" + +#: main.c +msgid "soft reboot\n" +msgstr "weicher reboot\n" + +#: py/objstr.c +msgid "start/end indices" +msgstr "" + +#: shared-bindings/displayio/Shape.c +msgid "start_x should be an int" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "step must be non-zero" +msgstr "Schritt (step) darf nicht Null sein" + +#: shared-bindings/busio/UART.c +msgid "stop must be 1 or 2" +msgstr "stop muss 1 oder 2 sein" + +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" +msgstr "stop ist von start aus nicht erreichbar" + +#: py/stream.c +msgid "stream operation not supported" +msgstr "stream operation ist nicht unterstützt" + +#: py/objstrunicode.c +msgid "string index out of range" +msgstr "" + +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" +msgstr "" + +#: py/stream.c +msgid "string not supported; use bytes or bytearray" +msgstr "" +"Zeichenfolgen werden nicht unterstützt; Verwenden Sie bytes oder bytearray" + +#: extmod/moductypes.c +msgid "struct: cannot index" +msgstr "struct: kann nicht indexieren" + +#: extmod/moductypes.c +msgid "struct: index out of range" +msgstr "struct: index außerhalb gültigen Bereichs" + +#: extmod/moductypes.c +msgid "struct: no fields" +msgstr "struct: keine Felder" + +#: py/objstr.c +msgid "substring not found" +msgstr "substring nicht gefunden" + +#: py/compile.c +msgid "super() can't find self" +msgstr "super() kann self nicht finden" + +#: extmod/modujson.c +msgid "syntax error in JSON" +msgstr "Syntaxfehler in JSON" + +#: extmod/moductypes.c +msgid "syntax error in uctypes descriptor" +msgstr "Syntaxfehler in uctypes Deskriptor" + +#: shared-bindings/touchio/TouchIn.c +msgid "threshold must be in the range 0-65536" +msgstr "threshold muss im Intervall 0-65536 liegen" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes a 9-sequence" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes exactly 1 argument" +msgstr "" + +#: shared-bindings/busio/UART.c +msgid "timeout >100 (units are now seconds, not msecs)" +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "timeout must be >= 0.0" +msgstr "timeout muss >= 0.0 sein" + +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" +msgstr "" + +#: shared-module/struct/__init__.c +msgid "too many arguments provided with the given format" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "" + +#: py/objstr.c +msgid "tuple index out of range" +msgstr "" + +#: py/obj.c +msgid "tuple/list has wrong length" +msgstr "tupel/list hat falsche Länge" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "tuple/list required on RHS" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "tx and rx cannot both be None" +msgstr "tx und rx können nicht beide None sein" + +#: py/objtype.c +msgid "type '%q' is not an acceptable base type" +msgstr "" + +#: py/objtype.c +msgid "type is not an acceptable base type" +msgstr "" + +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" +msgstr "" + +#: py/objtype.c +msgid "type takes 1 or 3 arguments" +msgstr "" + +#: py/objint_longlong.c +msgid "ulonglong too large" +msgstr "" + +#: py/emitnative.c +msgid "unary op %q not implemented" +msgstr "Der unäre Operator %q ist nicht implementiert" + +#: py/parse.c +msgid "unexpected indent" +msgstr "" +"unerwarteter Einzug (Einrückung) Bitte Leerzeichen am Zeilenanfang " +"kontrollieren!" + +#: py/bc.c +msgid "unexpected keyword argument" +msgstr "unerwartetes Keyword-Argument" + +#: py/bc.c py/objnamedtuple.c +msgid "unexpected keyword argument '%q'" +msgstr "unerwartetes Keyword-Argument '%q'" + +#: py/lexer.c +msgid "unicode name escapes" +msgstr "" + +#: py/parse.c +msgid "unindent does not match any outer indentation level" +msgstr "" +"Einrückung entspricht keiner äußeren Einrückungsebene. Bitte Leerzeichen am " +"Zeilenanfang kontrollieren!" + +#: py/objstr.c +#, c-format +msgid "unknown conversion specifier %c" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type '%s'" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'float'" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'str'" +msgstr "" + +#: py/compile.c +msgid "unknown type" +msgstr "unbekannter Typ" + +#: py/emitnative.c +msgid "unknown type '%q'" +msgstr "unbekannter Typ '%q'" + +#: py/objstr.c +msgid "unmatched '{' in format" +msgstr "" + +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" +msgstr "nicht lesbares Attribut" + +#: shared-bindings/displayio/TileGrid.c +msgid "unsupported %q type" +msgstr "Nicht unterstützter %q-Typ" + +#: py/emitinlinethumb.c +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "nicht unterstützter Thumb-Befehl '%s' mit %d Argumenten" + +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "" + +#: py/runtime.c +msgid "unsupported type for %q: '%s'" +msgstr "nicht unterstützter Type für %q: '%s'" + +#: py/runtime.c +msgid "unsupported type for operator" +msgstr "nicht unterstützter Typ für Operator" + +#: py/runtime.c +msgid "unsupported types for %q: '%s', '%s'" +msgstr "nicht unterstützte Typen für %q: '%s', '%s'" + +#: py/objint.c +#, c-format +msgid "value must fit in %d byte(s)" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "value_count must be > 0" +msgstr "" + +#: shared-bindings/_bleio/Scanner.c +msgid "window must be <= interval" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "write_args must be a list, tuple, or None" +msgstr "write_args muss eine Liste, ein Tupel oder None sein" + +#: py/objstr.c +msgid "wrong number of arguments" +msgstr "falsche Anzahl an Argumenten" + +#: py/runtime.c +msgid "wrong number of values to unpack" +msgstr "falsche Anzahl zu entpackender Werte" + +#: shared-module/displayio/Shape.c +msgid "x value out of bounds" +msgstr "x Wert außerhalb der Grenzen" + +#: shared-bindings/displayio/Shape.c +msgid "y should be an int" +msgstr "y sollte ein int sein" + +#: shared-module/displayio/Shape.c +msgid "y value out of bounds" +msgstr "y Wert außerhalb der Grenzen" + +#: py/objrange.c +msgid "zero step" +msgstr "" + +#~ msgid "AP required" +#~ msgstr "AP erforderlich" + +#~ msgid "Address is not %d bytes long or is in wrong format" +#~ msgstr "Die Adresse ist nicht %d Bytes lang oder das Format ist falsch" + +#~ msgid "C-level assert" +#~ msgstr "C-Level Assert" + +#~ msgid "Can't add services in Central mode" +#~ msgstr "Im Central mode können Dienste nicht hinzugefügt werden" + +#~ msgid "Can't advertise in Central mode" +#~ msgstr "Im Central mode kann advertise nicht gemacht werden" + +#~ msgid "Can't change the name in Central mode" +#~ msgstr "Im Central mode kann name nicht geändert werden" + +#~ msgid "Can't connect in Peripheral mode" +#~ msgstr "Im Peripheral mode kann keine Verbindung hergestellt werden" + +#~ msgid "Cannot connect to AP" +#~ msgstr "Kann nicht zu AP verbinden" + +#~ msgid "Cannot disconnect from AP" +#~ msgstr "Kann nicht trennen von AP" + +#~ msgid "Cannot set STA config" +#~ msgstr "Kann STA Konfiguration nicht setzen" + +#~ msgid "Cannot update i/f status" +#~ msgstr "Kann i/f Status nicht updaten" + +#~ msgid "Characteristic UUID doesn't match Service UUID" +#~ msgstr "Characteristic UUID stimmt nicht mit der Service-UUID überein" + +#~ msgid "Characteristic already in use by another Service." +#~ msgstr "Characteristic wird bereits von einem anderen Dienst verwendet." + +#~ msgid "Data too large for the advertisement packet" +#~ msgstr "Daten sind zu groß für das advertisement packet" + +#~ msgid "Don't know how to pass object to native function" +#~ msgstr "" +#~ "Ich weiß nicht, wie man das Objekt an die native Funktion übergeben kann" + +#~ msgid "ESP8226 does not support safe mode." +#~ msgstr "ESP8226 hat keinen Sicherheitsmodus" + +#~ msgid "ESP8266 does not support pull down." +#~ msgstr "ESP8266 unterstützt pull down nicht" + +#~ msgid "Error in ffi_prep_cif" +#~ msgstr "Fehler in ffi_prep_cif" + +#~ msgid "Failed to acquire mutex" +#~ msgstr "Akquirieren des Mutex gescheitert" + +#~ msgid "Failed to add service" +#~ msgstr "Dienst konnte nicht hinzugefügt werden" + +#~ msgid "Failed to connect:" +#~ msgstr "Verbindung fehlgeschlagen:" + +#~ msgid "Failed to continue scanning" +#~ msgstr "Der Scanvorgang kann nicht fortgesetzt werden" + +#~ msgid "Failed to create mutex" +#~ msgstr "Erstellen des Mutex ist fehlgeschlagen" + +#~ msgid "Failed to notify or indicate attribute value, err %0x04x" +#~ msgstr "Kann den Attributwert nicht mitteilen. Status: 0x%04x" + +#~ msgid "Failed to read attribute value, err %0x04x" +#~ msgstr "Kann den Attributwert nicht lesen. Status: 0x%04x" + +#~ msgid "Failed to release mutex" +#~ msgstr "Loslassen des Mutex gescheitert" + +#~ msgid "Failed to start advertising" +#~ msgstr "Kann advertisement nicht starten" + +#~ msgid "Failed to start scanning" +#~ msgstr "Der Scanvorgang kann nicht gestartet werden" + +#~ msgid "Failed to stop advertising" +#~ msgstr "Kann advertisement nicht stoppen" + +#~ msgid "Function requires lock." +#~ msgstr "" +#~ "Die Funktion erwartet, dass der 'lock'-Befehl zuvor ausgeführt wurde" + +#~ msgid "GPIO16 does not support pull up." +#~ msgstr "GPIO16 unterstützt pull up nicht" + +#~ msgid "Invalid bit clock pin" +#~ msgstr "Ungültiges bit clock pin" + +#~ msgid "Invalid clock pin" +#~ msgstr "Ungültiger clock pin" + +#~ msgid "Invalid data pin" +#~ msgstr "Ungültiger data pin" + +#~ msgid "Maximum PWM frequency is %dhz." +#~ msgstr "Maximale PWM Frequenz ist %dHz" + +#~ msgid "Minimum PWM frequency is 1hz." +#~ msgstr "Minimale PWM Frequenz ist %dHz" + +#~ msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." +#~ msgstr "" +#~ "Mehrere PWM Frequenzen werden nicht unterstützt. PWM wurde bereits auf " +#~ "%dHz gesetzt." + +#~ msgid "No PulseIn support for %q" +#~ msgstr "Keine PulseIn Unterstützung für %q" + +#~ msgid "No hardware support for analog out." +#~ msgstr "Keine Hardwareunterstützung für analog out" + +#~ msgid "Not connected." +#~ msgstr "Nicht verbunden." + +#~ msgid "Only Windows format, uncompressed BMP supported %d" +#~ msgstr "Nur unkomprimiertes Windows-Format (BMP) unterstützt %d" + +#~ msgid "Only bit maps of 8 bit color or less are supported" +#~ msgstr "" +#~ "Es werden nur Bitmaps mit einer Farbtiefe von 8 Bit oder weniger " +#~ "unterstützt" + +#~ msgid "Only tx supported on UART1 (GPIO2)." +#~ msgstr "UART1 (GPIO2) unterstützt nur tx" + +#~ msgid "PWM not supported on pin %d" +#~ msgstr "PWM nicht unterstützt an Pin %d" + +#~ msgid "Pin %q does not have ADC capabilities" +#~ msgstr "Pin %q hat keine ADC Funktion" + +#~ msgid "Pin(16) doesn't support pull" +#~ msgstr "Pin(16) unterstützt kein pull" + +#~ msgid "Pins not valid for SPI" +#~ msgstr "Pins nicht gültig für SPI" + +#~ msgid "STA must be active" +#~ msgstr "STA muss aktiv sein" + +#~ msgid "STA required" +#~ msgstr "STA erforderlich" + +#~ msgid "UART(%d) does not exist" +#~ msgstr "UART(%d) existiert nicht" + +#~ msgid "UART(1) can't read" +#~ msgstr "UART(1) kann nicht lesen" + +#~ msgid "UUID integer value not in range 0 to 0xffff" +#~ msgstr "UUID-Integer nicht im Bereich 0 bis 0xffff" + +#~ msgid "Unable to remount filesystem" +#~ msgstr "Dateisystem konnte nicht wieder eingebunden werden." + +#~ msgid "Unknown type" +#~ msgstr "Unbekannter Typ" + +#~ msgid "Use esptool to erase flash and re-upload Python instead" +#~ msgstr "" +#~ "Benutze das esptool um den flash zu löschen und Python erneut hochzuladen" + +#~ msgid "buffer too long" +#~ msgstr "Buffer zu lang" + +#~ msgid "expected a DigitalInOut" +#~ msgstr "erwarte DigitalInOut" + +#~ msgid "expecting a pin" +#~ msgstr "Ein Pin wird erwartet" + +#~ msgid "ffi_prep_closure_loc" +#~ msgstr "ffi_prep_closure_loc" + +#~ msgid "flash location must be below 1MByte" +#~ msgstr "flash location muss unter 1MByte sein" + +#~ msgid "frequency can only be either 80Mhz or 160MHz" +#~ msgstr "Die Frequenz kann nur 80Mhz oder 160Mhz sein" + +#~ msgid "impossible baudrate" +#~ msgstr "Unmögliche Baudrate" + +#~ msgid "interval not in range 0.0020 to 10.24" +#~ msgstr "Das Interval ist nicht im Bereich 0.0020 bis 10.24" + +#~ msgid "invalid alarm" +#~ msgstr "ungültiger Alarm" + +#~ msgid "invalid buffer length" +#~ msgstr "ungültige Pufferlänge" + +#~ msgid "invalid data bits" +#~ msgstr "ungültige Datenbits" + +#~ msgid "invalid pin" +#~ msgstr "ungültiger Pin" + +#~ msgid "invalid stop bits" +#~ msgstr "ungültige Stopbits" + +#~ msgid "len must be multiple of 4" +#~ msgstr "len muss ein vielfaches von 4 sein" + +#~ msgid "memory allocation failed, allocating %u bytes for native code" +#~ msgstr "" +#~ "Speicherallozierung fehlgeschlagen, alloziere %u Bytes für nativen Code" + +#~ msgid "not a valid ADC Channel: %d" +#~ msgstr "Kein gültiger ADC Kanal: %d" + +#~ msgid "pin does not have IRQ capabilities" +#~ msgstr "Pin hat keine IRQ Fähigkeiten" + +#~ msgid "scan failed" +#~ msgstr "Scan fehlgeschlagen" + +#~ msgid "too many arguments" +#~ msgstr "zu viele Argumente" + +#~ msgid "unknown status param" +#~ msgstr "Unbekannter Statusparameter" + +#~ msgid "wifi_set_ip_info() failed" +#~ msgstr "wifi_set_ip_info() fehlgeschlagen" diff --git a/locale/en_US.po b/locale/en_US.po new file mode 100644 index 00000000000..e5425cbfc9d --- /dev/null +++ b/locale/en_US.po @@ -0,0 +1,2688 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"PO-Revision-Date: 2018-07-27 11:55-0700\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.1.1\n" + +#: main.c +msgid "" +"\n" +"Code done running. Waiting for reload.\n" +msgstr "" + +#: py/obj.c +msgid " File \"%q\"" +msgstr "" + +#: py/obj.c +msgid " File \"%q\", line %d" +msgstr "" + +#: main.c +msgid " output:\n" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "%%c requires int or char" +msgstr "" + +#: shared-bindings/microcontroller/Pin.c +msgid "%q in use" +msgstr "" + +#: py/obj.c +msgid "%q index out of range" +msgstr "" + +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c +msgid "%q must be >= 1" +msgstr "" + +#: shared-bindings/fontio/BuiltinFont.c +msgid "%q should be an int" +msgstr "" + +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" +msgstr "" + +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" +msgstr "" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects a special register" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an FPU register" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects at most r%d" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "" + +#: py/emitinlinextensa.c +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item assignment" +msgstr "" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item deletion" +msgstr "" + +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not an iterator" +msgstr "" + +#: py/objtype.c py/runtime.c +#, c-format +msgid "'%s' object is not callable" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not iterable" +msgstr "" + +#: py/obj.c +#, c-format +msgid "'%s' object is not subscriptable" +msgstr "" + +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" +msgstr "" + +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" +msgstr "" + +#: py/compile.c +msgid "'align' requires 1 argument" +msgstr "" + +#: py/compile.c +msgid "'await' outside function" +msgstr "" + +#: py/compile.c +msgid "'break' outside loop" +msgstr "" + +#: py/compile.c +msgid "'continue' outside loop" +msgstr "" + +#: py/compile.c +msgid "'data' requires at least 2 arguments" +msgstr "" + +#: py/compile.c +msgid "'data' requires integer arguments" +msgstr "" + +#: py/compile.c +msgid "'label' requires 1 argument" +msgstr "" + +#: py/compile.c +msgid "'return' outside function" +msgstr "" + +#: py/compile.c +msgid "'yield' outside function" +msgstr "" + +#: py/compile.c +msgid "*x must be assignment target" +msgstr "" + +#: py/obj.c +msgid ", in %q\n" +msgstr "" + +#: py/objcomplex.c +msgid "0.0 to a complex power" +msgstr "" + +#: py/modbuiltins.c +msgid "3-arg pow() not supported" +msgstr "" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "A hardware interrupt channel is already in use" +msgstr "" + +#: shared-bindings/_bleio/Address.c +#, c-format +msgid "Address must be %d bytes long" +msgstr "" + +#: shared-bindings/_bleio/Address.c +msgid "Address type out of range" +msgstr "" + +#: ports/nrf/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" +msgstr "" + +#: ports/nrf/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +msgid "All UART peripherals are in use" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "" + +#: ports/atmel-samd/audio_dma.c ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "All sync event channels in use" +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c +msgid "All timers for this pin are in use" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: shared-module/_pew/PewPew.c +msgid "All timers in use" +msgstr "" + +#: ports/nrf/common-hal/analogio/AnalogOut.c +msgid "AnalogOut functionality not supported" +msgstr "" + +#: shared-bindings/analogio/AnalogOut.c +msgid "AnalogOut is only 16 bits. Value must be less than 65536." +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "AnalogOut not supported on given pin" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" +msgstr "" + +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "Attempted heap allocation when MicroPython VM not running.\n" +msgstr "" + +#: main.c +msgid "Auto-reload is off.\n" +msgstr "" + +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "" + +#: shared-module/displayio/Display.c +msgid "Below minimum frame rate" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Bit clock and word select must share a clock unit" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Bit depth must be multiple of 8." +msgstr "" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "Both pins must support hardware interrupts" +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Brightness must be 0-1.0" +msgstr "" + +#: shared-bindings/supervisor/__init__.c +msgid "Brightness must be between 0 and 255" +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Brightness not adjustable" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Buffer is not a bytearray." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Buffer is too small" +msgstr "" + +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Buffer length %d too big. It must be less than %d" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c +msgid "Buffer must be at least length 1" +msgstr "" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +#, c-format +msgid "Bus pin %d is already in use" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "Byte buffer must be 16 bytes." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Bytes must be between 0 and 255." +msgstr "" + +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Can not use dotstar with %s" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" +msgstr "" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/nrf/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "" + +#: ports/nrf/common-hal/microcontroller/Processor.c +msgid "Cannot get temperature" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Cannot output both channels on the same pin" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot read without MISO pin." +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Cannot record to a file" +msgstr "" + +#: shared-module/storage/__init__.c +msgid "Cannot remount '/' when USB is active." +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +msgid "Cannot reset into bootloader because no bootloader is present." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Cannot set value when direction is input." +msgstr "" + +#: py/objslice.c +msgid "Cannot subclass slice" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot transfer without MOSI and MISO pins." +msgstr "" + +#: extmod/moductypes.c +msgid "Cannot unambiguously get sizeof scalar" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot write without MOSI pin." +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Clock pin init failed." +msgstr "" + +#: shared-module/bitbangio/I2C.c +msgid "Clock stretch too long" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" +msgstr "" + +#: shared-bindings/_pew/PewPew.c +msgid "Column entry must be digitalio.DigitalInOut" +msgstr "" + +#: shared-bindings/displayio/I2CDisplay.c +msgid "Command must be 0-255" +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +msgid "Command must be an int between 0 and 255" +msgstr "" + +#: py/persistentcode.c +msgid "Corrupt .mpy file" +msgstr "" + +#: py/emitglue.c +msgid "Corrupt raw code" +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "Could not initialize UART" +msgstr "" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate first buffer" +msgstr "" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate second buffer" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "Crash into the HardFault_Handler.\n" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "DAC already in use" +msgstr "" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +msgid "Data 0 pin must be byte aligned" +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Data chunk must follow fmt chunk" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Data too large for advertisement packet" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Destination capacity is smaller than destination_length." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Display must have a 16 bit colorspace." +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Display rotation must be in 90 degree increments" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Drive mode not used when direction is input." +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "EXTINT channel already in use" +msgstr "" + +#: extmod/modure.c +msgid "Error in regex" +msgstr "" + +#: shared-bindings/microcontroller/Pin.c +#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c +#: shared-bindings/terminalio/Terminal.c +msgid "Expected a %q" +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c +msgid "Expected a Characteristic" +msgstr "" + +#: shared-bindings/_bleio/Service.c +msgid "Expected a Peripheral" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Expected a Service" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c +#: shared-bindings/_bleio/Service.c +msgid "Expected a UUID" +msgstr "" + +#: shared-bindings/_bleio/Central.c +msgid "Expected an Address" +msgstr "" + +#: shared-module/_pixelbuf/PixelBuf.c +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "" + +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + +#: ports/nrf/sd_mutex.c +#, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Service.c +#, c-format +msgid "Failed to add characteristic, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to add descriptor, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to add service, err 0x%04x" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "Failed to allocate RX buffer" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +#, c-format +msgid "Failed to allocate RX buffer of %d bytes" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to change softdevice state" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to configure advertising, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Central.c +msgid "Failed to connect: timeout" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, c-format +msgid "Failed to continue scanning, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "Failed to discover services" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to get local address" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to get softdevice state" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to notify or indicate attribute value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "Failed to read attribute value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to read gatts value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" +msgstr "" + +#: ports/nrf/sd_mutex.c +#, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to set device name, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Central.c +#, c-format +msgid "Failed to start connecting, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, c-format +msgid "Failed to start scanning, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to write CCCD, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to write attribute value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to write gatts value, err 0x%04x" +msgstr "" + +#: py/moduerrno.c +msgid "File exists" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash erase failed" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash erase failed to start, err 0x%04x" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash write failed" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash write failed to start, err 0x%04x" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Frequency captured is above capability. Capture Paused." +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c +msgid "Function requires lock" +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Group already used" +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Group full" +msgstr "" + +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" +msgstr "" + +#: extmod/machine_i2c.c +msgid "I2C operation not supported" +msgstr "" + +#: py/persistentcode.c +msgid "" +"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" +"mpy-update for more info." +msgstr "" + +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" +msgstr "" + +#: py/moduerrno.c +msgid "Input/output error" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Invalid %q pin" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Invalid BMP file" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c +#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c +msgid "Invalid PWM frequency" +msgstr "" + +#: py/moduerrno.c +msgid "Invalid argument" +msgstr "" + +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +msgid "Invalid buffer size" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Invalid capture period. Valid range: 1 - 500" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid channel count" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Invalid direction." +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid file" +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid number of bits" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid phase" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +#: shared-bindings/pulseio/PWMOut.c +msgid "Invalid pin" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for left channel" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for right channel" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/atmel-samd/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c +#: ports/nrf/common-hal/busio/I2C.c +msgid "Invalid pins" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid polarity" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + +#: shared-bindings/microcontroller/__init__.c +msgid "Invalid run mode." +msgstr "" + +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid voice count" +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid wave file" +msgstr "" + +#: py/compile.c +msgid "LHS of keyword arg must be an id" +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass." +msgstr "" + +#: py/objslice.c +msgid "Length must be an int" +msgstr "" + +#: py/objslice.c +msgid "Length must be non-negative" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Looks like our core CircuitPython code crashed hard. Whoops!\n" +"Please file an issue at https://github.com/adafruit/circuitpython/issues\n" +" with the contents of your CIRCUITPY drive and this message:\n" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "MISO pin init failed." +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "MOSI pin init failed." +msgstr "" + +#: shared-module/displayio/Shape.c +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython NLR jump failed. Likely memory corruption.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython fatal error.\n" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Microphone startup delay must be in range 0.0 to 1.0" +msgstr "" + +#: shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "No DAC on chip" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "No DMA channel found" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No RX pin" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No TX pin" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "No available clocks" +msgstr "" + +#: shared-bindings/board/__init__.c +msgid "No default %q bus" +msgstr "" + +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" +msgstr "" + +#: shared-bindings/os/__init__.c +msgid "No hardware random available" +msgstr "" + +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "No hardware support on pin" +msgstr "" + +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" +msgstr "" + +#: py/moduerrno.c +msgid "No space left on device" +msgstr "" + +#: py/moduerrno.c +msgid "No such file/directory" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Peripheral.c +msgid "Not connected" +msgstr "" + +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c +msgid "Not playing" +msgstr "" + +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +msgid "Odd parity is not supported" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Only 8 or 16 bit mono with " +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Only slices with step=1 (aka None) are supported" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Oversample must be multiple of 8." +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM frequency not writable when variable_frequency is False on construction." +msgstr "" + +#: py/moduerrno.c +msgid "Permission denied" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogIn.c +#: ports/nrf/common-hal/analogio/AnalogIn.c +msgid "Pin does not have ADC capabilities" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Pixel beyond bounds of buffer" +msgstr "" + +#: py/builtinhelp.c +msgid "Plus any modules on the filesystem\n" +msgstr "" + +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Pull not used when direction is output." +msgstr "" + +#: ports/nrf/common-hal/rtc/RTC.c +msgid "RTC calibration is not supported on this board" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Range out of bounds" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c +msgid "Read-only" +msgstr "" + +#: extmod/vfs_fat.c py/moduerrno.c +msgid "Read-only filesystem" +msgstr "" + +#: shared-module/displayio/Bitmap.c +msgid "Read-only object" +msgstr "" + +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Refresh too soon" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" +msgstr "" + +#: shared-bindings/_pew/PewPew.c +msgid "Row entry must be digitalio.DigitalInOut" +msgstr "" + +#: main.c +msgid "Running in safe mode! Auto-reload is off.\n" +msgstr "" + +#: main.c +msgid "Running in safe mode! Not running saved code.\n" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "SDA or SCL needs a pull up" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Sample rate must be positive" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Sample rate too high. It must be less than %d" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/pulseio/PulseIn.c +msgid "Slices not supported" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: extmod/modure.c +msgid "Splitting with sub-captures" +msgstr "" + +#: shared-bindings/supervisor/__init__.c +msgid "Stack size must be at least 256" +msgstr "" + +#: shared-bindings/multiterminal/__init__.c +msgid "Stream missing readinto() or write() method." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The CircuitPython heap was corrupted because the stack was too small.\n" +"Please increase stack size limits and press reset (after ejecting " +"CIRCUITPY).\n" +"If you didn't change the stack, then file an issue here with the contents of " +"your CIRCUITPY drive:\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The `microcontroller` module was used to boot into safe mode. Press reset to " +"exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The reset button was pressed while booting CircuitPython. Press again to " +"exit safe mode.\n" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's signedness does not match the mixer's" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile value out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample." +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "Too many display busses" +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Too many displays" +msgstr "" + +#: py/obj.c +msgid "Traceback (most recent call last):\n" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "Tuple or struct_time argument required" +msgstr "" + +#: shared-module/usb_hid/Device.c +msgid "USB Busy" +msgstr "" + +#: shared-module/usb_hid/Device.c +msgid "USB Error" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID integer value must be 0-0xffff" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Unable to allocate buffers for signed conversion" +msgstr "" + +#: shared-module/displayio/I2CDisplay.c +#, c-format +msgid "Unable to find I2C Display at %x" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Unable to find free GCLK" +msgstr "" + +#: py/parse.c +msgid "Unable to init parser" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +msgid "Unexpected nrfx uuid type" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "Unsupported baudrate" +msgstr "" + +#: shared-module/displayio/display_core.c +msgid "Unsupported display bus type" +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Unsupported format" +msgstr "" + +#: py/moduerrno.c +msgid "Unsupported operation" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Unsupported pull value." +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + +#: py/emitnative.c +msgid "Viper functions don't currently support more than 4 arguments" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "Voice index too high" +msgstr "" + +#: main.c +msgid "WARNING: Your code filename has two extensions\n" +msgstr "" + +#: py/builtinhelp.c +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"You are running in safe mode which means something unanticipated happened.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "You requested starting safe mode by " +msgstr "" + +#: py/objtype.c +msgid "__init__() should return None" +msgstr "" + +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "" + +#: py/objobject.c +msgid "__new__ arg must be a user-type" +msgstr "" + +#: extmod/modubinascii.c extmod/moduhashlib.c +msgid "a bytes-like object is required" +msgstr "" + +#: lib/embed/abort_.c +msgid "abort() called" +msgstr "" + +#: extmod/machine_mem.c +#, c-format +msgid "address %08x is not aligned to %d bytes" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "address out of bounds" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "addresses is empty" +msgstr "" + +#: py/modbuiltins.c +msgid "arg is an empty sequence" +msgstr "" + +#: py/runtime.c +msgid "argument has wrong type" +msgstr "" + +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +msgid "argument num/types mismatch" +msgstr "" + +#: py/runtime.c +msgid "argument should be a '%q' not a '%q'" +msgstr "" + +#: py/objarray.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" +msgstr "" + +#: py/objstr.c +msgid "attributes not supported yet" +msgstr "" + +#: py/builtinevex.c +msgid "bad compile mode" +msgstr "" + +#: py/objstr.c +msgid "bad conversion specifier" +msgstr "" + +#: py/objstr.c +msgid "bad format string" +msgstr "" + +#: py/binary.c +msgid "bad typecode" +msgstr "" + +#: py/emitnative.c +msgid "binary op %q not implemented" +msgstr "" + +#: shared-bindings/busio/UART.c +msgid "bits must be 7, 8 or 9" +msgstr "" + +#: extmod/machine_spi.c +msgid "bits must be 8" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "bits_per_sample must be 8 or 16" +msgstr "" + +#: py/emitinlinethumb.c +msgid "branch not in range" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "" + +#: shared-bindings/audiocore/RawSample.c +msgid "buffer must be a bytes-like object" +msgstr "" + +#: shared-module/struct/__init__.c +msgid "buffer size must match format" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" +msgstr "" + +#: py/modstruct.c shared-bindings/struct/__init__.c +#: shared-module/struct/__init__.c +msgid "buffer too small" +msgstr "" + +#: extmod/machine_spi.c +msgid "buffers must be the same length" +msgstr "" + +#: shared-bindings/_pew/PewPew.c +msgid "buttons must be digitalio.DigitalInOut" +msgstr "" + +#: py/vm.c +msgid "byte code not implemented" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "bytes > 8 bits not supported" +msgstr "" + +#: py/objstr.c +msgid "bytes value out of range" +msgstr "" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" +msgstr "" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" +msgstr "" + +#: ports/atmel-samd/common-hal/rtc/RTC.c +msgid "calibration value out of range +/-127" +msgstr "" + +#: py/emitinlinethumb.c +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "" + +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "" + +#: py/persistentcode.c +msgid "can only save bytecode" +msgstr "" + +#: py/objtype.c +msgid "can't add special method to already-subclassed class" +msgstr "" + +#: py/compile.c +msgid "can't assign to expression" +msgstr "" + +#: py/obj.c +#, c-format +msgid "can't convert %s to complex" +msgstr "" + +#: py/obj.c +#, c-format +msgid "can't convert %s to float" +msgstr "" + +#: py/obj.c +#, c-format +msgid "can't convert %s to int" +msgstr "" + +#: py/objstr.c +msgid "can't convert '%q' object to %q implicitly" +msgstr "" + +#: py/objint.c +msgid "can't convert NaN to int" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "can't convert address to int" +msgstr "" + +#: py/objint.c +msgid "can't convert inf to int" +msgstr "" + +#: py/obj.c +msgid "can't convert to complex" +msgstr "" + +#: py/obj.c +msgid "can't convert to float" +msgstr "" + +#: py/obj.c +msgid "can't convert to int" +msgstr "" + +#: py/objstr.c +msgid "can't convert to str implicitly" +msgstr "" + +#: py/compile.c +msgid "can't declare nonlocal in outer code" +msgstr "" + +#: py/compile.c +msgid "can't delete expression" +msgstr "" + +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" +msgstr "" + +#: py/objcomplex.c +msgid "can't do truncated division of a complex number" +msgstr "" + +#: py/compile.c +msgid "can't have multiple **x" +msgstr "" + +#: py/compile.c +msgid "can't have multiple *x" +msgstr "" + +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "" + +#: py/emitnative.c +msgid "can't load from '%q'" +msgstr "" + +#: py/emitnative.c +msgid "can't load with '%q' index" +msgstr "" + +#: py/objgenerator.c +msgid "can't pend throw to just-started generator" +msgstr "" + +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" +msgstr "" + +#: py/objnamedtuple.c +msgid "can't set attribute" +msgstr "" + +#: py/emitnative.c +msgid "can't store '%q'" +msgstr "" + +#: py/emitnative.c +msgid "can't store to '%q'" +msgstr "" + +#: py/emitnative.c +msgid "can't store with '%q' index" +msgstr "" + +#: py/objstr.c +msgid "" +"can't switch from automatic field numbering to manual field specification" +msgstr "" + +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "" + +#: py/objtype.c +msgid "cannot create '%q' instances" +msgstr "" + +#: py/objtype.c +msgid "cannot create instance" +msgstr "" + +#: py/runtime.c +msgid "cannot import name %q" +msgstr "" + +#: py/builtinimport.c +msgid "cannot perform relative import" +msgstr "" + +#: py/emitnative.c +msgid "casting" +msgstr "" + +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" +msgstr "" + +#: py/modbuiltins.c +msgid "chr() arg not in range(0x110000)" +msgstr "" + +#: py/modbuiltins.c +msgid "chr() arg not in range(256)" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer or int" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" +msgstr "" + +#: shared-bindings/displayio/ColorConverter.c +msgid "color should be an int" +msgstr "" + +#: py/objcomplex.c +msgid "complex division by zero" +msgstr "" + +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" +msgstr "" + +#: extmod/moduzlib.c +msgid "compression header" +msgstr "" + +#: py/parse.c +msgid "constant must be an integer" +msgstr "" + +#: py/emitnative.c +msgid "conversion to object" +msgstr "" + +#: py/parsenum.c +msgid "decimal numbers not supported" +msgstr "" + +#: py/compile.c +msgid "default 'except' must be last" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination_length must be an int >= 0" +msgstr "" + +#: py/objdict.c +msgid "dict update sequence has wrong length" +msgstr "" + +#: py/modmath.c py/objfloat.c py/objint_longlong.c py/objint_mpz.c py/runtime.c +#: shared-bindings/math/__init__.c +msgid "division by zero" +msgstr "" + +#: py/objdeque.c +msgid "empty" +msgstr "" + +#: extmod/moduheapq.c extmod/modutimeq.c +msgid "empty heap" +msgstr "" + +#: py/objstr.c +msgid "empty separator" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "empty sequence" +msgstr "" + +#: py/objstr.c +msgid "end of format while looking for conversion specifier" +msgstr "" + +#: shared-bindings/displayio/Shape.c +msgid "end_x should be an int" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +#, c-format +msgid "error = 0x%08lX" +msgstr "" + +#: py/runtime.c +msgid "exceptions must derive from BaseException" +msgstr "" + +#: py/objstr.c +msgid "expected ':' after format specifier" +msgstr "" + +#: py/obj.c +msgid "expected tuple/list" +msgstr "" + +#: py/modthread.c +msgid "expecting a dict for keyword args" +msgstr "" + +#: py/compile.c +msgid "expecting an assembler instruction" +msgstr "" + +#: py/compile.c +msgid "expecting just a value for set" +msgstr "" + +#: py/compile.c +msgid "expecting key:value for dict" +msgstr "" + +#: py/argcheck.c +msgid "extra keyword arguments given" +msgstr "" + +#: py/argcheck.c +msgid "extra positional arguments given" +msgstr "" + +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c +msgid "file must be a file opened in byte mode" +msgstr "" + +#: shared-bindings/storage/__init__.c +msgid "filesystem must provide mount method" +msgstr "" + +#: py/objtype.c +msgid "first argument to super() must be type" +msgstr "" + +#: extmod/machine_spi.c +msgid "firstbit must be MSB" +msgstr "" + +#: py/objint.c +msgid "float too big" +msgstr "" + +#: shared-bindings/_stage/Text.c +msgid "font must be 2048 bytes long" +msgstr "" + +#: py/objstr.c +msgid "format requires a dict" +msgstr "" + +#: py/objdeque.c +msgid "full" +msgstr "" + +#: py/argcheck.c +msgid "function does not take keyword arguments" +msgstr "" + +#: py/argcheck.c +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "" + +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" +msgstr "" + +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" +msgstr "" + +#: py/bc.c +msgid "function missing keyword-only argument" +msgstr "" + +#: py/bc.c +msgid "function missing required keyword argument '%q'" +msgstr "" + +#: py/bc.c +#, c-format +msgid "function missing required positional argument #%d" +msgstr "" + +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "function takes exactly 9 arguments" +msgstr "" + +#: py/objgenerator.c +msgid "generator already executing" +msgstr "" + +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" +msgstr "" + +#: shared-bindings/_stage/Layer.c +msgid "graphic must be 2048 bytes long" +msgstr "" + +#: extmod/moduheapq.c +msgid "heap must be a list" +msgstr "" + +#: py/compile.c +msgid "identifier redefined as global" +msgstr "" + +#: py/compile.c +msgid "identifier redefined as nonlocal" +msgstr "" + +#: py/objstr.c +msgid "incomplete format" +msgstr "" + +#: py/objstr.c +msgid "incomplete format key" +msgstr "" + +#: extmod/modubinascii.c +msgid "incorrect padding" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c py/obj.c +msgid "index out of range" +msgstr "" + +#: py/obj.c +msgid "indices must be integers" +msgstr "" + +#: py/compile.c +msgid "inline assembler must be a function" +msgstr "" + +#: py/parsenum.c +msgid "int() arg 2 must be >= 2 and <= 36" +msgstr "" + +#: py/objstr.c +msgid "integer required" +msgstr "" + +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c +#, c-format +msgid "interval must be in range %s-%s" +msgstr "" + +#: extmod/machine_i2c.c +msgid "invalid I2C peripheral" +msgstr "" + +#: extmod/machine_spi.c +msgid "invalid SPI peripheral" +msgstr "" + +#: lib/netutils/netutils.c +msgid "invalid arguments" +msgstr "" + +#: extmod/modussl_axtls.c +msgid "invalid cert" +msgstr "" + +#: extmod/uos_dupterm.c +msgid "invalid dupterm index" +msgstr "" + +#: extmod/modframebuf.c +msgid "invalid format" +msgstr "" + +#: py/objstr.c +msgid "invalid format specifier" +msgstr "" + +#: extmod/modussl_axtls.c +msgid "invalid key" +msgstr "" + +#: py/compile.c +msgid "invalid micropython decorator" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "invalid step" +msgstr "" + +#: py/compile.c py/parse.c +msgid "invalid syntax" +msgstr "" + +#: py/parsenum.c +msgid "invalid syntax for integer" +msgstr "" + +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "" + +#: py/parsenum.c +msgid "invalid syntax for number" +msgstr "" + +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" +msgstr "" + +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "" + +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "" + +#: py/argcheck.c +msgid "keyword argument(s) not yet implemented - use normal args instead" +msgstr "" + +#: py/bc.c +msgid "keywords must be strings" +msgstr "" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" +msgstr "" + +#: py/compile.c +msgid "label redefined" +msgstr "" + +#: py/stream.c +msgid "length argument not allowed for this type" +msgstr "" + +#: py/objarray.c +msgid "lhs and rhs should be compatible" +msgstr "" + +#: py/emitnative.c +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "" + +#: py/emitnative.c +msgid "local '%q' used before type known" +msgstr "" + +#: py/vm.c +msgid "local variable referenced before assignment" +msgstr "" + +#: py/objint.c +msgid "long int not supported in this build" +msgstr "" + +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" +msgstr "" + +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + +#: py/runtime.c +msgid "maximum recursion depth exceeded" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "" + +#: py/runtime.c +msgid "memory allocation failed, heap is locked" +msgstr "" + +#: py/builtinimport.c +msgid "module not found" +msgstr "" + +#: py/compile.c +msgid "multiple *x in assignment" +msgstr "" + +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" +msgstr "" + +#: py/objtype.c +msgid "multiple inheritance not supported" +msgstr "" + +#: py/emitnative.c +msgid "must raise an object" +msgstr "" + +#: extmod/machine_spi.c +msgid "must specify all of sck/mosi/miso" +msgstr "" + +#: py/modbuiltins.c +msgid "must use keyword argument for key function" +msgstr "" + +#: py/runtime.c +msgid "name '%q' is not defined" +msgstr "" + +#: shared-bindings/_bleio/Peripheral.c +msgid "name must be a string" +msgstr "" + +#: py/runtime.c +msgid "name not defined" +msgstr "" + +#: py/compile.c +msgid "name reused for argument" +msgstr "" + +#: py/emitnative.c +msgid "native yield" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "need more than %d values to unpack" +msgstr "" + +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" +msgstr "" + +#: py/objint_mpz.c py/runtime.c +msgid "negative shift count" +msgstr "" + +#: py/vm.c +msgid "no active exception to reraise" +msgstr "" + +#: shared-bindings/socket/__init__.c shared-module/network/__init__.c +msgid "no available NIC" +msgstr "" + +#: py/compile.c +msgid "no binding for nonlocal found" +msgstr "" + +#: py/builtinimport.c +msgid "no module named '%q'" +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "no reset pin available" +msgstr "" + +#: py/runtime.c shared-bindings/_pixelbuf/__init__.c +msgid "no such attribute" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" +msgstr "" + +#: py/compile.c +msgid "non-default argument follows default argument" +msgstr "" + +#: extmod/modubinascii.c +msgid "non-hex digit found" +msgstr "" + +#: py/compile.c +msgid "non-keyword arg after */**" +msgstr "" + +#: py/compile.c +msgid "non-keyword arg after keyword arg" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" +msgstr "" + +#: py/objstr.c +msgid "not all arguments converted during string formatting" +msgstr "" + +#: py/objstr.c +msgid "not enough arguments for format string" +msgstr "" + +#: py/obj.c +#, c-format +msgid "object '%s' is not a tuple or list" +msgstr "" + +#: py/obj.c +msgid "object does not support item assignment" +msgstr "" + +#: py/obj.c +msgid "object does not support item deletion" +msgstr "" + +#: py/obj.c +msgid "object has no len" +msgstr "" + +#: py/obj.c +msgid "object is not subscriptable" +msgstr "" + +#: py/runtime.c +msgid "object not an iterator" +msgstr "" + +#: py/objtype.c py/runtime.c +msgid "object not callable" +msgstr "" + +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" +msgstr "" + +#: py/runtime.c +msgid "object not iterable" +msgstr "" + +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" +msgstr "" + +#: py/obj.c +msgid "object with buffer protocol required" +msgstr "" + +#: extmod/modubinascii.c +msgid "odd-length string" +msgstr "" + +#: py/objstr.c py/objstrunicode.c +msgid "offset out of bounds" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" +msgstr "" + +#: py/modbuiltins.c +msgid "ord expects a character" +msgstr "" + +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "" + +#: py/objint_mpz.c +msgid "overflow converting long int to machine word" +msgstr "" + +#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c +msgid "palette must be 32 bytes long" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "palette_index should be an int" +msgstr "" + +#: py/compile.c +msgid "parameter annotation must be an identifier" +msgstr "" + +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" +msgstr "" + +#: py/emitinlinethumb.c +msgid "parameters must be registers in sequence r0 to r3" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel coordinates out of bounds" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel value requires too many bits" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" +msgstr "" + +#: py/objset.c +msgid "pop from an empty set" +msgstr "" + +#: py/objlist.c +msgid "pop from empty list" +msgstr "" + +#: py/objdict.c +msgid "popitem(): dictionary is empty" +msgstr "" + +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" +msgstr "" + +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" +msgstr "" + +#: extmod/modutimeq.c +msgid "queue overflow" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "rawbuf is not the same size as buf" +msgstr "" + +#: shared-bindings/_pixelbuf/__init__.c +msgid "readonly attribute" +msgstr "" + +#: py/builtinimport.c +msgid "relative import" +msgstr "" + +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" +msgstr "" + +#: py/compile.c +msgid "return annotation must be an identifier" +msgstr "" + +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" +msgstr "" + +#: py/objstr.c +msgid "rsplit(None,n)" +msgstr "" + +#: shared-bindings/audiocore/RawSample.c +msgid "" +"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " +"'B'" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" +msgstr "" + +#: py/modmicropython.c +msgid "schedule stack full" +msgstr "" + +#: lib/utils/pyexec.c py/builtinimport.c +msgid "script compilation not supported" +msgstr "" + +#: py/objstr.c +msgid "sign not allowed in string format specifier" +msgstr "" + +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" +msgstr "" + +#: py/objstr.c +msgid "single '}' encountered in format string" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "sleep length must be non-negative" +msgstr "" + +#: py/objslice.c py/sequence.c +msgid "slice step cannot be zero" +msgstr "" + +#: py/objint.c py/sequence.c +msgid "small int overflow" +msgstr "" + +#: main.c +msgid "soft reboot\n" +msgstr "" + +#: py/objstr.c +msgid "start/end indices" +msgstr "" + +#: shared-bindings/displayio/Shape.c +msgid "start_x should be an int" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "step must be non-zero" +msgstr "" + +#: shared-bindings/busio/UART.c +msgid "stop must be 1 or 2" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" +msgstr "" + +#: py/stream.c +msgid "stream operation not supported" +msgstr "" + +#: py/objstrunicode.c +msgid "string index out of range" +msgstr "" + +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" +msgstr "" + +#: py/stream.c +msgid "string not supported; use bytes or bytearray" +msgstr "" + +#: extmod/moductypes.c +msgid "struct: cannot index" +msgstr "" + +#: extmod/moductypes.c +msgid "struct: index out of range" +msgstr "" + +#: extmod/moductypes.c +msgid "struct: no fields" +msgstr "" + +#: py/objstr.c +msgid "substring not found" +msgstr "" + +#: py/compile.c +msgid "super() can't find self" +msgstr "" + +#: extmod/modujson.c +msgid "syntax error in JSON" +msgstr "" + +#: extmod/moductypes.c +msgid "syntax error in uctypes descriptor" +msgstr "" + +#: shared-bindings/touchio/TouchIn.c +msgid "threshold must be in the range 0-65536" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes a 9-sequence" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes exactly 1 argument" +msgstr "" + +#: shared-bindings/busio/UART.c +msgid "timeout >100 (units are now seconds, not msecs)" +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "timeout must be >= 0.0" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" +msgstr "" + +#: shared-module/struct/__init__.c +msgid "too many arguments provided with the given format" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "" + +#: py/objstr.c +msgid "tuple index out of range" +msgstr "" + +#: py/obj.c +msgid "tuple/list has wrong length" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "tuple/list required on RHS" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "tx and rx cannot both be None" +msgstr "" + +#: py/objtype.c +msgid "type '%q' is not an acceptable base type" +msgstr "" + +#: py/objtype.c +msgid "type is not an acceptable base type" +msgstr "" + +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" +msgstr "" + +#: py/objtype.c +msgid "type takes 1 or 3 arguments" +msgstr "" + +#: py/objint_longlong.c +msgid "ulonglong too large" +msgstr "" + +#: py/emitnative.c +msgid "unary op %q not implemented" +msgstr "" + +#: py/parse.c +msgid "unexpected indent" +msgstr "" + +#: py/bc.c +msgid "unexpected keyword argument" +msgstr "" + +#: py/bc.c py/objnamedtuple.c +msgid "unexpected keyword argument '%q'" +msgstr "" + +#: py/lexer.c +msgid "unicode name escapes" +msgstr "" + +#: py/parse.c +msgid "unindent does not match any outer indentation level" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown conversion specifier %c" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type '%s'" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'float'" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'str'" +msgstr "" + +#: py/compile.c +msgid "unknown type" +msgstr "" + +#: py/emitnative.c +msgid "unknown type '%q'" +msgstr "" + +#: py/objstr.c +msgid "unmatched '{' in format" +msgstr "" + +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "unsupported %q type" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "" + +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "" + +#: py/runtime.c +msgid "unsupported type for %q: '%s'" +msgstr "" + +#: py/runtime.c +msgid "unsupported type for operator" +msgstr "" + +#: py/runtime.c +msgid "unsupported types for %q: '%s', '%s'" +msgstr "" + +#: py/objint.c +#, c-format +msgid "value must fit in %d byte(s)" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "value_count must be > 0" +msgstr "" + +#: shared-bindings/_bleio/Scanner.c +msgid "window must be <= interval" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "write_args must be a list, tuple, or None" +msgstr "" + +#: py/objstr.c +msgid "wrong number of arguments" +msgstr "" + +#: py/runtime.c +msgid "wrong number of values to unpack" +msgstr "" + +#: shared-module/displayio/Shape.c +msgid "x value out of bounds" +msgstr "" + +#: shared-bindings/displayio/Shape.c +msgid "y should be an int" +msgstr "" + +#: shared-module/displayio/Shape.c +msgid "y value out of bounds" +msgstr "" + +#: py/objrange.c +msgid "zero step" +msgstr "" diff --git a/locale/en_x_pirate.po b/locale/en_x_pirate.po new file mode 100644 index 00000000000..7db72248b68 --- /dev/null +++ b/locale/en_x_pirate.po @@ -0,0 +1,2707 @@ +# Pirate (English) Translation +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"PO-Revision-Date: 2018-07-27 11:55-0700\n" +"Last-Translator: \n" +"Language-Team: @sommersoft, @MrCertainly\n" +"Language: en_x_pirate\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.1.1\n" + +#: main.c +msgid "" +"\n" +"Code done running. Waiting for reload.\n" +msgstr "" +"\n" +"Captin's orders are complete. Holdin' fast fer reload.\n" + +#: py/obj.c +msgid " File \"%q\"" +msgstr "" + +#: py/obj.c +msgid " File \"%q\", line %d" +msgstr "" + +#: main.c +msgid " output:\n" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "%%c requires int or char" +msgstr "" + +#: shared-bindings/microcontroller/Pin.c +msgid "%q in use" +msgstr "" + +#: py/obj.c +msgid "%q index out of range" +msgstr "" + +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c +msgid "%q must be >= 1" +msgstr "" + +#: shared-bindings/fontio/BuiltinFont.c +msgid "%q should be an int" +msgstr "" + +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" +msgstr "" + +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" +msgstr "" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects a special register" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an FPU register" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects at most r%d" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "" + +#: py/emitinlinextensa.c +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item assignment" +msgstr "" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item deletion" +msgstr "" + +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not an iterator" +msgstr "" + +#: py/objtype.c py/runtime.c +#, c-format +msgid "'%s' object is not callable" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not iterable" +msgstr "" + +#: py/obj.c +#, c-format +msgid "'%s' object is not subscriptable" +msgstr "" + +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" +msgstr "" + +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" +msgstr "" + +#: py/compile.c +msgid "'align' requires 1 argument" +msgstr "" + +#: py/compile.c +msgid "'await' outside function" +msgstr "" + +#: py/compile.c +msgid "'break' outside loop" +msgstr "" + +#: py/compile.c +msgid "'continue' outside loop" +msgstr "" + +#: py/compile.c +msgid "'data' requires at least 2 arguments" +msgstr "" + +#: py/compile.c +msgid "'data' requires integer arguments" +msgstr "" + +#: py/compile.c +msgid "'label' requires 1 argument" +msgstr "" + +#: py/compile.c +msgid "'return' outside function" +msgstr "" + +#: py/compile.c +msgid "'yield' outside function" +msgstr "" + +#: py/compile.c +msgid "*x must be assignment target" +msgstr "" + +#: py/obj.c +msgid ", in %q\n" +msgstr "" + +#: py/objcomplex.c +msgid "0.0 to a complex power" +msgstr "" + +#: py/modbuiltins.c +msgid "3-arg pow() not supported" +msgstr "" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "A hardware interrupt channel is already in use" +msgstr "Avast! A hardware interrupt channel be used already" + +#: shared-bindings/_bleio/Address.c +#, c-format +msgid "Address must be %d bytes long" +msgstr "" + +#: shared-bindings/_bleio/Address.c +msgid "Address type out of range" +msgstr "" + +#: ports/nrf/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" +msgstr "" + +#: ports/nrf/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +msgid "All UART peripherals are in use" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "" + +#: ports/atmel-samd/audio_dma.c ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "All sync event channels in use" +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c +msgid "All timers for this pin are in use" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: shared-module/_pew/PewPew.c +msgid "All timers in use" +msgstr "" + +#: ports/nrf/common-hal/analogio/AnalogOut.c +msgid "AnalogOut functionality not supported" +msgstr "" + +#: shared-bindings/analogio/AnalogOut.c +msgid "AnalogOut is only 16 bits. Value must be less than 65536." +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "AnalogOut not supported on given pin" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" +msgstr "Belay that! thar be another active send" + +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "Attempted heap allocation when MicroPython VM not running.\n" +msgstr "" + +#: main.c +msgid "Auto-reload is off.\n" +msgstr "Auto-reload be off.\n" + +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "" +"Auto-reload be on. Put yer files on USB to weigh anchor, er' bring'er about " +"t' the REPL t' scuttle.\n" + +#: shared-module/displayio/Display.c +msgid "Below minimum frame rate" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Bit clock and word select must share a clock unit" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Bit depth must be multiple of 8." +msgstr "" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "Both pins must support hardware interrupts" +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Brightness must be 0-1.0" +msgstr "" + +#: shared-bindings/supervisor/__init__.c +msgid "Brightness must be between 0 and 255" +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Brightness not adjustable" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Buffer is not a bytearray." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Buffer is too small" +msgstr "" + +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Buffer length %d too big. It must be less than %d" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c +msgid "Buffer must be at least length 1" +msgstr "" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +#, c-format +msgid "Bus pin %d is already in use" +msgstr "Belay that! Bus pin %d already be in use" + +#: shared-bindings/_bleio/UUID.c +msgid "Byte buffer must be 16 bytes." +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Bytes must be between 0 and 255." +msgstr "" + +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Can not use dotstar with %s" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" +msgstr "" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/nrf/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "" + +#: ports/nrf/common-hal/microcontroller/Processor.c +msgid "Cannot get temperature" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Cannot output both channels on the same pin" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot read without MISO pin." +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Cannot record to a file" +msgstr "" + +#: shared-module/storage/__init__.c +msgid "Cannot remount '/' when USB is active." +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +msgid "Cannot reset into bootloader because no bootloader is present." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Cannot set value when direction is input." +msgstr "" + +#: py/objslice.c +msgid "Cannot subclass slice" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot transfer without MOSI and MISO pins." +msgstr "" + +#: extmod/moductypes.c +msgid "Cannot unambiguously get sizeof scalar" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot write without MOSI pin." +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Clock pin init failed." +msgstr "" + +#: shared-module/bitbangio/I2C.c +msgid "Clock stretch too long" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" +msgstr "" + +#: shared-bindings/_pew/PewPew.c +msgid "Column entry must be digitalio.DigitalInOut" +msgstr "" + +#: shared-bindings/displayio/I2CDisplay.c +msgid "Command must be 0-255" +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +msgid "Command must be an int between 0 and 255" +msgstr "" + +#: py/persistentcode.c +msgid "Corrupt .mpy file" +msgstr "" + +#: py/emitglue.c +msgid "Corrupt raw code" +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "Could not initialize UART" +msgstr "" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate first buffer" +msgstr "" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate second buffer" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "Crash into the HardFault_Handler.\n" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "DAC already in use" +msgstr "" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +msgid "Data 0 pin must be byte aligned" +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Data chunk must follow fmt chunk" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Data too large for advertisement packet" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Destination capacity is smaller than destination_length." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Display must have a 16 bit colorspace." +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Display rotation must be in 90 degree increments" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Drive mode not used when direction is input." +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "EXTINT channel already in use" +msgstr "Avast! EXTINT channel already in use" + +#: extmod/modure.c +msgid "Error in regex" +msgstr "" + +#: shared-bindings/microcontroller/Pin.c +#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c +#: shared-bindings/terminalio/Terminal.c +msgid "Expected a %q" +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c +msgid "Expected a Characteristic" +msgstr "" + +#: shared-bindings/_bleio/Service.c +msgid "Expected a Peripheral" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Expected a Service" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c +#: shared-bindings/_bleio/Service.c +msgid "Expected a UUID" +msgstr "" + +#: shared-bindings/_bleio/Central.c +msgid "Expected an Address" +msgstr "" + +#: shared-module/_pixelbuf/PixelBuf.c +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "" + +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + +#: ports/nrf/sd_mutex.c +#, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Service.c +#, c-format +msgid "Failed to add characteristic, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to add descriptor, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to add service, err 0x%04x" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "Failed to allocate RX buffer" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +#, c-format +msgid "Failed to allocate RX buffer of %d bytes" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to change softdevice state" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to configure advertising, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Central.c +msgid "Failed to connect: timeout" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, c-format +msgid "Failed to continue scanning, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "Failed to discover services" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to get local address" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to get softdevice state" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to notify or indicate attribute value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "Failed to read attribute value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to read gatts value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" +msgstr "" + +#: ports/nrf/sd_mutex.c +#, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to set device name, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Central.c +#, c-format +msgid "Failed to start connecting, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, c-format +msgid "Failed to start scanning, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to write CCCD, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to write attribute value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to write gatts value, err 0x%04x" +msgstr "" + +#: py/moduerrno.c +msgid "File exists" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash erase failed" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash erase failed to start, err 0x%04x" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash write failed" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash write failed to start, err 0x%04x" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Frequency captured is above capability. Capture Paused." +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c +msgid "Function requires lock" +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Group already used" +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Group full" +msgstr "" + +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" +msgstr "" + +#: extmod/machine_i2c.c +msgid "I2C operation not supported" +msgstr "" + +#: py/persistentcode.c +msgid "" +"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" +"mpy-update for more info." +msgstr "" + +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" +msgstr "" + +#: py/moduerrno.c +msgid "Input/output error" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Invalid %q pin" +msgstr "Avast! %q pin be invalid" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Invalid BMP file" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c +#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c +msgid "Invalid PWM frequency" +msgstr "" + +#: py/moduerrno.c +msgid "Invalid argument" +msgstr "" + +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +msgid "Invalid buffer size" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Invalid capture period. Valid range: 1 - 500" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid channel count" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Invalid direction." +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid file" +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid number of bits" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid phase" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +#: shared-bindings/pulseio/PWMOut.c +msgid "Invalid pin" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for left channel" +msgstr "Belay that! Invalid pin for port-side channel" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for right channel" +msgstr "Belay that! Invalid pin for starboard-side channel" + +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/atmel-samd/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c +#: ports/nrf/common-hal/busio/I2C.c +msgid "Invalid pins" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid polarity" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + +#: shared-bindings/microcontroller/__init__.c +msgid "Invalid run mode." +msgstr "" + +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid voice count" +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid wave file" +msgstr "" + +#: py/compile.c +msgid "LHS of keyword arg must be an id" +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass." +msgstr "" + +#: py/objslice.c +msgid "Length must be an int" +msgstr "" + +#: py/objslice.c +msgid "Length must be non-negative" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Looks like our core CircuitPython code crashed hard. Whoops!\n" +"Please file an issue at https://github.com/adafruit/circuitpython/issues\n" +" with the contents of your CIRCUITPY drive and this message:\n" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "MISO pin init failed." +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "MOSI pin init failed." +msgstr "" + +#: shared-module/displayio/Shape.c +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython NLR jump failed. Likely memory corruption.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython fatal error.\n" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Microphone startup delay must be in range 0.0 to 1.0" +msgstr "" + +#: shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "No DAC on chip" +msgstr "Shiver me timbers! There be no DAC on this chip" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "No DMA channel found" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No RX pin" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No TX pin" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "No available clocks" +msgstr "" + +#: shared-bindings/board/__init__.c +msgid "No default %q bus" +msgstr "" + +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" +msgstr "" + +#: shared-bindings/os/__init__.c +msgid "No hardware random available" +msgstr "" + +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "No hardware support on pin" +msgstr "" + +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" +msgstr "" + +#: py/moduerrno.c +msgid "No space left on device" +msgstr "" + +#: py/moduerrno.c +msgid "No such file/directory" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Peripheral.c +msgid "Not connected" +msgstr "" + +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c +msgid "Not playing" +msgstr "" + +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +msgid "Odd parity is not supported" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Only 8 or 16 bit mono with " +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Only slices with step=1 (aka None) are supported" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Oversample must be multiple of 8." +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM frequency not writable when variable_frequency is False on construction." +msgstr "" + +#: py/moduerrno.c +msgid "Permission denied" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogIn.c +#: ports/nrf/common-hal/analogio/AnalogIn.c +msgid "Pin does not have ADC capabilities" +msgstr "Belay that! Th' Pin be not ADC capable" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Pixel beyond bounds of buffer" +msgstr "" + +#: py/builtinhelp.c +msgid "Plus any modules on the filesystem\n" +msgstr "" + +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Pull not used when direction is output." +msgstr "" + +#: ports/nrf/common-hal/rtc/RTC.c +msgid "RTC calibration is not supported on this board" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Range out of bounds" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c +msgid "Read-only" +msgstr "" + +#: extmod/vfs_fat.c py/moduerrno.c +msgid "Read-only filesystem" +msgstr "" + +#: shared-module/displayio/Bitmap.c +msgid "Read-only object" +msgstr "" + +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Refresh too soon" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" +msgstr "" + +#: shared-bindings/_pew/PewPew.c +msgid "Row entry must be digitalio.DigitalInOut" +msgstr "" + +#: main.c +msgid "Running in safe mode! Auto-reload is off.\n" +msgstr "Runnin' in safe mode! Auto-reload be off.\n" + +#: main.c +msgid "Running in safe mode! Not running saved code.\n" +msgstr "Runnin' in safe mode! Nay runnin' saved code.\n" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "SDA or SCL needs a pull up" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Sample rate must be positive" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Sample rate too high. It must be less than %d" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/pulseio/PulseIn.c +msgid "Slices not supported" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: extmod/modure.c +msgid "Splitting with sub-captures" +msgstr "" + +#: shared-bindings/supervisor/__init__.c +msgid "Stack size must be at least 256" +msgstr "" + +#: shared-bindings/multiterminal/__init__.c +msgid "Stream missing readinto() or write() method." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The CircuitPython heap was corrupted because the stack was too small.\n" +"Please increase stack size limits and press reset (after ejecting " +"CIRCUITPY).\n" +"If you didn't change the stack, then file an issue here with the contents of " +"your CIRCUITPY drive:\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The `microcontroller` module was used to boot into safe mode. Press reset to " +"exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The reset button was pressed while booting CircuitPython. Press again to " +"exit safe mode.\n" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's signedness does not match the mixer's" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile value out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample." +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "Too many display busses" +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Too many displays" +msgstr "" + +#: py/obj.c +msgid "Traceback (most recent call last):\n" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "Tuple or struct_time argument required" +msgstr "" + +#: shared-module/usb_hid/Device.c +msgid "USB Busy" +msgstr "" + +#: shared-module/usb_hid/Device.c +msgid "USB Error" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID integer value must be 0-0xffff" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Unable to allocate buffers for signed conversion" +msgstr "" + +#: shared-module/displayio/I2CDisplay.c +#, c-format +msgid "Unable to find I2C Display at %x" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Unable to find free GCLK" +msgstr "Arr! No free GCLK be in sight" + +#: py/parse.c +msgid "Unable to init parser" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +msgid "Unexpected nrfx uuid type" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "Unsupported baudrate" +msgstr "" + +#: shared-module/displayio/display_core.c +msgid "Unsupported display bus type" +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Unsupported format" +msgstr "" + +#: py/moduerrno.c +msgid "Unsupported operation" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Unsupported pull value." +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + +#: py/emitnative.c +msgid "Viper functions don't currently support more than 4 arguments" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "Voice index too high" +msgstr "" + +#: main.c +msgid "WARNING: Your code filename has two extensions\n" +msgstr "Blimey! Yer code filename has two extensions\n" + +#: py/builtinhelp.c +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"You are running in safe mode which means something unanticipated happened.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "You requested starting safe mode by " +msgstr "" + +#: py/objtype.c +msgid "__init__() should return None" +msgstr "" + +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "" + +#: py/objobject.c +msgid "__new__ arg must be a user-type" +msgstr "" + +#: extmod/modubinascii.c extmod/moduhashlib.c +msgid "a bytes-like object is required" +msgstr "" + +#: lib/embed/abort_.c +msgid "abort() called" +msgstr "" + +#: extmod/machine_mem.c +#, c-format +msgid "address %08x is not aligned to %d bytes" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "address out of bounds" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "addresses is empty" +msgstr "" + +#: py/modbuiltins.c +msgid "arg is an empty sequence" +msgstr "" + +#: py/runtime.c +msgid "argument has wrong type" +msgstr "" + +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +msgid "argument num/types mismatch" +msgstr "" + +#: py/runtime.c +msgid "argument should be a '%q' not a '%q'" +msgstr "" + +#: py/objarray.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" +msgstr "" + +#: py/objstr.c +msgid "attributes not supported yet" +msgstr "" + +#: py/builtinevex.c +msgid "bad compile mode" +msgstr "" + +#: py/objstr.c +msgid "bad conversion specifier" +msgstr "" + +#: py/objstr.c +msgid "bad format string" +msgstr "" + +#: py/binary.c +msgid "bad typecode" +msgstr "" + +#: py/emitnative.c +msgid "binary op %q not implemented" +msgstr "" + +#: shared-bindings/busio/UART.c +msgid "bits must be 7, 8 or 9" +msgstr "" + +#: extmod/machine_spi.c +msgid "bits must be 8" +msgstr "pieces must be of 8" + +#: shared-bindings/audiocore/Mixer.c +msgid "bits_per_sample must be 8 or 16" +msgstr "" + +#: py/emitinlinethumb.c +msgid "branch not in range" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "" + +#: shared-bindings/audiocore/RawSample.c +msgid "buffer must be a bytes-like object" +msgstr "" + +#: shared-module/struct/__init__.c +msgid "buffer size must match format" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" +msgstr "" + +#: py/modstruct.c shared-bindings/struct/__init__.c +#: shared-module/struct/__init__.c +msgid "buffer too small" +msgstr "" + +#: extmod/machine_spi.c +msgid "buffers must be the same length" +msgstr "yer buffers must be of the same length" + +#: shared-bindings/_pew/PewPew.c +msgid "buttons must be digitalio.DigitalInOut" +msgstr "" + +#: py/vm.c +msgid "byte code not implemented" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "bytes > 8 bits not supported" +msgstr "" + +#: py/objstr.c +msgid "bytes value out of range" +msgstr "" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" +msgstr "" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" +msgstr "" + +#: ports/atmel-samd/common-hal/rtc/RTC.c +msgid "calibration value out of range +/-127" +msgstr "" + +#: py/emitinlinethumb.c +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "" + +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "" + +#: py/persistentcode.c +msgid "can only save bytecode" +msgstr "" + +#: py/objtype.c +msgid "can't add special method to already-subclassed class" +msgstr "" + +#: py/compile.c +msgid "can't assign to expression" +msgstr "" + +#: py/obj.c +#, c-format +msgid "can't convert %s to complex" +msgstr "" + +#: py/obj.c +#, c-format +msgid "can't convert %s to float" +msgstr "" + +#: py/obj.c +#, c-format +msgid "can't convert %s to int" +msgstr "" + +#: py/objstr.c +msgid "can't convert '%q' object to %q implicitly" +msgstr "" + +#: py/objint.c +msgid "can't convert NaN to int" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "can't convert address to int" +msgstr "" + +#: py/objint.c +msgid "can't convert inf to int" +msgstr "" + +#: py/obj.c +msgid "can't convert to complex" +msgstr "" + +#: py/obj.c +msgid "can't convert to float" +msgstr "" + +#: py/obj.c +msgid "can't convert to int" +msgstr "" + +#: py/objstr.c +msgid "can't convert to str implicitly" +msgstr "" + +#: py/compile.c +msgid "can't declare nonlocal in outer code" +msgstr "" + +#: py/compile.c +msgid "can't delete expression" +msgstr "" + +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" +msgstr "" + +#: py/objcomplex.c +msgid "can't do truncated division of a complex number" +msgstr "" + +#: py/compile.c +msgid "can't have multiple **x" +msgstr "" + +#: py/compile.c +msgid "can't have multiple *x" +msgstr "" + +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "" + +#: py/emitnative.c +msgid "can't load from '%q'" +msgstr "" + +#: py/emitnative.c +msgid "can't load with '%q' index" +msgstr "" + +#: py/objgenerator.c +msgid "can't pend throw to just-started generator" +msgstr "" + +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" +msgstr "" + +#: py/objnamedtuple.c +msgid "can't set attribute" +msgstr "" + +#: py/emitnative.c +msgid "can't store '%q'" +msgstr "" + +#: py/emitnative.c +msgid "can't store to '%q'" +msgstr "" + +#: py/emitnative.c +msgid "can't store with '%q' index" +msgstr "" + +#: py/objstr.c +msgid "" +"can't switch from automatic field numbering to manual field specification" +msgstr "" + +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "" + +#: py/objtype.c +msgid "cannot create '%q' instances" +msgstr "" + +#: py/objtype.c +msgid "cannot create instance" +msgstr "" + +#: py/runtime.c +msgid "cannot import name %q" +msgstr "" + +#: py/builtinimport.c +msgid "cannot perform relative import" +msgstr "" + +#: py/emitnative.c +msgid "casting" +msgstr "" + +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" +msgstr "" + +#: py/modbuiltins.c +msgid "chr() arg not in range(0x110000)" +msgstr "" + +#: py/modbuiltins.c +msgid "chr() arg not in range(256)" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer or int" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" +msgstr "" + +#: shared-bindings/displayio/ColorConverter.c +msgid "color should be an int" +msgstr "" + +#: py/objcomplex.c +msgid "complex division by zero" +msgstr "" + +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" +msgstr "" + +#: extmod/moduzlib.c +msgid "compression header" +msgstr "" + +#: py/parse.c +msgid "constant must be an integer" +msgstr "" + +#: py/emitnative.c +msgid "conversion to object" +msgstr "" + +#: py/parsenum.c +msgid "decimal numbers not supported" +msgstr "" + +#: py/compile.c +msgid "default 'except' must be last" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination_length must be an int >= 0" +msgstr "" + +#: py/objdict.c +msgid "dict update sequence has wrong length" +msgstr "" + +#: py/modmath.c py/objfloat.c py/objint_longlong.c py/objint_mpz.c py/runtime.c +#: shared-bindings/math/__init__.c +msgid "division by zero" +msgstr "" + +#: py/objdeque.c +msgid "empty" +msgstr "" + +#: extmod/moduheapq.c extmod/modutimeq.c +msgid "empty heap" +msgstr "" + +#: py/objstr.c +msgid "empty separator" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "empty sequence" +msgstr "" + +#: py/objstr.c +msgid "end of format while looking for conversion specifier" +msgstr "" + +#: shared-bindings/displayio/Shape.c +msgid "end_x should be an int" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +#, c-format +msgid "error = 0x%08lX" +msgstr "" + +#: py/runtime.c +msgid "exceptions must derive from BaseException" +msgstr "" + +#: py/objstr.c +msgid "expected ':' after format specifier" +msgstr "" + +#: py/obj.c +msgid "expected tuple/list" +msgstr "" + +#: py/modthread.c +msgid "expecting a dict for keyword args" +msgstr "" + +#: py/compile.c +msgid "expecting an assembler instruction" +msgstr "" + +#: py/compile.c +msgid "expecting just a value for set" +msgstr "" + +#: py/compile.c +msgid "expecting key:value for dict" +msgstr "" + +#: py/argcheck.c +msgid "extra keyword arguments given" +msgstr "" + +#: py/argcheck.c +msgid "extra positional arguments given" +msgstr "" + +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c +msgid "file must be a file opened in byte mode" +msgstr "" + +#: shared-bindings/storage/__init__.c +msgid "filesystem must provide mount method" +msgstr "" + +#: py/objtype.c +msgid "first argument to super() must be type" +msgstr "" + +#: extmod/machine_spi.c +msgid "firstbit must be MSB" +msgstr "" + +#: py/objint.c +msgid "float too big" +msgstr "" + +#: shared-bindings/_stage/Text.c +msgid "font must be 2048 bytes long" +msgstr "" + +#: py/objstr.c +msgid "format requires a dict" +msgstr "" + +#: py/objdeque.c +msgid "full" +msgstr "" + +#: py/argcheck.c +msgid "function does not take keyword arguments" +msgstr "" + +#: py/argcheck.c +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "" + +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" +msgstr "" + +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" +msgstr "" + +#: py/bc.c +msgid "function missing keyword-only argument" +msgstr "" + +#: py/bc.c +msgid "function missing required keyword argument '%q'" +msgstr "" + +#: py/bc.c +#, c-format +msgid "function missing required positional argument #%d" +msgstr "" + +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "function takes exactly 9 arguments" +msgstr "" + +#: py/objgenerator.c +msgid "generator already executing" +msgstr "" + +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" +msgstr "" + +#: shared-bindings/_stage/Layer.c +msgid "graphic must be 2048 bytes long" +msgstr "" + +#: extmod/moduheapq.c +msgid "heap must be a list" +msgstr "" + +#: py/compile.c +msgid "identifier redefined as global" +msgstr "" + +#: py/compile.c +msgid "identifier redefined as nonlocal" +msgstr "" + +#: py/objstr.c +msgid "incomplete format" +msgstr "" + +#: py/objstr.c +msgid "incomplete format key" +msgstr "" + +#: extmod/modubinascii.c +msgid "incorrect padding" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c py/obj.c +msgid "index out of range" +msgstr "" + +#: py/obj.c +msgid "indices must be integers" +msgstr "" + +#: py/compile.c +msgid "inline assembler must be a function" +msgstr "" + +#: py/parsenum.c +msgid "int() arg 2 must be >= 2 and <= 36" +msgstr "" + +#: py/objstr.c +msgid "integer required" +msgstr "" + +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c +#, c-format +msgid "interval must be in range %s-%s" +msgstr "" + +#: extmod/machine_i2c.c +msgid "invalid I2C peripheral" +msgstr "Belay that! I2C peripheral be invalid" + +#: extmod/machine_spi.c +msgid "invalid SPI peripheral" +msgstr "Arr! SPI peripheral be invalid" + +#: lib/netutils/netutils.c +msgid "invalid arguments" +msgstr "" + +#: extmod/modussl_axtls.c +msgid "invalid cert" +msgstr "" + +#: extmod/uos_dupterm.c +msgid "invalid dupterm index" +msgstr "" + +#: extmod/modframebuf.c +msgid "invalid format" +msgstr "" + +#: py/objstr.c +msgid "invalid format specifier" +msgstr "" + +#: extmod/modussl_axtls.c +msgid "invalid key" +msgstr "" + +#: py/compile.c +msgid "invalid micropython decorator" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "invalid step" +msgstr "" + +#: py/compile.c py/parse.c +msgid "invalid syntax" +msgstr "" + +#: py/parsenum.c +msgid "invalid syntax for integer" +msgstr "" + +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "" + +#: py/parsenum.c +msgid "invalid syntax for number" +msgstr "" + +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" +msgstr "" + +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "" + +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "" + +#: py/argcheck.c +msgid "keyword argument(s) not yet implemented - use normal args instead" +msgstr "" + +#: py/bc.c +msgid "keywords must be strings" +msgstr "" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" +msgstr "" + +#: py/compile.c +msgid "label redefined" +msgstr "" + +#: py/stream.c +msgid "length argument not allowed for this type" +msgstr "" + +#: py/objarray.c +msgid "lhs and rhs should be compatible" +msgstr "" + +#: py/emitnative.c +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "" + +#: py/emitnative.c +msgid "local '%q' used before type known" +msgstr "" + +#: py/vm.c +msgid "local variable referenced before assignment" +msgstr "" + +#: py/objint.c +msgid "long int not supported in this build" +msgstr "" + +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" +msgstr "" + +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + +#: py/runtime.c +msgid "maximum recursion depth exceeded" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "" + +#: py/runtime.c +msgid "memory allocation failed, heap is locked" +msgstr "" + +#: py/builtinimport.c +msgid "module not found" +msgstr "" + +#: py/compile.c +msgid "multiple *x in assignment" +msgstr "" + +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" +msgstr "" + +#: py/objtype.c +msgid "multiple inheritance not supported" +msgstr "" + +#: py/emitnative.c +msgid "must raise an object" +msgstr "" + +#: extmod/machine_spi.c +msgid "must specify all of sck/mosi/miso" +msgstr "" + +#: py/modbuiltins.c +msgid "must use keyword argument for key function" +msgstr "" + +#: py/runtime.c +msgid "name '%q' is not defined" +msgstr "" + +#: shared-bindings/_bleio/Peripheral.c +msgid "name must be a string" +msgstr "" + +#: py/runtime.c +msgid "name not defined" +msgstr "" + +#: py/compile.c +msgid "name reused for argument" +msgstr "" + +#: py/emitnative.c +msgid "native yield" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "need more than %d values to unpack" +msgstr "" + +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" +msgstr "" + +#: py/objint_mpz.c py/runtime.c +msgid "negative shift count" +msgstr "" + +#: py/vm.c +msgid "no active exception to reraise" +msgstr "" + +#: shared-bindings/socket/__init__.c shared-module/network/__init__.c +msgid "no available NIC" +msgstr "" + +#: py/compile.c +msgid "no binding for nonlocal found" +msgstr "" + +#: py/builtinimport.c +msgid "no module named '%q'" +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "no reset pin available" +msgstr "" + +#: py/runtime.c shared-bindings/_pixelbuf/__init__.c +msgid "no such attribute" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" +msgstr "" + +#: py/compile.c +msgid "non-default argument follows default argument" +msgstr "" + +#: extmod/modubinascii.c +msgid "non-hex digit found" +msgstr "" + +#: py/compile.c +msgid "non-keyword arg after */**" +msgstr "" + +#: py/compile.c +msgid "non-keyword arg after keyword arg" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" +msgstr "" + +#: py/objstr.c +msgid "not all arguments converted during string formatting" +msgstr "" + +#: py/objstr.c +msgid "not enough arguments for format string" +msgstr "" + +#: py/obj.c +#, c-format +msgid "object '%s' is not a tuple or list" +msgstr "" + +#: py/obj.c +msgid "object does not support item assignment" +msgstr "" + +#: py/obj.c +msgid "object does not support item deletion" +msgstr "" + +#: py/obj.c +msgid "object has no len" +msgstr "" + +#: py/obj.c +msgid "object is not subscriptable" +msgstr "" + +#: py/runtime.c +msgid "object not an iterator" +msgstr "" + +#: py/objtype.c py/runtime.c +msgid "object not callable" +msgstr "" + +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" +msgstr "" + +#: py/runtime.c +msgid "object not iterable" +msgstr "" + +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" +msgstr "" + +#: py/obj.c +msgid "object with buffer protocol required" +msgstr "" + +#: extmod/modubinascii.c +msgid "odd-length string" +msgstr "" + +#: py/objstr.c py/objstrunicode.c +msgid "offset out of bounds" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" +msgstr "" + +#: py/modbuiltins.c +msgid "ord expects a character" +msgstr "" + +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "" + +#: py/objint_mpz.c +msgid "overflow converting long int to machine word" +msgstr "" + +#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c +msgid "palette must be 32 bytes long" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "palette_index should be an int" +msgstr "" + +#: py/compile.c +msgid "parameter annotation must be an identifier" +msgstr "" + +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" +msgstr "" + +#: py/emitinlinethumb.c +msgid "parameters must be registers in sequence r0 to r3" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel coordinates out of bounds" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel value requires too many bits" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" +msgstr "" + +#: py/objset.c +msgid "pop from an empty set" +msgstr "" + +#: py/objlist.c +msgid "pop from empty list" +msgstr "" + +#: py/objdict.c +msgid "popitem(): dictionary is empty" +msgstr "" + +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" +msgstr "" + +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" +msgstr "" + +#: extmod/modutimeq.c +msgid "queue overflow" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "rawbuf is not the same size as buf" +msgstr "" + +#: shared-bindings/_pixelbuf/__init__.c +msgid "readonly attribute" +msgstr "" + +#: py/builtinimport.c +msgid "relative import" +msgstr "" + +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" +msgstr "" + +#: py/compile.c +msgid "return annotation must be an identifier" +msgstr "" + +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" +msgstr "" + +#: py/objstr.c +msgid "rsplit(None,n)" +msgstr "" + +#: shared-bindings/audiocore/RawSample.c +msgid "" +"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " +"'B'" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" +msgstr "" + +#: py/modmicropython.c +msgid "schedule stack full" +msgstr "" + +#: lib/utils/pyexec.c py/builtinimport.c +msgid "script compilation not supported" +msgstr "" + +#: py/objstr.c +msgid "sign not allowed in string format specifier" +msgstr "" + +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" +msgstr "" + +#: py/objstr.c +msgid "single '}' encountered in format string" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "sleep length must be non-negative" +msgstr "" + +#: py/objslice.c py/sequence.c +msgid "slice step cannot be zero" +msgstr "" + +#: py/objint.c py/sequence.c +msgid "small int overflow" +msgstr "" + +#: main.c +msgid "soft reboot\n" +msgstr "" + +#: py/objstr.c +msgid "start/end indices" +msgstr "" + +#: shared-bindings/displayio/Shape.c +msgid "start_x should be an int" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "step must be non-zero" +msgstr "" + +#: shared-bindings/busio/UART.c +msgid "stop must be 1 or 2" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" +msgstr "" + +#: py/stream.c +msgid "stream operation not supported" +msgstr "" + +#: py/objstrunicode.c +msgid "string index out of range" +msgstr "" + +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" +msgstr "" + +#: py/stream.c +msgid "string not supported; use bytes or bytearray" +msgstr "" + +#: extmod/moductypes.c +msgid "struct: cannot index" +msgstr "" + +#: extmod/moductypes.c +msgid "struct: index out of range" +msgstr "" + +#: extmod/moductypes.c +msgid "struct: no fields" +msgstr "" + +#: py/objstr.c +msgid "substring not found" +msgstr "" + +#: py/compile.c +msgid "super() can't find self" +msgstr "" + +#: extmod/modujson.c +msgid "syntax error in JSON" +msgstr "" + +#: extmod/moductypes.c +msgid "syntax error in uctypes descriptor" +msgstr "" + +#: shared-bindings/touchio/TouchIn.c +msgid "threshold must be in the range 0-65536" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes a 9-sequence" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes exactly 1 argument" +msgstr "" + +#: shared-bindings/busio/UART.c +msgid "timeout >100 (units are now seconds, not msecs)" +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "timeout must be >= 0.0" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" +msgstr "" + +#: shared-module/struct/__init__.c +msgid "too many arguments provided with the given format" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "" + +#: py/objstr.c +msgid "tuple index out of range" +msgstr "" + +#: py/obj.c +msgid "tuple/list has wrong length" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "tuple/list required on RHS" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "tx and rx cannot both be None" +msgstr "" + +#: py/objtype.c +msgid "type '%q' is not an acceptable base type" +msgstr "" + +#: py/objtype.c +msgid "type is not an acceptable base type" +msgstr "" + +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" +msgstr "" + +#: py/objtype.c +msgid "type takes 1 or 3 arguments" +msgstr "" + +#: py/objint_longlong.c +msgid "ulonglong too large" +msgstr "" + +#: py/emitnative.c +msgid "unary op %q not implemented" +msgstr "" + +#: py/parse.c +msgid "unexpected indent" +msgstr "" + +#: py/bc.c +msgid "unexpected keyword argument" +msgstr "" + +#: py/bc.c py/objnamedtuple.c +msgid "unexpected keyword argument '%q'" +msgstr "" + +#: py/lexer.c +msgid "unicode name escapes" +msgstr "" + +#: py/parse.c +msgid "unindent does not match any outer indentation level" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown conversion specifier %c" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type '%s'" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'float'" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'str'" +msgstr "" + +#: py/compile.c +msgid "unknown type" +msgstr "" + +#: py/emitnative.c +msgid "unknown type '%q'" +msgstr "" + +#: py/objstr.c +msgid "unmatched '{' in format" +msgstr "" + +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "unsupported %q type" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "" + +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "" + +#: py/runtime.c +msgid "unsupported type for %q: '%s'" +msgstr "" + +#: py/runtime.c +msgid "unsupported type for operator" +msgstr "" + +#: py/runtime.c +msgid "unsupported types for %q: '%s', '%s'" +msgstr "" + +#: py/objint.c +#, c-format +msgid "value must fit in %d byte(s)" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "value_count must be > 0" +msgstr "" + +#: shared-bindings/_bleio/Scanner.c +msgid "window must be <= interval" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "write_args must be a list, tuple, or None" +msgstr "" + +#: py/objstr.c +msgid "wrong number of arguments" +msgstr "" + +#: py/runtime.c +msgid "wrong number of values to unpack" +msgstr "" + +#: shared-module/displayio/Shape.c +msgid "x value out of bounds" +msgstr "" + +#: shared-bindings/displayio/Shape.c +msgid "y should be an int" +msgstr "" + +#: shared-module/displayio/Shape.c +msgid "y value out of bounds" +msgstr "" + +#: py/objrange.c +msgid "zero step" +msgstr "" + +#~ msgid "All event channels " +#~ msgstr "Avast! All th' event channels " + +#~ msgid "All timers " +#~ msgstr "Heave-to! All th' timers be used" + +#~ msgid "Clock unit " +#~ msgstr "Blimey! Clock unit " + +#~ msgid "DAC already " +#~ msgstr "Blimey! DAC already under sail" + +#~ msgid "Invalid clock pin" +#~ msgstr "Avast! Clock pin be invalid" diff --git a/locale/es.po b/locale/es.po new file mode 100644 index 00000000000..bcb0515596c --- /dev/null +++ b/locale/es.po @@ -0,0 +1,3050 @@ +# Spanish translation. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Carlos Diaz , 2018. +# Juan Biondi , 2018. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"PO-Revision-Date: 2018-08-24 22:56-0500\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.1.1\n" + +#: main.c +msgid "" +"\n" +"Code done running. Waiting for reload.\n" +msgstr "" +"\n" +"El código terminó su ejecución. Esperando para recargar.\n" + +#: py/obj.c +msgid " File \"%q\"" +msgstr " Archivo \"%q\"" + +#: py/obj.c +msgid " File \"%q\", line %d" +msgstr " Archivo \"%q\", línea %d" + +#: main.c +msgid " output:\n" +msgstr " salida:\n" + +#: py/objstr.c +#, c-format +msgid "%%c requires int or char" +msgstr "%%c requiere int o char" + +#: shared-bindings/microcontroller/Pin.c +msgid "%q in use" +msgstr "%q está siendo utilizado" + +#: py/obj.c +msgid "%q index out of range" +msgstr "%q indice fuera de rango" + +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "%q indices deben ser enteros, no %s" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c +msgid "%q must be >= 1" +msgstr "%q debe ser >= 1" + +#: shared-bindings/fontio/BuiltinFont.c +msgid "%q should be an int" +msgstr "%q debe ser un int" + +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" +msgstr "%q() toma %d argumentos posicionales pero %d fueron dados" + +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "argumento '%q' requerido" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" +msgstr "'%s' espera una etiqueta" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" +msgstr "'%s' espera un registro" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects a special register" +msgstr "'%s' espera un carácter" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an FPU register" +msgstr "'%s' espera un registro de FPU" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "'%s' espera una dirección de forma [a, b]" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" +msgstr "'%s' espera un entero" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects at most r%d" +msgstr "'%s' espera a lo sumo r%d" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "'%s' espera {r0, r1, ...}" + +#: py/emitinlinextensa.c +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "'%s' entero %d no esta dentro del rango %d..%d" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "'%s' entero 0x%x no cabe en la máscara 0x%x" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item assignment" +msgstr "el objeto '%s' no soporta la asignación de elementos" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item deletion" +msgstr "objeto '%s' no soporta la eliminación de elementos" + +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" +msgstr "objeto '%s' no tiene atributo '%q'" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not an iterator" +msgstr "objeto '%s' no es un iterator" + +#: py/objtype.c py/runtime.c +#, c-format +msgid "'%s' object is not callable" +msgstr "objeto '%s' no puede ser llamado" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not iterable" +msgstr "objeto '%s' no es iterable" + +#: py/obj.c +#, c-format +msgid "'%s' object is not subscriptable" +msgstr "el objeto '%s' no es suscriptable" + +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" +msgstr "'=' alineación no permitida en el especificador string format" + +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" +msgstr "'S' y 'O' no son compatibles con los tipos de formato" + +#: py/compile.c +msgid "'align' requires 1 argument" +msgstr "'align' requiere 1 argumento" + +#: py/compile.c +msgid "'await' outside function" +msgstr "'await' fuera de la función" + +#: py/compile.c +msgid "'break' outside loop" +msgstr "'break' fuera de un bucle" + +#: py/compile.c +msgid "'continue' outside loop" +msgstr "'continue' fuera de un bucle" + +#: py/compile.c +msgid "'data' requires at least 2 arguments" +msgstr "'data' requiere como minomo 2 argumentos" + +#: py/compile.c +msgid "'data' requires integer arguments" +msgstr "'data' requiere argumentos de tipo entero" + +#: py/compile.c +msgid "'label' requires 1 argument" +msgstr "'label' requiere 1 argumento" + +#: py/compile.c +msgid "'return' outside function" +msgstr "'return' fuera de una función" + +#: py/compile.c +msgid "'yield' outside function" +msgstr "'yield' fuera de una función" + +#: py/compile.c +msgid "*x must be assignment target" +msgstr "*x debe ser objetivo de la tarea" + +#: py/obj.c +msgid ", in %q\n" +msgstr ", en %q\n" + +#: py/objcomplex.c +msgid "0.0 to a complex power" +msgstr "0.0 a una potencia compleja" + +#: py/modbuiltins.c +msgid "3-arg pow() not supported" +msgstr "pow() con 3 argumentos no soportado" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "A hardware interrupt channel is already in use" +msgstr "El canal EXTINT ya está siendo utilizado" + +#: shared-bindings/_bleio/Address.c +#, c-format +msgid "Address must be %d bytes long" +msgstr "La dirección debe ser %d bytes de largo" + +#: shared-bindings/_bleio/Address.c +msgid "Address type out of range" +msgstr "" + +#: ports/nrf/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" +msgstr "Todos los periféricos I2C están siendo usados" + +#: ports/nrf/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" +msgstr "Todos los periféricos SPI están siendo usados" + +#: ports/nrf/common-hal/busio/UART.c +msgid "All UART peripherals are in use" +msgstr "Todos los periféricos UART están siendo usados" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "Todos los canales de eventos estan siendo usados" + +#: ports/atmel-samd/audio_dma.c ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "All sync event channels in use" +msgstr "" +"Todos los canales de eventos de sincronización (sync event channels) están " +"siendo utilizados" + +#: shared-bindings/pulseio/PWMOut.c +msgid "All timers for this pin are in use" +msgstr "Todos los timers para este pin están siendo utilizados" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: shared-module/_pew/PewPew.c +msgid "All timers in use" +msgstr "Todos los timers en uso" + +#: ports/nrf/common-hal/analogio/AnalogOut.c +msgid "AnalogOut functionality not supported" +msgstr "Funcionalidad AnalogOut no soportada" + +#: shared-bindings/analogio/AnalogOut.c +msgid "AnalogOut is only 16 bits. Value must be less than 65536." +msgstr "AnalogOut es solo de 16 bits. Value debe ser menos a 65536." + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "AnalogOut not supported on given pin" +msgstr "El pin proporcionado no soporta AnalogOut" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" +msgstr "Otro envío ya está activo" + +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" +msgstr "Array debe contener media palabra (type 'H')" + +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." +msgstr "Valores del array deben ser bytes individuales." + +#: supervisor/shared/safe_mode.c +msgid "Attempted heap allocation when MicroPython VM not running.\n" +msgstr "" +"Intento de allocation de heap cuando la VM de MicroPython no estaba " +"corriendo.\n" + +#: main.c +msgid "Auto-reload is off.\n" +msgstr "Auto-recarga deshabilitada.\n" + +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "" +"Auto-reload habilitado. Simplemente guarda los archivos via USB para " +"ejecutarlos o entra al REPL para desabilitarlos.\n" + +#: shared-module/displayio/Display.c +msgid "Below minimum frame rate" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Bit clock and word select must share a clock unit" +msgstr "Bit clock y word select deben compartir una unidad de reloj" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Bit depth must be multiple of 8." +msgstr "Bits depth debe ser múltiplo de 8." + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "Both pins must support hardware interrupts" +msgstr "Ambos pines deben soportar interrupciones por hardware" + +#: shared-bindings/displayio/Display.c +msgid "Brightness must be 0-1.0" +msgstr "" + +#: shared-bindings/supervisor/__init__.c +msgid "Brightness must be between 0 and 255" +msgstr "El brillo debe estar entro 0 y 255" + +#: shared-bindings/displayio/Display.c +msgid "Brightness not adjustable" +msgstr "El brillo no se puede ajustar" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "Tamaño de buffer incorrecto. Debe ser de %d bytes." + +#: shared-bindings/displayio/Display.c +msgid "Buffer is not a bytearray." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Buffer is too small" +msgstr "" + +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Buffer length %d too big. It must be less than %d" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c +msgid "Buffer must be at least length 1" +msgstr "Buffer debe ser de longitud 1 como minimo" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +#, c-format +msgid "Bus pin %d is already in use" +msgstr "Bus pin %d ya está siendo utilizado" + +#: shared-bindings/_bleio/UUID.c +msgid "Byte buffer must be 16 bytes." +msgstr "Byte buffer debe de ser 16 bytes" + +#: shared-bindings/nvm/ByteArray.c +msgid "Bytes must be between 0 and 255." +msgstr "Bytes debe estar entre 0 y 255." + +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Can not use dotstar with %s" +msgstr "No se puede usar dotstar con %s" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" +msgstr "No se puede eliminar valores" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/nrf/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "No puede ser pull mientras este en modo de salida" + +#: ports/nrf/common-hal/microcontroller/Processor.c +msgid "Cannot get temperature" +msgstr "No se puede obtener la temperatura." + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Cannot output both channels on the same pin" +msgstr "No se puede tener ambos canales en el mismo pin" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot read without MISO pin." +msgstr "No se puede leer sin pin MISO." + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Cannot record to a file" +msgstr "No se puede grabar en un archivo" + +#: shared-module/storage/__init__.c +msgid "Cannot remount '/' when USB is active." +msgstr "No se puede volver a montar '/' cuando el USB esta activo." + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +msgid "Cannot reset into bootloader because no bootloader is present." +msgstr "No se puede reiniciar a bootloader porque no hay bootloader presente." + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Cannot set value when direction is input." +msgstr "No se puede asignar un valor cuando la dirección es input." + +#: py/objslice.c +msgid "Cannot subclass slice" +msgstr "Cannot subclass slice" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot transfer without MOSI and MISO pins." +msgstr "No se puede transmitir sin pines MOSI y MISO." + +#: extmod/moductypes.c +msgid "Cannot unambiguously get sizeof scalar" +msgstr "No se puede obtener inequívocamente sizeof escalar" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot write without MOSI pin." +msgstr "No se puede escribir sin pin MOSI." + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" +msgstr "CharateristicBuffer escritura no proporcionada" + +#: shared-module/bitbangio/SPI.c +msgid "Clock pin init failed." +msgstr "Clock pin init fallido" + +#: shared-module/bitbangio/I2C.c +msgid "Clock stretch too long" +msgstr "Clock stretch demasiado largo " + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" +msgstr "Clock unit está siendo utilizado" + +#: shared-bindings/_pew/PewPew.c +msgid "Column entry must be digitalio.DigitalInOut" +msgstr "Entrada de columna debe ser digitalio.DigitalInOut" + +#: shared-bindings/displayio/I2CDisplay.c +msgid "Command must be 0-255" +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +msgid "Command must be an int between 0 and 255" +msgstr "Command debe estar entre 0 y 255." + +#: py/persistentcode.c +msgid "Corrupt .mpy file" +msgstr "" + +#: py/emitglue.c +msgid "Corrupt raw code" +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "No se puede descodificar ble_uuid, err 0x%04x" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "Could not initialize UART" +msgstr "No se puede inicializar la UART" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate first buffer" +msgstr "No se pudo asignar el primer buffer" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate second buffer" +msgstr "No se pudo asignar el segundo buffer" + +#: supervisor/shared/safe_mode.c +msgid "Crash into the HardFault_Handler.\n" +msgstr "Choque en el HardFault_Handler.\n" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "DAC already in use" +msgstr "DAC ya está siendo utilizado" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +msgid "Data 0 pin must be byte aligned" +msgstr "El pin Data 0 debe estar alineado a bytes" + +#: shared-module/audiocore/WaveFile.c +msgid "Data chunk must follow fmt chunk" +msgstr "Trozo de datos debe seguir fmt chunk" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Data too large for advertisement packet" +msgstr "Data es muy grande para el paquete de advertisement." + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Destination capacity is smaller than destination_length." +msgstr "Capacidad de destino es mas pequeña que destination_length." + +#: shared-bindings/displayio/Display.c +msgid "Display must have a 16 bit colorspace." +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Display rotation must be in 90 degree increments" +msgstr "Rotación de display debe ser en incrementos de 90 grados" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Drive mode not used when direction is input." +msgstr "Modo Drive no se usa cuando la dirección es input." + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "EXTINT channel already in use" +msgstr "El canal EXTINT ya está siendo utilizado" + +#: extmod/modure.c +msgid "Error in regex" +msgstr "Error en regex" + +#: shared-bindings/microcontroller/Pin.c +#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c +#: shared-bindings/terminalio/Terminal.c +msgid "Expected a %q" +msgstr "Se espera un %q" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c +msgid "Expected a Characteristic" +msgstr "Se esperaba una Característica." + +#: shared-bindings/_bleio/Service.c +msgid "Expected a Peripheral" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Expected a Service" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c +#: shared-bindings/_bleio/Service.c +msgid "Expected a UUID" +msgstr "Se esperaba un UUID" + +#: shared-bindings/_bleio/Central.c +msgid "Expected an Address" +msgstr "" + +#: shared-module/_pixelbuf/PixelBuf.c +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "Se esperaba un tuple de %d, se obtuvo %d" + +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "Fallo enviando comando" + +#: ports/nrf/sd_mutex.c +#, fuzzy, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "No se puede adquirir el mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Service.c +#, fuzzy, c-format +msgid "Failed to add characteristic, err 0x%04x" +msgstr "Fallo al añadir caracteristica, err: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to add descriptor, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to add service, err 0x%04x" +msgstr "Fallo al agregar servicio. err: 0x%02x" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "Failed to allocate RX buffer" +msgstr "Ha fallado la asignación del buffer RX" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +#, c-format +msgid "Failed to allocate RX buffer of %d bytes" +msgstr "Falló la asignación del buffer RX de %d bytes" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to change softdevice state" +msgstr "No se puede cambiar el estado del softdevice" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to configure advertising, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Central.c +msgid "Failed to connect: timeout" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, c-format +msgid "Failed to continue scanning, err 0x%04x" +msgstr "No se puede iniciar el escaneo. err: 0x%02x" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy +msgid "Failed to discover services" +msgstr "No se puede descubrir servicios" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to get local address" +msgstr "No se puede obtener la dirección local" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to get softdevice state" +msgstr "No se puede obtener el estado del softdevice" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to notify or indicate attribute value, err 0x%04x" +msgstr "Error al notificar o indicar el valor del atributo, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "No se puede leer el valor del atributo. err 0x%02x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, fuzzy, c-format +msgid "Failed to read attribute value, err 0x%04x" +msgstr "Error al leer valor del atributo, err 0x%04" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to read gatts value, err 0x%04x" +msgstr "No se puede escribir el valor del atributo. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" +msgstr "Fallo al registrar el Vendor-Specific UUID, err 0x%04x" + +#: ports/nrf/sd_mutex.c +#, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "No se puede liberar el mutex, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to set device name, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "No se puede inicar el anuncio. err: 0x%04x" + +#: ports/nrf/common-hal/_bleio/Central.c +#, c-format +msgid "Failed to start connecting, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, c-format +msgid "Failed to start scanning, err 0x%04x" +msgstr "No se puede iniciar el escaneo. err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "No se puede detener el anuncio. err: 0x%04x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to write CCCD, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to write attribute value, err 0x%04x" +msgstr "No se puede escribir el valor del atributo. err: 0x%04x" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to write gatts value, err 0x%04x" +msgstr "No se puede escribir el valor del atributo. err: 0x%04x" + +#: py/moduerrno.c +msgid "File exists" +msgstr "El archivo ya existe" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash erase failed" +msgstr "Falló borrado de flash" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash erase failed to start, err 0x%04x" +msgstr "Falló el iniciar borrado de flash, err 0x%04x" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash write failed" +msgstr "Falló la escritura" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash write failed to start, err 0x%04x" +msgstr "Falló el iniciar la escritura de flash, err 0x%04x" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Frequency captured is above capability. Capture Paused." +msgstr "Frecuencia capturada por encima de la capacidad. Captura en pausa." + +#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c +msgid "Function requires lock" +msgstr "La función requiere lock" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Group already used" +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Group full" +msgstr "Group lleno" + +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" +msgstr "Operación I/O en archivo cerrado" + +#: extmod/machine_i2c.c +msgid "I2C operation not supported" +msgstr "operación I2C no soportada" + +#: py/persistentcode.c +msgid "" +"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" +"mpy-update for more info." +msgstr "" +"Archivo .mpy incompatible. Actualice todos los archivos .mpy. Consulte " +"http://adafru.it/mpy-update para más información" + +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" +msgstr "Tamaño incorrecto del buffer" + +#: py/moduerrno.c +msgid "Input/output error" +msgstr "error Input/output" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Invalid %q pin" +msgstr "Pin %q inválido" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Invalid BMP file" +msgstr "Archivo BMP inválido" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c +#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c +msgid "Invalid PWM frequency" +msgstr "Frecuencia PWM inválida" + +#: py/moduerrno.c +msgid "Invalid argument" +msgstr "Argumento inválido" + +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" +msgstr "Inválido bits por valor" + +#: ports/nrf/common-hal/busio/UART.c +msgid "Invalid buffer size" +msgstr "Tamaño de buffer inválido" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Invalid capture period. Valid range: 1 - 500" +msgstr "Inválido periodo de captura. Rango válido: 1 - 500" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid channel count" +msgstr "Cuenta de canales inválida" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Invalid direction." +msgstr "Dirección inválida." + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid file" +msgstr "Archivo inválido" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" +msgstr "Formato de fragmento de formato no válido" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid number of bits" +msgstr "Numero inválido de bits" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid phase" +msgstr "Fase inválida" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +#: shared-bindings/pulseio/PWMOut.c +msgid "Invalid pin" +msgstr "Pin inválido" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for left channel" +msgstr "Pin inválido para canal izquierdo" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for right channel" +msgstr "Pin inválido para canal derecho" + +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/atmel-samd/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c +#: ports/nrf/common-hal/busio/I2C.c +msgid "Invalid pins" +msgstr "pines inválidos" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid polarity" +msgstr "Polaridad inválida" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + +#: shared-bindings/microcontroller/__init__.c +msgid "Invalid run mode." +msgstr "Modo de ejecución inválido." + +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid voice count" +msgstr "Cuenta de voces inválida" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid wave file" +msgstr "Archivo wave inválido" + +#: py/compile.c +msgid "LHS of keyword arg must be an id" +msgstr "LHS del agumento por palabra clave deberia ser un identificador" + +#: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "Layer ya pertenece a un grupo" + +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass." +msgstr "Layer debe ser una subclase de Group o TileGrid." + +#: py/objslice.c +msgid "Length must be an int" +msgstr "Length debe ser un int" + +#: py/objslice.c +msgid "Length must be non-negative" +msgstr "Longitud no deberia ser negativa" + +#: supervisor/shared/safe_mode.c +msgid "" +"Looks like our core CircuitPython code crashed hard. Whoops!\n" +"Please file an issue at https://github.com/adafruit/circuitpython/issues\n" +" with the contents of your CIRCUITPY drive and this message:\n" +msgstr "" +"Parece que nuestro código de CircuitPython ha fallado con fuerza. Whoops!\n" +"Por favor, crea un issue en https://github.com/adafruit/circuitpython/" +"issues\n" +" con el contenido de su unidad CIRCUITPY y este mensaje:\n" + +#: shared-module/bitbangio/SPI.c +msgid "MISO pin init failed." +msgstr "MISO pin init fallido." + +#: shared-module/bitbangio/SPI.c +msgid "MOSI pin init failed." +msgstr "MOSI pin init fallido." + +#: shared-module/displayio/Shape.c +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "Valor máximo de x cuando se refleja es %d" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython NLR jump failed. Likely memory corruption.\n" +msgstr "MicroPython NLR salto fallido. Probable corrupción de memoria.\n" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython fatal error.\n" +msgstr "Error fatal de MicroPython.\n" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Microphone startup delay must be in range 0.0 to 1.0" +msgstr "Micrófono demora de inicio debe estar en el rango 0.0 a 1.0" + +#: shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." +msgstr "Debe de ser una subclase de %q" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "No DAC on chip" +msgstr "El chip no tiene DAC" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "No DMA channel found" +msgstr "No se encontró el canal DMA" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No RX pin" +msgstr "Sin pin RX" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No TX pin" +msgstr "Sin pin TX" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "No available clocks" +msgstr "Relojes no disponibles" + +#: shared-bindings/board/__init__.c +msgid "No default %q bus" +msgstr "Sin bus %q por defecto" + +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" +msgstr "Sin GCLKs libres" + +#: shared-bindings/os/__init__.c +msgid "No hardware random available" +msgstr "No hay hardware random disponible" + +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "Sin soporte de hardware en el pin clk" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "No hardware support on pin" +msgstr "Sin soporte de hardware en pin" + +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" +msgstr "" + +#: py/moduerrno.c +msgid "No space left on device" +msgstr "No queda espacio en el dispositivo" + +#: py/moduerrno.c +msgid "No such file/directory" +msgstr "No existe el archivo/directorio" + +#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Peripheral.c +msgid "Not connected" +msgstr "No conectado" + +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c +msgid "Not playing" +msgstr "No reproduciendo" + +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "" +"El objeto se ha desinicializado y ya no se puede utilizar. Crea un nuevo " +"objeto" + +#: ports/nrf/common-hal/busio/UART.c +msgid "Odd parity is not supported" +msgstr "Paridad impar no soportada" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Only 8 or 16 bit mono with " +msgstr "Solo mono de 8 ó 16 bit con " + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" +msgstr "" +"Solo formato de Windows, sin comprimir BMP soportado: tamaño de encabezado " +"dado es %d" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, fuzzy +msgid "Only slices with step=1 (aka None) are supported" +msgstr "solo se admiten segmentos con step=1 (alias None)" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Oversample must be multiple of 8." +msgstr "El sobremuestreo debe ser un múltiplo de 8" + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" +msgstr "PWM duty_cycle debe ser entre 0 y 65535 inclusivo (16 bit resolution)" + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM frequency not writable when variable_frequency is False on construction." +msgstr "" +"PWM frecuencia no esta escrito cuando el variable_frequency es falso en " +"construcion" + +#: py/moduerrno.c +msgid "Permission denied" +msgstr "Permiso denegado" + +#: ports/atmel-samd/common-hal/analogio/AnalogIn.c +#: ports/nrf/common-hal/analogio/AnalogIn.c +msgid "Pin does not have ADC capabilities" +msgstr "Pin no tiene capacidad ADC" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Pixel beyond bounds of buffer" +msgstr "Pixel beyond bounds of buffer" + +#: py/builtinhelp.c +#, fuzzy +msgid "Plus any modules on the filesystem\n" +msgstr "Incapaz de montar de nuevo el sistema de archivos" + +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "Pop de un buffer Ps2 vacio" + +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload." +msgstr "" +"Presiona cualquier tecla para entrar al REPL. Usa CTRL-D para recargar." + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Pull not used when direction is output." +msgstr "Pull no se usa cuando la dirección es output." + +#: ports/nrf/common-hal/rtc/RTC.c +msgid "RTC calibration is not supported on this board" +msgstr "Calibración de RTC no es soportada en esta placa" + +#: shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" +msgstr "RTC no soportado en esta placa" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, fuzzy +msgid "Range out of bounds" +msgstr "address fuera de límites" + +#: shared-bindings/pulseio/PulseIn.c +msgid "Read-only" +msgstr "Solo-lectura" + +#: extmod/vfs_fat.c py/moduerrno.c +msgid "Read-only filesystem" +msgstr "Sistema de archivos de solo-Lectura" + +#: shared-module/displayio/Bitmap.c +#, fuzzy +msgid "Read-only object" +msgstr "Solo-lectura" + +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Refresh too soon" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" +msgstr "Canal derecho no soportado" + +#: shared-bindings/_pew/PewPew.c +msgid "Row entry must be digitalio.DigitalInOut" +msgstr "La entrada de la fila debe ser digitalio.DigitalInOut" + +#: main.c +msgid "Running in safe mode! Auto-reload is off.\n" +msgstr "Ejecutando en modo seguro! La auto-recarga esta deshabilitada.\n" + +#: main.c +msgid "Running in safe mode! Not running saved code.\n" +msgstr "Ejecutando en modo seguro! No se esta ejecutando el código guardado.\n" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "SDA or SCL needs a pull up" +msgstr "SDA o SCL necesitan una pull up" + +#: shared-bindings/audiocore/Mixer.c +msgid "Sample rate must be positive" +msgstr "Sample rate debe ser positivo" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Sample rate too high. It must be less than %d" +msgstr "Frecuencia de muestreo demasiado alta. Debe ser menor a %d" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" +msgstr "Serializer está siendo utilizado" + +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." +msgstr "Slice y value tienen diferentes longitudes" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/pulseio/PulseIn.c +msgid "Slices not supported" +msgstr "Rebanadas no soportadas" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "Soft device assert, id: 0x%08lX, pc: 0x%08lX" + +#: extmod/modure.c +msgid "Splitting with sub-captures" +msgstr "Dividiendo con sub-capturas" + +#: shared-bindings/supervisor/__init__.c +msgid "Stack size must be at least 256" +msgstr "El tamaño de la pila debe ser de al menos 256" + +#: shared-bindings/multiterminal/__init__.c +msgid "Stream missing readinto() or write() method." +msgstr "A Stream le falta el método readinto() o write()." + +#: supervisor/shared/safe_mode.c +msgid "" +"The CircuitPython heap was corrupted because the stack was too small.\n" +"Please increase stack size limits and press reset (after ejecting " +"CIRCUITPY).\n" +"If you didn't change the stack, then file an issue here with the contents of " +"your CIRCUITPY drive:\n" +msgstr "" +"El heap de CircuitPython estaba corrupto porque el stack era demasiado " +"pequeño.\n" +"Aumente los límites del tamaño del stacj y presione reset (después de " +"expulsarCIRCUITPY).\n" +"Si no cambió el stack, entonces reporte un issue aquí con el contenido desu " +"unidad CIRCUITPY:\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"The `microcontroller` module was used to boot into safe mode. Press reset to " +"exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" +"La alimentación del microcontrolador cayó. Por favor asegurate de que tu " +"fuente de alimentación provee\n" +"suficiente energia para todo el circuito y presiona el botón de reset " +"(despuesde expulsar CIRCUITPY).\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"The reset button was pressed while booting CircuitPython. Press again to " +"exit safe mode.\n" +msgstr "" +"El botón reset fue presionado mientras arrancaba CircuitPython. Presiona " +"otra vez para salir del modo seguro.\n" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "Los bits_per_sample del sample no igualan a los del mixer" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's channel count does not match the mixer's" +msgstr "La cuenta de canales del sample no iguala a las del mixer" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's sample rate does not match the mixer's" +msgstr "El sample rate del sample no iguala al del mixer" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's signedness does not match the mixer's" +msgstr "El signo del sample no iguala al del mixer" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" +msgstr "La altura del Tile debe dividir exacto la altura del bitmap" + +#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile value out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" +msgstr "Ancho del Tile debe dividir exactamente el ancho de mapa de bits" + +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "Para salir, por favor reinicia la tarjeta sin " + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample." +msgstr "Demasiados canales en sample." + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "Too many display busses" +msgstr "Demasiados buses de pantalla" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Too many displays" +msgstr "Muchos displays" + +#: py/obj.c +msgid "Traceback (most recent call last):\n" +msgstr "Traceback (ultima llamada reciente):\n" + +#: shared-bindings/time/__init__.c +msgid "Tuple or struct_time argument required" +msgstr "Argumento tuple o struct_time requerido" + +#: shared-module/usb_hid/Device.c +msgid "USB Busy" +msgstr "USB ocupado" + +#: shared-module/usb_hid/Device.c +msgid "USB Error" +msgstr "Error USB" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID integer value must be 0-0xffff" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "UUID string no es 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" +msgstr "UUID valor no es un str, int o byte buffer" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Unable to allocate buffers for signed conversion" +msgstr "No se pudieron asignar buffers para la conversión con signo" + +#: shared-module/displayio/I2CDisplay.c +#, c-format +msgid "Unable to find I2C Display at %x" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Unable to find free GCLK" +msgstr "No se pudo encontrar un GCLK libre" + +#: py/parse.c +msgid "Unable to init parser" +msgstr "Incapaz de inicializar el parser" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" +msgstr "No se pudo leer los datos de la paleta de colores" + +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." +msgstr "Imposible escribir en nvm" + +#: ports/nrf/common-hal/_bleio/UUID.c +msgid "Unexpected nrfx uuid type" +msgstr "Tipo de uuid nrfx inesperado" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "Número incomparable de elementos en RHS (%d esperado,%d obtenido)" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "Unsupported baudrate" +msgstr "Baudrate no soportado" + +#: shared-module/displayio/display_core.c +#, fuzzy +msgid "Unsupported display bus type" +msgstr "tipo de bitmap no soportado" + +#: shared-module/audiocore/WaveFile.c +msgid "Unsupported format" +msgstr "Formato no soportado" + +#: py/moduerrno.c +msgid "Unsupported operation" +msgstr "Operación no soportada" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Unsupported pull value." +msgstr "valor pull no soportado." + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + +#: py/emitnative.c +msgid "Viper functions don't currently support more than 4 arguments" +msgstr "funciones Viper actualmente no soportan más de 4 argumentos." + +#: shared-module/audiocore/Mixer.c +msgid "Voice index too high" +msgstr "Index de voz demasiado alto" + +#: main.c +msgid "WARNING: Your code filename has two extensions\n" +msgstr "ADVERTENCIA: El nombre de archivo de tu código tiene dos extensiones\n" + +#: py/builtinhelp.c +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" +"Bienvenido a Adafruit CircuitPython %s!\n" +"\n" +"Visita learn.adafruit.com/category/circuitpython para obtener guías de " +"proyectos.\n" +"\n" +"Para listar los módulos incorporados por favor haga `help(\"modules\")`.\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"You are running in safe mode which means something unanticipated happened.\n" +msgstr "" +"Estás ejecutando en modo seguro, lo cual significa que algo realmente malo " +"ha sucedido.\n" + +#: supervisor/shared/safe_mode.c +msgid "You requested starting safe mode by " +msgstr "Solicitaste iniciar en modo seguro por " + +#: py/objtype.c +msgid "__init__() should return None" +msgstr "__init__() deberia devolver None" + +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "__init__() deberia devolver None, no '%s'" + +#: py/objobject.c +msgid "__new__ arg must be a user-type" +msgstr "__new__ arg debe ser un user-type" + +#: extmod/modubinascii.c extmod/moduhashlib.c +msgid "a bytes-like object is required" +msgstr "se requiere un objeto bytes-like" + +#: lib/embed/abort_.c +msgid "abort() called" +msgstr "se llamó abort()" + +#: extmod/machine_mem.c +#, c-format +msgid "address %08x is not aligned to %d bytes" +msgstr "la dirección %08x no esta alineada a %d bytes" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "address out of bounds" +msgstr "address fuera de límites" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "addresses is empty" +msgstr "addresses esta vacío" + +#: py/modbuiltins.c +msgid "arg is an empty sequence" +msgstr "argumento es una secuencia vacía" + +#: py/runtime.c +msgid "argument has wrong type" +msgstr "el argumento tiene un tipo erroneo" + +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +msgid "argument num/types mismatch" +msgstr "argumento número/tipos no coinciden" + +#: py/runtime.c +msgid "argument should be a '%q' not a '%q'" +msgstr "argumento deberia ser un '%q' no un '%q'" + +#: py/objarray.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" +msgstr "array/bytes requeridos en el lado derecho" + +#: py/objstr.c +msgid "attributes not supported yet" +msgstr "atributos aún no soportados" + +#: py/builtinevex.c +msgid "bad compile mode" +msgstr "modo de compilación erroneo" + +#: py/objstr.c +msgid "bad conversion specifier" +msgstr "especificador de conversion erroneo" + +#: py/objstr.c +msgid "bad format string" +msgstr "formato de string erroneo" + +#: py/binary.c +msgid "bad typecode" +msgstr "typecode erroneo" + +#: py/emitnative.c +msgid "binary op %q not implemented" +msgstr "operacion binaria %q no implementada" + +#: shared-bindings/busio/UART.c +msgid "bits must be 7, 8 or 9" +msgstr "bits deben ser 7, 8 ó 9" + +#: extmod/machine_spi.c +msgid "bits must be 8" +msgstr "bits debe ser 8" + +#: shared-bindings/audiocore/Mixer.c +msgid "bits_per_sample must be 8 or 16" +msgstr "bits_per_sample debe ser 8 ó 16" + +#: py/emitinlinethumb.c +msgid "branch not in range" +msgstr "El argumento de chr() no esta en el rango(256)" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "buf es demasiado pequeño. necesita %d bytes" + +#: shared-bindings/audiocore/RawSample.c +msgid "buffer must be a bytes-like object" +msgstr "buffer debe de ser un objeto bytes-like" + +#: shared-module/struct/__init__.c +msgid "buffer size must match format" +msgstr "el tamaño del buffer debe de coincidir con el formato" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" +msgstr "Las secciones del buffer necesitan tener longitud igual" + +#: py/modstruct.c shared-bindings/struct/__init__.c +#: shared-module/struct/__init__.c +msgid "buffer too small" +msgstr "buffer demasiado pequeño" + +#: extmod/machine_spi.c +msgid "buffers must be the same length" +msgstr "los buffers deben de tener la misma longitud" + +#: shared-bindings/_pew/PewPew.c +msgid "buttons must be digitalio.DigitalInOut" +msgstr "los botones necesitan ser digitalio.DigitalInOut" + +#: py/vm.c +msgid "byte code not implemented" +msgstr "codigo byte no implementado" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "byteorder no es instancia de ByteOrder (encontarmos un %s)" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "bytes > 8 bits not supported" +msgstr "bytes > 8 bits no soportados" + +#: py/objstr.c +msgid "bytes value out of range" +msgstr "valor de bytes fuera de rango" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" +msgstr "calibration esta fuera de rango" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" +msgstr "calibration es de solo lectura" + +#: ports/atmel-samd/common-hal/rtc/RTC.c +msgid "calibration value out of range +/-127" +msgstr "Valor de calibración fuera del rango +/-127" + +#: py/emitinlinethumb.c +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "solo puede tener hasta 4 parámetros para ensamblar Thumb" + +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "solo puede tener hasta 4 parámetros para ensamblador Xtensa" + +#: py/persistentcode.c +msgid "can only save bytecode" +msgstr "solo puede almacenar bytecode" + +#: py/objtype.c +msgid "can't add special method to already-subclassed class" +msgstr "no se puede agregar un método a una clase ya subclasificada" + +#: py/compile.c +msgid "can't assign to expression" +msgstr "no se puede asignar a la expresión" + +#: py/obj.c +#, c-format +msgid "can't convert %s to complex" +msgstr "no se puede convertir %s a complejo" + +#: py/obj.c +#, c-format +msgid "can't convert %s to float" +msgstr "no se puede convertir %s a float" + +#: py/obj.c +#, c-format +msgid "can't convert %s to int" +msgstr "no se puede convertir %s a int" + +#: py/objstr.c +msgid "can't convert '%q' object to %q implicitly" +msgstr "no se puede convertir el objeto '%q' a %q implícitamente" + +#: py/objint.c +msgid "can't convert NaN to int" +msgstr "no se puede convertir Nan a int" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "can't convert address to int" +msgstr "no se puede convertir address a int" + +#: py/objint.c +msgid "can't convert inf to int" +msgstr "no se puede convertir inf en int" + +#: py/obj.c +msgid "can't convert to complex" +msgstr "no se puede convertir a complejo" + +#: py/obj.c +msgid "can't convert to float" +msgstr "no se puede convertir a float" + +#: py/obj.c +msgid "can't convert to int" +msgstr "no se puede convertir a int" + +#: py/objstr.c +msgid "can't convert to str implicitly" +msgstr "no se puede convertir a str implícitamente" + +#: py/compile.c +msgid "can't declare nonlocal in outer code" +msgstr "no se puede declarar nonlocal" + +#: py/compile.c +msgid "can't delete expression" +msgstr "no se puede borrar la expresión" + +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" +msgstr "no se puede hacer una operacion binaria entre '%q' y '%q'" + +#: py/objcomplex.c +msgid "can't do truncated division of a complex number" +msgstr "no se puede hacer la división truncada de un número complejo" + +#: py/compile.c +msgid "can't have multiple **x" +msgstr "no puede tener multiples *x" + +#: py/compile.c +msgid "can't have multiple *x" +msgstr "no puede tener multiples *x" + +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "no se puede convertir implícitamente '%q' a 'bool'" + +#: py/emitnative.c +msgid "can't load from '%q'" +msgstr "no se puede cargar desde '%q'" + +#: py/emitnative.c +msgid "can't load with '%q' index" +msgstr "no se puede cargar con el índice '%q'" + +#: py/objgenerator.c +msgid "can't pend throw to just-started generator" +msgstr "no se puede colgar al generador recién iniciado" + +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" +msgstr "" +"no se puede enviar un valor que no sea None a un generador recién iniciado" + +#: py/objnamedtuple.c +msgid "can't set attribute" +msgstr "no se puede asignar el atributo" + +#: py/emitnative.c +msgid "can't store '%q'" +msgstr "no se puede almacenar '%q'" + +#: py/emitnative.c +msgid "can't store to '%q'" +msgstr "no se puede almacenar para '%q'" + +#: py/emitnative.c +msgid "can't store with '%q' index" +msgstr "no se puede almacenar con el indice '%q'" + +#: py/objstr.c +msgid "" +"can't switch from automatic field numbering to manual field specification" +msgstr "" +"no se puede cambiar de la numeración automática de campos a la " +"especificación de campo manual" + +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "" +"no se puede cambiar de especificación de campo manual a numeración " +"automática de campos" + +#: py/objtype.c +msgid "cannot create '%q' instances" +msgstr "no se pueden crear '%q' instancias" + +#: py/objtype.c +msgid "cannot create instance" +msgstr "no se puede crear instancia" + +#: py/runtime.c +msgid "cannot import name %q" +msgstr "no se puede importar name '%q'" + +#: py/builtinimport.c +msgid "cannot perform relative import" +msgstr "no se puedo realizar importación relativa" + +#: py/emitnative.c +msgid "casting" +msgstr "" + +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" +msgstr "chars buffer es demasiado pequeño" + +#: py/modbuiltins.c +msgid "chr() arg not in range(0x110000)" +msgstr "El argumento de chr() esta fuera de rango(0x110000)" + +#: py/modbuiltins.c +msgid "chr() arg not in range(256)" +msgstr "El argumento de chr() no esta en el rango(256)" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "color buffer debe ser 3 bytes (RGB) ó 4 bytes (RGB + pad byte)" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer or int" +msgstr "color buffer deber ser un buffer o un int" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "color buffer deberia ser un bytearray o array de tipo 'b' o 'B'" + +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" +msgstr "color debe estar entre 0x000000 y 0xffffff" + +#: shared-bindings/displayio/ColorConverter.c +msgid "color should be an int" +msgstr "color deberia ser un int" + +#: py/objcomplex.c +msgid "complex division by zero" +msgstr "división compleja por cero" + +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" +msgstr "valores complejos no soportados" + +#: extmod/moduzlib.c +msgid "compression header" +msgstr "encabezado de compresión" + +#: py/parse.c +msgid "constant must be an integer" +msgstr "constant debe ser un entero" + +#: py/emitnative.c +msgid "conversion to object" +msgstr "conversión a objeto" + +#: py/parsenum.c +msgid "decimal numbers not supported" +msgstr "números decimales no soportados" + +#: py/compile.c +msgid "default 'except' must be last" +msgstr "'except' por defecto deberia estar de último" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" +"el buffer de destino debe ser un bytearray o array de tipo 'B' para " +"bit_depth = 8" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "el buffer de destino debe ser un array de tipo 'H' para bit_depth = 16" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination_length must be an int >= 0" +msgstr "destination_length debe ser un int >= 0" + +#: py/objdict.c +msgid "dict update sequence has wrong length" +msgstr "la secuencia de actualizacion del dict tiene una longitud incorrecta" + +#: py/modmath.c py/objfloat.c py/objint_longlong.c py/objint_mpz.c py/runtime.c +#: shared-bindings/math/__init__.c +msgid "division by zero" +msgstr "división por cero" + +#: py/objdeque.c +msgid "empty" +msgstr "vacío" + +#: extmod/moduheapq.c extmod/modutimeq.c +msgid "empty heap" +msgstr "heap vacío" + +#: py/objstr.c +msgid "empty separator" +msgstr "separator vacío" + +#: shared-bindings/random/__init__.c +msgid "empty sequence" +msgstr "secuencia vacía" + +#: py/objstr.c +msgid "end of format while looking for conversion specifier" +msgstr "el final del formato mientras se busca el especificador de conversión" + +#: shared-bindings/displayio/Shape.c +msgid "end_x should be an int" +msgstr "end_x debe ser un int" + +#: ports/nrf/common-hal/busio/UART.c +#, c-format +msgid "error = 0x%08lX" +msgstr "error = 0x%08lx" + +#: py/runtime.c +msgid "exceptions must derive from BaseException" +msgstr "las excepciones deben derivar de BaseException" + +#: py/objstr.c +msgid "expected ':' after format specifier" +msgstr "se esperaba ':' después de un especificador de tipo format" + +#: py/obj.c +msgid "expected tuple/list" +msgstr "se esperaba una tupla/lista" + +#: py/modthread.c +msgid "expecting a dict for keyword args" +msgstr "esperando un diccionario para argumentos por palabra clave" + +#: py/compile.c +msgid "expecting an assembler instruction" +msgstr "esperando una instrucción de ensamblador" + +#: py/compile.c +msgid "expecting just a value for set" +msgstr "esperando solo un valor para set" + +#: py/compile.c +msgid "expecting key:value for dict" +msgstr "esperando la clave:valor para dict" + +#: py/argcheck.c +msgid "extra keyword arguments given" +msgstr "argumento(s) por palabra clave adicionales fueron dados" + +#: py/argcheck.c +msgid "extra positional arguments given" +msgstr "argumento posicional adicional dado" + +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c +msgid "file must be a file opened in byte mode" +msgstr "el archivo deberia ser una archivo abierto en modo byte" + +#: shared-bindings/storage/__init__.c +msgid "filesystem must provide mount method" +msgstr "sistema de archivos debe proporcionar método de montaje" + +#: py/objtype.c +msgid "first argument to super() must be type" +msgstr "primer argumento para super() debe ser de tipo" + +#: extmod/machine_spi.c +msgid "firstbit must be MSB" +msgstr "firstbit debe ser MSB" + +#: py/objint.c +msgid "float too big" +msgstr "" + +#: shared-bindings/_stage/Text.c +msgid "font must be 2048 bytes long" +msgstr "font debe ser 2048 bytes de largo" + +#: py/objstr.c +msgid "format requires a dict" +msgstr "format requiere un dict" + +#: py/objdeque.c +msgid "full" +msgstr "lleno" + +#: py/argcheck.c +msgid "function does not take keyword arguments" +msgstr "la función no tiene argumentos por palabra clave" + +#: py/argcheck.c +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "la función esperaba minimo %d argumentos, tiene %d" + +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" +msgstr "la función tiene múltiples valores para el argumento '%q'" + +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" +msgstr "a la función le hacen falta %d argumentos posicionales requeridos" + +#: py/bc.c +msgid "function missing keyword-only argument" +msgstr "falta palabra clave para función" + +#: py/bc.c +msgid "function missing required keyword argument '%q'" +msgstr "la función requiere del argumento por palabra clave '%q'" + +#: py/bc.c +#, c-format +msgid "function missing required positional argument #%d" +msgstr "la función requiere del argumento posicional #%d" + +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "la función toma %d argumentos posicionales pero le fueron dados %d" + +#: shared-bindings/time/__init__.c +msgid "function takes exactly 9 arguments" +msgstr "la función toma exactamente 9 argumentos." + +#: py/objgenerator.c +msgid "generator already executing" +msgstr "generador ya se esta ejecutando" + +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" +msgstr "generador ignorado GeneratorExit" + +#: shared-bindings/_stage/Layer.c +msgid "graphic must be 2048 bytes long" +msgstr "graphic debe ser 2048 bytes de largo" + +#: extmod/moduheapq.c +msgid "heap must be a list" +msgstr "heap debe ser una lista" + +#: py/compile.c +msgid "identifier redefined as global" +msgstr "identificador redefinido como global" + +#: py/compile.c +msgid "identifier redefined as nonlocal" +msgstr "identificador redefinido como nonlocal" + +#: py/objstr.c +msgid "incomplete format" +msgstr "formato incompleto" + +#: py/objstr.c +msgid "incomplete format key" +msgstr "" + +#: extmod/modubinascii.c +msgid "incorrect padding" +msgstr "relleno (padding) incorrecto" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c py/obj.c +msgid "index out of range" +msgstr "index fuera de rango" + +#: py/obj.c +msgid "indices must be integers" +msgstr "indices deben ser enteros" + +#: py/compile.c +msgid "inline assembler must be a function" +msgstr "ensamblador en línea debe ser una función" + +#: py/parsenum.c +msgid "int() arg 2 must be >= 2 and <= 36" +msgstr "int() arg 2 debe ser >= 2 y <= 36" + +#: py/objstr.c +msgid "integer required" +msgstr "Entero requerido" + +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c +#, c-format +msgid "interval must be in range %s-%s" +msgstr "" + +#: extmod/machine_i2c.c +msgid "invalid I2C peripheral" +msgstr "periférico I2C inválido" + +#: extmod/machine_spi.c +msgid "invalid SPI peripheral" +msgstr "periférico SPI inválido" + +#: lib/netutils/netutils.c +msgid "invalid arguments" +msgstr "argumentos inválidos" + +#: extmod/modussl_axtls.c +msgid "invalid cert" +msgstr "certificado inválido" + +#: extmod/uos_dupterm.c +msgid "invalid dupterm index" +msgstr "index dupterm inválido" + +#: extmod/modframebuf.c +msgid "invalid format" +msgstr "formato inválido" + +#: py/objstr.c +msgid "invalid format specifier" +msgstr "especificador de formato inválido" + +#: extmod/modussl_axtls.c +msgid "invalid key" +msgstr "llave inválida" + +#: py/compile.c +msgid "invalid micropython decorator" +msgstr "decorador de micropython inválido" + +#: shared-bindings/random/__init__.c +msgid "invalid step" +msgstr "" + +#: py/compile.c py/parse.c +msgid "invalid syntax" +msgstr "sintaxis inválida" + +#: py/parsenum.c +msgid "invalid syntax for integer" +msgstr "sintaxis inválida para entero" + +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "sintaxis inválida para entero con base %d" + +#: py/parsenum.c +msgid "invalid syntax for number" +msgstr "sintaxis inválida para número" + +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" +msgstr "issubclass() arg 1 debe ser una clase" + +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "issubclass() arg 2 debe ser una clase o tuple de clases" + +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "" +"join espera una lista de objetos str/bytes consistentes con el mismo objeto" + +#: py/argcheck.c +msgid "keyword argument(s) not yet implemented - use normal args instead" +msgstr "" +"argumento(s) por palabra clave aún no implementados - usa argumentos " +"normales en su lugar" + +#: py/bc.c +msgid "keywords must be strings" +msgstr "palabras clave deben ser strings" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" +msgstr "etiqueta '%q' no definida" + +#: py/compile.c +msgid "label redefined" +msgstr "etiqueta redefinida" + +#: py/stream.c +msgid "length argument not allowed for this type" +msgstr "argumento length no permitido para este tipo" + +#: py/objarray.c +msgid "lhs and rhs should be compatible" +msgstr "lhs y rhs deben ser compatibles" + +#: py/emitnative.c +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "la variable local '%q' tiene el tipo '%q' pero la fuente es '%q'" + +#: py/emitnative.c +msgid "local '%q' used before type known" +msgstr "variable local '%q' usada antes del tipo conocido" + +#: py/vm.c +msgid "local variable referenced before assignment" +msgstr "variable local referenciada antes de la asignación" + +#: py/objint.c +msgid "long int not supported in this build" +msgstr "long int no soportado en esta compilación" + +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" +msgstr "map buffer muy pequeño" + +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" +msgstr "error de dominio matemático" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + +#: py/runtime.c +msgid "maximum recursion depth exceeded" +msgstr "profundidad máxima de recursión excedida" + +#: py/runtime.c +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "la asignación de memoria falló, asignando %u bytes" + +#: py/runtime.c +msgid "memory allocation failed, heap is locked" +msgstr "la asignación de memoria falló, el heap está bloqueado" + +#: py/builtinimport.c +msgid "module not found" +msgstr "módulo no encontrado" + +#: py/compile.c +msgid "multiple *x in assignment" +msgstr "múltiples *x en la asignación" + +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" +msgstr "multiple bases tienen una instancia conel conflicto diseño" + +#: py/objtype.c +msgid "multiple inheritance not supported" +msgstr "herencia multiple no soportada" + +#: py/emitnative.c +msgid "must raise an object" +msgstr "debe hacer un raise de un objeto" + +#: extmod/machine_spi.c +msgid "must specify all of sck/mosi/miso" +msgstr "se deben de especificar sck/mosi/miso" + +#: py/modbuiltins.c +msgid "must use keyword argument for key function" +msgstr "debe utilizar argumento de palabra clave para la función clave" + +#: py/runtime.c +msgid "name '%q' is not defined" +msgstr "name '%q' no esta definido" + +#: shared-bindings/_bleio/Peripheral.c +msgid "name must be a string" +msgstr "name debe de ser un string" + +#: py/runtime.c +msgid "name not defined" +msgstr "name no definido" + +#: py/compile.c +msgid "name reused for argument" +msgstr "name reusado para argumento" + +#: py/emitnative.c +msgid "native yield" +msgstr "yield nativo" + +#: py/runtime.c +#, c-format +msgid "need more than %d values to unpack" +msgstr "necesita más de %d valores para descomprimir" + +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" +msgstr "potencia negativa sin float support" + +#: py/objint_mpz.c py/runtime.c +msgid "negative shift count" +msgstr "cuenta de corrimientos negativo" + +#: py/vm.c +msgid "no active exception to reraise" +msgstr "exception no activa para reraise" + +#: shared-bindings/socket/__init__.c shared-module/network/__init__.c +msgid "no available NIC" +msgstr "NIC no disponible" + +#: py/compile.c +msgid "no binding for nonlocal found" +msgstr "no se ha encontrado ningún enlace para nonlocal" + +#: py/builtinimport.c +msgid "no module named '%q'" +msgstr "ningún módulo se llama '%q'" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "no reset pin available" +msgstr "" + +#: py/runtime.c shared-bindings/_pixelbuf/__init__.c +msgid "no such attribute" +msgstr "no hay tal atributo" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" +msgstr "" + +#: py/compile.c +msgid "non-default argument follows default argument" +msgstr "argumento no predeterminado sigue argumento predeterminado" + +#: extmod/modubinascii.c +msgid "non-hex digit found" +msgstr "digito non-hex encontrado" + +#: py/compile.c +msgid "non-keyword arg after */**" +msgstr "no deberia estar/tener agumento por palabra clave despues de */**" + +#: py/compile.c +msgid "non-keyword arg after keyword arg" +msgstr "" +"no deberia estar/tener agumento por palabra clave despues de argumento por " +"palabra clave" + +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" +msgstr "no es 128-bit UUID" + +#: py/objstr.c +msgid "not all arguments converted during string formatting" +msgstr "" +"no todos los argumentos fueron convertidos durante el formato de string" + +#: py/objstr.c +msgid "not enough arguments for format string" +msgstr "no suficientes argumentos para format string" + +#: py/obj.c +#, c-format +msgid "object '%s' is not a tuple or list" +msgstr "el objeto '%s' no es una tupla o lista" + +#: py/obj.c +msgid "object does not support item assignment" +msgstr "el objeto no soporta la asignación de elementos" + +#: py/obj.c +msgid "object does not support item deletion" +msgstr "object no soporta la eliminación de elementos" + +#: py/obj.c +msgid "object has no len" +msgstr "el objeto no tiene longitud" + +#: py/obj.c +msgid "object is not subscriptable" +msgstr "el objeto no es suscriptable" + +#: py/runtime.c +msgid "object not an iterator" +msgstr "objeto no es un iterator" + +#: py/objtype.c py/runtime.c +msgid "object not callable" +msgstr "objeto no puede ser llamado" + +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" +msgstr "objeto no en secuencia" + +#: py/runtime.c +msgid "object not iterable" +msgstr "objeto no iterable" + +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" +msgstr "el objeto de tipo '%s' no tiene len()" + +#: py/obj.c +msgid "object with buffer protocol required" +msgstr "objeto con protocolo de buffer requerido" + +#: extmod/modubinascii.c +msgid "odd-length string" +msgstr "string de longitud impar" + +#: py/objstr.c py/objstrunicode.c +#, fuzzy +msgid "offset out of bounds" +msgstr "address fuera de límites" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" +msgstr "solo se admiten segmentos con step=1 (alias None)" + +#: py/modbuiltins.c +msgid "ord expects a character" +msgstr "ord espera un carácter" + +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "ord() espera un carácter, pero encontró un string de longitud %d" + +#: py/objint_mpz.c +msgid "overflow converting long int to machine word" +msgstr "desbordamiento convirtiendo long int a palabra de máquina" + +#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c +msgid "palette must be 32 bytes long" +msgstr "palette debe ser 32 bytes de largo" + +#: shared-bindings/displayio/Palette.c +msgid "palette_index should be an int" +msgstr "palette_index deberia ser un int" + +#: py/compile.c +msgid "parameter annotation must be an identifier" +msgstr "parámetro de anotación debe ser un identificador" + +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" +msgstr "los parámetros deben ser registros en secuencia de a2 a a5" + +#: py/emitinlinethumb.c +msgid "parameters must be registers in sequence r0 to r3" +msgstr "los parametros deben ser registros en secuencia del r0 al r3" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel coordinates out of bounds" +msgstr "coordenadas del pixel fuera de límites" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel value requires too many bits" +msgstr "valor del pixel require demasiado bits" + +#: shared-bindings/displayio/TileGrid.c +msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" +msgstr "pixel_shader debe ser displayio.Palette o displayio.ColorConverter" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" +msgstr "pop de un PulseIn vacío" + +#: py/objset.c +msgid "pop from an empty set" +msgstr "pop desde un set vacío" + +#: py/objlist.c +msgid "pop from empty list" +msgstr "pop desde una lista vacía" + +#: py/objdict.c +msgid "popitem(): dictionary is empty" +msgstr "popitem(): diccionario vacío" + +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" +msgstr "el 3er argumento de pow() no puede ser 0" + +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" +msgstr "pow() con 3 argumentos requiere enteros" + +#: extmod/modutimeq.c +msgid "queue overflow" +msgstr "desbordamiento de cola(queue)" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "rawbuf is not the same size as buf" +msgstr "rawbuf no es el mismo tamaño que buf" + +#: shared-bindings/_pixelbuf/__init__.c +#, fuzzy +msgid "readonly attribute" +msgstr "atributo no legible" + +#: py/builtinimport.c +msgid "relative import" +msgstr "import relativo" + +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" +msgstr "longitud solicitada %d pero el objeto tiene longitud %d" + +#: py/compile.c +msgid "return annotation must be an identifier" +msgstr "la anotación de retorno debe ser un identificador" + +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" +msgstr "retorno esperado '%q' pero se obtuvo '%q'" + +#: py/objstr.c +msgid "rsplit(None,n)" +msgstr "rsplit(None,n)" + +#: shared-bindings/audiocore/RawSample.c +msgid "" +"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " +"'B'" +msgstr "" +"sample_source buffer debe ser un bytearray o un array de tipo 'h', 'H', 'b' " +"o'B'" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" +msgstr "frecuencia de muestreo fuera de rango" + +#: py/modmicropython.c +msgid "schedule stack full" +msgstr "" + +#: lib/utils/pyexec.c py/builtinimport.c +msgid "script compilation not supported" +msgstr "script de compilación no soportado" + +#: py/objstr.c +msgid "sign not allowed in string format specifier" +msgstr "signo no permitido en el espeficador de string format" + +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" +msgstr "signo no permitido con el especificador integer format 'c'" + +#: py/objstr.c +msgid "single '}' encountered in format string" +msgstr "un solo '}' encontrado en format string" + +#: shared-bindings/time/__init__.c +msgid "sleep length must be non-negative" +msgstr "la longitud de sleep no puede ser negativa" + +#: py/objslice.c py/sequence.c +msgid "slice step cannot be zero" +msgstr "slice step no puede ser cero" + +#: py/objint.c py/sequence.c +msgid "small int overflow" +msgstr "pequeño int desbordamiento" + +#: main.c +msgid "soft reboot\n" +msgstr "reinicio suave\n" + +#: py/objstr.c +msgid "start/end indices" +msgstr "índices inicio/final" + +#: shared-bindings/displayio/Shape.c +#, fuzzy +msgid "start_x should be an int" +msgstr "y deberia ser un int" + +#: shared-bindings/random/__init__.c +msgid "step must be non-zero" +msgstr "paso debe ser numero no cero" + +#: shared-bindings/busio/UART.c +msgid "stop must be 1 or 2" +msgstr "stop debe ser 1 ó 2" + +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" +msgstr "stop no se puede alcanzar del principio" + +#: py/stream.c +msgid "stream operation not supported" +msgstr "operación stream no soportada" + +#: py/objstrunicode.c +msgid "string index out of range" +msgstr "string index fuera de rango" + +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" +msgstr "índices de string deben ser enteros, no %s" + +#: py/stream.c +msgid "string not supported; use bytes or bytearray" +msgstr "string no soportado; usa bytes o bytearray" + +#: extmod/moductypes.c +msgid "struct: cannot index" +msgstr "struct: no se puede indexar" + +#: extmod/moductypes.c +msgid "struct: index out of range" +msgstr "struct: index fuera de rango" + +#: extmod/moductypes.c +msgid "struct: no fields" +msgstr "struct: sin campos" + +#: py/objstr.c +msgid "substring not found" +msgstr "substring no encontrado" + +#: py/compile.c +msgid "super() can't find self" +msgstr "super() no puede encontrar self" + +#: extmod/modujson.c +msgid "syntax error in JSON" +msgstr "error de sintaxis en JSON" + +#: extmod/moductypes.c +msgid "syntax error in uctypes descriptor" +msgstr "error de sintaxis en el descriptor uctypes" + +#: shared-bindings/touchio/TouchIn.c +msgid "threshold must be in the range 0-65536" +msgstr "limite debe ser en el rango 0-65536" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes a 9-sequence" +msgstr "time.struct_time() toma un sequencio 9" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes exactly 1 argument" +msgstr "time.struct_time() acepta exactamente 1 argumento" + +#: shared-bindings/busio/UART.c +msgid "timeout >100 (units are now seconds, not msecs)" +msgstr "timepo muerto >100 (unidades en segundos)" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "timeout must be >= 0.0" +msgstr "tiempo muerto debe ser >= 0.0" + +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" +msgstr "timestamp fuera de rango para plataform time_t" + +#: shared-module/struct/__init__.c +msgid "too many arguments provided with the given format" +msgstr "demasiados argumentos provistos con el formato dado" + +#: py/runtime.c +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "demasiados valores para descomprimir (%d esperado)" + +#: py/objstr.c +msgid "tuple index out of range" +msgstr "tuple index fuera de rango" + +#: py/obj.c +msgid "tuple/list has wrong length" +msgstr "tupla/lista tiene una longitud incorrecta" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "tuple/list required on RHS" +msgstr "tuple/lista se require en RHS" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "tx and rx cannot both be None" +msgstr "Ambos tx y rx no pueden ser None" + +#: py/objtype.c +msgid "type '%q' is not an acceptable base type" +msgstr "type '%q' no es un tipo de base aceptable" + +#: py/objtype.c +msgid "type is not an acceptable base type" +msgstr "type no es un tipo de base aceptable" + +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" +msgstr "objeto de tipo '%q' no tiene atributo '%q'" + +#: py/objtype.c +msgid "type takes 1 or 3 arguments" +msgstr "type acepta 1 ó 3 argumentos" + +#: py/objint_longlong.c +msgid "ulonglong too large" +msgstr "ulonglong muy largo" + +#: py/emitnative.c +msgid "unary op %q not implemented" +msgstr "Operación unica %q no implementada" + +#: py/parse.c +msgid "unexpected indent" +msgstr "sangría inesperada" + +#: py/bc.c +msgid "unexpected keyword argument" +msgstr "argumento por palabra clave inesperado" + +#: py/bc.c py/objnamedtuple.c +msgid "unexpected keyword argument '%q'" +msgstr "argumento por palabra clave inesperado '%q'" + +#: py/lexer.c +msgid "unicode name escapes" +msgstr "nombre en unicode escapa" + +#: py/parse.c +msgid "unindent does not match any outer indentation level" +msgstr "sangría no coincide con ningún nivel exterior" + +#: py/objstr.c +#, c-format +msgid "unknown conversion specifier %c" +msgstr "especificador de conversión %c desconocido" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type '%s'" +msgstr "codigo format desconocido '%c' para el typo de objeto '%s'" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'float'" +msgstr "codigo format desconocido '%c' para el typo de objeto 'float'" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'str'" +msgstr "codigo format desconocido '%c' para objeto de tipo 'str'" + +#: py/compile.c +msgid "unknown type" +msgstr "tipo desconocido" + +#: py/emitnative.c +msgid "unknown type '%q'" +msgstr "tipo desconocido '%q'" + +#: py/objstr.c +msgid "unmatched '{' in format" +msgstr "No coinciden '{' en format" + +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" +msgstr "atributo no legible" + +#: shared-bindings/displayio/TileGrid.c +msgid "unsupported %q type" +msgstr "tipo de %q no soportado" + +#: py/emitinlinethumb.c +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "instrucción de tipo Thumb no admitida '%s' con %d argumentos" + +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "instrucción Xtensa '%s' con %d argumentos no soportada" + +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "carácter no soportado '%c' (0x%x) en índice %d" + +#: py/runtime.c +msgid "unsupported type for %q: '%s'" +msgstr "tipo no soportado para %q: '%s'" + +#: py/runtime.c +msgid "unsupported type for operator" +msgstr "tipo de operador no soportado" + +#: py/runtime.c +msgid "unsupported types for %q: '%s', '%s'" +msgstr "tipos no soportados para %q: '%s', '%s'" + +#: py/objint.c +#, c-format +msgid "value must fit in %d byte(s)" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "value_count must be > 0" +msgstr "" + +#: shared-bindings/_bleio/Scanner.c +msgid "window must be <= interval" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "write_args must be a list, tuple, or None" +msgstr "" + +#: py/objstr.c +msgid "wrong number of arguments" +msgstr "numero erroneo de argumentos" + +#: py/runtime.c +msgid "wrong number of values to unpack" +msgstr "numero erroneo de valores a descomprimir" + +#: shared-module/displayio/Shape.c +#, fuzzy +msgid "x value out of bounds" +msgstr "address fuera de límites" + +#: shared-bindings/displayio/Shape.c +msgid "y should be an int" +msgstr "y deberia ser un int" + +#: shared-module/displayio/Shape.c +#, fuzzy +msgid "y value out of bounds" +msgstr "address fuera de límites" + +#: py/objrange.c +msgid "zero step" +msgstr "paso cero" + +#~ msgid "AP required" +#~ msgstr "AP requerido" + +#~ msgid "Address is not %d bytes long or is in wrong format" +#~ msgstr "Direción no es %d bytes largo o esta en el formato incorrecto" + +#~ msgid "Can't add services in Central mode" +#~ msgstr "No se pueden agregar servicio en modo Central" + +#~ msgid "Can't advertise in Central mode" +#~ msgstr "No se puede anunciar en modo Central" + +#~ msgid "Can't change the name in Central mode" +#~ msgstr "No se puede cambiar el nombre en modo Central" + +#~ msgid "Can't connect in Peripheral mode" +#~ msgstr "No se puede conectar en modo Peripheral" + +#~ msgid "Cannot connect to AP" +#~ msgstr "No se puede conectar a AP" + +#~ msgid "Cannot disconnect from AP" +#~ msgstr "No se puede desconectar de AP" + +#~ msgid "Cannot set STA config" +#~ msgstr "No se puede establecer STA config" + +#~ msgid "Cannot update i/f status" +#~ msgstr "No se puede actualizar i/f status" + +#~ msgid "Characteristic UUID doesn't match Service UUID" +#~ msgstr "Características UUID no concide con el Service UUID" + +#~ msgid "Characteristic already in use by another Service." +#~ msgstr "Características ya esta en uso por otro Serivice" + +#, fuzzy +#~ msgid "Data too large for the advertisement packet" +#~ msgstr "Los datos no caben en el paquete de anuncio." + +#~ msgid "Don't know how to pass object to native function" +#~ msgstr "No se sabe cómo pasar objeto a función nativa" + +#~ msgid "ESP8226 does not support safe mode." +#~ msgstr "ESP8226 no soporta modo seguro." + +#~ msgid "ESP8266 does not support pull down." +#~ msgstr "ESP8266 no soporta pull down." + +#~ msgid "Error in ffi_prep_cif" +#~ msgstr "Error en ffi_prep_cif" + +#, fuzzy +#~ msgid "Failed to acquire mutex" +#~ msgstr "No se puede adquirir el mutex, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to add service" +#~ msgstr "No se puede detener el anuncio. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to connect:" +#~ msgstr "No se puede conectar. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to continue scanning" +#~ msgstr "No se puede iniciar el escaneo. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to create mutex" +#~ msgstr "No se puede leer el valor del atributo. status 0x%02x" + +#, fuzzy +#~ msgid "Failed to notify or indicate attribute value, err %0x04x" +#~ msgstr "No se puede notificar el valor del anuncio. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to read attribute value, err %0x04x" +#~ msgstr "No se puede leer el valor del atributo. status 0x%02x" + +#, fuzzy +#~ msgid "Failed to release mutex" +#~ msgstr "No se puede liberar el mutex, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to start advertising" +#~ msgstr "No se puede inicar el anuncio. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to start scanning" +#~ msgstr "No se puede iniciar el escaneo. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to stop advertising" +#~ msgstr "No se puede detener el anuncio. status: 0x%02x" + +#~ msgid "Function requires lock." +#~ msgstr "La función requiere lock" + +#~ msgid "GPIO16 does not support pull up." +#~ msgstr "GPIO16 no soporta pull up." + +#~ msgid "Invalid bit clock pin" +#~ msgstr "Pin bit clock inválido" + +#~ msgid "Invalid clock pin" +#~ msgstr "Pin clock inválido" + +#~ msgid "Invalid data pin" +#~ msgstr "Pin de datos inválido" + +#~ msgid "Maximum PWM frequency is %dhz." +#~ msgstr "La frecuencia máxima del PWM es %dhz." + +#~ msgid "Minimum PWM frequency is 1hz." +#~ msgstr "La frecuencia mínima del PWM es 1hz" + +#~ msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." +#~ msgstr "" +#~ "PWM de múltiples frecuencias no soportado. El PWM ya se estableció a %dhz" + +#~ msgid "Must be a Group subclass." +#~ msgstr "Debe ser una subclase de Group." + +#~ msgid "No PulseIn support for %q" +#~ msgstr "Sin soporte PulseIn para %q" + +#~ msgid "No hardware support for analog out." +#~ msgstr "Sin soporte de hardware para analog out" + +#~ msgid "Not connected." +#~ msgstr "No conectado." + +#~ msgid "Only Windows format, uncompressed BMP supported %d" +#~ msgstr "Solo formato Windows, BMP sin comprimir soportado %d" + +#~ msgid "Only bit maps of 8 bit color or less are supported" +#~ msgstr "Solo se admiten bit maps de color de 8 bits o menos" + +#~ msgid "" +#~ "Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d " +#~ "bpp given" +#~ msgstr "" +#~ "Solo se admiten BMP monocromos, indexados de 8bpp y 16bpp o superiores:% " +#~ "d bppdado" + +#~ msgid "Only true color (24 bpp or higher) BMP supported %x" +#~ msgstr "Solo color verdadero (24 bpp o superior) BMP admitido %x" + +#~ msgid "Only tx supported on UART1 (GPIO2)." +#~ msgstr "Solo tx soportada en UART1 (GPIO2)" + +#~ msgid "PWM not supported on pin %d" +#~ msgstr "El pin %d no soporta PWM" + +#~ msgid "Pin %q does not have ADC capabilities" +#~ msgstr "Pin %q no tiene capacidades de ADC" + +#~ msgid "Pin(16) doesn't support pull" +#~ msgstr "Pin(16) no soporta para pull" + +#~ msgid "Pins not valid for SPI" +#~ msgstr "Pines no válidos para SPI" + +#~ msgid "STA must be active" +#~ msgstr "STA debe estar activo" + +#~ msgid "STA required" +#~ msgstr "STA requerido" + +#~ msgid "Tile indices must be 0 - 255" +#~ msgstr "Los índices de Tile deben ser 0 - 255" + +#~ msgid "UART(%d) does not exist" +#~ msgstr "UART(%d) no existe" + +#~ msgid "UART(1) can't read" +#~ msgstr "UART(1) no puede leer" + +#~ msgid "UUID integer value not in range 0 to 0xffff" +#~ msgstr "El valor integer UUID no está en el rango 0 a 0xffff" + +#~ msgid "Unable to remount filesystem" +#~ msgstr "Incapaz de montar de nuevo el sistema de archivos" + +#~ msgid "Unknown type" +#~ msgstr "Tipo desconocido" + +#~ msgid "Use esptool to erase flash and re-upload Python instead" +#~ msgstr "" +#~ "Usa esptool para borrar la flash y vuelve a cargar Python en su lugar" + +#~ msgid "bad GATT role" +#~ msgstr "mal GATT role" + +#~ msgid "buffer too long" +#~ msgstr "buffer demasiado largo" + +#~ msgid "can query only one param" +#~ msgstr "puede consultar solo un param" + +#~ msgid "can't get AP config" +#~ msgstr "no se puede obtener AP config" + +#~ msgid "can't get STA config" +#~ msgstr "no se puede obtener STA config" + +#~ msgid "can't set AP config" +#~ msgstr "no se puede establecer AP config" + +#~ msgid "can't set STA config" +#~ msgstr "no se puede establecer STA config" + +#~ msgid "characteristics includes an object that is not a Characteristic" +#~ msgstr "characteristics incluye un objeto que no es una Characteristica" + +#~ msgid "either pos or kw args are allowed" +#~ msgstr "ya sea pos o kw args son permitidos" + +#~ msgid "expected a DigitalInOut" +#~ msgstr "se espera un DigitalInOut" + +#~ msgid "expecting a pin" +#~ msgstr "esperando un pin" + +#~ msgid "ffi_prep_closure_loc" +#~ msgstr "ffi_prep_closure_loc" + +#~ msgid "flash location must be below 1MByte" +#~ msgstr "la ubicación de la flash debe estar debajo de 1MByte" + +#~ msgid "frequency can only be either 80Mhz or 160MHz" +#~ msgstr "la frecuencia solo puede ser 80MHz ó 160MHz" + +#~ msgid "impossible baudrate" +#~ msgstr "baudrate imposible" + +#~ msgid "interval not in range 0.0020 to 10.24" +#~ msgstr "El intervalo está fuera del rango de 0.0020 a 10.24" + +#~ msgid "invalid alarm" +#~ msgstr "alarma inválida" + +#~ msgid "invalid buffer length" +#~ msgstr "longitud de buffer inválida" + +#~ msgid "invalid data bits" +#~ msgstr "data bits inválidos" + +#~ msgid "invalid pin" +#~ msgstr "pin inválido" + +#~ msgid "invalid stop bits" +#~ msgstr "stop bits inválidos" + +#~ msgid "len must be multiple of 4" +#~ msgstr "len debe de ser múltiple de 4" + +#~ msgid "memory allocation failed, allocating %u bytes for native code" +#~ msgstr "" +#~ "falló la asignación de memoria, asignando %u bytes para código nativo" + +#~ msgid "not a valid ADC Channel: %d" +#~ msgstr "no es un canal ADC válido: %d" + +#~ msgid "pin does not have IRQ capabilities" +#~ msgstr "pin sin capacidades IRQ" + +#~ msgid "position must be 2-tuple" +#~ msgstr "posición debe ser 2-tuple" + +#~ msgid "row must be packed and word aligned" +#~ msgstr "la fila debe estar empacada y la palabra alineada" + +#~ msgid "scan failed" +#~ msgstr "scan ha fallado" + +#~ msgid "services includes an object that is not a Service" +#~ msgstr "services incluye un objeto que no es servicio" + +#~ msgid "tile index out of bounds" +#~ msgstr "el indice del tile fuera de limite" + +#~ msgid "too many arguments" +#~ msgstr "muchos argumentos" + +#~ msgid "unknown config param" +#~ msgstr "parámetro config desconocido" + +#~ msgid "unknown status param" +#~ msgstr "status param desconocido" + +#~ msgid "wifi_set_ip_info() failed" +#~ msgstr "wifi_set_ip_info() ha fallado" diff --git a/locale/fil.po b/locale/fil.po new file mode 100644 index 00000000000..3e8041e6de1 --- /dev/null +++ b/locale/fil.po @@ -0,0 +1,3027 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"PO-Revision-Date: 2018-12-20 22:15-0800\n" +"Last-Translator: Timothy \n" +"Language-Team: fil\n" +"Language: fil\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.1.1\n" + +#: main.c +msgid "" +"\n" +"Code done running. Waiting for reload.\n" +msgstr "" + +#: py/obj.c +msgid " File \"%q\"" +msgstr " File \"%q\"" + +#: py/obj.c +msgid " File \"%q\", line %d" +msgstr " File \"%q\", line %d" + +#: main.c +msgid " output:\n" +msgstr " output:\n" + +#: py/objstr.c +#, c-format +msgid "%%c requires int or char" +msgstr "%%c nangangailangan ng int o char" + +#: shared-bindings/microcontroller/Pin.c +msgid "%q in use" +msgstr "%q ay ginagamit" + +#: py/obj.c +msgid "%q index out of range" +msgstr "%q indeks wala sa sakop" + +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "%q indeks ay dapat integers, hindi %s" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c +#, fuzzy +msgid "%q must be >= 1" +msgstr "aarehas na haba dapat ang buffer slices" + +#: shared-bindings/fontio/BuiltinFont.c +#, fuzzy +msgid "%q should be an int" +msgstr "y ay dapat int" + +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" +msgstr "" +"Ang %q() ay kumukuha ng %d positional arguments pero %d lang ang binigay" + +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "'%q' argument kailangan" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" +msgstr "'%s' umaasa ng label" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" +msgstr "Inaasahan ng '%s' ang isang rehistro" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects a special register" +msgstr "Inaasahan ng '%s' ang isang espesyal na register" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an FPU register" +msgstr "Inaasahan ng '%s' ang isang FPU register" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "Inaasahan ng '%s' ang isang address sa [a, b]" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" +msgstr "Inaasahan ng '%s' ang isang integer" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects at most r%d" +msgstr "Inaasahan ng '%s' ang hangang r%d" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "Inaasahan ng '%s' ay {r0, r1, …}" + +#: py/emitinlinextensa.c +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "'%s' integer %d ay wala sa sakop ng %d..%d" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "'%s' integer 0x%x ay wala sa mask na sakop ng 0x%x" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item assignment" +msgstr "'%s' object hindi sumusuporta ng item assignment" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item deletion" +msgstr "'%s' object ay hindi sumusuporta sa pagtanggal ng item" + +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" +msgstr "'%s' object ay walang attribute '%q'" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not an iterator" +msgstr "'%s' object ay hindi iterator" + +#: py/objtype.c py/runtime.c +#, c-format +msgid "'%s' object is not callable" +msgstr "'%s' object hindi matatawag" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not iterable" +msgstr "'%s' object ay hindi ma i-iterable" + +#: py/obj.c +#, c-format +msgid "'%s' object is not subscriptable" +msgstr "'%s' object ay hindi maaaring i-subscript" + +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" +msgstr "'=' Gindi pinapayagan ang alignment sa pag specify ng string format" + +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" +msgstr "Ang 'S' at 'O' ay hindi suportadong uri ng format" + +#: py/compile.c +msgid "'align' requires 1 argument" +msgstr "'align' kailangan ng 1 argument" + +#: py/compile.c +msgid "'await' outside function" +msgstr "'await' sa labas ng function" + +#: py/compile.c +msgid "'break' outside loop" +msgstr "'break' sa labas ng loop" + +#: py/compile.c +msgid "'continue' outside loop" +msgstr "'continue' sa labas ng loop" + +#: py/compile.c +msgid "'data' requires at least 2 arguments" +msgstr "'data' kailangan ng hindi bababa sa 2 argument" + +#: py/compile.c +msgid "'data' requires integer arguments" +msgstr "'data' kailangan ng integer arguments" + +#: py/compile.c +msgid "'label' requires 1 argument" +msgstr "'label' kailangan ng 1 argument" + +#: py/compile.c +msgid "'return' outside function" +msgstr "'return' sa labas ng function" + +#: py/compile.c +msgid "'yield' outside function" +msgstr "'yield' sa labas ng function" + +#: py/compile.c +msgid "*x must be assignment target" +msgstr "*x ay dapat na assignment target" + +#: py/obj.c +msgid ", in %q\n" +msgstr ", sa %q\n" + +#: py/objcomplex.c +msgid "0.0 to a complex power" +msgstr "0.0 para sa complex power" + +#: py/modbuiltins.c +msgid "3-arg pow() not supported" +msgstr "3-arg pow() hindi suportado" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "A hardware interrupt channel is already in use" +msgstr "Isang channel ng hardware interrupt ay ginagamit na" + +#: shared-bindings/_bleio/Address.c +#, fuzzy, c-format +msgid "Address must be %d bytes long" +msgstr "ang palette ay dapat 32 bytes ang haba" + +#: shared-bindings/_bleio/Address.c +msgid "Address type out of range" +msgstr "" + +#: ports/nrf/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" +msgstr "Lahat ng I2C peripherals ginagamit" + +#: ports/nrf/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" +msgstr "Lahat ng SPI peripherals ay ginagamit" + +#: ports/nrf/common-hal/busio/UART.c +#, fuzzy +msgid "All UART peripherals are in use" +msgstr "Lahat ng I2C peripherals ginagamit" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "Lahat ng event channels ginagamit" + +#: ports/atmel-samd/audio_dma.c ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "All sync event channels in use" +msgstr "Lahat ng sync event channels ay ginagamit" + +#: shared-bindings/pulseio/PWMOut.c +msgid "All timers for this pin are in use" +msgstr "Lahat ng timers para sa pin na ito ay ginagamit" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: shared-module/_pew/PewPew.c +msgid "All timers in use" +msgstr "Lahat ng timer ginagamit" + +#: ports/nrf/common-hal/analogio/AnalogOut.c +msgid "AnalogOut functionality not supported" +msgstr "Hindi supportado ang AnalogOut" + +#: shared-bindings/analogio/AnalogOut.c +msgid "AnalogOut is only 16 bits. Value must be less than 65536." +msgstr "AnalogOut ay 16 bits. Value ay dapat hindi hihigit pa sa 65536." + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "AnalogOut not supported on given pin" +msgstr "Hindi supportado ang AnalogOut sa ibinigay na pin" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" +msgstr "Isa pang send ay aktibo na" + +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" +msgstr "May halfwords (type 'H') dapat ang array" + +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." +msgstr "Array values ay dapat single bytes." + +#: supervisor/shared/safe_mode.c +msgid "Attempted heap allocation when MicroPython VM not running.\n" +msgstr "" + +#: main.c +msgid "Auto-reload is off.\n" +msgstr "Awtomatikong pag re-reload ay OFF.\n" + +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "" +"Ang awtomatikong pag re-reload ay ON. i-save lamang ang mga files sa USB " +"para patakbuhin sila o pasukin ang REPL para i-disable ito.\n" + +#: shared-module/displayio/Display.c +msgid "Below minimum frame rate" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Bit clock and word select must share a clock unit" +msgstr "Ang bit clock at word select dapat makibahagi sa isang clock unit" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Bit depth must be multiple of 8." +msgstr "Bit depth ay dapat multiple ng 8." + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "Both pins must support hardware interrupts" +msgstr "Ang parehong mga pin ay dapat na sumusuporta sa hardware interrupts" + +#: shared-bindings/displayio/Display.c +msgid "Brightness must be 0-1.0" +msgstr "" + +#: shared-bindings/supervisor/__init__.c +msgid "Brightness must be between 0 and 255" +msgstr "Ang liwanag ay dapat sa gitna ng 0 o 255" + +#: shared-bindings/displayio/Display.c +msgid "Brightness not adjustable" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "Mali ang size ng buffer. Dapat %d bytes." + +#: shared-bindings/displayio/Display.c +msgid "Buffer is not a bytearray." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Buffer is too small" +msgstr "" + +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Buffer length %d too big. It must be less than %d" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c +msgid "Buffer must be at least length 1" +msgstr "Buffer dapat ay hindi baba sa 1 na haba" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +#, fuzzy, c-format +msgid "Bus pin %d is already in use" +msgstr "Ginagamit na ang DAC" + +#: shared-bindings/_bleio/UUID.c +#, fuzzy +msgid "Byte buffer must be 16 bytes." +msgstr "buffer ay dapat bytes-like object" + +#: shared-bindings/nvm/ByteArray.c +msgid "Bytes must be between 0 and 255." +msgstr "Sa gitna ng 0 o 255 dapat ang bytes." + +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Can not use dotstar with %s" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" +msgstr "Hindi mabura ang values" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/nrf/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "Hindi makakakuha ng pull habang nasa output mode" + +#: ports/nrf/common-hal/microcontroller/Processor.c +#, fuzzy +msgid "Cannot get temperature" +msgstr "Hindi makuha ang temperatura. status 0x%02x" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Cannot output both channels on the same pin" +msgstr "Hindi maaaring output ang mga parehong channel sa parehong pin" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot read without MISO pin." +msgstr "Hindi maaring mabasa kapag walang MISO pin." + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Cannot record to a file" +msgstr "Hindi ma-record sa isang file" + +#: shared-module/storage/__init__.c +msgid "Cannot remount '/' when USB is active." +msgstr "Hindi ma-remount '/' kapag aktibo ang USB." + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +msgid "Cannot reset into bootloader because no bootloader is present." +msgstr "Hindi ma-reset sa bootloader dahil walang bootloader." + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Cannot set value when direction is input." +msgstr "Hindi ma i-set ang value kapag ang direksyon ay input." + +#: py/objslice.c +msgid "Cannot subclass slice" +msgstr "Hindi magawa ang sublcass slice" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot transfer without MOSI and MISO pins." +msgstr "Hindi maaaring ilipat kapag walang MOSI at MISO pin." + +#: extmod/moductypes.c +msgid "Cannot unambiguously get sizeof scalar" +msgstr "Hindi puedeng hindi sigurado ang get sizeof scalar" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot write without MOSI pin." +msgstr "Hindi maaring isulat kapag walang MOSI pin." + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Clock pin init failed." +msgstr "Nabigo sa pag init ng Clock pin." + +#: shared-module/bitbangio/I2C.c +msgid "Clock stretch too long" +msgstr "Masyadong mahaba ang Clock stretch" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" +msgstr "Clock unit ginagamit" + +#: shared-bindings/_pew/PewPew.c +msgid "Column entry must be digitalio.DigitalInOut" +msgstr "" + +#: shared-bindings/displayio/I2CDisplay.c +msgid "Command must be 0-255" +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +#, fuzzy +msgid "Command must be an int between 0 and 255" +msgstr "Sa gitna ng 0 o 255 dapat ang bytes." + +#: py/persistentcode.c +msgid "Corrupt .mpy file" +msgstr "" + +#: py/emitglue.c +msgid "Corrupt raw code" +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "Could not initialize UART" +msgstr "Hindi ma-initialize ang UART" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate first buffer" +msgstr "Hindi ma-iallocate ang first buffer" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate second buffer" +msgstr "Hindi ma-iallocate ang second buffer" + +#: supervisor/shared/safe_mode.c +msgid "Crash into the HardFault_Handler.\n" +msgstr "Nagcrash sa HardFault_Handler.\n" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "DAC already in use" +msgstr "Ginagamit na ang DAC" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +#, fuzzy +msgid "Data 0 pin must be byte aligned" +msgstr "graphic ay dapat 2048 bytes ang haba" + +#: shared-module/audiocore/WaveFile.c +msgid "Data chunk must follow fmt chunk" +msgstr "Dapat sunurin ng Data chunk ang fmt chunk" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy +msgid "Data too large for advertisement packet" +msgstr "Hindi makasya ang data sa loob ng advertisement packet" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Destination capacity is smaller than destination_length." +msgstr "" +"Ang kapasidad ng destinasyon ay mas maliit kaysa sa destination_length." + +#: shared-bindings/displayio/Display.c +msgid "Display must have a 16 bit colorspace." +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Display rotation must be in 90 degree increments" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Drive mode not used when direction is input." +msgstr "Drive mode ay hindi ginagamit kapag ang direksyon ay input." + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "EXTINT channel already in use" +msgstr "Ginagamit na ang EXTINT channel" + +#: extmod/modure.c +msgid "Error in regex" +msgstr "May pagkakamali sa REGEX" + +#: shared-bindings/microcontroller/Pin.c +#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c +#: shared-bindings/terminalio/Terminal.c +msgid "Expected a %q" +msgstr "Umasa ng %q" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c +#, fuzzy +msgid "Expected a Characteristic" +msgstr "Hindi mabasa and Characteristic." + +#: shared-bindings/_bleio/Service.c +msgid "Expected a Peripheral" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Expected a Service" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c +#: shared-bindings/_bleio/Service.c +#, fuzzy +msgid "Expected a UUID" +msgstr "Umasa ng %q" + +#: shared-bindings/_bleio/Central.c +msgid "Expected an Address" +msgstr "" + +#: shared-module/_pixelbuf/PixelBuf.c +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "" + +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + +#: ports/nrf/sd_mutex.c +#, fuzzy, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "Nabigo sa pag kuha ng mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Service.c +#, fuzzy, c-format +msgid "Failed to add characteristic, err 0x%04x" +msgstr "Nabigo sa paglagay ng characteristic, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to add descriptor, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy, c-format +msgid "Failed to add service, err 0x%04x" +msgstr "Hindi matagumpay ang paglagay ng service, status: 0x%08lX" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "Failed to allocate RX buffer" +msgstr "Nabigong ilaan ang RX buffer" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +#, c-format +msgid "Failed to allocate RX buffer of %d bytes" +msgstr "Nabigong ilaan ang RX buffer ng %d bytes" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, fuzzy +msgid "Failed to change softdevice state" +msgstr "Nabigo sa pagbago ng softdevice state, error: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to configure advertising, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Central.c +msgid "Failed to connect: timeout" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, fuzzy, c-format +msgid "Failed to continue scanning, err 0x%04x" +msgstr "Hindi maituloy ang pag scan, status: 0x%0xlX" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy +msgid "Failed to discover services" +msgstr "Nabigo sa pagdiscover ng services, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, fuzzy +msgid "Failed to get local address" +msgstr "Nabigo sa pagkuha ng local na address, , error: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, fuzzy +msgid "Failed to get softdevice state" +msgstr "Nabigo sa pagkuha ng softdevice state, error: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to notify or indicate attribute value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, fuzzy, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "Hindi mabasa ang value ng attribute, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "Failed to read attribute value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy, c-format +msgid "Failed to read gatts value, err 0x%04x" +msgstr "Hindi maisulat ang gatts value, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, fuzzy, c-format +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" +msgstr "Hindi matagumpay ang paglagay ng Vender Specific UUID, status: 0x%08lX" + +#: ports/nrf/sd_mutex.c +#, fuzzy, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "Nabigo sa pagrelease ng mutex, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to set device name, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "Hindi masimulaan ang advertisement, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Central.c +#, c-format +msgid "Failed to start connecting, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, fuzzy, c-format +msgid "Failed to start scanning, err 0x%04x" +msgstr "Hindi masimulaan mag i-scan, status: 0x%0xlX" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "Hindi mahinto ang advertisement, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to write CCCD, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy, c-format +msgid "Failed to write attribute value, err 0x%04x" +msgstr "Hindi maisulat ang attribute value, status: 0x%08lX" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy, c-format +msgid "Failed to write gatts value, err 0x%04x" +msgstr "Hindi maisulat ang gatts value, status: 0x%08lX" + +#: py/moduerrno.c +msgid "File exists" +msgstr "Mayroong file" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash erase failed" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash erase failed to start, err 0x%04x" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash write failed" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash write failed to start, err 0x%04x" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Frequency captured is above capability. Capture Paused." +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c +msgid "Function requires lock" +msgstr "Function nangangailangan ng lock" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Group already used" +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Group full" +msgstr "Puno ang group" + +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" +msgstr "I/O operasyon sa saradong file" + +#: extmod/machine_i2c.c +msgid "I2C operation not supported" +msgstr "Hindi supportado ang operasyong I2C" + +#: py/persistentcode.c +msgid "" +"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" +"mpy-update for more info." +msgstr "" +".mpy file hindi compatible. Maaring i-update lahat ng .mpy files. See http://" +"adafru.it/mpy-update for more info." + +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" +msgstr "" + +#: py/moduerrno.c +msgid "Input/output error" +msgstr "May mali sa Input/Output" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Invalid %q pin" +msgstr "Mali ang %q pin" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Invalid BMP file" +msgstr "Mali ang BMP file" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c +#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c +msgid "Invalid PWM frequency" +msgstr "Mali ang PWM frequency" + +#: py/moduerrno.c +msgid "Invalid argument" +msgstr "Maling argumento" + +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +msgid "Invalid buffer size" +msgstr "Mali ang buffer size" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Invalid capture period. Valid range: 1 - 500" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid channel count" +msgstr "Maling bilang ng channel" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Invalid direction." +msgstr "Mali ang direksyon." + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid file" +msgstr "Mali ang file" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" +msgstr "Mali ang format ng chunk size" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid number of bits" +msgstr "Mali ang bilang ng bits" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid phase" +msgstr "Mali ang phase" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +#: shared-bindings/pulseio/PWMOut.c +msgid "Invalid pin" +msgstr "Mali ang pin" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for left channel" +msgstr "Mali ang pin para sa kaliwang channel" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for right channel" +msgstr "Mali ang pin para sa kanang channel" + +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/atmel-samd/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c +#: ports/nrf/common-hal/busio/I2C.c +msgid "Invalid pins" +msgstr "Mali ang pins" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid polarity" +msgstr "Mali ang polarity" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + +#: shared-bindings/microcontroller/__init__.c +msgid "Invalid run mode." +msgstr "Mali ang run mode." + +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid voice count" +msgstr "Maling bilang ng voice" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid wave file" +msgstr "May hindi tama sa wave file" + +#: py/compile.c +msgid "LHS of keyword arg must be an id" +msgstr "LHS ng keyword arg ay dapat na id" + +#: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass." +msgstr "" + +#: py/objslice.c +msgid "Length must be an int" +msgstr "Haba ay dapat int" + +#: py/objslice.c +msgid "Length must be non-negative" +msgstr "Haba ay dapat hindi negatibo" + +#: supervisor/shared/safe_mode.c +msgid "" +"Looks like our core CircuitPython code crashed hard. Whoops!\n" +"Please file an issue at https://github.com/adafruit/circuitpython/issues\n" +" with the contents of your CIRCUITPY drive and this message:\n" +msgstr "" +"Mukhang ang core CircuitPython code nag crash. Ay!\n" +"Maaring mag file ng issue sa https://github.com/adafruit/circuitpython/" +"issues\n" +"kasama ng laman ng iyong CIRCUITPY drive at ang message na ito:\n" + +#: shared-module/bitbangio/SPI.c +msgid "MISO pin init failed." +msgstr "Hindi ma-initialize ang MISO pin." + +#: shared-module/bitbangio/SPI.c +msgid "MOSI pin init failed." +msgstr "Hindi ma-initialize ang MOSI pin." + +#: shared-module/displayio/Shape.c +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython NLR jump failed. Likely memory corruption.\n" +msgstr "CircuitPython NLR jump nabigo. Maaring memory corruption.\n" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython fatal error.\n" +msgstr "CircuitPython fatal na pagkakamali.\n" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Microphone startup delay must be in range 0.0 to 1.0" +msgstr "Ang delay ng startup ng mikropono ay dapat na nasa 0.0 hanggang 1.0" + +#: shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "No DAC on chip" +msgstr "Walang DAC sa chip" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "No DMA channel found" +msgstr "Walang DMA channel na mahanap" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No RX pin" +msgstr "Walang RX pin" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No TX pin" +msgstr "Walang TX pin" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "No available clocks" +msgstr "" + +#: shared-bindings/board/__init__.c +msgid "No default %q bus" +msgstr "Walang default na %q bus" + +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" +msgstr "Walang libreng GCLKs" + +#: shared-bindings/os/__init__.c +msgid "No hardware random available" +msgstr "Walang magagamit na hardware random" + +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "No hardware support on pin" +msgstr "Walang support sa hardware ang pin" + +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" +msgstr "" + +#: py/moduerrno.c +msgid "No space left on device" +msgstr "" + +#: py/moduerrno.c +msgid "No such file/directory" +msgstr "Walang file/directory" + +#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Peripheral.c +#, fuzzy +msgid "Not connected" +msgstr "Hindi maka connect sa AP" + +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c +msgid "Not playing" +msgstr "Hindi playing" + +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "" +"Object ay deinitialized at hindi na magagamit. Lumikha ng isang bagong " +"Object." + +#: ports/nrf/common-hal/busio/UART.c +msgid "Odd parity is not supported" +msgstr "Odd na parity ay hindi supportado" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Only 8 or 16 bit mono with " +msgstr "Tanging 8 o 16 na bit mono na may " + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, fuzzy +msgid "Only slices with step=1 (aka None) are supported" +msgstr "ang mga slices lamang na may hakbang = 1 (aka None) ang sinusuportahan" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Oversample must be multiple of 8." +msgstr "Oversample ay dapat multiple ng 8." + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" +msgstr "PWM duty_cycle ay dapat sa loob ng 0 at 65535 (16 bit resolution)" + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM frequency not writable when variable_frequency is False on construction." +msgstr "" +"PWM frequency hindi writable kapag variable_frequency ay False sa pag buo." + +#: py/moduerrno.c +msgid "Permission denied" +msgstr "Walang pahintulot" + +#: ports/atmel-samd/common-hal/analogio/AnalogIn.c +#: ports/nrf/common-hal/analogio/AnalogIn.c +msgid "Pin does not have ADC capabilities" +msgstr "Ang pin ay walang kakayahan sa ADC" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Pixel beyond bounds of buffer" +msgstr "" + +#: py/builtinhelp.c +msgid "Plus any modules on the filesystem\n" +msgstr "Kasama ang kung ano pang modules na sa filesystem\n" + +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload." +msgstr "" +"Pindutin ang anumang key upang pumasok sa REPL. Gamitin ang CTRL-D upang i-" +"reload." + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Pull not used when direction is output." +msgstr "Pull hindi ginagamit kapag ang direksyon ay output." + +#: ports/nrf/common-hal/rtc/RTC.c +msgid "RTC calibration is not supported on this board" +msgstr "RTC calibration ay hindi supportado ng board na ito" + +#: shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" +msgstr "Hindi supportado ang RTC sa board na ito" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, fuzzy +msgid "Range out of bounds" +msgstr "wala sa sakop ang address" + +#: shared-bindings/pulseio/PulseIn.c +msgid "Read-only" +msgstr "Basahin-lamang" + +#: extmod/vfs_fat.c py/moduerrno.c +msgid "Read-only filesystem" +msgstr "Basahin-lamang mode" + +#: shared-module/displayio/Bitmap.c +#, fuzzy +msgid "Read-only object" +msgstr "Basahin-lamang" + +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Refresh too soon" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" +msgstr "Hindi supportado ang kanang channel" + +#: shared-bindings/_pew/PewPew.c +msgid "Row entry must be digitalio.DigitalInOut" +msgstr "" + +#: main.c +msgid "Running in safe mode! Auto-reload is off.\n" +msgstr "Tumatakbo sa safe mode! Awtomatikong pag re-reload ay OFF.\n" + +#: main.c +msgid "Running in safe mode! Not running saved code.\n" +msgstr "Tumatakbo sa safe mode! Hindi tumatakbo ang nai-save na code.\n" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "SDA or SCL needs a pull up" +msgstr "Kailangan ng pull up resistors ang SDA o SCL" + +#: shared-bindings/audiocore/Mixer.c +msgid "Sample rate must be positive" +msgstr "Sample rate ay dapat positibo" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Sample rate too high. It must be less than %d" +msgstr "Sample rate ay masyadong mataas. Ito ay dapat hindi hiigit sa %d" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" +msgstr "Serializer ginagamit" + +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." +msgstr "Slice at value iba't ibang haba." + +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/pulseio/PulseIn.c +msgid "Slices not supported" +msgstr "Hindi suportado ang Slices" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: extmod/modure.c +msgid "Splitting with sub-captures" +msgstr "Binibiyak gamit ang sub-captures" + +#: shared-bindings/supervisor/__init__.c +msgid "Stack size must be at least 256" +msgstr "Ang laki ng stack ay dapat na hindi bababa sa 256" + +#: shared-bindings/multiterminal/__init__.c +msgid "Stream missing readinto() or write() method." +msgstr "Stream kulang ng readinto() o write() method." + +#: supervisor/shared/safe_mode.c +msgid "" +"The CircuitPython heap was corrupted because the stack was too small.\n" +"Please increase stack size limits and press reset (after ejecting " +"CIRCUITPY).\n" +"If you didn't change the stack, then file an issue here with the contents of " +"your CIRCUITPY drive:\n" +msgstr "" +"Ang CircuitPython heap ay na corrupt dahil ang stack ay maliit.\n" +"Maaring i-increase ang stack size limit at i-press ang reset (pagkatapos i-" +"eject ang CIRCUITPY.\n" +"Kung hindi mo pinalitan ang stack, mag file ng issue dito kasama ng laman ng " +"CIRCUITPY drive:\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"The `microcontroller` module was used to boot into safe mode. Press reset to " +"exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" +"Ang kapangyarihan ng mikrokontroller ay bumaba. Mangyaring suriin ang power " +"supply \n" +"pindutin ang reset (pagkatapos i-eject ang CIRCUITPY).\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"The reset button was pressed while booting CircuitPython. Press again to " +"exit safe mode.\n" +msgstr "" +"Ang reset button ay pinindot habang nag boot ang CircuitPython. Pindutin " +"ulit para lumabas sa safe mode.\n" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "Ang bits_per_sample ng sample ay hindi tugma sa mixer" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's channel count does not match the mixer's" +msgstr "Ang channel count ng sample ay hindi tugma sa mixer" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's sample rate does not match the mixer's" +msgstr "Ang sample rate ng sample ay hindi tugma sa mixer" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's signedness does not match the mixer's" +msgstr "Ang signedness ng sample hindi tugma sa mixer" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile value out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "Para lumabas, paki-reset ang board na wala ang " + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample." +msgstr "Sobra ang channels sa sample." + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "Too many display busses" +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Too many displays" +msgstr "" + +#: py/obj.c +msgid "Traceback (most recent call last):\n" +msgstr "Traceback (pinakahuling huling tawag): \n" + +#: shared-bindings/time/__init__.c +msgid "Tuple or struct_time argument required" +msgstr "Tuple o struct_time argument kailangan" + +#: shared-module/usb_hid/Device.c +msgid "USB Busy" +msgstr "Busy ang USB" + +#: shared-module/usb_hid/Device.c +msgid "USB Error" +msgstr "May pagkakamali ang USB" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID integer value must be 0-0xffff" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Unable to allocate buffers for signed conversion" +msgstr "Hindi ma-allocate ang buffers para sa naka-sign na conversion" + +#: shared-module/displayio/I2CDisplay.c +#, c-format +msgid "Unable to find I2C Display at %x" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Unable to find free GCLK" +msgstr "Hindi mahanap ang libreng GCLK" + +#: py/parse.c +msgid "Unable to init parser" +msgstr "Hindi ma-init ang parser" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." +msgstr "Hindi ma i-sulat sa NVM." + +#: ports/nrf/common-hal/_bleio/UUID.c +#, fuzzy +msgid "Unexpected nrfx uuid type" +msgstr "hindi inaasahang indent" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "Unsupported baudrate" +msgstr "Hindi supportadong baudrate" + +#: shared-module/displayio/display_core.c +#, fuzzy +msgid "Unsupported display bus type" +msgstr "Hindi supportadong tipo ng bitmap" + +#: shared-module/audiocore/WaveFile.c +msgid "Unsupported format" +msgstr "Hindi supportadong format" + +#: py/moduerrno.c +msgid "Unsupported operation" +msgstr "Hindi sinusuportahang operasyon" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Unsupported pull value." +msgstr "Hindi suportado ang pull value." + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + +#: py/emitnative.c +msgid "Viper functions don't currently support more than 4 arguments" +msgstr "" +"Ang mga function ng Viper ay kasalukuyang hindi sumusuporta sa higit sa 4 na " +"argumento" + +#: shared-module/audiocore/Mixer.c +msgid "Voice index too high" +msgstr "Index ng Voice ay masyadong mataas" + +#: main.c +msgid "WARNING: Your code filename has two extensions\n" +msgstr "BABALA: Ang pangalan ng file ay may dalawang extension\n" + +#: py/builtinhelp.c +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" +"Mabuhay sa Adafruit CircuitPython %s!\n" +"\n" +"Mangyaring bisitahin ang learn.adafruit.com/category/circuitpython para sa " +"project guides.\n" +"\n" +"Para makita ang listahan ng modules, `help(“modulesâ€)`.\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"You are running in safe mode which means something unanticipated happened.\n" +msgstr "Ikaw ay tumatakbo sa safe mode dahil may masamang nangyari.\n" + +#: supervisor/shared/safe_mode.c +msgid "You requested starting safe mode by " +msgstr "Ikaw ang humiling sa safe mode sa pamamagitan ng " + +#: py/objtype.c +msgid "__init__() should return None" +msgstr "__init __ () dapat magbalik na None" + +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "__init__() dapat magbalink na None, hindi '%s'" + +#: py/objobject.c +msgid "__new__ arg must be a user-type" +msgstr "__new__ arg ay dapat na user-type" + +#: extmod/modubinascii.c extmod/moduhashlib.c +msgid "a bytes-like object is required" +msgstr "a bytes-like object ay kailangan" + +#: lib/embed/abort_.c +msgid "abort() called" +msgstr "abort() tinawag" + +#: extmod/machine_mem.c +#, c-format +msgid "address %08x is not aligned to %d bytes" +msgstr "address %08x ay hindi pantay sa %d bytes" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "address out of bounds" +msgstr "wala sa sakop ang address" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "addresses is empty" +msgstr "walang laman ang address" + +#: py/modbuiltins.c +msgid "arg is an empty sequence" +msgstr "arg ay walang laman na sequence" + +#: py/runtime.c +msgid "argument has wrong type" +msgstr "may maling type ang argument" + +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +msgid "argument num/types mismatch" +msgstr "hindi tugma ang argument num/types" + +#: py/runtime.c +msgid "argument should be a '%q' not a '%q'" +msgstr "argument ay dapat na '%q' hindi '%q'" + +#: py/objarray.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" +msgstr "array/bytes kinakailangan sa kanang bahagi" + +#: py/objstr.c +msgid "attributes not supported yet" +msgstr "attributes hindi sinusuportahan" + +#: py/builtinevex.c +msgid "bad compile mode" +msgstr "masamang mode ng compile" + +#: py/objstr.c +msgid "bad conversion specifier" +msgstr "masamang pag convert na specifier" + +#: py/objstr.c +msgid "bad format string" +msgstr "maling format ang string" + +#: py/binary.c +msgid "bad typecode" +msgstr "masamang typecode" + +#: py/emitnative.c +msgid "binary op %q not implemented" +msgstr "binary op %q hindi implemented" + +#: shared-bindings/busio/UART.c +msgid "bits must be 7, 8 or 9" +msgstr "bits ay dapat 7, 8 o 9" + +#: extmod/machine_spi.c +msgid "bits must be 8" +msgstr "bits ay dapat walo (8)" + +#: shared-bindings/audiocore/Mixer.c +msgid "bits_per_sample must be 8 or 16" +msgstr "bits_per_sample ay dapat 8 o 16" + +#: py/emitinlinethumb.c +msgid "branch not in range" +msgstr "branch wala sa range" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "" + +#: shared-bindings/audiocore/RawSample.c +msgid "buffer must be a bytes-like object" +msgstr "buffer ay dapat bytes-like object" + +#: shared-module/struct/__init__.c +#, fuzzy +msgid "buffer size must match format" +msgstr "aarehas na haba dapat ang buffer slices" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" +msgstr "aarehas na haba dapat ang buffer slices" + +#: py/modstruct.c shared-bindings/struct/__init__.c +#: shared-module/struct/__init__.c +msgid "buffer too small" +msgstr "masyadong maliit ang buffer" + +#: extmod/machine_spi.c +msgid "buffers must be the same length" +msgstr "ang buffers ay dapat parehas sa haba" + +#: shared-bindings/_pew/PewPew.c +msgid "buttons must be digitalio.DigitalInOut" +msgstr "" + +#: py/vm.c +msgid "byte code not implemented" +msgstr "byte code hindi pa implemented" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "bytes > 8 bits not supported" +msgstr "hindi sinusuportahan ang bytes > 8 bits" + +#: py/objstr.c +msgid "bytes value out of range" +msgstr "bytes value wala sa sakop" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" +msgstr "kalibrasion ay wala sa sakop" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" +msgstr "pagkakalibrate ay basahin lamang" + +#: ports/atmel-samd/common-hal/rtc/RTC.c +msgid "calibration value out of range +/-127" +msgstr "ang halaga ng pagkakalibrate ay wala sa sakop +/-127" + +#: py/emitinlinethumb.c +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "maaari lamang magkaroon ng hanggang 4 na parameter sa Thumb assembly" + +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "maaari lamang magkaroon ng hanggang 4 na parameter sa Xtensa assembly" + +#: py/persistentcode.c +msgid "can only save bytecode" +msgstr "maaring i-save lamang ang bytecode" + +#: py/objtype.c +msgid "can't add special method to already-subclassed class" +msgstr "" +"hindi madagdag ang isang espesyal na method sa isang na i-subclass na class" + +#: py/compile.c +msgid "can't assign to expression" +msgstr "hindi ma i-assign sa expression" + +#: py/obj.c +#, c-format +msgid "can't convert %s to complex" +msgstr "hindi ma-convert %s sa complex" + +#: py/obj.c +#, c-format +msgid "can't convert %s to float" +msgstr "hindi ma-convert %s sa int" + +#: py/obj.c +#, c-format +msgid "can't convert %s to int" +msgstr "hindi ma-convert %s sa int" + +#: py/objstr.c +msgid "can't convert '%q' object to %q implicitly" +msgstr "hindi maaaring i-convert ang '%q' na bagay sa %q nang walang pahiwatig" + +#: py/objint.c +msgid "can't convert NaN to int" +msgstr "hindi ma i-convert NaN sa int" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "can't convert address to int" +msgstr "hindi ma i-convert ang address sa INT" + +#: py/objint.c +msgid "can't convert inf to int" +msgstr "hindi ma i-convert inf sa int" + +#: py/obj.c +msgid "can't convert to complex" +msgstr "hindi ma-convert sa complex" + +#: py/obj.c +msgid "can't convert to float" +msgstr "hindi ma-convert sa float" + +#: py/obj.c +msgid "can't convert to int" +msgstr "hindi ma-convert sa int" + +#: py/objstr.c +msgid "can't convert to str implicitly" +msgstr "hindi ma i-convert sa string ng walang pahiwatig" + +#: py/compile.c +msgid "can't declare nonlocal in outer code" +msgstr "hindi madeclare nonlocal sa outer code" + +#: py/compile.c +msgid "can't delete expression" +msgstr "hindi mabura ang expression" + +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" +msgstr "hindi magawa ang binary op sa gitna ng '%q' at '%q'" + +#: py/objcomplex.c +msgid "can't do truncated division of a complex number" +msgstr "" +"hindi maaaring gawin ang truncated division ng isang kumplikadong numero" + +#: py/compile.c +msgid "can't have multiple **x" +msgstr "hindi puede ang maraming **x" + +#: py/compile.c +msgid "can't have multiple *x" +msgstr "hindi puede ang maraming *x" + +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "hindi maaaring ma-convert ang '% qt' sa 'bool'" + +#: py/emitnative.c +msgid "can't load from '%q'" +msgstr "hidi ma i-load galing sa '%q'" + +#: py/emitnative.c +msgid "can't load with '%q' index" +msgstr "hindi ma i-load gamit ng '%q' na index" + +#: py/objgenerator.c +msgid "can't pend throw to just-started generator" +msgstr "hindi mapadala ang send throw sa isang kaka umpisang generator" + +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" +msgstr "hindi mapadala ang non-None value sa isang kaka umpisang generator" + +#: py/objnamedtuple.c +msgid "can't set attribute" +msgstr "hindi ma i-set ang attribute" + +#: py/emitnative.c +msgid "can't store '%q'" +msgstr "hindi ma i-store ang '%q'" + +#: py/emitnative.c +msgid "can't store to '%q'" +msgstr "hindi ma i-store sa '%q'" + +#: py/emitnative.c +msgid "can't store with '%q' index" +msgstr "hindi ma i-store gamit ng '%q' na index" + +#: py/objstr.c +msgid "" +"can't switch from automatic field numbering to manual field specification" +msgstr "" +"hindi mapalitan ang awtomatikong field numbering sa manual field " +"specification" + +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "" +"hindi mapalitan ang manual field specification sa awtomatikong field " +"numbering" + +#: py/objtype.c +msgid "cannot create '%q' instances" +msgstr "hindi magawa '%q' instances" + +#: py/objtype.c +msgid "cannot create instance" +msgstr "hindi magawa ang instance" + +#: py/runtime.c +msgid "cannot import name %q" +msgstr "hindi ma-import ang name %q" + +#: py/builtinimport.c +msgid "cannot perform relative import" +msgstr "hindi maaring isagawa ang relative import" + +#: py/emitnative.c +msgid "casting" +msgstr "casting" + +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" +msgstr "masyadong maliit ang buffer" + +#: py/modbuiltins.c +msgid "chr() arg not in range(0x110000)" +msgstr "chr() arg wala sa sakop ng range(0x110000)" + +#: py/modbuiltins.c +msgid "chr() arg not in range(256)" +msgstr "chr() arg wala sa sakop ng range(256)" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "color buffer ay dapat na 3 bytes (RGB) o 4 bytes (RGB + pad byte)" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer or int" +msgstr "color buffer ay dapat buffer or int" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "ang color buffer ay dapat bytearray o array na type ‘b’ or ‘B’" + +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" +msgstr "color ay dapat mula sa 0x000000 hangang 0xffffff" + +#: shared-bindings/displayio/ColorConverter.c +msgid "color should be an int" +msgstr "color ay dapat na int" + +#: py/objcomplex.c +msgid "complex division by zero" +msgstr "kumplikadong dibisyon sa pamamagitan ng zero" + +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" +msgstr "kumplikadong values hindi sinusuportahan" + +#: extmod/moduzlib.c +msgid "compression header" +msgstr "compression header" + +#: py/parse.c +msgid "constant must be an integer" +msgstr "constant ay dapat na integer" + +#: py/emitnative.c +msgid "conversion to object" +msgstr "kombersyon to object" + +#: py/parsenum.c +msgid "decimal numbers not supported" +msgstr "decimal numbers hindi sinusuportahan" + +#: py/compile.c +msgid "default 'except' must be last" +msgstr "default 'except' ay dapat sa huli" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" +"ang destination buffer ay dapat na isang bytearray o array ng uri na 'B' " +"para sa bit_depth = 8" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "" +"ang destination buffer ay dapat na isang array ng uri 'H' para sa bit_depth " +"= 16" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination_length must be an int >= 0" +msgstr "ang destination_length ay dapat na isang int >= 0" + +#: py/objdict.c +msgid "dict update sequence has wrong length" +msgstr "may mali sa haba ng dict update sequence" + +#: py/modmath.c py/objfloat.c py/objint_longlong.c py/objint_mpz.c py/runtime.c +#: shared-bindings/math/__init__.c +msgid "division by zero" +msgstr "dibisyon ng zero" + +#: py/objdeque.c +msgid "empty" +msgstr "walang laman" + +#: extmod/moduheapq.c extmod/modutimeq.c +msgid "empty heap" +msgstr "walang laman ang heap" + +#: py/objstr.c +msgid "empty separator" +msgstr "walang laman na separator" + +#: shared-bindings/random/__init__.c +msgid "empty sequence" +msgstr "walang laman ang sequence" + +#: py/objstr.c +msgid "end of format while looking for conversion specifier" +msgstr "sa huli ng format habang naghahanap sa conversion specifier" + +#: shared-bindings/displayio/Shape.c +#, fuzzy +msgid "end_x should be an int" +msgstr "y ay dapat int" + +#: ports/nrf/common-hal/busio/UART.c +#, c-format +msgid "error = 0x%08lX" +msgstr "" + +#: py/runtime.c +msgid "exceptions must derive from BaseException" +msgstr "ang mga exceptions ay dapat makuha mula sa BaseException" + +#: py/objstr.c +msgid "expected ':' after format specifier" +msgstr "umaasa ng ':' pagkatapos ng format specifier" + +#: py/obj.c +msgid "expected tuple/list" +msgstr "umaasa ng tuple/list" + +#: py/modthread.c +msgid "expecting a dict for keyword args" +msgstr "umaasa ng dict para sa keyword args" + +#: py/compile.c +msgid "expecting an assembler instruction" +msgstr "umaasa ng assembler instruction" + +#: py/compile.c +msgid "expecting just a value for set" +msgstr "umaasa sa value para sa set" + +#: py/compile.c +msgid "expecting key:value for dict" +msgstr "umaasang key: halaga para sa dict" + +#: py/argcheck.c +msgid "extra keyword arguments given" +msgstr "dagdag na keyword argument na ibinigay" + +#: py/argcheck.c +msgid "extra positional arguments given" +msgstr "dagdag na positional argument na ibinigay" + +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c +msgid "file must be a file opened in byte mode" +msgstr "file ay dapat buksan sa byte mode" + +#: shared-bindings/storage/__init__.c +msgid "filesystem must provide mount method" +msgstr "ang filesystem dapat mag bigay ng mount method" + +#: py/objtype.c +msgid "first argument to super() must be type" +msgstr "unang argument ng super() ay dapat type" + +#: extmod/machine_spi.c +msgid "firstbit must be MSB" +msgstr "firstbit ay dapat MSB" + +#: py/objint.c +msgid "float too big" +msgstr "masyadong malaki ang float" + +#: shared-bindings/_stage/Text.c +msgid "font must be 2048 bytes long" +msgstr "font ay dapat 2048 bytes ang haba" + +#: py/objstr.c +msgid "format requires a dict" +msgstr "kailangan ng format ng dict" + +#: py/objdeque.c +msgid "full" +msgstr "puno" + +#: py/argcheck.c +msgid "function does not take keyword arguments" +msgstr "ang function ay hindi kumukuha ng mga argumento ng keyword" + +#: py/argcheck.c +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "function na inaasahang %d ang argumento, ngunit %d ang nakuha" + +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" +msgstr "ang function ay nakakuha ng maraming values para sa argument '%q'" + +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" +msgstr "function kulang ng %d required na positional arguments" + +#: py/bc.c +msgid "function missing keyword-only argument" +msgstr "function nangangailangan ng keyword-only argument" + +#: py/bc.c +msgid "function missing required keyword argument '%q'" +msgstr "function nangangailangan ng keyword argument '%q'" + +#: py/bc.c +#, c-format +msgid "function missing required positional argument #%d" +msgstr "function nangangailangan ng positional argument #%d" + +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "" +"ang function ay kumuhuha ng %d positional arguments ngunit %d ang ibinigay" + +#: shared-bindings/time/__init__.c +msgid "function takes exactly 9 arguments" +msgstr "function kumukuha ng 9 arguments" + +#: py/objgenerator.c +msgid "generator already executing" +msgstr "insinasagawa na ng generator" + +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" +msgstr "hindi pinansin ng generator ang GeneratorExit" + +#: shared-bindings/_stage/Layer.c +msgid "graphic must be 2048 bytes long" +msgstr "graphic ay dapat 2048 bytes ang haba" + +#: extmod/moduheapq.c +msgid "heap must be a list" +msgstr "list dapat ang heap" + +#: py/compile.c +msgid "identifier redefined as global" +msgstr "identifier ginawang global" + +#: py/compile.c +msgid "identifier redefined as nonlocal" +msgstr "identifier ginawang nonlocal" + +#: py/objstr.c +msgid "incomplete format" +msgstr "hindi kumpleto ang format" + +#: py/objstr.c +msgid "incomplete format key" +msgstr "hindi kumpleto ang format key" + +#: extmod/modubinascii.c +msgid "incorrect padding" +msgstr "mali ang padding" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c py/obj.c +msgid "index out of range" +msgstr "index wala sa sakop" + +#: py/obj.c +msgid "indices must be integers" +msgstr "ang mga indeks ay dapat na integer" + +#: py/compile.c +msgid "inline assembler must be a function" +msgstr "inline assembler ay dapat na function" + +#: py/parsenum.c +msgid "int() arg 2 must be >= 2 and <= 36" +msgstr "int() arg 2 ay dapat >=2 at <= 36" + +#: py/objstr.c +msgid "integer required" +msgstr "kailangan ng int" + +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c +#, c-format +msgid "interval must be in range %s-%s" +msgstr "" + +#: extmod/machine_i2c.c +msgid "invalid I2C peripheral" +msgstr "maling I2C peripheral" + +#: extmod/machine_spi.c +msgid "invalid SPI peripheral" +msgstr "hindi wastong SPI peripheral" + +#: lib/netutils/netutils.c +msgid "invalid arguments" +msgstr "mali ang mga argumento" + +#: extmod/modussl_axtls.c +msgid "invalid cert" +msgstr "mali ang cert" + +#: extmod/uos_dupterm.c +msgid "invalid dupterm index" +msgstr "mali ang dupterm index" + +#: extmod/modframebuf.c +msgid "invalid format" +msgstr "hindi wastong pag-format" + +#: py/objstr.c +msgid "invalid format specifier" +msgstr "mali ang format specifier" + +#: extmod/modussl_axtls.c +msgid "invalid key" +msgstr "mali ang key" + +#: py/compile.c +msgid "invalid micropython decorator" +msgstr "mali ang micropython decorator" + +#: shared-bindings/random/__init__.c +msgid "invalid step" +msgstr "mali ang step" + +#: py/compile.c py/parse.c +msgid "invalid syntax" +msgstr "mali ang sintaks" + +#: py/parsenum.c +msgid "invalid syntax for integer" +msgstr "maling sintaks sa integer" + +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "maling sintaks sa integer na may base %d" + +#: py/parsenum.c +msgid "invalid syntax for number" +msgstr "maling sintaks sa number" + +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" +msgstr "issubclass() arg 1 ay dapat na class" + +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "issubclass() arg 2 ay dapat na class o tuple ng classes" + +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "" +"join umaaasang may listahan ng str/bytes objects na naalinsunod sa self " +"object" + +#: py/argcheck.c +msgid "keyword argument(s) not yet implemented - use normal args instead" +msgstr "" +"kindi pa ipinapatupad ang (mga) argument(s) ng keyword - gumamit ng normal " +"args" + +#: py/bc.c +msgid "keywords must be strings" +msgstr "ang keywords dapat strings" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" +msgstr "label '%d' kailangan na i-define" + +#: py/compile.c +msgid "label redefined" +msgstr "ang label ay na-define ulit" + +#: py/stream.c +msgid "length argument not allowed for this type" +msgstr "length argument ay walang pahintulot sa ganitong type" + +#: py/objarray.c +msgid "lhs and rhs should be compatible" +msgstr "lhs at rhs ay dapat magkasundo" + +#: py/emitnative.c +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "local '%q' ay may type '%q' pero ang source ay '%q'" + +#: py/emitnative.c +msgid "local '%q' used before type known" +msgstr "local '%q' ginamit bago alam ang type" + +#: py/vm.c +msgid "local variable referenced before assignment" +msgstr "local variable na reference bago na i-assign" + +#: py/objint.c +msgid "long int not supported in this build" +msgstr "long int hindi sinusuportahan sa build na ito" + +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" +msgstr "masyadong maliit ang buffer map" + +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" +msgstr "may pagkakamali sa math domain" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + +#: py/runtime.c +msgid "maximum recursion depth exceeded" +msgstr "lumagpas ang maximum recursion depth" + +#: py/runtime.c +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "nabigo ang paglalaan ng memorya, paglalaan ng %u bytes" + +#: py/runtime.c +msgid "memory allocation failed, heap is locked" +msgstr "abigo ang paglalaan ng memorya, ang heap ay naka-lock" + +#: py/builtinimport.c +msgid "module not found" +msgstr "module hindi nakita" + +#: py/compile.c +msgid "multiple *x in assignment" +msgstr "maramihang *x sa assignment" + +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" +msgstr "maraming bases ay may instance lay-out conflict" + +#: py/objtype.c +msgid "multiple inheritance not supported" +msgstr "maraming inhertance hindi sinusuportahan" + +#: py/emitnative.c +msgid "must raise an object" +msgstr "dapat itaas ang isang object" + +#: extmod/machine_spi.c +msgid "must specify all of sck/mosi/miso" +msgstr "dapat tukuyin lahat ng SCK/MOSI/MISO" + +#: py/modbuiltins.c +msgid "must use keyword argument for key function" +msgstr "dapat gumamit ng keyword argument para sa key function" + +#: py/runtime.c +msgid "name '%q' is not defined" +msgstr "name '%q' ay hindi defined" + +#: shared-bindings/_bleio/Peripheral.c +#, fuzzy +msgid "name must be a string" +msgstr "ang keywords dapat strings" + +#: py/runtime.c +msgid "name not defined" +msgstr "name hindi na define" + +#: py/compile.c +msgid "name reused for argument" +msgstr "name muling ginamit para sa argument" + +#: py/emitnative.c +msgid "native yield" +msgstr "native yield" + +#: py/runtime.c +#, c-format +msgid "need more than %d values to unpack" +msgstr "kailangan ng higit sa %d na halaga upang i-unpack" + +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" +msgstr "negatibong power na walang float support" + +#: py/objint_mpz.c py/runtime.c +msgid "negative shift count" +msgstr "negative shift count" + +#: py/vm.c +msgid "no active exception to reraise" +msgstr "walang aktibong exception para i-reraise" + +#: shared-bindings/socket/__init__.c shared-module/network/__init__.c +msgid "no available NIC" +msgstr "walang magagamit na NIC" + +#: py/compile.c +msgid "no binding for nonlocal found" +msgstr "no binding para sa nonlocal, nahanap" + +#: py/builtinimport.c +msgid "no module named '%q'" +msgstr "walang module na '%q'" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "no reset pin available" +msgstr "" + +#: py/runtime.c shared-bindings/_pixelbuf/__init__.c +msgid "no such attribute" +msgstr "walang ganoon na attribute" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" +msgstr "" + +#: py/compile.c +msgid "non-default argument follows default argument" +msgstr "non-default argument sumusunod sa default argument" + +#: extmod/modubinascii.c +msgid "non-hex digit found" +msgstr "non-hex digit nahanap" + +#: py/compile.c +msgid "non-keyword arg after */**" +msgstr "non-keyword arg sa huli ng */**" + +#: py/compile.c +msgid "non-keyword arg after keyword arg" +msgstr "non-keyword arg sa huli ng keyword arg" + +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" +msgstr "" + +#: py/objstr.c +msgid "not all arguments converted during string formatting" +msgstr "hindi lahat ng arguments na i-convert habang string formatting" + +#: py/objstr.c +msgid "not enough arguments for format string" +msgstr "kulang sa arguments para sa format string" + +#: py/obj.c +#, c-format +msgid "object '%s' is not a tuple or list" +msgstr "object '%s' ay hindi tuple o list" + +#: py/obj.c +msgid "object does not support item assignment" +msgstr "ang object na '%s' ay hindi maaaring i-subscript" + +#: py/obj.c +msgid "object does not support item deletion" +msgstr "ang object ay hindi sumusuporta sa pagbura ng item" + +#: py/obj.c +msgid "object has no len" +msgstr "object walang len" + +#: py/obj.c +msgid "object is not subscriptable" +msgstr "ang bagay ay hindi maaaring ma-subscript" + +#: py/runtime.c +msgid "object not an iterator" +msgstr "object ay hindi iterator" + +#: py/objtype.c py/runtime.c +msgid "object not callable" +msgstr "hindi matatawag ang object" + +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" +msgstr "object wala sa sequence" + +#: py/runtime.c +msgid "object not iterable" +msgstr "object hindi ma i-iterable" + +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" +msgstr "object na type '%s' walang len()" + +#: py/obj.c +msgid "object with buffer protocol required" +msgstr "object na may buffer protocol kinakailangan" + +#: extmod/modubinascii.c +msgid "odd-length string" +msgstr "odd-length string" + +#: py/objstr.c py/objstrunicode.c +#, fuzzy +msgid "offset out of bounds" +msgstr "wala sa sakop ang address" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" +msgstr "ang mga slices lamang na may hakbang = 1 (aka None) ang sinusuportahan" + +#: py/modbuiltins.c +msgid "ord expects a character" +msgstr "ord umaasa ng character" + +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "ord() umaasa ng character pero string ng %d haba ang nakita" + +#: py/objint_mpz.c +msgid "overflow converting long int to machine word" +msgstr "overflow nagcoconvert ng long int sa machine word" + +#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c +msgid "palette must be 32 bytes long" +msgstr "ang palette ay dapat 32 bytes ang haba" + +#: shared-bindings/displayio/Palette.c +msgid "palette_index should be an int" +msgstr "palette_index ay dapat na int" + +#: py/compile.c +msgid "parameter annotation must be an identifier" +msgstr "parameter annotation ay dapat na identifier" + +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" +msgstr "ang mga parameter ay dapat na nagrerehistro sa sequence a2 hanggang a5" + +#: py/emitinlinethumb.c +msgid "parameters must be registers in sequence r0 to r3" +msgstr "ang mga parameter ay dapat na nagrerehistro sa sequence r0 hanggang r3" + +#: shared-bindings/displayio/Bitmap.c +#, fuzzy +msgid "pixel coordinates out of bounds" +msgstr "wala sa sakop ang address" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel value requires too many bits" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" +msgstr "pixel_shader ay dapat displayio.Palette o displayio.ColorConverter" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" +msgstr "pop mula sa walang laman na PulseIn" + +#: py/objset.c +msgid "pop from an empty set" +msgstr "pop sa walang laman na set" + +#: py/objlist.c +msgid "pop from empty list" +msgstr "pop galing sa walang laman na list" + +#: py/objdict.c +msgid "popitem(): dictionary is empty" +msgstr "popitem(): dictionary ay walang laman" + +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" +msgstr "pow() 3rd argument ay hindi maaring 0" + +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" +msgstr "pow() na may 3 argumento kailangan ng integers" + +#: extmod/modutimeq.c +msgid "queue overflow" +msgstr "puno na ang pila (overflow)" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "rawbuf is not the same size as buf" +msgstr "" + +#: shared-bindings/_pixelbuf/__init__.c +#, fuzzy +msgid "readonly attribute" +msgstr "hindi mabasa ang attribute" + +#: py/builtinimport.c +msgid "relative import" +msgstr "relative import" + +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" +msgstr "hiniling ang haba %d ngunit may haba ang object na %d" + +#: py/compile.c +msgid "return annotation must be an identifier" +msgstr "return annotation ay dapat na identifier" + +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" +msgstr "return umasa ng '%q' pero ang nakuha ay ‘%q’" + +#: py/objstr.c +msgid "rsplit(None,n)" +msgstr "rsplit(None,n)" + +#: shared-bindings/audiocore/RawSample.c +msgid "" +"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " +"'B'" +msgstr "" +"ang sample_source buffer ay dapat na isang bytearray o array ng uri na 'h', " +"'H', 'b' o'B'" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" +msgstr "pagpili ng rate wala sa sakop" + +#: py/modmicropython.c +msgid "schedule stack full" +msgstr "puno na ang schedule stack" + +#: lib/utils/pyexec.c py/builtinimport.c +msgid "script compilation not supported" +msgstr "script kompilasyon hindi supportado" + +#: py/objstr.c +msgid "sign not allowed in string format specifier" +msgstr "sign hindi maaring string format specifier" + +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" +msgstr "sign hindi maari sa integer format specifier 'c'" + +#: py/objstr.c +msgid "single '}' encountered in format string" +msgstr "isang '}' nasalubong sa format string" + +#: shared-bindings/time/__init__.c +msgid "sleep length must be non-negative" +msgstr "sleep length ay dapat hindi negatibo" + +#: py/objslice.c py/sequence.c +msgid "slice step cannot be zero" +msgstr "slice step ay hindi puedeng 0" + +#: py/objint.c py/sequence.c +msgid "small int overflow" +msgstr "small int overflow" + +#: main.c +msgid "soft reboot\n" +msgstr "malambot na reboot\n" + +#: py/objstr.c +msgid "start/end indices" +msgstr "start/end indeks" + +#: shared-bindings/displayio/Shape.c +#, fuzzy +msgid "start_x should be an int" +msgstr "y ay dapat int" + +#: shared-bindings/random/__init__.c +msgid "step must be non-zero" +msgstr "step ay dapat hindi zero" + +#: shared-bindings/busio/UART.c +msgid "stop must be 1 or 2" +msgstr "stop dapat 1 o 2" + +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" +msgstr "stop hindi maabot sa simula" + +#: py/stream.c +msgid "stream operation not supported" +msgstr "stream operation hindi sinusuportahan" + +#: py/objstrunicode.c +msgid "string index out of range" +msgstr "indeks ng string wala sa sakop" + +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" +msgstr "ang indeks ng string ay dapat na integer, hindi %s" + +#: py/stream.c +msgid "string not supported; use bytes or bytearray" +msgstr "string hindi supportado; gumamit ng bytes o kaya bytearray" + +#: extmod/moductypes.c +msgid "struct: cannot index" +msgstr "struct: hindi ma-index" + +#: extmod/moductypes.c +msgid "struct: index out of range" +msgstr "struct: index hindi maabot" + +#: extmod/moductypes.c +msgid "struct: no fields" +msgstr "struct: walang fields" + +#: py/objstr.c +msgid "substring not found" +msgstr "substring hindi nahanap" + +#: py/compile.c +msgid "super() can't find self" +msgstr "super() hindi mahanap ang sarili" + +#: extmod/modujson.c +msgid "syntax error in JSON" +msgstr "sintaks error sa JSON" + +#: extmod/moductypes.c +msgid "syntax error in uctypes descriptor" +msgstr "may pagkakamali sa sintaks sa uctypes descriptor" + +#: shared-bindings/touchio/TouchIn.c +msgid "threshold must be in the range 0-65536" +msgstr "ang threshold ay dapat sa range 0-65536" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes a 9-sequence" +msgstr "time.struct_time() kumukuha ng 9-sequence" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes exactly 1 argument" +msgstr "time.struct_time() kumukuha ng 1 argument" + +#: shared-bindings/busio/UART.c +msgid "timeout >100 (units are now seconds, not msecs)" +msgstr "timeout >100 (units ay seconds, hindi na msecs)" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#, fuzzy +msgid "timeout must be >= 0.0" +msgstr "bits ay dapat walo (8)" + +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" +msgstr "wala sa sakop ng timestamp ang platform time_t" + +#: shared-module/struct/__init__.c +msgid "too many arguments provided with the given format" +msgstr "masyadong maraming mga argumento na ibinigay sa ibinigay na format" + +#: py/runtime.c +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "masyadong maraming values para i-unpact (umaasa ng %d)" + +#: py/objstr.c +msgid "tuple index out of range" +msgstr "indeks ng tuple wala sa sakop" + +#: py/obj.c +msgid "tuple/list has wrong length" +msgstr "mali ang haba ng tuple/list" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "tuple/list required on RHS" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "tx and rx cannot both be None" +msgstr "tx at rx hindi pwedeng parehas na None" + +#: py/objtype.c +msgid "type '%q' is not an acceptable base type" +msgstr "hindi maari ang type na '%q' para sa base type" + +#: py/objtype.c +msgid "type is not an acceptable base type" +msgstr "hindi puede ang type para sa base type" + +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" +msgstr "type object '%q' ay walang attribute '%q'" + +#: py/objtype.c +msgid "type takes 1 or 3 arguments" +msgstr "type kumuhuha ng 1 o 3 arguments" + +#: py/objint_longlong.c +msgid "ulonglong too large" +msgstr "ulonglong masyadong malaki" + +#: py/emitnative.c +msgid "unary op %q not implemented" +msgstr "unary op %q hindi implemented" + +#: py/parse.c +msgid "unexpected indent" +msgstr "hindi inaasahang indent" + +#: py/bc.c +msgid "unexpected keyword argument" +msgstr "hindi inaasahang argumento ng keyword" + +#: py/bc.c py/objnamedtuple.c +msgid "unexpected keyword argument '%q'" +msgstr "hindi inaasahang argumento ng keyword na '%q'" + +#: py/lexer.c +msgid "unicode name escapes" +msgstr "unicode name escapes" + +#: py/parse.c +msgid "unindent does not match any outer indentation level" +msgstr "unindent hindi tugma sa indentation level sa labas" + +#: py/objstr.c +#, c-format +msgid "unknown conversion specifier %c" +msgstr "hindi alam ang conversion specifier na %c" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type '%s'" +msgstr "hindi alam ang format code '%c' para sa object na ang type ay '%s'" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'float'" +msgstr "hindi alam ang format code '%c' sa object na ang type ay 'float'" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'str'" +msgstr "hindi alam ang format ng code na '%c' para sa object ng type ay 'str'" + +#: py/compile.c +msgid "unknown type" +msgstr "hindi malaman ang type (unknown type)" + +#: py/emitnative.c +msgid "unknown type '%q'" +msgstr "hindi malaman ang type '%q'" + +#: py/objstr.c +msgid "unmatched '{' in format" +msgstr "hindi tugma ang '{' sa format" + +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" +msgstr "hindi mabasa ang attribute" + +#: shared-bindings/displayio/TileGrid.c +msgid "unsupported %q type" +msgstr "Hindi supportadong tipo ng %q" + +#: py/emitinlinethumb.c +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "hindi sinusuportahan ang thumb instruktion '%s' sa %d argumento" + +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "hindi sinusuportahan ang instruction ng Xtensa '%s' sa %d argumento" + +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "hindi sinusuportahan ang format character na '%c' (0x%x) sa index %d" + +#: py/runtime.c +msgid "unsupported type for %q: '%s'" +msgstr "hindi sinusuportahang type para sa %q: '%s'" + +#: py/runtime.c +msgid "unsupported type for operator" +msgstr "hindi sinusuportahang type para sa operator" + +#: py/runtime.c +msgid "unsupported types for %q: '%s', '%s'" +msgstr "hindi sinusuportahang type para sa %q: '%s', '%s'" + +#: py/objint.c +#, c-format +msgid "value must fit in %d byte(s)" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "value_count must be > 0" +msgstr "" + +#: shared-bindings/_bleio/Scanner.c +msgid "window must be <= interval" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "write_args must be a list, tuple, or None" +msgstr "" + +#: py/objstr.c +msgid "wrong number of arguments" +msgstr "mali ang bilang ng argumento" + +#: py/runtime.c +msgid "wrong number of values to unpack" +msgstr "maling number ng value na i-unpack" + +#: shared-module/displayio/Shape.c +#, fuzzy +msgid "x value out of bounds" +msgstr "wala sa sakop ang address" + +#: shared-bindings/displayio/Shape.c +msgid "y should be an int" +msgstr "y ay dapat int" + +#: shared-module/displayio/Shape.c +#, fuzzy +msgid "y value out of bounds" +msgstr "wala sa sakop ang address" + +#: py/objrange.c +msgid "zero step" +msgstr "zero step" + +#~ msgid "AP required" +#~ msgstr "AP kailangan" + +#~ msgid "C-level assert" +#~ msgstr "C-level assert" + +#~ msgid "Can't add services in Central mode" +#~ msgstr "Hindi maarang maglagay ng service sa Central mode" + +#~ msgid "Can't advertise in Central mode" +#~ msgstr "Hindi ma advertise habang nasa Central mode" + +#~ msgid "Can't change the name in Central mode" +#~ msgstr "Hindi mapalitan ang pangalan sa Central mode" + +#~ msgid "Can't connect in Peripheral mode" +#~ msgstr "Hindi maconnect sa Peripheral mode" + +#~ msgid "Cannot connect to AP" +#~ msgstr "Hindi maka connect sa AP" + +#~ msgid "Cannot disconnect from AP" +#~ msgstr "Hindi ma disconnect sa AP" + +#~ msgid "Cannot set STA config" +#~ msgstr "Hindi ma-set ang STA Config" + +#~ msgid "Cannot update i/f status" +#~ msgstr "Hindi ma-update i/f status" + +#, fuzzy +#~ msgid "Data too large for the advertisement packet" +#~ msgstr "Hindi makasya ang data sa loob ng advertisement packet" + +#~ msgid "Don't know how to pass object to native function" +#~ msgstr "Hindi alam ipasa ang object sa native function" + +#~ msgid "ESP8226 does not support safe mode." +#~ msgstr "Walang safemode support ang ESP8266." + +#~ msgid "ESP8266 does not support pull down." +#~ msgstr "Walang pull down support ang ESP8266." + +#~ msgid "Error in ffi_prep_cif" +#~ msgstr "Pagkakamali sa ffi_prep_cif" + +#, fuzzy +#~ msgid "Failed to acquire mutex" +#~ msgstr "Nabigo sa pag kuha ng mutex, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to add service" +#~ msgstr "Hindi matagumpay ang paglagay ng service, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to connect:" +#~ msgstr "Hindi makaconnect, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to continue scanning" +#~ msgstr "Hindi maituloy ang pag scan, status: 0x%0xlX" + +#, fuzzy +#~ msgid "Failed to create mutex" +#~ msgstr "Hindi matagumpay ang pagbuo ng mutex, status: 0x%0xlX" + +#, fuzzy +#~ msgid "Failed to notify or indicate attribute value, err %0x04x" +#~ msgstr "Hindi mabalitaan ang attribute value, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to read attribute value, err %0x04x" +#~ msgstr "Hindi mabasa ang value ng attribute, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to release mutex" +#~ msgstr "Nabigo sa pagrelease ng mutex, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to start advertising" +#~ msgstr "Hindi masimulaan ang advertisement, status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to start scanning" +#~ msgstr "Hindi masimulaan mag i-scan, status: 0x%0xlX" + +#, fuzzy +#~ msgid "Failed to stop advertising" +#~ msgstr "Hindi mahinto ang advertisement, status: 0x%08lX" + +#~ msgid "Function requires lock." +#~ msgstr "Kailangan ng lock ang function." + +#~ msgid "GPIO16 does not support pull up." +#~ msgstr "Walang pull down support ang GPI016." + +#~ msgid "Invalid bit clock pin" +#~ msgstr "Mali ang bit clock pin" + +#~ msgid "Invalid clock pin" +#~ msgstr "Mali ang clock pin" + +#~ msgid "Invalid data pin" +#~ msgstr "Mali ang data pin" + +#~ msgid "Maximum PWM frequency is %dhz." +#~ msgstr "Pinakamataas na PWM frequency ay %dhz." + +#~ msgid "Minimum PWM frequency is 1hz." +#~ msgstr "Pinakamababang PWM frequency ay 1hz." + +#~ msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." +#~ msgstr "" +#~ "Hindi sinusuportahan ang maraming mga PWM frequency. PWM na naka-set sa " +#~ "%dhz." + +#~ msgid "No PulseIn support for %q" +#~ msgstr "Walang PulseIn support sa %q" + +#~ msgid "No hardware support for analog out." +#~ msgstr "Hindi supportado ng hardware ang analog out." + +#~ msgid "Only Windows format, uncompressed BMP supported %d" +#~ msgstr "Tanging Windows format, uncompressed BMP lamang ang supportado %d" + +#~ msgid "Only bit maps of 8 bit color or less are supported" +#~ msgstr "Tanging bit maps na may 8 bit color o mas mababa ang supportado" + +#~ msgid "Only true color (24 bpp or higher) BMP supported %x" +#~ msgstr "Dapat true color (24 bpp o mas mataas) BMP lamang ang supportado %x" + +#~ msgid "Only tx supported on UART1 (GPIO2)." +#~ msgstr "Tanging suportado ang TX sa UART1 (GPIO2)." + +#~ msgid "PWM not supported on pin %d" +#~ msgstr "Walang PWM support sa pin %d" + +#~ msgid "Pin %q does not have ADC capabilities" +#~ msgstr "Walang kakayahang ADC ang pin %q" + +#~ msgid "Pin(16) doesn't support pull" +#~ msgstr "Walang pull support ang Pin(16)" + +#~ msgid "Pins not valid for SPI" +#~ msgstr "Mali ang pins para sa SPI" + +#~ msgid "STA must be active" +#~ msgstr "Dapat aktibo ang STA" + +#~ msgid "STA required" +#~ msgstr "STA kailangan" + +#~ msgid "UART(%d) does not exist" +#~ msgstr "Walang UART(%d)" + +#~ msgid "UART(1) can't read" +#~ msgstr "Hindi mabasa ang UART(1)" + +#~ msgid "Unable to remount filesystem" +#~ msgstr "Hindi ma-remount ang filesystem" + +#~ msgid "Unknown type" +#~ msgstr "Hindi alam ang type" + +#~ msgid "Use esptool to erase flash and re-upload Python instead" +#~ msgstr "" +#~ "Gamitin ang esptool upang burahin ang flash at muling i-upload ang Python" + +#~ msgid "[addrinfo error %d]" +#~ msgstr "[addrinfo error %d]" + +#~ msgid "buffer too long" +#~ msgstr "masyadong mahaba ng buffer" + +#~ msgid "can query only one param" +#~ msgstr "maaaring i-query lamang ang isang param" + +#~ msgid "can't get AP config" +#~ msgstr "hindi makuha ang AP config" + +#~ msgid "can't get STA config" +#~ msgstr "hindi makuha ang STA config" + +#~ msgid "can't set AP config" +#~ msgstr "hindi makuha ang AP config" + +#~ msgid "can't set STA config" +#~ msgstr "hindi makuha ang STA config" + +#~ msgid "either pos or kw args are allowed" +#~ msgstr "pos o kw args ang pinahihintulutan" + +#~ msgid "expected a DigitalInOut" +#~ msgstr "umasa ng DigitalInOut" + +#~ msgid "expecting a pin" +#~ msgstr "umaasa ng isang pin" + +#~ msgid "ffi_prep_closure_loc" +#~ msgstr "ffi_prep_closure_loc" + +#~ msgid "flash location must be below 1MByte" +#~ msgstr "dapat na mas mababa sa 1MB ang lokasyon ng flash" + +#~ msgid "frequency can only be either 80Mhz or 160MHz" +#~ msgstr "ang frequency ay dapat 80Mhz or 160MHz lamang" + +#~ msgid "impossible baudrate" +#~ msgstr "impossibleng baudrate" + +#~ msgid "invalid alarm" +#~ msgstr "mali ang alarm" + +#~ msgid "invalid buffer length" +#~ msgstr "mali ang buffer length" + +#~ msgid "invalid data bits" +#~ msgstr "mali ang data bits" + +#~ msgid "invalid pin" +#~ msgstr "mali ang pin" + +#~ msgid "invalid stop bits" +#~ msgstr "mali ang stop bits" + +#~ msgid "len must be multiple of 4" +#~ msgstr "len ay dapat multiple ng 4" + +#~ msgid "memory allocation failed, allocating %u bytes for native code" +#~ msgstr "" +#~ "nabigo ang paglalaan ng memorya, naglalaan ng %u bytes para sa native code" + +#~ msgid "not a valid ADC Channel: %d" +#~ msgstr "hindi tamang ADC Channel: %d" + +#~ msgid "pin does not have IRQ capabilities" +#~ msgstr "walang IRQ capabilities ang pin" + +#~ msgid "position must be 2-tuple" +#~ msgstr "position ay dapat 2-tuple" + +#~ msgid "row must be packed and word aligned" +#~ msgstr "row ay dapat packed at ang word nakahanay" + +#~ msgid "scan failed" +#~ msgstr "nabigo ang pag-scan" + +#~ msgid "too many arguments" +#~ msgstr "masyadong maraming argumento" + +#~ msgid "unknown config param" +#~ msgstr "hindi alam na config param" + +#~ msgid "unknown status param" +#~ msgstr "hindi alam na status param" + +#~ msgid "wifi_set_ip_info() failed" +#~ msgstr "nabigo ang wifi_set_ip_info()" diff --git a/locale/fr.po b/locale/fr.po new file mode 100644 index 00000000000..f8345bcee78 --- /dev/null +++ b/locale/fr.po @@ -0,0 +1,3098 @@ +# French translation. +# Copyright (C) 2018 +# This file is distributed under the same license as the PACKAGE package. +# Pierrick Couturier , 2018. +# Olivier Deveault +# +msgid "" +msgstr "" +"Project-Id-Version: 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"PO-Revision-Date: 2019-04-14 20:05+0100\n" +"Last-Translator: Pierrick Couturier \n" +"Language-Team: fr\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: main.c +msgid "" +"\n" +"Code done running. Waiting for reload.\n" +msgstr "" +"\n" +"Fin d'éxecution du code. En attente de recharge.\n" + +#: py/obj.c +msgid " File \"%q\"" +msgstr " Fichier \"%q\"" + +#: py/obj.c +msgid " File \"%q\", line %d" +msgstr " Fichier \"%q\", ligne %d" + +#: main.c +msgid " output:\n" +msgstr " sortie:\n" + +#: py/objstr.c +#, c-format +msgid "%%c requires int or char" +msgstr "%%c nécessite un entier 'int' ou un caractère 'char'" + +#: shared-bindings/microcontroller/Pin.c +msgid "%q in use" +msgstr "%q utilisé" + +#: py/obj.c +msgid "%q index out of range" +msgstr "index %q hors gamme" + +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "les indices %q doivent être des entiers, pas %s" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c +#, fuzzy +msgid "%q must be >= 1" +msgstr "%d doit être >=1" + +#: shared-bindings/fontio/BuiltinFont.c +#, fuzzy +msgid "%q should be an int" +msgstr "y doit être un entier (int)" + +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" +msgstr "%q() prend %d arguments positionnels mais %d ont été donnés" + +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "'%q' argument requis" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" +msgstr "'%s' attend un label" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" +msgstr "'%s' attend un registre" + +#: py/emitinlinethumb.c +#, fuzzy, c-format +msgid "'%s' expects a special register" +msgstr "'%s' attend un registre special" + +#: py/emitinlinethumb.c +#, fuzzy, c-format +msgid "'%s' expects an FPU register" +msgstr "'%s' attend un registre FPU" + +#: py/emitinlinethumb.c +#, fuzzy, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "'%s' attend une adresse de la forme [a, b]" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" +msgstr "'%s' attend un entier" + +#: py/emitinlinethumb.c +#, fuzzy, c-format +msgid "'%s' expects at most r%d" +msgstr "'%s' s'attend au plus à r%d" + +#: py/emitinlinethumb.c +#, fuzzy, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "'%s' attend {r0, r1, ...}" + +#: py/emitinlinextensa.c +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "'%s' l'entier %d n'est pas dans la gamme %d..%d" + +#: py/emitinlinethumb.c +#, fuzzy, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "'%s' l'entier 0x%x ne correspond pas au masque 0x%x" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item assignment" +msgstr "l'objet '%s' ne supporte pas l'assignation d'éléments" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item deletion" +msgstr "l'objet '%s' ne supporte pas la suppression d'éléments" + +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" +msgstr "l'objet '%s' n'a pas d'attribut '%q'" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not an iterator" +msgstr "l'objet '%s' n'est pas un itérateur" + +#: py/objtype.c py/runtime.c +#, c-format +msgid "'%s' object is not callable" +msgstr "objet '%s' n'est pas appelable" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not iterable" +msgstr "objet '%s' n'est pas itérable" + +#: py/obj.c +#, c-format +msgid "'%s' object is not subscriptable" +msgstr "l'objet '%s' n'est pas sous-scriptable" + +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" +msgstr "'=' alignement non autorisé dans la spéc. de format de chaîne" + +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" +msgstr "'S' et 'O' ne sont pas des types de format supportés" + +#: py/compile.c +msgid "'align' requires 1 argument" +msgstr "'align' nécessite 1 argument" + +#: py/compile.c +msgid "'await' outside function" +msgstr "'await' en dehors d'une fonction" + +#: py/compile.c +msgid "'break' outside loop" +msgstr "'break' en dehors d'une boucle" + +#: py/compile.c +msgid "'continue' outside loop" +msgstr "'continue' en dehors d'une boucle" + +#: py/compile.c +msgid "'data' requires at least 2 arguments" +msgstr "'data' nécessite au moins 2 arguments" + +#: py/compile.c +msgid "'data' requires integer arguments" +msgstr "'data' nécessite des arguments entiers" + +#: py/compile.c +msgid "'label' requires 1 argument" +msgstr "'label' nécessite 1 argument" + +#: py/compile.c +msgid "'return' outside function" +msgstr "'return' en dehors d'une fonction" + +#: py/compile.c +msgid "'yield' outside function" +msgstr "'yield' en dehors d'une fonction" + +#: py/compile.c +msgid "*x must be assignment target" +msgstr "*x doit être la cible de l'assignement" + +#: py/obj.c +msgid ", in %q\n" +msgstr ", dans %q\n" + +#: py/objcomplex.c +msgid "0.0 to a complex power" +msgstr "0.0 à une puissance complexe" + +#: py/modbuiltins.c +msgid "3-arg pow() not supported" +msgstr "pow() non supporté avec 3 arguments" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "A hardware interrupt channel is already in use" +msgstr "Un canal d'interruptions matérielles est déjà utilisé" + +#: shared-bindings/_bleio/Address.c +#, fuzzy, c-format +msgid "Address must be %d bytes long" +msgstr "L'adresse doit être longue de %d octets" + +#: shared-bindings/_bleio/Address.c +msgid "Address type out of range" +msgstr "" + +#: ports/nrf/common-hal/busio/I2C.c +#, fuzzy +msgid "All I2C peripherals are in use" +msgstr "Tous les périphériques I2C sont utilisés" + +#: ports/nrf/common-hal/busio/SPI.c +#, fuzzy +msgid "All SPI peripherals are in use" +msgstr "Tous les périphériques SPI sont utilisés" + +#: ports/nrf/common-hal/busio/UART.c +#, fuzzy +msgid "All UART peripherals are in use" +msgstr "Tous les périphériques I2C sont utilisés" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "Tous les canaux d'événements sont utilisés" + +#: ports/atmel-samd/audio_dma.c ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "All sync event channels in use" +msgstr "Tous les canaux d'événements de synchro sont utilisés" + +#: shared-bindings/pulseio/PWMOut.c +msgid "All timers for this pin are in use" +msgstr "Tous les timers pour cette broche sont utilisés" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: shared-module/_pew/PewPew.c +msgid "All timers in use" +msgstr "Tous les timers sont utilisés" + +#: ports/nrf/common-hal/analogio/AnalogOut.c +msgid "AnalogOut functionality not supported" +msgstr "Fonctionnalité AnalogOut non supportée" + +#: shared-bindings/analogio/AnalogOut.c +msgid "AnalogOut is only 16 bits. Value must be less than 65536." +msgstr "" +"AnalogOut est seulement 16 bits. Les valeurs doivent être inf. à 65536." + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "AnalogOut not supported on given pin" +msgstr "'AnalogOut' n'est pas supporté sur la broche indiquée" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" +msgstr "Un autre envoi est déjà actif" + +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" +msgstr "Le tableau doit contenir des demi-mots (type 'H')" + +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." +msgstr "Les valeurs du tableau doivent être des octets simples 'bytes'." + +#: supervisor/shared/safe_mode.c +msgid "Attempted heap allocation when MicroPython VM not running.\n" +msgstr "" +"Tentative d'allocation de tas alors que la VM MicroPython ne tourne pas.\n" + +#: main.c +msgid "Auto-reload is off.\n" +msgstr "L'auto-chargement est désactivé.\n" + +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "" +"Auto-chargement activé. Copiez simplement les fichiers en USB pour les " +"lancer ou entrez sur REPL pour le désactiver.\n" + +#: shared-module/displayio/Display.c +msgid "Below minimum frame rate" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Bit clock and word select must share a clock unit" +msgstr "'bit clock' et 'word select' doivent partager une horloge" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Bit depth must be multiple of 8." +msgstr "La profondeur de bit doit être un multiple de 8." + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "Both pins must support hardware interrupts" +msgstr "Les deux entrées doivent supporter les interruptions matérielles" + +#: shared-bindings/displayio/Display.c +msgid "Brightness must be 0-1.0" +msgstr "" + +#: shared-bindings/supervisor/__init__.c +msgid "Brightness must be between 0 and 255" +msgstr "La luminosité doit être entre 0 et 255" + +#: shared-bindings/displayio/Display.c +msgid "Brightness not adjustable" +msgstr "Luminosité non-ajustable" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "Tampon de taille incorrect. Devrait être de %d octets." + +#: shared-bindings/displayio/Display.c +msgid "Buffer is not a bytearray." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Buffer is too small" +msgstr "" + +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Buffer length %d too big. It must be less than %d" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c +msgid "Buffer must be at least length 1" +msgstr "Le tampon doit être de longueur au moins 1" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +#, fuzzy, c-format +msgid "Bus pin %d is already in use" +msgstr "La broche %d du bus est déjà utilisée" + +#: shared-bindings/_bleio/UUID.c +#, fuzzy +msgid "Byte buffer must be 16 bytes." +msgstr "Le tampon d'octets doit être de 16 octets." + +#: shared-bindings/nvm/ByteArray.c +msgid "Bytes must be between 0 and 255." +msgstr "Les octets 'bytes' doivent être entre 0 et 255" + +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Can not use dotstar with %s" +msgstr "Impossible d'utiliser 'dotstar' avec %s" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" +msgstr "Impossible de supprimer les valeurs" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/nrf/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "Ne peut être tiré ('pull') en mode 'output'" + +#: ports/nrf/common-hal/microcontroller/Processor.c +#, fuzzy +msgid "Cannot get temperature" +msgstr "Impossible de lire la température" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Cannot output both channels on the same pin" +msgstr "Les 2 canaux de sortie ne peuvent être sur la même broche" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot read without MISO pin." +msgstr "Impossible de lire sans broche MISO." + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Cannot record to a file" +msgstr "Impossible d'enregistrer vers un fichier" + +#: shared-module/storage/__init__.c +msgid "Cannot remount '/' when USB is active." +msgstr "'/' ne peut être remonté quand l'USB est actif." + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +msgid "Cannot reset into bootloader because no bootloader is present." +msgstr "" +"Ne peut être redémarré vers le bootloader car il n'y a pas de bootloader." + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Cannot set value when direction is input." +msgstr "Impossible d'affecter une valeur quand la direction est 'input'." + +#: py/objslice.c +msgid "Cannot subclass slice" +msgstr "On ne peut faire de sous-classes de tranches" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot transfer without MOSI and MISO pins." +msgstr "Pas de transfert sans broches MOSI et MISO." + +#: extmod/moductypes.c +msgid "Cannot unambiguously get sizeof scalar" +msgstr "Impossible d'obtenir la taille du scalaire sans ambigüité" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot write without MOSI pin." +msgstr "Impossible d'écrire sans broche MOSI." + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" +msgstr "Ecriture sur 'CharacteristicBuffer' non fournie" + +#: shared-module/bitbangio/SPI.c +msgid "Clock pin init failed." +msgstr "Echec de l'init. de la broche d'horloge" + +#: shared-module/bitbangio/I2C.c +msgid "Clock stretch too long" +msgstr "Période de l'horloge trop longue" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" +msgstr "Horloge en cours d'utilisation" + +#: shared-bindings/_pew/PewPew.c +msgid "Column entry must be digitalio.DigitalInOut" +msgstr "L'entrée 'Column' doit être un digitalio.DigitalInOut" + +#: shared-bindings/displayio/I2CDisplay.c +msgid "Command must be 0-255" +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +#, fuzzy +msgid "Command must be an int between 0 and 255" +msgstr "La commande doit être un entier entre 0 et 255" + +#: py/persistentcode.c +msgid "Corrupt .mpy file" +msgstr "" + +#: py/emitglue.c +msgid "Corrupt raw code" +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "Impossible de décoder le 'ble_uuid', err 0x%04x" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "Could not initialize UART" +msgstr "L'UART n'a pu être initialisé" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate first buffer" +msgstr "Impossible d'allouer le 1er tampon" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate second buffer" +msgstr "Impossible d'allouer le 2e tampon" + +#: supervisor/shared/safe_mode.c +msgid "Crash into the HardFault_Handler.\n" +msgstr "Plantage vers le 'HardFault_Handler'.\n" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "DAC already in use" +msgstr "DAC déjà utilisé" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +#, fuzzy +msgid "Data 0 pin must be byte aligned" +msgstr "La broche 'Data 0' doit être aligné sur l'octet" + +#: shared-module/audiocore/WaveFile.c +msgid "Data chunk must follow fmt chunk" +msgstr "Un bloc de données doit suivre un bloc de format" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Data too large for advertisement packet" +msgstr "Données trop volumineuses pour un paquet de diffusion" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Destination capacity is smaller than destination_length." +msgstr "La capacité de destination est plus petite que 'destination_length'." + +#: shared-bindings/displayio/Display.c +msgid "Display must have a 16 bit colorspace." +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Display rotation must be in 90 degree increments" +msgstr "La rotation d'affichage doit se faire par incréments de 90 degrés" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Drive mode not used when direction is input." +msgstr "Le mode Drive n'est pas utilisé quand la direction est 'input'." + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "EXTINT channel already in use" +msgstr "Canal EXTINT déjà utilisé" + +#: extmod/modure.c +msgid "Error in regex" +msgstr "Erreur dans l'expression régulière" + +#: shared-bindings/microcontroller/Pin.c +#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c +#: shared-bindings/terminalio/Terminal.c +msgid "Expected a %q" +msgstr "Attendu un %q" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c +#, fuzzy +msgid "Expected a Characteristic" +msgstr "Une 'Characteristic' est attendue" + +#: shared-bindings/_bleio/Service.c +msgid "Expected a Peripheral" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Expected a Service" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c +#: shared-bindings/_bleio/Service.c +#, fuzzy +msgid "Expected a UUID" +msgstr "Un UUID est attendu" + +#: shared-bindings/_bleio/Central.c +msgid "Expected an Address" +msgstr "" + +#: shared-module/_pixelbuf/PixelBuf.c +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "Tuple de longueur %d attendu, obtenu %d" + +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + +#: ports/nrf/sd_mutex.c +#, fuzzy, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "Echec de l'obtention de mutex, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Service.c +#, fuzzy, c-format +msgid "Failed to add characteristic, err 0x%04x" +msgstr "Echec de l'ajout de caractéristique, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to add descriptor, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy, c-format +msgid "Failed to add service, err 0x%04x" +msgstr "Echec de l'ajout de service, err 0x%04x" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "Failed to allocate RX buffer" +msgstr "Echec de l'allocation du tampon RX" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +#, c-format +msgid "Failed to allocate RX buffer of %d bytes" +msgstr "Echec de l'allocation de %d octets du tampon RX" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, fuzzy +msgid "Failed to change softdevice state" +msgstr "Echec de la modification de l'état du périphérique" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to configure advertising, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Central.c +msgid "Failed to connect: timeout" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, fuzzy, c-format +msgid "Failed to continue scanning, err 0x%04x" +msgstr "Impossible de poursuivre le scan, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy +msgid "Failed to discover services" +msgstr "Echec de la découverte de services" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, fuzzy +msgid "Failed to get local address" +msgstr "Echec de l'obtention de l'adresse locale" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, fuzzy +msgid "Failed to get softdevice state" +msgstr "Echec de l'obtention de l'état du périphérique" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to notify or indicate attribute value, err 0x%04x" +msgstr "" +"Impossible de notifier ou d'indiquer la valeur de l'attribut, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, fuzzy, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "Impossible de lire la valeur 'CCCD', err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "Failed to read attribute value, err 0x%04x" +msgstr "Impossible de lire la valeur de l'attribut, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy, c-format +msgid "Failed to read gatts value, err 0x%04x" +msgstr "Impossible de lire la valeur de 'gatts', err 0x%04x" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, fuzzy, c-format +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" +msgstr "Echec de l'ajout de l'UUID du fournisseur, err 0x%04x" + +#: ports/nrf/sd_mutex.c +#, fuzzy, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "Impossible de libérer mutex, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to set device name, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "Impossible de commencer à diffuser, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Central.c +#, c-format +msgid "Failed to start connecting, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, fuzzy, c-format +msgid "Failed to start scanning, err 0x%04x" +msgstr "Impossible de commencer à scanner, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "Echec de l'arrêt de diffusion, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to write CCCD, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy, c-format +msgid "Failed to write attribute value, err 0x%04x" +msgstr "Impossible d'écrire la valeur de l'attribut, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy, c-format +msgid "Failed to write gatts value, err 0x%04x" +msgstr "Impossible d'écrire la valeur de 'gatts', err 0x%04x" + +#: py/moduerrno.c +msgid "File exists" +msgstr "Le fichier existe" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash erase failed" +msgstr "L'effacement de la flash a échoué" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash erase failed to start, err 0x%04x" +msgstr "Echec du démarrage de l'effacement de la flash, err 0x%04x" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash write failed" +msgstr "L'écriture de la flash échoué" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash write failed to start, err 0x%04x" +msgstr "Echec du démarrage de l'écriture de la flash, err 0x%04x" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Frequency captured is above capability. Capture Paused." +msgstr "La fréquence capturée est au delà des capacités. Capture en pause." + +#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c +msgid "Function requires lock" +msgstr "La fonction nécessite un verrou" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Group already used" +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Group full" +msgstr "Groupe plein" + +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" +msgstr "opération d'E/S sur un fichier fermé" + +#: extmod/machine_i2c.c +msgid "I2C operation not supported" +msgstr "opération sur I2C non supportée" + +#: py/persistentcode.c +msgid "" +"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" +"mpy-update for more info." +msgstr "" +"Fichier .mpy incompatible. Merci de mettre à jour tous les fichiers .mpy." +"Voir http://adafru.it/mpy-update pour plus d'informations." + +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" +msgstr "Taille de tampon incorrecte" + +#: py/moduerrno.c +msgid "Input/output error" +msgstr "Erreur d'entrée/sortie" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Invalid %q pin" +msgstr "Broche invalide pour '%q'" + +#: shared-module/displayio/OnDiskBitmap.c +#, fuzzy +msgid "Invalid BMP file" +msgstr "Fichier BMP invalide" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c +#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c +msgid "Invalid PWM frequency" +msgstr "Fréquence de PWM invalide" + +#: py/moduerrno.c +msgid "Invalid argument" +msgstr "Argument invalide" + +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" +msgstr "Bits par valeur invalides" + +#: ports/nrf/common-hal/busio/UART.c +#, fuzzy +msgid "Invalid buffer size" +msgstr "Longueur de tampon invalide" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Invalid capture period. Valid range: 1 - 500" +msgstr "Période de capture invalide. Gamme valide: 1 à 500" + +#: shared-bindings/audiocore/Mixer.c +#, fuzzy +msgid "Invalid channel count" +msgstr "Nombre de canaux invalide" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Invalid direction." +msgstr "Direction invalide" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid file" +msgstr "Fichier invalide" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" +msgstr "Taille de bloc de formatage invalide" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid number of bits" +msgstr "Nombre de bits invalide" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid phase" +msgstr "Phase invalide" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +#: shared-bindings/pulseio/PWMOut.c +msgid "Invalid pin" +msgstr "Broche invalide" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for left channel" +msgstr "Broche invalide pour le canal gauche" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for right channel" +msgstr "Broche invalide pour le canal droit" + +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/atmel-samd/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c +#: ports/nrf/common-hal/busio/I2C.c +msgid "Invalid pins" +msgstr "Broches invalides" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid polarity" +msgstr "Polarité invalide" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + +#: shared-bindings/microcontroller/__init__.c +msgid "Invalid run mode." +msgstr "Mode de lancement invalide." + +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +#, fuzzy +msgid "Invalid voice count" +msgstr "Nombre de voix invalide" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid wave file" +msgstr "Fichier WAVE invalide" + +#: py/compile.c +msgid "LHS of keyword arg must be an id" +msgstr "La partie gauche de l'argument nommé doit être un identifiant" + +#: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass." +msgstr "'Layer' doit être un 'Group' ou une sous-classe 'TileGrid'." + +#: py/objslice.c +msgid "Length must be an int" +msgstr "La longueur doit être un nombre entier" + +#: py/objslice.c +msgid "Length must be non-negative" +msgstr "La longueur ne doit pas être négative" + +#: supervisor/shared/safe_mode.c +msgid "" +"Looks like our core CircuitPython code crashed hard. Whoops!\n" +"Please file an issue at https://github.com/adafruit/circuitpython/issues\n" +" with the contents of your CIRCUITPY drive and this message:\n" +msgstr "" +"On dirait que notre code CircuitPython a durement planté. Oups !\n" +"Merci de remplir un ticket sur https://github.com/adafruit/circuitpython/" +"issues\n" +"avec le contenu de votre lecteur CIRCUITPY et ce message:\n" + +#: shared-module/bitbangio/SPI.c +msgid "MISO pin init failed." +msgstr "Echec de l'init. de la broche MISO" + +#: shared-module/bitbangio/SPI.c +msgid "MOSI pin init failed." +msgstr "Echec de l'init. de la broche MOSI" + +#: shared-module/displayio/Shape.c +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "La valeur max. de x est %d lors d'une opération miroir" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython NLR jump failed. Likely memory corruption.\n" +msgstr "Saut MicroPython NLR a échoué. Corruption de mémoire possible.\n" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython fatal error.\n" +msgstr "Erreur fatale de MicroPython.\n" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Microphone startup delay must be in range 0.0 to 1.0" +msgstr "Le délais au démarrage du micro doit être entre 0.0 et 1.0" + +#: shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "No DAC on chip" +msgstr "Pas de DAC sur la puce" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "No DMA channel found" +msgstr "Aucun canal DMA trouvé" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No RX pin" +msgstr "Pas de broche RX" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No TX pin" +msgstr "Pas de broche TX" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "No available clocks" +msgstr "Pas d'horloge disponible" + +#: shared-bindings/board/__init__.c +msgid "No default %q bus" +msgstr "Pas de bus %q par défaut" + +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" +msgstr "Pas de GCLK libre" + +#: shared-bindings/os/__init__.c +msgid "No hardware random available" +msgstr "Pas de source matérielle d'aléa disponible" + +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "No hardware support on pin" +msgstr "Pas de support matériel pour cette broche" + +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" +msgstr "" + +#: py/moduerrno.c +msgid "No space left on device" +msgstr "Il n'y a plus d'espace libre sur le périphérique" + +#: py/moduerrno.c +msgid "No such file/directory" +msgstr "Fichier/dossier introuvable" + +#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Peripheral.c +#, fuzzy +msgid "Not connected" +msgstr "Non connecté" + +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c +msgid "Not playing" +msgstr "Ne joue pas" + +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "" +"L'objet a été désinitialisé et ne peut plus être utilisé. Créez un nouvel " +"objet." + +#: ports/nrf/common-hal/busio/UART.c +#, fuzzy +msgid "Odd parity is not supported" +msgstr "Parité impaire non supportée" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Only 8 or 16 bit mono with " +msgstr "Uniquement 8 ou 16 bit mono avec " + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" +msgstr "" +"Seul le format BMP Windows, non compressé est supporté: la taille de " +"l'entêtefournie est %d" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, fuzzy +msgid "Only slices with step=1 (aka None) are supported" +msgstr "seuls les slices avec 'step=1' (cad 'None') sont supportées" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Oversample must be multiple of 8." +msgstr "Le sur-échantillonage doit être un multiple de 8." + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" +msgstr "" +"La valeur de cycle PWM doit être entre 0 et 65535 inclus (résolution de 16 " +"bits)" + +#: shared-bindings/pulseio/PWMOut.c +#, fuzzy +msgid "" +"PWM frequency not writable when variable_frequency is False on construction." +msgstr "" +"La fréquence de PWM n'est pas modifiable quand variable_frequency est False " +"à la construction." + +#: py/moduerrno.c +msgid "Permission denied" +msgstr "Permission refusée" + +#: ports/atmel-samd/common-hal/analogio/AnalogIn.c +#: ports/nrf/common-hal/analogio/AnalogIn.c +msgid "Pin does not have ADC capabilities" +msgstr "La broche ne peut être utilisée pour l'ADC" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Pixel beyond bounds of buffer" +msgstr "Pixel au-delà des limites du tampon" + +#: py/builtinhelp.c +#, fuzzy +msgid "Plus any modules on the filesystem\n" +msgstr "Ainsi que tout autre module présent sur le système de fichiers\n" + +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload." +msgstr "Appuyez sur une touche pour entrer sur REPL ou CTRL-D pour recharger." + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Pull not used when direction is output." +msgstr "Le tirage 'pull' n'est pas utilisé quand la direction est 'output'." + +#: ports/nrf/common-hal/rtc/RTC.c +msgid "RTC calibration is not supported on this board" +msgstr "étalonnage de la RTC non supportée sur cette carte" + +#: shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" +msgstr "RTC non supportée sur cette carte" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, fuzzy +msgid "Range out of bounds" +msgstr "adresse hors limites" + +#: shared-bindings/pulseio/PulseIn.c +msgid "Read-only" +msgstr "Lecture seule" + +#: extmod/vfs_fat.c py/moduerrno.c +msgid "Read-only filesystem" +msgstr "Système de fichier en lecture seule" + +#: shared-module/displayio/Bitmap.c +#, fuzzy +msgid "Read-only object" +msgstr "Objet en lecture seule" + +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Refresh too soon" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" +msgstr "Canal droit non supporté" + +#: shared-bindings/_pew/PewPew.c +msgid "Row entry must be digitalio.DigitalInOut" +msgstr "L'entrée de ligne 'Row' doit être un digitalio.DigitalInOut" + +#: main.c +msgid "Running in safe mode! Auto-reload is off.\n" +msgstr "Mode sans-échec! Auto-chargement désactivé.\n" + +#: main.c +msgid "Running in safe mode! Not running saved code.\n" +msgstr "Mode sans-échec! Le code sauvegardé n'est pas éxecuté.\n" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "SDA or SCL needs a pull up" +msgstr "SDA ou SCL a besoin d'une résistance de tirage ('pull up')" + +#: shared-bindings/audiocore/Mixer.c +#, fuzzy +msgid "Sample rate must be positive" +msgstr "Le taux d'échantillonage doit être positif" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Sample rate too high. It must be less than %d" +msgstr "Taux d'échantillonage trop élevé. Doit être inf. à %d" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" +msgstr "Sérialiseur en cours d'utilisation" + +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." +msgstr "Tranche et valeur de tailles différentes" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/pulseio/PulseIn.c +msgid "Slices not supported" +msgstr "Tranches non supportées" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "Assertion en mode 'soft-device', id: 0x%08lX, pc: 0x%08lX" + +#: extmod/modure.c +msgid "Splitting with sub-captures" +msgstr "Fractionnement avec des sous-captures" + +#: shared-bindings/supervisor/__init__.c +msgid "Stack size must be at least 256" +msgstr "La pile doit être au moins de 256" + +#: shared-bindings/multiterminal/__init__.c +msgid "Stream missing readinto() or write() method." +msgstr "Il manque une méthode readinto() ou write() au flux." + +#: supervisor/shared/safe_mode.c +msgid "" +"The CircuitPython heap was corrupted because the stack was too small.\n" +"Please increase stack size limits and press reset (after ejecting " +"CIRCUITPY).\n" +"If you didn't change the stack, then file an issue here with the contents of " +"your CIRCUITPY drive:\n" +msgstr "" +"Le tas (heap) de CircuitPython a été corrompu parce que la pile était trop " +"petite.\n" +"Augmentez la limite de taille de la pile et appuyez sur 'reset' (après avoir " +"éjecté CIRCUITPY).\n" +"Si vous n'avez pas modifié la pile, merci de remplir un ticket avec le " +"contenu de votre lecteur CIRCUITPY :\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"The `microcontroller` module was used to boot into safe mode. Press reset to " +"exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +#, fuzzy +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" +"L'alimentation du microcontroleur a chuté. Merci de vérifier que votre " +"alimentation fournit\n" +"suffisamment de puissance pour l'ensemble du circuit et appuyez sur " +"'reset' (après avoir éjecté CIRCUITPY).\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"The reset button was pressed while booting CircuitPython. Press again to " +"exit safe mode.\n" +msgstr "" +"Le bouton 'reset' a été appuyé pendant le démarrage de CircuitPython. " +"Appuyer de nouveau pour quitter de le mode sans-échec.\n" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" +"Le 'bits_per_sample' de l'échantillon ne correspond pas à celui du mixer" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's channel count does not match the mixer's" +msgstr "Le canal de l'échantillon ne correspond pas à celui du mixer" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's sample rate does not match the mixer's" +msgstr "L'échantillonage de l'échantillon ne correspond pas à celui du mixer" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's signedness does not match the mixer's" +msgstr "Le signe de l'échantillon ne correspond pas à celui du mixer" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" +msgstr "La hauteur de la tuile doit diviser exactement la hauteur de l'image" + +#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile value out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" +msgstr "La largeur de la tuile doit diviser exactement la largeur de l'image" + +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "Pour quitter, redémarrez la carte SVP sans " + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample." +msgstr "Trop de canaux dans l'échantillon." + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "Too many display busses" +msgstr "Trop de bus d'affichage" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Too many displays" +msgstr "Trop d'affichages" + +#: py/obj.c +msgid "Traceback (most recent call last):\n" +msgstr "Trace (appels les plus récents en dernier):\n" + +#: shared-bindings/time/__init__.c +msgid "Tuple or struct_time argument required" +msgstr "Argument de type tuple ou struct_time nécessaire" + +#: shared-module/usb_hid/Device.c +msgid "USB Busy" +msgstr "USB occupé" + +#: shared-module/usb_hid/Device.c +msgid "USB Error" +msgstr "Erreur USB" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID integer value must be 0-0xffff" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "" +"La chaîne UUID n'est pas au format 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" +msgstr "" +"la valeur de l'UUID n'est pas une chaîne de caractères, un entier ou un " +"tampon d'octets" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Unable to allocate buffers for signed conversion" +msgstr "Impossible d'allouer des tampons pour une conversion signée" + +#: shared-module/displayio/I2CDisplay.c +#, c-format +msgid "Unable to find I2C Display at %x" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Unable to find free GCLK" +msgstr "Impossible de trouver un GCLK libre" + +#: py/parse.c +msgid "Unable to init parser" +msgstr "Impossible d'initialiser le parser" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" +msgstr "Impossible de lire les données de la palette de couleurs" + +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." +msgstr "Impossible d'écrire sur la mémoire non-volatile." + +#: ports/nrf/common-hal/_bleio/UUID.c +#, fuzzy +msgid "Unexpected nrfx uuid type" +msgstr "Type inattendu pour l'uuid nrfx" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" +"Pas de correspondance du nombres d'éléments à droite (attendu %d, obtenu %d)" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "Unsupported baudrate" +msgstr "Débit non supporté" + +#: shared-module/displayio/display_core.c +#, fuzzy +msgid "Unsupported display bus type" +msgstr "Type de bus d'affichage non supporté" + +#: shared-module/audiocore/WaveFile.c +msgid "Unsupported format" +msgstr "Format non supporté" + +#: py/moduerrno.c +msgid "Unsupported operation" +msgstr "Opération non supportée" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Unsupported pull value." +msgstr "Valeur de tirage 'pull' non supportée." + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + +#: py/emitnative.c +msgid "Viper functions don't currently support more than 4 arguments" +msgstr "" +"les fonctions de Viper ne supportent pas plus de 4 arguments actuellement" + +#: shared-module/audiocore/Mixer.c +msgid "Voice index too high" +msgstr "Index de la voix trop grand" + +#: main.c +msgid "WARNING: Your code filename has two extensions\n" +msgstr "ATTENTION: le nom de fichier de votre code a deux extensions\n" + +#: py/builtinhelp.c +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" +"Bienvenue sur Adafruit CircuitPython %s!\n" +"\n" +"Visitez learn.adafruit.com/category/circuitpython pour les guides.\n" +"\n" +"Pour lister les modules inclus, tapez `help(\"modules\")`.\n" + +#: supervisor/shared/safe_mode.c +#, fuzzy +msgid "" +"You are running in safe mode which means something unanticipated happened.\n" +msgstr "" +"Vous êtes en mode sans-échec ce qui signifie qu'un imprévu est survenu.\n" + +#: supervisor/shared/safe_mode.c +msgid "You requested starting safe mode by " +msgstr "Vous avez demandé à démarrer en mode sans-échec par " + +#: py/objtype.c +msgid "__init__() should return None" +msgstr "__init__() doit retourner None" + +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "__init__() doit retourner None, pas '%s'" + +#: py/objobject.c +msgid "__new__ arg must be a user-type" +msgstr "l'argument __new__ doit être d'un type défini par l'utilisateur" + +#: extmod/modubinascii.c extmod/moduhashlib.c +msgid "a bytes-like object is required" +msgstr "un objet 'bytes-like' est requis" + +#: lib/embed/abort_.c +msgid "abort() called" +msgstr "abort() appelé" + +#: extmod/machine_mem.c +#, c-format +msgid "address %08x is not aligned to %d bytes" +msgstr "l'adresse %08x n'est pas alignée sur %d octets" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "address out of bounds" +msgstr "adresse hors limites" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "addresses is empty" +msgstr "adresses vides" + +#: py/modbuiltins.c +msgid "arg is an empty sequence" +msgstr "l'argument est une séquence vide" + +#: py/runtime.c +msgid "argument has wrong type" +msgstr "l'argument est d'un mauvais type" + +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +msgid "argument num/types mismatch" +msgstr "argument num/types ne correspond pas" + +#: py/runtime.c +msgid "argument should be a '%q' not a '%q'" +msgstr "l'argument devrait être un(e) '%q', pas '%q'" + +#: py/objarray.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" +msgstr "tableau/octets requis à droite" + +#: py/objstr.c +msgid "attributes not supported yet" +msgstr "attribut pas encore supporté" + +#: py/builtinevex.c +msgid "bad compile mode" +msgstr "mauvais mode de compilation" + +#: py/objstr.c +msgid "bad conversion specifier" +msgstr "mauvaise spécification de conversion" + +#: py/objstr.c +msgid "bad format string" +msgstr "chaîne mal-formée" + +#: py/binary.c +msgid "bad typecode" +msgstr "mauvais code type" + +#: py/emitnative.c +msgid "binary op %q not implemented" +msgstr "opération binaire '%q' non implémentée" + +#: shared-bindings/busio/UART.c +msgid "bits must be 7, 8 or 9" +msgstr "bits doivent être 7, 8 ou 9" + +#: extmod/machine_spi.c +msgid "bits must be 8" +msgstr "les bits doivent être 8" + +#: shared-bindings/audiocore/Mixer.c +#, fuzzy +msgid "bits_per_sample must be 8 or 16" +msgstr "'bits_per_sample' doivent être 8 ou 16" + +#: py/emitinlinethumb.c +#, fuzzy +msgid "branch not in range" +msgstr "branche hors-bornes" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "'buf' est trop petit. Besoin de %d octets" + +#: shared-bindings/audiocore/RawSample.c +msgid "buffer must be a bytes-like object" +msgstr "le tampon doit être un objet bytes-like" + +#: shared-module/struct/__init__.c +#, fuzzy +msgid "buffer size must match format" +msgstr "la taille du tampon doit correspondre au format" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" +msgstr "les tranches de tampon doivent être de longueurs égales" + +#: py/modstruct.c shared-bindings/struct/__init__.c +#: shared-module/struct/__init__.c +msgid "buffer too small" +msgstr "tampon trop petit" + +#: extmod/machine_spi.c +msgid "buffers must be the same length" +msgstr "les tampons doivent être de la même longueur" + +#: shared-bindings/_pew/PewPew.c +msgid "buttons must be digitalio.DigitalInOut" +msgstr "les boutons doivent être des digitalio.DigitalInOut" + +#: py/vm.c +msgid "byte code not implemented" +msgstr "bytecode non implémenté" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "'byteorder' n'est pas une instance de ByteOrder (reçu un %s)" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "bytes > 8 bits not supported" +msgstr "octets > 8 bits non supporté" + +#: py/objstr.c +msgid "bytes value out of range" +msgstr "valeur des octets hors bornes" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" +msgstr "étalonnage hors bornes" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" +msgstr "étalonnage en lecture seule" + +#: ports/atmel-samd/common-hal/rtc/RTC.c +msgid "calibration value out of range +/-127" +msgstr "valeur de étalonnage hors bornes +/-127" + +#: py/emitinlinethumb.c +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "il peut y avoir jusqu'à 4 paramètres pour l'assemblage Thumb" + +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "maximum 4 paramètres pour l'assembleur Xtensa" + +#: py/persistentcode.c +msgid "can only save bytecode" +msgstr "ne peut sauvegarder que du bytecode" + +#: py/objtype.c +msgid "can't add special method to already-subclassed class" +msgstr "" +"impossible d'ajouter une méthode spéciale à une classe déjà sous-classée" + +#: py/compile.c +msgid "can't assign to expression" +msgstr "ne peut pas assigner à une expression" + +#: py/obj.c +#, c-format +msgid "can't convert %s to complex" +msgstr "ne peut convertir %s en nombre complexe" + +#: py/obj.c +#, c-format +msgid "can't convert %s to float" +msgstr "ne peut convertir %s en nombre à virgule flottante 'float'" + +#: py/obj.c +#, c-format +msgid "can't convert %s to int" +msgstr "ne peut convertir %s en entier 'int'" + +#: py/objstr.c +msgid "can't convert '%q' object to %q implicitly" +msgstr "impossible de convertir l'objet '%q' en '%q' implicitement" + +#: py/objint.c +msgid "can't convert NaN to int" +msgstr "on ne peut convertir NaN en entier 'int'" + +#: shared-bindings/i2cslave/I2CSlave.c +#, fuzzy +msgid "can't convert address to int" +msgstr "ne peut convertir l'adresse en entier 'int'" + +#: py/objint.c +msgid "can't convert inf to int" +msgstr "on ne peut convertir l'infini 'inf' en entier 'int'" + +#: py/obj.c +msgid "can't convert to complex" +msgstr "ne peut convertir en nombre complexe" + +#: py/obj.c +msgid "can't convert to float" +msgstr "ne peut convertir en nombre à virgule flottante 'float'" + +#: py/obj.c +msgid "can't convert to int" +msgstr "ne peut convertir en entier 'int'" + +#: py/objstr.c +msgid "can't convert to str implicitly" +msgstr "impossible de convertir en chaine 'str' implicitement" + +#: py/compile.c +msgid "can't declare nonlocal in outer code" +msgstr "ne peut déclarer de 'nonlocal' dans un code externe" + +#: py/compile.c +msgid "can't delete expression" +msgstr "ne peut pas supprimer l'expression" + +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" +msgstr "opération binaire impossible entre '%q' et '%q'" + +#: py/objcomplex.c +msgid "can't do truncated division of a complex number" +msgstr "on ne peut pas faire de division tronquée de nombres complexes" + +#: py/compile.c +msgid "can't have multiple **x" +msgstr "il ne peut y avoir de **x multiples" + +#: py/compile.c +msgid "can't have multiple *x" +msgstr "il ne peut y avoir de *x multiples" + +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "impossible de convertir implicitement '%q' en 'bool'" + +#: py/emitnative.c +msgid "can't load from '%q'" +msgstr "impossible de charger depuis '%q'" + +#: py/emitnative.c +msgid "can't load with '%q' index" +msgstr "impossible de charger avec l'indice '%q'" + +#: py/objgenerator.c +msgid "can't pend throw to just-started generator" +msgstr "" +"on ne peut effectuer une action de type 'pend throw' sur un générateur " +"fraîchement démarré" + +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" +msgstr "" +"on ne peut envoyer une valeur autre que 'None' à un générateur fraîchement " +"démarré" + +#: py/objnamedtuple.c +msgid "can't set attribute" +msgstr "attribut non modifiable" + +#: py/emitnative.c +msgid "can't store '%q'" +msgstr "impossible de stocker '%q'" + +#: py/emitnative.c +msgid "can't store to '%q'" +msgstr "impossible de stocker vers '%q'" + +#: py/emitnative.c +msgid "can't store with '%q' index" +msgstr "impossible de stocker avec un indice '%q'" + +#: py/objstr.c +msgid "" +"can't switch from automatic field numbering to manual field specification" +msgstr "" +"impossible de passer d'une énumération auto des champs à une spécification " +"manuelle" + +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "" +"impossible de passer d'une spécification manuelle des champs à une " +"énumération auto" + +#: py/objtype.c +msgid "cannot create '%q' instances" +msgstr "ne peut pas créer une instance de '%q'" + +#: py/objtype.c +msgid "cannot create instance" +msgstr "ne peut pas créer une instance" + +#: py/runtime.c +msgid "cannot import name %q" +msgstr "ne peut pas importer le nom %q" + +#: py/builtinimport.c +msgid "cannot perform relative import" +msgstr "ne peut pas réaliser un import relatif" + +#: py/emitnative.c +msgid "casting" +msgstr "typage" + +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" +msgstr "tampon de caractères trop petit" + +#: py/modbuiltins.c +msgid "chr() arg not in range(0x110000)" +msgstr "argument de chr() hors de la gamme range(0x11000)" + +#: py/modbuiltins.c +msgid "chr() arg not in range(256)" +msgstr "argument de chr() hors de la gamme range(256)" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "le tampon de couleur doit faire 3 octets (RVB) ou 4 (RVB + pad byte)" + +#: shared-bindings/displayio/Palette.c +#, fuzzy +msgid "color buffer must be a buffer or int" +msgstr "le tampon de couleur doit être un tampon ou un entier 'int'" + +#: shared-bindings/displayio/Palette.c +#, fuzzy +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" +"le tampon de couleur doit être un bytearray ou un tableau de type 'b' ou 'B'" + +#: shared-bindings/displayio/Palette.c +#, fuzzy +msgid "color must be between 0x000000 and 0xffffff" +msgstr "la couleur doit être entre 0x000000 et 0xffffff" + +#: shared-bindings/displayio/ColorConverter.c +#, fuzzy +msgid "color should be an int" +msgstr "la couleur doit être un entier 'int'" + +#: py/objcomplex.c +msgid "complex division by zero" +msgstr "division complexe par zéro" + +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" +msgstr "valeurs complexes non supportées" + +#: extmod/moduzlib.c +msgid "compression header" +msgstr "entête de compression" + +#: py/parse.c +msgid "constant must be an integer" +msgstr "constante doit être un entier" + +#: py/emitnative.c +msgid "conversion to object" +msgstr "conversion en objet" + +#: py/parsenum.c +msgid "decimal numbers not supported" +msgstr "nombres décimaux non supportés" + +#: py/compile.c +msgid "default 'except' must be last" +msgstr "l''except' par défaut doit être en dernier" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" +"le tampon de destination doit être un tableau de type 'B' pour bit_depth = 8" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "" +"le tampon de destination doit être un tableau de type 'H' pour bit_depth = 16" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination_length must be an int >= 0" +msgstr "destination_length doit être un entier >= 0" + +#: py/objdict.c +msgid "dict update sequence has wrong length" +msgstr "la séquence de mise à jour de dict a une mauvaise longueur" + +#: py/modmath.c py/objfloat.c py/objint_longlong.c py/objint_mpz.c py/runtime.c +#: shared-bindings/math/__init__.c +msgid "division by zero" +msgstr "division par zéro" + +#: py/objdeque.c +msgid "empty" +msgstr "vide" + +#: extmod/moduheapq.c extmod/modutimeq.c +msgid "empty heap" +msgstr "tas vide" + +#: py/objstr.c +msgid "empty separator" +msgstr "séparateur vide" + +#: shared-bindings/random/__init__.c +msgid "empty sequence" +msgstr "séquence vide" + +#: py/objstr.c +msgid "end of format while looking for conversion specifier" +msgstr "fin de format en cherchant une spécification de conversion" + +#: shared-bindings/displayio/Shape.c +#, fuzzy +msgid "end_x should be an int" +msgstr "y doit être un entier 'int'" + +#: ports/nrf/common-hal/busio/UART.c +#, c-format +msgid "error = 0x%08lX" +msgstr "erreur = 0x%08lX" + +#: py/runtime.c +msgid "exceptions must derive from BaseException" +msgstr "les exceptions doivent dériver de 'BaseException'" + +#: py/objstr.c +msgid "expected ':' after format specifier" +msgstr "':' attendu après la spécification de format" + +#: py/obj.c +msgid "expected tuple/list" +msgstr "un tuple ou une liste est attendu" + +#: py/modthread.c +msgid "expecting a dict for keyword args" +msgstr "un dict est attendu pour les arguments nommés" + +#: py/compile.c +msgid "expecting an assembler instruction" +msgstr "une instruction assembleur est attendue" + +#: py/compile.c +msgid "expecting just a value for set" +msgstr "une simple valeur est attendue pour l'ensemble 'set'" + +#: py/compile.c +msgid "expecting key:value for dict" +msgstr "couple clef:valeur attendu pour un dictionnaire 'dict'" + +#: py/argcheck.c +msgid "extra keyword arguments given" +msgstr "argument(s) nommé(s) supplémentaire(s) donné(s)" + +#: py/argcheck.c +msgid "extra positional arguments given" +msgstr "argument(s) positionnel(s) supplémentaire(s) donné(s)" + +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c +msgid "file must be a file opened in byte mode" +msgstr "le fichier doit être un fichier ouvert en mode 'byte'" + +#: shared-bindings/storage/__init__.c +msgid "filesystem must provide mount method" +msgstr "le system de fichier doit fournir une méthode 'mount'" + +#: py/objtype.c +msgid "first argument to super() must be type" +msgstr "le premier argument de super() doit être un type" + +#: extmod/machine_spi.c +msgid "firstbit must be MSB" +msgstr "le 1er bit doit être le MSB" + +#: py/objint.c +msgid "float too big" +msgstr "nombre à virgule flottante trop grand" + +#: shared-bindings/_stage/Text.c +msgid "font must be 2048 bytes long" +msgstr "la police doit être longue de 2048 octets" + +#: py/objstr.c +msgid "format requires a dict" +msgstr "le format nécessite un dict" + +#: py/objdeque.c +msgid "full" +msgstr "plein" + +#: py/argcheck.c +msgid "function does not take keyword arguments" +msgstr "la fonction ne prend pas d'arguments nommés" + +#: py/argcheck.c +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "la fonction attendait au plus %d arguments, reçu %d" + +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" +msgstr "la fonction a reçu plusieurs valeurs pour l'argument '%q'" + +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" +msgstr "il manque %d arguments obligatoires à la fonction" + +#: py/bc.c +msgid "function missing keyword-only argument" +msgstr "il manque un argument nommé obligatoire" + +#: py/bc.c +msgid "function missing required keyword argument '%q'" +msgstr "il manque l'argument nommé obligatoire '%q'" + +#: py/bc.c +#, c-format +msgid "function missing required positional argument #%d" +msgstr "il manque l'argument positionnel obligatoire #%d" + +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "la fonction prend %d argument(s) positionnels mais %d ont été donné(s)" + +#: shared-bindings/time/__init__.c +msgid "function takes exactly 9 arguments" +msgstr "la fonction prend exactement 9 arguments" + +#: py/objgenerator.c +msgid "generator already executing" +msgstr "générateur déjà en cours d'exécution" + +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" +msgstr "le générateur a ignoré GeneratorExit" + +#: shared-bindings/_stage/Layer.c +msgid "graphic must be 2048 bytes long" +msgstr "graphic doit être long de 2048 octets" + +#: extmod/moduheapq.c +msgid "heap must be a list" +msgstr "le tas doit être une liste" + +#: py/compile.c +msgid "identifier redefined as global" +msgstr "identifiant redéfini comme global" + +#: py/compile.c +msgid "identifier redefined as nonlocal" +msgstr "identifiant redéfini comme nonlocal" + +#: py/objstr.c +msgid "incomplete format" +msgstr "format incomplet" + +#: py/objstr.c +msgid "incomplete format key" +msgstr "clé de format incomplète" + +#: extmod/modubinascii.c +msgid "incorrect padding" +msgstr "espacement incorrect" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c py/obj.c +msgid "index out of range" +msgstr "index hors gamme" + +#: py/obj.c +msgid "indices must be integers" +msgstr "les indices doivent être des entiers" + +#: py/compile.c +msgid "inline assembler must be a function" +msgstr "l'assembleur doit être une fonction" + +#: py/parsenum.c +msgid "int() arg 2 must be >= 2 and <= 36" +msgstr "l'argument 2 de int() doit être >=2 et <=36" + +#: py/objstr.c +msgid "integer required" +msgstr "entier requis" + +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c +#, c-format +msgid "interval must be in range %s-%s" +msgstr "" + +#: extmod/machine_i2c.c +msgid "invalid I2C peripheral" +msgstr "périphérique I2C invalide" + +#: extmod/machine_spi.c +msgid "invalid SPI peripheral" +msgstr "périphérique SPI invalide" + +#: lib/netutils/netutils.c +msgid "invalid arguments" +msgstr "arguments invalides" + +#: extmod/modussl_axtls.c +msgid "invalid cert" +msgstr "certificat invalide" + +#: extmod/uos_dupterm.c +msgid "invalid dupterm index" +msgstr "index invalide pour dupterm" + +#: extmod/modframebuf.c +msgid "invalid format" +msgstr "format invalide" + +#: py/objstr.c +msgid "invalid format specifier" +msgstr "spécification de format invalide" + +#: extmod/modussl_axtls.c +msgid "invalid key" +msgstr "clé invalide" + +#: py/compile.c +msgid "invalid micropython decorator" +msgstr "décorateur micropython invalide" + +#: shared-bindings/random/__init__.c +msgid "invalid step" +msgstr "pas invalide" + +#: py/compile.c py/parse.c +msgid "invalid syntax" +msgstr "syntaxe invalide" + +#: py/parsenum.c +msgid "invalid syntax for integer" +msgstr "syntaxe invalide pour un entier" + +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "syntaxe invalide pour un entier de base %d" + +#: py/parsenum.c +msgid "invalid syntax for number" +msgstr "syntaxe invalide pour un nombre" + +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" +msgstr "l'argument 1 de issubclass() doit être une classe" + +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "" +"l'argument 2 de issubclass() doit être une classe ou un tuple de classes" + +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "" +"'join' s'attend à une liste d'objets str/bytes cohérents avec l'objet self" + +#: py/argcheck.c +msgid "keyword argument(s) not yet implemented - use normal args instead" +msgstr "" +"argument(s) nommé(s) pas encore implémenté(s) - utilisez les arguments " +"normaux" + +#: py/bc.c +msgid "keywords must be strings" +msgstr "les noms doivent être des chaînes de caractères" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" +msgstr "label '%q' non supporté" + +#: py/compile.c +msgid "label redefined" +msgstr "label redéfini" + +#: py/stream.c +msgid "length argument not allowed for this type" +msgstr "argument 'length' non-permis pour ce type" + +#: py/objarray.c +msgid "lhs and rhs should be compatible" +msgstr "Les parties gauches et droites doivent être compatibles" + +#: py/emitnative.c +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "la variable locale '%q' a le type '%q' mais la source est '%q'" + +#: py/emitnative.c +msgid "local '%q' used before type known" +msgstr "variable locale '%q' utilisée avant d'en connaitre le type" + +#: py/vm.c +msgid "local variable referenced before assignment" +msgstr "variable locale référencée avant d'être assignée" + +#: py/objint.c +msgid "long int not supported in this build" +msgstr "entiers longs non supportés dans cette build" + +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" +msgstr "tampon trop petit" + +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" +msgstr "erreur de domaine math" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + +#: py/runtime.c +msgid "maximum recursion depth exceeded" +msgstr "profondeur maximale de récursivité dépassée" + +#: py/runtime.c +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "l'allocation de mémoire a échoué en allouant %u octets" + +#: py/runtime.c +msgid "memory allocation failed, heap is locked" +msgstr "l'allocation de mémoire a échoué, le tas est vérrouillé" + +#: py/builtinimport.c +msgid "module not found" +msgstr "module introuvable" + +#: py/compile.c +msgid "multiple *x in assignment" +msgstr "*x multiple dans l'assignement" + +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" +msgstr "de multiples bases ont un conflit de lay-out d'instance" + +#: py/objtype.c +msgid "multiple inheritance not supported" +msgstr "héritages multiples non supportés" + +#: py/emitnative.c +msgid "must raise an object" +msgstr "doit lever un objet" + +#: extmod/machine_spi.c +msgid "must specify all of sck/mosi/miso" +msgstr "sck, mosi et miso doivent tous être spécifiés" + +#: py/modbuiltins.c +msgid "must use keyword argument for key function" +msgstr "doit utiliser un argument nommé pour une fonction key" + +#: py/runtime.c +msgid "name '%q' is not defined" +msgstr "nom '%q' non défini" + +#: shared-bindings/_bleio/Peripheral.c +#, fuzzy +msgid "name must be a string" +msgstr "les noms doivent être des chaînes de caractère" + +#: py/runtime.c +msgid "name not defined" +msgstr "nom non défini" + +#: py/compile.c +msgid "name reused for argument" +msgstr "nom réutilisé comme argument" + +#: py/emitnative.c +msgid "native yield" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "need more than %d values to unpack" +msgstr "nécessite plus de %d valeurs à dégrouper" + +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" +msgstr "puissance négative sans support des nombres à virgule flottante" + +#: py/objint_mpz.c py/runtime.c +msgid "negative shift count" +msgstr "compte de décalage négatif" + +#: py/vm.c +msgid "no active exception to reraise" +msgstr "aucune exception active à relever" + +#: shared-bindings/socket/__init__.c shared-module/network/__init__.c +#, fuzzy +msgid "no available NIC" +msgstr "adapteur réseau non disponible" + +#: py/compile.c +msgid "no binding for nonlocal found" +msgstr "pas de lien trouvé pour nonlocal" + +#: py/builtinimport.c +msgid "no module named '%q'" +msgstr "pas de module '%q'" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "no reset pin available" +msgstr "" + +#: py/runtime.c shared-bindings/_pixelbuf/__init__.c +msgid "no such attribute" +msgstr "pas de tel attribut" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" +msgstr "" + +#: py/compile.c +msgid "non-default argument follows default argument" +msgstr "" +"un argument sans valeur par défaut suit un argument avec valeur par défaut" + +#: extmod/modubinascii.c +msgid "non-hex digit found" +msgstr "chiffre non-héxadécimale trouvé" + +#: py/compile.c +msgid "non-keyword arg after */**" +msgstr "argument non-nommé après */**" + +#: py/compile.c +msgid "non-keyword arg after keyword arg" +msgstr "argument non-nommé après argument nommé" + +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" +msgstr "n'est pas un UUID 128 bits" + +#: py/objstr.c +msgid "not all arguments converted during string formatting" +msgstr "" +"tous les arguments n'ont pas été convertis pendant le formatage de la chaîne" + +#: py/objstr.c +msgid "not enough arguments for format string" +msgstr "pas assez d'arguments pour la chaîne de format" + +#: py/obj.c +#, c-format +msgid "object '%s' is not a tuple or list" +msgstr "l'objet '%s' n'est pas un tuple ou une liste" + +#: py/obj.c +msgid "object does not support item assignment" +msgstr "l'objet ne supporte pas l'assignation d'éléments" + +#: py/obj.c +msgid "object does not support item deletion" +msgstr "l'objet ne supporte pas la suppression d'éléments" + +#: py/obj.c +msgid "object has no len" +msgstr "l'objet n'a pas de 'len'" + +#: py/obj.c +msgid "object is not subscriptable" +msgstr "l'objet n'est pas sous-scriptable" + +#: py/runtime.c +msgid "object not an iterator" +msgstr "l'objet n'est pas un itérateur" + +#: py/objtype.c py/runtime.c +msgid "object not callable" +msgstr "objet non appelable" + +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" +msgstr "l'objet n'est pas dans la séquence" + +#: py/runtime.c +msgid "object not iterable" +msgstr "objet non itérable" + +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" +msgstr "l'objet de type '%s' n'a pas de len()" + +#: py/obj.c +msgid "object with buffer protocol required" +msgstr "un objet avec un protocole de tampon est nécessaire" + +#: extmod/modubinascii.c +msgid "odd-length string" +msgstr "chaîne de longueur impaire" + +#: py/objstr.c py/objstrunicode.c +#, fuzzy +msgid "offset out of bounds" +msgstr "adresse hors limites" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" +msgstr "seules les tranches avec 'step=1' (cad None) sont supportées" + +#: py/modbuiltins.c +msgid "ord expects a character" +msgstr "ord attend un caractère" + +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "" +"ord() attend un caractère mais une chaîne de caractère de longueur %d a été " +"trouvée" + +#: py/objint_mpz.c +msgid "overflow converting long int to machine word" +msgstr "dépassement de capacité en convertissant un entier long en mot machine" + +#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c +msgid "palette must be 32 bytes long" +msgstr "la palette doit être longue de 32 octets" + +#: shared-bindings/displayio/Palette.c +#, fuzzy +msgid "palette_index should be an int" +msgstr "palette_index devrait être un entier 'int'" + +#: py/compile.c +msgid "parameter annotation must be an identifier" +msgstr "l'annotation du paramètre doit être un identifiant" + +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" +msgstr "les paramètres doivent être des registres dans la séquence a2 à a5" + +#: py/emitinlinethumb.c +#, fuzzy +msgid "parameters must be registers in sequence r0 to r3" +msgstr "les paramètres doivent être des registres dans la séquence r0 à r3" + +#: shared-bindings/displayio/Bitmap.c +#, fuzzy +msgid "pixel coordinates out of bounds" +msgstr "coordonnées de pixel hors limites" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel value requires too many bits" +msgstr "la valeur du pixel requiet trop de bits" + +#: shared-bindings/displayio/TileGrid.c +msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" +msgstr "" +"pixel_shader doit être un objet displayio.Palette ou displayio.ColorConverter" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" +msgstr "'pop' d'une entrée PulseIn vide" + +#: py/objset.c +msgid "pop from an empty set" +msgstr "'pop' d'un ensemble set vide" + +#: py/objlist.c +msgid "pop from empty list" +msgstr "'pop' d'une liste vide" + +#: py/objdict.c +msgid "popitem(): dictionary is empty" +msgstr "popitem(): dictionnaire vide" + +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" +msgstr "le 3e argument de pow() ne peut être 0" + +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" +msgstr "pow() avec 3 arguments nécessite des entiers" + +#: extmod/modutimeq.c +msgid "queue overflow" +msgstr "dépassement de file" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "rawbuf is not the same size as buf" +msgstr "'rawbuf' n'est pas de la même taille que 'buf'" + +#: shared-bindings/_pixelbuf/__init__.c +#, fuzzy +msgid "readonly attribute" +msgstr "attribut en lecture seule" + +#: py/builtinimport.c +msgid "relative import" +msgstr "import relatif" + +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" +msgstr "la longueur requise est %d mais l'objet est long de %d" + +#: py/compile.c +msgid "return annotation must be an identifier" +msgstr "l'annotation de return doit être un identifiant" + +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" +msgstr "return attendait '%q' mais a reçu '%q'" + +#: py/objstr.c +msgid "rsplit(None,n)" +msgstr "" + +#: shared-bindings/audiocore/RawSample.c +msgid "" +"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " +"'B'" +msgstr "" +"le tampon de sample_source doit être un bytearray ou un tableau de type " +"'h','H', 'b' ou 'B'" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" +msgstr "taux d'échantillonage hors gamme" + +#: py/modmicropython.c +msgid "schedule stack full" +msgstr "pile de planification pleine" + +#: lib/utils/pyexec.c py/builtinimport.c +msgid "script compilation not supported" +msgstr "compilation de script non supportée" + +#: py/objstr.c +msgid "sign not allowed in string format specifier" +msgstr "signe non autorisé dans les spéc. de formats de chaînes de caractères" + +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" +msgstr "signe non autorisé avec la spéc. de format d'entier 'c'" + +#: py/objstr.c +msgid "single '}' encountered in format string" +msgstr "'}' seule rencontrée dans une chaîne de format" + +#: shared-bindings/time/__init__.c +msgid "sleep length must be non-negative" +msgstr "la longueur de sleep ne doit pas être négative" + +#: py/objslice.c py/sequence.c +msgid "slice step cannot be zero" +msgstr "le pas 'step' de la tranche ne peut être zéro" + +#: py/objint.c py/sequence.c +msgid "small int overflow" +msgstr "dépassement de capacité d'un entier court" + +#: main.c +msgid "soft reboot\n" +msgstr "redémarrage logiciel\n" + +#: py/objstr.c +msgid "start/end indices" +msgstr "indices de début/fin" + +#: shared-bindings/displayio/Shape.c +#, fuzzy +msgid "start_x should be an int" +msgstr "'start_x' doit être un entier 'int'" + +#: shared-bindings/random/__init__.c +msgid "step must be non-zero" +msgstr "le pas 'step' doit être non nul" + +#: shared-bindings/busio/UART.c +msgid "stop must be 1 or 2" +msgstr "stop doit être 1 ou 2" + +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" +msgstr "stop n'est pas accessible au démarrage" + +#: py/stream.c +msgid "stream operation not supported" +msgstr "opération de flux non supportée" + +#: py/objstrunicode.c +msgid "string index out of range" +msgstr "index de chaîne hors gamme" + +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" +msgstr "les indices de chaîne de caractères doivent être des entiers, pas %s" + +#: py/stream.c +msgid "string not supported; use bytes or bytearray" +msgstr "" +"chaîne de carac. non supportée; utilisez des bytes ou un tableau de bytes" + +#: extmod/moductypes.c +msgid "struct: cannot index" +msgstr "struct: indexage impossible" + +#: extmod/moductypes.c +msgid "struct: index out of range" +msgstr "struct: index hors limites" + +#: extmod/moductypes.c +msgid "struct: no fields" +msgstr "struct: aucun champs" + +#: py/objstr.c +msgid "substring not found" +msgstr "sous-chaîne non trouvée" + +#: py/compile.c +msgid "super() can't find self" +msgstr "super() ne peut pas trouver self" + +#: extmod/modujson.c +msgid "syntax error in JSON" +msgstr "erreur de syntaxe JSON" + +#: extmod/moductypes.c +msgid "syntax error in uctypes descriptor" +msgstr "erreur de syntaxe dans le descripteur d'uctypes" + +#: shared-bindings/touchio/TouchIn.c +msgid "threshold must be in the range 0-65536" +msgstr "le seuil doit être dans la gamme 0-65536" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes a 9-sequence" +msgstr "time.struct_time() prend une séquence de longueur 9" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes exactly 1 argument" +msgstr "time.struct_time() prend exactement 1 argument" + +#: shared-bindings/busio/UART.c +msgid "timeout >100 (units are now seconds, not msecs)" +msgstr "timeout >100 (exprimé en secondes, pas en ms)" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#, fuzzy +msgid "timeout must be >= 0.0" +msgstr "'timeout' doit être >=0.0" + +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" +msgstr "'timestamp' hors bornes pour 'time_t' de la plateforme" + +#: shared-module/struct/__init__.c +msgid "too many arguments provided with the given format" +msgstr "trop d'arguments fournis avec ce format" + +#: py/runtime.c +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "trop de valeur à dégrouper (%d attendues)" + +#: py/objstr.c +msgid "tuple index out of range" +msgstr "index du tuple hors gamme" + +#: py/obj.c +msgid "tuple/list has wrong length" +msgstr "tuple/liste a une mauvaise longueur" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "tuple/list required on RHS" +msgstr "tuple ou liste requis en partie droite" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "tx and rx cannot both be None" +msgstr "tx et rx ne peuvent être 'None' tous les deux" + +#: py/objtype.c +msgid "type '%q' is not an acceptable base type" +msgstr "le type '%q' n'est pas un type de base accepté" + +#: py/objtype.c +msgid "type is not an acceptable base type" +msgstr "le type n'est pas un type de base accepté" + +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" +msgstr "l'objet de type '%q' n'a pas d'attribut '%q'" + +#: py/objtype.c +msgid "type takes 1 or 3 arguments" +msgstr "le type prend 1 ou 3 arguments" + +#: py/objint_longlong.c +msgid "ulonglong too large" +msgstr "ulonglong trop grand" + +#: py/emitnative.c +msgid "unary op %q not implemented" +msgstr "opération unaire '%q' non implémentée" + +#: py/parse.c +msgid "unexpected indent" +msgstr "indentation inattendue" + +#: py/bc.c +msgid "unexpected keyword argument" +msgstr "argument nommé inattendu" + +#: py/bc.c py/objnamedtuple.c +msgid "unexpected keyword argument '%q'" +msgstr "argument nommé '%q' inattendu" + +#: py/lexer.c +msgid "unicode name escapes" +msgstr "échappements de nom unicode" + +#: py/parse.c +msgid "unindent does not match any outer indentation level" +msgstr "la désindentation ne correspond à aucune indentation précédente" + +#: py/objstr.c +#, c-format +msgid "unknown conversion specifier %c" +msgstr "spécification %c de conversion inconnue" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type '%s'" +msgstr "code de format '%c' inconnu pour un objet de type '%s'" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'float'" +msgstr "code de format '%c' inconnu pour un objet de type 'float'" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'str'" +msgstr "code de format '%c' inconnu pour un objet de type 'str'" + +#: py/compile.c +msgid "unknown type" +msgstr "type inconnu" + +#: py/emitnative.c +msgid "unknown type '%q'" +msgstr "type '%q' inconnu" + +#: py/objstr.c +msgid "unmatched '{' in format" +msgstr "'{' sans correspondance dans le format" + +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" +msgstr "attribut illisible" + +#: shared-bindings/displayio/TileGrid.c +#, fuzzy +msgid "unsupported %q type" +msgstr "type de %q non supporté" + +#: py/emitinlinethumb.c +#, fuzzy, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "instruction Thumb '%s' non supportée avec %d arguments" + +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "instruction Xtensa '%s' non supportée avec %d arguments" + +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "caractère de format '%c' (0x%x) non supporté à l'index %d" + +#: py/runtime.c +msgid "unsupported type for %q: '%s'" +msgstr "type non supporté pour %q: '%s'" + +#: py/runtime.c +msgid "unsupported type for operator" +msgstr "type non supporté pour l'opérateur" + +#: py/runtime.c +msgid "unsupported types for %q: '%s', '%s'" +msgstr "type non supporté pour %q: '%s', '%s'" + +#: py/objint.c +#, c-format +msgid "value must fit in %d byte(s)" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "value_count must be > 0" +msgstr "'value_count' doit être > 0" + +#: shared-bindings/_bleio/Scanner.c +msgid "window must be <= interval" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "write_args must be a list, tuple, or None" +msgstr "'write_args' doit être une liste, un tuple ou 'None'" + +#: py/objstr.c +msgid "wrong number of arguments" +msgstr "mauvais nombres d'arguments" + +#: py/runtime.c +msgid "wrong number of values to unpack" +msgstr "mauvais nombre de valeurs à dégrouper" + +#: shared-module/displayio/Shape.c +#, fuzzy +msgid "x value out of bounds" +msgstr "valeur x hors limites" + +#: shared-bindings/displayio/Shape.c +#, fuzzy +msgid "y should be an int" +msgstr "y doit être un entier 'int'" + +#: shared-module/displayio/Shape.c +#, fuzzy +msgid "y value out of bounds" +msgstr "valeur y hors limites" + +#: py/objrange.c +msgid "zero step" +msgstr "'step' nul" + +#~ msgid "AP required" +#~ msgstr "'AP' requis" + +#~ msgid "Address is not %d bytes long or is in wrong format" +#~ msgstr "L'adresse n'est pas longue de %d octets ou est d'un format erroné" + +#~ msgid "Can't add services in Central mode" +#~ msgstr "Impossible d'ajouter des services en mode Central" + +#~ msgid "Can't advertise in Central mode" +#~ msgstr "Impossible de publier en mode Central" + +#~ msgid "Can't change the name in Central mode" +#~ msgstr "Modification du nom impossible en mode Central" + +#~ msgid "Can't connect in Peripheral mode" +#~ msgstr "Impossible de se connecter en mode 'Peripheral'" + +#~ msgid "Cannot connect to AP" +#~ msgstr "Impossible de se connecter à 'AP'" + +#~ msgid "Cannot disconnect from AP" +#~ msgstr "Impossible de se déconnecter de 'AP'" + +#~ msgid "Cannot set STA config" +#~ msgstr "Impossible de configurer STA" + +#~ msgid "Cannot update i/f status" +#~ msgstr "le status i/f ne peut être mis à jour" + +#~ msgid "Characteristic UUID doesn't match Service UUID" +#~ msgstr "L'UUID de 'Characteristic' ne correspond pas à l'UUID du Service" + +#~ msgid "Characteristic already in use by another Service." +#~ msgstr "'Characteristic' déjà en utilisation par un autre service" + +#~ msgid "Data too large for the advertisement packet" +#~ msgstr "Données trop volumineuses pour le paquet de diffusion" + +#~ msgid "Don't know how to pass object to native function" +#~ msgstr "Ne sais pas comment passer l'objet à une fonction native" + +#~ msgid "ESP8226 does not support safe mode." +#~ msgstr "L'ESP8266 ne supporte pas le mode sans-échec" + +#~ msgid "ESP8266 does not support pull down." +#~ msgstr "L'ESP8266 ne supporte pas le rappel (pull-down)" + +#~ msgid "Error in ffi_prep_cif" +#~ msgstr "Erreur dans ffi_prep_cif" + +#, fuzzy +#~ msgid "Failed to acquire mutex" +#~ msgstr "Echec de l'obtention de mutex" + +#, fuzzy +#~ msgid "Failed to add service" +#~ msgstr "Echec de l'ajout de service" + +#, fuzzy +#~ msgid "Failed to connect:" +#~ msgstr "Echec de connection:" + +#, fuzzy +#~ msgid "Failed to continue scanning" +#~ msgstr "Impossible de poursuivre le scan" + +#, fuzzy +#~ msgid "Failed to create mutex" +#~ msgstr "Echec de la création de mutex" + +#, fuzzy +#~ msgid "Failed to notify or indicate attribute value, err %0x04x" +#~ msgstr "Impossible de notifier la valeur de l'attribut. status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to read attribute value, err %0x04x" +#~ msgstr "Impossible de lire la valeur de l'attribut. status: 0x%08lX" + +#, fuzzy +#~ msgid "Failed to release mutex" +#~ msgstr "Impossible de libérer mutex" + +#, fuzzy +#~ msgid "Failed to start advertising" +#~ msgstr "Echec du démarrage de la diffusion" + +#, fuzzy +#~ msgid "Failed to start scanning" +#~ msgstr "Impossible de commencer à scanner" + +#, fuzzy +#~ msgid "Failed to stop advertising" +#~ msgstr "Echec de l'arrêt de diffusion" + +#~ msgid "Function requires lock." +#~ msgstr "La fonction nécessite un verrou." + +#~ msgid "GPIO16 does not support pull up." +#~ msgstr "Le GPIO16 ne supporte pas le tirage (pull-up)" + +#~ msgid "Invalid bit clock pin" +#~ msgstr "Broche invalide pour 'bit clock'" + +#~ msgid "Invalid clock pin" +#~ msgstr "Broche d'horloge invalide" + +#~ msgid "Invalid data pin" +#~ msgstr "Broche de données invalide" + +#~ msgid "Maximum PWM frequency is %dhz." +#~ msgstr "La fréquence de PWM maximale est %dHz" + +#~ msgid "Minimum PWM frequency is 1hz." +#~ msgstr "La fréquence de PWM minimale est 1Hz" + +#~ msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." +#~ msgstr "" +#~ "Les fréquences de PWM multiples ne sont pas supportées. PWM réglé à %dHz" + +#~ msgid "Must be a Group subclass." +#~ msgstr "Doit être une sous-classe de 'Group'" + +#~ msgid "No PulseIn support for %q" +#~ msgstr "Pas de support de PulseIn pour %q" + +#~ msgid "No hardware support for analog out." +#~ msgstr "Pas de support matériel pour une sortie analogique" + +#~ msgid "Only Windows format, uncompressed BMP supported %d" +#~ msgstr "Seul les BMP non-compressé au format Windows sont supportés %d" + +#~ msgid "Only bit maps of 8 bit color or less are supported" +#~ msgstr "Seules les bitmaps de 8bits par couleur ou moins sont supportées" + +#~ msgid "" +#~ "Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d " +#~ "bpp given" +#~ msgstr "" +#~ "Seul les BMP monochromes, 8bit indexé et 16bit sont supportés: %d bpp " +#~ "fourni" + +#~ msgid "Only true color (24 bpp or higher) BMP supported %x" +#~ msgstr "Seul les BMP 24bits ou plus sont supportés %x" + +#~ msgid "Only tx supported on UART1 (GPIO2)." +#~ msgstr "Seul le tx est supporté sur l'UART1 (GPIO2)." + +#~ msgid "PWM not supported on pin %d" +#~ msgstr "La broche %d ne supporte pas le PWM" + +#~ msgid "Pin %q does not have ADC capabilities" +#~ msgstr "La broche %q n'a pas de convertisseur analogique-digital" + +#~ msgid "Pin(16) doesn't support pull" +#~ msgstr "Pin(16) ne supporte pas le tirage (pull)" + +#~ msgid "Pins not valid for SPI" +#~ msgstr "Broche invalide pour le SPI" + +#~ msgid "STA must be active" +#~ msgstr "'STA' doit être actif" + +#~ msgid "STA required" +#~ msgstr "'STA' requis" + +#~ msgid "Tile indices must be 0 - 255" +#~ msgstr "Les indices des tuiles doivent être compris entre 0 et 255 " + +#~ msgid "UART(%d) does not exist" +#~ msgstr "UART(%d) n'existe pas" + +#~ msgid "UART(1) can't read" +#~ msgstr "UART(1) ne peut pas lire" + +#~ msgid "UUID integer value not in range 0 to 0xffff" +#~ msgstr "valeur de l'entier UUID est hors-bornes 0 à 0xffff" + +#~ msgid "Unable to remount filesystem" +#~ msgstr "Impossible de remonter le système de fichiers" + +#~ msgid "Unknown type" +#~ msgstr "Type inconnu" + +#~ msgid "Use esptool to erase flash and re-upload Python instead" +#~ msgstr "" +#~ "Utilisez 'esptool' pour effacer la flash et recharger Python à la place" + +#~ msgid "bad GATT role" +#~ msgstr "mauvais rôle GATT" + +#~ msgid "buffer too long" +#~ msgstr "tampon trop long" + +#~ msgid "can query only one param" +#~ msgstr "ne peut demander qu'un seul paramètre" + +#~ msgid "can't get AP config" +#~ msgstr "impossible de récupérer la config de 'AP'" + +#~ msgid "can't get STA config" +#~ msgstr "impossible de récupérer la config de 'STA'" + +#~ msgid "can't set AP config" +#~ msgstr "impossible de régler la config de 'AP'" + +#~ msgid "can't set STA config" +#~ msgstr "impossible de régler la config de 'STA'" + +#~ msgid "characteristics includes an object that is not a Characteristic" +#~ msgstr "" +#~ "'characteristics' inclut un objet qui n'est pas une 'Characteristic'" + +#~ msgid "either pos or kw args are allowed" +#~ msgstr "soit 'pos', soit 'kw' est permis en argument" + +#~ msgid "expected a DigitalInOut" +#~ msgstr "objet DigitalInOut attendu" + +#~ msgid "expecting a pin" +#~ msgstr "une broche (Pin) est attendue" + +#~ msgid "flash location must be below 1MByte" +#~ msgstr "l'emplacement en mémoire flash doit être inférieur à 1Mo" + +#~ msgid "frequency can only be either 80Mhz or 160MHz" +#~ msgstr "la fréquence doit être soit 80MHz soit 160MHz" + +#~ msgid "impossible baudrate" +#~ msgstr "débit impossible" + +#~ msgid "interval not in range 0.0020 to 10.24" +#~ msgstr "intervalle hors bornes 0.0020 à 10.24" + +#~ msgid "invalid alarm" +#~ msgstr "alarme invalide" + +#~ msgid "invalid buffer length" +#~ msgstr "longueur de tampon invalide" + +#~ msgid "invalid data bits" +#~ msgstr "bits de données invalides" + +#~ msgid "invalid pin" +#~ msgstr "broche invalide" + +#~ msgid "invalid stop bits" +#~ msgstr "bits d'arrêt invalides" + +#~ msgid "len must be multiple of 4" +#~ msgstr "'len' doit être un multiple de 4" + +#~ msgid "memory allocation failed, allocating %u bytes for native code" +#~ msgstr "" +#~ "l'allocation de mémoire a échoué en allouant %u octets pour un code natif" + +#~ msgid "not a valid ADC Channel: %d" +#~ msgstr "canal ADC non valide : %d" + +#~ msgid "pin does not have IRQ capabilities" +#~ msgstr "la broche ne supporte pas les interruptions (IRQ)" + +#, fuzzy +#~ msgid "position must be 2-tuple" +#~ msgstr "position doit être un 2-tuple" + +#~ msgid "scan failed" +#~ msgstr "échec du scan" + +#~ msgid "services includes an object that is not a Service" +#~ msgstr "'services' inclut un object qui n'est pas un 'Service'" + +#~ msgid "tile index out of bounds" +#~ msgstr "indice de tuile hors limites" + +#~ msgid "too many arguments" +#~ msgstr "trop d'arguments" + +#~ msgid "unknown config param" +#~ msgstr "paramètre de config. inconnu" + +#~ msgid "unknown status param" +#~ msgstr "paramètre de statut inconnu" + +#~ msgid "wifi_set_ip_info() failed" +#~ msgstr "wifi_set_ip_info() a échoué" diff --git a/locale/it_IT.po b/locale/it_IT.po new file mode 100644 index 00000000000..1b48a73066d --- /dev/null +++ b/locale/it_IT.po @@ -0,0 +1,3028 @@ +# Italian translation. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Enrico Paganin , 2018 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"PO-Revision-Date: 2018-10-02 16:27+0200\n" +"Last-Translator: Enrico Paganin \n" +"Language-Team: \n" +"Language: it_IT\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: main.c +msgid "" +"\n" +"Code done running. Waiting for reload.\n" +msgstr "" + +#: py/obj.c +msgid " File \"%q\"" +msgstr " File \"%q\"" + +#: py/obj.c +msgid " File \"%q\", line %d" +msgstr " File \"%q\", riga %d" + +#: main.c +msgid " output:\n" +msgstr " output:\n" + +#: py/objstr.c +#, c-format +msgid "%%c requires int or char" +msgstr "%%c necessita di int o char" + +#: shared-bindings/microcontroller/Pin.c +msgid "%q in use" +msgstr "%q in uso" + +#: py/obj.c +msgid "%q index out of range" +msgstr "indice %q fuori intervallo" + +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "gli indici %q devono essere interi, non %s" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c +#, fuzzy +msgid "%q must be >= 1" +msgstr "slice del buffer devono essere della stessa lunghezza" + +#: shared-bindings/fontio/BuiltinFont.c +#, fuzzy +msgid "%q should be an int" +msgstr "y dovrebbe essere un int" + +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" +msgstr "%q() prende %d argomenti posizionali ma ne sono stati forniti %d" + +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "'%q' argomento richiesto" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" +msgstr "'%s' aspetta una etichetta" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" +msgstr "'%s' aspetta un registro" + +#: py/emitinlinethumb.c +#, fuzzy, c-format +msgid "'%s' expects a special register" +msgstr "'%s' aspetta un registro" + +#: py/emitinlinethumb.c +#, fuzzy, c-format +msgid "'%s' expects an FPU register" +msgstr "'%s' aspetta un registro" + +#: py/emitinlinethumb.c +#, fuzzy, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "'%s' aspetta un registro" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" +msgstr "'%s' aspetta un intero" + +#: py/emitinlinethumb.c +#, fuzzy, c-format +msgid "'%s' expects at most r%d" +msgstr "'%s' aspetta un registro" + +#: py/emitinlinethumb.c +#, fuzzy, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "'%s' aspetta un registro" + +#: py/emitinlinextensa.c +#, fuzzy, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "intero '%s' non è nell'intervallo %d..%d" + +#: py/emitinlinethumb.c +#, fuzzy, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "intero '%s' non è nell'intervallo %d..%d" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item assignment" +msgstr "oggeto '%s' non supporta assengnamento di item" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item deletion" +msgstr "oggeto '%s' non supporta eliminamento di item" + +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" +msgstr "l'oggetto '%s' non ha l'attributo '%q'" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not an iterator" +msgstr "l'oggetto '%s' non è un iteratore" + +#: py/objtype.c py/runtime.c +#, c-format +msgid "'%s' object is not callable" +msgstr "oggeto '%s' non è chiamabile" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not iterable" +msgstr "l'oggetto '%s' non è iterabile" + +#: py/obj.c +#, c-format +msgid "'%s' object is not subscriptable" +msgstr "oggeto '%s' non è " + +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" +msgstr "aligniamento '=' non è permesso per il specificatore formato string" + +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" +msgstr "'S' e 'O' non sono formati supportati" + +#: py/compile.c +msgid "'align' requires 1 argument" +msgstr "'align' richiede 1 argomento" + +#: py/compile.c +msgid "'await' outside function" +msgstr "'await' al di fuori della funzione" + +#: py/compile.c +msgid "'break' outside loop" +msgstr "'break' al di fuori del ciclo" + +#: py/compile.c +msgid "'continue' outside loop" +msgstr "'continue' al di fuori del ciclo" + +#: py/compile.c +msgid "'data' requires at least 2 arguments" +msgstr "'data' richiede almeno 2 argomento" + +#: py/compile.c +msgid "'data' requires integer arguments" +msgstr "'data' richiede argomenti interi" + +#: py/compile.c +msgid "'label' requires 1 argument" +msgstr "'label' richiede 1 argomento" + +#: py/compile.c +msgid "'return' outside function" +msgstr "'return' al di fuori della funzione" + +#: py/compile.c +msgid "'yield' outside function" +msgstr "'yield' al di fuori della funzione" + +#: py/compile.c +msgid "*x must be assignment target" +msgstr "*x deve essere il bersaglio del assegnamento" + +#: py/obj.c +msgid ", in %q\n" +msgstr ", in %q\n" + +#: py/objcomplex.c +msgid "0.0 to a complex power" +msgstr "0.0 elevato alla potenza di un numero complesso" + +#: py/modbuiltins.c +msgid "3-arg pow() not supported" +msgstr "pow() con tre argmomenti non supportata" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "A hardware interrupt channel is already in use" +msgstr "Un canale di interrupt hardware è già in uso" + +#: shared-bindings/_bleio/Address.c +#, fuzzy, c-format +msgid "Address must be %d bytes long" +msgstr "la palette deve essere lunga 32 byte" + +#: shared-bindings/_bleio/Address.c +msgid "Address type out of range" +msgstr "" + +#: ports/nrf/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" +msgstr "Tutte le periferiche I2C sono in uso" + +#: ports/nrf/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" +msgstr "Tutte le periferiche SPI sono in uso" + +#: ports/nrf/common-hal/busio/UART.c +#, fuzzy +msgid "All UART peripherals are in use" +msgstr "Tutte le periferiche I2C sono in uso" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "Tutti i canali eventi utilizati" + +#: ports/atmel-samd/audio_dma.c ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "All sync event channels in use" +msgstr "Tutti i canali di eventi sincronizzati in uso" + +#: shared-bindings/pulseio/PWMOut.c +msgid "All timers for this pin are in use" +msgstr "Tutti i timer per questo pin sono in uso" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: shared-module/_pew/PewPew.c +msgid "All timers in use" +msgstr "Tutti i timer utilizzati" + +#: ports/nrf/common-hal/analogio/AnalogOut.c +msgid "AnalogOut functionality not supported" +msgstr "funzionalità AnalogOut non supportata" + +#: shared-bindings/analogio/AnalogOut.c +msgid "AnalogOut is only 16 bits. Value must be less than 65536." +msgstr "AnalogOut ha solo 16 bit. Il valore deve essere meno di 65536." + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "AnalogOut not supported on given pin" +msgstr "AnalogOut non supportato sul pin scelto" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" +msgstr "Another send è gia activato" + +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" +msgstr "Array deve avere mezzoparole (typo 'H')" + +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." +msgstr "Valori di Array dovrebbero essere bytes singulari" + +#: supervisor/shared/safe_mode.c +msgid "Attempted heap allocation when MicroPython VM not running.\n" +msgstr "" + +#: main.c +msgid "Auto-reload is off.\n" +msgstr "Auto-reload disattivato.\n" + +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "" +"L'auto-reload è attivo. Salva i file su USB per eseguirli o entra nel REPL " +"per disabilitarlo.\n" + +#: shared-module/displayio/Display.c +msgid "Below minimum frame rate" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Bit clock and word select must share a clock unit" +msgstr "" +"Clock di bit e selezione parola devono condividere la stessa unità di clock" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Bit depth must be multiple of 8." +msgstr "La profondità di bit deve essere multipla di 8." + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "Both pins must support hardware interrupts" +msgstr "Entrambi i pin devono supportare gli interrupt hardware" + +#: shared-bindings/displayio/Display.c +msgid "Brightness must be 0-1.0" +msgstr "" + +#: shared-bindings/supervisor/__init__.c +msgid "Brightness must be between 0 and 255" +msgstr "La luminosità deve essere compreso tra 0 e 255" + +#: shared-bindings/displayio/Display.c +msgid "Brightness not adjustable" +msgstr "Illiminazione non è regolabile" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "Buffer di lunghezza non valida. Dovrebbe essere di %d bytes." + +#: shared-bindings/displayio/Display.c +msgid "Buffer is not a bytearray." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Buffer is too small" +msgstr "" + +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Buffer length %d too big. It must be less than %d" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c +msgid "Buffer must be at least length 1" +msgstr "Il buffer deve essere lungo almeno 1" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +#, fuzzy, c-format +msgid "Bus pin %d is already in use" +msgstr "DAC già in uso" + +#: shared-bindings/_bleio/UUID.c +#, fuzzy +msgid "Byte buffer must be 16 bytes." +msgstr "i buffer devono essere della stessa lunghezza" + +#: shared-bindings/nvm/ByteArray.c +msgid "Bytes must be between 0 and 255." +msgstr "I byte devono essere compresi tra 0 e 255" + +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Can not use dotstar with %s" +msgstr "dotstar non può essere usato con %s" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" +msgstr "Impossibile cancellare valori" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/nrf/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "non si può tirare quando nella modalita output" + +#: ports/nrf/common-hal/microcontroller/Processor.c +#, fuzzy +msgid "Cannot get temperature" +msgstr "Impossibile leggere la temperatura. status: 0x%02x" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Cannot output both channels on the same pin" +msgstr "Impossibile dare in output entrambi i canal sullo stesso pin" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot read without MISO pin." +msgstr "Impossibile leggere senza pin MISO." + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Cannot record to a file" +msgstr "Impossibile registrare in un file" + +#: shared-module/storage/__init__.c +msgid "Cannot remount '/' when USB is active." +msgstr "Non è possibile rimontare '/' mentre l'USB è attiva." + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +msgid "Cannot reset into bootloader because no bootloader is present." +msgstr "" +"Impossibile resettare nel bootloader poiché nessun bootloader è presente." + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Cannot set value when direction is input." +msgstr "non si può impostare un valore quando direzione è input" + +#: py/objslice.c +msgid "Cannot subclass slice" +msgstr "Impossibile subclasare slice" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot transfer without MOSI and MISO pins." +msgstr "Impossibile trasferire senza i pin MOSI e MISO." + +#: extmod/moductypes.c +msgid "Cannot unambiguously get sizeof scalar" +msgstr "Impossibile ricavare la grandezza scalare di sizeof inequivocabilmente" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot write without MOSI pin." +msgstr "Impossibile scrivere senza pin MOSI." + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" +msgstr "CharacteristicBuffer scritura non dato" + +#: shared-module/bitbangio/SPI.c +msgid "Clock pin init failed." +msgstr "Inizializzazione del pin di clock fallita." + +#: shared-module/bitbangio/I2C.c +msgid "Clock stretch too long" +msgstr "Orologio e troppo allungato" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" +msgstr "Unità di clock in uso" + +#: shared-bindings/_pew/PewPew.c +msgid "Column entry must be digitalio.DigitalInOut" +msgstr "" + +#: shared-bindings/displayio/I2CDisplay.c +msgid "Command must be 0-255" +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +#, fuzzy +msgid "Command must be an int between 0 and 255" +msgstr "I byte devono essere compresi tra 0 e 255" + +#: py/persistentcode.c +msgid "Corrupt .mpy file" +msgstr "" + +#: py/emitglue.c +msgid "Corrupt raw code" +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "Could not initialize UART" +msgstr "Impossibile inizializzare l'UART" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate first buffer" +msgstr "Impossibile allocare il primo buffer" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate second buffer" +msgstr "Impossibile allocare il secondo buffer" + +#: supervisor/shared/safe_mode.c +msgid "Crash into the HardFault_Handler.\n" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "DAC already in use" +msgstr "DAC già in uso" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +#, fuzzy +msgid "Data 0 pin must be byte aligned" +msgstr "graphic deve essere lunga 2048 byte" + +#: shared-module/audiocore/WaveFile.c +msgid "Data chunk must follow fmt chunk" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy +msgid "Data too large for advertisement packet" +msgstr "Impossibile inserire dati nel pacchetto di advertisement." + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Destination capacity is smaller than destination_length." +msgstr "La capacità di destinazione è più piccola di destination_length." + +#: shared-bindings/displayio/Display.c +msgid "Display must have a 16 bit colorspace." +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Display rotation must be in 90 degree increments" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Drive mode not used when direction is input." +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "EXTINT channel already in use" +msgstr "Canale EXTINT già in uso" + +#: extmod/modure.c +msgid "Error in regex" +msgstr "Errore nella regex" + +#: shared-bindings/microcontroller/Pin.c +#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c +#: shared-bindings/terminalio/Terminal.c +msgid "Expected a %q" +msgstr "Atteso un %q" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c +#, fuzzy +msgid "Expected a Characteristic" +msgstr "Non è possibile aggiungere Characteristic." + +#: shared-bindings/_bleio/Service.c +msgid "Expected a Peripheral" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Expected a Service" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c +#: shared-bindings/_bleio/Service.c +#, fuzzy +msgid "Expected a UUID" +msgstr "Atteso un %q" + +#: shared-bindings/_bleio/Central.c +msgid "Expected an Address" +msgstr "" + +#: shared-module/_pixelbuf/PixelBuf.c +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "" + +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + +#: ports/nrf/sd_mutex.c +#, fuzzy, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Service.c +#, fuzzy, c-format +msgid "Failed to add characteristic, err 0x%04x" +msgstr "Impossibile fermare advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to add descriptor, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy, c-format +msgid "Failed to add service, err 0x%04x" +msgstr "Impossibile fermare advertisement. status: 0x%02x" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "Failed to allocate RX buffer" +msgstr "Impossibile allocare buffer RX" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +#, c-format +msgid "Failed to allocate RX buffer of %d bytes" +msgstr "Fallita allocazione del buffer RX di %d byte" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, fuzzy +msgid "Failed to change softdevice state" +msgstr "Impossibile fermare advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to configure advertising, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Central.c +msgid "Failed to connect: timeout" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, fuzzy, c-format +msgid "Failed to continue scanning, err 0x%04x" +msgstr "Impossible iniziare la scansione. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy +msgid "Failed to discover services" +msgstr "Impossibile fermare advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to get local address" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, fuzzy +msgid "Failed to get softdevice state" +msgstr "Impossibile fermare advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to notify or indicate attribute value, err 0x%04x" +msgstr "Notificamento o indicazione di attribute value fallito, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, fuzzy, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "Failed to read attribute value, err 0x%04x" +msgstr "Tentative leggere attribute value fallito, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy, c-format +msgid "Failed to read gatts value, err 0x%04x" +msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, fuzzy, c-format +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" +msgstr "Non è possibile aggiungere l'UUID del vendor specifico da 128-bit" + +#: ports/nrf/sd_mutex.c +#, fuzzy, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to set device name, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "Impossibile avviare advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Central.c +#, c-format +msgid "Failed to start connecting, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, fuzzy, c-format +msgid "Failed to start scanning, err 0x%04x" +msgstr "Impossible iniziare la scansione. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "Impossibile fermare advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to write CCCD, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy, c-format +msgid "Failed to write attribute value, err 0x%04x" +msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy, c-format +msgid "Failed to write gatts value, err 0x%04x" +msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x" + +#: py/moduerrno.c +msgid "File exists" +msgstr "File esistente" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash erase failed" +msgstr "Cancellamento di Flash fallito" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash erase failed to start, err 0x%04x" +msgstr "Iniziamento di Cancellamento di Flash fallito, err 0x%04x" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash write failed" +msgstr "Impostazione di Flash fallito" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash write failed to start, err 0x%04x" +msgstr "Iniziamento di Impostazione di Flash dallito, err 0x%04x" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Frequency captured is above capability. Capture Paused." +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c +msgid "Function requires lock" +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Group already used" +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Group full" +msgstr "Gruppo pieno" + +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" +msgstr "operazione I/O su file chiuso" + +#: extmod/machine_i2c.c +msgid "I2C operation not supported" +msgstr "operazione I2C non supportata" + +#: py/persistentcode.c +msgid "" +"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" +"mpy-update for more info." +msgstr "" +"File .mpy incompatibile. Aggiorna tutti i file .mpy. Vedi http://adafru.it/" +"mpy-update per più informazioni." + +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" +msgstr "" + +#: py/moduerrno.c +msgid "Input/output error" +msgstr "Errore input/output" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Invalid %q pin" +msgstr "Pin %q non valido" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Invalid BMP file" +msgstr "File BMP non valido" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c +#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c +msgid "Invalid PWM frequency" +msgstr "Frequenza PWM non valida" + +#: py/moduerrno.c +msgid "Invalid argument" +msgstr "Argomento non valido" + +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" +msgstr "bits per valore invalido" + +#: ports/nrf/common-hal/busio/UART.c +#, fuzzy +msgid "Invalid buffer size" +msgstr "lunghezza del buffer non valida" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Invalid capture period. Valid range: 1 - 500" +msgstr "periodo di cattura invalido. Zona valida: 1 - 500" + +#: shared-bindings/audiocore/Mixer.c +#, fuzzy +msgid "Invalid channel count" +msgstr "Argomento non valido" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Invalid direction." +msgstr "Direzione non valida." + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid file" +msgstr "File non valido" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" +msgstr "" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid number of bits" +msgstr "Numero di bit non valido" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid phase" +msgstr "Fase non valida" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +#: shared-bindings/pulseio/PWMOut.c +msgid "Invalid pin" +msgstr "Pin non valido" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for left channel" +msgstr "Pin non valido per il canale sinistro" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for right channel" +msgstr "Pin non valido per il canale destro" + +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/atmel-samd/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c +#: ports/nrf/common-hal/busio/I2C.c +msgid "Invalid pins" +msgstr "Pin non validi" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid polarity" +msgstr "Polarità non valida" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + +#: shared-bindings/microcontroller/__init__.c +msgid "Invalid run mode." +msgstr "Modalità di esecuzione non valida." + +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +#, fuzzy +msgid "Invalid voice count" +msgstr "Tipo di servizio non valido" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid wave file" +msgstr "File wave non valido" + +#: py/compile.c +msgid "LHS of keyword arg must be an id" +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass." +msgstr "Layer deve essere un Group o TileGrid subclass" + +#: py/objslice.c +msgid "Length must be an int" +msgstr "Length deve essere un intero" + +#: py/objslice.c +msgid "Length must be non-negative" +msgstr "Length deve essere non negativo" + +#: supervisor/shared/safe_mode.c +msgid "" +"Looks like our core CircuitPython code crashed hard. Whoops!\n" +"Please file an issue at https://github.com/adafruit/circuitpython/issues\n" +" with the contents of your CIRCUITPY drive and this message:\n" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "MISO pin init failed." +msgstr "inizializzazione del pin MISO fallita." + +#: shared-module/bitbangio/SPI.c +msgid "MOSI pin init failed." +msgstr "inizializzazione del pin MOSI fallita." + +#: shared-module/displayio/Shape.c +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "Valore massimo di x quando rispachiato è %d" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython NLR jump failed. Likely memory corruption.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython fatal error.\n" +msgstr "Errore fatale in MicroPython.\n" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Microphone startup delay must be in range 0.0 to 1.0" +msgstr "" +"Il ritardo di avvio del microfono deve essere nell'intervallo tra 0.0 e 1.0" + +#: shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "No DAC on chip" +msgstr "Nessun DAC sul chip" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "No DMA channel found" +msgstr "Nessun canale DMA trovato" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No RX pin" +msgstr "Nessun pin RX" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No TX pin" +msgstr "Nessun pin TX" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "No available clocks" +msgstr "Nessun orologio a disposizione" + +#: shared-bindings/board/__init__.c +msgid "No default %q bus" +msgstr "Nessun bus %q predefinito" + +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" +msgstr "Nessun GCLK libero" + +#: shared-bindings/os/__init__.c +msgid "No hardware random available" +msgstr "Nessun generatore hardware di numeri casuali disponibile" + +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "No hardware support on pin" +msgstr "Nessun supporto hardware sul pin" + +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" +msgstr "" + +#: py/moduerrno.c +msgid "No space left on device" +msgstr "Non che spazio sul dispositivo" + +#: py/moduerrno.c +msgid "No such file/directory" +msgstr "Nessun file/directory esistente" + +#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Peripheral.c +#, fuzzy +msgid "Not connected" +msgstr "Impossible connettersi all'AP" + +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c +msgid "Not playing" +msgstr "In pausa" + +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "" +"L'oggetto è stato deinizializzato e non può essere più usato. Crea un nuovo " +"oggetto." + +#: ports/nrf/common-hal/busio/UART.c +#, fuzzy +msgid "Odd parity is not supported" +msgstr "operazione I2C non supportata" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Only 8 or 16 bit mono with " +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, fuzzy +msgid "Only slices with step=1 (aka None) are supported" +msgstr "solo slice con step=1 (aka None) sono supportate" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Oversample must be multiple of 8." +msgstr "L'oversampling deve essere multiplo di 8." + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" +msgstr "" +"duty_cycle del PWM deve essere compresa tra 0 e 65535 inclusiva (risoluzione " +"a 16 bit)" + +#: shared-bindings/pulseio/PWMOut.c +#, fuzzy +msgid "" +"PWM frequency not writable when variable_frequency is False on construction." +msgstr "" +"frequenza PWM frequency non è scrivibile quando variable_frequency è " +"impostato nel costruttore a False." + +#: py/moduerrno.c +msgid "Permission denied" +msgstr "Permesso negato" + +#: ports/atmel-samd/common-hal/analogio/AnalogIn.c +#: ports/nrf/common-hal/analogio/AnalogIn.c +msgid "Pin does not have ADC capabilities" +msgstr "Il pin non ha capacità di ADC" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Pixel beyond bounds of buffer" +msgstr "" + +#: py/builtinhelp.c +#, fuzzy +msgid "Plus any modules on the filesystem\n" +msgstr "Imposssibile rimontare il filesystem" + +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload." +msgstr "" +"Premi un qualunque tasto per entrare nel REPL. Usa CTRL-D per ricaricare." + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Pull not used when direction is output." +msgstr "" + +#: ports/nrf/common-hal/rtc/RTC.c +msgid "RTC calibration is not supported on this board" +msgstr "calibrazione RTC non supportata su questa scheda" + +#: shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" +msgstr "RTC non supportato su questa scheda" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, fuzzy +msgid "Range out of bounds" +msgstr "indirizzo fuori limite" + +#: shared-bindings/pulseio/PulseIn.c +msgid "Read-only" +msgstr "Sola lettura" + +#: extmod/vfs_fat.c py/moduerrno.c +msgid "Read-only filesystem" +msgstr "Filesystem in sola lettura" + +#: shared-module/displayio/Bitmap.c +#, fuzzy +msgid "Read-only object" +msgstr "Sola lettura" + +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Refresh too soon" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" +msgstr "Canale destro non supportato" + +#: shared-bindings/_pew/PewPew.c +msgid "Row entry must be digitalio.DigitalInOut" +msgstr "" + +#: main.c +msgid "Running in safe mode! Auto-reload is off.\n" +msgstr "Modalità sicura in esecuzione! Auto-reload disattivato.\n" + +#: main.c +msgid "Running in safe mode! Not running saved code.\n" +msgstr "Modalità sicura in esecuzione! Codice salvato non in esecuzione.\n" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "SDA or SCL needs a pull up" +msgstr "SDA o SCL necessitano un pull-up" + +#: shared-bindings/audiocore/Mixer.c +#, fuzzy +msgid "Sample rate must be positive" +msgstr "STA deve essere attiva" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Sample rate too high. It must be less than %d" +msgstr "" +"Frequenza di campionamento troppo alta. Il valore deve essere inferiore a %d" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" +msgstr "Serializer in uso" + +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/pulseio/PulseIn.c +msgid "Slices not supported" +msgstr "Slice non supportate" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: extmod/modure.c +msgid "Splitting with sub-captures" +msgstr "Suddivisione con sotto-catture" + +#: shared-bindings/supervisor/__init__.c +msgid "Stack size must be at least 256" +msgstr "La dimensione dello stack deve essere almeno 256" + +#: shared-bindings/multiterminal/__init__.c +msgid "Stream missing readinto() or write() method." +msgstr "Metodi mancanti readinto() o write() allo stream." + +#: supervisor/shared/safe_mode.c +msgid "" +"The CircuitPython heap was corrupted because the stack was too small.\n" +"Please increase stack size limits and press reset (after ejecting " +"CIRCUITPY).\n" +"If you didn't change the stack, then file an issue here with the contents of " +"your CIRCUITPY drive:\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The `microcontroller` module was used to boot into safe mode. Press reset to " +"exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +#, fuzzy +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" +"La potenza del microcontrollore è calata. Assicurati che l'alimentazione sia " +"attaccata correttamente\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"The reset button was pressed while booting CircuitPython. Press again to " +"exit safe mode.\n" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's signedness does not match the mixer's" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile value out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "Per uscire resettare la scheda senza " + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample." +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "Too many display busses" +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Too many displays" +msgstr "Troppi schermi" + +#: py/obj.c +msgid "Traceback (most recent call last):\n" +msgstr "Traceback (chiamata più recente per ultima):\n" + +#: shared-bindings/time/__init__.c +msgid "Tuple or struct_time argument required" +msgstr "Tupla o struct_time richiesto come argomento" + +#: shared-module/usb_hid/Device.c +msgid "USB Busy" +msgstr "USB occupata" + +#: shared-module/usb_hid/Device.c +msgid "USB Error" +msgstr "Errore USB" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID integer value must be 0-0xffff" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Unable to allocate buffers for signed conversion" +msgstr "Ipossibilitato ad allocare buffer per la conversione con segno" + +#: shared-module/displayio/I2CDisplay.c +#, c-format +msgid "Unable to find I2C Display at %x" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Unable to find free GCLK" +msgstr "Impossibile trovare un GCLK libero" + +#: py/parse.c +msgid "Unable to init parser" +msgstr "Inizilizzazione del parser non possibile" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." +msgstr "Imposibile scrivere su nvm." + +#: ports/nrf/common-hal/_bleio/UUID.c +#, fuzzy +msgid "Unexpected nrfx uuid type" +msgstr "indentazione inaspettata" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "Unsupported baudrate" +msgstr "baudrate non supportato" + +#: shared-module/displayio/display_core.c +#, fuzzy +msgid "Unsupported display bus type" +msgstr "tipo di bitmap non supportato" + +#: shared-module/audiocore/WaveFile.c +msgid "Unsupported format" +msgstr "Formato non supportato" + +#: py/moduerrno.c +msgid "Unsupported operation" +msgstr "Operazione non supportata" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Unsupported pull value." +msgstr "Valore di pull non supportato." + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + +#: py/emitnative.c +msgid "Viper functions don't currently support more than 4 arguments" +msgstr "Le funzioni Viper non supportano più di 4 argomenti al momento" + +#: shared-module/audiocore/Mixer.c +msgid "Voice index too high" +msgstr "" + +#: main.c +msgid "WARNING: Your code filename has two extensions\n" +msgstr "ATTENZIONE: Il nome del sorgente ha due estensioni\n" + +#: py/builtinhelp.c +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +#, fuzzy +msgid "" +"You are running in safe mode which means something unanticipated happened.\n" +msgstr "" +"Sei nella modalità sicura che significa che qualcosa di molto brutto è " +"successo.\n" + +#: supervisor/shared/safe_mode.c +msgid "You requested starting safe mode by " +msgstr "È stato richiesto l'avvio in modalità sicura da " + +#: py/objtype.c +msgid "__init__() should return None" +msgstr "__init__() deve ritornare None" + +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "__init__() deve ritornare None, non '%s'" + +#: py/objobject.c +msgid "__new__ arg must be a user-type" +msgstr "" + +#: extmod/modubinascii.c extmod/moduhashlib.c +msgid "a bytes-like object is required" +msgstr "un oggetto byte-like è richiesto" + +#: lib/embed/abort_.c +msgid "abort() called" +msgstr "abort() chiamato" + +#: extmod/machine_mem.c +#, c-format +msgid "address %08x is not aligned to %d bytes" +msgstr "l'indirizzo %08x non è allineato a %d bytes" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "address out of bounds" +msgstr "indirizzo fuori limite" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "addresses is empty" +msgstr "gli indirizzi sono vuoti" + +#: py/modbuiltins.c +msgid "arg is an empty sequence" +msgstr "l'argomento è una sequenza vuota" + +#: py/runtime.c +msgid "argument has wrong type" +msgstr "il tipo dell'argomento è errato" + +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +msgid "argument num/types mismatch" +msgstr "discrepanza di numero/tipo di argomenti" + +#: py/runtime.c +msgid "argument should be a '%q' not a '%q'" +msgstr "l'argomento dovrebbe essere un '%q' e non un '%q'" + +#: py/objarray.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" +msgstr "" + +#: py/objstr.c +msgid "attributes not supported yet" +msgstr "attributi non ancora supportati" + +#: py/builtinevex.c +msgid "bad compile mode" +msgstr "" + +#: py/objstr.c +msgid "bad conversion specifier" +msgstr "specificatore di conversione scorretto" + +#: py/objstr.c +msgid "bad format string" +msgstr "stringa di formattazione scorretta" + +#: py/binary.c +msgid "bad typecode" +msgstr "" + +#: py/emitnative.c +msgid "binary op %q not implemented" +msgstr "operazione binaria %q non implementata" + +#: shared-bindings/busio/UART.c +msgid "bits must be 7, 8 or 9" +msgstr "i bit devono essere 7, 8 o 9" + +#: extmod/machine_spi.c +msgid "bits must be 8" +msgstr "i bit devono essere 8" + +#: shared-bindings/audiocore/Mixer.c +#, fuzzy +msgid "bits_per_sample must be 8 or 16" +msgstr "i bit devono essere 7, 8 o 9" + +#: py/emitinlinethumb.c +#, fuzzy +msgid "branch not in range" +msgstr "argomento di chr() non è in range(256)" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "" + +#: shared-bindings/audiocore/RawSample.c +msgid "buffer must be a bytes-like object" +msgstr "" + +#: shared-module/struct/__init__.c +#, fuzzy +msgid "buffer size must match format" +msgstr "slice del buffer devono essere della stessa lunghezza" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" +msgstr "slice del buffer devono essere della stessa lunghezza" + +#: py/modstruct.c shared-bindings/struct/__init__.c +#: shared-module/struct/__init__.c +msgid "buffer too small" +msgstr "buffer troppo piccolo" + +#: extmod/machine_spi.c +msgid "buffers must be the same length" +msgstr "i buffer devono essere della stessa lunghezza" + +#: shared-bindings/_pew/PewPew.c +msgid "buttons must be digitalio.DigitalInOut" +msgstr "" + +#: py/vm.c +msgid "byte code not implemented" +msgstr "byte code non implementato" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "bytes > 8 bits not supported" +msgstr "byte > 8 bit non supportati" + +#: py/objstr.c +msgid "bytes value out of range" +msgstr "valore byte fuori intervallo" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" +msgstr "la calibrazione è fuori intervallo" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" +msgstr "la calibrazione è in sola lettura" + +#: ports/atmel-samd/common-hal/rtc/RTC.c +msgid "calibration value out of range +/-127" +msgstr "valore di calibrazione fuori intervallo +/-127" + +#: py/emitinlinethumb.c +#, fuzzy +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "sono disponibili fino a 4 parametri per il Xtensa assembly" + +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "sono disponibili fino a 4 parametri per il Xtensa assembly" + +#: py/persistentcode.c +msgid "can only save bytecode" +msgstr "È possibile salvare solo bytecode" + +#: py/objtype.c +msgid "can't add special method to already-subclassed class" +msgstr "" + +#: py/compile.c +msgid "can't assign to expression" +msgstr "impossibile assegnare all'espressione" + +#: py/obj.c +#, fuzzy, c-format +msgid "can't convert %s to complex" +msgstr "non è possibile convertire a complex" + +#: py/obj.c +#, c-format +msgid "can't convert %s to float" +msgstr "non è possibile convertire %s a float" + +#: py/obj.c +#, c-format +msgid "can't convert %s to int" +msgstr "non è possibile convertire %s a int" + +#: py/objstr.c +msgid "can't convert '%q' object to %q implicitly" +msgstr "impossibile convertire l'oggetto '%q' implicitamente in %q" + +#: py/objint.c +msgid "can't convert NaN to int" +msgstr "impossibile convertire NaN in int" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "can't convert address to int" +msgstr "impossible convertire indirizzo in int" + +#: py/objint.c +msgid "can't convert inf to int" +msgstr "impossibile convertire inf in int" + +#: py/obj.c +msgid "can't convert to complex" +msgstr "non è possibile convertire a complex" + +#: py/obj.c +msgid "can't convert to float" +msgstr "non è possibile convertire a float" + +#: py/obj.c +msgid "can't convert to int" +msgstr "non è possibile convertire a int" + +#: py/objstr.c +msgid "can't convert to str implicitly" +msgstr "impossibile convertire a stringa implicitamente" + +#: py/compile.c +msgid "can't declare nonlocal in outer code" +msgstr "impossibile dichiarare nonlocal nel codice esterno" + +#: py/compile.c +msgid "can't delete expression" +msgstr "impossibile cancellare l'espessione" + +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" +msgstr "impossibile eseguire operazione binaria tra '%q' e '%q'" + +#: py/objcomplex.c +msgid "can't do truncated division of a complex number" +msgstr "impossibile fare il modulo di un numero complesso" + +#: py/compile.c +msgid "can't have multiple **x" +msgstr "impossibile usare **x multipli" + +#: py/compile.c +msgid "can't have multiple *x" +msgstr "impossibile usare *x multipli" + +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "non è possibile convertire implicitamente '%q' in 'bool'" + +#: py/emitnative.c +msgid "can't load from '%q'" +msgstr "impossibile caricare da '%q'" + +#: py/emitnative.c +msgid "can't load with '%q' index" +msgstr "impossibile caricare con indice '%q'" + +#: py/objgenerator.c +msgid "can't pend throw to just-started generator" +msgstr "" + +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" +msgstr "" + +#: py/objnamedtuple.c +msgid "can't set attribute" +msgstr "impossibile impostare attributo" + +#: py/emitnative.c +msgid "can't store '%q'" +msgstr "impossibile memorizzare '%q'" + +#: py/emitnative.c +msgid "can't store to '%q'" +msgstr "impossibile memorizzare in '%q'" + +#: py/emitnative.c +msgid "can't store with '%q' index" +msgstr "impossibile memorizzare con indice '%q'" + +#: py/objstr.c +msgid "" +"can't switch from automatic field numbering to manual field specification" +msgstr "" + +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "" + +#: py/objtype.c +msgid "cannot create '%q' instances" +msgstr "creare '%q' istanze" + +#: py/objtype.c +msgid "cannot create instance" +msgstr "impossibile creare un istanza" + +#: py/runtime.c +msgid "cannot import name %q" +msgstr "impossibile imporate il nome %q" + +#: py/builtinimport.c +msgid "cannot perform relative import" +msgstr "impossibile effettuare l'importazione relativa" + +#: py/emitnative.c +msgid "casting" +msgstr "casting" + +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" +msgstr "buffer dei caratteri troppo piccolo" + +#: py/modbuiltins.c +msgid "chr() arg not in range(0x110000)" +msgstr "argomento di chr() non è in range(0x110000)" + +#: py/modbuiltins.c +msgid "chr() arg not in range(256)" +msgstr "argomento di chr() non è in range(256)" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "" +"il buffer del colore deve esseer di 3 byte (RGB) o 4 byte (RGB + pad byte)" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer or int" +msgstr "il buffer del colore deve essere un buffer o un int" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" +"buffer del colore deve essere un bytearray o un array di tipo 'b' o 'B'" + +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" +msgstr "il colore deve essere compreso tra 0x000000 e 0xffffff" + +#: shared-bindings/displayio/ColorConverter.c +msgid "color should be an int" +msgstr "il colore deve essere un int" + +#: py/objcomplex.c +msgid "complex division by zero" +msgstr "complex divisione per zero" + +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" +msgstr "valori complessi non supportai" + +#: extmod/moduzlib.c +msgid "compression header" +msgstr "compressione dell'header" + +#: py/parse.c +msgid "constant must be an integer" +msgstr "la costante deve essere un intero" + +#: py/emitnative.c +msgid "conversion to object" +msgstr "conversione in oggetto" + +#: py/parsenum.c +msgid "decimal numbers not supported" +msgstr "numeri decimali non supportati" + +#: py/compile.c +msgid "default 'except' must be last" +msgstr "'except' predefinito deve essere ultimo" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" +"il buffer di destinazione deve essere un bytearray o un array di tipo 'B' " +"con bit_depth = 8" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "" +"il buffer di destinazione deve essere un array di tipo 'H' con bit_depth = 16" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination_length must be an int >= 0" +msgstr "destination_length deve essere un int >= 0" + +#: py/objdict.c +msgid "dict update sequence has wrong length" +msgstr "sequanza di aggiornamento del dizionario ha la lunghezza errata" + +#: py/modmath.c py/objfloat.c py/objint_longlong.c py/objint_mpz.c py/runtime.c +#: shared-bindings/math/__init__.c +msgid "division by zero" +msgstr "divisione per zero" + +#: py/objdeque.c +msgid "empty" +msgstr "vuoto" + +#: extmod/moduheapq.c extmod/modutimeq.c +msgid "empty heap" +msgstr "heap vuoto" + +#: py/objstr.c +msgid "empty separator" +msgstr "separatore vuoto" + +#: shared-bindings/random/__init__.c +msgid "empty sequence" +msgstr "sequenza vuota" + +#: py/objstr.c +msgid "end of format while looking for conversion specifier" +msgstr "" + +#: shared-bindings/displayio/Shape.c +#, fuzzy +msgid "end_x should be an int" +msgstr "y dovrebbe essere un int" + +#: ports/nrf/common-hal/busio/UART.c +#, c-format +msgid "error = 0x%08lX" +msgstr "errore = 0x%08lX" + +#: py/runtime.c +msgid "exceptions must derive from BaseException" +msgstr "le eccezioni devono derivare da BaseException" + +#: py/objstr.c +msgid "expected ':' after format specifier" +msgstr "':' atteso dopo lo specificatore di formato" + +#: py/obj.c +msgid "expected tuple/list" +msgstr "lista/tupla prevista" + +#: py/modthread.c +msgid "expecting a dict for keyword args" +msgstr "argomenti nominati necessitano un dizionario" + +#: py/compile.c +msgid "expecting an assembler instruction" +msgstr "istruzione assembler attesa" + +#: py/compile.c +msgid "expecting just a value for set" +msgstr "un solo valore atteso per set" + +#: py/compile.c +msgid "expecting key:value for dict" +msgstr "chiave:valore atteso per dict" + +#: py/argcheck.c +msgid "extra keyword arguments given" +msgstr "argomento nominato aggiuntivo fornito" + +#: py/argcheck.c +msgid "extra positional arguments given" +msgstr "argomenti posizonali extra dati" + +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c +msgid "file must be a file opened in byte mode" +msgstr "" + +#: shared-bindings/storage/__init__.c +msgid "filesystem must provide mount method" +msgstr "il filesystem deve fornire un metodo di mount" + +#: py/objtype.c +msgid "first argument to super() must be type" +msgstr "" + +#: extmod/machine_spi.c +msgid "firstbit must be MSB" +msgstr "il primo bit deve essere il più significativo (MSB)" + +#: py/objint.c +msgid "float too big" +msgstr "float troppo grande" + +#: shared-bindings/_stage/Text.c +msgid "font must be 2048 bytes long" +msgstr "il font deve essere lungo 2048 byte" + +#: py/objstr.c +msgid "format requires a dict" +msgstr "la formattazione richiede un dict" + +#: py/objdeque.c +msgid "full" +msgstr "pieno" + +#: py/argcheck.c +msgid "function does not take keyword arguments" +msgstr "la funzione non prende argomenti nominati" + +#: py/argcheck.c +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "la funzione prevede al massimo %d argmoneti, ma ne ha ricevuti %d" + +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" +msgstr "la funzione ha ricevuto valori multipli per l'argomento '%q'" + +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" +msgstr "mancano %d argomenti posizionali obbligatori alla funzione" + +#: py/bc.c +msgid "function missing keyword-only argument" +msgstr "argomento nominato mancante alla funzione" + +#: py/bc.c +msgid "function missing required keyword argument '%q'" +msgstr "argomento nominato '%q' mancante alla funzione" + +#: py/bc.c +#, c-format +msgid "function missing required positional argument #%d" +msgstr "mancante il #%d argomento posizonale obbligatorio della funzione" + +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "" +"la funzione prende %d argomenti posizionali ma ne sono stati forniti %d" + +#: shared-bindings/time/__init__.c +msgid "function takes exactly 9 arguments" +msgstr "la funzione prende esattamente 9 argomenti" + +#: py/objgenerator.c +msgid "generator already executing" +msgstr "" + +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" +msgstr "" + +#: shared-bindings/_stage/Layer.c +msgid "graphic must be 2048 bytes long" +msgstr "graphic deve essere lunga 2048 byte" + +#: extmod/moduheapq.c +msgid "heap must be a list" +msgstr "l'heap deve essere una lista" + +#: py/compile.c +msgid "identifier redefined as global" +msgstr "identificatore ridefinito come globale" + +#: py/compile.c +msgid "identifier redefined as nonlocal" +msgstr "identificatore ridefinito come nonlocal" + +#: py/objstr.c +msgid "incomplete format" +msgstr "formato incompleto" + +#: py/objstr.c +msgid "incomplete format key" +msgstr "" + +#: extmod/modubinascii.c +msgid "incorrect padding" +msgstr "padding incorretto" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c py/obj.c +msgid "index out of range" +msgstr "indice fuori intervallo" + +#: py/obj.c +msgid "indices must be integers" +msgstr "gli indici devono essere interi" + +#: py/compile.c +msgid "inline assembler must be a function" +msgstr "inline assembler deve essere una funzione" + +#: py/parsenum.c +msgid "int() arg 2 must be >= 2 and <= 36" +msgstr "il secondo argomanto di int() deve essere >= 2 e <= 36" + +#: py/objstr.c +msgid "integer required" +msgstr "intero richiesto" + +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c +#, c-format +msgid "interval must be in range %s-%s" +msgstr "" + +#: extmod/machine_i2c.c +msgid "invalid I2C peripheral" +msgstr "periferica I2C invalida" + +#: extmod/machine_spi.c +msgid "invalid SPI peripheral" +msgstr "periferica SPI invalida" + +#: lib/netutils/netutils.c +msgid "invalid arguments" +msgstr "argomenti non validi" + +#: extmod/modussl_axtls.c +msgid "invalid cert" +msgstr "certificato non valido" + +#: extmod/uos_dupterm.c +msgid "invalid dupterm index" +msgstr "indice dupterm non valido" + +#: extmod/modframebuf.c +msgid "invalid format" +msgstr "formato non valido" + +#: py/objstr.c +msgid "invalid format specifier" +msgstr "specificatore di formato non valido" + +#: extmod/modussl_axtls.c +msgid "invalid key" +msgstr "chiave non valida" + +#: py/compile.c +msgid "invalid micropython decorator" +msgstr "decoratore non valido in micropython" + +#: shared-bindings/random/__init__.c +msgid "invalid step" +msgstr "step non valida" + +#: py/compile.c py/parse.c +msgid "invalid syntax" +msgstr "sintassi non valida" + +#: py/parsenum.c +msgid "invalid syntax for integer" +msgstr "sintassi invalida per l'intero" + +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "sintassi invalida per l'intero con base %d" + +#: py/parsenum.c +msgid "invalid syntax for number" +msgstr "sintassi invalida per il numero" + +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" +msgstr "il primo argomento di issubclass() deve essere una classe" + +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "" +"il secondo argomento di issubclass() deve essere una classe o una tupla di " +"classi" + +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "" +"join prende una lista di oggetti str/byte consistenti con l'oggetto stesso" + +#: py/argcheck.c +msgid "keyword argument(s) not yet implemented - use normal args instead" +msgstr "" +"argomento(i) nominati non ancora implementati - usare invece argomenti " +"normali" + +#: py/bc.c +msgid "keywords must be strings" +msgstr "argomenti nominati devono essere stringhe" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" +msgstr "etichetta '%q' non definita" + +#: py/compile.c +msgid "label redefined" +msgstr "etichetta ridefinita" + +#: py/stream.c +msgid "length argument not allowed for this type" +msgstr "" + +#: py/objarray.c +msgid "lhs and rhs should be compatible" +msgstr "lhs e rhs devono essere compatibili" + +#: py/emitnative.c +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "local '%q' ha tipo '%q' ma sorgente è '%q'" + +#: py/emitnative.c +msgid "local '%q' used before type known" +msgstr "locla '%q' utilizzato prima che il tipo fosse noto" + +#: py/vm.c +msgid "local variable referenced before assignment" +msgstr "variabile locale richiamata prima di un assegnamento" + +#: py/objint.c +msgid "long int not supported in this build" +msgstr "long int non supportata in questa build" + +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" +msgstr "map buffer troppo piccolo" + +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" +msgstr "errore di dominio matematico" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + +#: py/runtime.c +msgid "maximum recursion depth exceeded" +msgstr "profondità massima di ricorsione superata" + +#: py/runtime.c +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "allocazione di memoria fallita, allocando %u byte" + +#: py/runtime.c +msgid "memory allocation failed, heap is locked" +msgstr "allocazione di memoria fallita, l'heap è bloccato" + +#: py/builtinimport.c +msgid "module not found" +msgstr "modulo non trovato" + +#: py/compile.c +msgid "multiple *x in assignment" +msgstr "*x multipli nell'assegnamento" + +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" +msgstr "" + +#: py/objtype.c +msgid "multiple inheritance not supported" +msgstr "ereditarietà multipla non supportata" + +#: py/emitnative.c +msgid "must raise an object" +msgstr "deve lanciare un oggetto" + +#: extmod/machine_spi.c +msgid "must specify all of sck/mosi/miso" +msgstr "è necessario specificare tutte le sck/mosi/miso" + +#: py/modbuiltins.c +msgid "must use keyword argument for key function" +msgstr "" + +#: py/runtime.c +msgid "name '%q' is not defined" +msgstr "nome '%q'non definito" + +#: shared-bindings/_bleio/Peripheral.c +#, fuzzy +msgid "name must be a string" +msgstr "argomenti nominati devono essere stringhe" + +#: py/runtime.c +msgid "name not defined" +msgstr "nome non definito" + +#: py/compile.c +msgid "name reused for argument" +msgstr "nome riutilizzato come argomento" + +#: py/emitnative.c +msgid "native yield" +msgstr "yield nativo" + +#: py/runtime.c +#, c-format +msgid "need more than %d values to unpack" +msgstr "necessari più di %d valori da scompattare" + +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" +msgstr "potenza negativa senza supporto per float" + +#: py/objint_mpz.c py/runtime.c +msgid "negative shift count" +msgstr "" + +#: py/vm.c +msgid "no active exception to reraise" +msgstr "nessuna eccezione attiva da rilanciare" + +#: shared-bindings/socket/__init__.c shared-module/network/__init__.c +#, fuzzy +msgid "no available NIC" +msgstr "busio.UART non ancora implementato" + +#: py/compile.c +msgid "no binding for nonlocal found" +msgstr "nessun binding per nonlocal trovato" + +#: py/builtinimport.c +msgid "no module named '%q'" +msgstr "nessun modulo chiamato '%q'" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "no reset pin available" +msgstr "" + +#: py/runtime.c shared-bindings/_pixelbuf/__init__.c +msgid "no such attribute" +msgstr "attributo inesistente" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" +msgstr "" + +#: py/compile.c +msgid "non-default argument follows default argument" +msgstr "argomento non predefinito segue argmoento predfinito" + +#: extmod/modubinascii.c +msgid "non-hex digit found" +msgstr "trovata cifra non esadecimale" + +#: py/compile.c +msgid "non-keyword arg after */**" +msgstr "argomento non nominato dopo */**" + +#: py/compile.c +msgid "non-keyword arg after keyword arg" +msgstr "argomento non nominato seguito da argomento nominato" + +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" +msgstr "" + +#: py/objstr.c +msgid "not all arguments converted during string formatting" +msgstr "" +"non tutti gli argomenti sono stati convertiti durante la formatazione in " +"stringhe" + +#: py/objstr.c +msgid "not enough arguments for format string" +msgstr "argomenti non sufficienti per la stringa di formattazione" + +#: py/obj.c +#, c-format +msgid "object '%s' is not a tuple or list" +msgstr "oggetto '%s' non è una tupla o una lista" + +#: py/obj.c +msgid "object does not support item assignment" +msgstr "" + +#: py/obj.c +msgid "object does not support item deletion" +msgstr "" + +#: py/obj.c +msgid "object has no len" +msgstr "l'oggetto non ha lunghezza" + +#: py/obj.c +msgid "object is not subscriptable" +msgstr "" + +#: py/runtime.c +msgid "object not an iterator" +msgstr "l'oggetto non è un iteratore" + +#: py/objtype.c py/runtime.c +msgid "object not callable" +msgstr "" + +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" +msgstr "oggetto non in sequenza" + +#: py/runtime.c +msgid "object not iterable" +msgstr "oggetto non iterabile" + +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" +msgstr "l'oggetto di tipo '%s' non implementa len()" + +#: py/obj.c +msgid "object with buffer protocol required" +msgstr "" + +#: extmod/modubinascii.c +msgid "odd-length string" +msgstr "stringa di lunghezza dispari" + +#: py/objstr.c py/objstrunicode.c +#, fuzzy +msgid "offset out of bounds" +msgstr "indirizzo fuori limite" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" +msgstr "solo slice con step=1 (aka None) sono supportate" + +#: py/modbuiltins.c +msgid "ord expects a character" +msgstr "ord() aspetta un carattere" + +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "" +"ord() aspettava un carattere, ma ha ricevuto una stringa di lunghezza %d" + +#: py/objint_mpz.c +msgid "overflow converting long int to machine word" +msgstr "overflow convertendo long int in parola" + +#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c +msgid "palette must be 32 bytes long" +msgstr "la palette deve essere lunga 32 byte" + +#: shared-bindings/displayio/Palette.c +msgid "palette_index should be an int" +msgstr "palette_index deve essere un int" + +#: py/compile.c +msgid "parameter annotation must be an identifier" +msgstr "" + +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" +msgstr "parametri devono essere i registri in sequenza da a2 a a5" + +#: py/emitinlinethumb.c +#, fuzzy +msgid "parameters must be registers in sequence r0 to r3" +msgstr "parametri devono essere i registri in sequenza da a2 a a5" + +#: shared-bindings/displayio/Bitmap.c +#, fuzzy +msgid "pixel coordinates out of bounds" +msgstr "indirizzo fuori limite" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel value requires too many bits" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" +msgstr "pixel_shader deve essere displayio.Palette o displayio.ColorConverter" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" +msgstr "pop sun un PulseIn vuoto" + +#: py/objset.c +msgid "pop from an empty set" +msgstr "pop da un set vuoto" + +#: py/objlist.c +msgid "pop from empty list" +msgstr "pop da una lista vuota" + +#: py/objdict.c +msgid "popitem(): dictionary is empty" +msgstr "popitem(): il dizionario è vuoto" + +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" +msgstr "il terzo argomento di pow() non può essere 0" + +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" +msgstr "pow() con 3 argomenti richiede interi" + +#: extmod/modutimeq.c +msgid "queue overflow" +msgstr "overflow della coda" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "rawbuf is not the same size as buf" +msgstr "" + +#: shared-bindings/_pixelbuf/__init__.c +#, fuzzy +msgid "readonly attribute" +msgstr "attributo non leggibile" + +#: py/builtinimport.c +msgid "relative import" +msgstr "importazione relativa" + +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" +msgstr "lunghezza %d richiesta ma l'oggetto ha lunghezza %d" + +#: py/compile.c +msgid "return annotation must be an identifier" +msgstr "" + +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" +msgstr "return aspettava '%q' ma ha ottenuto '%q'" + +#: py/objstr.c +msgid "rsplit(None,n)" +msgstr "" + +#: shared-bindings/audiocore/RawSample.c +msgid "" +"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " +"'B'" +msgstr "" +"il buffer sample_source deve essere un bytearray o un array di tipo 'h', " +"'H', 'b' o 'B'" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" +msgstr "frequenza di campionamento fuori intervallo" + +#: py/modmicropython.c +msgid "schedule stack full" +msgstr "" + +#: lib/utils/pyexec.c py/builtinimport.c +msgid "script compilation not supported" +msgstr "compilazione dello scrip non suportata" + +#: py/objstr.c +msgid "sign not allowed in string format specifier" +msgstr "segno non permesso nello spcificatore di formato della stringa" + +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" +msgstr "segno non permesso nello spcificatore di formato 'c' della stringa" + +#: py/objstr.c +msgid "single '}' encountered in format string" +msgstr "'}' singolo presente nella stringa di formattazione" + +#: shared-bindings/time/__init__.c +msgid "sleep length must be non-negative" +msgstr "la lunghezza di sleed deve essere non negativa" + +#: py/objslice.c py/sequence.c +msgid "slice step cannot be zero" +msgstr "la step della slice non può essere zero" + +#: py/objint.c py/sequence.c +msgid "small int overflow" +msgstr "small int overflow" + +#: main.c +msgid "soft reboot\n" +msgstr "soft reboot\n" + +#: py/objstr.c +msgid "start/end indices" +msgstr "" + +#: shared-bindings/displayio/Shape.c +#, fuzzy +msgid "start_x should be an int" +msgstr "y dovrebbe essere un int" + +#: shared-bindings/random/__init__.c +msgid "step must be non-zero" +msgstr "step deve essere non zero" + +#: shared-bindings/busio/UART.c +msgid "stop must be 1 or 2" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" +msgstr "stop non raggiungibile dall'inizio" + +#: py/stream.c +msgid "stream operation not supported" +msgstr "operazione di stream non supportata" + +#: py/objstrunicode.c +msgid "string index out of range" +msgstr "indice della stringa fuori intervallo" + +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" +msgstr "indici della stringa devono essere interi, non %s" + +#: py/stream.c +msgid "string not supported; use bytes or bytearray" +msgstr "" + +#: extmod/moductypes.c +msgid "struct: cannot index" +msgstr "struct: impossibile indicizzare" + +#: extmod/moductypes.c +msgid "struct: index out of range" +msgstr "struct: indice fuori intervallo" + +#: extmod/moductypes.c +msgid "struct: no fields" +msgstr "struct: nessun campo" + +#: py/objstr.c +msgid "substring not found" +msgstr "sottostringa non trovata" + +#: py/compile.c +msgid "super() can't find self" +msgstr "" + +#: extmod/modujson.c +msgid "syntax error in JSON" +msgstr "errore di sintassi nel JSON" + +#: extmod/moductypes.c +msgid "syntax error in uctypes descriptor" +msgstr "errore di sintassi nel descrittore uctypes" + +#: shared-bindings/touchio/TouchIn.c +msgid "threshold must be in the range 0-65536" +msgstr "la soglia deve essere nell'intervallo 0-65536" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes a 9-sequence" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes exactly 1 argument" +msgstr "time.struct_time() prende esattamente un argomento" + +#: shared-bindings/busio/UART.c +msgid "timeout >100 (units are now seconds, not msecs)" +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#, fuzzy +msgid "timeout must be >= 0.0" +msgstr "i bit devono essere 8" + +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" +msgstr "timestamp è fuori intervallo per il time_t della piattaforma" + +#: shared-module/struct/__init__.c +msgid "too many arguments provided with the given format" +msgstr "troppi argomenti forniti con il formato specificato" + +#: py/runtime.c +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "troppi valori da scompattare (%d attesi)" + +#: py/objstr.c +msgid "tuple index out of range" +msgstr "indice della tupla fuori intervallo" + +#: py/obj.c +msgid "tuple/list has wrong length" +msgstr "tupla/lista ha la lunghezza sbagliata" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "tuple/list required on RHS" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "tx and rx cannot both be None" +msgstr "tx e rx non possono essere entrambi None" + +#: py/objtype.c +msgid "type '%q' is not an acceptable base type" +msgstr "il tipo '%q' non è un tipo di base accettabile" + +#: py/objtype.c +msgid "type is not an acceptable base type" +msgstr "il tipo non è un tipo di base accettabile" + +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" +msgstr "l'oggetto di tipo '%q' non ha l'attributo '%q'" + +#: py/objtype.c +msgid "type takes 1 or 3 arguments" +msgstr "tipo prende 1 o 3 argomenti" + +#: py/objint_longlong.c +msgid "ulonglong too large" +msgstr "ulonglong troppo grande" + +#: py/emitnative.c +msgid "unary op %q not implemented" +msgstr "operazione unaria %q non implementata" + +#: py/parse.c +msgid "unexpected indent" +msgstr "indentazione inaspettata" + +#: py/bc.c +msgid "unexpected keyword argument" +msgstr "argomento nominato inaspettato" + +#: py/bc.c py/objnamedtuple.c +msgid "unexpected keyword argument '%q'" +msgstr "argomento nominato '%q' inaspettato" + +#: py/lexer.c +msgid "unicode name escapes" +msgstr "" + +#: py/parse.c +msgid "unindent does not match any outer indentation level" +msgstr "" + +#: py/objstr.c +#, fuzzy, c-format +msgid "unknown conversion specifier %c" +msgstr "specificatore di conversione %s sconosciuto" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type '%s'" +msgstr "codice di formattaione '%c' sconosciuto per oggetto di tipo '%s'" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'float'" +msgstr "codice di formattazione '%c' sconosciuto per oggetto di tipo 'float'" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'str'" +msgstr "codice di formattazione '%c' sconosciuto per oggetto di tipo 'str'" + +#: py/compile.c +msgid "unknown type" +msgstr "tipo sconosciuto" + +#: py/emitnative.c +msgid "unknown type '%q'" +msgstr "tipo '%q' sconosciuto" + +#: py/objstr.c +msgid "unmatched '{' in format" +msgstr "'{' spaiato nella stringa di formattazione" + +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" +msgstr "attributo non leggibile" + +#: shared-bindings/displayio/TileGrid.c +msgid "unsupported %q type" +msgstr "tipo di %q non supportato" + +#: py/emitinlinethumb.c +#, fuzzy, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "istruzione '%s' Xtensa non supportata con %d argomenti" + +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "istruzione '%s' Xtensa non supportata con %d argomenti" + +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "carattere di formattazione '%c' (0x%x) non supportato all indice %d" + +#: py/runtime.c +msgid "unsupported type for %q: '%s'" +msgstr "tipo non supportato per %q: '%s'" + +#: py/runtime.c +msgid "unsupported type for operator" +msgstr "tipo non supportato per l'operando" + +#: py/runtime.c +msgid "unsupported types for %q: '%s', '%s'" +msgstr "tipi non supportati per %q: '%s', '%s'" + +#: py/objint.c +#, c-format +msgid "value must fit in %d byte(s)" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "value_count must be > 0" +msgstr "" + +#: shared-bindings/_bleio/Scanner.c +msgid "window must be <= interval" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "write_args must be a list, tuple, or None" +msgstr "" + +#: py/objstr.c +msgid "wrong number of arguments" +msgstr "numero di argomenti errato" + +#: py/runtime.c +msgid "wrong number of values to unpack" +msgstr "numero di valori da scompattare non corretto" + +#: shared-module/displayio/Shape.c +#, fuzzy +msgid "x value out of bounds" +msgstr "indirizzo fuori limite" + +#: shared-bindings/displayio/Shape.c +msgid "y should be an int" +msgstr "y dovrebbe essere un int" + +#: shared-module/displayio/Shape.c +#, fuzzy +msgid "y value out of bounds" +msgstr "indirizzo fuori limite" + +#: py/objrange.c +msgid "zero step" +msgstr "zero step" + +#~ msgid "AP required" +#~ msgstr "AP richiesto" + +#~ msgid "C-level assert" +#~ msgstr "assert a livello C" + +#~ msgid "Can't add services in Central mode" +#~ msgstr "non si può aggiungere servizi in Central mode" + +#~ msgid "Can't advertise in Central mode" +#~ msgstr "non si può pubblicizzare in Central mode" + +#~ msgid "Can't change the name in Central mode" +#~ msgstr "non si può cambiare il nome in Central mode" + +#~ msgid "Can't connect in Peripheral mode" +#~ msgstr "non si può connettere in Periferal mode" + +#~ msgid "Cannot connect to AP" +#~ msgstr "Impossible connettersi all'AP" + +#~ msgid "Cannot disconnect from AP" +#~ msgstr "Impossible disconnettersi all'AP" + +#~ msgid "Cannot set STA config" +#~ msgstr "Impossibile impostare la configurazione della STA" + +#~ msgid "Cannot update i/f status" +#~ msgstr "Impossibile aggiornare status di i/f" + +#~ msgid "Characteristic UUID doesn't match Service UUID" +#~ msgstr "caratteristico UUID non assomiglia servizio UUID" + +#~ msgid "Characteristic already in use by another Service." +#~ msgstr "caratteristico già usato da un altro servizio" + +#, fuzzy +#~ msgid "Data too large for the advertisement packet" +#~ msgstr "Impossibile inserire dati nel pacchetto di advertisement." + +#~ msgid "Don't know how to pass object to native function" +#~ msgstr "Non so come passare l'oggetto alla funzione nativa" + +#~ msgid "ESP8226 does not support safe mode." +#~ msgstr "ESP8266 non supporta la modalità sicura." + +#~ msgid "ESP8266 does not support pull down." +#~ msgstr "ESP8266 non supporta pull-down" + +#~ msgid "Error in ffi_prep_cif" +#~ msgstr "Errore in ffi_prep_cif" + +#, fuzzy +#~ msgid "Failed to acquire mutex" +#~ msgstr "Impossibile allocare buffer RX" + +#, fuzzy +#~ msgid "Failed to add service" +#~ msgstr "Impossibile fermare advertisement. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to connect:" +#~ msgstr "Impossibile connettersi. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to continue scanning" +#~ msgstr "Impossible iniziare la scansione. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to create mutex" +#~ msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to notify or indicate attribute value, err %0x04x" +#~ msgstr "Impossibile notificare valore dell'attributo. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to read attribute value, err %0x04x" +#~ msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to release mutex" +#~ msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to start advertising" +#~ msgstr "Impossibile avviare advertisement. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to start scanning" +#~ msgstr "Impossible iniziare la scansione. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to stop advertising" +#~ msgstr "Impossibile fermare advertisement. status: 0x%02x" + +#~ msgid "GPIO16 does not support pull up." +#~ msgstr "GPIO16 non supporta pull-up" + +#~ msgid "Invalid bit clock pin" +#~ msgstr "Pin del clock di bit non valido" + +#~ msgid "Invalid clock pin" +#~ msgstr "Pin di clock non valido" + +#~ msgid "Invalid data pin" +#~ msgstr "Pin dati non valido" + +#~ msgid "Maximum PWM frequency is %dhz." +#~ msgstr "Frequenza massima su PWM è %dhz" + +#~ msgid "Minimum PWM frequency is 1hz." +#~ msgstr "Frequenza minima su PWM è 1hz" + +#~ msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." +#~ msgstr "Frequenze PWM multiple non supportate. PWM già impostato a %shz." + +#~ msgid "Must be a Group subclass." +#~ msgstr "Deve essere un Group subclass" + +#~ msgid "No PulseIn support for %q" +#~ msgstr "Nessun supporto per PulseIn per %q" + +#~ msgid "No hardware support for analog out." +#~ msgstr "Nessun supporto hardware per l'uscita analogica." + +#~ msgid "Only Windows format, uncompressed BMP supported %d" +#~ msgstr "Formato solo di Windows, BMP non compresso supportato %d" + +#~ msgid "Only bit maps of 8 bit color or less are supported" +#~ msgstr "Sono supportate solo bitmap con colori a 8 bit o meno" + +#~ msgid "Only true color (24 bpp or higher) BMP supported %x" +#~ msgstr "Solo BMP true color (24 bpp o superiore) sono supportati %x" + +#~ msgid "Only tx supported on UART1 (GPIO2)." +#~ msgstr "Solo tx supportato su UART1 (GPIO2)." + +#~ msgid "PWM not supported on pin %d" +#~ msgstr "PWM non è supportato sul pin %d" + +#~ msgid "Pin %q does not have ADC capabilities" +#~ msgstr "Il pin %q non ha capacità ADC" + +#~ msgid "Pin(16) doesn't support pull" +#~ msgstr "Pin(16) non supporta pull" + +#~ msgid "Pins not valid for SPI" +#~ msgstr "Pin non validi per SPI" + +#~ msgid "STA must be active" +#~ msgstr "STA deve essere attiva" + +#~ msgid "STA required" +#~ msgstr "STA richiesta" + +#~ msgid "UART(%d) does not exist" +#~ msgstr "UART(%d) non esistente" + +#~ msgid "UART(1) can't read" +#~ msgstr "UART(1) non leggibile" + +#~ msgid "Unable to remount filesystem" +#~ msgstr "Imposssibile rimontare il filesystem" + +#~ msgid "Unknown type" +#~ msgstr "Tipo sconosciuto" + +#~ msgid "Use esptool to erase flash and re-upload Python instead" +#~ msgstr "Usa esptool per cancellare la flash e ricaricare Python invece" + +#~ msgid "[addrinfo error %d]" +#~ msgstr "[errore addrinfo %d]" + +#~ msgid "buffer too long" +#~ msgstr "buffer troppo lungo" + +#~ msgid "can query only one param" +#~ msgstr "è possibile interrogare solo un parametro" + +#~ msgid "can't get AP config" +#~ msgstr "impossibile recuperare le configurazioni dell'AP" + +#~ msgid "can't get STA config" +#~ msgstr "impossibile recuperare la configurazione della STA" + +#~ msgid "can't set AP config" +#~ msgstr "impossibile impostare le configurazioni dell'AP" + +#~ msgid "can't set STA config" +#~ msgstr "impossibile impostare le configurazioni della STA" + +#~ msgid "either pos or kw args are allowed" +#~ msgstr "sono permesse solo gli argomenti pos o kw" + +#~ msgid "expected a DigitalInOut" +#~ msgstr "DigitalInOut atteso" + +#~ msgid "expecting a pin" +#~ msgstr "pin atteso" + +#~ msgid "ffi_prep_closure_loc" +#~ msgstr "ffi_prep_closure_loc" + +#~ msgid "flash location must be below 1MByte" +#~ msgstr "Locazione della flash deve essere inferiore a 1mb" + +#~ msgid "frequency can only be either 80Mhz or 160MHz" +#~ msgstr "la frequenza può essere o 80Mhz o 160Mhz" + +#~ msgid "impossible baudrate" +#~ msgstr "baudrate impossibile" + +#~ msgid "invalid alarm" +#~ msgstr "alarm non valido" + +#~ msgid "invalid buffer length" +#~ msgstr "lunghezza del buffer non valida" + +#~ msgid "invalid data bits" +#~ msgstr "bit dati invalidi" + +#~ msgid "invalid pin" +#~ msgstr "pin non valido" + +#~ msgid "invalid stop bits" +#~ msgstr "bit di stop invalidi" + +#~ msgid "len must be multiple of 4" +#~ msgstr "len deve essere multiplo di 4" + +#~ msgid "memory allocation failed, allocating %u bytes for native code" +#~ msgstr "" +#~ "allocazione di memoria fallita, allocazione di %d byte per codice nativo" + +#~ msgid "not a valid ADC Channel: %d" +#~ msgstr "canale ADC non valido: %d" + +#~ msgid "pin does not have IRQ capabilities" +#~ msgstr "il pin non implementa IRQ" + +#~ msgid "position must be 2-tuple" +#~ msgstr "position deve essere una 2-tuple" + +#~ msgid "row must be packed and word aligned" +#~ msgstr "la riga deve essere compattata e allineata alla parola" + +#~ msgid "scan failed" +#~ msgstr "scansione fallita" + +#~ msgid "too many arguments" +#~ msgstr "troppi argomenti" + +#~ msgid "unknown config param" +#~ msgstr "parametro di configurazione sconosciuto" + +#~ msgid "unknown status param" +#~ msgstr "prametro di stato sconosciuto" + +#~ msgid "wifi_set_ip_info() failed" +#~ msgstr "wifi_set_ip_info() faillito" diff --git a/locale/pl.po b/locale/pl.po new file mode 100644 index 00000000000..c1444c1dd92 --- /dev/null +++ b/locale/pl.po @@ -0,0 +1,2805 @@ +# Adafruit CircuitPython Polish Translation +# Copyright (C) 2019 +# This file is distributed under the same license as the CircuitPython package. +# Radomir Dopieralski , 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"PO-Revision-Date: 2019-03-19 18:37-0700\n" +"Last-Translator: Radomir Dopieralski \n" +"Language-Team: pl\n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: main.c +msgid "" +"\n" +"Code done running. Waiting for reload.\n" +msgstr "" +"\n" +"Kod wykonany. Czekam na przeÅ‚adowanie.\n" + +#: py/obj.c +msgid " File \"%q\"" +msgstr " Plik \"%q\"" + +#: py/obj.c +msgid " File \"%q\", line %d" +msgstr " Plik \"%q\", linia %d" + +#: main.c +msgid " output:\n" +msgstr " wyjÅ›cie:\n" + +#: py/objstr.c +#, c-format +msgid "%%c requires int or char" +msgstr "%%c wymaga int lub char" + +#: shared-bindings/microcontroller/Pin.c +msgid "%q in use" +msgstr "%q w użyciu" + +#: py/obj.c +msgid "%q index out of range" +msgstr "%q poza zakresem" + +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "%q indeks musi być liczbÄ… caÅ‚kowitÄ…, a nie %s" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c +msgid "%q must be >= 1" +msgstr "%q musi być >= 1" + +#: shared-bindings/fontio/BuiltinFont.c +msgid "%q should be an int" +msgstr "%q powinno być typu int" + +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" +msgstr "%q() bierze %d argumentów pozycyjnych, lecz podano %d" + +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "'%q' wymaga argumentu" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" +msgstr "'%s' oczekuje etykiety" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" +msgstr "'%s' oczekuje rejestru" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects a special register" +msgstr "'%s' oczekuje rejestru specjalnego" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an FPU register" +msgstr "'%s' oczekuje rejestru FPU" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "'%s' oczekuje adresu w postaci [a, b]" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" +msgstr "'%s' oczekuje liczby caÅ‚kowitej" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects at most r%d" +msgstr "'%s' oczekuje co najwyżej r%d" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "'%s' oczekuje {r0, r1, ...}" + +#: py/emitinlinextensa.c +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "'%s' liczba %d poza zakresem %d..%d" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "'%s' liczba 0x%x nie pasuje do maski 0x%x" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item assignment" +msgstr "'%s' obiekt nie wspiera przypisania do elementów" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item deletion" +msgstr "'%s' obiekt nie wspiera usuwania elementów" + +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" +msgstr "'%s' obiekt nie ma atrybutu '%q'" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not an iterator" +msgstr "'%s' obiekt nie jest iteratorem" + +#: py/objtype.c py/runtime.c +#, c-format +msgid "'%s' object is not callable" +msgstr "'%s' nie można wywoÅ‚ywać obiektu" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not iterable" +msgstr "'%s' nie można iterować po obiekcie" + +#: py/obj.c +#, c-format +msgid "'%s' object is not subscriptable" +msgstr "'%s' nie można indeksować obiektu" + +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" +msgstr "wyrównanie '=' niedozwolone w specyfikacji formatu" + +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" +msgstr "typy formatowania 'S' oraz 'O' sÄ… niewspierane" + +#: py/compile.c +msgid "'align' requires 1 argument" +msgstr "'align' wymaga 1 argumentu" + +#: py/compile.c +msgid "'await' outside function" +msgstr "'await' poza funkcjÄ…" + +#: py/compile.c +msgid "'break' outside loop" +msgstr "'break' poza pÄ™tlÄ…" + +#: py/compile.c +msgid "'continue' outside loop" +msgstr "'continue' poza pÄ™tlÄ…" + +#: py/compile.c +msgid "'data' requires at least 2 arguments" +msgstr "'data' wymaga 2 lub wiÄ™cej argumentów" + +#: py/compile.c +msgid "'data' requires integer arguments" +msgstr "'data' wymaga caÅ‚kowitych argumentów" + +#: py/compile.c +msgid "'label' requires 1 argument" +msgstr "'label' wymaga 1 argumentu" + +#: py/compile.c +msgid "'return' outside function" +msgstr "'return' poza funkcjÄ…" + +#: py/compile.c +msgid "'yield' outside function" +msgstr "'yield' poza funkcjÄ…" + +#: py/compile.c +msgid "*x must be assignment target" +msgstr "*x musi być obiektem przypisania" + +#: py/obj.c +msgid ", in %q\n" +msgstr ", w %q\n" + +#: py/objcomplex.c +msgid "0.0 to a complex power" +msgstr "0.0 do potÄ™gi zespolonej" + +#: py/modbuiltins.c +msgid "3-arg pow() not supported" +msgstr "3-argumentowy pow() jest niewspierany" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "A hardware interrupt channel is already in use" +msgstr "KanaÅ‚ przerwaÅ„ sprzÄ™towych w użyciu" + +#: shared-bindings/_bleio/Address.c +#, c-format +msgid "Address must be %d bytes long" +msgstr "Adres musi mieć %d bajtów" + +#: shared-bindings/_bleio/Address.c +msgid "Address type out of range" +msgstr "" + +#: ports/nrf/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" +msgstr "Wszystkie peryferia I2C w użyciu" + +#: ports/nrf/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" +msgstr "Wszystkie peryferia SPI w użyciu" + +#: ports/nrf/common-hal/busio/UART.c +msgid "All UART peripherals are in use" +msgstr "Wszystkie peryferia UART w użyciu" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "Wszystkie kanaÅ‚y zdarzeÅ„ w użyciu" + +#: ports/atmel-samd/audio_dma.c ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "All sync event channels in use" +msgstr "Wszystkie kanaÅ‚y zdarzeÅ„ synchronizacji w użyciu" + +#: shared-bindings/pulseio/PWMOut.c +msgid "All timers for this pin are in use" +msgstr "Wszystkie timery tej nóżki w użyciu" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: shared-module/_pew/PewPew.c +msgid "All timers in use" +msgstr "Wszystkie timery w użyciu" + +#: ports/nrf/common-hal/analogio/AnalogOut.c +msgid "AnalogOut functionality not supported" +msgstr "AnalogOut jest niewspierane" + +#: shared-bindings/analogio/AnalogOut.c +msgid "AnalogOut is only 16 bits. Value must be less than 65536." +msgstr "AnalogOut ma 16 bitów. Wartość musi być mniejsza od 65536." + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "AnalogOut not supported on given pin" +msgstr "AnalogOut niewspierany na tej nóżce" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" +msgstr "WysyÅ‚anie jest już w toku" + +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" +msgstr "Tablica musi zawierać pół-sÅ‚owa (typ 'H')" + +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." +msgstr "WartoÅ›ci powinny być bajtami." + +#: supervisor/shared/safe_mode.c +msgid "Attempted heap allocation when MicroPython VM not running.\n" +msgstr "Próba alokacji pamiÄ™ci na stercie gdy VM nie dziaÅ‚a.\n" + +#: main.c +msgid "Auto-reload is off.\n" +msgstr "Samo-przeÅ‚adowywanie wyłączone.\n" + +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "" +"Samo-przeÅ‚adowywanie włączone. Po prostu zapisz pliki przez USB aby je " +"uruchomić, albo wejdź w konsolÄ™ aby wyłączyć.\n" + +#: shared-module/displayio/Display.c +msgid "Below minimum frame rate" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Bit clock and word select must share a clock unit" +msgstr "Zegar bitowy i wybór sÅ‚owa muszÄ… współdzielić jednostkÄ™ zegara" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Bit depth must be multiple of 8." +msgstr "Głębia musi być wielokrotnoÅ›ciÄ… 8." + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "Both pins must support hardware interrupts" +msgstr "Obie nóżki muszÄ… wspierać przerwania sprzÄ™towe" + +#: shared-bindings/displayio/Display.c +msgid "Brightness must be 0-1.0" +msgstr "" + +#: shared-bindings/supervisor/__init__.c +msgid "Brightness must be between 0 and 255" +msgstr "Jasność musi być pomiÄ™dzy 0 a 255" + +#: shared-bindings/displayio/Display.c +msgid "Brightness not adjustable" +msgstr "Jasność nie jest regulowana" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "ZÅ‚a wielkość bufora. Powinno być %d bajtów." + +#: shared-bindings/displayio/Display.c +msgid "Buffer is not a bytearray." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Buffer is too small" +msgstr "" + +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Buffer length %d too big. It must be less than %d" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c +msgid "Buffer must be at least length 1" +msgstr "Bufor musi mieć dÅ‚ugość 1 lub wiÄ™cej" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +#, c-format +msgid "Bus pin %d is already in use" +msgstr "Nóżka magistrali %d jest w użyciu" + +#: shared-bindings/_bleio/UUID.c +msgid "Byte buffer must be 16 bytes." +msgstr "Bufor musi mieć 16 bajtów." + +#: shared-bindings/nvm/ByteArray.c +msgid "Bytes must be between 0 and 255." +msgstr "Bytes musi być miÄ™dzy 0 a 255." + +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Can not use dotstar with %s" +msgstr "Nie można używać dotstar z %s" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" +msgstr "Nie można usunąć" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/nrf/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "Nie ma podciÄ…gniÄ™cia w trybie wyjÅ›cia" + +#: ports/nrf/common-hal/microcontroller/Processor.c +msgid "Cannot get temperature" +msgstr "Nie można odczytać temperatury" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Cannot output both channels on the same pin" +msgstr "Nie można mieć obu kanałów na tej samej nóżce" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot read without MISO pin." +msgstr "Nie można czytać bez nóżki MISO" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Cannot record to a file" +msgstr "Nie można nagrać do pliku" + +#: shared-module/storage/__init__.c +msgid "Cannot remount '/' when USB is active." +msgstr "Nie można przemontować '/' gdy USB dziaÅ‚a." + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +msgid "Cannot reset into bootloader because no bootloader is present." +msgstr "Nie można zrestartować -- nie ma bootloadera." + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Cannot set value when direction is input." +msgstr "Nie można ustawić wartoÅ›ci w trybie wejÅ›cia" + +#: py/objslice.c +msgid "Cannot subclass slice" +msgstr "Nie można dziedziczyć ze slice" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot transfer without MOSI and MISO pins." +msgstr "Nie można przesyÅ‚ać bez nóżek MOSI i MISO." + +#: extmod/moductypes.c +msgid "Cannot unambiguously get sizeof scalar" +msgstr "Wielkość skalara jest niejednoznaczna" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot write without MOSI pin." +msgstr "Nie można pisać bez nóżki MOSI." + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" +msgstr "Pisanie do CharacteristicBuffer niewspierane" + +#: shared-module/bitbangio/SPI.c +msgid "Clock pin init failed." +msgstr "Nie powiodÅ‚o siÄ™ ustawienie nóżki zegara" + +#: shared-module/bitbangio/I2C.c +msgid "Clock stretch too long" +msgstr "RozciÄ…gniÄ™cie zegara zbyt duże" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" +msgstr "Jednostka zegara w użyciu" + +#: shared-bindings/_pew/PewPew.c +msgid "Column entry must be digitalio.DigitalInOut" +msgstr "Kolumny muszÄ… być typu digitalio.DigitalInOut" + +#: shared-bindings/displayio/I2CDisplay.c +msgid "Command must be 0-255" +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +msgid "Command must be an int between 0 and 255" +msgstr "Komenda musi być int pomiÄ™dzy 0 a 255" + +#: py/persistentcode.c +msgid "Corrupt .mpy file" +msgstr "" + +#: py/emitglue.c +msgid "Corrupt raw code" +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "Nie można zdekodować ble_uuid, błąd 0x%04x" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "Could not initialize UART" +msgstr "Ustawienie UART nie powiodÅ‚o siÄ™" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate first buffer" +msgstr "Nie udaÅ‚a siÄ™ alokacja pierwszego bufora" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate second buffer" +msgstr "Nie udaÅ‚a siÄ™ alokacja drugiego bufora" + +#: supervisor/shared/safe_mode.c +msgid "Crash into the HardFault_Handler.\n" +msgstr "Katastrofa w HardFault_Handler.\n" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "DAC already in use" +msgstr "DAC w użyciu" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +msgid "Data 0 pin must be byte aligned" +msgstr "Nóżka data 0 musi być wyrównana do bajtu" + +#: shared-module/audiocore/WaveFile.c +msgid "Data chunk must follow fmt chunk" +msgstr "Fragment danych musi nastÄ™pować po fragmencie fmt" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Data too large for advertisement packet" +msgstr "Zbyt dużo danych pakietu rozgÅ‚oszeniowego" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Destination capacity is smaller than destination_length." +msgstr "Pojemność celu mniejsza od destination_length." + +#: shared-bindings/displayio/Display.c +msgid "Display must have a 16 bit colorspace." +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Display rotation must be in 90 degree increments" +msgstr "WyÅ›wietlacz można obracać co 90 stopni" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Drive mode not used when direction is input." +msgstr "Tryb sterowania nieużywany w trybie wejÅ›cia." + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "EXTINT channel already in use" +msgstr "KanaÅ‚ EXTINT w użyciu" + +#: extmod/modure.c +msgid "Error in regex" +msgstr "Błąd w regex" + +#: shared-bindings/microcontroller/Pin.c +#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c +#: shared-bindings/terminalio/Terminal.c +msgid "Expected a %q" +msgstr "Oczekiwano %q" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c +msgid "Expected a Characteristic" +msgstr "Oczekiwano charakterystyki" + +#: shared-bindings/_bleio/Service.c +msgid "Expected a Peripheral" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Expected a Service" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c +#: shared-bindings/_bleio/Service.c +msgid "Expected a UUID" +msgstr "Oczekiwano UUID" + +#: shared-bindings/_bleio/Central.c +msgid "Expected an Address" +msgstr "" + +#: shared-module/_pixelbuf/PixelBuf.c +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "Oczekiwano krotkÄ™ dÅ‚ugoÅ›ci %d, otrzymano %d" + +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + +#: ports/nrf/sd_mutex.c +#, fuzzy, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "Nie udaÅ‚o siÄ™ uzyskać blokady, błąd 0x$04x" + +#: ports/nrf/common-hal/_bleio/Service.c +#, fuzzy, c-format +msgid "Failed to add characteristic, err 0x%04x" +msgstr "Nie udaÅ‚o siÄ™ dodać charakterystyki, błąd 0x$04x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to add descriptor, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to add service, err 0x%04x" +msgstr "Nie udaÅ‚o siÄ™ dodać serwisu, błąd 0x%04x" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "Failed to allocate RX buffer" +msgstr "Nie udaÅ‚a siÄ™ alokacja bufora RX" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +#, c-format +msgid "Failed to allocate RX buffer of %d bytes" +msgstr "Nie udaÅ‚a siÄ™ alokacja %d bajtów na bufor RX" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to change softdevice state" +msgstr "Nie udaÅ‚o siÄ™ zmienić stanu softdevice" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to configure advertising, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Central.c +msgid "Failed to connect: timeout" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, c-format +msgid "Failed to continue scanning, err 0x%04x" +msgstr "Nie udaÅ‚a siÄ™ kontynuacja skanowania, błąd 0x%04x" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "Failed to discover services" +msgstr "Nie udaÅ‚o siÄ™ odkryć serwisów" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to get local address" +msgstr "Nie udaÅ‚o się uzyskać lokalnego adresu" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to get softdevice state" +msgstr "Nie udaÅ‚o siÄ™ odczytać stanu softdevice" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to notify or indicate attribute value, err 0x%04x" +msgstr "Nie udaÅ‚o siÄ™ powiadomić o wartoÅ›ci atrybutu, błąd 0x%04x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "Nie udaÅ‚o siÄ™ odczytać CCCD, błąd 0x%04x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "Failed to read attribute value, err 0x%04x" +msgstr "Nie udaÅ‚o siÄ™ odczytać wartoÅ›ci atrybutu, błąd 0x%04x" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to read gatts value, err 0x%04x" +msgstr "Nie udaÅ‚o siÄ™ odczytać gatts, błąd 0x%04x" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" +msgstr "Nie udaÅ‚o siÄ™ zarejestrować UUID dostawcy, błąd 0x%04x" + +#: ports/nrf/sd_mutex.c +#, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "Nie udaÅ‚o siÄ™ zwolnić blokady, błąd 0x%04x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to set device name, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "Nie udaÅ‚o siÄ™ rozpocząć rozgÅ‚aszania, błąd 0x%04x" + +#: ports/nrf/common-hal/_bleio/Central.c +#, c-format +msgid "Failed to start connecting, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, c-format +msgid "Failed to start scanning, err 0x%04x" +msgstr "Nie udaÅ‚o siÄ™ rozpocząć skanowania, błąd 0x%04x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "Nie udaÅ‚o siÄ™ zatrzymać rozgÅ‚aszania, błąd 0x%04x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to write CCCD, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to write attribute value, err 0x%04x" +msgstr "Nie udaÅ‚o siÄ™ zapisać atrybutu, błąd 0x%04x" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to write gatts value, err 0x%04x" +msgstr "Nie udaÅ‚o siÄ™ zapisać gatts, błąd 0x%04x" + +#: py/moduerrno.c +msgid "File exists" +msgstr "Plik istnieje" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash erase failed" +msgstr "Nie udaÅ‚o się skasować flash" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash erase failed to start, err 0x%04x" +msgstr "Nie udaÅ‚o siÄ™ rozpocząć kasowania flash, błąd 0x%04x" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash write failed" +msgstr "Zapis do flash nie powiódÅ‚ siÄ™" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash write failed to start, err 0x%04x" +msgstr "Nie udaÅ‚o siÄ™ rozpocząć zapisu do flash, błąd 0x%04x" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Frequency captured is above capability. Capture Paused." +msgstr "Uzyskana czÄ™stotliwość jest niemożliwa. Spauzowano." + +#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c +msgid "Function requires lock" +msgstr "Funkcja wymaga blokady" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Group already used" +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Group full" +msgstr "Grupa peÅ‚na" + +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" +msgstr "Operacja I/O na zamkniÄ™tym pliku" + +#: extmod/machine_i2c.c +msgid "I2C operation not supported" +msgstr "Operacja I2C nieobsÅ‚ugiwana" + +#: py/persistentcode.c +msgid "" +"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" +"mpy-update for more info." +msgstr "" +"Niekompatybilny plik .mpy. ProszÄ™ odÅ›wieżyć wszystkie pliki .mpy. WiÄ™cej " +"informacji na http://adafrui.it/mpy-update." + +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" +msgstr "NiewÅ‚aÅ›ciwa wielkość bufora" + +#: py/moduerrno.c +msgid "Input/output error" +msgstr "Błąd I/O" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Invalid %q pin" +msgstr "ZÅ‚a nóżka %q" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Invalid BMP file" +msgstr "ZÅ‚y BMP" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c +#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c +msgid "Invalid PWM frequency" +msgstr "ZÅ‚a czÄ™stotliwość PWM" + +#: py/moduerrno.c +msgid "Invalid argument" +msgstr "ZÅ‚y argument" + +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" +msgstr "ZÅ‚a liczba bitów wartoÅ›ci" + +#: ports/nrf/common-hal/busio/UART.c +msgid "Invalid buffer size" +msgstr "ZÅ‚a wielkość bufora" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Invalid capture period. Valid range: 1 - 500" +msgstr "ZÅ‚y okres. Poprawny zakres to: 1 - 500" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid channel count" +msgstr "ZÅ‚a liczba kanałów" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Invalid direction." +msgstr "ZÅ‚y tryb" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid file" +msgstr "ZÅ‚y plik" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" +msgstr "ZÅ‚a wielkość fragmentu formatu" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid number of bits" +msgstr "ZÅ‚a liczba bitów" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid phase" +msgstr "ZÅ‚a faza" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +#: shared-bindings/pulseio/PWMOut.c +msgid "Invalid pin" +msgstr "ZÅ‚a nóżka" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for left channel" +msgstr "ZÅ‚a nóżka dla lewego kanaÅ‚u" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for right channel" +msgstr "ZÅ‚a nóżka dla prawego kanaÅ‚u" + +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/atmel-samd/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c +#: ports/nrf/common-hal/busio/I2C.c +msgid "Invalid pins" +msgstr "ZÅ‚e nóżki" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid polarity" +msgstr "ZÅ‚a polaryzacja" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + +#: shared-bindings/microcontroller/__init__.c +msgid "Invalid run mode." +msgstr "ZÅ‚y tryb uruchomienia" + +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid voice count" +msgstr "ZÅ‚a liczba gÅ‚osów" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid wave file" +msgstr "ZÅ‚y plik wave" + +#: py/compile.c +msgid "LHS of keyword arg must be an id" +msgstr "Lewa strona argumentu nazwanego musi być nazwÄ…" + +#: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass." +msgstr "Layer musi dziedziczyć z Group albo TileGrid" + +#: py/objslice.c +msgid "Length must be an int" +msgstr "DÅ‚ugość musi być caÅ‚kowita" + +#: py/objslice.c +msgid "Length must be non-negative" +msgstr "DÅ‚ugość musi być nieujemna" + +#: supervisor/shared/safe_mode.c +msgid "" +"Looks like our core CircuitPython code crashed hard. Whoops!\n" +"Please file an issue at https://github.com/adafruit/circuitpython/issues\n" +" with the contents of your CIRCUITPY drive and this message:\n" +msgstr "" +"Ojej, wyglÄ…da na to, że CircuitPython natrafiÅ‚ na poważny problem!\n" +"Prosimy o zgÅ‚oszenie błędu pod adresem https://github.com/adafruit/" +"circuitpython/issues\n" +" z zawartoÅ›ciÄ… dysku CIRCUITPY oraz tym komunikatem:\n" + +#: shared-module/bitbangio/SPI.c +msgid "MISO pin init failed." +msgstr "Nie powiodÅ‚o siÄ™ ustawienie nóżki MISO." + +#: shared-module/bitbangio/SPI.c +msgid "MOSI pin init failed." +msgstr "Nie powiodÅ‚o siÄ™ ustawienie nóżki MOSI" + +#: shared-module/displayio/Shape.c +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "NajwiÄ™ksza wartość x przy odwróceniu to %d" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython NLR jump failed. Likely memory corruption.\n" +msgstr "" +"Skok NLR MicroPythona nie powiódÅ‚ siÄ™. Prawdopodobne skażenie pamiÄ™ci.\n" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython fatal error.\n" +msgstr "Krytyczny błąd MicroPythona.\n" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Microphone startup delay must be in range 0.0 to 1.0" +msgstr "Opóźnienie włączenia mikrofonu musi być w zakresie od 0.0 do 1.0" + +#: shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "No DAC on chip" +msgstr "Brak DAC" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "No DMA channel found" +msgstr "Nie znaleziono kanaÅ‚u DMA" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No RX pin" +msgstr "Brak nóżki RX" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No TX pin" +msgstr "Brak nóżki TX" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "No available clocks" +msgstr "Brak wolnych zegarów" + +#: shared-bindings/board/__init__.c +msgid "No default %q bus" +msgstr "Nie ma domyÅ›lnej magistrali %q" + +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" +msgstr "Brak wolnych GLCK" + +#: shared-bindings/os/__init__.c +msgid "No hardware random available" +msgstr "Brak generatora liczb losowych" + +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "No hardware support on pin" +msgstr "Brak sprzÄ™towej obsÅ‚ugi na nóżce" + +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" +msgstr "" + +#: py/moduerrno.c +msgid "No space left on device" +msgstr "Brak miejsca" + +#: py/moduerrno.c +msgid "No such file/directory" +msgstr "Brak pliku/katalogu" + +#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Peripheral.c +msgid "Not connected" +msgstr "Nie podłączono" + +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c +msgid "Not playing" +msgstr "Nic nie jest odtwarzane" + +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "Obiekt zostaÅ‚ zwolniony i nie można go już używać. Utwórz nowy obiekt." + +#: ports/nrf/common-hal/busio/UART.c +msgid "Odd parity is not supported" +msgstr "Nieparzysta parzystość nie jest wspierana" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Only 8 or 16 bit mono with " +msgstr "Tylko 8 lub 16 bitów mono z " + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" +msgstr "Wspierane sÄ… tylko nieskompresowane pliki BMP: wielkość nagłówka %d" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Only slices with step=1 (aka None) are supported" +msgstr "Wspierane sÄ… tylko fragmenty z step=1 (albo None)" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Oversample must be multiple of 8." +msgstr "Nadpróbkowanie musi być wielokrotnoÅ›ciÄ… 8." + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" +msgstr "duty_cycle musi być pomiÄ™dzy 0 a 65535 włącznie (rozdzielczość 16 bit)" + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM frequency not writable when variable_frequency is False on construction." +msgstr "Nie można zmienić czÄ™stotliwoÅ›ci PWM gdy variable_frequency=False." + +#: py/moduerrno.c +msgid "Permission denied" +msgstr "Odmowa dostÄ™pu" + +#: ports/atmel-samd/common-hal/analogio/AnalogIn.c +#: ports/nrf/common-hal/analogio/AnalogIn.c +msgid "Pin does not have ADC capabilities" +msgstr "Nóżka nie obsÅ‚uguje ADC" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Pixel beyond bounds of buffer" +msgstr "Piksel poza granicami bufora" + +#: py/builtinhelp.c +msgid "Plus any modules on the filesystem\n" +msgstr "Oraz moduÅ‚y w systemie plików\n" + +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload." +msgstr "Dowolny klawisz aby uruchomić konsolÄ™. CTRL-D aby przeÅ‚adować." + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Pull not used when direction is output." +msgstr "PodciÄ…gniÄ™cie nieużywane w trybie wyjÅ›cia." + +#: ports/nrf/common-hal/rtc/RTC.c +msgid "RTC calibration is not supported on this board" +msgstr "Brak obsÅ‚ugi kalibracji RTC" + +#: shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" +msgstr "Brak obsÅ‚ugi RTC" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Range out of bounds" +msgstr "Zakres poza granicami" + +#: shared-bindings/pulseio/PulseIn.c +msgid "Read-only" +msgstr "Tylko do odczytu" + +#: extmod/vfs_fat.c py/moduerrno.c +msgid "Read-only filesystem" +msgstr "System plików tylko do odczytu" + +#: shared-module/displayio/Bitmap.c +msgid "Read-only object" +msgstr "Obiekt tylko do odczytu" + +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Refresh too soon" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" +msgstr "Prawy kanaÅ‚ jest niewspierany" + +#: shared-bindings/_pew/PewPew.c +msgid "Row entry must be digitalio.DigitalInOut" +msgstr "RzÄ™dy muszÄ… być digitalio.DigitalInOut" + +#: main.c +msgid "Running in safe mode! Auto-reload is off.\n" +msgstr "Uruchomiony tryb bezpieczeÅ„stwa! Samo-przeÅ‚adowanie wyłączone.\n" + +#: main.c +msgid "Running in safe mode! Not running saved code.\n" +msgstr "Uruchomiony tryb bezpieczeÅ„stwa! Zapisany kod nie jest uruchamiany.\n" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "SDA or SCL needs a pull up" +msgstr "SDA lub SCL wymagajÄ… podciÄ…gniÄ™cia" + +#: shared-bindings/audiocore/Mixer.c +msgid "Sample rate must be positive" +msgstr "CzÄ™stotliwość próbkowania musi być dodatnia" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Sample rate too high. It must be less than %d" +msgstr "Zbyt wysoka czÄ™stotliwość próbkowania. Musi być mniejsza niż %d" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" +msgstr "Serializator w użyciu" + +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." +msgstr "Fragment i wartość sÄ… różnych dÅ‚ugoÅ›ci." + +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/pulseio/PulseIn.c +msgid "Slices not supported" +msgstr "Fragmenty nieobsÅ‚ugiwane" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "Soft device assert, id: 0x%08lX, pc: 0x%08lX" + +#: extmod/modure.c +msgid "Splitting with sub-captures" +msgstr "PodziaÅ‚ z podgrupami" + +#: shared-bindings/supervisor/__init__.c +msgid "Stack size must be at least 256" +msgstr "Stos musi mieć co najmniej 256 bajtów" + +#: shared-bindings/multiterminal/__init__.c +msgid "Stream missing readinto() or write() method." +msgstr "StrumieÅ„ nie ma metod readinto() lub write()." + +#: supervisor/shared/safe_mode.c +msgid "" +"The CircuitPython heap was corrupted because the stack was too small.\n" +"Please increase stack size limits and press reset (after ejecting " +"CIRCUITPY).\n" +"If you didn't change the stack, then file an issue here with the contents of " +"your CIRCUITPY drive:\n" +msgstr "" +"Sterta CircuitPythona jest skażona z powodu zbyt maÅ‚ego stosu.\n" +"ProszÄ™ zwiÄ™kszyć limity wielkoÅ›ci stosu i nazisnąć reset (po odmontowaniu " +"CIRCUITPY).\n" +"JeÅ›li wielkość stosu nie byÅ‚a zmieniana, proszÄ™ zgÅ‚osić błąd zawierajÄ…cy " +"zawartość CIRCUITPY tutaj:\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"The `microcontroller` module was used to boot into safe mode. Press reset to " +"exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" +"Zasilanie mikrokontrolera gwaÅ‚townie spadÅ‚o. ProszÄ™ upewnić siÄ™,\n" +"że zasilanie jest wystarczajÄ…ce dla caÅ‚ego obwodu in nacisnąć reset (po " +"odmontowaniu CIRCUITPY).\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"The reset button was pressed while booting CircuitPython. Press again to " +"exit safe mode.\n" +msgstr "" +"Przycisk reset zostaÅ‚ wciÅ›niÄ™ty podczas startu CircuitPythona. WciÅ›nij go " +"ponownie aby wyjść z trybu bezpieczeÅ„stwa.\n" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "Wartość bits_per_sample nie pasuje do miksera" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's channel count does not match the mixer's" +msgstr "Liczba kanałów nie pasuje do miksera " + +#: shared-module/audiocore/Mixer.c +msgid "The sample's sample rate does not match the mixer's" +msgstr "Sample rate nie pasuje do miksera" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's signedness does not match the mixer's" +msgstr "Znak nie pasuje do miksera" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" +msgstr "Wysokość bitmapy musi być wielokrotnoÅ›ciÄ… wysokoÅ›ci kafelka" + +#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile value out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" +msgstr "Szerokość bitmapy musi być wielokrotnoÅ›ciÄ… szerokoÅ›ci kafelka" + +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "By wyjść, proszÄ™ zresetować pÅ‚ytkÄ™ bez " + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample." +msgstr "Zbyt wiele kanałów." + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "Too many display busses" +msgstr "Zbyt wiele magistrali" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Too many displays" +msgstr "Zbyt wiele wyÅ›wietlaczy" + +#: py/obj.c +msgid "Traceback (most recent call last):\n" +msgstr "Åšlad wyjÄ…tku (najnowsze wywoÅ‚anie na koÅ„cu):\n" + +#: shared-bindings/time/__init__.c +msgid "Tuple or struct_time argument required" +msgstr "Wymagana krotka lub struct_time" + +#: shared-module/usb_hid/Device.c +msgid "USB Busy" +msgstr "USB ZajÄ™te" + +#: shared-module/usb_hid/Device.c +msgid "USB Error" +msgstr "Błąd USB" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID integer value must be 0-0xffff" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "UUID inny, niż `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" +msgstr "UUID nie jest typu str, int lub bytes" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Unable to allocate buffers for signed conversion" +msgstr "Nie udaÅ‚a siÄ™ alokacja buforów do konwersji ze znakiem" + +#: shared-module/displayio/I2CDisplay.c +#, c-format +msgid "Unable to find I2C Display at %x" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Unable to find free GCLK" +msgstr "Brak wolnego GCLK" + +#: py/parse.c +msgid "Unable to init parser" +msgstr "Błąd ustawienia parsera" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" +msgstr "Nie można odczytać danych palety" + +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." +msgstr "Błąd zapisu do NVM." + +#: ports/nrf/common-hal/_bleio/UUID.c +msgid "Unexpected nrfx uuid type" +msgstr "Nieoczekiwany typ nrfx uuid." + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "ZÅ‚a liczba obiektów po prawej stronie (oczekiwano %d, jest %d)." + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "Unsupported baudrate" +msgstr "ZÅ‚a szybkość transmisji" + +#: shared-module/displayio/display_core.c +msgid "Unsupported display bus type" +msgstr "ZÅ‚y typ magistrali wyÅ›wietlaczy" + +#: shared-module/audiocore/WaveFile.c +msgid "Unsupported format" +msgstr "ZÅ‚y format" + +#: py/moduerrno.c +msgid "Unsupported operation" +msgstr "ZÅ‚a operacja" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Unsupported pull value." +msgstr "ZÅ‚a wartość podciÄ…gniÄ™cia." + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + +#: py/emitnative.c +msgid "Viper functions don't currently support more than 4 arguments" +msgstr "Funkcje Viper nie obsÅ‚ugujÄ… obecnie wiÄ™cej niż 4 argumentów" + +#: shared-module/audiocore/Mixer.c +msgid "Voice index too high" +msgstr "Zbyt wysoki indeks gÅ‚osu" + +#: main.c +msgid "WARNING: Your code filename has two extensions\n" +msgstr "UWAGA: Nazwa pliku ma dwa rozszerzenia\n" + +#: py/builtinhelp.c +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" +"Witamy w CircuitPythonie Adafruita %s!\n" +"PodrÄ™czniki dostÄ™pne na learn.adafruit.com/category/circuitpyhon.\n" +"Aby zobaczyć wbudowane moduÅ‚y, wpisz `help(\"modules\")`.\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"You are running in safe mode which means something unanticipated happened.\n" +msgstr "" +"Uruchomiono w trybie bezpieczeÅ„stwa, gdyż nastÄ…piÅ‚o coÅ› nieoczekiwanego.\n" + +#: supervisor/shared/safe_mode.c +msgid "You requested starting safe mode by " +msgstr "Zażądano trybu bezpieczeÅ„stwa przez " + +#: py/objtype.c +msgid "__init__() should return None" +msgstr "__init__() powinien zwracać None" + +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "__init__() powinien zwracać None, nie '%s'" + +#: py/objobject.c +msgid "__new__ arg must be a user-type" +msgstr "Argument __new__ musi być typu użytkownika" + +#: extmod/modubinascii.c extmod/moduhashlib.c +msgid "a bytes-like object is required" +msgstr "wymagany obiekt typu bytes" + +#: lib/embed/abort_.c +msgid "abort() called" +msgstr "WywoÅ‚ano abort()" + +#: extmod/machine_mem.c +#, c-format +msgid "address %08x is not aligned to %d bytes" +msgstr "adres %08x nie jest wyrównany do %d bajtów" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "address out of bounds" +msgstr "adres poza zakresem" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "addresses is empty" +msgstr "adres jest pusty" + +#: py/modbuiltins.c +msgid "arg is an empty sequence" +msgstr "arg jest puste" + +#: py/runtime.c +msgid "argument has wrong type" +msgstr "argument ma zÅ‚y typ" + +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +msgid "argument num/types mismatch" +msgstr "zÅ‚a liczba lub typ argumentów" + +#: py/runtime.c +msgid "argument should be a '%q' not a '%q'" +msgstr "argument powinien być '%q' a nie '%q'" + +#: py/objarray.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" +msgstr "tablica/bytes wymagane po prawej stronie" + +#: py/objstr.c +msgid "attributes not supported yet" +msgstr "atrybuty nie sÄ… jeszcze obsÅ‚ugiwane" + +#: py/builtinevex.c +msgid "bad compile mode" +msgstr "zÅ‚y tryb kompilacji" + +#: py/objstr.c +msgid "bad conversion specifier" +msgstr "zÅ‚y specyfikator konwersji" + +#: py/objstr.c +msgid "bad format string" +msgstr "zÅ‚a specyfikacja formatu" + +#: py/binary.c +msgid "bad typecode" +msgstr "zÅ‚y typecode" + +#: py/emitnative.c +msgid "binary op %q not implemented" +msgstr "brak dwu-argumentowego operatora %q" + +#: shared-bindings/busio/UART.c +msgid "bits must be 7, 8 or 9" +msgstr "bits musi być 7, 8 lub 9" + +#: extmod/machine_spi.c +msgid "bits must be 8" +msgstr "bits musi być 8" + +#: shared-bindings/audiocore/Mixer.c +msgid "bits_per_sample must be 8 or 16" +msgstr "bits_per_sample musi być 8 lub 16" + +#: py/emitinlinethumb.c +msgid "branch not in range" +msgstr "skok poza zakres" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "buf zbyt maÅ‚y. Wymagane %d bajtów" + +#: shared-bindings/audiocore/RawSample.c +msgid "buffer must be a bytes-like object" +msgstr "bufor mysi być typu bytes" + +#: shared-module/struct/__init__.c +msgid "buffer size must match format" +msgstr "wielkość bufora musi pasować do formatu" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" +msgstr "fragmenty bufora muszÄ… mieć tÄ™ samÄ… dÅ‚ugość" + +#: py/modstruct.c shared-bindings/struct/__init__.c +#: shared-module/struct/__init__.c +msgid "buffer too small" +msgstr "zbyt maÅ‚y bufor" + +#: extmod/machine_spi.c +msgid "buffers must be the same length" +msgstr "bufory muszÄ… mieć tÄ™ samÄ… dÅ‚ugość" + +#: shared-bindings/_pew/PewPew.c +msgid "buttons must be digitalio.DigitalInOut" +msgstr "buttons musi być digitalio.DigitalInOut" + +#: py/vm.c +msgid "byte code not implemented" +msgstr "bajtkod niezaimplemntowany" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "byteorder musi być typu ByteOrder (jest %s)" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "bytes > 8 bits not supported" +msgstr "bajty wiÄ™ksze od 8 bitów sÄ… niewspierane" + +#: py/objstr.c +msgid "bytes value out of range" +msgstr "wartość bytes poza zakresem" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" +msgstr "kalibracja poza zakresem" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" +msgstr "kalibracja tylko do odczytu" + +#: ports/atmel-samd/common-hal/rtc/RTC.c +msgid "calibration value out of range +/-127" +msgstr "wartość kalibracji poza zakresem +/-127" + +#: py/emitinlinethumb.c +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "asembler Thumb może przyjąć do 4 parameterów" + +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "asembler Xtensa może przyjąć do 4 parameterów" + +#: py/persistentcode.c +msgid "can only save bytecode" +msgstr "można zapisać tylko bytecode" + +#: py/objtype.c +msgid "can't add special method to already-subclassed class" +msgstr "nie można dodać specjalnej metody do podklasy" + +#: py/compile.c +msgid "can't assign to expression" +msgstr "przypisanie do wyrażenia" + +#: py/obj.c +#, c-format +msgid "can't convert %s to complex" +msgstr "nie można skonwertować %s do complex" + +#: py/obj.c +#, c-format +msgid "can't convert %s to float" +msgstr "nie można skonwertować %s do float" + +#: py/obj.c +#, c-format +msgid "can't convert %s to int" +msgstr "nie można skonwertować %s do int" + +#: py/objstr.c +msgid "can't convert '%q' object to %q implicitly" +msgstr "nie można automatycznie skonwertować '%q' do '%q'" + +#: py/objint.c +msgid "can't convert NaN to int" +msgstr "nie można skonwertować NaN do int" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "can't convert address to int" +msgstr "nie można skonwertować adresu do int" + +#: py/objint.c +msgid "can't convert inf to int" +msgstr "nie można skonwertować inf do int" + +#: py/obj.c +msgid "can't convert to complex" +msgstr "nie można skonwertować do complex" + +#: py/obj.c +msgid "can't convert to float" +msgstr "nie można skonwertować do float" + +#: py/obj.c +msgid "can't convert to int" +msgstr "nie można skonwertować do int" + +#: py/objstr.c +msgid "can't convert to str implicitly" +msgstr "nie można automatycznie skonwertować do str" + +#: py/compile.c +msgid "can't declare nonlocal in outer code" +msgstr "deklaracja nonlocal na poziomie moduÅ‚u" + +#: py/compile.c +msgid "can't delete expression" +msgstr "nie można usunąć wyrażenia" + +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" +msgstr "nie można użyć operatora pomiÄ™dzy '%q' a '%q'" + +#: py/objcomplex.c +msgid "can't do truncated division of a complex number" +msgstr "nie można wykonać dzielenia caÅ‚kowitego na liczbie zespolonej" + +#: py/compile.c +msgid "can't have multiple **x" +msgstr "nie można mieć wielu **x" + +#: py/compile.c +msgid "can't have multiple *x" +msgstr "nie można mieć wielu *x" + +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "nie można automatyczne skonwertować '%q' do 'bool'" + +#: py/emitnative.c +msgid "can't load from '%q'" +msgstr "nie można Å‚adować z '%q'" + +#: py/emitnative.c +msgid "can't load with '%q' index" +msgstr "nie można Å‚adować z indeksem '%q'" + +#: py/objgenerator.c +msgid "can't pend throw to just-started generator" +msgstr "nie można skoczyć do Å›wieżo stworzonego generatora" + +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" +msgstr "Å›wieżo stworzony generator może tylko przyjąć None" + +#: py/objnamedtuple.c +msgid "can't set attribute" +msgstr "nie można ustawić atrybutu" + +#: py/emitnative.c +msgid "can't store '%q'" +msgstr "nie można zapisać '%q'" + +#: py/emitnative.c +msgid "can't store to '%q'" +msgstr "nie można zpisać do '%q'" + +#: py/emitnative.c +msgid "can't store with '%q' index" +msgstr "nie można zapisać z indeksem '%q'" + +#: py/objstr.c +msgid "" +"can't switch from automatic field numbering to manual field specification" +msgstr "nie można zmienić z automatycznego numerowania pól do rÄ™cznego" + +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "nie można zmienić z rÄ™cznego numerowaniu pól do automatycznego" + +#: py/objtype.c +msgid "cannot create '%q' instances" +msgstr "nie można tworzyć instancji '%q'" + +#: py/objtype.c +msgid "cannot create instance" +msgstr "nie można stworzyć instancji" + +#: py/runtime.c +msgid "cannot import name %q" +msgstr "nie można zaimportować nazwy %q" + +#: py/builtinimport.c +msgid "cannot perform relative import" +msgstr "nie można wykonać relatywnego importu" + +#: py/emitnative.c +msgid "casting" +msgstr "rzutowanie" + +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" +msgstr "bufor chars zbyt maÅ‚y" + +#: py/modbuiltins.c +msgid "chr() arg not in range(0x110000)" +msgstr "argument chr() poza zakresem range(0x110000)" + +#: py/modbuiltins.c +msgid "chr() arg not in range(256)" +msgstr "argument chr() poza zakresem range(256)" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "bufor kolorów musi nieć 3 bajty (RGB) lub 4 bajty (RGB + wypeÅ‚nienie)" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer or int" +msgstr "bufor kolorów musi być typu buffer lub int" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "bufor kolorów musi być bytearray lub tablicÄ… typu 'b' lub 'B'" + +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" +msgstr "kolor musi być pomiÄ™dzy 0x000000 a 0xffffff" + +#: shared-bindings/displayio/ColorConverter.c +msgid "color should be an int" +msgstr "kolor powinien być liczbÄ… caÅ‚kowitÄ…" + +#: py/objcomplex.c +msgid "complex division by zero" +msgstr "zespolone dzielenie przez zero" + +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" +msgstr "wartoÅ›ci zespolone nieobsÅ‚ugiwane" + +#: extmod/moduzlib.c +msgid "compression header" +msgstr "nagłówek kompresji" + +#: py/parse.c +msgid "constant must be an integer" +msgstr "staÅ‚a musi być liczbÄ… caÅ‚kowitÄ…" + +#: py/emitnative.c +msgid "conversion to object" +msgstr "konwersja do obiektu" + +#: py/parsenum.c +msgid "decimal numbers not supported" +msgstr "liczby dziesiÄ™tne nieobsÅ‚ugiwane" + +#: py/compile.c +msgid "default 'except' must be last" +msgstr "domyÅ›lny 'except' musi być ostatni" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" +"bufor docelowy musi być bytearray lub tablicÄ… typu 'B' dla bit_depth = 8" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "bufor docelowy musi być tablicÄ… typu 'H' dla bit_depth = 16" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination_length must be an int >= 0" +msgstr "destination_length musi być nieujemnÄ… liczbÄ… caÅ‚kowitÄ…" + +#: py/objdict.c +msgid "dict update sequence has wrong length" +msgstr "sekwencja ma złą dÅ‚ugość" + +#: py/modmath.c py/objfloat.c py/objint_longlong.c py/objint_mpz.c py/runtime.c +#: shared-bindings/math/__init__.c +msgid "division by zero" +msgstr "dzielenie przez zero" + +#: py/objdeque.c +msgid "empty" +msgstr "puste" + +#: extmod/moduheapq.c extmod/modutimeq.c +msgid "empty heap" +msgstr "pusta sterta" + +#: py/objstr.c +msgid "empty separator" +msgstr "pusty separator" + +#: shared-bindings/random/__init__.c +msgid "empty sequence" +msgstr "pusta sekwencja" + +#: py/objstr.c +msgid "end of format while looking for conversion specifier" +msgstr "koniec formatu przy szukaniu specyfikacji konwersji" + +#: shared-bindings/displayio/Shape.c +msgid "end_x should be an int" +msgstr "end_x powinien być caÅ‚kowity" + +#: ports/nrf/common-hal/busio/UART.c +#, c-format +msgid "error = 0x%08lX" +msgstr "błąd = 0x%08lX" + +#: py/runtime.c +msgid "exceptions must derive from BaseException" +msgstr "wyjÄ…tki muszÄ… dziedziczyć po BaseException" + +#: py/objstr.c +msgid "expected ':' after format specifier" +msgstr "oczekiwano ':' po specyfikacji formatu" + +#: py/obj.c +msgid "expected tuple/list" +msgstr "oczekiwano krotki/listy" + +#: py/modthread.c +msgid "expecting a dict for keyword args" +msgstr "oczekiwano dict dla argumentów nazwanych" + +#: py/compile.c +msgid "expecting an assembler instruction" +msgstr "oczekiwano instrukcji asemblera" + +#: py/compile.c +msgid "expecting just a value for set" +msgstr "oczekiwano tylko wartoÅ›ci dla zbioru" + +#: py/compile.c +msgid "expecting key:value for dict" +msgstr "oczekiwano klucz:wartość dla sÅ‚ownika" + +#: py/argcheck.c +msgid "extra keyword arguments given" +msgstr "nadmiarowe argumenty nazwane" + +#: py/argcheck.c +msgid "extra positional arguments given" +msgstr "nadmiarowe argumenty pozycyjne" + +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c +msgid "file must be a file opened in byte mode" +msgstr "file musi być otwarte w trybie bajtowym" + +#: shared-bindings/storage/__init__.c +msgid "filesystem must provide mount method" +msgstr "system plików musi mieć metodÄ™ mount" + +#: py/objtype.c +msgid "first argument to super() must be type" +msgstr "pierwszy argument super() musi być typem" + +#: extmod/machine_spi.c +msgid "firstbit must be MSB" +msgstr "firstbit musi być MSB" + +#: py/objint.c +msgid "float too big" +msgstr "float zbyt wielki" + +#: shared-bindings/_stage/Text.c +msgid "font must be 2048 bytes long" +msgstr "font musi mieć 2048 bajtów dÅ‚ugoÅ›ci" + +#: py/objstr.c +msgid "format requires a dict" +msgstr "format wymaga sÅ‚ownika" + +#: py/objdeque.c +msgid "full" +msgstr "peÅ‚ny" + +#: py/argcheck.c +msgid "function does not take keyword arguments" +msgstr "funkcja nie bierze argumentów nazwanych" + +#: py/argcheck.c +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "funkcja bierze najwyżej %d argumentów, jest %d" + +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" +msgstr "funkcja dostaÅ‚a wiele wartoÅ›ci dla argumentu '%q'" + +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" +msgstr "brak %d wymaganych argumentów pozycyjnych funkcji" + +#: py/bc.c +msgid "function missing keyword-only argument" +msgstr "brak argumentu nazwanego funkcji" + +#: py/bc.c +msgid "function missing required keyword argument '%q'" +msgstr "brak wymaganego argumentu nazwanego '%q' funkcji" + +#: py/bc.c +#, c-format +msgid "function missing required positional argument #%d" +msgstr "brak wymaganego argumentu pozycyjnego #%d funkcji" + +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "funkcja wymaga %d argumentów pozycyjnych, ale jest %d" + +#: shared-bindings/time/__init__.c +msgid "function takes exactly 9 arguments" +msgstr "funkcja wymaga dokÅ‚adnie 9 argumentów" + +#: py/objgenerator.c +msgid "generator already executing" +msgstr "generator już siÄ™ wykonuje" + +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" +msgstr "generator zignorowaÅ‚ GeneratorExit" + +#: shared-bindings/_stage/Layer.c +msgid "graphic must be 2048 bytes long" +msgstr "graphic musi mieć 2048 bajtów dÅ‚ugoÅ›ci" + +#: extmod/moduheapq.c +msgid "heap must be a list" +msgstr "heap musi być listÄ…" + +#: py/compile.c +msgid "identifier redefined as global" +msgstr "nazwa przedefiniowana jako globalna" + +#: py/compile.c +msgid "identifier redefined as nonlocal" +msgstr "nazwa przedefiniowana jako nielokalna" + +#: py/objstr.c +msgid "incomplete format" +msgstr "niepeÅ‚ny format" + +#: py/objstr.c +msgid "incomplete format key" +msgstr "niepeÅ‚ny klucz formatu" + +#: extmod/modubinascii.c +msgid "incorrect padding" +msgstr "zÅ‚e wypeÅ‚nienie" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c py/obj.c +msgid "index out of range" +msgstr "indeks poza zakresem" + +#: py/obj.c +msgid "indices must be integers" +msgstr "indeksy muszÄ… być caÅ‚kowite" + +#: py/compile.c +msgid "inline assembler must be a function" +msgstr "wtrÄ…cony asembler musi być funkcjÄ…" + +#: py/parsenum.c +msgid "int() arg 2 must be >= 2 and <= 36" +msgstr "argument 2 do int() busi być pomiÄ™dzy 2 a 36" + +#: py/objstr.c +msgid "integer required" +msgstr "wymagana liczba caÅ‚kowita" + +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c +#, c-format +msgid "interval must be in range %s-%s" +msgstr "" + +#: extmod/machine_i2c.c +msgid "invalid I2C peripheral" +msgstr "zÅ‚e I2C" + +#: extmod/machine_spi.c +msgid "invalid SPI peripheral" +msgstr "zÅ‚e SPI" + +#: lib/netutils/netutils.c +msgid "invalid arguments" +msgstr "zÅ‚e arguemnty" + +#: extmod/modussl_axtls.c +msgid "invalid cert" +msgstr "zÅ‚y ceryfikat" + +#: extmod/uos_dupterm.c +msgid "invalid dupterm index" +msgstr "zÅ‚y indeks dupterm" + +#: extmod/modframebuf.c +msgid "invalid format" +msgstr "zÅ‚y format" + +#: py/objstr.c +msgid "invalid format specifier" +msgstr "zÅ‚a specyfikacja formatu" + +#: extmod/modussl_axtls.c +msgid "invalid key" +msgstr "zÅ‚y klucz" + +#: py/compile.c +msgid "invalid micropython decorator" +msgstr "zÅ‚y dekorator micropythona" + +#: shared-bindings/random/__init__.c +msgid "invalid step" +msgstr "zÅ‚y krok" + +#: py/compile.c py/parse.c +msgid "invalid syntax" +msgstr "zÅ‚a skÅ‚adnia" + +#: py/parsenum.c +msgid "invalid syntax for integer" +msgstr "zÅ‚a skÅ‚adnia dla liczby caÅ‚kowitej" + +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "zÅ‚a skÅ‚adnia dla liczby caÅ‚kowitej w bazie %d" + +#: py/parsenum.c +msgid "invalid syntax for number" +msgstr "zÅ‚a skÅ‚adnia dla liczby" + +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" +msgstr "argument 1 dla issubclass() musi być klasÄ…" + +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "argument 2 dla issubclass() musi być klasÄ… lub krotkÄ… klas" + +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "join oczekuje listy str/bytes zgodnych z self" + +#: py/argcheck.c +msgid "keyword argument(s) not yet implemented - use normal args instead" +msgstr "argumenty nazwane nieobsÅ‚ugiwane - proszÄ™ użyć zwykÅ‚ych argumentów" + +#: py/bc.c +msgid "keywords must be strings" +msgstr "sÅ‚owa kluczowe muszÄ… być Å‚aÅ„cuchami" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" +msgstr "etykieta '%q' niezdefiniowana" + +#: py/compile.c +msgid "label redefined" +msgstr "etykieta przedefiniowana" + +#: py/stream.c +msgid "length argument not allowed for this type" +msgstr "ten typ nie pozawala na podanie dÅ‚ugoÅ›ci" + +#: py/objarray.c +msgid "lhs and rhs should be compatible" +msgstr "lewa i prawa strona powinny być kompatybilne" + +#: py/emitnative.c +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "local '%q' jest typu '%q' lecz źródÅ‚o jest '%q'" + +#: py/emitnative.c +msgid "local '%q' used before type known" +msgstr "local '%q' użyty zanim typ jest znany" + +#: py/vm.c +msgid "local variable referenced before assignment" +msgstr "zmienna lokalna użyta przed przypisaniem" + +#: py/objint.c +msgid "long int not supported in this build" +msgstr "long int jest nieobsÅ‚ugiwany" + +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" +msgstr "bufor mapy zbyt maÅ‚y" + +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" +msgstr "błąd domeny" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + +#: py/runtime.c +msgid "maximum recursion depth exceeded" +msgstr "przekroczono dozwolonÄ… głębokość rekurencji" + +#: py/runtime.c +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "alokacja pamiÄ™ci nie powiodÅ‚a siÄ™, alokowano %u bajtów" + +#: py/runtime.c +msgid "memory allocation failed, heap is locked" +msgstr "alokacja pamiÄ™ci nie powiodÅ‚a siÄ™, sterta zablokowana" + +#: py/builtinimport.c +msgid "module not found" +msgstr "brak moduÅ‚u" + +#: py/compile.c +msgid "multiple *x in assignment" +msgstr "wiele *x w przypisaniu" + +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" +msgstr "konflikt w planie instancji z powodu wielu baz" + +#: py/objtype.c +msgid "multiple inheritance not supported" +msgstr "wielokrotne dziedzicznie niewspierane" + +#: py/emitnative.c +msgid "must raise an object" +msgstr "wyjÄ…tek musi być obiektem" + +#: extmod/machine_spi.c +msgid "must specify all of sck/mosi/miso" +msgstr "sck/mosi/miso muszÄ… być podane" + +#: py/modbuiltins.c +msgid "must use keyword argument for key function" +msgstr "funkcja key musi być podana jako argument nazwany" + +#: py/runtime.c +msgid "name '%q' is not defined" +msgstr "nazwa '%q' niezdefiniowana" + +#: shared-bindings/_bleio/Peripheral.c +msgid "name must be a string" +msgstr "nazwa musi być Å‚aÅ„cuchem" + +#: py/runtime.c +msgid "name not defined" +msgstr "nazwa niezdefiniowana" + +#: py/compile.c +msgid "name reused for argument" +msgstr "nazwa użyta ponownie jako argument" + +#: py/emitnative.c +msgid "native yield" +msgstr "natywny yield" + +#: py/runtime.c +#, c-format +msgid "need more than %d values to unpack" +msgstr "potrzeba wiÄ™cej niż %d do rozpakowania" + +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" +msgstr "ujemna potÄ™ga, ale brak obsÅ‚ugi liczb zmiennoprzecinkowych" + +#: py/objint_mpz.c py/runtime.c +msgid "negative shift count" +msgstr "ujemne przesuniÄ™cie" + +#: py/vm.c +msgid "no active exception to reraise" +msgstr "brak wyjÄ…tku do ponownego rzucenia" + +#: shared-bindings/socket/__init__.c shared-module/network/__init__.c +msgid "no available NIC" +msgstr "brak wolnego NIC" + +#: py/compile.c +msgid "no binding for nonlocal found" +msgstr "brak wiÄ…zania dla zmiennej nielokalnej" + +#: py/builtinimport.c +msgid "no module named '%q'" +msgstr "brak moduÅ‚u o nazwie '%q'" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "no reset pin available" +msgstr "" + +#: py/runtime.c shared-bindings/_pixelbuf/__init__.c +msgid "no such attribute" +msgstr "nie ma takiego atrybutu" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" +msgstr "" + +#: py/compile.c +msgid "non-default argument follows default argument" +msgstr "argument z wartoÅ›ciÄ… domyÅ›lnÄ… przed argumentem bez" + +#: extmod/modubinascii.c +msgid "non-hex digit found" +msgstr "cyfra nieszesnastkowa" + +#: py/compile.c +msgid "non-keyword arg after */**" +msgstr "argument nienazwany po */**" + +#: py/compile.c +msgid "non-keyword arg after keyword arg" +msgstr "argument nienazwany po nazwanym" + +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" +msgstr "to nie jest 128-bitowy UUID" + +#: py/objstr.c +msgid "not all arguments converted during string formatting" +msgstr "nie wszystkie argumenty wykorzystane w formatowaniu" + +#: py/objstr.c +msgid "not enough arguments for format string" +msgstr "nie dość argumentów przy formatowaniu" + +#: py/obj.c +#, c-format +msgid "object '%s' is not a tuple or list" +msgstr "obiekt '%s' nie jest krotkÄ… ani listÄ…" + +#: py/obj.c +msgid "object does not support item assignment" +msgstr "obiekt nie obsÅ‚uguje przypisania do elementów" + +#: py/obj.c +msgid "object does not support item deletion" +msgstr "obiekt nie obsÅ‚uguje usuwania elementów" + +#: py/obj.c +msgid "object has no len" +msgstr "obiekt nie ma len" + +#: py/obj.c +msgid "object is not subscriptable" +msgstr "obiekt nie ma elementów" + +#: py/runtime.c +msgid "object not an iterator" +msgstr "obiekt nie jest iteratorem" + +#: py/objtype.c py/runtime.c +msgid "object not callable" +msgstr "obiekt nie jest wywoÅ‚ywalny" + +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" +msgstr "obiektu nie ma sekwencji" + +#: py/runtime.c +msgid "object not iterable" +msgstr "obiekt nie jest iterowalny" + +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" +msgstr "obiekt typu '%s' nie ma len()" + +#: py/obj.c +msgid "object with buffer protocol required" +msgstr "wymagany obiekt z protokoÅ‚em buforu" + +#: extmod/modubinascii.c +msgid "odd-length string" +msgstr "Å‚aÅ„cuch o nieparzystej dÅ‚ugoÅ›ci" + +#: py/objstr.c py/objstrunicode.c +msgid "offset out of bounds" +msgstr "offset poza zakresem" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" +msgstr "tylko fragmenty ze step=1 (lub None) sÄ… wspierane" + +#: py/modbuiltins.c +msgid "ord expects a character" +msgstr "ord oczekuje znaku" + +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "ord() oczekuje znaku, a jest Å‚aÅ„cuch od dÅ‚ugoÅ›ci %d" + +#: py/objint_mpz.c +msgid "overflow converting long int to machine word" +msgstr "przepeÅ‚nienie przy konwersji long in to sÅ‚owa maszynowego" + +#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c +msgid "palette must be 32 bytes long" +msgstr "paleta musi mieć 32 bajty dÅ‚ugoÅ›ci" + +#: shared-bindings/displayio/Palette.c +msgid "palette_index should be an int" +msgstr "palette_index powinien być caÅ‚kowity" + +#: py/compile.c +msgid "parameter annotation must be an identifier" +msgstr "anotacja parametru musi być identyfikatorem" + +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" +msgstr "parametry muszÄ… być rejestrami w kolejnoÅ›ci a2 do a5" + +#: py/emitinlinethumb.c +msgid "parameters must be registers in sequence r0 to r3" +msgstr "parametry muszÄ… być rejestrami w kolejnoÅ›ci r0 do r3" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel coordinates out of bounds" +msgstr "współrzÄ™dne piksela poza zakresem" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel value requires too many bits" +msgstr "wartość piksela wymaga zbyt wielu bitów" + +#: shared-bindings/displayio/TileGrid.c +msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" +msgstr "" +"pixel_shader musi być typu displayio.Palette lub dispalyio.ColorConverter" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" +msgstr "pop z pustego PulseIn" + +#: py/objset.c +msgid "pop from an empty set" +msgstr "pop z pustego zbioru" + +#: py/objlist.c +msgid "pop from empty list" +msgstr "pop z pustej listy" + +#: py/objdict.c +msgid "popitem(): dictionary is empty" +msgstr "popitem(): sÅ‚ownik jest pusty" + +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" +msgstr "trzeci argument pow() nie może być 0" + +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" +msgstr "trzyargumentowe pow() wymaga liczb caÅ‚kowitych" + +#: extmod/modutimeq.c +msgid "queue overflow" +msgstr "przepeÅ‚nienie kolejki" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "rawbuf is not the same size as buf" +msgstr "rawbuf nie jest tej samej wielkoÅ›ci co buf" + +#: shared-bindings/_pixelbuf/__init__.c +msgid "readonly attribute" +msgstr "atrybut tylko do odczytu" + +#: py/builtinimport.c +msgid "relative import" +msgstr "relatywny import" + +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" +msgstr "zażądano dÅ‚ugoÅ›ci %d ale obiekt ma dÅ‚ugość %d" + +#: py/compile.c +msgid "return annotation must be an identifier" +msgstr "anotacja wartoÅ›ci musi być identyfikatorem" + +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" +msgstr "return oczekiwaÅ‚ '%q', a jest '%q'" + +#: py/objstr.c +msgid "rsplit(None,n)" +msgstr "rsplit(None,n)" + +#: shared-bindings/audiocore/RawSample.c +msgid "" +"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " +"'B'" +msgstr "" +"bufor sample_source musi być bytearray lub tablicÄ… typu 'h', 'H', 'b' lub 'B'" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" +msgstr "czÄ™stotliwość próbkowania poza zakresem" + +#: py/modmicropython.c +msgid "schedule stack full" +msgstr "stos planu peÅ‚en" + +#: lib/utils/pyexec.c py/builtinimport.c +msgid "script compilation not supported" +msgstr "kompilowanie skryptów nieobsÅ‚ugiwane" + +#: py/objstr.c +msgid "sign not allowed in string format specifier" +msgstr "znak jest niedopuszczalny w specyfikacji formatu Å‚aÅ„cucha" + +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" +msgstr "znak jest niedopuszczalny w specyfikacji 'c'" + +#: py/objstr.c +msgid "single '}' encountered in format string" +msgstr "pojedynczy '}' w specyfikacji formatu" + +#: shared-bindings/time/__init__.c +msgid "sleep length must be non-negative" +msgstr "okres snu musi być nieujemny" + +#: py/objslice.c py/sequence.c +msgid "slice step cannot be zero" +msgstr "zerowy krok" + +#: py/objint.c py/sequence.c +msgid "small int overflow" +msgstr "przepeÅ‚nienie small int" + +#: main.c +msgid "soft reboot\n" +msgstr "programowy reset\n" + +#: py/objstr.c +msgid "start/end indices" +msgstr "poczÄ…tkowe/koÅ„cowe indeksy" + +#: shared-bindings/displayio/Shape.c +msgid "start_x should be an int" +msgstr "start_x powinien być caÅ‚kowity" + +#: shared-bindings/random/__init__.c +msgid "step must be non-zero" +msgstr "step nie może być zerowe" + +#: shared-bindings/busio/UART.c +msgid "stop must be 1 or 2" +msgstr "stop musi być 1 lub 2" + +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" +msgstr "stop nie jest osiÄ…galne ze start" + +#: py/stream.c +msgid "stream operation not supported" +msgstr "operacja na strumieniu nieobsÅ‚ugiwana" + +#: py/objstrunicode.c +msgid "string index out of range" +msgstr "indeks Å‚aÅ„cucha poza zakresem" + +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" +msgstr "indeksy Å‚aÅ„cucha muszÄ… być caÅ‚kowite, nie %s" + +#: py/stream.c +msgid "string not supported; use bytes or bytearray" +msgstr "Å‚aÅ„cuchy nieobsÅ‚ugiwane; użyj bytes lub bytearray" + +#: extmod/moductypes.c +msgid "struct: cannot index" +msgstr "struct: nie można indeksować" + +#: extmod/moductypes.c +msgid "struct: index out of range" +msgstr "struct: indeks poza zakresem" + +#: extmod/moductypes.c +msgid "struct: no fields" +msgstr "struct: brak pól" + +#: py/objstr.c +msgid "substring not found" +msgstr "brak pod-Å‚aÅ„cucha" + +#: py/compile.c +msgid "super() can't find self" +msgstr "super() nie może znaleźć self" + +#: extmod/modujson.c +msgid "syntax error in JSON" +msgstr "błąd skÅ‚adni w JSON" + +#: extmod/moductypes.c +msgid "syntax error in uctypes descriptor" +msgstr "błąd skÅ‚adni w deskryptorze uctypes" + +#: shared-bindings/touchio/TouchIn.c +msgid "threshold must be in the range 0-65536" +msgstr "threshold musi być w zakresie 0-65536" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes a 9-sequence" +msgstr "time.struct_time() wymaga 9-elementowej sekwencji" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes exactly 1 argument" +msgstr "time.struct_time() wymaga jednego argumentu" + +#: shared-bindings/busio/UART.c +msgid "timeout >100 (units are now seconds, not msecs)" +msgstr "timeout > 100 (jednostkami sÄ… sekundy)" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "timeout must be >= 0.0" +msgstr "timeout musi być >= 0.0" + +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" +msgstr "timestamp poza zakresem dla time_t na tej platformie" + +#: shared-module/struct/__init__.c +msgid "too many arguments provided with the given format" +msgstr "zbyt wiele argumentów podanych dla tego formatu" + +#: py/runtime.c +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "zbyt wiele wartoÅ›ci do rozpakowania (oczekiwano %d)" + +#: py/objstr.c +msgid "tuple index out of range" +msgstr "indeks krotki poza zakresem" + +#: py/obj.c +msgid "tuple/list has wrong length" +msgstr "krotka/lista ma złą dÅ‚ugość" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "tuple/list required on RHS" +msgstr "wymagana krotka/lista po prawej stronie" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "tx and rx cannot both be None" +msgstr "tx i rx nie mogÄ… być oba None" + +#: py/objtype.c +msgid "type '%q' is not an acceptable base type" +msgstr "typ '%q' nie może być bazowy" + +#: py/objtype.c +msgid "type is not an acceptable base type" +msgstr "typ nie może być bazowy" + +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" +msgstr "typ '%q' nie ma atrybutu '%q'" + +#: py/objtype.c +msgid "type takes 1 or 3 arguments" +msgstr "type wymaga 1 lub 3 argumentów" + +#: py/objint_longlong.c +msgid "ulonglong too large" +msgstr "ulonglong zbyt wielkie" + +#: py/emitnative.c +msgid "unary op %q not implemented" +msgstr "operator unarny %q niezaimplementowany" + +#: py/parse.c +msgid "unexpected indent" +msgstr "zÅ‚e wciÄ™cie" + +#: py/bc.c +msgid "unexpected keyword argument" +msgstr "zÅ‚y argument nazwany" + +#: py/bc.c py/objnamedtuple.c +msgid "unexpected keyword argument '%q'" +msgstr "zÅ‚y argument nazwany '%q'" + +#: py/lexer.c +msgid "unicode name escapes" +msgstr "nazwy unicode" + +#: py/parse.c +msgid "unindent does not match any outer indentation level" +msgstr "wciÄ™cie nie pasuje do żadnego wczeÅ›niejszego wciÄ™cia" + +#: py/objstr.c +#, c-format +msgid "unknown conversion specifier %c" +msgstr "zÅ‚a specyfikacja konwersji %c" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type '%s'" +msgstr "zÅ‚y kod formatowania '%c' dla obiektu typu '%s'" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'float'" +msgstr "zÅ‚y kod foratowania '%c' dla obiektu typu 'float'" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'str'" +msgstr "zÅ‚y kod formatowania '%c' dla obiektu typu 'str'" + +#: py/compile.c +msgid "unknown type" +msgstr "zÅ‚y typ" + +#: py/emitnative.c +msgid "unknown type '%q'" +msgstr "zÅ‚y typ '%q'" + +#: py/objstr.c +msgid "unmatched '{' in format" +msgstr "niepasujÄ…ce '{' for formacie" + +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" +msgstr "nieczytelny atrybut" + +#: shared-bindings/displayio/TileGrid.c +msgid "unsupported %q type" +msgstr "zÅ‚y typ %q" + +#: py/emitinlinethumb.c +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "zÅ‚a instrukcja Thumb '%s' z %d argumentami" + +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "zÅ‚a instrukcja Xtensa '%s' z %d argumentami" + +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "zÅ‚y znak formatowania '%c' (0x%x) na pozycji %d" + +#: py/runtime.c +msgid "unsupported type for %q: '%s'" +msgstr "zÅ‚y typ dla %q: '%s'" + +#: py/runtime.c +msgid "unsupported type for operator" +msgstr "zÅ‚y typ dla operatora" + +#: py/runtime.c +msgid "unsupported types for %q: '%s', '%s'" +msgstr "zÅ‚e typy dla %q: '%s', '%s'" + +#: py/objint.c +#, c-format +msgid "value must fit in %d byte(s)" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "value_count must be > 0" +msgstr "value_count musi być > 0" + +#: shared-bindings/_bleio/Scanner.c +msgid "window must be <= interval" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "write_args must be a list, tuple, or None" +msgstr "write_args musi być listÄ…, krotkÄ… lub None" + +#: py/objstr.c +msgid "wrong number of arguments" +msgstr "zÅ‚a liczba argumentów" + +#: py/runtime.c +msgid "wrong number of values to unpack" +msgstr "zÅ‚a liczba wartoÅ›ci do rozpakowania" + +#: shared-module/displayio/Shape.c +msgid "x value out of bounds" +msgstr "x poza zakresem" + +#: shared-bindings/displayio/Shape.c +msgid "y should be an int" +msgstr "y powinno być caÅ‚kowite" + +#: shared-module/displayio/Shape.c +msgid "y value out of bounds" +msgstr "y poza zakresem" + +#: py/objrange.c +msgid "zero step" +msgstr "zerowy krok" + +#~ msgid "Address is not %d bytes long or is in wrong format" +#~ msgstr "Adres nie ma dÅ‚ugoÅ›ci %d bajtów lub zÅ‚y format" + +#~ msgid "Can't add services in Central mode" +#~ msgstr "Nie można dodać serwisów w trybie Central" + +#~ msgid "Can't advertise in Central mode" +#~ msgstr "Nie można rozgÅ‚aszać w trybie Central" + +#~ msgid "Can't change the name in Central mode" +#~ msgstr "Nie można zmienić nazwy w trybie Central" + +#~ msgid "Can't connect in Peripheral mode" +#~ msgstr "Nie można siÄ™ łączyć w trybie Peripheral" + +#~ msgid "Characteristic UUID doesn't match Service UUID" +#~ msgstr "UUID charakterystyki inny niż UUID serwisu" + +#~ msgid "Characteristic already in use by another Service." +#~ msgstr "Charakterystyka w użyciu w innym serwisie" + +#~ msgid "Data too large for the advertisement packet" +#~ msgstr "Zbyt dużo danych pakietu rozgÅ‚oszeniowego" + +#~ msgid "Failed to acquire mutex" +#~ msgstr "Nie udaÅ‚o siÄ™ uzyskać blokady" + +#~ msgid "Failed to add service" +#~ msgstr "Nie udaÅ‚o siÄ™ dodać serwisu" + +#~ msgid "Failed to connect:" +#~ msgstr "Nie udaÅ‚o siÄ™ połączenie:" + +#~ msgid "Failed to continue scanning" +#~ msgstr "Nie udaÅ‚a siÄ™ kontynuacja skanowania" + +#~ msgid "Failed to create mutex" +#~ msgstr "Nie udaÅ‚o siÄ™ stworzyć blokady" + +#~ msgid "Failed to release mutex" +#~ msgstr "Nie udaÅ‚o siÄ™ zwolnić blokady" + +#~ msgid "Failed to start advertising" +#~ msgstr "Nie udaÅ‚o siÄ™ rozpocząć rozgÅ‚aszania" + +#~ msgid "Failed to start scanning" +#~ msgstr "Nie udaÅ‚o siÄ™ rozpocząć skanowania" + +#~ msgid "Failed to stop advertising" +#~ msgstr "Nie udaÅ‚o siÄ™ zatrzymać rozgÅ‚aszania" + +#~ msgid "Invalid bit clock pin" +#~ msgstr "ZÅ‚a nóżka zegara" + +#~ msgid "Invalid clock pin" +#~ msgstr "ZÅ‚a nóżka zegara" + +#~ msgid "Invalid data pin" +#~ msgstr "ZÅ‚a nóżka danych" + +#~ msgid "Must be a Group subclass." +#~ msgstr "Musi dziedziczyć z Group." + +#~ msgid "" +#~ "Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d " +#~ "bpp given" +#~ msgstr "Wspierane sÄ… tylko pliki BMP czarno-biaÅ‚e, 8bpp i 16bpp: %d bpp " + +#~ msgid "Tile indices must be 0 - 255" +#~ msgstr "Indeks kafelka musi być pomiÄ™dzy 0 a 255 włącznie" + +#~ msgid "UUID integer value not in range 0 to 0xffff" +#~ msgstr "Wartość UUID poza zakresem 0 do 0xffff" + +#~ msgid "bad GATT role" +#~ msgstr "zÅ‚a rola GATT" + +#~ msgid "characteristics includes an object that is not a Characteristic" +#~ msgstr "" +#~ "charakterystyki zawierajÄ… obiekt, który nie jest typu Characteristic" + +#~ msgid "interval not in range 0.0020 to 10.24" +#~ msgstr "przedziaÅ‚ poza zakresem 0.0020 do 10.24" + +#~ msgid "services includes an object that is not a Service" +#~ msgstr "obiekt typu innego niż Service w services" + +#~ msgid "tile index out of bounds" +#~ msgstr "indeks kafelka poza zakresem" diff --git a/locale/pt_BR.po b/locale/pt_BR.po new file mode 100644 index 00000000000..a697947d990 --- /dev/null +++ b/locale/pt_BR.po @@ -0,0 +1,2938 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"PO-Revision-Date: 2018-10-02 21:14-0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: main.c +msgid "" +"\n" +"Code done running. Waiting for reload.\n" +msgstr "" + +#: py/obj.c +msgid " File \"%q\"" +msgstr " Arquivo \"%q\"" + +#: py/obj.c +msgid " File \"%q\", line %d" +msgstr " Arquivo \"%q\", linha %d" + +#: main.c +msgid " output:\n" +msgstr " saída:\n" + +#: py/objstr.c +#, c-format +msgid "%%c requires int or char" +msgstr "%%c requer int ou char" + +#: shared-bindings/microcontroller/Pin.c +msgid "%q in use" +msgstr "%q em uso" + +#: py/obj.c +msgid "%q index out of range" +msgstr "" + +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c +#, fuzzy +msgid "%q must be >= 1" +msgstr "buffers devem ser o mesmo tamanho" + +#: shared-bindings/fontio/BuiltinFont.c +#, fuzzy +msgid "%q should be an int" +msgstr "y deve ser um int" + +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" +msgstr "" + +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "'%q' argumento(s) requerido(s)" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" +msgstr "" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects a special register" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an FPU register" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects at most r%d" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "" + +#: py/emitinlinextensa.c +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item assignment" +msgstr "" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item deletion" +msgstr "" + +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not an iterator" +msgstr "" + +#: py/objtype.c py/runtime.c +#, c-format +msgid "'%s' object is not callable" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not iterable" +msgstr "" + +#: py/obj.c +#, c-format +msgid "'%s' object is not subscriptable" +msgstr "" + +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" +msgstr "" + +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" +msgstr "'S' e 'O' não são tipos de formato suportados" + +#: py/compile.c +msgid "'align' requires 1 argument" +msgstr "" + +#: py/compile.c +msgid "'await' outside function" +msgstr "" + +#: py/compile.c +msgid "'break' outside loop" +msgstr "" + +#: py/compile.c +msgid "'continue' outside loop" +msgstr "" + +#: py/compile.c +msgid "'data' requires at least 2 arguments" +msgstr "" + +#: py/compile.c +msgid "'data' requires integer arguments" +msgstr "" + +#: py/compile.c +msgid "'label' requires 1 argument" +msgstr "" + +#: py/compile.c +msgid "'return' outside function" +msgstr "" + +#: py/compile.c +msgid "'yield' outside function" +msgstr "" + +#: py/compile.c +msgid "*x must be assignment target" +msgstr "" + +#: py/obj.c +msgid ", in %q\n" +msgstr "" + +#: py/objcomplex.c +msgid "0.0 to a complex power" +msgstr "" + +#: py/modbuiltins.c +msgid "3-arg pow() not supported" +msgstr "" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "A hardware interrupt channel is already in use" +msgstr "Um canal de interrupção de hardware já está em uso" + +#: shared-bindings/_bleio/Address.c +#, fuzzy, c-format +msgid "Address must be %d bytes long" +msgstr "buffers devem ser o mesmo tamanho" + +#: shared-bindings/_bleio/Address.c +msgid "Address type out of range" +msgstr "" + +#: ports/nrf/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" +msgstr "Todos os periféricos I2C estão em uso" + +#: ports/nrf/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" +msgstr "Todos os periféricos SPI estão em uso" + +#: ports/nrf/common-hal/busio/UART.c +#, fuzzy +msgid "All UART peripherals are in use" +msgstr "Todos os periféricos I2C estão em uso" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "Todos os canais de eventos em uso" + +#: ports/atmel-samd/audio_dma.c ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "All sync event channels in use" +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c +msgid "All timers for this pin are in use" +msgstr "Todos os temporizadores para este pino estão em uso" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: shared-module/_pew/PewPew.c +msgid "All timers in use" +msgstr "Todos os temporizadores em uso" + +#: ports/nrf/common-hal/analogio/AnalogOut.c +msgid "AnalogOut functionality not supported" +msgstr "Funcionalidade AnalogOut não suportada" + +#: shared-bindings/analogio/AnalogOut.c +msgid "AnalogOut is only 16 bits. Value must be less than 65536." +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "AnalogOut not supported on given pin" +msgstr "Saída analógica não suportada no pino fornecido" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" +msgstr "Outro envio já está ativo" + +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" +msgstr "Array deve conter meias palavras (tipo 'H')" + +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "Attempted heap allocation when MicroPython VM not running.\n" +msgstr "" + +#: main.c +msgid "Auto-reload is off.\n" +msgstr "A atualização automática está desligada.\n" + +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "" + +#: shared-module/displayio/Display.c +msgid "Below minimum frame rate" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Bit clock and word select must share a clock unit" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Bit depth must be multiple of 8." +msgstr "" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "Both pins must support hardware interrupts" +msgstr "Ambos os pinos devem suportar interrupções de hardware" + +#: shared-bindings/displayio/Display.c +msgid "Brightness must be 0-1.0" +msgstr "" + +#: shared-bindings/supervisor/__init__.c +msgid "Brightness must be between 0 and 255" +msgstr "O brilho deve estar entre 0 e 255" + +#: shared-bindings/displayio/Display.c +msgid "Brightness not adjustable" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "Buffer de tamanho incorreto. Deve ser %d bytes." + +#: shared-bindings/displayio/Display.c +msgid "Buffer is not a bytearray." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Buffer is too small" +msgstr "" + +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Buffer length %d too big. It must be less than %d" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c +msgid "Buffer must be at least length 1" +msgstr "" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +#, fuzzy, c-format +msgid "Bus pin %d is already in use" +msgstr "DAC em uso" + +#: shared-bindings/_bleio/UUID.c +#, fuzzy +msgid "Byte buffer must be 16 bytes." +msgstr "buffers devem ser o mesmo tamanho" + +#: shared-bindings/nvm/ByteArray.c +msgid "Bytes must be between 0 and 255." +msgstr "Os bytes devem estar entre 0 e 255." + +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Can not use dotstar with %s" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" +msgstr "Não é possível excluir valores" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/nrf/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "" + +#: ports/nrf/common-hal/microcontroller/Processor.c +#, fuzzy +msgid "Cannot get temperature" +msgstr "Não pode obter a temperatura. status: 0x%02x" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Cannot output both channels on the same pin" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot read without MISO pin." +msgstr "Não é possível ler sem o pino MISO." + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Cannot record to a file" +msgstr "Não é possível gravar em um arquivo" + +#: shared-module/storage/__init__.c +msgid "Cannot remount '/' when USB is active." +msgstr "Não é possível remontar '/' enquanto o USB estiver ativo." + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +msgid "Cannot reset into bootloader because no bootloader is present." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Cannot set value when direction is input." +msgstr "" + +#: py/objslice.c +msgid "Cannot subclass slice" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot transfer without MOSI and MISO pins." +msgstr "Não é possível transferir sem os pinos MOSI e MISO." + +#: extmod/moductypes.c +msgid "Cannot unambiguously get sizeof scalar" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot write without MOSI pin." +msgstr "Não é possível ler sem um pino MOSI" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "Clock pin init failed." +msgstr "Inicialização do pino de Clock falhou." + +#: shared-module/bitbangio/I2C.c +msgid "Clock stretch too long" +msgstr "Clock se estendeu por tempo demais" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" +msgstr "Unidade de Clock em uso" + +#: shared-bindings/_pew/PewPew.c +msgid "Column entry must be digitalio.DigitalInOut" +msgstr "" + +#: shared-bindings/displayio/I2CDisplay.c +msgid "Command must be 0-255" +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +#, fuzzy +msgid "Command must be an int between 0 and 255" +msgstr "Os bytes devem estar entre 0 e 255." + +#: py/persistentcode.c +msgid "Corrupt .mpy file" +msgstr "" + +#: py/emitglue.c +msgid "Corrupt raw code" +msgstr "" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "Could not initialize UART" +msgstr "Não foi possível inicializar o UART" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate first buffer" +msgstr "Não pôde alocar primeiro buffer" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate second buffer" +msgstr "Não pôde alocar segundo buffer" + +#: supervisor/shared/safe_mode.c +msgid "Crash into the HardFault_Handler.\n" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "DAC already in use" +msgstr "DAC em uso" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +msgid "Data 0 pin must be byte aligned" +msgstr "" + +#: shared-module/audiocore/WaveFile.c +msgid "Data chunk must follow fmt chunk" +msgstr "Pedaço de dados deve seguir o pedaço de cortes" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy +msgid "Data too large for advertisement packet" +msgstr "Não é possível ajustar dados no pacote de anúncios." + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Destination capacity is smaller than destination_length." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Display must have a 16 bit colorspace." +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Display rotation must be in 90 degree increments" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Drive mode not used when direction is input." +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "EXTINT channel already in use" +msgstr "Canal EXTINT em uso" + +#: extmod/modure.c +msgid "Error in regex" +msgstr "Erro no regex" + +#: shared-bindings/microcontroller/Pin.c +#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c +#: shared-bindings/terminalio/Terminal.c +msgid "Expected a %q" +msgstr "Esperado um" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c +#, fuzzy +msgid "Expected a Characteristic" +msgstr "Não é possível adicionar Característica." + +#: shared-bindings/_bleio/Service.c +msgid "Expected a Peripheral" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Expected a Service" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c +#: shared-bindings/_bleio/Service.c +#, fuzzy +msgid "Expected a UUID" +msgstr "Esperado um" + +#: shared-bindings/_bleio/Central.c +msgid "Expected an Address" +msgstr "" + +#: shared-module/_pixelbuf/PixelBuf.c +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "" + +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "Falha ao enviar comando." + +#: ports/nrf/sd_mutex.c +#, fuzzy, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "Não é possível ler o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Service.c +#, fuzzy, c-format +msgid "Failed to add characteristic, err 0x%04x" +msgstr "Não pode parar propaganda. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to add descriptor, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy, c-format +msgid "Failed to add service, err 0x%04x" +msgstr "Não pode parar propaganda. status: 0x%02x" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "Failed to allocate RX buffer" +msgstr "Falha ao alocar buffer RX" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +#, c-format +msgid "Failed to allocate RX buffer of %d bytes" +msgstr "Falha ao alocar buffer RX de %d bytes" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, fuzzy +msgid "Failed to change softdevice state" +msgstr "Não pode parar propaganda. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to configure advertising, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Central.c +msgid "Failed to connect: timeout" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, fuzzy, c-format +msgid "Failed to continue scanning, err 0x%04x" +msgstr "Não é possível iniciar o anúncio. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy +msgid "Failed to discover services" +msgstr "Não pode parar propaganda. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to get local address" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, fuzzy +msgid "Failed to get softdevice state" +msgstr "Não pode parar propaganda. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to notify or indicate attribute value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, fuzzy, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "Não é possível ler o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "Failed to read attribute value, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy, c-format +msgid "Failed to read gatts value, err 0x%04x" +msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, fuzzy, c-format +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" +msgstr "Não é possível adicionar o UUID de 128 bits específico do fornecedor." + +#: ports/nrf/sd_mutex.c +#, fuzzy, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "Não é possível ler o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to set device name, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "Não é possível iniciar o anúncio. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Central.c +#, c-format +msgid "Failed to start connecting, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, fuzzy, c-format +msgid "Failed to start scanning, err 0x%04x" +msgstr "Não é possível iniciar o anúncio. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, fuzzy, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "Não pode parar propaganda. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to write CCCD, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy, c-format +msgid "Failed to write attribute value, err 0x%04x" +msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, fuzzy, c-format +msgid "Failed to write gatts value, err 0x%04x" +msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" + +#: py/moduerrno.c +msgid "File exists" +msgstr "Arquivo já existe" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash erase failed" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash erase failed to start, err 0x%04x" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash write failed" +msgstr "" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash write failed to start, err 0x%04x" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Frequency captured is above capability. Capture Paused." +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c +msgid "Function requires lock" +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Group already used" +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Group full" +msgstr "Grupo cheio" + +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" +msgstr "Operação I/O no arquivo fechado" + +#: extmod/machine_i2c.c +msgid "I2C operation not supported" +msgstr "I2C operação não suportada" + +#: py/persistentcode.c +msgid "" +"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" +"mpy-update for more info." +msgstr "" + +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" +msgstr "" + +#: py/moduerrno.c +msgid "Input/output error" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Invalid %q pin" +msgstr "Pino do %q inválido" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Invalid BMP file" +msgstr "Arquivo BMP inválido" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c +#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c +msgid "Invalid PWM frequency" +msgstr "Frequência PWM inválida" + +#: py/moduerrno.c +msgid "Invalid argument" +msgstr "Argumento inválido" + +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" +msgstr "" + +#: ports/nrf/common-hal/busio/UART.c +#, fuzzy +msgid "Invalid buffer size" +msgstr "Arquivo inválido" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Invalid capture period. Valid range: 1 - 500" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +#, fuzzy +msgid "Invalid channel count" +msgstr "certificado inválido" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Invalid direction." +msgstr "Direção inválida" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid file" +msgstr "Arquivo inválido" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" +msgstr "Tamanho do pedaço de formato inválido" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid number of bits" +msgstr "Número inválido de bits" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid phase" +msgstr "Fase Inválida" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +#: shared-bindings/pulseio/PWMOut.c +msgid "Invalid pin" +msgstr "Pino inválido" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for left channel" +msgstr "Pino inválido para canal esquerdo" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for right channel" +msgstr "Pino inválido para canal direito" + +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/atmel-samd/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c +#: ports/nrf/common-hal/busio/I2C.c +msgid "Invalid pins" +msgstr "Pinos inválidos" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid polarity" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + +#: shared-bindings/microcontroller/__init__.c +msgid "Invalid run mode." +msgstr "" + +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +#, fuzzy +msgid "Invalid voice count" +msgstr "certificado inválido" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid wave file" +msgstr "Aqruivo de ondas inválido" + +#: py/compile.c +msgid "LHS of keyword arg must be an id" +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass." +msgstr "" + +#: py/objslice.c +msgid "Length must be an int" +msgstr "Tamanho deve ser um int" + +#: py/objslice.c +msgid "Length must be non-negative" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Looks like our core CircuitPython code crashed hard. Whoops!\n" +"Please file an issue at https://github.com/adafruit/circuitpython/issues\n" +" with the contents of your CIRCUITPY drive and this message:\n" +msgstr "" + +#: shared-module/bitbangio/SPI.c +msgid "MISO pin init failed." +msgstr "Inicialização do pino MISO falhou" + +#: shared-module/bitbangio/SPI.c +msgid "MOSI pin init failed." +msgstr "Inicialização do pino MOSI falhou." + +#: shared-module/displayio/Shape.c +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython NLR jump failed. Likely memory corruption.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython fatal error.\n" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Microphone startup delay must be in range 0.0 to 1.0" +msgstr "" + +#: shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "No DAC on chip" +msgstr "Nenhum DAC no chip" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "No DMA channel found" +msgstr "Nenhum canal DMA encontrado" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No RX pin" +msgstr "Nenhum pino RX" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No TX pin" +msgstr "Nenhum pino TX" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "No available clocks" +msgstr "" + +#: shared-bindings/board/__init__.c +msgid "No default %q bus" +msgstr "Nenhum barramento %q padrão" + +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" +msgstr "Não há GCLKs livre" + +#: shared-bindings/os/__init__.c +msgid "No hardware random available" +msgstr "" + +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "Sem suporte de hardware no pino de clock" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "No hardware support on pin" +msgstr "Nenhum suporte de hardware no pino" + +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" +msgstr "" + +#: py/moduerrno.c +msgid "No space left on device" +msgstr "" + +#: py/moduerrno.c +msgid "No such file/directory" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Peripheral.c +#, fuzzy +msgid "Not connected" +msgstr "Não é possível conectar-se ao AP" + +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c +msgid "Not playing" +msgstr "" + +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "" +"Objeto foi desinicializado e não pode ser mais usaado. Crie um novo objeto." + +#: ports/nrf/common-hal/busio/UART.c +#, fuzzy +msgid "Odd parity is not supported" +msgstr "I2C operação não suportada" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Only 8 or 16 bit mono with " +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Only slices with step=1 (aka None) are supported" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Oversample must be multiple of 8." +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" +msgstr "" + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM frequency not writable when variable_frequency is False on construction." +msgstr "" + +#: py/moduerrno.c +msgid "Permission denied" +msgstr "Permissão negada" + +#: ports/atmel-samd/common-hal/analogio/AnalogIn.c +#: ports/nrf/common-hal/analogio/AnalogIn.c +msgid "Pin does not have ADC capabilities" +msgstr "O pino não tem recursos de ADC" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Pixel beyond bounds of buffer" +msgstr "" + +#: py/builtinhelp.c +#, fuzzy +msgid "Plus any modules on the filesystem\n" +msgstr "Não é possível remontar o sistema de arquivos" + +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "Buffer Ps2 vazio" + +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload." +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Pull not used when direction is output." +msgstr "" + +#: ports/nrf/common-hal/rtc/RTC.c +msgid "RTC calibration is not supported on this board" +msgstr "A calibração RTC não é suportada nesta placa" + +#: shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" +msgstr "O RTC não é suportado nesta placa" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Range out of bounds" +msgstr "" + +#: shared-bindings/pulseio/PulseIn.c +msgid "Read-only" +msgstr "Somente leitura" + +#: extmod/vfs_fat.c py/moduerrno.c +msgid "Read-only filesystem" +msgstr "Sistema de arquivos somente leitura" + +#: shared-module/displayio/Bitmap.c +#, fuzzy +msgid "Read-only object" +msgstr "Somente leitura" + +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Refresh too soon" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" +msgstr "Canal direito não suportado" + +#: shared-bindings/_pew/PewPew.c +msgid "Row entry must be digitalio.DigitalInOut" +msgstr "" + +#: main.c +msgid "Running in safe mode! Auto-reload is off.\n" +msgstr "Rodando em modo seguro! Atualização automática está desligada.\n" + +#: main.c +msgid "Running in safe mode! Not running saved code.\n" +msgstr "Rodando em modo seguro! Não está executando o código salvo.\n" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "SDA or SCL needs a pull up" +msgstr "SDA ou SCL precisa de um pull up" + +#: shared-bindings/audiocore/Mixer.c +msgid "Sample rate must be positive" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Sample rate too high. It must be less than %d" +msgstr "Taxa de amostragem muito alta. Deve ser menor que %d" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" +msgstr "Serializer em uso" + +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/pulseio/PulseIn.c +msgid "Slices not supported" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: extmod/modure.c +msgid "Splitting with sub-captures" +msgstr "" + +#: shared-bindings/supervisor/__init__.c +msgid "Stack size must be at least 256" +msgstr "O tamanho da pilha deve ser pelo menos 256" + +#: shared-bindings/multiterminal/__init__.c +msgid "Stream missing readinto() or write() method." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The CircuitPython heap was corrupted because the stack was too small.\n" +"Please increase stack size limits and press reset (after ejecting " +"CIRCUITPY).\n" +"If you didn't change the stack, then file an issue here with the contents of " +"your CIRCUITPY drive:\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The `microcontroller` module was used to boot into safe mode. Press reset to " +"exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"The reset button was pressed while booting CircuitPython. Press again to " +"exit safe mode.\n" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's channel count does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's sample rate does not match the mixer's" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's signedness does not match the mixer's" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile value out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "Para sair, por favor, reinicie a placa sem " + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample." +msgstr "Muitos canais na amostra." + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "Too many display busses" +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Too many displays" +msgstr "" + +#: py/obj.c +msgid "Traceback (most recent call last):\n" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "Tuple or struct_time argument required" +msgstr "" + +#: shared-module/usb_hid/Device.c +msgid "USB Busy" +msgstr "USB ocupada" + +#: shared-module/usb_hid/Device.c +msgid "USB Error" +msgstr "Erro na USB" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID integer value must be 0-0xffff" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Unable to allocate buffers for signed conversion" +msgstr "Não é possível alocar buffers para conversão assinada" + +#: shared-module/displayio/I2CDisplay.c +#, c-format +msgid "Unable to find I2C Display at %x" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Unable to find free GCLK" +msgstr "Não é possível encontrar GCLK livre" + +#: py/parse.c +msgid "Unable to init parser" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" +msgstr "" + +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." +msgstr "Não é possível gravar no nvm." + +#: ports/nrf/common-hal/_bleio/UUID.c +msgid "Unexpected nrfx uuid type" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "Unsupported baudrate" +msgstr "Taxa de transmissão não suportada" + +#: shared-module/displayio/display_core.c +#, fuzzy +msgid "Unsupported display bus type" +msgstr "Taxa de transmissão não suportada" + +#: shared-module/audiocore/WaveFile.c +msgid "Unsupported format" +msgstr "Formato não suportado" + +#: py/moduerrno.c +msgid "Unsupported operation" +msgstr "" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Unsupported pull value." +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + +#: py/emitnative.c +msgid "Viper functions don't currently support more than 4 arguments" +msgstr "" + +#: shared-module/audiocore/Mixer.c +msgid "Voice index too high" +msgstr "" + +#: main.c +msgid "WARNING: Your code filename has two extensions\n" +msgstr "AVISO: Seu arquivo de código tem duas extensões\n" + +#: py/builtinhelp.c +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"You are running in safe mode which means something unanticipated happened.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "You requested starting safe mode by " +msgstr "Você solicitou o início do modo de segurança" + +#: py/objtype.c +msgid "__init__() should return None" +msgstr "" + +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "" + +#: py/objobject.c +msgid "__new__ arg must be a user-type" +msgstr "" + +#: extmod/modubinascii.c extmod/moduhashlib.c +msgid "a bytes-like object is required" +msgstr "" + +#: lib/embed/abort_.c +msgid "abort() called" +msgstr "abort() chamado" + +#: extmod/machine_mem.c +#, c-format +msgid "address %08x is not aligned to %d bytes" +msgstr "endereço %08x não está alinhado com %d bytes" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "address out of bounds" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "addresses is empty" +msgstr "" + +#: py/modbuiltins.c +msgid "arg is an empty sequence" +msgstr "" + +#: py/runtime.c +msgid "argument has wrong type" +msgstr "argumento tem tipo errado" + +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +msgid "argument num/types mismatch" +msgstr "" + +#: py/runtime.c +msgid "argument should be a '%q' not a '%q'" +msgstr "" + +#: py/objarray.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" +msgstr "" + +#: py/objstr.c +msgid "attributes not supported yet" +msgstr "atributos ainda não suportados" + +#: py/builtinevex.c +msgid "bad compile mode" +msgstr "" + +#: py/objstr.c +msgid "bad conversion specifier" +msgstr "" + +#: py/objstr.c +msgid "bad format string" +msgstr "" + +#: py/binary.c +msgid "bad typecode" +msgstr "" + +#: py/emitnative.c +msgid "binary op %q not implemented" +msgstr "" + +#: shared-bindings/busio/UART.c +msgid "bits must be 7, 8 or 9" +msgstr "" + +#: extmod/machine_spi.c +msgid "bits must be 8" +msgstr "bits devem ser 8" + +#: shared-bindings/audiocore/Mixer.c +#, fuzzy +msgid "bits_per_sample must be 8 or 16" +msgstr "bits devem ser 8" + +#: py/emitinlinethumb.c +#, fuzzy +msgid "branch not in range" +msgstr "Calibração está fora do intervalo" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "" + +#: shared-bindings/audiocore/RawSample.c +msgid "buffer must be a bytes-like object" +msgstr "" + +#: shared-module/struct/__init__.c +#, fuzzy +msgid "buffer size must match format" +msgstr "buffers devem ser o mesmo tamanho" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" +msgstr "" + +#: py/modstruct.c shared-bindings/struct/__init__.c +#: shared-module/struct/__init__.c +msgid "buffer too small" +msgstr "" + +#: extmod/machine_spi.c +msgid "buffers must be the same length" +msgstr "buffers devem ser o mesmo tamanho" + +#: shared-bindings/_pew/PewPew.c +msgid "buttons must be digitalio.DigitalInOut" +msgstr "" + +#: py/vm.c +msgid "byte code not implemented" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "bytes > 8 bits not supported" +msgstr "bytes > 8 bits não suportado" + +#: py/objstr.c +msgid "bytes value out of range" +msgstr "" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" +msgstr "Calibração está fora do intervalo" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" +msgstr "Calibração é somente leitura" + +#: ports/atmel-samd/common-hal/rtc/RTC.c +msgid "calibration value out of range +/-127" +msgstr "Valor de calibração fora do intervalo +/- 127" + +#: py/emitinlinethumb.c +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "" + +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "" + +#: py/persistentcode.c +msgid "can only save bytecode" +msgstr "" + +#: py/objtype.c +msgid "can't add special method to already-subclassed class" +msgstr "" + +#: py/compile.c +msgid "can't assign to expression" +msgstr "" + +#: py/obj.c +#, c-format +msgid "can't convert %s to complex" +msgstr "" + +#: py/obj.c +#, c-format +msgid "can't convert %s to float" +msgstr "" + +#: py/obj.c +#, c-format +msgid "can't convert %s to int" +msgstr "" + +#: py/objstr.c +msgid "can't convert '%q' object to %q implicitly" +msgstr "" + +#: py/objint.c +msgid "can't convert NaN to int" +msgstr "" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "can't convert address to int" +msgstr "" + +#: py/objint.c +msgid "can't convert inf to int" +msgstr "" + +#: py/obj.c +msgid "can't convert to complex" +msgstr "" + +#: py/obj.c +msgid "can't convert to float" +msgstr "" + +#: py/obj.c +msgid "can't convert to int" +msgstr "" + +#: py/objstr.c +msgid "can't convert to str implicitly" +msgstr "" + +#: py/compile.c +msgid "can't declare nonlocal in outer code" +msgstr "" + +#: py/compile.c +msgid "can't delete expression" +msgstr "" + +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" +msgstr "" + +#: py/objcomplex.c +msgid "can't do truncated division of a complex number" +msgstr "" + +#: py/compile.c +msgid "can't have multiple **x" +msgstr "" + +#: py/compile.c +msgid "can't have multiple *x" +msgstr "" + +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "" + +#: py/emitnative.c +msgid "can't load from '%q'" +msgstr "" + +#: py/emitnative.c +msgid "can't load with '%q' index" +msgstr "" + +#: py/objgenerator.c +msgid "can't pend throw to just-started generator" +msgstr "" + +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" +msgstr "" + +#: py/objnamedtuple.c +msgid "can't set attribute" +msgstr "" + +#: py/emitnative.c +msgid "can't store '%q'" +msgstr "" + +#: py/emitnative.c +msgid "can't store to '%q'" +msgstr "" + +#: py/emitnative.c +msgid "can't store with '%q' index" +msgstr "" + +#: py/objstr.c +msgid "" +"can't switch from automatic field numbering to manual field specification" +msgstr "" + +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "" + +#: py/objtype.c +msgid "cannot create '%q' instances" +msgstr "" + +#: py/objtype.c +msgid "cannot create instance" +msgstr "não é possível criar instância" + +#: py/runtime.c +msgid "cannot import name %q" +msgstr "não pode importar nome %q" + +#: py/builtinimport.c +msgid "cannot perform relative import" +msgstr "" + +#: py/emitnative.c +msgid "casting" +msgstr "" + +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" +msgstr "" + +#: py/modbuiltins.c +msgid "chr() arg not in range(0x110000)" +msgstr "" + +#: py/modbuiltins.c +msgid "chr() arg not in range(256)" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer or int" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" +msgstr "cor deve estar entre 0x000000 e 0xffffff" + +#: shared-bindings/displayio/ColorConverter.c +msgid "color should be an int" +msgstr "cor deve ser um int" + +#: py/objcomplex.c +msgid "complex division by zero" +msgstr "" + +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" +msgstr "" + +#: extmod/moduzlib.c +msgid "compression header" +msgstr "" + +#: py/parse.c +msgid "constant must be an integer" +msgstr "constante deve ser um inteiro" + +#: py/emitnative.c +msgid "conversion to object" +msgstr "" + +#: py/parsenum.c +msgid "decimal numbers not supported" +msgstr "" + +#: py/compile.c +msgid "default 'except' must be last" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination_length must be an int >= 0" +msgstr "destination_length deve ser um int >= 0" + +#: py/objdict.c +msgid "dict update sequence has wrong length" +msgstr "" + +#: py/modmath.c py/objfloat.c py/objint_longlong.c py/objint_mpz.c py/runtime.c +#: shared-bindings/math/__init__.c +msgid "division by zero" +msgstr "divisão por zero" + +#: py/objdeque.c +msgid "empty" +msgstr "vazio" + +#: extmod/moduheapq.c extmod/modutimeq.c +msgid "empty heap" +msgstr "heap vazia" + +#: py/objstr.c +msgid "empty separator" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "empty sequence" +msgstr "seqüência vazia" + +#: py/objstr.c +msgid "end of format while looking for conversion specifier" +msgstr "" + +#: shared-bindings/displayio/Shape.c +#, fuzzy +msgid "end_x should be an int" +msgstr "y deve ser um int" + +#: ports/nrf/common-hal/busio/UART.c +#, c-format +msgid "error = 0x%08lX" +msgstr "erro = 0x%08lX" + +#: py/runtime.c +msgid "exceptions must derive from BaseException" +msgstr "" + +#: py/objstr.c +msgid "expected ':' after format specifier" +msgstr "" + +#: py/obj.c +msgid "expected tuple/list" +msgstr "" + +#: py/modthread.c +msgid "expecting a dict for keyword args" +msgstr "" + +#: py/compile.c +msgid "expecting an assembler instruction" +msgstr "" + +#: py/compile.c +msgid "expecting just a value for set" +msgstr "" + +#: py/compile.c +msgid "expecting key:value for dict" +msgstr "" + +#: py/argcheck.c +msgid "extra keyword arguments given" +msgstr "argumentos extras de palavras-chave passados" + +#: py/argcheck.c +msgid "extra positional arguments given" +msgstr "argumentos extra posicionais passados" + +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c +msgid "file must be a file opened in byte mode" +msgstr "" + +#: shared-bindings/storage/__init__.c +msgid "filesystem must provide mount method" +msgstr "sistema de arquivos deve fornecer método de montagem" + +#: py/objtype.c +msgid "first argument to super() must be type" +msgstr "" + +#: extmod/machine_spi.c +msgid "firstbit must be MSB" +msgstr "firstbit devem ser MSB" + +#: py/objint.c +msgid "float too big" +msgstr "float muito grande" + +#: shared-bindings/_stage/Text.c +msgid "font must be 2048 bytes long" +msgstr "" + +#: py/objstr.c +msgid "format requires a dict" +msgstr "" + +#: py/objdeque.c +msgid "full" +msgstr "cheio" + +#: py/argcheck.c +msgid "function does not take keyword arguments" +msgstr "função não aceita argumentos de palavras-chave" + +#: py/argcheck.c +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "função esperada na maioria dos %d argumentos, obteve %d" + +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" +msgstr "" + +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" +msgstr "função ausente %d requer argumentos posicionais" + +#: py/bc.c +msgid "function missing keyword-only argument" +msgstr "" + +#: py/bc.c +msgid "function missing required keyword argument '%q'" +msgstr "" + +#: py/bc.c +#, c-format +msgid "function missing required positional argument #%d" +msgstr "" + +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "função leva %d argumentos posicionais, mas apenas %d foram passadas" + +#: shared-bindings/time/__init__.c +msgid "function takes exactly 9 arguments" +msgstr "função leva exatamente 9 argumentos" + +#: py/objgenerator.c +msgid "generator already executing" +msgstr "" + +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" +msgstr "" + +#: shared-bindings/_stage/Layer.c +msgid "graphic must be 2048 bytes long" +msgstr "" + +#: extmod/moduheapq.c +msgid "heap must be a list" +msgstr "heap deve ser uma lista" + +#: py/compile.c +msgid "identifier redefined as global" +msgstr "" + +#: py/compile.c +msgid "identifier redefined as nonlocal" +msgstr "" + +#: py/objstr.c +msgid "incomplete format" +msgstr "formato incompleto" + +#: py/objstr.c +msgid "incomplete format key" +msgstr "" + +#: extmod/modubinascii.c +msgid "incorrect padding" +msgstr "preenchimento incorreto" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c py/obj.c +msgid "index out of range" +msgstr "Ãndice fora do intervalo" + +#: py/obj.c +msgid "indices must be integers" +msgstr "" + +#: py/compile.c +msgid "inline assembler must be a function" +msgstr "" + +#: py/parsenum.c +msgid "int() arg 2 must be >= 2 and <= 36" +msgstr "" + +#: py/objstr.c +msgid "integer required" +msgstr "inteiro requerido" + +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c +#, c-format +msgid "interval must be in range %s-%s" +msgstr "" + +#: extmod/machine_i2c.c +msgid "invalid I2C peripheral" +msgstr "periférico I2C inválido" + +#: extmod/machine_spi.c +msgid "invalid SPI peripheral" +msgstr "periférico SPI inválido" + +#: lib/netutils/netutils.c +msgid "invalid arguments" +msgstr "argumentos inválidos" + +#: extmod/modussl_axtls.c +msgid "invalid cert" +msgstr "certificado inválido" + +#: extmod/uos_dupterm.c +msgid "invalid dupterm index" +msgstr "Ãndice de dupterm inválido" + +#: extmod/modframebuf.c +msgid "invalid format" +msgstr "formato inválido" + +#: py/objstr.c +msgid "invalid format specifier" +msgstr "" + +#: extmod/modussl_axtls.c +msgid "invalid key" +msgstr "chave inválida" + +#: py/compile.c +msgid "invalid micropython decorator" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "invalid step" +msgstr "passo inválido" + +#: py/compile.c py/parse.c +msgid "invalid syntax" +msgstr "" + +#: py/parsenum.c +msgid "invalid syntax for integer" +msgstr "" + +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "" + +#: py/parsenum.c +msgid "invalid syntax for number" +msgstr "" + +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" +msgstr "" + +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "" + +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "" + +#: py/argcheck.c +msgid "keyword argument(s) not yet implemented - use normal args instead" +msgstr "" + +#: py/bc.c +msgid "keywords must be strings" +msgstr "" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" +msgstr "" + +#: py/compile.c +msgid "label redefined" +msgstr "" + +#: py/stream.c +msgid "length argument not allowed for this type" +msgstr "" + +#: py/objarray.c +msgid "lhs and rhs should be compatible" +msgstr "" + +#: py/emitnative.c +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "" + +#: py/emitnative.c +msgid "local '%q' used before type known" +msgstr "" + +#: py/vm.c +msgid "local variable referenced before assignment" +msgstr "" + +#: py/objint.c +msgid "long int not supported in this build" +msgstr "" + +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" +msgstr "" + +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + +#: py/runtime.c +msgid "maximum recursion depth exceeded" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "" + +#: py/runtime.c +msgid "memory allocation failed, heap is locked" +msgstr "" + +#: py/builtinimport.c +msgid "module not found" +msgstr "" + +#: py/compile.c +msgid "multiple *x in assignment" +msgstr "" + +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" +msgstr "" + +#: py/objtype.c +msgid "multiple inheritance not supported" +msgstr "" + +#: py/emitnative.c +msgid "must raise an object" +msgstr "" + +#: extmod/machine_spi.c +msgid "must specify all of sck/mosi/miso" +msgstr "deve especificar todos sck/mosi/miso" + +#: py/modbuiltins.c +msgid "must use keyword argument for key function" +msgstr "" + +#: py/runtime.c +msgid "name '%q' is not defined" +msgstr "" + +#: shared-bindings/_bleio/Peripheral.c +#, fuzzy +msgid "name must be a string" +msgstr "heap deve ser uma lista" + +#: py/runtime.c +msgid "name not defined" +msgstr "nome não definido" + +#: py/compile.c +msgid "name reused for argument" +msgstr "" + +#: py/emitnative.c +msgid "native yield" +msgstr "" + +#: py/runtime.c +#, c-format +msgid "need more than %d values to unpack" +msgstr "precisa de mais de %d valores para desempacotar" + +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" +msgstr "" + +#: py/objint_mpz.c py/runtime.c +msgid "negative shift count" +msgstr "" + +#: py/vm.c +msgid "no active exception to reraise" +msgstr "" + +#: shared-bindings/socket/__init__.c shared-module/network/__init__.c +msgid "no available NIC" +msgstr "" + +#: py/compile.c +msgid "no binding for nonlocal found" +msgstr "" + +#: py/builtinimport.c +msgid "no module named '%q'" +msgstr "" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "no reset pin available" +msgstr "" + +#: py/runtime.c shared-bindings/_pixelbuf/__init__.c +msgid "no such attribute" +msgstr "" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" +msgstr "" + +#: py/compile.c +msgid "non-default argument follows default argument" +msgstr "" + +#: extmod/modubinascii.c +msgid "non-hex digit found" +msgstr "" + +#: py/compile.c +msgid "non-keyword arg after */**" +msgstr "" + +#: py/compile.c +msgid "non-keyword arg after keyword arg" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" +msgstr "" + +#: py/objstr.c +msgid "not all arguments converted during string formatting" +msgstr "" + +#: py/objstr.c +msgid "not enough arguments for format string" +msgstr "" + +#: py/obj.c +#, c-format +msgid "object '%s' is not a tuple or list" +msgstr "" + +#: py/obj.c +msgid "object does not support item assignment" +msgstr "" + +#: py/obj.c +msgid "object does not support item deletion" +msgstr "" + +#: py/obj.c +msgid "object has no len" +msgstr "" + +#: py/obj.c +msgid "object is not subscriptable" +msgstr "" + +#: py/runtime.c +msgid "object not an iterator" +msgstr "" + +#: py/objtype.c py/runtime.c +msgid "object not callable" +msgstr "" + +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" +msgstr "objeto não em seqüência" + +#: py/runtime.c +msgid "object not iterable" +msgstr "objeto não iterável" + +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" +msgstr "" + +#: py/obj.c +msgid "object with buffer protocol required" +msgstr "" + +#: extmod/modubinascii.c +msgid "odd-length string" +msgstr "" + +#: py/objstr.c py/objstrunicode.c +msgid "offset out of bounds" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" +msgstr "" + +#: py/modbuiltins.c +msgid "ord expects a character" +msgstr "" + +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "" + +#: py/objint_mpz.c +msgid "overflow converting long int to machine word" +msgstr "" + +#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c +msgid "palette must be 32 bytes long" +msgstr "" + +#: shared-bindings/displayio/Palette.c +msgid "palette_index should be an int" +msgstr "" + +#: py/compile.c +msgid "parameter annotation must be an identifier" +msgstr "" + +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" +msgstr "" + +#: py/emitinlinethumb.c +msgid "parameters must be registers in sequence r0 to r3" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel coordinates out of bounds" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel value requires too many bits" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" +msgstr "" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" +msgstr "" + +#: py/objset.c +msgid "pop from an empty set" +msgstr "" + +#: py/objlist.c +msgid "pop from empty list" +msgstr "" + +#: py/objdict.c +msgid "popitem(): dictionary is empty" +msgstr "" + +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" +msgstr "" + +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" +msgstr "" + +#: extmod/modutimeq.c +msgid "queue overflow" +msgstr "estouro de fila" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "rawbuf is not the same size as buf" +msgstr "" + +#: shared-bindings/_pixelbuf/__init__.c +#, fuzzy +msgid "readonly attribute" +msgstr "atributo ilegível" + +#: py/builtinimport.c +msgid "relative import" +msgstr "" + +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" +msgstr "" + +#: py/compile.c +msgid "return annotation must be an identifier" +msgstr "" + +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" +msgstr "" + +#: py/objstr.c +msgid "rsplit(None,n)" +msgstr "" + +#: shared-bindings/audiocore/RawSample.c +msgid "" +"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " +"'B'" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" +msgstr "Taxa de amostragem fora do intervalo" + +#: py/modmicropython.c +msgid "schedule stack full" +msgstr "" + +#: lib/utils/pyexec.c py/builtinimport.c +msgid "script compilation not supported" +msgstr "compilação de script não suportada" + +#: py/objstr.c +msgid "sign not allowed in string format specifier" +msgstr "" + +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" +msgstr "" + +#: py/objstr.c +msgid "single '}' encountered in format string" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "sleep length must be non-negative" +msgstr "" + +#: py/objslice.c py/sequence.c +msgid "slice step cannot be zero" +msgstr "" + +#: py/objint.c py/sequence.c +msgid "small int overflow" +msgstr "" + +#: main.c +msgid "soft reboot\n" +msgstr "" + +#: py/objstr.c +msgid "start/end indices" +msgstr "" + +#: shared-bindings/displayio/Shape.c +#, fuzzy +msgid "start_x should be an int" +msgstr "y deve ser um int" + +#: shared-bindings/random/__init__.c +msgid "step must be non-zero" +msgstr "o passo deve ser diferente de zero" + +#: shared-bindings/busio/UART.c +msgid "stop must be 1 or 2" +msgstr "" + +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" +msgstr "" + +#: py/stream.c +msgid "stream operation not supported" +msgstr "" + +#: py/objstrunicode.c +msgid "string index out of range" +msgstr "" + +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" +msgstr "" + +#: py/stream.c +msgid "string not supported; use bytes or bytearray" +msgstr "" + +#: extmod/moductypes.c +msgid "struct: cannot index" +msgstr "struct: não pode indexar" + +#: extmod/moductypes.c +msgid "struct: index out of range" +msgstr "struct: índice fora do intervalo" + +#: extmod/moductypes.c +msgid "struct: no fields" +msgstr "struct: sem campos" + +#: py/objstr.c +msgid "substring not found" +msgstr "" + +#: py/compile.c +msgid "super() can't find self" +msgstr "" + +#: extmod/modujson.c +msgid "syntax error in JSON" +msgstr "erro de sintaxe no JSON" + +#: extmod/moductypes.c +msgid "syntax error in uctypes descriptor" +msgstr "" + +#: shared-bindings/touchio/TouchIn.c +msgid "threshold must be in the range 0-65536" +msgstr "Limite deve estar no alcance de 0-65536" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes a 9-sequence" +msgstr "" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes exactly 1 argument" +msgstr "" + +#: shared-bindings/busio/UART.c +msgid "timeout >100 (units are now seconds, not msecs)" +msgstr "" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#, fuzzy +msgid "timeout must be >= 0.0" +msgstr "bits devem ser 8" + +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" +msgstr "timestamp fora do intervalo para a plataforma time_t" + +#: shared-module/struct/__init__.c +msgid "too many arguments provided with the given format" +msgstr "Muitos argumentos fornecidos com o formato dado" + +#: py/runtime.c +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "" + +#: py/objstr.c +msgid "tuple index out of range" +msgstr "" + +#: py/obj.c +msgid "tuple/list has wrong length" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "tuple/list required on RHS" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "tx and rx cannot both be None" +msgstr "TX e RX não podem ser ambos" + +#: py/objtype.c +msgid "type '%q' is not an acceptable base type" +msgstr "" + +#: py/objtype.c +msgid "type is not an acceptable base type" +msgstr "" + +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" +msgstr "" + +#: py/objtype.c +msgid "type takes 1 or 3 arguments" +msgstr "" + +#: py/objint_longlong.c +msgid "ulonglong too large" +msgstr "" + +#: py/emitnative.c +msgid "unary op %q not implemented" +msgstr "" + +#: py/parse.c +msgid "unexpected indent" +msgstr "" + +#: py/bc.c +msgid "unexpected keyword argument" +msgstr "" + +#: py/bc.c py/objnamedtuple.c +msgid "unexpected keyword argument '%q'" +msgstr "" + +#: py/lexer.c +msgid "unicode name escapes" +msgstr "" + +#: py/parse.c +msgid "unindent does not match any outer indentation level" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown conversion specifier %c" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type '%s'" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'float'" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'str'" +msgstr "" + +#: py/compile.c +msgid "unknown type" +msgstr "" + +#: py/emitnative.c +msgid "unknown type '%q'" +msgstr "" + +#: py/objstr.c +msgid "unmatched '{' in format" +msgstr "" + +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" +msgstr "atributo ilegível" + +#: shared-bindings/displayio/TileGrid.c +msgid "unsupported %q type" +msgstr "" + +#: py/emitinlinethumb.c +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "" + +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "" + +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "" + +#: py/runtime.c +msgid "unsupported type for %q: '%s'" +msgstr "" + +#: py/runtime.c +msgid "unsupported type for operator" +msgstr "" + +#: py/runtime.c +msgid "unsupported types for %q: '%s', '%s'" +msgstr "" + +#: py/objint.c +#, c-format +msgid "value must fit in %d byte(s)" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c +msgid "value_count must be > 0" +msgstr "" + +#: shared-bindings/_bleio/Scanner.c +msgid "window must be <= interval" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "write_args must be a list, tuple, or None" +msgstr "" + +#: py/objstr.c +msgid "wrong number of arguments" +msgstr "" + +#: py/runtime.c +msgid "wrong number of values to unpack" +msgstr "" + +#: shared-module/displayio/Shape.c +msgid "x value out of bounds" +msgstr "" + +#: shared-bindings/displayio/Shape.c +msgid "y should be an int" +msgstr "y deve ser um int" + +#: shared-module/displayio/Shape.c +msgid "y value out of bounds" +msgstr "" + +#: py/objrange.c +msgid "zero step" +msgstr "passo zero" + +#~ msgid "AP required" +#~ msgstr "AP requerido" + +#~ msgid "Cannot connect to AP" +#~ msgstr "Não é possível conectar-se ao AP" + +#~ msgid "Cannot disconnect from AP" +#~ msgstr "Não é possível desconectar do AP" + +#~ msgid "Cannot set STA config" +#~ msgstr "Não é possível definir a configuração STA" + +#~ msgid "Cannot update i/f status" +#~ msgstr "Não é possível atualizar o status i/f" + +#, fuzzy +#~ msgid "Data too large for the advertisement packet" +#~ msgstr "Não é possível ajustar dados no pacote de anúncios." + +#~ msgid "Don't know how to pass object to native function" +#~ msgstr "Não sabe como passar o objeto para a função nativa" + +#~ msgid "ESP8226 does not support safe mode." +#~ msgstr "O ESP8226 não suporta o modo de segurança." + +#~ msgid "ESP8266 does not support pull down." +#~ msgstr "ESP8266 não suporta pull down." + +#~ msgid "Error in ffi_prep_cif" +#~ msgstr "Erro no ffi_prep_cif" + +#, fuzzy +#~ msgid "Failed to acquire mutex" +#~ msgstr "Falha ao alocar buffer RX" + +#, fuzzy +#~ msgid "Failed to add service" +#~ msgstr "Não pode parar propaganda. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to create mutex" +#~ msgstr "Não é possível ler o valor do atributo. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to notify or indicate attribute value, err %0x04x" +#~ msgstr "Não é possível gravar o valor do atributo. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to read attribute value, err %0x04x" +#~ msgstr "Não é possível ler o valor do atributo. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to release mutex" +#~ msgstr "Não é possível ler o valor do atributo. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to start advertising" +#~ msgstr "Não é possível iniciar o anúncio. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to start scanning" +#~ msgstr "Não é possível iniciar o anúncio. status: 0x%02x" + +#, fuzzy +#~ msgid "Failed to stop advertising" +#~ msgstr "Não pode parar propaganda. status: 0x%02x" + +#~ msgid "GPIO16 does not support pull up." +#~ msgstr "GPIO16 não suporta pull up." + +#~ msgid "Invalid bit clock pin" +#~ msgstr "Pino de bit clock inválido" + +#~ msgid "Invalid clock pin" +#~ msgstr "Pino do Clock inválido" + +#~ msgid "Invalid data pin" +#~ msgstr "Pino de dados inválido" + +#~ msgid "Maximum PWM frequency is %dhz." +#~ msgstr "A frequência máxima PWM é de %dhz." + +#~ msgid "Minimum PWM frequency is 1hz." +#~ msgstr "A frequência mínima PWM é de 1hz" + +#~ msgid "Multiple PWM frequencies not supported. PWM already set to %dhz." +#~ msgstr "" +#~ "Múltiplas frequências PWM não suportadas. PWM já definido para %dhz." + +#~ msgid "No PulseIn support for %q" +#~ msgstr "Não há suporte para PulseIn no pino %q" + +#~ msgid "No hardware support for analog out." +#~ msgstr "Nenhum suporte de hardware para saída analógica." + +#~ msgid "Only Windows format, uncompressed BMP supported %d" +#~ msgstr "Apenas formato Windows, BMP descomprimido suportado" + +#~ msgid "Only bit maps of 8 bit color or less are supported" +#~ msgstr "Apenas bit maps de cores de 8 bit ou menos são suportados" + +#~ msgid "Only true color (24 bpp or higher) BMP supported %x" +#~ msgstr "Apenas cores verdadeiras (24 bpp ou maior) BMP suportadas" + +#~ msgid "Only tx supported on UART1 (GPIO2)." +#~ msgstr "Apenas TX suportado no UART1 (GPIO2)." + +#~ msgid "PWM not supported on pin %d" +#~ msgstr "PWM não suportado no pino %d" + +#~ msgid "Pin %q does not have ADC capabilities" +#~ msgstr "Pino %q não tem recursos de ADC" + +#~ msgid "Pin(16) doesn't support pull" +#~ msgstr "Pino (16) não suporta pull" + +#~ msgid "Pins not valid for SPI" +#~ msgstr "Pinos não válidos para SPI" + +#~ msgid "STA must be active" +#~ msgstr "STA deve estar ativo" + +#~ msgid "STA required" +#~ msgstr "STA requerido" + +#~ msgid "UART(%d) does not exist" +#~ msgstr "UART(%d) não existe" + +#~ msgid "UART(1) can't read" +#~ msgstr "UART(1) não pode ler" + +#~ msgid "Unable to remount filesystem" +#~ msgstr "Não é possível remontar o sistema de arquivos" + +#~ msgid "Unknown type" +#~ msgstr "Tipo desconhecido" + +#~ msgid "Use esptool to erase flash and re-upload Python instead" +#~ msgstr "Use o esptool para apagar o flash e recarregar o Python" + +#~ msgid "buffer too long" +#~ msgstr "buffer muito longo" + +#~ msgid "can query only one param" +#~ msgstr "pode consultar apenas um parâmetro" + +#~ msgid "can't get AP config" +#~ msgstr "não pode obter configuração de AP" + +#~ msgid "can't get STA config" +#~ msgstr "não pode obter a configuração STA" + +#~ msgid "can't set AP config" +#~ msgstr "não é possível definir a configuração do AP" + +#~ msgid "can't set STA config" +#~ msgstr "não é possível definir a configuração STA" + +#~ msgid "either pos or kw args are allowed" +#~ msgstr "pos ou kw args são permitidos" + +#~ msgid "expecting a pin" +#~ msgstr "esperando um pino" + +#~ msgid "ffi_prep_closure_loc" +#~ msgstr "ffi_prep_closure_loc" + +#~ msgid "flash location must be below 1MByte" +#~ msgstr "o local do flash deve estar abaixo de 1 MByte" + +#~ msgid "frequency can only be either 80Mhz or 160MHz" +#~ msgstr "A frequência só pode ser 80Mhz ou 160MHz" + +#~ msgid "impossible baudrate" +#~ msgstr "taxa de transmissão impossível" + +#~ msgid "invalid alarm" +#~ msgstr "Alarme inválido" + +#~ msgid "invalid buffer length" +#~ msgstr "comprimento de buffer inválido" + +#~ msgid "invalid data bits" +#~ msgstr "Bits de dados inválidos" + +#~ msgid "invalid pin" +#~ msgstr "Pino inválido" + +#~ msgid "invalid stop bits" +#~ msgstr "Bits de parada inválidos" + +#~ msgid "len must be multiple of 4" +#~ msgstr "len deve ser múltiplo de 4" + +#~ msgid "memory allocation failed, allocating %u bytes for native code" +#~ msgstr "alocação de memória falhou, alocando %u bytes para código nativo" + +#~ msgid "not a valid ADC Channel: %d" +#~ msgstr "não é um canal ADC válido: %d" + +#~ msgid "pin does not have IRQ capabilities" +#~ msgstr "Pino não tem recursos de IRQ" + +#~ msgid "row must be packed and word aligned" +#~ msgstr "Linha deve ser comprimida e com as palavras alinhadas" + +#~ msgid "scan failed" +#~ msgstr "varredura falhou" + +#~ msgid "too many arguments" +#~ msgstr "muitos argumentos" + +#~ msgid "unknown config param" +#~ msgstr "parâmetro configuração desconhecido" + +#~ msgid "unknown status param" +#~ msgstr "parâmetro de status desconhecido" + +#~ msgid "wifi_set_ip_info() failed" +#~ msgstr "wifi_set_ip_info() falhou" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po new file mode 100644 index 00000000000..67a8f5d71ac --- /dev/null +++ b/locale/zh_Latn_pinyin.po @@ -0,0 +1,2845 @@ +# Adafruit CircuitPython Chinese Hanyu Pinyin Translation +# Copyright (C) 2019 +# This file is distributed under the same license as the CircuitPython package. +# @hexthat#2155, 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: circuitpython-cn\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"PO-Revision-Date: 2019-04-13 10:10-0700\n" +"Last-Translator: hexthat\n" +"Language-Team: Chinese Hanyu Pinyin\n" +"Language: zh\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.2.1\n" + +#: main.c +msgid "" +"\n" +"Code done running. Waiting for reload.\n" +msgstr "" +"\n" +"DàimÇŽ yÇ wánchéng yùnxíng. Zhèngzài dÄ›ngdài chóngxÄ«n jiÄzài.\n" + +#: py/obj.c +msgid " File \"%q\"" +msgstr " Wénjiàn \"%q\"" + +#: py/obj.c +msgid " File \"%q\", line %d" +msgstr " Wénjiàn \"%q\", dì %d xíng" + +#: main.c +msgid " output:\n" +msgstr " shÅ«chÅ«:\n" + +#: py/objstr.c +#, c-format +msgid "%%c requires int or char" +msgstr "%%c xÅ«yào zhÄ›ngshù huò char" + +#: shared-bindings/microcontroller/Pin.c +msgid "%q in use" +msgstr "%q zhèngzài shÇyòng" + +#: py/obj.c +msgid "%q index out of range" +msgstr "%q suÇ’yÇn chÄochÅ« fànwéi" + +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "%q suÇ’yÇn bìxÅ« shì zhÄ›ngshù, ér bùshì %s" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c +msgid "%q must be >= 1" +msgstr "%q bìxÅ« dàyú huò dÄ›ngyú 1" + +#: shared-bindings/fontio/BuiltinFont.c +msgid "%q should be an int" +msgstr "%q yÄ«nggÄi shì yÄ«gè int" + +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" +msgstr "%q() cÇŽiyòng %d wèizhì cÄnshù, dàn gÄ›i chÅ« %d" + +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "xÅ«yào '%q' cÄnshù" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" +msgstr "'%s' qÄ«wàng biÄoqiÄn" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" +msgstr "'%s' qÄ«wàng yÄ«gè zhùcè" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects a special register" +msgstr "'%s' xÅ«yào yÄ«gè tèshÅ« de jìcúnqì" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an FPU register" +msgstr "'%s' xÅ«yào FPU jìcúnqì" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "'%s' qÄ«wàng chuÄng tÇ [a, b] dì dìzhÇ" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" +msgstr "'%s' qídài yÄ«gè zhÄ›ngshù" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects at most r%d" +msgstr "'%s' qÄ«wàng zuìduÅ de shì %d" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "'%s' yùqí {r0, r1, ...}" + +#: py/emitinlinextensa.c +#, c-format +msgid "'%s' integer %d is not within range %d..%d" +msgstr "'%s' zhÄ›ngshù %d bùzài fànwéi nèi %d.%d" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' integer 0x%x does not fit in mask 0x%x" +msgstr "'%s' zhÄ›ngshù 0x%x bù shìyòng yú yÇŽn mÇŽ 0x%x" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item assignment" +msgstr "'%s' duìxiàng bù zhÄ«chí xiàngmù fÄ“npèi" + +#: py/obj.c +#, c-format +msgid "'%s' object does not support item deletion" +msgstr "'%s' duìxiàng bù zhÄ«chí shÄnchú xiàngmù" + +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" +msgstr "'%s' duìxiàng méiyÇ’u shÇ”xìng '%q'" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not an iterator" +msgstr "'%s' duìxiàng bùshì yÄ«gè diédài qì" + +#: py/objtype.c py/runtime.c +#, c-format +msgid "'%s' object is not callable" +msgstr "'%s' duìxiàng wúfÇŽ diàoyòng" + +#: py/runtime.c +#, c-format +msgid "'%s' object is not iterable" +msgstr "'%s' duìxiàng bùnéng diédài" + +#: py/obj.c +#, c-format +msgid "'%s' object is not subscriptable" +msgstr "'%s' duìxiàng bùnéng fÄ“nshù" + +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" +msgstr "zìfú chuàn géshì shuÅmíng fú zhÅng bù yÇ”nxÇ” '=' duìqí" + +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" +msgstr "'S' hé 'O' bù zhÄ«chí géshì lèixíng" + +#: py/compile.c +msgid "'align' requires 1 argument" +msgstr "'align' xÅ«yào 1 gè cÄnshù" + +#: py/compile.c +msgid "'await' outside function" +msgstr "'await' wàibù gÅngnéng" + +#: py/compile.c +msgid "'break' outside loop" +msgstr "'break' wàibù xúnhuán" + +#: py/compile.c +msgid "'continue' outside loop" +msgstr "'continue' wàibù xúnhuán" + +#: py/compile.c +msgid "'data' requires at least 2 arguments" +msgstr "'data' xÅ«yào zhìshÇŽo 2 gè cÄnshù" + +#: py/compile.c +msgid "'data' requires integer arguments" +msgstr "'data' xÅ«yào zhÄ›ngshù cÄnshù" + +#: py/compile.c +msgid "'label' requires 1 argument" +msgstr "'label' xÅ«yào 1 cÄnshù" + +#: py/compile.c +msgid "'return' outside function" +msgstr "'return' wàibù gÅngnéng" + +#: py/compile.c +msgid "'yield' outside function" +msgstr "'yield' wàibù gÅngnéng" + +#: py/compile.c +msgid "*x must be assignment target" +msgstr "*x bìxÅ« shì rènwù mùbiÄo" + +#: py/obj.c +msgid ", in %q\n" +msgstr ", zài %q\n" + +#: py/objcomplex.c +msgid "0.0 to a complex power" +msgstr "0.0 dào fùzá diànyuán" + +#: py/modbuiltins.c +msgid "3-arg pow() not supported" +msgstr "bù zhÄ«chí 3-arg pow ()" + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "A hardware interrupt channel is already in use" +msgstr "Yìngjiàn zhÅngduàn tÅngdào yÇ zài shÇyòng zhÅng" + +#: shared-bindings/_bleio/Address.c +#, c-format +msgid "Address must be %d bytes long" +msgstr "DìzhÇ bìxÅ« shì %d zì jié zhÇŽng" + +#: shared-bindings/_bleio/Address.c +msgid "Address type out of range" +msgstr "" + +#: ports/nrf/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" +msgstr "SuÇ’yÇ’u I2C wàiwéi qì zhèngzài shÇyòng" + +#: ports/nrf/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" +msgstr "SuÇ’yÇ’u SPI wàiwéi qì zhèngzài shÇyòng" + +#: ports/nrf/common-hal/busio/UART.c +msgid "All UART peripherals are in use" +msgstr "SuÇ’yÇ’u UART wàiwéi zhèngzài shÇyòng" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "SuÇ’yÇ’u shÇyòng de shìjiàn píndào" + +#: ports/atmel-samd/audio_dma.c ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "All sync event channels in use" +msgstr "SuÇ’yÇ’u tóngbù shìjiàn píndào shÇyòng" + +#: shared-bindings/pulseio/PWMOut.c +msgid "All timers for this pin are in use" +msgstr "CÇ yÇn jiÇŽo de suÇ’yÇ’u jìshí qì zhèngzài shÇyòng" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: shared-module/_pew/PewPew.c +msgid "All timers in use" +msgstr "SuÇ’yÇ’u jìshí qì shÇyòng" + +#: ports/nrf/common-hal/analogio/AnalogOut.c +msgid "AnalogOut functionality not supported" +msgstr "Bù zhÄ«chí AnalogOut gÅngnéng" + +#: shared-bindings/analogio/AnalogOut.c +msgid "AnalogOut is only 16 bits. Value must be less than 65536." +msgstr "AnalogOut jÇn wèi 16 wèi. Zhí bìxÅ« xiÇŽoyú 65536." + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "AnalogOut not supported on given pin" +msgstr "Wèi zhÄ«chí zhÇdìng de yÇn jiÇŽo AnalogOut" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" +msgstr "Lìng yÄ«gè fÄsòng yÇjÄ«ng jÄ«huó" + +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" +msgstr "ShùzÇ” bìxÅ« bÄohán bàn zìshù (type 'H')" + +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." +msgstr "ShùzÇ” zhí yÄ«nggÄi shì dÄngè zì jié." + +#: supervisor/shared/safe_mode.c +msgid "Attempted heap allocation when MicroPython VM not running.\n" +msgstr "MicroPython VM wèi yùnxíng shí chángshì duÄ« fÄ“npèi.\n" + +#: main.c +msgid "Auto-reload is off.\n" +msgstr "Zìdòng chóngxÄ«n jiÄzài yÇ guÄnbì.\n" + +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "" +"Zìdòng chóngxÄ«n jiÄzài. ZhÇ xÅ« tÅngguò USB bÇŽocún wénjiàn lái yùnxíng tÄmen " +"huò shÅ«rù REPL jìnyòng.\n" + +#: shared-module/displayio/Display.c +msgid "Below minimum frame rate" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Bit clock and word select must share a clock unit" +msgstr "BÇtè shízhÅng hé dÄnzì xuÇŽnzé bìxÅ« gòngxiÇŽng shízhÅng dÄnwèi" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Bit depth must be multiple of 8." +msgstr "BÇtè shÄ“ndù bìxÅ« shì 8 bèi yÇshàng." + +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +msgid "Both pins must support hardware interrupts" +msgstr "LiÇŽng gè yÇn jiÇŽo dÅu bìxÅ« zhÄ«chí yìngjiàn zhÅngduàn" + +#: shared-bindings/displayio/Display.c +msgid "Brightness must be 0-1.0" +msgstr "" + +#: shared-bindings/supervisor/__init__.c +msgid "Brightness must be between 0 and 255" +msgstr "Liàngdù bìxÅ« jiè yú 0 dào 255 zhÄ« jiÄn" + +#: shared-bindings/displayio/Display.c +msgid "Brightness not adjustable" +msgstr "Liàngdù wúfÇŽ tiáozhÄ›ng" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "Buffer incorrect size. Should be %d bytes." +msgstr "HuÇŽnchÅng qÅ« dàxiÇŽo bù zhèngquè. YÄ«nggÄi shì %d zì jié." + +#: shared-bindings/displayio/Display.c +msgid "Buffer is not a bytearray." +msgstr "" + +#: shared-bindings/displayio/Display.c +msgid "Buffer is too small" +msgstr "" + +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Buffer length %d too big. It must be less than %d" +msgstr "" + +#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c +msgid "Buffer must be at least length 1" +msgstr "HuÇŽnchÅng qÅ« bìxÅ« zhìshÇŽo chángdù 1" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +#, c-format +msgid "Bus pin %d is already in use" +msgstr "ZÇ’ngxiàn yÇn jiÇŽo %d yÇ zài shÇyòng zhÅng" + +#: shared-bindings/_bleio/UUID.c +msgid "Byte buffer must be 16 bytes." +msgstr "Zì jié huÇŽnchÅng qÅ« bìxÅ« shì 16 zì jié." + +#: shared-bindings/nvm/ByteArray.c +msgid "Bytes must be between 0 and 255." +msgstr "Zì jié bìxÅ« jiè yú 0 dào 255 zhÄ« jiÄn." + +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." +msgstr "Zài fÇŽngwèn bÄ›n jÄ« wùjiàn zhÄ«qián diàoyòng super().__init__()" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Can not use dotstar with %s" +msgstr "WúfÇŽ yÇ” dotstar yÄ«qÇ shÇyòng %s" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" +msgstr "WúfÇŽ shÄnchú zhí" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/nrf/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "Zài shÅ«chÅ« móshì xià wúfÇŽ huòqÇ” lÄdòng" + +#: ports/nrf/common-hal/microcontroller/Processor.c +msgid "Cannot get temperature" +msgstr "WúfÇŽ huòqÇ” wÄ“ndù" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Cannot output both channels on the same pin" +msgstr "WúfÇŽ shÅ«chÅ« tóng yÄ«gè yÇn jiÇŽo shàng de liÇŽng gè píndào" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot read without MISO pin." +msgstr "WúfÇŽ dòu qÇ” méiyÇ’u MISO de yÇn jiÇŽo." + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Cannot record to a file" +msgstr "WúfÇŽ jìlù dào wénjiàn" + +#: shared-module/storage/__init__.c +msgid "Cannot remount '/' when USB is active." +msgstr "USB jÄ«huó shí wúfÇŽ chóngxÄ«n bÇŽng ding '/'." + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +msgid "Cannot reset into bootloader because no bootloader is present." +msgstr "WúfÇŽ chóng zhì wèi bootloader, yÄ«nwèi méiyÇ’u bootloader cúnzài." + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Cannot set value when direction is input." +msgstr "DÄng fÄngxiàng xiàng nèi shí, bùnéng shèzhì gÄi zhí." + +#: py/objslice.c +msgid "Cannot subclass slice" +msgstr "WúfÇŽ zi fÄ“nlèi" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot transfer without MOSI and MISO pins." +msgstr "MéiyÇ’u MOSI/MISO jiù wúfÇŽ zhuÇŽnyí." + +#: extmod/moductypes.c +msgid "Cannot unambiguously get sizeof scalar" +msgstr "WúfÇŽ míngquè de huòdé biÄoliàng de dàxiÇŽo" + +#: shared-module/bitbangio/SPI.c +msgid "Cannot write without MOSI pin." +msgstr "WúfÇŽ xiÄ› rù MOSI de yÇn jiÇŽo." + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" +msgstr "Wèi tígÅng zìfú huÇŽncún xiÄ› rù" + +#: shared-module/bitbangio/SPI.c +msgid "Clock pin init failed." +msgstr "ShízhÅng de yÇn jiÇŽo chÅ«shÇhuà shÄ«bài." + +#: shared-module/bitbangio/I2C.c +msgid "Clock stretch too long" +msgstr "ShízhÅng shÄ“nzhÇŽn tài zhÇŽng" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" +msgstr "ShÇyòng shízhÅng dÄnwèi" + +#: shared-bindings/_pew/PewPew.c +msgid "Column entry must be digitalio.DigitalInOut" +msgstr "Liè tiáomù bìxÅ« shì digitalio.DigitalInOut" + +#: shared-bindings/displayio/I2CDisplay.c +msgid "Command must be 0-255" +msgstr "Mìnglìng bìxÅ« wèi 0-255" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/ParallelBus.c +msgid "Command must be an int between 0 and 255" +msgstr "Mìnglìng bìxÅ« shì 0 dào 255 zhÄ« jiÄn de int" + +#: py/persistentcode.c +msgid "Corrupt .mpy file" +msgstr "FÇ”bài de .mpy wénjiàn" + +#: py/emitglue.c +msgid "Corrupt raw code" +msgstr "SÇ”nhuài de yuánshÇ dàimÇŽ" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Could not decode ble_uuid, err 0x%04x" +msgstr "WúfÇŽ jiÄ›mÇŽ kÄ› dú_uuid, err 0x%04x" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "Could not initialize UART" +msgstr "WúfÇŽ chÅ«shÇhuà UART" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate first buffer" +msgstr "WúfÇŽ fÄ“npèi dì yÄ« gè huÇŽnchÅng qÅ«" + +#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +msgid "Couldn't allocate second buffer" +msgstr "WúfÇŽ fÄ“npèi dì èr gè huÇŽnchÅng qÅ«" + +#: supervisor/shared/safe_mode.c +msgid "Crash into the HardFault_Handler.\n" +msgstr "BÄ“ngkuì dào HardFault_Handler.\n" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "DAC already in use" +msgstr "FÄ yuán huì yÇjÄ«ng shÇyòng" + +#: ports/atmel-samd/common-hal/displayio/ParallelBus.c +#: ports/nrf/common-hal/displayio/ParallelBus.c +msgid "Data 0 pin must be byte aligned" +msgstr "Shùjù 0 de yÇn jiÇŽo bìxÅ« shì zì jié duìqí" + +#: shared-module/audiocore/WaveFile.c +msgid "Data chunk must follow fmt chunk" +msgstr "Shùjù kuài bìxÅ« zÅ«nxún fmt qÅ« kuài" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Data too large for advertisement packet" +msgstr "GuÇŽnggào bÄo de shùjù tài dà" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Destination capacity is smaller than destination_length." +msgstr "MùbiÄo róngliàng xiÇŽoyú mùdì de_chángdù." + +#: shared-bindings/displayio/Display.c +msgid "Display must have a 16 bit colorspace." +msgstr "" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Display rotation must be in 90 degree increments" +msgstr "XiÇŽnshì xuánzhuÇŽn bìxÅ« 90 dù jiÄ xÄ«n" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Drive mode not used when direction is input." +msgstr "FÄngxiàng shÅ«rù shí qÅ«dòng móshì méiyÇ’u shÇyòng." + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "EXTINT channel already in use" +msgstr "EXTINT píndào yÇjÄ«ng shÇyòng" + +#: extmod/modure.c +msgid "Error in regex" +msgstr "Zhèngzé biÇŽodá shì cuòwù" + +#: shared-bindings/microcontroller/Pin.c +#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c +#: shared-bindings/terminalio/Terminal.c +msgid "Expected a %q" +msgstr "Yùqí %q" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Descriptor.c +msgid "Expected a Characteristic" +msgstr "Yùqí de tèdiÇŽn" + +#: shared-bindings/_bleio/Service.c +msgid "Expected a Peripheral" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Expected a Service" +msgstr "" + +#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c +#: shared-bindings/_bleio/Service.c +msgid "Expected a UUID" +msgstr "Yùqí UUID" + +#: shared-bindings/_bleio/Central.c +msgid "Expected an Address" +msgstr "Qídài yÄ«gè dìzhÇ" + +#: shared-module/_pixelbuf/PixelBuf.c +#, c-format +msgid "Expected tuple of length %d, got %d" +msgstr "QÄ«wàng de chángdù wèi %d de yuán zÇ”, dédào %d" + +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "FÄsòng mìnglìng shÄ«bài." + +#: ports/nrf/sd_mutex.c +#, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "WúfÇŽ huòdé mutex, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Service.c +#, c-format +msgid "Failed to add characteristic, err 0x%04x" +msgstr "TiÄnjiÄ tèxìng shÄ«bài, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to add descriptor, err 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to add service, err 0x%04x" +msgstr "TiÄnjiÄ fúwù shÄ«bài, err 0x%04x" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "Failed to allocate RX buffer" +msgstr "FÄ“npèi RX huÇŽnchÅng shÄ«bài" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +#, c-format +msgid "Failed to allocate RX buffer of %d bytes" +msgstr "FÄ“npèi RX huÇŽnchÅng qÅ«%d zì jié shÄ«bài" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to change softdevice state" +msgstr "GÄ“nggÇŽi ruÇŽn shèbèi zhuàngtài shÄ«bài" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to configure advertising, err 0x%04x" +msgstr "WúfÇŽ pèizhì guÇŽnggào, cuòwù 0x%04x" + +#: ports/nrf/common-hal/_bleio/Central.c +msgid "Failed to connect: timeout" +msgstr "LiánjiÄ“ shÄ«bài: ChÄoshí" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, c-format +msgid "Failed to continue scanning, err 0x%04x" +msgstr "Jìxù sÇŽomiáo shÄ«bài, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "Failed to discover services" +msgstr "FÄxiàn fúwù shÄ«bài" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to get local address" +msgstr "HuòqÇ” bÄ›ndì dìzhÇ shÄ«bài" + +#: ports/nrf/common-hal/_bleio/Adapter.c +msgid "Failed to get softdevice state" +msgstr "WúfÇŽ huòdé ruÇŽnjiàn shèbèi zhuàngtài" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to notify or indicate attribute value, err 0x%04x" +msgstr "WúfÇŽ tÅngzhÄ« huò xiÇŽnshì shÇ”xìng zhí, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +msgid "Failed to pair" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to read CCCD value, err 0x%04x" +msgstr "Dòu qÇ” CCCD zhí, err 0x%04x shÄ«bài" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "Failed to read attribute value, err 0x%04x" +msgstr "Dòu qÇ” shÇ”xìng zhí shÄ«bài, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to read gatts value, err 0x%04x" +msgstr "WúfÇŽ dòu qÇ” gatts zhí, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/UUID.c +#, c-format +msgid "Failed to register Vendor-Specific UUID, err 0x%04x" +msgstr "WúfÇŽ zhùcè màizhÇ” tèdìng de UUID, err 0x%04x" + +#: ports/nrf/sd_mutex.c +#, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "WúfÇŽ shìfàng mutex, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to set device name, err 0x%04x" +msgstr "WúfÇŽ shèzhì shèbèi míngchÄ“ng, cuòwù 0x%04x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start advertising, err 0x%04x" +msgstr "QÇdòng guÇŽnggào shÄ«bài, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Central.c +#, c-format +msgid "Failed to start connecting, error 0x%04x" +msgstr "WúfÇŽ kÄishÇ liánjiÄ“, cuòwù 0x%04x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to start pairing, error 0x%04x" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Scanner.c +#, c-format +msgid "Failed to start scanning, err 0x%04x" +msgstr "QÇdòng sÇŽomiáo shÄ«bài, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Peripheral.c +#, c-format +msgid "Failed to stop advertising, err 0x%04x" +msgstr "WúfÇŽ tíngzhÇ guÇŽnggào, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#, c-format +msgid "Failed to write CCCD, err 0x%04x" +msgstr "WúfÇŽ xiÄ› rù CCCD, cuòwù 0x%04x" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to write attribute value, err 0x%04x" +msgstr "XiÄ› rù shÇ”xìng zhí shÄ«bài, err 0x%04x" + +#: ports/nrf/common-hal/_bleio/__init__.c +#, c-format +msgid "Failed to write gatts value, err 0x%04x" +msgstr "XiÄ› rù gatts zhí,err 0x%04x shÄ«bài" + +#: py/moduerrno.c +msgid "File exists" +msgstr "Wénjiàn cúnzài" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash erase failed" +msgstr "Flash cÄ chú shÄ«bài" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash erase failed to start, err 0x%04x" +msgstr "Flash cÄ chú shÄ«bài, err 0x%04x" + +#: ports/nrf/peripherals/nrf/nvm.c +msgid "Flash write failed" +msgstr "Flash xiÄ› rù shÄ«bài" + +#: ports/nrf/peripherals/nrf/nvm.c +#, c-format +msgid "Flash write failed to start, err 0x%04x" +msgstr "Flash xiÄ› rù shÄ«bài, err 0x%04x" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Frequency captured is above capability. Capture Paused." +msgstr "PínlÇœ bÇ”huò gÄo yú nénglì. BÇ”huò zàntíng." + +#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c +msgid "Function requires lock" +msgstr "Hánshù xÅ«yào suÇ’dìng" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Group already used" +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Group full" +msgstr "FÄ“nzÇ” yÇ mÇŽn" + +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" +msgstr "Wénjiàn shàng de I/ O cÄozuò" + +#: extmod/machine_i2c.c +msgid "I2C operation not supported" +msgstr "I2C cÄozuò bù zhÄ«chí" + +#: py/persistentcode.c +msgid "" +"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" +"mpy-update for more info." +msgstr "" +"Bù jiÄnróng.Mpy wénjiàn. QÇng gÄ“ngxÄ«n suÇ’yÇ’u.Mpy wénjiàn. YÇ’uguÄn xiángxì " +"xìnxÄ«, qÇng cÄnyuè http://Adafru.It/mpy-update." + +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" +msgstr "HuÇŽnchÅng qÅ« dàxiÇŽo bù zhèngquè" + +#: py/moduerrno.c +msgid "Input/output error" +msgstr "ShÅ«rù/shÅ«chÅ« cuòwù" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Invalid %q pin" +msgstr "Wúxiào de %q yÇn jiÇŽo" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Invalid BMP file" +msgstr "Wúxiào de BMP wénjiàn" + +#: ports/atmel-samd/common-hal/pulseio/PWMOut.c +#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c +msgid "Invalid PWM frequency" +msgstr "Wúxiào de PWM pínlÇœ" + +#: py/moduerrno.c +msgid "Invalid argument" +msgstr "Wúxiào de cÄnshù" + +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" +msgstr "MÄ›i gè zhí de wèi wúxiào" + +#: ports/nrf/common-hal/busio/UART.c +msgid "Invalid buffer size" +msgstr "Wúxiào de huÇŽnchÅng qÅ« dàxiÇŽo" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "Invalid capture period. Valid range: 1 - 500" +msgstr "Wúxiào de bÇ”huò zhÅuqí. YÇ’uxiào fànwéi: 1-500" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid channel count" +msgstr "Wúxiào de tÅngdào jìshù" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Invalid direction." +msgstr "Wúxiào de fÄngxiàng." + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid file" +msgstr "Wúxiào de wénjiàn" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" +msgstr "Géshì kuài dàxiÇŽo wúxiào" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid number of bits" +msgstr "Wèi shù wúxiào" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid phase" +msgstr "JiÄ“duàn wúxiào" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +#: shared-bindings/pulseio/PWMOut.c +msgid "Invalid pin" +msgstr "Wúxiào de yÇn jiÇŽo" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for left channel" +msgstr "ZuÇ’ tÅngdào de yÇn jiÇŽo wúxiào" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Invalid pin for right channel" +msgstr "Yòuxián tÅngdào yÇn jiÇŽo wúxiào" + +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/atmel-samd/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/i2cslave/I2CSlave.c +#: ports/nrf/common-hal/busio/I2C.c +msgid "Invalid pins" +msgstr "Wúxiào de yÇn jiÇŽo" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "Invalid polarity" +msgstr "Wúxiào liÇŽng jí zhí" + +#: shared-bindings/_bleio/Characteristic.c +msgid "Invalid properties" +msgstr "" + +#: shared-bindings/microcontroller/__init__.c +msgid "Invalid run mode." +msgstr "Wúxiào de yùnxíng móshì." + +#: shared-module/_bleio/Attribute.c +msgid "Invalid security_mode" +msgstr "" + +#: shared-bindings/audiocore/Mixer.c +msgid "Invalid voice count" +msgstr "Wúxiào de yÇ”yÄ«n jìshù" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid wave file" +msgstr "Wúxiào de làng làngcháo wénjiàn" + +#: py/compile.c +msgid "LHS of keyword arg must be an id" +msgstr "GuÄnjiàn zì arg de LHS bìxÅ« shì id" + +#: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass." +msgstr "Layer bìxÅ« shì Group huò TileGrid zi lèi." + +#: py/objslice.c +msgid "Length must be an int" +msgstr "Chángdù bìxÅ« shì yÄ«gè zhÄ›ngshù" + +#: py/objslice.c +msgid "Length must be non-negative" +msgstr "Chángdù bìxÅ« shìfÄ“i fùshù" + +#: supervisor/shared/safe_mode.c +msgid "" +"Looks like our core CircuitPython code crashed hard. Whoops!\n" +"Please file an issue at https://github.com/adafruit/circuitpython/issues\n" +" with the contents of your CIRCUITPY drive and this message:\n" +msgstr "" +"Kàn lái wÇ’men de héxÄ«n CircuitPython dàimÇŽ bÄ“ngkuì dé hÄ›n lìhài. Ä€i yÅu!\n" +"QÇng zài https://Github.Com/adafruit/circuitpython/issues\n" +"shàng tíjiÄo yÄ«gè wèntí, qízhÅng bÄohán nín de CIRCUITPY qÅ«dòngqì de nèiróng " +"hé cÇ xiÄoxÄ«:\n" + +#: shared-module/bitbangio/SPI.c +msgid "MISO pin init failed." +msgstr "MISO yÇn jiÇŽo chÅ«shÇhuà shÄ«bài." + +#: shared-module/bitbangio/SPI.c +msgid "MOSI pin init failed." +msgstr "MOSI yÇn jiÇŽo shÅ«rù shÄ«bài." + +#: shared-module/displayio/Shape.c +#, c-format +msgid "Maximum x value when mirrored is %d" +msgstr "Jìngxiàng shí de zuìdà X zhí wèi%d" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython NLR jump failed. Likely memory corruption.\n" +msgstr "MicroPython NLR tiàoyuè shÄ«bài. KÄ›néng nèicún fÇ”bài.\n" + +#: supervisor/shared/safe_mode.c +msgid "MicroPython fatal error.\n" +msgstr "MicroPython zhìmìng cuòwù.\n" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Microphone startup delay must be in range 0.0 to 1.0" +msgstr "MàikèfÄ“ng qÇdòng yánchí bìxÅ« zài 0.0 Dào 1.0 De fànwéi nèi" + +#: shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +msgid "No DAC on chip" +msgstr "MéiyÇ’u DAC zài xÄ«npiàn shàng de" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "No DMA channel found" +msgstr "Wèi zhÇŽodào DMA píndào" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No RX pin" +msgstr "Wèi zhÇŽodào RX yÇn jiÇŽo" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "No TX pin" +msgstr "Wèi zhÇŽodào TX yÇn jiÇŽo" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +msgid "No available clocks" +msgstr "MéiyÇ’u kÄ›yòng de shízhÅng" + +#: shared-bindings/board/__init__.c +msgid "No default %q bus" +msgstr "wú mòrèn %q zÇ’ngxiàn" + +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" +msgstr "MéiyÇ’u miÇŽnfèi de GCLKs" + +#: shared-bindings/os/__init__.c +msgid "No hardware random available" +msgstr "MéiyÇ’u kÄ›yòng de yìngjiàn suíjÄ«" + +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "No hardware support on pin" +msgstr "MéiyÇ’u zài yÇn jiÇŽo shàng de yìngjiàn zhÄ«chí" + +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" +msgstr "" + +#: py/moduerrno.c +msgid "No space left on device" +msgstr "Shèbèi shàng méiyÇ’u kònggé" + +#: py/moduerrno.c +msgid "No such file/directory" +msgstr "MéiyÇ’u cÇ lèi wénjiàn/mùlù" + +#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +#: shared-bindings/_bleio/Peripheral.c +msgid "Not connected" +msgstr "Wèi liánjiÄ“" + +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c +msgid "Not playing" +msgstr "Wèi bòfàng" + +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "" +"Duìxiàng yÇjÄ«ng bèi shÄnchú, wúfÇŽ zài shÇyòng. Chuàngjiàn yÄ«gè xÄ«n duìxiàng." + +#: ports/nrf/common-hal/busio/UART.c +msgid "Odd parity is not supported" +msgstr "Bù zhÄ«chí jÄ«shù" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Only 8 or 16 bit mono with " +msgstr "ZhÇyÇ’u 8 huò 16 wèi dÄnwèi " + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" +msgstr "" +"JÇn zhÄ«chí Windows géshì, zhÄ«chí wèi yÄsuÅ de BMP: GÄ›i dìng de biÄo tóu " +"dàxiÇŽo wèi %d" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " +"%d bpp given" +msgstr "" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Only slices with step=1 (aka None) are supported" +msgstr "JÇn zhÄ«chí 1 bù qiÄ“piàn" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "Oversample must be multiple of 8." +msgstr "Guò cÇŽiyàng bìxÅ« shì 8 de bèishù." + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" +msgstr "" +"PWM yìwù zhÅuqí bìxÅ« jiè yú 0 zhì 65535 de bÄoróng xìng (16 wèi fÄ“nbiàn lÇœ)" + +#: shared-bindings/pulseio/PWMOut.c +msgid "" +"PWM frequency not writable when variable_frequency is False on construction." +msgstr "DÄng biànliàng_pínlÇœ shì False zài jiànzhú shí PWM pínlÇœ bùkÄ› xiÄ›." + +#: py/moduerrno.c +msgid "Permission denied" +msgstr "Quánxiàn bèi jùjué" + +#: ports/atmel-samd/common-hal/analogio/AnalogIn.c +#: ports/nrf/common-hal/analogio/AnalogIn.c +msgid "Pin does not have ADC capabilities" +msgstr "Pin méiyÇ’u ADC nénglì" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Pixel beyond bounds of buffer" +msgstr "Xiàngsù chÄochÅ« huÇŽnchÅng qÅ« biÄnjiè" + +#: py/builtinhelp.c +msgid "Plus any modules on the filesystem\n" +msgstr "Zài wénjiàn xìtÇ’ng shàng tiÄnjiÄ rènhé mókuài\n" + +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "Cóng kÅng de Ps2 huÇŽnchÅng qÅ« dànchÅ«" + +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload." +msgstr "Àn xià rènhé jiàn jìnrù REPL. ShÇyòng CTRL-D chóngxÄ«n jiÄzài." + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Pull not used when direction is output." +msgstr "FÄngxiàng shÅ«chÅ« shí Pull méiyÇ’u shÇyòng." + +#: ports/nrf/common-hal/rtc/RTC.c +msgid "RTC calibration is not supported on this board" +msgstr "CÇ bÇŽn bù zhÄ«chí RTC jiàozhÇ”n" + +#: shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" +msgstr "CÇ bÇŽn bù zhÄ«chí RTC" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "Range out of bounds" +msgstr "Fànwéi chÄochÅ« biÄnjiè" + +#: shared-bindings/pulseio/PulseIn.c +msgid "Read-only" +msgstr "ZhÇ dú" + +#: extmod/vfs_fat.c py/moduerrno.c +msgid "Read-only filesystem" +msgstr "ZhÇ dú wénjiàn xìtÇ’ng" + +#: shared-module/displayio/Bitmap.c +msgid "Read-only object" +msgstr "ZhÇ dú duìxiàng" + +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Refresh too soon" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" +msgstr "Bù zhÄ«chí yòu tÅngdào" + +#: shared-bindings/_pew/PewPew.c +msgid "Row entry must be digitalio.DigitalInOut" +msgstr "Xíng xiàng bìxÅ« shì digitalio.DigitalInOut" + +#: main.c +msgid "Running in safe mode! Auto-reload is off.\n" +msgstr "Zài Änquán móshì xià yùnxíng! Zìdòng chóngxÄ«n jiÄzài yÇ guÄnbì.\n" + +#: main.c +msgid "Running in safe mode! Not running saved code.\n" +msgstr "Zài Änquán móshì xià yùnxíng! Bù yùnxíng yÇ bÇŽocún de dàimÇŽ.\n" + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "SDA or SCL needs a pull up" +msgstr "SDA huò SCL xÅ«yào lÄdòng" + +#: shared-bindings/audiocore/Mixer.c +msgid "Sample rate must be positive" +msgstr "CÇŽiyàng lÇœ bìxÅ« wèi zhèng shù" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Sample rate too high. It must be less than %d" +msgstr "CÇŽiyàng lÇœ tài gÄo. TÄ bìxÅ« xiÇŽoyú %d" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" +msgstr "Xùliè huà yÇjÄ«ng shÇyòngguò" + +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." +msgstr "QiÄ“piàn hé zhí bùtóng chángdù." + +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/pulseio/PulseIn.c +msgid "Slices not supported" +msgstr "QiÄ“piàn bù shòu zhÄ«chí" + +#: ports/nrf/common-hal/_bleio/Adapter.c +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "RuÇŽn shèbèi wéihù, id: 0X%08lX, pc: 0X%08lX" + +#: extmod/modure.c +msgid "Splitting with sub-captures" +msgstr "YÇ” zi bÇ”huò fÄ“nliè" + +#: shared-bindings/supervisor/__init__.c +msgid "Stack size must be at least 256" +msgstr "DuÄ«zhàn dàxiÇŽo bìxÅ« zhìshÇŽo 256" + +#: shared-bindings/multiterminal/__init__.c +msgid "Stream missing readinto() or write() method." +msgstr "Liú quÄ“shÇŽo readinto() huò write() fÄngfÇŽ." + +#: supervisor/shared/safe_mode.c +msgid "" +"The CircuitPython heap was corrupted because the stack was too small.\n" +"Please increase stack size limits and press reset (after ejecting " +"CIRCUITPY).\n" +"If you didn't change the stack, then file an issue here with the contents of " +"your CIRCUITPY drive:\n" +msgstr "" +"Yóuyú duÄ«zhàn tài xiÇŽo, huánliú Python rè sÇ”nhuài.\n" +"QÇng zÄ“ngjiÄ duÄ«zhàn chÇcùn xiànzhì, ránhòu chóngxÄ«n shèzhì (zài dànchÅ« " +"CIRCUITPY).\n" +"RúguÇ’ nín méiyÇ’u gÇŽibiàn duÄ«zhàn, qÇng zài cÇ chù tíchÅ« yÄ«gè wèntí, bìng zài " +"rù nín de CIRCUITPY qÅ«dòngqì:\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"The `microcontroller` module was used to boot into safe mode. Press reset to " +"exit safe mode.\n" +msgstr "" +"“WÄ“i kòngzhì qì†mókuài yòng yú qÇdòng Änquán móshì. Àn chóng zhì kÄ› tuìchÅ« " +"Änquán móshì.\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"The microcontroller's power dipped. Please make sure your power supply " +"provides\n" +"enough power for the whole circuit and press reset (after ejecting " +"CIRCUITPY).\n" +msgstr "" +"WÄ“i kòngzhì qì de diànliàng bèi chÅng chÅ«. QÇng quèbÇŽo nín de diànyuán wèi\n" +"zhÄ›nggè diànlù tígÅng zúgòu de diànyuán bìng àn xià fùwèi (zài dànchÅ« " +"CIRCUITPY hòu).\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"The reset button was pressed while booting CircuitPython. Press again to " +"exit safe mode.\n" +msgstr "" +"QÇdòng CircuitPython shí, chóng zhì ànniÇ” bèi àn xià. Zàicì àn xià yÇ tuìchÅ« " +"Änquán móshì\n" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's bits_per_sample does not match the mixer's" +msgstr "YàngbÄ›n de bits_per_sample yÇ” hÇ”n yÄ«n qì bù pÇpèi" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's channel count does not match the mixer's" +msgstr "YàngbÄ›n de píndào jìshù yÇ” hÇ”n yÄ«n qì bù xiÄngfú" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's sample rate does not match the mixer's" +msgstr "YàngbÄ›n de yàngbÄ›n sùdù yÇ” hÇ”n yÄ«n qì de xiÄngchà bù pÇpèi" + +#: shared-module/audiocore/Mixer.c +msgid "The sample's signedness does not match the mixer's" +msgstr "YàngbÄ›n de qiÄnmíng yÇ” hÇ”n yÄ«n qì de qiÄnmíng bù pÇpèi" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" +msgstr "Píng pÅ« gÄodù bìxÅ« huàfÄ“n wèi tú gÄodù" + +#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile value out of bounds" +msgstr "" + +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" +msgstr "Píng pÅ« kuÄndù bìxÅ« huàfÄ“n wèi tú kuÄndù" + +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "Yào tuìchÅ«, qÇng chóng zhì bÇŽnkuài ér bùyòng " + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample." +msgstr "ChÅuyàng zhÅng de píndào tài duÅ." + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "Too many display busses" +msgstr "XiÇŽnshì zÇ’ngxiàn tài duÅle" + +#: shared-bindings/displayio/Display.c +#: shared-bindings/displayio/EPaperDisplay.c +msgid "Too many displays" +msgstr "XiÇŽnshì tài duÅ" + +#: py/obj.c +msgid "Traceback (most recent call last):\n" +msgstr "Traceback (Zuìjìn yÄ«cì dÇŽ diànhuà):\n" + +#: shared-bindings/time/__init__.c +msgid "Tuple or struct_time argument required" +msgstr "XÅ«yào Tuple huò struct_time cÄnshù" + +#: shared-module/usb_hid/Device.c +msgid "USB Busy" +msgstr "USB máng" + +#: shared-module/usb_hid/Device.c +msgid "USB Error" +msgstr "USB Cuòwù" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID integer value must be 0-0xffff" +msgstr "UUID zhÄ›ngshù zhí bìxÅ« wèi 0-0xffff" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "UUID Zìfú chuàn bùshì 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" +msgstr "UUID zhí bùshì str,int huò zì jié huÇŽnchÅng qÅ«" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Unable to allocate buffers for signed conversion" +msgstr "WúfÇŽ fÄ“npèi huÇŽnchÅng qÅ« yòng yú qiÄnmíng zhuÇŽnhuàn" + +#: shared-module/displayio/I2CDisplay.c +#, c-format +msgid "Unable to find I2C Display at %x" +msgstr "WúfÇŽ zài%x zhÇŽodào I2C xiÇŽnshìqì" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Unable to find free GCLK" +msgstr "WúfÇŽ zhÇŽodào miÇŽnfèi de GCLK" + +#: py/parse.c +msgid "Unable to init parser" +msgstr "WúfÇŽ chÅ«shÇ jiÄ›xÄ« qì" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" +msgstr "WúfÇŽ dòu qÇ” sè tiáo shùjù" + +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." +msgstr "WúfÇŽ xiÄ› rù nvm." + +#: ports/nrf/common-hal/_bleio/UUID.c +msgid "Unexpected nrfx uuid type" +msgstr "Yìwài de nrfx uuid lèixíng" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "RHS (yùqí %d, huòdé %d) shàng wèi pÇpèi de xiàngmù." + +#: ports/atmel-samd/common-hal/busio/I2C.c +msgid "Unsupported baudrate" +msgstr "Bù zhÄ«chí de baudrate" + +#: shared-module/displayio/display_core.c +msgid "Unsupported display bus type" +msgstr "Bù zhÄ«chí de gÅnggòng qìchÄ“ lèixíng" + +#: shared-module/audiocore/WaveFile.c +msgid "Unsupported format" +msgstr "Bù zhÄ«chí de géshì" + +#: py/moduerrno.c +msgid "Unsupported operation" +msgstr "Bù zhÄ«chí de cÄozuò" + +#: shared-bindings/digitalio/DigitalInOut.c +msgid "Unsupported pull value." +msgstr "Bù zhÄ«chí de lÄdòng zhí." + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + +#: py/emitnative.c +msgid "Viper functions don't currently support more than 4 arguments" +msgstr "Viper hánshù mùqián bù zhÄ«chí chÄoguò 4 gè cÄnshù" + +#: shared-module/audiocore/Mixer.c +msgid "Voice index too high" +msgstr "YÇ”yÄ«n suÇ’yÇn tài gÄo" + +#: main.c +msgid "WARNING: Your code filename has two extensions\n" +msgstr "JÇnggào: NÇ de dàimÇŽ wénjiàn míng yÇ’u liÇŽng gè kuòzhÇŽn míng\n" + +#: py/builtinhelp.c +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Please visit learn.adafruit.com/category/circuitpython for project guides.\n" +"\n" +"To list built-in modules please do `help(\"modules\")`.\n" +msgstr "" +"HuÄnyíng lái dào Adafruit CircuitPython%s!\n" +"\n" +"QÇng fÇŽngwèn xuéxí. learn.Adafruit.com/category/circuitpython.\n" +"\n" +"Ruò yào liè chÅ« nèizài de mókuài, qÇng qÇng zuò yÇxià `help(\"modules\")`.\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"You are running in safe mode which means something unanticipated happened.\n" +msgstr "" +"NÇ zhèngzài Änquán móshì xià yùnxíng, zhè yì wèi zhuó yìwài fÄshÄ“ng de " +"shìqíng.\n" + +#: supervisor/shared/safe_mode.c +msgid "You requested starting safe mode by " +msgstr "Nín qÇngqiú qÇdòng Änquán móshì " + +#: py/objtype.c +msgid "__init__() should return None" +msgstr "__init__() fÇŽnhuí not" + +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "__Init__() yÄ«nggÄi fÇŽnhuí not, ér bùshì '%s'" + +#: py/objobject.c +msgid "__new__ arg must be a user-type" +msgstr "__new__ cÄnshù bìxÅ« shì yònghù lèixíng" + +#: extmod/modubinascii.c extmod/moduhashlib.c +msgid "a bytes-like object is required" +msgstr "xÅ«yào yÄ«gè zì jié lèi duìxiàng" + +#: lib/embed/abort_.c +msgid "abort() called" +msgstr "zhÅngzhÇ () diàoyòng" + +#: extmod/machine_mem.c +#, c-format +msgid "address %08x is not aligned to %d bytes" +msgstr "wèi zhÇ %08x wèi yÇ” %d wèi yuán zÇ” duìqí" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "address out of bounds" +msgstr "dìzhÇ chÄochÅ« biÄnjiè" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "addresses is empty" +msgstr "dìzhÇ wèi kÅng" + +#: py/modbuiltins.c +msgid "arg is an empty sequence" +msgstr "cÄnshù shì yÄ«gè kÅng de xùliè" + +#: py/runtime.c +msgid "argument has wrong type" +msgstr "cÄnshù lèixíng cuòwù" + +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +msgid "argument num/types mismatch" +msgstr "cÄnshù biÄnhào/lèixíng bù pÇpèi" + +#: py/runtime.c +msgid "argument should be a '%q' not a '%q'" +msgstr "cÄnshù yÄ«nggÄi shì '%q', 'bùshì '%q'" + +#: py/objarray.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" +msgstr "yòu cè xÅ«yào shùzÇ”/zì jié" + +#: py/objstr.c +msgid "attributes not supported yet" +msgstr "shÇ”xìng shàngwèi zhÄ«chí" + +#: py/builtinevex.c +msgid "bad compile mode" +msgstr "biÄnyì móshì cuòwù" + +#: py/objstr.c +msgid "bad conversion specifier" +msgstr "cuòwù zhuÇŽnhuàn biÄozhù" + +#: py/objstr.c +msgid "bad format string" +msgstr "géshì cuòwù zìfú chuàn" + +#: py/binary.c +msgid "bad typecode" +msgstr "cuòwù de dàimÇŽ lèixíng" + +#: py/emitnative.c +msgid "binary op %q not implemented" +msgstr "èrjìnzhì bÇŽn qián bÇŽn %q wèi zhíxíng" + +#: shared-bindings/busio/UART.c +msgid "bits must be 7, 8 or 9" +msgstr "bÇtè bìxÅ« shì 7,8 huò 9" + +#: extmod/machine_spi.c +msgid "bits must be 8" +msgstr "bÇtè bìxÅ« shì 8" + +#: shared-bindings/audiocore/Mixer.c +msgid "bits_per_sample must be 8 or 16" +msgstr "mÄ›i jiàn yàngbÄ›n bìxÅ« wèi 8 huò 16" + +#: py/emitinlinethumb.c +msgid "branch not in range" +msgstr "fÄ“nzhÄ« bùzài fànwéi nèi" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "buf is too small. need %d bytes" +msgstr "huÇŽnchÅng tài xiÇŽo. XÅ«yào%d zì jié" + +#: shared-bindings/audiocore/RawSample.c +msgid "buffer must be a bytes-like object" +msgstr "huÇŽnchÅng qÅ« bìxÅ« shì zì jié lèi duìxiàng" + +#: shared-module/struct/__init__.c +msgid "buffer size must match format" +msgstr "huÇŽnchÅng qÅ« dàxiÇŽo bìxÅ« pÇpèi géshì" + +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" +msgstr "huÇŽnchÅng qÅ« qiÄ“piàn bìxÅ« chángdù xiÄngdÄ›ng" + +#: py/modstruct.c shared-bindings/struct/__init__.c +#: shared-module/struct/__init__.c +msgid "buffer too small" +msgstr "huÇŽnchÅng qÅ« tài xiÇŽo" + +#: extmod/machine_spi.c +msgid "buffers must be the same length" +msgstr "huÇŽnchÅng qÅ« bìxÅ« shì chángdù xiÄngtóng" + +#: shared-bindings/_pew/PewPew.c +msgid "buttons must be digitalio.DigitalInOut" +msgstr "ànniÇ” bìxÅ« shì digitalio.DigitalInOut" + +#: py/vm.c +msgid "byte code not implemented" +msgstr "zì jié dàimÇŽ wèi zhíxíng" + +#: shared-bindings/_pixelbuf/PixelBuf.c +#, c-format +msgid "byteorder is not an instance of ByteOrder (got a %s)" +msgstr "zì jié bùshì zì jié xù shílì (yÇ’u %s)" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "bytes > 8 bits not supported" +msgstr "zì jié > 8 wèi" + +#: py/objstr.c +msgid "bytes value out of range" +msgstr "zì jié zhí chÄochÅ« fànwéi" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" +msgstr "jiàozhÇ”n fànwéi chÄochÅ« fànwéi" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" +msgstr "jiàozhÇ”n zhÇ dú dào" + +#: ports/atmel-samd/common-hal/rtc/RTC.c +msgid "calibration value out of range +/-127" +msgstr "jiàozhÇ”n zhí chÄochÅ« fànwéi +/-127" + +#: py/emitinlinethumb.c +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "zhÇyÇ’u Thumb zÇ”jiàn zuìduÅ 4 cÄnshù" + +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "zhÇyÇ’u Xtensa zÇ”jiàn zuìduÅ 4 cÄnshù" + +#: py/persistentcode.c +msgid "can only save bytecode" +msgstr "zhÇ néng bÇŽocún zì jié mÇŽ jìlù" + +#: py/objtype.c +msgid "can't add special method to already-subclassed class" +msgstr "wúfÇŽ tiÄnjiÄ tèshÅ« fÄngfÇŽ dào zi fÄ“nlèi lèi" + +#: py/compile.c +msgid "can't assign to expression" +msgstr "bùnéng fÄ“npèi dào biÇŽodá shì" + +#: py/obj.c +#, c-format +msgid "can't convert %s to complex" +msgstr "wúfÇŽ zhuÇŽnhuàn%s dào fùzá" + +#: py/obj.c +#, c-format +msgid "can't convert %s to float" +msgstr "wúfÇŽ zhuÇŽnhuàn %s dào fú diÇŽn xíng biànliàng" + +#: py/obj.c +#, c-format +msgid "can't convert %s to int" +msgstr "wúfÇŽ zhuÇŽnhuàn%s dào int" + +#: py/objstr.c +msgid "can't convert '%q' object to %q implicitly" +msgstr "wúfÇŽ jiÄng '%q' duìxiàng zhuÇŽnhuàn wèi %q yÇn hán" + +#: py/objint.c +msgid "can't convert NaN to int" +msgstr "wúfÇŽ jiÄng dÇŽoháng zhuÇŽnhuàn wèi int" + +#: shared-bindings/i2cslave/I2CSlave.c +msgid "can't convert address to int" +msgstr "wúfÇŽ jiÄng dìzhÇ zhuÇŽnhuàn wèi int" + +#: py/objint.c +msgid "can't convert inf to int" +msgstr "bùnéng jiÄng inf zhuÇŽnhuàn wèi int" + +#: py/obj.c +msgid "can't convert to complex" +msgstr "bùnéng zhuÇŽnhuàn wèi fùzá" + +#: py/obj.c +msgid "can't convert to float" +msgstr "bùnéng zhuÇŽnhuàn wèi fú diÇŽn" + +#: py/obj.c +msgid "can't convert to int" +msgstr "bùnéng zhuÇŽnhuàn wèi int" + +#: py/objstr.c +msgid "can't convert to str implicitly" +msgstr "bùnéng mò shì zhuÇŽnhuàn wèi str" + +#: py/compile.c +msgid "can't declare nonlocal in outer code" +msgstr "wúfÇŽ zàiwài dàimÇŽ zhÅng shÄ“ngmíng fÄ“i bÄ›ndì" + +#: py/compile.c +msgid "can't delete expression" +msgstr "bùnéng shÄnchú biÇŽodá shì" + +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" +msgstr "bùnéng zài '%q' hé '%q' zhÄ« jiÄn jìnxíng èr yuán yùnsuàn" + +#: py/objcomplex.c +msgid "can't do truncated division of a complex number" +msgstr "bùnéng fÄ“njiÄ› fùzá de shùzì" + +#: py/compile.c +msgid "can't have multiple **x" +msgstr "wúfÇŽ yÇ’u duÅ gè **x" + +#: py/compile.c +msgid "can't have multiple *x" +msgstr "wúfÇŽ yÇ’u duÅ gè *x" + +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "bùnéng yÇn hán de jiÄng '%q' zhuÇŽnhuàn wèi 'bool'" + +#: py/emitnative.c +msgid "can't load from '%q'" +msgstr "wúfÇŽ cóng '%q' jiÄzài" + +#: py/emitnative.c +msgid "can't load with '%q' index" +msgstr "wúfÇŽ yòng '%q' ' suÇ’yÇn jiÄzài" + +#: py/objgenerator.c +msgid "can't pend throw to just-started generator" +msgstr "bùnéng bÇŽ tÄ rÄ“ng dào gÄng qÇdòng de fÄ diànjÄ« shàng" + +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" +msgstr "wúfÇŽ xiàng gÄnggÄng qÇdòng de shÄ“ngchéng qì fÄsòng fÄ“i zhí" + +#: py/objnamedtuple.c +msgid "can't set attribute" +msgstr "wúfÇŽ shèzhì shÇ”xìng" + +#: py/emitnative.c +msgid "can't store '%q'" +msgstr "wúfÇŽ cúnchú '%q'" + +#: py/emitnative.c +msgid "can't store to '%q'" +msgstr "bùnéng cúnchú dào'%q'" + +#: py/emitnative.c +msgid "can't store with '%q' index" +msgstr "bùnéng cúnchú '%q' suÇ’yÇn" + +#: py/objstr.c +msgid "" +"can't switch from automatic field numbering to manual field specification" +msgstr "wúfÇŽ zìdòng zìduàn biÄnhào gÇŽi wèi shÇ’udòng zìduàn guÄ«gé" + +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "wúfÇŽ cóng shÇ’udòng zìduàn guÄ«gé qiÄ“huàn dào zìdòng zìduàn biÄnhào" + +#: py/objtype.c +msgid "cannot create '%q' instances" +msgstr "wúfÇŽ chuàngjiàn '%q' ' shílì" + +#: py/objtype.c +msgid "cannot create instance" +msgstr "wúfÇŽ chuàngjiàn shílì" + +#: py/runtime.c +msgid "cannot import name %q" +msgstr "wúfÇŽ dÇŽorù míngchÄ“ng %q" + +#: py/builtinimport.c +msgid "cannot perform relative import" +msgstr "wúfÇŽ zhíxíng xiÄngguÄn dÇŽorù" + +#: py/emitnative.c +msgid "casting" +msgstr "tóuyÇng" + +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" +msgstr "zìfú huÇŽnchÅng qÅ« tài xiÇŽo" + +#: py/modbuiltins.c +msgid "chr() arg not in range(0x110000)" +msgstr "chr() cÄn shÇ” bùzài fànwéi (0x110000)" + +#: py/modbuiltins.c +msgid "chr() arg not in range(256)" +msgstr "chr() cÄn shÇ” bùzài fànwéi (256)" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "" +"yánsè huÇŽnchÅng qÅ« bìxÅ« wèi 3 zì jié (RGB) huò 4 zì jié (RGB + pad zì jié)" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer or int" +msgstr "yánsè huÇŽnchÅng qÅ« bìxÅ« shì huÇŽnchÅng qÅ« huò zhÄ›ngshù" + +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +msgstr "" +"yánsè huÇŽnchÅng qÅ« bìxÅ« shì zì jié shùzÇ” huò lèixíng wèi 'b' huò 'B' de shùzÇ”" + +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" +msgstr "yánsè bìxÅ« jiè yú 0x000000 hé 0xffffff zhÄ« jiÄn" + +#: shared-bindings/displayio/ColorConverter.c +msgid "color should be an int" +msgstr "yánsè yÄ«ng wèi zhÄ›ngshù" + +#: py/objcomplex.c +msgid "complex division by zero" +msgstr "fùzá de fÄ“ngé wèi 0" + +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" +msgstr "bù zhÄ«chí fùzá de zhí" + +#: extmod/moduzlib.c +msgid "compression header" +msgstr "yÄsuÅ tóu bù" + +#: py/parse.c +msgid "constant must be an integer" +msgstr "chángshù bìxÅ« shì yÄ«gè zhÄ›ngshù" + +#: py/emitnative.c +msgid "conversion to object" +msgstr "zhuÇŽnhuàn wèi duìxiàng" + +#: py/parsenum.c +msgid "decimal numbers not supported" +msgstr "bù zhÄ«chí xiÇŽoshù shù" + +#: py/compile.c +msgid "default 'except' must be last" +msgstr "mòrèn 'except' bìxÅ« shì zuìhòu yÄ«gè" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" +"mùbiÄo huÇŽnchÅng qÅ« bìxÅ« shì zì yÇŽnlèi huò lèixíng 'B' wèi wèi shÄ“ndù = 8" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "mùbiÄo huÇŽnchÅng qÅ« bìxÅ« shì wèi shÄ“ndù'H' lèixíng de shùzÇ” = 16" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination_length must be an int >= 0" +msgstr "mùbiÄo chángdù bìxÅ« shì > = 0 de zhÄ›ngshù" + +#: py/objdict.c +msgid "dict update sequence has wrong length" +msgstr "yÇ”fÇŽ gÄ“ngxÄ«n xùliè de chángdù cuòwù" + +#: py/modmath.c py/objfloat.c py/objint_longlong.c py/objint_mpz.c py/runtime.c +#: shared-bindings/math/__init__.c +msgid "division by zero" +msgstr "bèi líng chú" + +#: py/objdeque.c +msgid "empty" +msgstr "kòngxián" + +#: extmod/moduheapq.c extmod/modutimeq.c +msgid "empty heap" +msgstr "kÅng yÄ«n yÄ«nxiào" + +#: py/objstr.c +msgid "empty separator" +msgstr "kÅng fÄ“ngé fú" + +#: shared-bindings/random/__init__.c +msgid "empty sequence" +msgstr "kÅng xùliè" + +#: py/objstr.c +msgid "end of format while looking for conversion specifier" +msgstr "xúnzhÇŽo zhuÇŽnhuàn biÄozhù géshì de jiéshù" + +#: shared-bindings/displayio/Shape.c +msgid "end_x should be an int" +msgstr "jiéwÄ›i_x yÄ«nggÄi shì yÄ«gè zhÄ›ngshù" + +#: ports/nrf/common-hal/busio/UART.c +#, c-format +msgid "error = 0x%08lX" +msgstr "cuòwù = 0x%08lX" + +#: py/runtime.c +msgid "exceptions must derive from BaseException" +msgstr "lìwài bìxÅ« láizì BaseException" + +#: py/objstr.c +msgid "expected ':' after format specifier" +msgstr "zài géshì shuÅmíng fú zhÄ«hòu yùqí ':'" + +#: py/obj.c +msgid "expected tuple/list" +msgstr "yùqí de yuán zÇ”/lièbiÇŽo" + +#: py/modthread.c +msgid "expecting a dict for keyword args" +msgstr "qídài guÄnjiàn zì cÄn shÇ” de zìdiÇŽn" + +#: py/compile.c +msgid "expecting an assembler instruction" +msgstr "qídài zhuÄngpèi zhÇlìng" + +#: py/compile.c +msgid "expecting just a value for set" +msgstr "jÇn qídài shèzhì de zhí" + +#: py/compile.c +msgid "expecting key:value for dict" +msgstr "qídài guÄnjiàn: ZìdiÇŽn de jiàzhí" + +#: py/argcheck.c +msgid "extra keyword arguments given" +msgstr "éwài de guÄnjiàn cí cÄnshù" + +#: py/argcheck.c +msgid "extra positional arguments given" +msgstr "gÄ›i chÅ«le éwài de wèizhì cÄnshù" + +#: shared-bindings/audiocore/WaveFile.c +#: shared-bindings/displayio/OnDiskBitmap.c +msgid "file must be a file opened in byte mode" +msgstr "wénjiàn bìxÅ« shì zài zì jié móshì xià dÇŽkÄi de wénjiàn" + +#: shared-bindings/storage/__init__.c +msgid "filesystem must provide mount method" +msgstr "wénjiàn xìtÇ’ng bìxÅ« tígÅng guà zài fÄngfÇŽ" + +#: py/objtype.c +msgid "first argument to super() must be type" +msgstr "chÄojí () de dì yÄ« gè cÄnshù bìxÅ« shì lèixíng" + +#: extmod/machine_spi.c +msgid "firstbit must be MSB" +msgstr "dì yÄ« wèi bìxÅ« shì MSB" + +#: py/objint.c +msgid "float too big" +msgstr "fú diÇŽn tài dà" + +#: shared-bindings/_stage/Text.c +msgid "font must be 2048 bytes long" +msgstr "zìtÇ bìxÅ« wèi 2048 zì jié" + +#: py/objstr.c +msgid "format requires a dict" +msgstr "géshì yÄoqiú yÄ«gè yÇ”jù" + +#: py/objdeque.c +msgid "full" +msgstr "chÅngfèn" + +#: py/argcheck.c +msgid "function does not take keyword arguments" +msgstr "hánshù méiyÇ’u guÄnjiàn cí cÄnshù" + +#: py/argcheck.c +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "hánshù yùjì zuìduÅ %d cÄnshù, huòdé %d" + +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" +msgstr "hánshù huòdé cÄnshù '%q' de duÅchóng zhí" + +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" +msgstr "hánshù diÅ«shÄ« %d suÇ’ xÅ« wèizhì cÄnshù" + +#: py/bc.c +msgid "function missing keyword-only argument" +msgstr "hánshù quÄ“shÇŽo guÄnjiàn zì cÄnshù" + +#: py/bc.c +msgid "function missing required keyword argument '%q'" +msgstr "hánshù quÄ“shÇŽo suÇ’ xÅ« guÄnjiàn zì cÄnshù '%q'" + +#: py/bc.c +#, c-format +msgid "function missing required positional argument #%d" +msgstr "hánshù quÄ“shÇŽo suÇ’ xÅ« de wèizhì cÄnshù #%d" + +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "hánshù xÅ«yào %d gè wèizhì cÄnshù, dàn %d bèi gÄ›i chÅ«" + +#: shared-bindings/time/__init__.c +msgid "function takes exactly 9 arguments" +msgstr "hánshù xÅ«yào wánquán 9 zhÇ’ng cÄnshù" + +#: py/objgenerator.c +msgid "generator already executing" +msgstr "shÄ“ngchéng qì yÇjÄ«ng zhíxíng" + +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" +msgstr "shÄ“ngchéng qì hÅ«lüè shÄ“ngchéng qì tuìchÅ«" + +#: shared-bindings/_stage/Layer.c +msgid "graphic must be 2048 bytes long" +msgstr "túxíng bìxÅ« wèi 2048 zì jié" + +#: extmod/moduheapq.c +msgid "heap must be a list" +msgstr "duÄ« bìxÅ« shì yÄ«gè lièbiÇŽo" + +#: py/compile.c +msgid "identifier redefined as global" +msgstr "biÄozhì fú chóngxÄ«n dìngyì wèi quánjú" + +#: py/compile.c +msgid "identifier redefined as nonlocal" +msgstr "biÄozhì fú chóngxÄ«n dìngyì wéi fÄ“i bÄ›ndì" + +#: py/objstr.c +msgid "incomplete format" +msgstr "géshì bù wánzhÄ›ng" + +#: py/objstr.c +msgid "incomplete format key" +msgstr "géshì bù wánzhÄ›ng de mì yào" + +#: extmod/modubinascii.c +msgid "incorrect padding" +msgstr "bù zhèngquè de tiánchÅng" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c py/obj.c +msgid "index out of range" +msgstr "suÇ’yÇn chÄochÅ« fànwéi" + +#: py/obj.c +msgid "indices must be integers" +msgstr "suÇ’yÇn bìxÅ« shì zhÄ›ngshù" + +#: py/compile.c +msgid "inline assembler must be a function" +msgstr "nèi lián jíhé bìxÅ« shì yÄ«gè hánshù" + +#: py/parsenum.c +msgid "int() arg 2 must be >= 2 and <= 36" +msgstr "zhÄ›ngshù() cÄnshù 2 bìxÅ« > = 2 qiÄ› <= 36" + +#: py/objstr.c +msgid "integer required" +msgstr "xÅ«yào zhÄ›ngshù" + +#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c +#, c-format +msgid "interval must be in range %s-%s" +msgstr "Jiàngé bìxÅ« zài %s-%s fànwéi nèi" + +#: extmod/machine_i2c.c +msgid "invalid I2C peripheral" +msgstr "wúxiào de I2C wàiwéi qì" + +#: extmod/machine_spi.c +msgid "invalid SPI peripheral" +msgstr "wúxiào de SPI wàiwéi qì" + +#: lib/netutils/netutils.c +msgid "invalid arguments" +msgstr "wúxiào de cÄnshù" + +#: extmod/modussl_axtls.c +msgid "invalid cert" +msgstr "zhèngshÅ« wúxiào" + +#: extmod/uos_dupterm.c +msgid "invalid dupterm index" +msgstr "dupterm suÇ’yÇn wúxiào" + +#: extmod/modframebuf.c +msgid "invalid format" +msgstr "wúxiào géshì" + +#: py/objstr.c +msgid "invalid format specifier" +msgstr "wúxiào de géshì biÄozhù" + +#: extmod/modussl_axtls.c +msgid "invalid key" +msgstr "wúxiào de mì yào" + +#: py/compile.c +msgid "invalid micropython decorator" +msgstr "wúxiào de MicroPython zhuÄngshì qì" + +#: shared-bindings/random/__init__.c +msgid "invalid step" +msgstr "wúxiào bùzhòu" + +#: py/compile.c py/parse.c +msgid "invalid syntax" +msgstr "wúxiào de yÇ”fÇŽ" + +#: py/parsenum.c +msgid "invalid syntax for integer" +msgstr "zhÄ›ngshù wúxiào de yÇ”fÇŽ" + +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "jÄ«shù wèi %d de zhÄ›ng shÇ” de yÇ”fÇŽ wúxiào" + +#: py/parsenum.c +msgid "invalid syntax for number" +msgstr "wúxiào de hàomÇŽ yÇ”fÇŽ" + +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" +msgstr "issubclass() cÄnshù 1 bìxÅ« shì yÄ«gè lèi" + +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "issubclass() cÄnshù 2 bìxÅ« shì lèi de lèi huò yuán zÇ”" + +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "" +"tiÄnjiÄ yÄ«gè fúhé zìshÄ“n duìxiàng de zìfú chuàn/zì jié duìxiàng lièbiÇŽo" + +#: py/argcheck.c +msgid "keyword argument(s) not yet implemented - use normal args instead" +msgstr "guÄnjiàn zì cÄnshù shàngwèi shíxiàn - qÇng shÇyòng chángguÄ« cÄnshù" + +#: py/bc.c +msgid "keywords must be strings" +msgstr "guÄnjiàn zì bìxÅ« shì zìfú chuàn" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" +msgstr "biÄoqiÄn '%q' wèi dìngyì" + +#: py/compile.c +msgid "label redefined" +msgstr "biÄoqiÄn chóngxÄ«n dìngyì" + +#: py/stream.c +msgid "length argument not allowed for this type" +msgstr "bù yÇ”nxÇ” gÄi lèixíng de chángdù cÄnshù" + +#: py/objarray.c +msgid "lhs and rhs should be compatible" +msgstr "lhs hé rhs yÄ«nggÄi jiÄnróng" + +#: py/emitnative.c +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "bendì '%q' bÄohán lèixíng '%q' dàn yuán shì '%q'" + +#: py/emitnative.c +msgid "local '%q' used before type known" +msgstr "bÄ›ndì '%q' zài zhÄ« lèixíng zhÄ«qián shÇyòng" + +#: py/vm.c +msgid "local variable referenced before assignment" +msgstr "fùzhí qián yÇnyòng de júbù biànliàng" + +#: py/objint.c +msgid "long int not supported in this build" +msgstr "cÇ bÇŽnbÄ›n bù zhÄ«chí zhÇŽng zhÄ›ngshù" + +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" +msgstr "dìtú huÇŽnchÅng qÅ« tài xiÇŽo" + +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" +msgstr "shùxué yù cuòwù" + +#: ports/nrf/common-hal/_bleio/Characteristic.c +#: ports/nrf/common-hal/_bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" + +#: py/runtime.c +msgid "maximum recursion depth exceeded" +msgstr "chÄochÅ« zuìdà dìguÄ« shÄ“ndù" + +#: py/runtime.c +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "nèicún fÄ“npèi shÄ«bài, fÄ“npèi %u zì jié" + +#: py/runtime.c +msgid "memory allocation failed, heap is locked" +msgstr "jìyì tÇ fÄ“npèi shÄ«bài, duÄ« bèi suÇ’dìng" + +#: py/builtinimport.c +msgid "module not found" +msgstr "zhÇŽo bù dào mókuài" + +#: py/compile.c +msgid "multiple *x in assignment" +msgstr "duÅ gè*x zài zuòyè zhÅng" + +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" +msgstr "duÅ gè jÄ«dì yÇ’u shílì bùjú chÅngtú" + +#: py/objtype.c +msgid "multiple inheritance not supported" +msgstr "bù zhÄ«chí duÅ gè jìchéng" + +#: py/emitnative.c +msgid "must raise an object" +msgstr "bìxÅ« tíchÅ« duìxiàng" + +#: extmod/machine_spi.c +msgid "must specify all of sck/mosi/miso" +msgstr "bìxÅ« zhÇdìng suÇ’yÇ’u sck/mosi/misco" + +#: py/modbuiltins.c +msgid "must use keyword argument for key function" +msgstr "bìxÅ« shÇyòng guÄnjiàn cí cÄnshù" + +#: py/runtime.c +msgid "name '%q' is not defined" +msgstr "míngchÄ“ng '%q' wèi dìngyì" + +#: shared-bindings/_bleio/Peripheral.c +msgid "name must be a string" +msgstr "míngchÄ“ng bìxÅ« shì yÄ«gè zìfú chuàn" + +#: py/runtime.c +msgid "name not defined" +msgstr "míngchÄ“ng wèi dìngyì" + +#: py/compile.c +msgid "name reused for argument" +msgstr "cÄn shÇ” míngchÄ“ng bèi chóngxÄ«n shÇyòng" + +#: py/emitnative.c +#, fuzzy +msgid "native yield" +msgstr "yuánshÄ“ng chÇŽnliàng" + +#: py/runtime.c +#, c-format +msgid "need more than %d values to unpack" +msgstr "xÅ«yào chÄoguò%d de zhí cáinéng jiÄ›dú" + +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" +msgstr "méiyÇ’u fú diÇŽn zhÄ«chí de xiÄojí gÅnglÇœ" + +#: py/objint_mpz.c py/runtime.c +msgid "negative shift count" +msgstr "fù zhuÇŽnyí jìshù" + +#: py/vm.c +msgid "no active exception to reraise" +msgstr "méiyÇ’u jÄ«huó de yìcháng lái chóngxÄ«n píngjià" + +#: shared-bindings/socket/__init__.c shared-module/network/__init__.c +msgid "no available NIC" +msgstr "méiyÇ’u kÄ›yòng de NIC" + +#: py/compile.c +msgid "no binding for nonlocal found" +msgstr "zhÇŽo bù dào fÄ“i bÄ›ndì de bÇŽng dìng" + +#: py/builtinimport.c +msgid "no module named '%q'" +msgstr "méiyÇ’u mókuài '%q'" + +#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c +#: shared-bindings/displayio/ParallelBus.c +msgid "no reset pin available" +msgstr "" + +#: py/runtime.c shared-bindings/_pixelbuf/__init__.c +msgid "no such attribute" +msgstr "méiyÇ’u cÇ shÇ”xìng" + +#: ports/nrf/common-hal/_bleio/__init__.c +msgid "non-UUID found in service_uuids_whitelist" +msgstr "" + +#: py/compile.c +msgid "non-default argument follows default argument" +msgstr "bùshì mòrèn cÄnshù zÅ«nxún mòrèn cÄnshù" + +#: extmod/modubinascii.c +msgid "non-hex digit found" +msgstr "zhÇŽodào fÄ“i shíliù jìn zhì shùzì" + +#: py/compile.c +msgid "non-keyword arg after */**" +msgstr "zài */** zhÄ«hòu fÄ“i guÄnjiàn cí cÄnshù" + +#: py/compile.c +msgid "non-keyword arg after keyword arg" +msgstr "guÄnjiàn zì cÄnshù zhÄ«hòu de fÄ“i guÄnjiàn zì cÄnshù" + +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" +msgstr "bùshì 128 wèi UUID" + +#: py/objstr.c +msgid "not all arguments converted during string formatting" +msgstr "bùshì zì chuàn géshì huà guòchéng zhÅng zhuÇŽnhuàn de suÇ’yÇ’u cÄnshù" + +#: py/objstr.c +msgid "not enough arguments for format string" +msgstr "géshì zìfú chuàn cÄn shÇ” bùzú" + +#: py/obj.c +#, c-format +msgid "object '%s' is not a tuple or list" +msgstr "duìxiàng '%s' bùshì yuán zÇ” huò lièbiÇŽo" + +#: py/obj.c +msgid "object does not support item assignment" +msgstr "duìxiàng bù zhÄ«chí xiàngmù fÄ“npèi" + +#: py/obj.c +msgid "object does not support item deletion" +msgstr "duìxiàng bù zhÄ«chí shÄnchú xiàngmù" + +#: py/obj.c +msgid "object has no len" +msgstr "duìxiàng méiyÇ’u chángdù" + +#: py/obj.c +msgid "object is not subscriptable" +msgstr "duìxiàng bùnéng xià biÄo" + +#: py/runtime.c +msgid "object not an iterator" +msgstr "duìxiàng bùshì diédài qì" + +#: py/objtype.c py/runtime.c +msgid "object not callable" +msgstr "duìxiàng wúfÇŽ diàoyòng" + +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" +msgstr "duìxiàng bùshì xùliè" + +#: py/runtime.c +msgid "object not iterable" +msgstr "duìxiàng bùnéng diédài" + +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" +msgstr "lèixíng '%s' de duìxiàng méiyÇ’u chángdù" + +#: py/obj.c +msgid "object with buffer protocol required" +msgstr "xÅ«yào huÇŽnchÅng qÅ« xiéyì de duìxiàng" + +#: extmod/modubinascii.c +msgid "odd-length string" +msgstr "jÄ«shù zìfú chuàn" + +#: py/objstr.c py/objstrunicode.c +msgid "offset out of bounds" +msgstr "piÄnlí biÄnjiè" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nrf/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" + +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" +msgstr "jÇn zhÄ«chí bù zhÇŽng = 1(jí wú) de qiÄ“piàn" + +#: py/modbuiltins.c +msgid "ord expects a character" +msgstr "ord yùqí zìfú" + +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "ord() yùqí zìfú, dàn chángdù zìfú chuàn %d" + +#: py/objint_mpz.c +msgid "overflow converting long int to machine word" +msgstr "chÄo gÄo zhuÇŽnhuàn zhÇŽng zhÄ›ng shùzì shí" + +#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c +msgid "palette must be 32 bytes long" +msgstr "yánsè bìxÅ« shì 32 gè zì jié" + +#: shared-bindings/displayio/Palette.c +msgid "palette_index should be an int" +msgstr "yánsè suÇ’yÇn yÄ«nggÄi shì yÄ«gè zhÄ›ngshù" + +#: py/compile.c +msgid "parameter annotation must be an identifier" +msgstr "cÄnshù zhùshì bìxÅ« shì biÄozhì fú" + +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" +msgstr "cÄnshù bìxÅ« shì xùliè a2 zhì a5 de dÄ“ngjì shù" + +#: py/emitinlinethumb.c +msgid "parameters must be registers in sequence r0 to r3" +msgstr "cÄnshù bìxÅ« shì xùliè r0 zhì r3 de dÄ“ngjì qì" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel coordinates out of bounds" +msgstr "xiàngsù zuòbiÄo chÄochÅ« biÄnjiè" + +#: shared-bindings/displayio/Bitmap.c +msgid "pixel value requires too many bits" +msgstr "xiàngsù zhí xÅ«yào tài duÅ wèi" + +#: shared-bindings/displayio/TileGrid.c +msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" +msgstr "pixel_shader bìxÅ« shì displayio.Palette huò displayio.ColorConverter" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/nrf/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" +msgstr "cóng kÅng de PulseIn dànchÅ« dànchÅ«" + +#: py/objset.c +msgid "pop from an empty set" +msgstr "cóng kÅng jí dànchÅ«" + +#: py/objlist.c +msgid "pop from empty list" +msgstr "cóng kÅng lièbiÇŽo zhòng dànchÅ«" + +#: py/objdict.c +msgid "popitem(): dictionary is empty" +msgstr "dànchÅ« xiàngmù (): ZìdiÇŽn wèi kÅng" + +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" +msgstr "pow() 3 cÄn shÇ” bùnéng wéi 0" + +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" +msgstr "pow() yÇ’u 3 cÄnshù xÅ«yào zhÄ›ngshù" + +#: extmod/modutimeq.c +msgid "queue overflow" +msgstr "duìliè yìchÅ«" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "rawbuf is not the same size as buf" +msgstr "yuánshÇ huÇŽnchÅng qÅ« hé huÇŽnchÅng qÅ« de dàxiÇŽo bùtóng" + +#: shared-bindings/_pixelbuf/__init__.c +msgid "readonly attribute" +msgstr "zhÇ dú shÇ”xìng" + +#: py/builtinimport.c +msgid "relative import" +msgstr "xiÄngduì dÇŽorù" + +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" +msgstr "qÇngqiú chángdù %d dàn duìxiàng chángdù %d" + +#: py/compile.c +msgid "return annotation must be an identifier" +msgstr "fÇŽnhuí zhùshì bìxÅ« shì biÄozhì fú" + +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" +msgstr "fÇŽnhuí yùqí de '%q' dàn huòdéle '%q'" + +#: py/objstr.c +msgid "rsplit(None,n)" +msgstr "" + +#: shared-bindings/audiocore/RawSample.c +msgid "" +"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " +"'B'" +msgstr "" +"yàngbÄ›n yuán_yuán huÇŽnchÅng qÅ« bìxÅ« shì zì yÇŽnlèi huò lèixíng 'h', 'H', 'b' " +"huò 'B' de shùzÇ”" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" +msgstr "qÇ”yàng lÇœ chÄochÅ« fànwéi" + +#: py/modmicropython.c +msgid "schedule stack full" +msgstr "jìhuà duÄ«zhàn yÇ mÇŽn" + +#: lib/utils/pyexec.c py/builtinimport.c +msgid "script compilation not supported" +msgstr "bù zhÄ«chí jiÇŽobÄ›n biÄnyì" + +#: py/objstr.c +msgid "sign not allowed in string format specifier" +msgstr "zìfú chuàn géshì shuÅmíng fú zhÅng bù yÇ”nxÇ” shÇyòng fúhào" + +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" +msgstr "zhÄ›ngshù géshì shuÅmíng fú 'c' bù yÇ”nxÇ” shÇyòng fúhào" + +#: py/objstr.c +msgid "single '}' encountered in format string" +msgstr "zài géshì zìfú chuàn zhÅng yù dào de dÄngè '}'" + +#: shared-bindings/time/__init__.c +msgid "sleep length must be non-negative" +msgstr "shuìmián chángdù bìxÅ« shìfÄ“i fùshù" + +#: py/objslice.c py/sequence.c +msgid "slice step cannot be zero" +msgstr "qiÄ“piàn bù bùnéng wéi líng" + +#: py/objint.c py/sequence.c +msgid "small int overflow" +msgstr "xiÇŽo zhÄ›ngshù yìchÅ«" + +#: main.c +msgid "soft reboot\n" +msgstr "ruÇŽn chóngqÇ\n" + +#: py/objstr.c +msgid "start/end indices" +msgstr "kÄishÇ/jiéshù zhÇshù" + +#: shared-bindings/displayio/Shape.c +msgid "start_x should be an int" +msgstr "kÄishÇ_x yÄ«nggÄi shì yÄ«gè zhÄ›ngshù" + +#: shared-bindings/random/__init__.c +msgid "step must be non-zero" +msgstr "bùzhòu bìxÅ« shìfÄ“i líng" + +#: shared-bindings/busio/UART.c +msgid "stop must be 1 or 2" +msgstr "tíngzhÇ bìxÅ« wèi 1 huò 2" + +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" +msgstr "tíngzhÇ wúfÇŽ cóng kÄishÇ zhÅng zhÇŽodào" + +#: py/stream.c +msgid "stream operation not supported" +msgstr "bù zhÄ«chí liú cÄozuò" + +#: py/objstrunicode.c +msgid "string index out of range" +msgstr "zìfú chuàn suÇ’yÇn chÄochÅ« fànwéi" + +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" +msgstr "zìfú chuàn zhÇshù bìxÅ« shì zhÄ›ngshù, ér bùshì %s" + +#: py/stream.c +msgid "string not supported; use bytes or bytearray" +msgstr "zìfú chuàn bù zhÄ«chí; shÇyòng zì jié huò zì jié zÇ”" + +#: extmod/moductypes.c +msgid "struct: cannot index" +msgstr "jiégòu: bùnéng suÇ’yÇn" + +#: extmod/moductypes.c +msgid "struct: index out of range" +msgstr "jiégòu: suÇ’yÇn chÄochÅ« fànwéi" + +#: extmod/moductypes.c +msgid "struct: no fields" +msgstr "jiégòu: méiyÇ’u zìduàn" + +#: py/objstr.c +msgid "substring not found" +msgstr "wèi zhÇŽodào zi zìfú chuàn" + +#: py/compile.c +msgid "super() can't find self" +msgstr "chÄojí() zhÇŽo bù dào zìjÇ" + +#: extmod/modujson.c +msgid "syntax error in JSON" +msgstr "JSON yÇ”fÇŽ cuòwù" + +#: extmod/moductypes.c +msgid "syntax error in uctypes descriptor" +msgstr "uctypes miáoshù fú zhÅng de yÇ”fÇŽ cuòwù" + +#: shared-bindings/touchio/TouchIn.c +msgid "threshold must be in the range 0-65536" +msgstr "yùzhí bìxÅ« zài fànwéi 0-65536" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes a 9-sequence" +msgstr "time.struct_time() xÅ«yào 9 xùliè" + +#: shared-bindings/time/__init__.c +msgid "time.struct_time() takes exactly 1 argument" +msgstr "time.struct_time() xÅ«yào wánquán 1 cÄnshù" + +#: shared-bindings/busio/UART.c +msgid "timeout >100 (units are now seconds, not msecs)" +msgstr "chÄoshí >100 (dÄnwèi shì miÇŽo, ér bùshì háomiÇŽo)" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "timeout must be >= 0.0" +msgstr "chÄoshí bìxÅ« shì >= 0.0" + +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" +msgstr "time_t shíjiÄn chuÅ chÄochÅ« píngtái fànwéi" + +#: shared-module/struct/__init__.c +msgid "too many arguments provided with the given format" +msgstr "tígÅng jÇ dìng géshì de cÄnshù tài duÅ" + +#: py/runtime.c +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "dÇŽkÄi tài duÅ zhí (yùqí %d)" + +#: py/objstr.c +msgid "tuple index out of range" +msgstr "yuán zÇ” suÇ’yÇn chÄochÅ« fànwéi" + +#: py/obj.c +msgid "tuple/list has wrong length" +msgstr "yuán zÇ”/lièbiÇŽo chángdù cuòwù" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "tuple/list required on RHS" +msgstr "RHS yÄoqiú de yuán zÇ”/lièbiÇŽo" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c +msgid "tx and rx cannot both be None" +msgstr "tx hé rx bùnéng dÅu shì wú" + +#: py/objtype.c +msgid "type '%q' is not an acceptable base type" +msgstr "lèixíng '%q' bùshì kÄ› jiÄ“shòu de jÄ«chÇ” lèixíng" + +#: py/objtype.c +msgid "type is not an acceptable base type" +msgstr "lèixíng bùshì kÄ› jiÄ“shòu de jÄ«chÇ” lèixíng" + +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" +msgstr "lèixíng duìxiàng '%q' méiyÇ’u shÇ”xìng '%q'" + +#: py/objtype.c +msgid "type takes 1 or 3 arguments" +msgstr "lèixíng wèi 1 huò 3 gè cÄnshù" + +#: py/objint_longlong.c +msgid "ulonglong too large" +msgstr "tài kuÄn" + +#: py/emitnative.c +msgid "unary op %q not implemented" +msgstr "wèi zhíxíng %q" + +#: py/parse.c +msgid "unexpected indent" +msgstr "wèi yùliào de suÅ jìn" + +#: py/bc.c +msgid "unexpected keyword argument" +msgstr "yìwài de guÄnjiàn cí cÄnshù" + +#: py/bc.c py/objnamedtuple.c +msgid "unexpected keyword argument '%q'" +msgstr "yìwài de guÄnjiàn cí cÄnshù '%q'" + +#: py/lexer.c +msgid "unicode name escapes" +msgstr "unicode míngchÄ“ng táoyì" + +#: py/parse.c +msgid "unindent does not match any outer indentation level" +msgstr "bùsuÅ jìn yÇ” rènhé wàibù suÅ jìn jíbié dÅu bù pÇpèi" + +#: py/objstr.c +#, c-format +msgid "unknown conversion specifier %c" +msgstr "wèizhÄ« de zhuÇŽnhuàn biÄozhù %c" + +#: py/objstr.c +#, fuzzy, c-format +msgid "unknown format code '%c' for object of type '%s'" +msgstr "lèixíng '%s' duìxiàng wèizhÄ« de géshì dàimÇŽ '%c'" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'float'" +msgstr "lèixíng 'float' duìxiàng wèizhÄ« de géshì dàimÇŽ '%c'" + +#: py/objstr.c +#, c-format +msgid "unknown format code '%c' for object of type 'str'" +msgstr "lèixíng 'str' duìxiàng wèizhÄ« de géshì dàimÇŽ '%c'" + +#: py/compile.c +msgid "unknown type" +msgstr "wèizhÄ« lèixíng" + +#: py/emitnative.c +msgid "unknown type '%q'" +msgstr "wèizhÄ« lèixíng '%q'" + +#: py/objstr.c +msgid "unmatched '{' in format" +msgstr "géshì wèi pÇpèi '{'" + +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" +msgstr "bùkÄ› dú shÇ”xìng" + +#: shared-bindings/displayio/TileGrid.c +msgid "unsupported %q type" +msgstr "bù zhÄ«chí %q lèixíng" + +#: py/emitinlinethumb.c +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "bù zhÄ«chí de Thumb zhÇshì '%s', shÇyòng %d cÄnshù" + +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "bù zhÄ«chí de Xtensa zhÇlìng '%s', shÇyòng %d cÄnshù" + +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "bù zhÄ«chí de géshì zìfú '%c' (0x%x) suÇ’yÇn %d" + +#: py/runtime.c +msgid "unsupported type for %q: '%s'" +msgstr "bù zhÄ«chí de lèixíng %q: '%s'" + +#: py/runtime.c +msgid "unsupported type for operator" +msgstr "bù zhÄ«chí de cÄozuò zhÄ› lèixíng" + +#: py/runtime.c +msgid "unsupported types for %q: '%s', '%s'" +msgstr "bù zhÄ«chí de lèixíng wèi %q: '%s', '%s'" + +#: py/objint.c +#, c-format +msgid "value must fit in %d byte(s)" +msgstr "Zhí bìxÅ« fúhé %d zì jié" + +#: shared-bindings/displayio/Bitmap.c +msgid "value_count must be > 0" +msgstr "zhí jìshù bìxÅ« wèi > 0" + +#: shared-bindings/_bleio/Scanner.c +msgid "window must be <= interval" +msgstr "ChuÄngkÇ’u bìxÅ« shì <= jiàngé" + +#: shared-bindings/_pixelbuf/PixelBuf.c +msgid "write_args must be a list, tuple, or None" +msgstr "xiÄ› cÄnshù bìxÅ« shì yuán zÇ”, lièbiÇŽo huò None" + +#: py/objstr.c +msgid "wrong number of arguments" +msgstr "cÄnshù shù cuòwù" + +#: py/runtime.c +msgid "wrong number of values to unpack" +msgstr "wúfÇŽ jiÄ› bÄo de zhí shù" + +#: shared-module/displayio/Shape.c +msgid "x value out of bounds" +msgstr "x zhí chÄochÅ« biÄnjiè" + +#: shared-bindings/displayio/Shape.c +msgid "y should be an int" +msgstr "y yÄ«nggÄi shì yÄ«gè zhÄ›ngshù" + +#: shared-module/displayio/Shape.c +msgid "y value out of bounds" +msgstr "y zhí chÄochÅ« biÄnjiè" + +#: py/objrange.c +msgid "zero step" +msgstr "líng bù" + +#~ msgid "Address is not %d bytes long or is in wrong format" +#~ msgstr "DìzhÇ bùshì %d zì jié zhÇŽng, huòzhÄ› géshì cuòwù" + +#~ msgid "Can't add services in Central mode" +#~ msgstr "WúfÇŽ zài zhÅngyÄng móshì xià tiÄnjiÄ fúwù" + +#~ msgid "Can't advertise in Central mode" +#~ msgstr "WúfÇŽ zài zhÅngyÄng móshì zhÅng guÇŽnggào" + +#~ msgid "Can't change the name in Central mode" +#~ msgstr "WúfÇŽ gÄ“nggÇŽi zhÅngyÄng móshì de míngchÄ“ng" + +#~ msgid "Can't connect in Peripheral mode" +#~ msgstr "WúfÇŽ zài biÄnyuán móshì zhÅng liánjiÄ“" + +#~ msgid "Can't set CCCD for local Characteristic" +#~ msgstr "WúfÇŽ wéi bÄ›ndì tèzhÄ“ng shèzhì CCCD" + +#~ msgid "Characteristic UUID doesn't match Service UUID" +#~ msgstr "Zìfú UUID bù fúhé fúwù UUID" + +#~ msgid "Characteristic already in use by another Service." +#~ msgstr "QítÄ fúwù bùmén yÇ shÇyòng de gÅngnéng." + +#~ msgid "Data too large for the advertisement packet" +#~ msgstr "GuÇŽnggào bÄo de shùjù tài dà" + +#~ msgid "Failed to acquire mutex" +#~ msgstr "WúfÇŽ huòdé mutex" + +#~ msgid "Failed to add service" +#~ msgstr "TiÄnjiÄ fúwù shÄ«bài" + +#~ msgid "Failed to connect:" +#~ msgstr "LiánjiÄ“ shÄ«bài:" + +#~ msgid "Failed to continue scanning" +#~ msgstr "Jìxù sÇŽomiáo shÄ«bài" + +#~ msgid "Failed to create mutex" +#~ msgstr "WúfÇŽ chuàngjiàn hù chì suÇ’" + +#~ msgid "Failed to release mutex" +#~ msgstr "WúfÇŽ shìfàng mutex" + +#~ msgid "Failed to start advertising" +#~ msgstr "QÇdòng guÇŽnggào shÄ«bài" + +#~ msgid "Failed to start scanning" +#~ msgstr "QÇdòng sÇŽomiáo shÄ«bài" + +#~ msgid "Failed to stop advertising" +#~ msgstr "WúfÇŽ tíngzhÇ guÇŽnggào" + +#~ msgid "Invalid bit clock pin" +#~ msgstr "Wúxiào de wèi shízhÅng yÇn jiÇŽo" + +#~ msgid "Invalid clock pin" +#~ msgstr "Wúxiào de shízhÅng yÇn jiÇŽo" + +#~ msgid "Invalid data pin" +#~ msgstr "Wúxiào de shùjù yÇn jiÇŽo" + +#~ msgid "Must be a Group subclass." +#~ msgstr "BìxÅ« shì fÄ“nzÇ” zi lèi." + +#~ msgid "No default I2C bus" +#~ msgstr "MéiyÇ’u mòrèn I2C gÅnggòng qìchÄ“" + +#~ msgid "No default SPI bus" +#~ msgstr "MéiyÇ’u mòrèn SPI gÅnggòng qìchÄ“" + +#~ msgid "No default UART bus" +#~ msgstr "MéiyÇ’u mòrèn UART gÅnggòng qìchÄ“" + +#~ msgid "Only bit maps of 8 bit color or less are supported" +#~ msgstr "JÇn zhÄ«chí 8 wèi yánsè huò xiÇŽoyú" + +#~ msgid "" +#~ "Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d " +#~ "bpp given" +#~ msgstr "" +#~ "JÇn zhÄ«chí dÄn sè, suÇ’yÇn 8bpp hé 16bpp huò gèng dà de BMP: %d bpp tígÅng" + +#~ msgid "Tile indices must be 0 - 255" +#~ msgstr "Píng pÅ« zhÇshù bìxÅ« wèi 0 - 255" + +#~ msgid "UUID integer value not in range 0 to 0xffff" +#~ msgstr "UUID zhÄ›ngshù zhí bùzài fànwéi 0 zhì 0xffff" + +#~ msgid "bad GATT role" +#~ msgstr "zÇ’ng xiédìng de bùliáng juésè" + +#~ msgid "characteristics includes an object that is not a Characteristic" +#~ msgstr "tèxìng bÄokuò bùshì zìfú de wùtÇ" + +#~ msgid "expected a DigitalInOut" +#~ msgstr "qídài de DigitalInOut" + +#~ msgid "interval not in range 0.0020 to 10.24" +#~ msgstr "jùlí 0.0020 Zhì 10.24 ZhÄ« jiÄn de jiàngé shíjiÄn" + +#~ msgid "row must be packed and word aligned" +#~ msgstr "xíng bìxÅ« dÇŽbÄo bìngqiÄ› zì duìqí" + +#~ msgid "services includes an object that is not a Service" +#~ msgstr "fúwù bÄokuò yÄ«gè bùshì fúwù de wùjiàn" + +#~ msgid "tile index out of bounds" +#~ msgstr "kuài suÇ’yÇn chÄochÅ« fànwéi" + +#~ msgid "too many arguments" +#~ msgstr "tài duÅ cÄnshù" + +#~ msgid "unsupported bitmap type" +#~ msgstr "bù zhÄ«chí de bitmap lèixíng" diff --git a/logo/1bit-logo.png b/logo/1bit-logo.png deleted file mode 100644 index 42927f3140e..00000000000 Binary files a/logo/1bit-logo.png and /dev/null differ diff --git a/logo/CircuitPython_Repo_header_logo.png b/logo/CircuitPython_Repo_header_logo.png new file mode 100644 index 00000000000..6ce287922ab Binary files /dev/null and b/logo/CircuitPython_Repo_header_logo.png differ diff --git a/logo/FONT-LICENSE.txt b/logo/FONT-LICENSE.txt deleted file mode 100644 index 69c49d84c83..00000000000 --- a/logo/FONT-LICENSE.txt +++ /dev/null @@ -1,97 +0,0 @@ -The font used for the MicroPython logo is "Exo", -http://www.google.com/fonts/specimen/Exo. - -Copyright (c) 2013, Natanael Gama (https://plus.google.com/u/0/+NatanaelGama), -with Reserved Font Name Exo. - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/logo/adafruit_blinka_angles-back.svg b/logo/adafruit_blinka_angles-back.svg new file mode 100644 index 00000000000..589ed6f0a6b --- /dev/null +++ b/logo/adafruit_blinka_angles-back.svg @@ -0,0 +1,371 @@ + +image/svg+xml \ No newline at end of file diff --git a/logo/adafruit_blinka_angles-front.svg b/logo/adafruit_blinka_angles-front.svg new file mode 100644 index 00000000000..f09ce386072 --- /dev/null +++ b/logo/adafruit_blinka_angles-front.svg @@ -0,0 +1,416 @@ + +image/svg+xml \ No newline at end of file diff --git a/logo/adafruit_blinka_angles-left.svg b/logo/adafruit_blinka_angles-left.svg new file mode 100644 index 00000000000..32c83c40740 --- /dev/null +++ b/logo/adafruit_blinka_angles-left.svg @@ -0,0 +1,5876 @@ + +image/svg+xml \ No newline at end of file diff --git a/logo/adafruit_blinka_angles-right.svg b/logo/adafruit_blinka_angles-right.svg new file mode 100644 index 00000000000..51f9279aac5 --- /dev/null +++ b/logo/adafruit_blinka_angles-right.svg @@ -0,0 +1,481 @@ + +image/svg+xml \ No newline at end of file diff --git a/logo/adafruit_blinka_computer.svg b/logo/adafruit_blinka_computer.svg new file mode 100644 index 00000000000..31753081aee --- /dev/null +++ b/logo/adafruit_blinka_computer.svg @@ -0,0 +1,621 @@ + +image/svg+xml \ No newline at end of file diff --git a/logo/adafruit_circuit_python_ourboros_color.svg b/logo/adafruit_circuit_python_ourboros_color.svg new file mode 100644 index 00000000000..d1177ef2248 --- /dev/null +++ b/logo/adafruit_circuit_python_ourboros_color.svg @@ -0,0 +1,555 @@ + +image/svg+xml \ No newline at end of file diff --git a/logo/adafruit_circuit_python_ouroboros_logo_final.svg b/logo/adafruit_circuit_python_ouroboros_logo_final.svg new file mode 100644 index 00000000000..051966d4ac6 --- /dev/null +++ b/logo/adafruit_circuit_python_ouroboros_logo_final.svg @@ -0,0 +1,96 @@ + +image/svg+xml \ No newline at end of file diff --git a/logo/adafruit_circuit_python_sitting_color.svg b/logo/adafruit_circuit_python_sitting_color.svg new file mode 100644 index 00000000000..6da7f5ca862 --- /dev/null +++ b/logo/adafruit_circuit_python_sitting_color.svg @@ -0,0 +1,606 @@ + +image/svg+xml \ No newline at end of file diff --git a/logo/adafruit_circuit_python_stacked_lockup_logo_final.svg b/logo/adafruit_circuit_python_stacked_lockup_logo_final.svg new file mode 100644 index 00000000000..3fbce7126e9 --- /dev/null +++ b/logo/adafruit_circuit_python_stacked_lockup_logo_final.svg @@ -0,0 +1,77 @@ + +image/svg+xml \ No newline at end of file diff --git a/logo/awesome_circuitpython.svg b/logo/awesome_circuitpython.svg new file mode 100644 index 00000000000..f60b0c65931 --- /dev/null +++ b/logo/awesome_circuitpython.svg @@ -0,0 +1,636 @@ + +image/svg+xml \ No newline at end of file diff --git a/logo/blinka_colorform-cooking.png b/logo/blinka_colorform-cooking.png new file mode 100644 index 00000000000..38b2f53ff43 Binary files /dev/null and b/logo/blinka_colorform-cooking.png differ diff --git a/logo/blinka_colorform-cooking.svg b/logo/blinka_colorform-cooking.svg new file mode 100644 index 00000000000..d108479f756 --- /dev/null +++ b/logo/blinka_colorform-cooking.svg @@ -0,0 +1,1085 @@ + +image/svg+xml \ No newline at end of file diff --git a/logo/blinka_colorform-first-birthday.svg b/logo/blinka_colorform-first-birthday.svg new file mode 100644 index 00000000000..37626864c35 --- /dev/null +++ b/logo/blinka_colorform-first-birthday.svg @@ -0,0 +1,886 @@ + +image/svg+xml1 + \ No newline at end of file diff --git a/logo/blinka_colorform-painting.svg b/logo/blinka_colorform-painting.svg new file mode 100644 index 00000000000..c7493207ac6 --- /dev/null +++ b/logo/blinka_colorform-painting.svg @@ -0,0 +1,1022 @@ + +image/svg+xml \ No newline at end of file diff --git a/logo/blinka_colorform-reading.svg b/logo/blinka_colorform-reading.svg new file mode 100644 index 00000000000..761895ac06a --- /dev/null +++ b/logo/blinka_colorform-reading.svg @@ -0,0 +1,906 @@ + +image/svg+xml \ No newline at end of file diff --git a/logo/blinka_colorform-singing.svg b/logo/blinka_colorform-singing.svg new file mode 100644 index 00000000000..ec22f436279 --- /dev/null +++ b/logo/blinka_colorform-singing.svg @@ -0,0 +1,1037 @@ + +image/svg+xml \ No newline at end of file diff --git a/logo/blinka_colorform-telescope.svg b/logo/blinka_colorform-telescope.svg new file mode 100644 index 00000000000..8b3724171b3 --- /dev/null +++ b/logo/blinka_colorform-telescope.svg @@ -0,0 +1,965 @@ + +image/svg+xml \ No newline at end of file diff --git a/logo/blinka_colorform-test_tubes.svg b/logo/blinka_colorform-test_tubes.svg new file mode 100644 index 00000000000..b6b939d2f0a --- /dev/null +++ b/logo/blinka_colorform-test_tubes.svg @@ -0,0 +1,1217 @@ + +image/svg+xml \ No newline at end of file diff --git a/logo/logo.jpg b/logo/logo.jpg deleted file mode 100644 index 377aa8ac28f..00000000000 Binary files a/logo/logo.jpg and /dev/null differ diff --git a/logo/micropythonpowered-art.png b/logo/micropythonpowered-art.png deleted file mode 100644 index 9045bb0a433..00000000000 Binary files a/logo/micropythonpowered-art.png and /dev/null differ diff --git a/logo/trans-logo.png b/logo/trans-logo.png deleted file mode 100644 index b114d90bd84..00000000000 Binary files a/logo/trans-logo.png and /dev/null differ diff --git a/logo/upython-with-micro.jpg b/logo/upython-with-micro.jpg deleted file mode 100644 index 4984d8e2f2f..00000000000 Binary files a/logo/upython-with-micro.jpg and /dev/null differ diff --git a/logo/upython-with-micro.png b/logo/upython-with-micro.png deleted file mode 100644 index 2b3431cbdd9..00000000000 Binary files a/logo/upython-with-micro.png and /dev/null differ diff --git a/logo/vector-logo-2-BW.svg b/logo/vector-logo-2-BW.svg deleted file mode 100644 index d7ff920f98f..00000000000 --- a/logo/vector-logo-2-BW.svg +++ /dev/null @@ -1,587 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/logo/vector-logo-2.png b/logo/vector-logo-2.png deleted file mode 100644 index 72ce88e1d52..00000000000 Binary files a/logo/vector-logo-2.png and /dev/null differ diff --git a/logo/vector-logo-3.png b/logo/vector-logo-3.png deleted file mode 100644 index ba75b056241..00000000000 Binary files a/logo/vector-logo-3.png and /dev/null differ diff --git a/logo/vector-logo-R2000.dxf b/logo/vector-logo-R2000.dxf deleted file mode 100644 index 4b28e7a23db..00000000000 --- a/logo/vector-logo-R2000.dxf +++ /dev/null @@ -1,33724 +0,0 @@ - 0 -SECTION - 2 -HEADER - 9 -$ACADVER - 1 -AC1015 - 9 -$ACADMAINTVER - 70 - 6 - 9 -$DWGCODEPAGE - 3 -ANSI_1252 - 9 -$INSBASE - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$EXTMIN - 10 -0.1721479520991333 - 20 -0.1940338359368368 - 30 -0.0 - 9 -$EXTMAX - 10 -3.827852047900866 - 20 -3.91966423026812 - 30 -0.0 - 9 -$LIMMIN - 10 -0.0 - 20 -0.0 - 9 -$LIMMAX - 10 -12.0 - 20 -9.0 - 9 -$ORTHOMODE - 70 - 0 - 9 -$REGENMODE - 70 - 1 - 9 -$FILLMODE - 70 - 1 - 9 -$QTEXTMODE - 70 - 0 - 9 -$MIRRTEXT - 70 - 0 - 9 -$LTSCALE - 40 -1.0 - 9 -$ATTMODE - 70 - 1 - 9 -$TEXTSIZE - 40 -0.2 - 9 -$TRACEWID - 40 -0.05 - 9 -$TEXTSTYLE - 7 -Standard - 9 -$CLAYER - 8 -0 - 9 -$CELTYPE - 6 -ByLayer - 9 -$CECOLOR - 62 - 256 - 9 -$CELTSCALE - 40 -1.0 - 9 -$DISPSILH - 70 - 0 - 9 -$DIMSCALE - 40 -1.0 - 9 -$DIMASZ - 40 -0.18 - 9 -$DIMEXO - 40 -0.0625 - 9 -$DIMDLI - 40 -0.38 - 9 -$DIMRND - 40 -0.0 - 9 -$DIMDLE - 40 -0.0 - 9 -$DIMEXE - 40 -0.18 - 9 -$DIMTP - 40 -0.0 - 9 -$DIMTM - 40 -0.0 - 9 -$DIMTXT - 40 -0.18 - 9 -$DIMCEN - 40 -0.09 - 9 -$DIMTSZ - 40 -0.0 - 9 -$DIMTOL - 70 - 0 - 9 -$DIMLIM - 70 - 0 - 9 -$DIMTIH - 70 - 1 - 9 -$DIMTOH - 70 - 1 - 9 -$DIMSE1 - 70 - 0 - 9 -$DIMSE2 - 70 - 0 - 9 -$DIMTAD - 70 - 0 - 9 -$DIMZIN - 70 - 0 - 9 -$DIMBLK - 1 - - 9 -$DIMASO - 70 - 1 - 9 -$DIMSHO - 70 - 1 - 9 -$DIMPOST - 1 - - 9 -$DIMAPOST - 1 - - 9 -$DIMALT - 70 - 0 - 9 -$DIMALTD - 70 - 2 - 9 -$DIMALTF - 40 -25.4 - 9 -$DIMLFAC - 40 -1.0 - 9 -$DIMTOFL - 70 - 0 - 9 -$DIMTVP - 40 -0.0 - 9 -$DIMTIX - 70 - 0 - 9 -$DIMSOXD - 70 - 0 - 9 -$DIMSAH - 70 - 0 - 9 -$DIMBLK1 - 1 - - 9 -$DIMBLK2 - 1 - - 9 -$DIMSTYLE - 2 -Standard - 9 -$DIMCLRD - 70 - 0 - 9 -$DIMCLRE - 70 - 0 - 9 -$DIMCLRT - 70 - 0 - 9 -$DIMTFAC - 40 -1.0 - 9 -$DIMGAP - 40 -0.09 - 9 -$DIMJUST - 70 - 0 - 9 -$DIMSD1 - 70 - 0 - 9 -$DIMSD2 - 70 - 0 - 9 -$DIMTOLJ - 70 - 1 - 9 -$DIMTZIN - 70 - 0 - 9 -$DIMALTZ - 70 - 0 - 9 -$DIMALTTZ - 70 - 0 - 9 -$DIMUPT - 70 - 0 - 9 -$DIMDEC - 70 - 4 - 9 -$DIMTDEC - 70 - 4 - 9 -$DIMALTU - 70 - 2 - 9 -$DIMALTTD - 70 - 2 - 9 -$DIMTXSTY - 7 -Standard - 9 -$DIMAUNIT - 70 - 0 - 9 -$DIMADEC - 70 - 0 - 9 -$DIMALTRND - 40 -0.0 - 9 -$DIMAZIN - 70 - 0 - 9 -$DIMDSEP - 70 - 46 - 9 -$DIMATFIT - 70 - 3 - 9 -$DIMFRAC - 70 - 0 - 9 -$DIMLDRBLK - 1 - - 9 -$DIMLUNIT - 70 - 2 - 9 -$DIMLWD - 70 - -2 - 9 -$DIMLWE - 70 - -2 - 9 -$DIMTMOVE - 70 - 0 - 9 -$LUNITS - 70 - 2 - 9 -$LUPREC - 70 - 4 - 9 -$SKETCHINC - 40 -0.1 - 9 -$FILLETRAD - 40 -0.0196850393700787 - 9 -$AUNITS - 70 - 0 - 9 -$AUPREC - 70 - 0 - 9 -$MENU - 1 -. - 9 -$ELEVATION - 40 -0.0 - 9 -$PELEVATION - 40 -0.0 - 9 -$THICKNESS - 40 -0.0 - 9 -$LIMCHECK - 70 - 0 - 9 -$CHAMFERA - 40 -0.0 - 9 -$CHAMFERB - 40 -0.0 - 9 -$CHAMFERC - 40 -0.0 - 9 -$CHAMFERD - 40 -0.0 - 9 -$SKPOLY - 70 - 0 - 9 -$TDCREATE - 40 -2452642.813384259 - 9 -$TDUCREATE - 40 -2452643.063384271 - 9 -$TDUPDATE - 40 -2456660.752361111 - 9 -$TDUUPDATE - 40 -2456661.002361111 - 9 -$TDINDWG - 40 -0.0 - 9 -$TDUSRTIMER - 40 -2456661.001018519 - 9 -$USRTIMER - 70 - 1 - 9 -$ANGBASE - 50 -0.0 - 9 -$ANGDIR - 70 - 0 - 9 -$PDMODE - 70 - 0 - 9 -$PDSIZE - 40 -0.0 - 9 -$PLINEWID - 40 -0.0 - 9 -$SPLFRAME - 70 - 0 - 9 -$SPLINETYPE - 70 - 6 - 9 -$SPLINESEGS - 70 - 8 - 9 -$HANDSEED - 5 -1B45 - 9 -$SURFTAB1 - 70 - 6 - 9 -$SURFTAB2 - 70 - 6 - 9 -$SURFTYPE - 70 - 6 - 9 -$SURFU - 70 - 6 - 9 -$SURFV - 70 - 6 - 9 -$UCSBASE - 2 - - 9 -$UCSNAME - 2 - - 9 -$UCSORG - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$UCSXDIR - 10 -1.0 - 20 -0.0 - 30 -0.0 - 9 -$UCSYDIR - 10 -0.0 - 20 -1.0 - 30 -0.0 - 9 -$UCSORTHOREF - 2 - - 9 -$UCSORTHOVIEW - 70 - 0 - 9 -$UCSORGTOP - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$UCSORGBOTTOM - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$UCSORGLEFT - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$UCSORGRIGHT - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$UCSORGFRONT - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$UCSORGBACK - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PUCSBASE - 2 - - 9 -$PUCSNAME - 2 - - 9 -$PUCSORG - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PUCSXDIR - 10 -1.0 - 20 -0.0 - 30 -0.0 - 9 -$PUCSYDIR - 10 -0.0 - 20 -1.0 - 30 -0.0 - 9 -$PUCSORTHOREF - 2 - - 9 -$PUCSORTHOVIEW - 70 - 0 - 9 -$PUCSORGTOP - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PUCSORGBOTTOM - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PUCSORGLEFT - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PUCSORGRIGHT - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PUCSORGFRONT - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PUCSORGBACK - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$USERI1 - 70 - 0 - 9 -$USERI2 - 70 - 0 - 9 -$USERI3 - 70 - 0 - 9 -$USERI4 - 70 - 0 - 9 -$USERI5 - 70 - 0 - 9 -$USERR1 - 40 -0.0 - 9 -$USERR2 - 40 -0.0 - 9 -$USERR3 - 40 -0.0 - 9 -$USERR4 - 40 -0.0 - 9 -$USERR5 - 40 -0.0 - 9 -$WORLDVIEW - 70 - 1 - 9 -$SHADEDGE - 70 - 3 - 9 -$SHADEDIF - 70 - 70 - 9 -$TILEMODE - 70 - 1 - 9 -$MAXACTVP - 70 - 64 - 9 -$PINSBASE - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PLIMCHECK - 70 - 0 - 9 -$PEXTMIN - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PEXTMAX - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PLIMMIN - 10 -0.0 - 20 -0.0 - 9 -$PLIMMAX - 10 -0.0 - 20 -0.0 - 9 -$UNITMODE - 70 - 0 - 9 -$VISRETAIN - 70 - 1 - 9 -$PLINEGEN - 70 - 0 - 9 -$PSLTSCALE - 70 - 1 - 9 -$TREEDEPTH - 70 - 3020 - 9 -$CMLSTYLE - 2 -Standard - 9 -$CMLJUST - 70 - 0 - 9 -$CMLSCALE - 40 -1.0 - 9 -$PROXYGRAPHICS - 70 - 1 - 9 -$MEASUREMENT - 70 - 0 - 9 -$CELWEIGHT -370 - -1 - 9 -$ENDCAPS -280 - 0 - 9 -$JOINSTYLE -280 - 0 - 9 -$LWDISPLAY -290 - 0 - 9 -$INSUNITS - 70 - 1 - 9 -$HYPERLINKBASE - 1 - - 9 -$STYLESHEET - 1 - - 9 -$XEDIT -290 - 1 - 9 -$CEPSNTYPE -380 - 0 - 9 -$PSTYLEMODE -290 - 1 - 9 -$FINGERPRINTGUID - 2 -{FDEAD576-A652-11D2-9A35-0060089B3A3F} - 9 -$VERSIONGUID - 2 -{FBC2AE19-5C5C-49EC-81BC-71B1A3362A02} - 9 -$EXTNAMES -290 - 1 - 9 -$PSVPSCALE - 40 -0.0 - 9 -$OLESTARTUP -290 - 0 - 0 -ENDSEC - 0 -SECTION - 2 -CLASSES - 0 -CLASS - 1 -ACDBDICTIONARYWDFLT - 2 -AcDbDictionaryWithDefault - 3 -ObjectDBX Classes - 90 - 0 -280 - 0 -281 - 0 - 0 -CLASS - 1 -ACDBPLACEHOLDER - 2 -AcDbPlaceHolder - 3 -ObjectDBX Classes - 90 - 0 -280 - 0 -281 - 0 - 0 -CLASS - 1 -LAYOUT - 2 -AcDbLayout - 3 -ObjectDBX Classes - 90 - 0 -280 - 0 -281 - 0 - 0 -CLASS - 1 -DICTIONARYVAR - 2 -AcDbDictionaryVar - 3 -ObjectDBX Classes - 90 - 0 -280 - 0 -281 - 0 - 0 -CLASS - 1 -TABLESTYLE - 2 -AcDbTableStyle - 3 -ObjectDBX Classes - 90 - 4095 -280 - 0 -281 - 0 - 0 -CLASS - 1 -MATERIAL - 2 -AcDbMaterial - 3 -ObjectDBX Classes - 90 - 1153 -280 - 0 -281 - 0 - 0 -CLASS - 1 -VISUALSTYLE - 2 -AcDbVisualStyle - 3 -ObjectDBX Classes - 90 - 4095 -280 - 0 -281 - 0 - 0 -CLASS - 1 -SCALE - 2 -AcDbScale - 3 -ObjectDBX Classes - 90 - 1153 -280 - 0 -281 - 0 - 0 -CLASS - 1 -CELLSTYLEMAP - 2 -AcDbCellStyleMap - 3 -ObjectDBX Classes - 90 - 1152 -280 - 0 -281 - 0 - 0 -CLASS - 1 -RASTERVARIABLES - 2 -AcDbRasterVariables - 3 -ISM - 90 - 0 -280 - 0 -281 - 0 - 0 -CLASS - 1 -SUN - 2 -AcDbSun - 3 -SCENEOE - 90 - 1153 -280 - 0 -281 - 0 - 0 -CLASS - 1 -IMAGEDEF - 2 -AcDbRasterImageDef - 3 -ISM - 90 - 0 -280 - 0 -281 - 0 - 0 -CLASS - 1 -IMAGE - 2 -AcDbRasterImage - 3 -ISM - 90 - 127 -280 - 0 -281 - 1 - 0 -CLASS - 1 -IMAGEDEF_REACTOR - 2 -AcDbRasterImageDefReactor - 3 -ISM - 90 - 1 -280 - 0 -281 - 0 - 0 -CLASS - 1 -SORTENTSTABLE - 2 -AcDbSortentsTable - 3 -ObjectDBX Classes - 90 - 0 -280 - 0 -281 - 0 - 0 -ENDSEC - 0 -SECTION - 2 -TABLES - 0 -TABLE - 2 -VPORT - 5 -8 -330 -0 -100 -AcDbSymbolTable - 70 - 1 - 0 -VPORT - 5 -94 -330 -8 -100 -AcDbSymbolTableRecord -100 -AcDbViewportTableRecord - 2 -*Active - 70 - 0 - 10 -0.0 - 20 -0.0 - 11 -1.0 - 21 -1.0 - 12 -29.66959356597982 - 22 -21.59555199096451 - 13 -0.0 - 23 -0.0 - 14 -0.5 - 24 -0.5 - 15 -0.5 - 25 -0.5 - 16 -0.0 - 26 -0.0 - 36 -1.0 - 17 --27.66959356597982 - 27 --19.53870295786203 - 37 -0.0 - 40 -3.800143002217909 - 41 -2.172519083969465 - 42 -50.0 - 43 -0.0 - 44 -0.0 - 50 -0.0 - 51 -0.0 - 71 - 16 - 72 - 1000 - 73 - 1 - 74 - 3 - 75 - 0 - 76 - 0 - 77 - 0 - 78 - 1 -281 - 5 - 65 - 1 -110 -0.0 -120 -0.0 -130 -0.0 -111 -1.0 -121 -0.0 -131 -0.0 -112 -0.0 -122 -1.0 -132 -0.0 - 79 - 0 -146 -0.0 - 0 -ENDTAB - 0 -TABLE - 2 -LTYPE - 5 -5 -330 -0 -100 -AcDbSymbolTable - 70 - 1 - 0 -LTYPE - 5 -14 -330 -5 -100 -AcDbSymbolTableRecord -100 -AcDbLinetypeTableRecord - 2 -ByBlock - 70 - 0 - 3 - - 72 - 65 - 73 - 0 - 40 -0.0 - 0 -LTYPE - 5 -15 -330 -5 -100 -AcDbSymbolTableRecord -100 -AcDbLinetypeTableRecord - 2 -ByLayer - 70 - 0 - 3 - - 72 - 65 - 73 - 0 - 40 -0.0 - 0 -LTYPE - 5 -16 -330 -5 -100 -AcDbSymbolTableRecord -100 -AcDbLinetypeTableRecord - 2 -Continuous - 70 - 0 - 3 -Solid line - 72 - 65 - 73 - 0 - 40 -0.0 - 0 -ENDTAB - 0 -TABLE - 2 -LAYER - 5 -2 -102 -{ACAD_XDICTIONARY -360 -133 -102 -} -330 -0 -100 -AcDbSymbolTable - 70 - 8 - 0 -LAYER - 5 -10 -330 -2 -100 -AcDbSymbolTableRecord -100 -AcDbLayerTableRecord - 2 -0 - 70 - 0 - 62 - 7 - 6 -Continuous -370 - -3 -390 -F - 0 -LAYER - 5 -4B2 -330 -2 -100 -AcDbSymbolTableRecord -100 -AcDbLayerTableRecord - 2 -OUTLINE - 70 - 0 - 62 - 3 - 6 -Continuous -370 - -3 -390 -F -1001 -AcAecLayerStandard -1000 - -1000 - - 0 -LAYER - 5 -B85 -330 -2 -100 -AcDbSymbolTableRecord -100 -AcDbLayerTableRecord - 2 -HATCH-BLACK - 70 - 0 - 62 - -178 - 6 -Continuous -370 - -3 -390 -F -1001 -AcAecLayerStandard -1000 - -1000 - - 0 -LAYER - 5 -B86 -330 -2 -100 -AcDbSymbolTableRecord -100 -AcDbLayerTableRecord - 2 -HATCH-RED - 70 - 0 - 62 - -1 - 6 -Continuous -370 - -3 -390 -F -1001 -AcAecLayerStandard -1000 - -1000 - - 0 -LAYER - 5 -B87 -330 -2 -100 -AcDbSymbolTableRecord -100 -AcDbLayerTableRecord - 2 -HATCH-YELLOW - 70 - 0 - 62 - -2 - 6 -Continuous -370 - -3 -390 -F -1001 -AcAecLayerStandard -1000 - -1000 - - 0 -LAYER - 5 -C34 -330 -2 -100 -AcDbSymbolTableRecord -100 -AcDbLayerTableRecord - 2 -HATCH-WHITE - 70 - 0 - 62 - -7 - 6 -Continuous -370 - -3 -390 -F -1001 -AcAecLayerStandard -1000 - -1000 - - 0 -LAYER - 5 -C35 -330 -2 -100 -AcDbSymbolTableRecord -100 -AcDbLayerTableRecord - 2 -CENTERLINE - 70 - 0 - 62 - 5 - 6 -Continuous -370 - -3 -390 -F -1001 -AcAecLayerStandard -1000 - -1000 - - 0 -ENDTAB - 0 -TABLE - 2 -STYLE - 5 -3 -330 -0 -100 -AcDbSymbolTable - 70 - 1 - 0 -STYLE - 5 -11 -330 -3 -100 -AcDbSymbolTableRecord -100 -AcDbTextStyleTableRecord - 2 -Standard - 70 - 0 - 40 -0.0 - 41 -1.0 - 50 -0.0 - 71 - 0 - 42 -0.2 - 3 -arial.ttf - 4 - -1001 -ACAD -1000 -Arial -1071 - 0 - 0 -ENDTAB - 0 -TABLE - 2 -VIEW - 5 -6 -330 -0 -100 -AcDbSymbolTable - 70 - 0 - 0 -ENDTAB - 0 -TABLE - 2 -UCS - 5 -7 -330 -0 -100 -AcDbSymbolTable - 70 - 0 - 0 -ENDTAB - 0 -TABLE - 2 -APPID - 5 -9 -330 -0 -100 -AcDbSymbolTable - 70 - 2 - 0 -APPID - 5 -12 -330 -9 -100 -AcDbSymbolTableRecord -100 -AcDbRegAppTableRecord - 2 -ACAD - 70 - 0 - 0 -APPID - 5 -4B3 -330 -9 -100 -AcDbSymbolTableRecord -100 -AcDbRegAppTableRecord - 2 -AcAecLayerStandard - 70 - 0 - 0 -ENDTAB - 0 -TABLE - 2 -DIMSTYLE - 5 -A -330 -0 -100 -AcDbSymbolTable - 70 - 1 -100 -AcDbDimStyleTable - 0 -DIMSTYLE -105 -27 -330 -A -100 -AcDbSymbolTableRecord -100 -AcDbDimStyleTableRecord - 2 -Standard - 70 - 0 -178 - 0 -340 -11 - 0 -ENDTAB - 0 -TABLE - 2 -BLOCK_RECORD - 5 -1 -330 -0 -100 -AcDbSymbolTable - 70 - 1 - 0 -BLOCK_RECORD - 5 -1F -102 -{ACAD_XDICTIONARY -360 -C3A -102 -} -330 -1 -100 -AcDbSymbolTableRecord -100 -AcDbBlockTableRecord - 2 -*Model_Space -340 -22 - 0 -BLOCK_RECORD - 5 -58 -330 -1 -100 -AcDbSymbolTableRecord -100 -AcDbBlockTableRecord - 2 -*Paper_Space -340 -59 - 0 -BLOCK_RECORD - 5 -5D -330 -1 -100 -AcDbSymbolTableRecord -100 -AcDbBlockTableRecord - 2 -*Paper_Space0 -340 -5E - 0 -ENDTAB - 0 -ENDSEC - 0 -SECTION - 2 -BLOCKS - 0 -BLOCK - 5 -20 -330 -1F -100 -AcDbEntity - 8 -0 -100 -AcDbBlockBegin - 2 -*Model_Space - 70 - 0 - 10 -0.0 - 20 -0.0 - 30 -0.0 - 3 -*Model_Space - 1 -*Model_Space - 0 -ENDBLK - 5 -21 -330 -1F -100 -AcDbEntity - 8 -0 -100 -AcDbBlockEnd - 0 -BLOCK - 5 -5A -330 -58 -100 -AcDbEntity - 67 - 1 - 8 -0 -100 -AcDbBlockBegin - 2 -*Paper_Space - 70 - 0 - 10 -0.0 - 20 -0.0 - 30 -0.0 - 3 -*Paper_Space - 1 -*Paper_Space - 0 -ENDBLK - 5 -5B -330 -58 -100 -AcDbEntity - 67 - 1 - 8 -0 -100 -AcDbBlockEnd - 0 -BLOCK - 5 -5F -330 -5D -100 -AcDbEntity - 8 -0 -100 -AcDbBlockBegin - 2 -*Paper_Space0 - 70 - 0 - 10 -0.0 - 20 -0.0 - 30 -0.0 - 3 -*Paper_Space0 - 1 -*Paper_Space0 - 0 -ENDBLK - 5 -60 -330 -5D -100 -AcDbEntity - 8 -0 -100 -AcDbBlockEnd - 0 -ENDSEC - 0 -SECTION - 2 -ENTITIES - 0 -LWPOLYLINE - 5 -12A -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 12 - 70 - 1 - 43 -0.0 - 10 -2.051456726858387 - 20 -3.24742480916928 - 10 -2.123046084816941 - 20 -3.189691455976897 - 42 -0.4158687069147495 - 10 -2.238512791201705 - 20 -3.202392793679222 - 42 -0.26959558438999 - 10 -2.297400811457934 - 20 -3.601907597770506 - 42 -0.5584229650981822 - 10 -2.131128754263874 - 20 -3.630774274366697 - 42 -0.0728974356199314 - 10 -2.083688019187524 - 20 -3.556961618598168 - 10 -2.102120376925607 - 20 -3.616965010523272 - 42 -0.2082143708428352 - 10 -2.078212672061864 - 20 -3.708788569361961 - 42 -0.3964961476078332 - 10 -1.961304941181418 - 20 -3.726524255462661 - 42 -0.3247796006490571 - 10 -1.824130493996318 - 20 -3.336662468025144 - 42 -0.2118780432517558 - 10 -1.926924729355354 - 20 -3.21641832666371 - 42 -0.2797558288082047 - 10 -2.010060757952385 - 20 -3.224731929523413 - 0 -LWPOLYLINE - 5 -137 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -2.002382887993199 - 20 -2.593662641184479 - 42 -0.1140103683665206 - 10 -2.015684652568724 - 20 -2.695642836263502 - 0 -LWPOLYLINE - 5 -138 -102 -{ACAD_REACTORS -330 -C20 -330 -C24 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 4 - 70 - 1 - 43 -0.0 - 10 -2.020828542221933 - 20 -2.58678815101607 - 42 -0.1140103683665206 - 10 -2.035276511011441 - 20 -2.697555911735634 - 42 -1.000000000000011 - 10 -1.996092794126006 - 20 -2.693729760791369 - 42 --0.1140103683665206 - 10 -1.983937233764465 - 20 -2.600537131352887 - 42 -0.9999999999999872 - 0 -LWPOLYLINE - 5 -14D -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -1.722674860472906 - 20 -2.732887777074972 - 42 -0.0678677703915072 - 10 -1.716999440920682 - 20 -2.659580274525414 - 0 -LWPOLYLINE - 5 -14E -102 -{ACAD_REACTORS -330 -C20 -330 -C25 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 4 - 70 - 1 - 43 -0.0 - 10 -1.697347802700083 - 20 -2.658434024008193 - 42 --0.0678677703915072 - 10 -1.703433819452505 - 20 -2.73704507372698 - 42 --0.999999999999989 - 10 -1.741915901493307 - 20 -2.728730480422965 - 42 -0.0678677703915072 - 10 -1.736651079141282 - 20 -2.660726525042634 - 42 --0.9999999999999999 - 0 -LWPOLYLINE - 5 -164 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 11 - 70 - 0 - 43 -0.0 - 10 -1.811731838460656 - 20 -3.397331983591354 - 42 -0.2124467312467683 - 10 -1.672244722447104 - 20 -3.269516246350102 - 42 -0.1056357518612903 - 10 -1.585025186716269 - 20 -2.838970667001557 - 42 -0.1451314237734208 - 10 -1.646476928687697 - 20 -2.639513658809246 - 42 -0.1600067868781768 - 10 -1.833948673174001 - 20 -2.492097314767818 - 42 -0.1190176972929128 - 10 -1.973432454486796 - 20 -2.47639384269949 - 42 -0.0768957533116813 - 10 -2.089822894522638 - 20 -2.509648254138302 - 42 -0.0709021530444379 - 10 -2.251476283461308 - 20 -2.614030156710129 - 42 -0.2070922264234396 - 10 -2.404700602833892 - 20 -2.933295599864002 - 42 -0.0419975136654783 - 10 -2.393883717863114 - 20 -3.174067136850973 - 42 -0.2398427593227676 - 10 -2.300258287041964 - 20 -3.311026577316722 - 42 -0.027034225506599 - 0 -LWPOLYLINE - 5 -1D5 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -1.848504434043273 - 20 -2.228690132322405 - 42 --0.3662698243153691 - 10 -1.793291568736173 - 20 -2.065168888754275 - 0 -LWPOLYLINE - 5 -1E1 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 4 - 70 - 0 - 43 -0.0 - 10 -1.838460881357442 - 20 -2.490495972621108 - 42 -0.1790279848154445 - 10 -1.825573029994973 - 20 -2.288268448973123 - 42 -0.0769094708198934 - 10 -1.880276536811822 - 20 -2.173319033432963 - 42 --0.3080726058837938 - 10 -1.880276536811822 - 20 -2.030140317515856 - 0 -LWPOLYLINE - 5 -21B -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -2.842082767727739 - 20 -1.084629450592382 - 42 -0.1471000450502847 - 10 -2.973927140373517 - 20 -1.328615998752327 - 42 -0.012522411014275 - 0 -LWPOLYLINE - 5 -222 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -2.698425240848715 - 20 -1.242823919320058 - 42 --0.1015039731478666 - 10 -2.611250576927156 - 20 -1.057272707094957 - 42 --0.0126876031091603 - 0 -LWPOLYLINE - 5 -225 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -2.242747987090025 - 20 -1.529761688692975 - 42 -0.0725476044851412 - 10 -2.257696032217536 - 20 -1.639194230959991 - 42 -0.0343380551866947 - 0 -LWPOLYLINE - 5 -226 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -2.495551054582072 - 20 -1.53241438712026 - 42 -0.1036418617890253 - 10 -2.558948542514864 - 20 -1.68753297643855 - 42 -0.053253313175051 - 0 -LWPOLYLINE - 5 -227 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -2.821324146542795 - 20 -1.632324731905094 - 42 -0.1131246587363501 - 10 -2.830405427290065 - 20 -1.811571024886944 - 42 -0.0627672114645879 - 0 -LWPOLYLINE - 5 -22E -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 13 - 70 - 0 - 43 -0.0 - 10 -2.093724705533888 - 20 -1.557613530636603 - 42 -0.2441872791679012 - 10 -3.026855656910417 - 20 -1.767371768597087 - 42 --0.2679491924311224 - 10 -3.157725822448509 - 20 -1.69686877794936 - 42 --0.1202060689774955 - 10 -3.218222973836714 - 20 -1.510442253718783 - 42 --0.1376749084255927 - 10 -3.164885690739821 - 20 -1.246107314101505 - 42 --0.1576175352251851 - 10 -3.093739724933785 - 20 -1.174961348295469 - 42 --0.0918492106817739 - 10 -2.728380896324767 - 20 -1.066112269787028 - 42 --0.0504127972198909 - 10 -2.347761134221376 - 20 -1.063970822126171 - 42 --0.1916344722089164 - 10 -2.225767565997291 - 20 -1.163124980703929 - 42 --0.1572294045872512 - 10 -2.090834049478103 - 20 -1.818212016772601 - 42 --0.082508630093775 - 10 -2.21598539544255 - 20 -2.26448668874584 - 42 -0.000862340954801 - 10 -2.279411658998576 - 20 -2.40050474988379 - 42 -0.1021773121869368 - 10 -2.404700602833892 - 20 -2.933295599864003 - 42 -0.1021773121869368 - 0 -LWPOLYLINE - 5 -231 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 4 - 70 - 0 - 43 -0.0 - 10 -2.099277124665835 - 20 -3.285428055915363 - 42 -0.5205670505517482 - 10 -2.139077350685995 - 20 -3.338013952617782 - 42 -0.1061689985690478 - 10 -2.120029457222835 - 20 -3.371005871873133 - 42 -0.613270554273111 - 10 -2.068634698539837 - 20 -3.335369986556996 - 0 -LWPOLYLINE - 5 -232 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 4 - 70 - 0 - 43 -0.0 - 10 -1.973661171909946 - 20 -3.292995281984995 - 42 --0.3922502215719873 - 10 -1.946797519362752 - 20 -3.372829517019611 - 42 --0.7101707266102861 - 10 -2.015384873593222 - 20 -3.366828901063208 - 42 --0.0639643640494128 - 10 -2.018358052101874 - 20 -3.342323304531541 - 0 -LWPOLYLINE - 5 -235 -102 -{ACAD_REACTORS -330 -BFB -330 -C40 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 8 - 70 - 1 - 43 -0.0 - 10 -2.098548696321338 - 20 -3.265756498601605 - 42 -0.5205670505517482 - 10 -2.157811705099888 - 20 -3.344057522729578 - 42 -0.1134405246031883 - 10 -2.132468959817252 - 20 -3.3865310504764 - 42 -0.6360781342605795 - 10 -2.049130653843808 - 20 -3.332706714979239 - 42 -0.9999999999999999 - 10 -2.088138743235865 - 20 -3.338033258134752 - 42 --0.5492430075431818 - 10 -2.107983316870547 - 20 -3.354815495403025 - 42 --0.0921948717360171 - 10 -2.120342996272102 - 20 -3.331970382505986 - 42 --0.5205670505517482 - 10 -2.100005553010331 - 20 -3.305099613229121 - 42 -0.999999999999977 - 0 -LWPOLYLINE - 5 -267 -102 -{ACAD_REACTORS -330 -BFC -330 -C40 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 8 - 70 - 1 - 43 -0.0 - 10 -1.998673497536078 - 20 -3.342461458603947 - 42 -0.0639643640494127 - 10 -1.996304467484263 - 20 -3.361987529592359 - 42 -0.7101707266102861 - 10 -1.964747355896155 - 20 -3.364748419109942 - 42 -0.3922502215719873 - 10 -1.983074304769177 - 20 -3.310283824571807 - 42 --0.9999999999999997 - 10 -1.964248039050714 - 20 -3.275706739398183 - 42 --0.3922502215719873 - 10 -1.92884768282935 - 20 -3.380910614929281 - 42 --0.7101707266102861 - 10 -2.034465279702181 - 20 -3.371670272534057 - 42 --0.0639643640494129 - 10 -2.038042606667671 - 20 -3.342185150459134 - 42 --0.9999999999999888 - 0 -LWPOLYLINE - 5 -2AF -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -2.085608292827229 - 20 -1.648485389947214 - 42 -0.2371550452328881 - 10 -3.038263728075514 - 20 -1.980095333928444 - 42 -0.0363699080748577 - 0 -LWPOLYLINE - 5 -2B5 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -2.428981511922024 - 20 -1.228952354254482 - 42 --0.1215147796354945 - 10 -2.347761134221376 - 20 -1.063970822126171 - 42 --0.0158934016013214 - 0 -LWPOLYLINE - 5 -34A -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 6 - 70 - 0 - 43 -0.0 - 10 -2.100129120524675 - 20 -1.887439157700382 - 42 -0.1601220285391677 - 10 -2.669056601079002 - 20 -2.103591135847005 - 42 -0.3249446074510534 - 10 -2.710306617856964 - 20 -2.257538294275427 - 42 -0.3057060432679023 - 10 -2.64763418517673 - 20 -2.301422004076068 - 42 -0.1122985838264234 - 10 -2.540456015841269 - 20 -2.279007501710551 - 42 -0.067059303923133 - 10 -2.127272926405246 - 20 -2.017804783046922 - 42 -0.0105768622903034 - 0 -LWPOLYLINE - 5 -34C -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 5 - 70 - 0 - 43 -0.0 - 10 -2.669056601079002 - 20 -2.103591135847005 - 10 -2.735759906135099 - 20 -2.150297292870786 - 42 --0.2679491924311215 - 10 -2.905437956246976 - 20 -2.165142198704758 - 42 --0.3152987888789877 - 10 -3.038801514311188 - 20 -1.93414974025938 - 42 --0.0857659994463428 - 10 -2.98610429311309 - 20 -1.734756081375588 - 42 --0.0017098342482428 - 0 -LWPOLYLINE - 5 -38C -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -2.169209475319699 - 20 -1.278410952985928 - 42 -0.2549125200517152 - 10 -3.219511504449442 - 20 -1.483099110977059 - 42 -0.0218867276949896 - 0 -LWPOLYLINE - 5 -44D -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -2.380970941004577 - 20 -3.751630247646181 - 42 -0.2679491924311219 - 10 -2.309791821489833 - 20 -3.828814460633206 - 0 -LWPOLYLINE - 5 -44E -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -2.028658926483394 - 20 -3.899981872009325 - 42 -0.1316524975873958 - 10 -1.971574507059384 - 20 -3.857657770838914 - 0 -LWPOLYLINE - 5 -44F -102 -{ACAD_REACTORS -330 -BFE -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 4 - 70 - 1 - 43 -0.0 - 10 -2.035890886983224 - 20 -3.881673417068221 - 42 -0.1316524975873958 - 10 -1.986991796041955 - 20 -3.84541816400579 - 42 --1.000000000000004 - 10 -1.956157218076813 - 20 -3.869897377672038 - 42 --0.1316524975873958 - 10 -2.021426965983563 - 20 -3.918290326950429 - 42 --1.0 - 0 -LWPOLYLINE - 5 -451 -102 -{ACAD_REACTORS -330 -BFD -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 4 - 70 - 1 - 43 -0.0 - 10 -2.36176616039695 - 20 -3.747308537705142 - 42 -0.2679491924311219 - 10 -2.303932141782747 - 20 -3.810021777782375 - 42 --1.000000000000003 - 10 -2.315651501196919 - 20 -3.847607143484037 - 42 --0.2679491924311219 - 10 -2.400175721612204 - 20 -3.755951957587221 - 42 --1.0 - 0 -LWPOLYLINE - 5 -480 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 15 - 70 - 0 - 43 -0.0 - 10 -2.164414868289778 - 20 -1.116788876483231 - 42 --0.1509933859269548 - 10 -2.011994434051636 - 20 -1.339405082556968 - 42 --0.1070963951594745 - 10 -1.964337309124437 - 20 -1.884128513074088 - 42 --0.0569571948585108 - 10 -1.999005825805648 - 20 -2.025855120814207 - 42 -0.1145587361047281 - 10 -2.02996377257399 - 20 -2.271091588487681 - 42 -0.1238858905685379 - 10 -1.988035257076031 - 20 -2.386289238049577 - 42 -0.3726487049030961 - 10 -1.897599265772163 - 20 -2.410521488886157 - 42 -0.1535645609181053 - 10 -1.752129598807603 - 20 -2.273262792103868 - 42 -0.013230494041686 - 10 -1.679912845283239 - 20 -2.135632504011972 - 42 --0.0334295576837925 - 10 -1.547372627715803 - 20 -1.906066113138941 - 42 -0.1212729089747999 - 10 -1.459245452693659 - 20 -1.663938689725279 - 42 -0.142060045402927 - 10 -1.535615350530265 - 20 -1.230823476558462 - 42 -0.2110002865385294 - 10 -1.767733703190374 - 20 -1.036053052451884 - 42 -0.0977925466168199 - 10 -1.905714464335645 - 20 -1.023981300066994 - 42 -0.1523642735345087 - 10 -2.225767565997291 - 20 -1.16312498070393 - 42 -0.0131161693340735 - 0 -LWPOLYLINE - 5 -489 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -1.726540556633805 - 20 -2.226489993047315 - 42 -0.1491830429238438 - 10 -1.791794192050712 - 20 -2.183894323205893 - 0 -LWPOLYLINE - 5 -48A -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -1.654521263715424 - 20 -2.085752782994799 - 42 -0.2936017206055124 - 10 -1.910780338072042 - 20 -1.973525769477851 - 0 -LWPOLYLINE - 5 -48B -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -1.551496630284455 - 20 -1.912244632638939 - 42 -0.2413057746814911 - 10 -1.835672170020508 - 20 -1.78904239903142 - 0 -LWPOLYLINE - 5 -48C -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -1.460547644534427 - 20 -1.674926403649493 - 42 -0.2628135643200116 - 10 -1.85610884645455 - 20 -1.543874911031386 - 0 -LWPOLYLINE - 5 -48D -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -1.476099861503821 - 20 -1.396361427764304 - 42 -0.4559232792117359 - 10 -1.995510222782983 - 20 -1.397313095656098 - 42 -0.0249343028351756 - 0 -LWPOLYLINE - 5 -48E -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -1.940182455435743 - 20 -1.155046537921709 - 42 --0.1735068790932082 - 10 -1.591939878857363 - 20 -1.147027352610094 - 42 --0.0902466536252015 - 0 -LWPOLYLINE - 5 -48F -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 5 - 70 - 0 - 43 -0.0 - 10 -1.685157252816573 - 20 -1.071176985228859 - 42 --0.0967671337827555 - 10 -1.386905873969099 - 20 -1.073654945933856 - 42 --0.1283919655451407 - 10 -0.9396849704065366 - 20 -1.293355139281928 - 42 --0.2277426076900994 - 10 -0.8184698262111015 - 20 -1.571535724136809 - 42 --0.2585706959153292 - 10 -0.9396146897297675 - 20 -1.77228158619182 - 42 --0.0016259949892818 - 0 -LWPOLYLINE - 5 -490 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 6 - 70 - 0 - 43 -0.0 - 10 -1.454805769320285 - 20 -1.564461529127514 - 42 --0.1581711632332484 - 10 -1.079130851571503 - 20 -1.639243530487171 - 42 --0.1439729528407531 - 10 -0.9262274383574314 - 20 -1.795491369527463 - 42 --0.2034041621669866 - 10 -0.9154532561194422 - 20 -1.918640836027165 - 42 --0.194428280448302 - 10 -1.041151067775051 - 20 -2.068441654648967 - 42 --0.1994742666452343 - 10 -1.19286906097098 - 20 -2.082870785844477 - 42 --0.0611756567655047 - 0 -LWPOLYLINE - 5 -492 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 5 - 70 - 0 - 43 -0.0 - 10 -1.527535040931072 - 20 -1.87410829973367 - 42 --0.1177728459219032 - 10 -1.312388080418405 - 20 -1.947278913508062 - 42 --0.1120190572174949 - 10 -1.206886139482316 - 20 -2.052780854444151 - 42 --0.6961980985337713 - 10 -1.357198164134302 - 20 -2.248853535690163 - 42 --0.1138630283068457 - 10 -1.650613743929805 - 20 -2.078374984748495 - 42 --0.0035904482483965 - 0 -LWPOLYLINE - 5 -4AD -102 -{ACAD_REACTORS -330 -BAE -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 5 - 70 - 1 - 43 -0.0 - 10 -2.991096081171635 - 20 -1.314895048081054 - 42 -0.0536325233126152 - 10 -3.198865278725419 - 20 -1.441471338442461 - 42 --0.1019234865027202 - 10 -3.147359585391412 - 20 -1.255070371967993 - 42 --0.1576175352251851 - 10 -3.084776667067298 - 20 -1.19248745364388 - 42 --0.0487853903884156 - 10 -2.898805094451518 - 20 -1.119232145882148 - 42 -0.1091929375390922 - 0 -LWPOLYLINE - 5 -4B5 -102 -{ACAD_REACTORS -330 -BBA -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 6 - 70 - 1 - 43 -0.0 - 10 -2.183868006181016 - 20 -1.294456920706576 - 42 -0.2503802653463202 - 10 -3.199550468590465 - 20 -1.49218169636237 - 42 -0.0087756063211912 - 10 -3.19859257272434 - 20 -1.508976604658183 - 42 -0.1202060689774955 - 10 -3.140975326177503 - 20 -1.686528485415947 - 42 -0.2542613217194215 - 10 -3.034045022847889 - 20 -1.747720550442733 - 42 --0.2349955175811071 - 10 -2.117425810875627 - 20 -1.531432319991749 - 42 -0.0576901279999135 - 0 -LWPOLYLINE - 5 -4B9 -102 -{ACAD_REACTORS -330 -BAD -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 5 - 70 - 1 - 43 -0.0 - 10 -2.714378415408047 - 20 -1.225693872673844 - 42 --0.0759384074577222 - 10 -2.650179425501943 - 20 -1.079126736500261 - 42 -0.0101996300129822 - 10 -2.726291014277126 - 20 -1.085686057566314 - 42 -0.0261370793966787 - 10 -2.832212463468567 - 20 -1.102630606438461 - 42 -0.1222814332374564 - 10 -2.945078532962091 - 20 -1.294462394011187 - 42 --0.0530654994633163 - 0 -LWPOLYLINE - 5 -4BA -102 -{ACAD_REACTORS -330 -BAC -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 4 - 70 - 1 - 43 -0.0 - 10 -2.385206484967541 - 20 -1.080514837710239 - 42 -0.0878528142492813 - 10 -2.44424140664477 - 20 -1.208278724252974 - 42 -0.0501038956066548 - 10 -2.671374519065504 - 20 -1.218555099887139 - 42 --0.0813315417893164 - 10 -2.600965728709292 - 20 -1.076545040917626 - 42 --0.0288327089816677 - 0 -LWPOLYLINE - 5 -4BC -102 -{ACAD_REACTORS -330 -BAB -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 4 - 70 - 1 - 43 -0.0 - 10 -2.204441612310571 - 20 -1.2474540192852 - 42 -0.0447207077553119 - 10 -2.404217085512474 - 20 -1.211187767388987 - 42 --0.0963940214031873 - 10 -2.341193762157614 - 20 -1.087133059592365 - 42 --0.1740198039637825 - 10 -2.242925650927047 - 20 -1.172774016895618 - 42 --0.0196351821885444 - 0 -LWPOLYLINE - 5 -4C0 -102 -{ACAD_REACTORS -330 -BAF -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 4 - 70 - 1 - 43 -0.0 - 10 -2.111590265540881 - 20 -1.573348926544125 - 42 -0.0291422971591348 - 10 -2.228085740598704 - 20 -1.551356274330868 - 42 -0.0473221239695471 - 10 -2.237652044114153 - 20 -1.619229653732975 - 42 --0.0287252676909968 - 10 -2.106626866510892 - 20 -1.626116355527945 - 42 -0.0123842072538969 - 0 -LWPOLYLINE - 5 -4C1 -102 -{ACAD_REACTORS -330 -BB0 -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 4 - 70 - 1 - 43 -0.0 - 10 -2.267503548545168 - 20 -1.547048928709969 - 42 -0.0533543951524521 - 10 -2.484089073429926 - 20 -1.550784222461052 - 42 -0.0768690501849397 - 10 -2.532391987223791 - 20 -1.659393561191435 - 42 --0.0566860153224456 - 10 -2.277093772004332 - 20 -1.620104770218732 - 42 --0.0458852076194563 - 0 -LWPOLYLINE - 5 -4C3 -102 -{ACAD_REACTORS -330 -BB1 -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 4 - 70 - 1 - 43 -0.0 - 10 -2.575978434475863 - 20 -1.672202312238555 - 42 --0.0711923834185597 - 10 -2.534187811152101 - 20 -1.558291292956125 - 42 -0.0701806584121727 - 10 -2.804649062203535 - 20 -1.646049204465365 - 42 -0.0880028594988734 - 10 -2.815004646385387 - 20 -1.779090298343385 - 42 --0.0574665063324246 - 0 -LWPOLYLINE - 5 -4C7 -102 -{ACAD_REACTORS -330 -BBB -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 7 - 70 - 1 - 43 -0.0 - 10 -2.10461778187463 - 20 -1.665965877260762 - 42 --0.0351389292849169 - 10 -2.110402761135924 - 20 -1.8160751267299 - 42 --0.0095038145827776 - 10 -2.117156173606469 - 20 -1.868640946110094 - 42 -0.1557808751637161 - 10 -2.680907394207461 - 20 -2.087858154687554 - 10 -2.747050780866419 - 20 -2.134172252628876 - 42 --0.2679491924311215 - 10 -2.897118699126096 - 20 -2.147301494235533 - 42 --0.2502096061484992 - 10 -3.017490352158867 - 20 -1.987010103205812 - 42 --0.2309255538296563 - 0 -LWPOLYLINE - 5 -4C8 -102 -{ACAD_REACTORS -330 -BBC -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 6 - 70 - 1 - 43 -0.0 - 10 -2.123645620818254 - 20 -1.90852967158985 - 42 -0.1535620368154201 - 10 -2.656669093820602 - 20 -2.118889842946778 - 42 -0.3249446074510534 - 10 -2.691929368331739 - 20 -2.250482978911167 - 42 -0.3057060432679023 - 10 -2.647289746908166 - 20 -2.281739978334781 - 42 -0.1122985838264234 - 10 -2.548658946753702 - 20 -2.261113013747846 - 42 -0.0661825067963756 - 10 -2.144771760651222 - 20 -2.006772737968957 - 42 -0.0180243406510753 - 0 -LWPOLYLINE - 5 -4C9 -102 -{ACAD_REACTORS -330 -C20 -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 17 - 70 - 1 - 43 -0.0 - 10 -1.795927086013099 - 20 -3.369886028656918 - 42 -0.1834763883041901 - 10 -1.690295415947398 - 20 -3.261663015221454 - 42 -0.1056357518612903 - 10 -1.604709116716065 - 20 -2.839179652083978 - 42 -0.1451314237734208 - 10 -1.66286553317314 - 20 -2.650418447574797 - 42 -0.1600067868781768 - 10 -1.84068071995552 - 20 -2.510595431459335 - 42 -0.1190176972929128 - 10 -1.970981934519221 - 20 -2.495925758296534 - 42 -0.0768957533116813 - 10 -2.081584776821197 - 20 -2.527526570382813 - 42 -0.0709021530444379 - 10 -2.238571559817636 - 20 -2.628895178831943 - 42 -0.2070922264234396 - 10 -2.385030570405729 - 20 -2.934064104435615 - 42 -0.0419975136654783 - 10 -2.374361839564172 - 20 -3.171537899281493 - 42 -0.2041023265544078 - 10 -2.30953573868931 - 20 -3.281794913306262 - 42 --0.0638786287537656 - 10 -2.253905428386551 - 20 -3.190122198930097 - 42 --0.4158687069147495 - 10 -2.110688753100606 - 20 -3.174368364648643 - 10 -2.049360338450518 - 20 -3.223826763560005 - 10 -2.020698206844207 - 20 -3.208114453397319 - 42 --0.275738643742557 - 10 -1.918435234414153 - 20 -3.198657998664349 - 42 --0.2118780432517558 - 10 -1.805265959929118 - 20 -3.331038401042169 - 42 --0.0269158367577847 - 0 -LWPOLYLINE - 5 -4CB -102 -{ACAD_REACTORS -330 -C28 -330 -C40 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 13 - 70 - 1 - 43 -0.0 - 10 -2.053553115266256 - 20 -3.271022854778554 - 10 -2.135403416533275 - 20 -3.205014547305152 - 42 -0.4158687069147495 - 10 -2.223120154016859 - 20 -3.214663388428346 - 42 -0.26959558438999 - 10 -2.279122382999181 - 20 -3.59460007917116 - 42 -0.5581360462772155 - 10 -2.145920537005866 - 20 -3.617785434351675 - 42 -0.0728307330332283 - 10 -2.101616152707511 - 20 -3.548832485588364 - 42 --0.9381223686609327 - 10 -2.064870809553132 - 20 -3.562742050811843 - 10 -2.082872800905891 - 20 -3.621344458486482 - 42 -0.2046959930292842 - 10 -2.062725504642901 - 20 -3.696637502728181 - 42 -0.3964961476078332 - 10 -1.972491420232154 - 20 -3.71032661793588 - 42 -0.3247796006490571 - 10 -1.842995028063519 - 20 -3.342286535008118 - 42 -0.2118780432517558 - 10 -1.935414224296555 - 20 -3.23417865466307 - 42 -0.2856103122495783 - 10 -1.999267568517967 - 20 -3.241264030153233 - 0 -LWPOLYLINE - 5 -4CD -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -1.541590875260533 - 20 -1.219181584929098 - 42 --0.2584842710932977 - 10 -0.820082757115996 - 20 -1.522632196851646 - 42 --0.0230272271526239 - 0 -LWPOLYLINE - 5 -4CE -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -1.458123574270783 - 20 -1.652827431708805 - 42 --0.2951443317480729 - 10 -0.941461714899275 - 20 -1.974891353638494 - 42 --0.0281477710443027 - 0 -LWPOLYLINE - 5 -4CF -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -1.149191552360515 - 20 -1.154795257187257 - 42 -0.1554073147032292 - 10 -0.735992563639889 - 20 -1.096559104863405 - 42 --0.383579166426189 - 10 -0.9194102381455578 - 20 -1.312304764434089 - 42 --0.023050174561539 - 0 -LWPOLYLINE - 5 -4D0 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -1.24989523667859 - 20 -1.240900333949516 - 42 -0.1256439210154252 - 10 -1.345357819803049 - 20 -1.083069957917427 - 42 -0.0704007111098051 - 0 -LWPOLYLINE - 5 -4D1 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -1.037864942416157 - 20 -1.3303917414282 - 42 -0.0872453218025478 - 10 -1.042370972787492 - 20 -1.21582065403204 - 42 -0.0971278145482142 - 0 -LWPOLYLINE - 5 -4D2 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -1.252136016103313 - 20 -1.688388482710066 - 42 -0.0590285034647111 - 10 -1.266518295486159 - 20 -1.571079816805446 - 42 -0.040710128897272 - 0 -LWPOLYLINE - 5 -4D3 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -1.052845021272466 - 20 -1.816519721371516 - 42 -0.1113687809723345 - 10 -1.031596064763292 - 20 -1.670646745988808 - 42 -0.1054872080523193 - 0 -LWPOLYLINE - 5 -4E7 -102 -{ACAD_REACTORS -330 -BB6 -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 4 - 70 - 1 - 43 -0.0 - 10 -1.055916139802069 - 20 -1.183858027338503 - 42 -0.1086902960134493 - 10 -0.7572717136065252 - 20 -1.127799089885956 - 42 --0.3246303955088655 - 10 -0.9126882033208936 - 20 -1.29130332219202 - 42 -0.0129078914938259 - 10 -0.9268235401588977 - 20 -1.278452643283383 - 42 -0.0398388581973403 - 0 -LWPOLYLINE - 5 -4EB -102 -{ACAD_REACTORS -330 -BA6 -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 4 - 70 - 1 - 43 -0.0 - 10 -1.060018004406812 - 20 -1.22781950439698 - 42 --0.056608990335621 - 10 -1.05478008384554 - 20 -1.297904456500116 - 42 -0.0588177228710549 - 10 -1.234398517271265 - 20 -1.224686922587824 - 42 -0.0753850106847673 - 10 -1.287966831577129 - 20 -1.11990052780729 - 42 --0.0655149355972575 - 0 -LWPOLYLINE - 5 -4EE -102 -{ACAD_REACTORS -330 -BB7 -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 6 - 70 - 1 - 43 -0.0 - 10 -0.9337884234626875 - 20 -1.745337488462597 - 42 -0.1140426130224996 - 10 -1.069517024899449 - 20 -1.622065780002278 - 42 -0.1496103246747427 - 10 -1.435800351452426 - 20 -1.542762378894283 - 42 -0.098469544262505 - 10 -1.511203238184653 - 20 -1.236207952572697 - 42 --0.2469581287149142 - 10 -0.8391304022153184 - 20 -1.53029339160826 - 42 --0.0306677320577088 - 10 -0.8381414565311932 - 20 -1.570809270042459 - 42 --0.2364748902496887 - 0 -LWPOLYLINE - 5 -4F0 -102 -{ACAD_REACTORS -330 -BA5 -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 4 - 70 - 1 - 43 -0.0 - 10 -0.8557672849696794 - 20 -1.451424859785045 - 42 -0.0630395648108045 - 10 -1.01685683292838 - 20 -1.320182987586002 - 42 -0.0445931465006306 - 10 -1.016312593127104 - 20 -1.257746897185134 - 42 --0.0210506403179615 - 10 -0.9525464006541762 - 20 -1.308257635280474 - 42 --0.1329522052869259 - 0 -LWPOLYLINE - 5 -4F3 -102 -{ACAD_REACTORS -330 -C01 -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 17 - 70 - 1 - 43 -0.0 - 10 -1.84986913761158 - 20 -2.466300860817559 - 42 -0.0673153145939977 - 10 -1.833988541120499 - 20 -2.395045529905472 - 42 --0.0456048674756574 - 10 -1.889008320037764 - 20 -2.428232966136522 - 42 --0.3726487049030961 - 10 -2.004330972949735 - 20 -2.397332354419744 - 42 --0.1238858905685379 - 10 -2.049545393540757 - 20 -2.273106754812188 - 42 --0.1145587361047281 - 10 -2.017472341220017 - 20 -2.019036867118983 - 42 -0.0569571948585108 - 10 -1.983866015583199 - 20 -1.881652548807571 - 42 -0.1070963951594745 - 10 -2.030796508895675 - 20 -1.345234555651572 - 42 -0.1426114747077699 - 10 -2.165557450307532 - 20 -1.141311124747446 - 42 -0.019413333947305 - 10 -2.200668024179765 - 20 -1.167752668813839 - 42 --0.1534467262547569 - 10 -2.071265337820281 - 20 -1.820348906815302 - 42 --0.082508630093775 - 10 -2.198159065568731 - 20 -2.272836703011166 - 42 -0.000862340954801 - 10 -2.261556633001577 - 20 -2.408793225114376 - 42 -0.0606801155133229 - 10 -2.360970556998814 - 20 -2.715554284918385 - 42 --0.0817679966984111 - 10 -2.264381007104979 - 20 -2.599165134588315 - 42 --0.0709021530444379 - 10 -2.098061012224078 - 20 -2.49176993789379 - 42 --0.0768957533116813 - 10 -1.97588297445437 - 20 -2.456861927102445 - 42 --0.1001198017354382 - 0 -LWPOLYLINE - 5 -4F4 -102 -{ACAD_REACTORS -330 -BB3 -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 11 - 70 - 1 - 43 -0.0 - 10 -1.985708655480637 - 20 -1.35859138415058 - 42 --0.3682846044885977 - 10 -1.514588534428652 - 20 -1.333441193996956 - 42 -0.0330251139842943 - 10 -1.553282361892708 - 20 -1.239505497320984 - 42 -0.0639008891509803 - 10 -1.603183045430495 - 20 -1.164065854453502 - 42 -0.1707629002601277 - 10 -1.933126177068946 - 20 -1.17342341770615 - 42 --1.000000000000009 - 10 -1.94723873380254 - 20 -1.136669658137267 - 42 --0.1354090889595181 - 10 -1.663131530982194 - 20 -1.10889954806288 - 42 -0.0869057462878126 - 10 -1.77321598022121 - 20 -1.054959279298051 - 42 -0.0977925466168199 - 10 -1.903598507249911 - 20 -1.043552286261177 - 42 -0.1070337225744706 - 10 -2.131038389154381 - 20 -1.11916439867858 - 42 --0.1361955436546222 - 10 -1.993192359207598 - 20 -1.333575609462363 - 42 --0.0049803061650251 - 0 -LWPOLYLINE - 5 -4F7 -102 -{ACAD_REACTORS -330 -BB4 -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 36 - 70 - 1 - 43 -0.0 - 10 -1.800080314455621 - 20 -2.308917195085585 - 42 -0.0437118087611369 - 10 -1.769312650034374 - 20 -2.26365844280057 - 42 -0.0033308209162503 - 10 -1.750572816609542 - 20 -2.229600425683039 - 42 -0.1199820129190778 - 10 -1.797274715454282 - 20 -2.202801058466759 - 42 --0.9999999999999999 - 10 -1.786313668647142 - 20 -2.164987587945027 - 42 --0.1021140647943497 - 10 -1.731552642365071 - 20 -2.193892004093673 - 42 -0.0064323953109214 - 10 -1.697579856645681 - 20 -2.12695048324945 - 42 --0.0055509425268816 - 10 -1.677510563493305 - 20 -2.087231690238655 - 42 -0.2805803818424905 - 10 -1.907675826757856 - 20 -1.99296446245093 - 42 --1.000000000000002 - 10 -1.913884849386228 - 20 -1.954087076504771 - 42 --0.2626963580826674 - 10 -1.65730585773017 - 20 -2.04932297149283 - 42 --0.0197119133471879 - 10 -1.576111447954835 - 20 -1.913814831608159 - 42 -0.229407728918388 - 10 -1.834403866994767 - 20 -1.808686537659429 - 42 --1.000000000000006 - 10 -1.836940473046249 - 20 -1.76939826040341 - 42 --0.2218376429216039 - 10 -1.55389731810562 - 20 -1.879874561474816 - 42 -0.1027759246248995 - 10 -1.481321802657222 - 20 -1.68147851322532 - 42 -0.2567981434431833 - 10 -1.852312329231318 - 20 -1.563190377165427 - 42 --0.9999999999999999 - 10 -1.859905363677781 - 20 -1.524559444897346 - 42 --0.2372321476697851 - 10 -1.476143434862462 - 20 -1.631501691187762 - 42 -0.0739602798598165 - 10 -1.494131551859586 - 20 -1.40568894806263 - 42 -0.4420288920812132 - 10 -1.973843248718476 - 20 -1.402603074502723 - 42 --0.0932841665178725 - 10 -1.944808602665675 - 20 -1.886604477340606 - 42 --0.0569571948585108 - 10 -1.98053931039128 - 20 -2.032673374509431 - 42 -0.1145587361047281 - 10 -2.010382151607223 - 20 -2.269076422163175 - 42 -0.1238858905685379 - 10 -1.971739541202327 - 20 -2.375246121679411 - 42 -0.3726487049030961 - 10 -1.906190211506561 - 20 -2.392810011635793 - 42 -0.0692252662755674 - 10 -1.834372402647776 - 20 -2.344740013080819 - 42 -0.0476713025068407 - 10 -1.844432384008702 - 20 -2.293909862021855 - 42 -0.0769094708198934 - 10 -1.896548904341149 - 20 -2.184396525477287 - 42 --0.3080726058837938 - 10 -1.896548904341149 - 20 -2.019062825471532 - 42 --0.9999999999999999 - 10 -1.864004169282495 - 20 -2.041217809560179 - 42 -0.2582998793018828 - 10 -1.873587490264647 - 20 -2.144928461209456 - 42 --0.2026932661734018 - 10 -1.803462564620088 - 20 -2.048315057803096 - 42 --0.999999999999995 - 10 -1.783120572852258 - 20 -2.082022719705455 - 42 -0.3646986474062371 - 10 -1.830429247500239 - 20 -2.220863495048448 - 42 --0.0379960309145583 - 10 -1.806713675981244 - 20 -2.282627035924392 - 42 --0.0217555693507311 - 0 -LWPOLYLINE - 5 -505 -102 -{ACAD_REACTORS -330 -BB8 -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 7 - 70 - 1 - 43 -0.0 - 10 -1.496545734250796 - 20 -1.858090362879029 - 42 -0.0874292139153708 - 10 -1.440409322525223 - 20 -1.672501008241135 - 42 --0.2810079005908725 - 10 -0.963992618224232 - 20 -1.973488406523313 - 42 --0.1221105918102025 - 10 -1.050391027094316 - 20 -2.051059942225276 - 42 --0.1855272393840248 - 10 -1.177801591011496 - 20 -2.066644978446405 - 42 -0.0452485050555582 - 10 -1.190231879786862 - 20 -2.04228626493346 - 42 -0.1120190572174949 - 10 -1.301893490907713 - 20 -1.930624653812608 - 42 -0.1031607726849441 - 0 -LWPOLYLINE - 5 -507 -102 -{ACAD_REACTORS -330 -BA9 -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 5 - 70 - 1 - 43 -0.0 - 10 -1.232680305288136 - 20 -1.674823294981787 - 42 -0.0376631697644602 - 10 -1.24092624183496 - 20 -1.596731177563018 - 42 --0.0683286784235571 - 10 -1.088744678243557 - 20 -1.656421280972064 - 42 --0.0308076295927463 - 10 -1.050667583615558 - 20 -1.680925971586079 - 42 --0.0803202890882193 - 10 -1.061814443246697 - 20 -1.780967062069061 - 42 -0.0873178465018551 - 0 -LWPOLYLINE - 5 -509 -102 -{ACAD_REACTORS -330 -BA8 -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 5 - 70 - 1 - 43 -0.0 - 10 -1.03011243645825 - 20 -1.811587717464269 - 42 -0.0701949736097343 - 10 -1.011360717734072 - 20 -1.714273589617648 - 42 --0.0772792890158624 - 10 -0.9436091507811217 - 20 -1.804731328846728 - 42 --0.2034041621669866 - 10 -0.9341754033724281 - 20 -1.912559555139139 - 42 --0.021365350595909 - 10 -0.9413736096183022 - 20 -1.931870968260919 - 42 -0.0646639173137995 - 0 -LWPOLYLINE - 5 -50B -102 -{ACAD_REACTORS -330 -BB9 -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 6 - 70 - 1 - 43 -0.0 - 10 -1.517012100394491 - 20 -1.895029973752357 - 42 --0.1110664831625005 - 10 -1.322882669929097 - 20 -1.963933173203516 - 42 --0.1120190572174949 - 10 -1.22354039917777 - 20 -2.063275443954843 - 42 --0.6961980985337713 - 10 -1.351388497511153 - 20 -2.230045331397104 - 42 --0.1086664830114359 - 10 -1.62603521686569 - 20 -2.074220841935225 - 42 --0.0233827832969574 - 10 -1.531020271498053 - 20 -1.917025183406504 - 42 -0.0116709324309886 - 0 -LWPOLYLINE - 5 -510 -102 -{ACAD_REACTORS -330 -BB2 -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 4 - 70 - 1 - 43 -0.0 - 10 -2.84997659259958 - 20 -1.669588479790926 - 42 -0.0790070326196522 - 10 -2.851886405500074 - 20 -1.80192109397708 - 42 -0.0465967056483061 - 10 -3.018962226551324 - 20 -1.933310565196752 - 42 --0.0825476832350667 - 10 -2.970238833200536 - 20 -1.747438830578402 - 42 --0.0352296221604151 - 0 -LWPOLYLINE - 5 -559 -102 -{ACAD_REACTORS -330 -BA7 -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 5 - 70 - 1 - 43 -0.0 - 10 -1.355385427777645 - 20 -1.100872595462885 - 42 --0.0964781721945481 - 10 -1.280659164315312 - 20 -1.213328327577104 - 42 -0.0761322456062632 - 10 -1.530692586565761 - 20 -1.198306536487731 - 42 -0.0982025130561956 - 10 -1.632063828471465 - 20 -1.082968026772228 - 42 --0.0801281899540377 - 10 -1.390840639583887 - 20 -1.092942724306655 - 42 --0.009398208639944 - 0 -LWPOLYLINE - 5 -620 -102 -{ACAD_REACTORS -330 -BAA -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 4 - 70 - 1 - 43 -0.0 - 10 -1.272750873165488 - 20 -1.660423889558836 - 42 -0.0720111964992741 - 10 -1.436797603060258 - 20 -1.633190144890045 - 42 -0.0157631540077514 - 10 -1.434991753420616 - 20 -1.582208383349729 - 42 --0.0636343006390252 - 10 -1.282776238934902 - 20 -1.588169636138475 - 42 --0.0378416081317004 - 0 -LWPOLYLINE - 5 -8B3 -102 -{ACAD_REACTORS -330 -C28 -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 48 - 70 - 1 - 43 -0.0 - 10 -3.027996198643118 - 20 -1.787090153383295 - 42 --0.2652120571486825 - 10 -3.174476318719514 - 20 -1.707209070482774 - 42 --0.1202060689774955 - 10 -3.237853374949089 - 20 -1.511907902779382 - 42 --0.1376749084255928 - 10 -3.182411796088231 - 20 -1.237144256235018 - 42 --0.1576175352251852 - 10 -3.102702782800273 - 20 -1.157435242947061 - 42 --0.091849210681774 - 10 -2.73047077837241 - 20 -1.046538482007744 - 42 --0.0506776859186796 - 10 -2.34388013009181 - 20 -1.044567731825123 - 42 --0.1678583337512084 - 10 -2.221067012551395 - 20 -1.133620430754517 - 42 --0.1427259380349648 - 10 -1.907830421421379 - 20 -1.004410313872811 - 42 --0.0977925466168198 - 10 -1.762251426159538 - 20 -1.017146825605717 - 42 --0.0554068829065345 - 10 -1.681692239060136 - 20 -1.050537537701288 - 42 --0.0944908669632265 - 10 -1.382971108354313 - 20 -1.054367167561056 - 42 --0.063211812705244 - 10 -1.14310982680291 - 20 -1.135855466777803 - 42 -0.1543252686721255 - 10 -0.7445258947417084 - 20 -1.078819797230121 - 42 --0.5434510775266247 - 10 -0.7163152163407374 - 20 -1.096008851948713 - 42 --0.3401781029993987 - 10 -0.8820862850200285 - 20 -1.324403005153777 - 42 --0.182531460234485 - 10 -0.79879819589101 - 20 -1.572262178231159 - 42 --0.2383486190805098 - 10 -0.9129246094229353 - 20 -1.778768451782942 - 42 --0.0052329189934023 - 10 -0.9088457259337407 - 20 -1.786251410208198 - 42 --0.2034041621669866 - 10 -0.8967311088664565 - 20 -1.92472211691519 - 42 --0.194428280448302 - 10 -1.031911108455786 - 20 -2.085823367072657 - 42 --0.1617232608950327 - 10 -1.167586754433075 - 20 -2.108823943952719 - 42 --0.5347302517393296 - 10 -1.363007830757451 - 20 -2.267661739983221 - 42 --0.105444424534756 - 10 -1.644986728674037 - 20 -2.110043533348865 - 42 -0.0048822169168032 - 10 -1.662245833920796 - 20 -2.144314524774496 - 42 --0.013230494041686 - 10 -1.734946547580834 - 20 -2.282867141407166 - 42 --0.0694197792179022 - 10 -1.793844951212572 - 20 -2.360618102610478 - 42 --0.097214664119097 - 10 -1.812670378378858 - 20 -2.479214960413685 - 42 --0.1500723642402677 - 10 -1.630088324202255 - 20 -2.628608870043696 - 42 --0.1451314237734207 - 10 -1.565341256716473 - 20 -2.838761681919137 - 42 --0.1056357518612903 - 10 -1.65419402894681 - 20 -3.277369477478751 - 42 --0.1962234048498945 - 10 -1.790739940431784 - 20 -3.410546342344788 - 42 --0.2655031168224304 - 10 -1.950118462130682 - 20 -3.742721892989442 - 42 --0.3964961476078332 - 10 -2.093699839480827 - 20 -3.720939635995741 - 42 --0.1405234862865436 - 10 -2.122456164203622 - 20 -3.650189734969364 - 42 --0.5343574555981587 - 10 -2.315679239916688 - 20 -3.609215116369852 - 42 --0.1773163153754776 - 10 -2.324179645939324 - 20 -3.319578756296038 - 42 --0.2178846001444296 - 10 -2.413405596162056 - 20 -3.176596374420452 - 42 --0.0419776577731284 - 10 -2.424375140175325 - 20 -2.932642516763373 - 42 --0.1021560486223639 - 10 -2.297266684995574 - 20 -2.392216274653201 - 42 --0.0008623409548011 - 10 -2.233811725316336 - 20 -2.256136674480434 - 42 -0.0354069305283612 - 10 -2.162996833972185 - 20 -2.072072274041452 - 42 --0.0586147259804529 - 10 -2.532253084928835 - 20 -2.296901989673256 - 42 --0.1122985838264234 - 10 -2.647978623445294 - 20 -2.321104029817356 - 42 --0.3057060432679023 - 10 -2.728683867382189 - 20 -2.264593609639688 - 42 --0.1508928720957283 - 10 -2.734821253334247 - 20 -2.173180071930798 - 42 --0.2505867392793861 - 10 -2.913757213367856 - 20 -2.182982903173984 - 42 --0.3152987888789875 - 10 -3.058411646163387 - 20 -1.932434076032064 - 42 --0.0595813595316129 - 0 -HATCH - 5 -BA5 -330 -1F -100 -AcDbEntity - 8 -HATCH-YELLOW -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 4 - 72 - 2 - 10 -1.454717916970981 - 20 -2.022108206218515 - 40 -0.8272976136018175 - 50 -223.615566083045 - 51 -238.0440774153107 - 73 - 1 - 72 - 2 - 10 -1.365920530767478 - 20 -1.285919869338796 - 40 -0.3507412528077177 - 50 -174.3939645983117 - 51 -184.6071947080589 - 73 - 1 - 72 - 2 - 10 -1.584035429735767 - 20 -2.039961850738251 - 40 -0.9665244191271588 - 50 -125.9717238731088 - 51 -130.7954628287447 - 73 - 0 - 72 - 2 - 10 -1.168606309785878 - 20 -1.558605525778289 - 40 -0.3306901126594289 - 50 -130.7954628287448 - 51 -161.0882096390424 - 73 - 0 - 97 - 1 -330 -4F0 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BA6 -330 -1F -100 -AcDbEntity - 8 -HATCH-YELLOW -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 4 - 72 - 2 - 10 -1.365920530767478 - 20 -1.285919869338796 - 40 -0.3113711740675595 - 50 -169.2458500319289 - 51 -182.205842988757 - 73 - 0 - 72 - 2 - 10 -1.454717916970979 - 20 -2.022108206218515 - 40 -0.827297613601817 - 50 -241.09054843511 - 51 -254.5550649161042 - 73 - 1 - 72 - 2 - 10 -1.606711922375474 - 20 -1.348933253591385 - 40 -0.3924976718251174 - 50 -198.4545948543501 - 51 -215.6989500329358 - 73 - 1 - 72 - 2 - 10 -1.584035429735761 - 20 -2.039961850738243 - 40 -0.9665244191271488 - 50 -107.8377726397921 - 51 -122.8312626374707 - 73 - 0 - 97 - 1 -330 -4EB - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BA7 -330 -1F -100 -AcDbEntity - 8 -HATCH-YELLOW -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 5 - 72 - 2 - 10 -1.606711922375474 - 20 -1.348933253591385 - 40 -0.3531275930849602 - 50 -135.3746912145926 - 51 -157.4176362906217 - 73 - 0 - 72 - 2 - 10 -1.454717916970981 - 20 -2.022108206218514 - 40 -0.827297613601817 - 50 -257.8545362072944 - 51 -275.2691677284761 - 73 - 1 - 72 - 2 - 10 -1.872170704325741 - 20 -1.396215376152876 - 40 -0.3946836881941063 - 50 -210.0950891144055 - 51 -232.5295145799341 - 73 - 1 - 72 - 2 - 10 -1.542373482613905 - 20 -1.835739673019258 - 40 -0.75809597646572 - 50 -83.20542127045559 - 51 -101.5302981560868 - 73 - 0 - 72 - 2 - 10 -1.584035429735767 - 20 -2.039961850738253 - 40 -0.9665244191271609 - 50 -101.5302981560871 - 51 -103.684145503982 - 73 - 0 - 97 - 1 -330 -559 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BA8 -330 -1F -100 -AcDbEntity - 8 -HATCH-YELLOW -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 5 - 72 - 2 - 10 -1.365613936631296 - 20 -1.696475315724716 - 40 -0.3547000446188475 - 50 -161.0626247765776 - 51 -177.1237827075663 - 73 - 1 - 72 - 2 - 10 -1.26836984905495 - 20 -1.977371145189359 - 40 -0.3677961627452389 - 50 -134.3293201388803 - 51 -152.0052969205894 - 73 - 0 - 72 - 2 - 10 -1.065938622495786 - 20 -1.869760556959495 - 40 -0.1385398865270621 - 50 -152.0052969205897 - 51 -197.9947030794107 - 73 - 0 - 72 - 2 - 10 -1.163637847655055 - 20 -1.838026139816656 - 40 -0.2412638458944715 - 50 -197.9947030794104 - 51 -202.8905358909278 - 73 - 0 - 72 - 2 - 10 -1.448830865211249 - 20 -2.213371853903019 - 40 -0.5803064835681331 - 50 -209.0183706588869 - 51 -223.8176444671686 - 73 - 1 - 97 - 1 -330 -509 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BA9 -330 -1F -100 -AcDbEntity - 8 -HATCH-YELLOW -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 5 - 72 - 2 - 10 -1.75442661167109 - 20 -1.690434343062299 - 40 -0.5219798013778194 - 50 -181.7138221824677 - 51 -190.3415069086127 - 73 - 1 - 72 - 2 - 10 -1.382209127764958 - 20 -2.180776385554784 - 40 -0.6008907212088186 - 50 -103.5988396513469 - 51 -119.2343164314062 - 73 - 0 - 72 - 2 - 10 -1.26836984905495 - 20 -1.977371145189357 - 40 -0.3677961627452375 - 50 -119.2343164314065 - 51 -126.2926725539458 - 73 - 0 - 72 - 2 - 10 -1.365613936631298 - 20 -1.696475315724717 - 40 -0.3153299658786926 - 50 -177.17352188641 - 51 -195.5421431149888 - 73 - 0 - 72 - 2 - 10 -1.448830865211245 - 20 -2.213371853903018 - 40 -0.5803064835681301 - 50 -228.1704174204192 - 51 -248.1315658423051 - 73 - 1 - 97 - 1 -330 -507 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BAA -330 -1F -100 -AcDbEntity - 8 -HATCH-YELLOW -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 4 - 72 - 2 - 10 -1.448830865211245 - 20 -2.213371853903018 - 40 -0.5803064835681306 - 50 -252.3365152710513 - 51 -268.8118268997819 - 73 - 1 - 72 - 2 - 10 -2.244252791706375 - 20 -1.579066020312691 - 40 -0.8092671391653076 - 50 -176.1651718242215 - 51 -179.7775214345853 - 73 - 1 - 72 - 2 - 10 -1.382209127764961 - 20 -2.180776385554781 - 40 -0.6008907212088166 - 50 -84.96060718028212 - 51 -99.52487731460255 - 73 - 0 - 72 - 2 - 10 -1.754426611671092 - 20 -1.690434343062297 - 40 -0.4826097226376628 - 50 -167.7663152513758 - 51 -176.4348368363554 - 73 - 0 - 97 - 1 -330 -620 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BAB -330 -1F -100 -AcDbEntity - 8 -HATCH-YELLOW -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 4 - 72 - 2 - 10 -2.506661351932914 - 20 -2.343882490801417 - 40 -1.137317969685164 - 50 -254.5896536710559 - 51 -264.8320604814776 - 73 - 1 - 72 - 2 - 10 -2.053956362533489 - 20 -1.311094011306244 - 40 -0.3642304650017842 - 50 -15.91994768566973 - 51 -37.94378452603665 - 73 - 0 - 72 - 2 - 10 -2.41136725018985 - 20 -1.266852136052575 - 40 -0.1929333171495304 - 50 -111.3287610035634 - 51 -150.8157377309437 - 73 - 0 - 72 - 2 - 10 -3.174161319020494 - 20 -1.699913413586516 - 40 -1.070082152487879 - 50 -150.4873427015391 - 51 -154.9868167954895 - 73 - 0 - 97 - 1 -330 -4BC - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BAC -330 -1F -100 -AcDbEntity - 8 -HATCH-YELLOW -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 4 - 72 - 2 - 10 -2.05395636253349 - 20 -1.311094011306242 - 40 -0.40360054374194 - 50 -325.1586938734879 - 51 -345.2415144983743 - 73 - 1 - 72 - 2 - 10 -2.506661351932912 - 20 -2.343882490801414 - 40 -1.137317969685161 - 50 -266.8538285473494 - 51 -278.3272010683704 - 73 - 1 - 72 - 2 - 10 -2.202541654133556 - 20 -1.362543685931675 - 40 -0.4904456831815359 - 50 -17.0728403884595 - 51 -35.67171941040231 - 73 - 0 - 72 - 2 - 10 -2.527478440588521 - 20 -2.947760106017855 - 40 -1.87265752378095 - 50 -87.75100742187989 - 51 -94.35714735717728 - 73 - 0 - 97 - 1 -330 -4BA - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BAD -330 -1F -100 -AcDbEntity - 8 -HATCH-YELLOW -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 5 - 72 - 2 - 10 -2.202541654133554 - 20 -1.362543685931673 - 40 -0.5298157619216942 - 50 -14.96903515149527 - 51 -32.33949759932654 - 73 - 0 - 72 - 2 - 10 -2.527478440588518 - 20 -2.947760106017868 - 40 -1.872657523780963 - 50 -273.7568474686516 - 51 -276.0943494215687 - 73 - 1 - 72 - 2 - 10 -2.617288604059703 - 20 -2.10660015529557 - 40 -1.026716669960875 - 50 -276.0943494215687 - 51 -282.0831632762506 - 73 - 1 - 72 - 2 - 10 -2.502316662315184 - 20 -1.425846770903515 - 40 -0.4618440522407246 - 50 -315.5859663701619 - 51 -343.4723636742463 - 73 - 1 - 72 - 2 - 10 -2.506661351932922 - 20 -2.3438824908014 - 40 -1.137317969685146 - 50 -67.32624731613089 - 51 -79.47656760874074 - 73 - 0 - 97 - 1 -330 -4B9 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BAE -330 -1F -100 -AcDbEntity - 8 -HATCH-YELLOW -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 5 - 72 - 2 - 10 -2.506661351932912 - 20 -2.343882490801413 - 40 -1.137317969685161 - 50 -295.2104838476032 - 51 -307.4903876208237 - 73 - 1 - 72 - 2 - 10 -2.72065401068705 - 20 -1.473292657067691 - 40 -0.4792688318657009 - 50 -3.806985506611603 - 51 -27.08574039713036 - 73 - 0 - 72 - 2 - 10 -3.019270278182163 - 20 -1.32057676085313 - 40 -0.1438678477148946 - 50 -27.08574039713062 - 51 -62.91425960287042 - 73 - 0 - 72 - 2 - 10 -2.617288604059699 - 20 -2.106600155295566 - 40 -1.026716669960872 - 50 -62.91425960286999 - 51 -74.08618998756283 - 73 - 0 - 72 - 2 - 10 -2.502316662315185 - 20 -1.425846770903515 - 40 -0.5012141309808816 - 50 -322.28430360547 - 51 -347.21072780023 - 73 - 1 - 97 - 1 -330 -4AD - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BAF -330 -1F -100 -AcDbEntity - 8 -HATCH-YELLOW -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 4 - 72 - 2 - 10 -2.358343856922912 - 20 -2.56087150497244 - 40 -1.017884167165223 - 50 -255.9706947110459 - 51 -262.6477274601202 - 73 - 1 - 72 - 2 - 10 -1.875100795739507 - 20 -1.635718008880588 - 40 -0.3629259890852237 - 50 -346.5587102880505 - 51 -357.396057379031 - 73 - 1 - 72 - 2 - 10 -2.23202592329045 - 20 -2.762062415766459 - 40 -1.142846610535554 - 50 -89.71793740532951 - 51 -96.29947398788597 - 73 - 0 - 72 - 2 - 10 -3.174161319020505 - 20 -1.699913413586497 - 40 -1.070082152487882 - 50 -183.9544802865682 - 51 -186.7925864334441 - 73 - 1 - 97 - 1 -330 -4C0 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BB0 -330 -1F -100 -AcDbEntity - 8 -HATCH-YELLOW -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 4 - 72 - 2 - 10 -2.35834385692291 - 20 -2.560871504972433 - 40 -1.017884167165215 - 50 -264.8798691909198 - 51 -277.0962125668474 - 73 - 1 - 72 - 2 - 10 -2.157099264484859 - 20 -1.761255447038774 - 40 -0.3888707645596128 - 50 -327.2321171951457 - 51 -344.8146293833702 - 73 - 1 - 72 - 2 - 10 -2.232025923290449 - 20 -2.762062415766465 - 40 -1.14284661053556 - 50 -74.76238100741742 - 51 -87.73997032522614 - 73 - 0 - 72 - 2 - 10 -1.875100795739506 - 20 -1.635718008880588 - 40 -0.4022960678253824 - 50 -2.224226079808037 - 51 -12.73296995122379 - 73 - 0 - 97 - 1 -330 -4C1 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BB1 -330 -1F -100 -AcDbEntity - 8 -HATCH-YELLOW -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 4 - 72 - 2 - 10 -2.157099264484858 - 20 -1.761255447038777 - 40 -0.4282408432997721 - 50 -12.00230574940428 - 51 -28.29091643485702 - 73 - 0 - 72 - 2 - 10 -2.358343856922911 - 20 -2.560871504972434 - 40 -1.017884167165216 - 50 -279.9480036533407 - 51 -296.005896865796 - 73 - 1 - 72 - 2 - 10 -2.43480848147727 - 20 -1.74176023846554 - 40 -0.3820244196138822 - 50 -345.4907424301736 - 51 -365.6076870699981 - 73 - 1 - 72 - 2 - 10 -2.232025923290445 - 20 -2.762062415766465 - 40 -1.142846610535562 - 50 -59.32877074017064 - 51 -72.48465458233305 - 73 - 0 - 97 - 1 -330 -4C3 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BB2 -330 -1F -100 -AcDbEntity - 8 -HATCH-YELLOW -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 4 - 72 - 2 - 10 -2.434808481477273 - 20 -1.741760238465535 - 40 -0.4213944983540373 - 50 -350.138398092684 - 51 -368.2079411900966 - 73 - 1 - 72 - 2 - 10 -2.232025923290449 - 20 -2.76206241576646 - 40 -1.142846610535555 - 50 -302.8460023643591 - 51 -313.5174616433824 - 73 - 1 - 72 - 2 - 10 -2.435514026542539 - 20 -1.986930556286178 - 40 -0.5859069085937808 - 50 -5.250840664227033 - 51 -24.12657987446927 - 73 - 0 - 72 - 2 - 10 -2.358343856922903 - 20 -2.560871504972432 - 40 -1.017884167165218 - 50 -53.04812421612736 - 51 -61.11882105703474 - 73 - 0 - 97 - 1 -330 -510 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BB3 -330 -1F -100 -AcDbEntity - 8 -HATCH-YELLOW -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 11 - 72 - 2 - 10 -1.735391678484751 - 20 -1.622446814297793 - 40 -0.3637008069698632 - 50 -46.50828210019076 - 51 -127.3801843342055 - 73 - 0 - 72 - 2 - 10 -2.244252791706377 - 20 -1.579066020312692 - 40 -0.7698970604251519 - 50 -198.604632170139 - 51 -206.170680909061 - 73 - 1 - 72 - 2 - 10 -1.87217070432574 - 20 -1.396215376152875 - 40 -0.3553136094539483 - 50 -206.170680909061 - 51 -220.7958011940912 - 73 - 1 - 72 - 2 - 10 -1.754854449164134 - 20 -1.637701886096329 - 40 -0.4973281664865742 - 50 -252.2434918237404 - 51 -291.0055844420299 - 73 - 1 - 72 - 2 - 10 -1.940182455435743 - 20 -1.155046537921708 - 40 -0.0196850393700786 - 50 -248.9944155579697 - 51 -428.9944155579707 - 73 - 0 - 72 - 2 - 10 -1.754854449164133 - 20 -1.637701886096329 - 40 -0.5366982452267322 - 50 -68.99441555797011 - 51 -99.84027979757452 - 73 - 0 - 72 - 2 - 10 -1.872170704325739 - 20 -1.396215376152874 - 40 -0.3553136094539469 - 50 -233.9619057741986 - 51 -253.8293190909382 - 73 - 1 - 72 - 2 - 10 -1.867289566555308 - 20 -1.379382243234548 - 40 -0.3377870618823355 - 50 -253.8293190909384 - 51 -276.1706809090611 - 73 - 1 - 72 - 2 - 10 -1.842733556184505 - 20 -1.606506575382589 - 40 -0.5662349988373994 - 50 -276.170680909061 - 51 -300.6079669543535 - 73 - 1 - 72 - 2 - 10 -2.448387279831183 - 20 -1.47470612641788 - 40 -0.4765713362946238 - 50 -131.7514141291648 - 51 -162.7742566190203 - 73 - 0 - 72 - 2 - 10 -3.245154141911026 - 20 -1.721739021653879 - 40 -1.31075517924367 - 50 -162.7742566190193 - 51 -163.9156492780123 - 73 - 0 - 97 - 1 -330 -4F4 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BB4 -330 -1F -100 -AcDbEntity - 8 -HATCH-YELLOW -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 36 - 72 - 2 - 10 -2.043049297315998 - 20 -2.110655210550977 - 40 -0.3135948678531067 - 50 -140.7856547310828 - 51 -150.7972901196548 - 73 - 1 - 72 - 2 - 10 -4.316192387813921 - 20 -0.8400973818280717 - 40 -2.91772556849152 - 50 -150.7972901196538 - 51 -151.5606552199046 - 73 - 1 - 72 - 2 - 10 -1.82896029060598 - 20 -2.312110103765454 - 40 -0.1138088004365485 - 50 -226.4676036039469 - 51 -253.8346334294888 - 73 - 1 - 72 - 2 - 10 -1.791794192050712 - 20 -2.183894323205893 - 40 -0.0196850393700787 - 50 -286.1653665705111 - 51 -466.1653665705111 - 73 - 0 - 72 - 2 - 10 -1.82896029060598 - 20 -2.312110103765454 - 40 -0.153178879176706 - 50 -106.1653665705111 - 51 -129.487348884315 - 73 - 0 - 72 - 2 - 10 -4.31619238781396 - 20 -0.8400973818280881 - 40 -2.917725568491546 - 50 -152.3551430085055 - 51 -153.8293190909382 - 73 - 1 - 72 - 2 - 10 --0.1012307034243785 - 20 -3.010931950741638 - 40 -2.004281084551068 - 50 -26.17068090906094 - 51 -27.44285015917365 - 73 - 0 - 72 - 2 - 10 -1.869973878918131 - 20 -2.229032723885394 - 40 -0.2390599525801008 - 50 -216.3816426472188 - 51 -279.0739534633693 - 73 - 1 - 72 - 2 - 10 -1.910780338072042 - 20 -1.973525769477851 - 40 -0.0196850393700789 - 50 -260.9260465366305 - 51 -440.9260465366307 - 73 - 0 - 72 - 2 - 10 -1.869973878918132 - 20 -2.229032723885395 - 40 -0.278430031320259 - 50 -80.92604653663092 - 51 -139.8013610445865 - 73 - 0 - 72 - 2 - 10 --0.101230703424352 - 20 -3.01093195074165 - 40 -2.004281084551049 - 50 -28.67087156360686 - 51 -33.18792433993601 - 73 - 0 - 72 - 2 - 10 -1.813793246529746 - 20 -2.127914574971419 - 40 -0.3198926968250738 - 50 -222.0119914468626 - 51 -273.6941141002521 - 73 - 1 - 72 - 2 - 10 -1.835672170020508 - 20 -1.78904239903142 - 40 -0.0196850393700788 - 50 -266.3058858997472 - 51 -446.3058858997478 - 73 - 0 - 72 - 2 - 10 -1.813793246529746 - 20 -2.127914574971419 - 40 -0.3592627755652315 - 50 -86.30588589974785 - 51 -136.3371185375852 - 73 - 0 - 72 - 2 - 10 -1.995105659775399 - 20 -1.606003070595645 - 40 -0.5192979821599312 - 50 -148.1708625321174 - 51 -171.6429565217715 - 73 - 1 - 72 - 2 - 10 -1.774379750743404 - 20 -1.9596864265737 - 40 -0.4040824222682091 - 50 -223.5109336967462 - 51 -281.1199173397384 - 73 - 1 - 72 - 2 - 10 -1.85610884645455 - 20 -1.543874911031386 - 40 -0.0196850393700787 - 50 -258.8800826602615 - 51 -438.8800826602615 - 73 - 0 - 72 - 2 - 10 -1.774379750743404 - 20 -1.9596864265737 - 40 -0.4434525010083663 - 50 -78.88008266026162 - 51 -132.2628434475095 - 73 - 0 - 72 - 2 - 10 -2.244252791706375 - 20 -1.579066020312694 - 40 -0.7698970604251502 - 50 -176.0947114644605 - 51 -193.0143530481955 - 73 - 1 - 72 - 2 - 10 -1.735391678484751 - 20 -1.622446814297793 - 40 -0.3243307282297058 - 50 -221.9378076910892 - 51 -317.3250616801697 - 73 - 1 - 72 - 2 - 10 -3.245154141910992 - 20 -1.721739021653846 - 40 -1.310755179243628 - 50 -165.9082787983328 - 51 -187.2257433809798 - 73 - 0 - 72 - 2 - 10 -2.601728566753492 - 20 -1.803316300498068 - 40 -0.6621787973190414 - 50 -187.2257433809798 - 51 -200.265282453191 - 73 - 0 - 72 - 2 - 10 -1.486332025585369 - 20 -2.215145842661859 - 40 -0.5268178451693419 - 50 -339.734717546809 - 51 -365.875687911445 - 73 - 1 - 72 - 2 - 10 -1.780100104900293 - 20 -2.245377841414935 - 40 -0.231498258665186 - 50 -5.875687911445098 - 51 -34.12431208855465 - 73 - 1 - 72 - 2 - 10 -1.928818024879454 - 20 -2.346159501416084 - 40 -0.0518487033762426 - 50 -34.12431208855484 - 51 -115.8756879114452 - 73 - 1 - 72 - 2 - 10 -2.043049297315996 - 20 -2.110655210550977 - 40 -0.3135948678531048 - 50 -115.8756879114451 - 51 -131.7156800642676 - 73 - 1 - 72 - 2 - 10 -2.105362384851459 - 20 -2.371962053549119 - 40 -0.2723538322513749 - 50 -185.7363493931126 - 51 -196.6535421822968 - 73 - 1 - 72 - 2 - 10 -2.224366300494004 - 20 -2.407559786221583 - 40 -0.3965678834278744 - 50 -196.6535421822967 - 51 -214.2452636527788 - 73 - 1 - 72 - 2 - 10 -1.775114796299714 - 20 -2.101729675474409 - 40 -0.1469014999420266 - 50 -325.7547363472213 - 51 -394.2452636527789 - 73 - 0 - 72 - 2 - 10 -1.880276536811822 - 20 -2.030140317515856 - 40 -0.0196850393700786 - 50 -34.24526365277875 - 51 -214.2452636527787 - 73 - 0 - 72 - 2 - 10 -1.775114796299714 - 20 -2.101729675474409 - 40 -0.1075314212018693 - 50 -325.7547363472211 - 51 -383.6864830926802 - 73 - 1 - 72 - 2 - 10 -1.724258670730545 - 20 -2.179559731729328 - 40 -0.1532919477378671 - 50 -13.05681211459937 - 51 -58.88974415557702 - 73 - 0 - 72 - 2 - 10 -1.793291568736173 - 20 -2.065168888754275 - 40 -0.0196850393700787 - 50 -58.88974415557702 - 51 -238.8897441555765 - 73 - 0 - 72 - 2 - 10 -1.724258670730541 - 20 -2.179559731729329 - 40 -0.1139218689977123 - 50 -301.1102558444241 - 51 -381.2576330469557 - 73 - 1 - 72 - 2 - 10 -2.224366300494005 - 20 -2.407559786221586 - 40 -0.435937962168034 - 50 -154.6425959514791 - 51 -163.3464578177032 - 73 - 0 - 72 - 2 - 10 -2.105362384851463 - 20 -2.371962053549115 - 40 -0.3117239109915352 - 50 -163.3464578177044 - 51 -168.3316806257954 - 73 - 0 - 97 - 1 -330 -4F7 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BB6 -330 -1F -100 -AcDbEntity - 8 -HATCH-RED -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 4 - 72 - 2 - 10 -1.034012571047431 - 20 -0.4770274671951757 - 40 -0.7071698573021327 - 50 -88.2250617963899 - 51 -113.037640194644 - 73 - 1 - 72 - 2 - 10 -0.9476260308821789 - 20 -1.102477175547732 - 40 -0.1920311575011529 - 50 -187.577294301379 - 51 -259.5173177193701 - 73 - 0 - 72 - 2 - 10 -1.168606309785881 - 20 -1.558605525778299 - 40 -0.3700601913995948 - 50 -226.2464306309096 - 51 -229.2045371712558 - 73 - 1 - 72 - 2 - 10 -1.584035429735768 - 20 -2.03996185073825 - 40 -1.005894497867316 - 50 -229.2045371712552 - 51 -238.3301051192357 - 73 - 1 - 97 - 1 -330 -4E7 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BB7 -330 -1F -100 -AcDbEntity - 8 -HATCH-RED -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 6 - 72 - 2 - 10 -1.268369849054951 - 20 -1.97737114518936 - 40 -0.4071662414853972 - 50 -214.7414744545867 - 51 -240.7656835685936 - 73 - 1 - 72 - 2 - 10 -1.382209127764962 - 20 -2.180776385554782 - 40 -0.6402607999489762 - 50 -240.7656835685933 - 51 -274.8013992041994 - 73 - 1 - 72 - 2 - 10 -2.244252791706376 - 20 -1.579066020312693 - 40 -0.8092671391653085 - 50 -182.5711456908801 - 51 -205.0661840751609 - 73 - 1 - 72 - 2 - 10 -1.454717916970982 - 20 -2.022108206218515 - 40 -0.78792753486166 - 50 -85.88902674875129 - 51 -141.3773954764613 - 73 - 0 - 72 - 2 - 10 -1.168606309785876 - 20 -1.558605525778289 - 40 -0.3306901126594269 - 50 -175.0885918849935 - 51 -182.1149161181871 - 73 - 0 - 72 - 2 - 10 -1.060157361703603 - 20 -1.562610439508386 - 40 -0.2221672409957212 - 50 -182.1149161181872 - 51 -235.3333452342021 - 73 - 0 - 97 - 1 -330 -4EE - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BB8 -330 -1F -100 -AcDbEntity - 8 -HATCH-RED -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 7 - 72 - 2 - 10 -1.995105659775398 - 20 -1.606003070595649 - 40 -0.5586680609000869 - 50 -153.1774302023765 - 51 -173.1639087815069 - 73 - 1 - 72 - 2 - 10 -1.448830865211247 - 20 -2.213371853903018 - 40 -0.5409364048279738 - 50 -90.89204265530425 - 51 -153.6751728635248 - 73 - 0 - 72 - 2 - 10 -1.163637847655053 - 20 -1.838026139816656 - 40 -0.2412638458944706 - 50 -214.15747754694 - 51 -242.0052969205898 - 73 - 0 - 72 - 2 - 10 -1.134374454956795 - 20 -1.893074853652674 - 40 -0.1789203855540918 - 50 -242.0052969205894 - 51 -284.046994134434 - 73 - 0 - 72 - 2 - 10 -1.318324160529892 - 20 -2.123002906229338 - 40 -0.1514028023784195 - 50 -201.853727881165 - 51 -212.2168526331622 - 73 - 1 - 72 - 2 - 10 -1.492137893232153 - 20 -2.232530667257897 - 40 -0.3568475494804613 - 50 -212.2168526331617 - 51 -237.7831473668378 - 73 - 1 - 72 - 2 - 10 -1.573128668857933 - 20 -2.361057982102735 - 40 -0.5087645544459671 - 50 -237.7831473668379 - 51 -261.3425166986952 - 73 - 1 - 97 - 1 -330 -505 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BB9 -330 -1F -100 -AcDbEntity - 8 -HATCH-RED -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 6 - 72 - 2 - 10 -1.573128668857933 - 20 -2.361057982102735 - 40 -0.4693944757058101 - 50 -96.86618894004766 - 51 -122.2168526331621 - 73 - 0 - 72 - 2 - 10 -1.492137893232154 - 20 -2.232530667257898 - 40 -0.3174774707403054 - 50 -122.2168526331621 - 51 -147.7831473668382 - 73 - 0 - 72 - 2 - 10 -1.318324160529893 - 20 -2.123002906229338 - 40 -0.1120327236382623 - 50 -147.783147366838 - 51 -287.1653967341294 - 73 - 0 - 72 - 2 - 10 -1.134452552508394 - 20 -1.527737292608446 - 40 -0.7350495123332927 - 50 -287.1653967341295 - 51 -311.9725813008354 - 73 - 0 - 72 - 2 - 10 --0.1012307034243558 - 20 -3.010931950741639 - 40 -1.964911005810889 - 50 -28.47135626072658 - 51 -33.82931909093841 - 73 - 0 - 72 - 2 - 10 -1.9951056597754 - 20 -1.606003070595648 - 40 -0.5586680609000885 - 50 -146.1706809090616 - 51 -148.8453401595469 - 73 - 1 - 97 - 1 -330 -50B - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BBA -330 -1F -100 -AcDbEntity - 8 -HATCH-RED -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 6 - 72 - 2 - 10 -2.506661351932914 - 20 -2.343882490801411 - 40 -1.097947890945 - 50 -252.9025993502986 - 51 -309.129589783908 - 73 - 1 - 72 - 2 - 10 -2.720654010687031 - 20 -1.473292657067699 - 40 -0.4792688318657188 - 50 -2.258737765182703 - 51 -4.269906958171121 - 73 - 1 - 72 - 2 - 10 -2.805854019540959 - 20 -1.479653877718507 - 40 -0.3938316816506187 - 50 -4.26990695817209 - 51 -31.68755658158391 - 73 - 1 - 72 - 2 - 10 -3.031233358735755 - 20 -1.618783385319762 - 40 -0.1289678177105734 - 50 -31.68755658158397 - 51 -88.75077942665364 - 73 - 1 - 72 - 2 - 10 -2.358343856922911 - 20 -2.560871504972435 - 40 -1.057254245905374 - 50 -50.27455552545634 - 51 -103.1717867618754 - 73 - 0 - 72 - 2 - 10 -3.174161319020478 - 20 -1.699913413586489 - 40 -1.070082152487853 - 50 -189.0587348045097 - 51 -202.2656996106713 - 73 - 1 - 97 - 1 -330 -4B5 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BBB -330 -1F -100 -AcDbEntity - 8 -HATCH-RED -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 7 - 72 - 2 - 10 -3.174161319020492 - 20 -1.69991341358649 - 40 -1.070082152487867 - 50 -178.182030269148 - 51 -186.2319675330486 - 73 - 0 - 72 - 2 - 10 -3.496410384846752 - 20 -1.66472403412841 - 40 -1.394246852682911 - 50 -186.2319675330462 - 51 -188.4100158185151 - 73 - 0 - 72 - 2 - 10 -2.05576545700618 - 20 -2.861012413940887 - 40 -0.994268550367224 - 50 -273.5399568619239 - 51 -308.9576328012706 - 73 - 1 - 72 - 1 - 10 -2.680907394207461 - 20 -2.087858154687554 - 11 -2.747050780866419 - 21 -2.134172252628876 - 72 - 2 - 10 -2.833454996760046 - 20 -2.010774243926277 - 40 -0.1506411533278984 - 50 -235.0000000000002 - 51 -295.0 - 73 - 0 - 72 - 2 - 10 -2.807174025728471 - 20 -1.954414519671351 - 40 -0.2128272285895981 - 50 -294.9999999999998 - 51 -351.1901840561478 - 73 - 0 - 72 - 2 - 10 -2.232025923290446 - 20 -2.76206241576646 - 40 -1.1034765317954 - 50 -44.6177154324492 - 51 -96.63019658365178 - 73 - 0 - 97 - 1 -330 -4C7 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BBC -330 -1F -100 -AcDbEntity - 8 -HATCH-RED -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 6 - 72 - 2 - 10 -2.05576545700618 - 20 -2.861012413940887 - 40 -0.9548984716270655 - 50 -274.0763809413058 - 51 -308.9974179950865 - 73 - 1 - 72 - 2 - 10 -2.583746606177169 - 20 -2.208949913643178 - 40 -0.1158814287879965 - 50 -308.9974179950865 - 51 -381.0025820049136 - 73 - 1 - 72 - 2 - 10 -2.64643710148901 - 20 -2.233017781588249 - 40 -0.0487296568838581 - 50 -21.00258200491355 - 51 -88.99741799508618 - 73 - 1 - 72 - 2 - 10 -2.643315164634613 - 20 -2.054622849494738 - 40 -0.2271519040571613 - 50 -88.99741799508604 - 51 -114.6269796357359 - 73 - 1 - 72 - 2 - 10 -3.303260542295614 - 20 -0.6149685670603082 - 40 -1.810860322430921 - 50 -114.6269796357358 - 51 -129.7728051417874 - 73 - 1 - 72 - 2 - 10 -3.496410384846758 - 20 -1.664724034128341 - 40 -1.394246852682927 - 50 -165.7987430109054 - 51 -169.9291703474848 - 73 - 1 - 97 - 1 -330 -4C8 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BFB -330 -1F -100 -AcDbEntity - 8 -HATCH-BLACK -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 8 - 72 - 2 - 10 -2.10076671703864 - 20 -3.325655213407455 - 40 -0.0599397668605327 - 50 -267.8793336511986 - 51 -377.8793336511989 - 73 - 1 - 72 - 2 - 10 -2.052741812238583 - 20 -3.310162719091439 - 40 -0.1104017214519507 - 50 -17.87933365119892 - 51 -43.7673166448306 - 73 - 1 - 72 - 2 - 10 -2.103395451769339 - 20 -3.340116557206334 - 40 -0.0547683672910658 - 50 -57.93744139888317 - 51 -187.77563216475 - 73 - 1 - 72 - 2 - 10 -2.068634698539837 - 20 -3.335369986556996 - 40 -0.0196850393700788 - 50 -187.7756321647501 - 51 -367.7756321647502 - 73 - 1 - 72 - 2 - 10 -2.103395451769339 - 20 -3.340116557206334 - 40 -0.0153982885509082 - 50 -172.2243678352504 - 51 -287.334302618237 - 73 - 0 - 72 - 2 - 10 -2.052741812238584 - 20 -3.310162719091439 - 40 -0.0710316427117921 - 50 -321.0507208994834 - 51 -342.1206663488011 - 73 - 0 - 72 - 2 - 10 -2.100766717038639 - 20 -3.325655213407456 - 40 -0.0205696881203755 - 50 -342.1206663488009 - 51 -452.1206663488013 - 73 - 0 - 72 - 2 - 10 -2.099277124665835 - 20 -3.285428055915363 - 40 -0.0196850393700787 - 50 -87.8793336512005 - 51 -267.8793336511979 - 73 - 1 - 97 - 1 -330 -235 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BFC -330 -1F -100 -AcDbEntity - 8 -HATCH-BLACK -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 8 - 72 - 2 - 10 -1.921485017130019 - 20 -3.343003198213819 - 40 -0.0771903814552135 - 50 -359.5978819190761 - 51 -374.2374903606301 - 73 - 1 - 72 - 2 - 10 -1.980044176928186 - 20 -3.357861720825169 - 40 -0.0167755580220592 - 50 -14.23749036062933 - 51 -155.7625096393687 - 73 - 1 - 72 - 2 - 10 -2.003282808101446 - 20 -3.34739958355454 - 40 -0.0422606574936387 - 50 -155.7625096393692 - 51 -241.4329313324614 - 73 - 1 - 72 - 2 - 10 -1.973661171909946 - 20 -3.292995281984995 - 40 -0.0196850393700789 - 50 -298.5670686675385 - 51 -478.5670686675385 - 73 - 0 - 72 - 2 - 10 -2.003282808101446 - 20 -3.34739958355454 - 40 -0.0816307362337962 - 50 -118.5670686675387 - 51 -204.2374903606309 - 73 - 0 - 72 - 2 - 10 -1.980044176928186 - 20 -3.357861720825169 - 40 -0.0561456367622165 - 50 -204.2374903606306 - 51 -345.7625096393699 - 73 - 0 - 72 - 2 - 10 -1.921485017130019 - 20 -3.34300319821382 - 40 -0.1165604601953712 - 50 -345.76250963937 - 51 -360.4021180809241 - 73 - 0 - 72 - 2 - 10 -2.018358052101874 - 20 -3.342323304531541 - 40 -0.0196850393700787 - 50 -0.4021180809244088 - 51 -180.4021180809231 - 73 - 0 - 97 - 1 -330 -267 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BFD -330 -1F -100 -AcDbEntity - 8 -HATCH-BLACK -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 4 - 72 - 2 - 10 -2.278537892029333 - 20 -3.728579428420916 - 40 -0.0853095785363673 - 50 -12.6821846844064 - 51 -72.68218468440622 - 73 - 1 - 72 - 2 - 10 -2.309791821489833 - 20 -3.828814460633206 - 40 -0.0196850393700787 - 50 -107.3178153155941 - 51 -287.3178153155944 - 73 - 0 - 72 - 2 - 10 -2.278537892029333 - 20 -3.728579428420916 - 40 -0.1246796572765245 - 50 -287.3178153155936 - 51 -347.3178153155935 - 73 - 0 - 72 - 2 - 10 -2.380970941004577 - 20 -3.751630247646181 - 40 -0.0196850393700789 - 50 -347.3178153155935 - 51 -527.3178153155935 - 73 - 0 - 97 - 1 -330 -451 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -BFE -330 -1F -100 -AcDbEntity - 8 -HATCH-BLACK -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 4 - 72 - 2 - 10 -2.07909456474772 - 20 -3.772298844618632 - 40 -0.1175982774997528 - 50 -111.5543469318192 - 51 -141.5543469318192 - 73 - 1 - 72 - 2 - 10 -1.971574507059384 - 20 -3.857657770838914 - 40 -0.0196850393700788 - 50 -38.44565306818044 - 51 -218.4456530681808 - 73 - 0 - 72 - 2 - 10 -2.079094564747719 - 20 -3.772298844618632 - 40 -0.1569683562399099 - 50 -218.4456530681809 - 51 -248.4456530681809 - 73 - 0 - 72 - 2 - 10 -2.028658926483394 - 20 -3.899981872009325 - 40 -0.0196850393700786 - 50 -248.4456530681804 - 51 -428.4456530681804 - 73 - 0 - 97 - 1 -330 -44F - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -C01 -330 -1F -100 -AcDbEntity - 8 -HATCH-RED -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 17 - 72 - 2 - 10 -2.10536238485146 - 20 -2.371962053549118 - 40 -0.2723538322513761 - 50 -159.7337422418206 - 51 -175.1380365575864 - 73 - 1 - 72 - 2 - 10 -2.043049297315996 - 20 -2.110655210550977 - 40 -0.352964946593263 - 50 -233.6796832772765 - 51 -244.1243120885548 - 73 - 0 - 72 - 2 - 10 -1.928818024879453 - 20 -2.346159501416084 - 40 -0.0912187821164004 - 50 -244.1243120885551 - 51 -325.8756879114455 - 73 - 0 - 72 - 2 - 10 -1.780100104900293 - 20 -2.245377841414934 - 40 -0.2708683374053446 - 50 -325.8756879114452 - 51 -354.1243120885547 - 73 - 0 - 72 - 2 - 10 -1.486332025585371 - 20 -2.215145842661859 - 40 -0.5661879239094977 - 50 -354.124312088555 - 51 -380.265282453191 - 73 - 0 - 72 - 2 - 10 -2.601728566753494 - 20 -1.803316300498069 - 40 -0.622808718578886 - 50 -159.7347175468091 - 51 -172.7742566190203 - 73 - 1 - 72 - 2 - 10 -3.245154141910993 - 20 -1.721739021653846 - 40 -1.271385100503472 - 50 -172.7742566190202 - 51 -197.2257433809798 - 73 - 1 - 72 - 2 - 10 -2.448387279831183 - 20 -1.474706126417881 - 40 -0.4372012575544668 - 50 -197.2257433809797 - 51 -229.6909739682446 - 73 - 1 - 72 - 2 - 10 -1.84273355618451 - 20 -1.606506575382588 - 40 -0.5662349988373949 - 50 -304.7588400511317 - 51 -309.2074896477569 - 73 - 1 - 72 - 2 - 10 -3.174161319020478 - 20 -1.699913413586492 - 40 -1.109452231228011 - 50 -151.3367493281762 - 51 -186.2319675330486 - 73 - 0 - 72 - 2 - 10 -3.49641038484678 - 20 -1.664724034128332 - 40 -1.433616931423104 - 50 -186.2319675330492 - 51 -205.0988169699291 - 73 - 0 - 72 - 2 - 10 --37.1850685335689 - 20 -20.72029698200291 - 40 -43.48962412887072 - 50 -334.901183030072 - 51 -335.0988169699286 - 73 - 1 - 72 - 2 - 10 -1.05207209728287 - 20 -2.970247608757844 - 40 -1.33344811187206 - 50 -335.0988169699285 - 51 -348.9886439523909 - 73 - 1 - 72 - 2 - 10 -1.959203223948364 - 20 -2.950701101027533 - 40 -0.4655223034750759 - 50 -30.33963089325502 - 51 -49.03787718203768 - 73 - 0 - 72 - 2 - 10 -1.804450685812644 - 20 -3.128961400613438 - 40 -0.701583910831935 - 50 -49.03787718203728 - 51 -65.26030603284518 - 73 - 0 - 72 - 2 - 10 -1.924151714798596 - 20 -2.869186907390315 - 40 -0.4155574720721139 - 50 -65.26030603284511 - 51 -82.84890216530907 - 73 - 0 - 72 - 2 - 10 -1.936208898089171 - 20 -2.773084900679216 - 40 -0.318702057340656 - 50 -82.84890216530943 - 51 -105.7184590811235 - 73 - 0 - 97 - 1 -330 -4F3 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -C20 -330 -1F -100 -AcDbEntity - 8 -HATCH-RED -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 3 - 92 - 1 - 93 - 17 - 72 - 2 - 10 -1.885608931176688 - 20 -3.176688874055116 - 40 -0.2129975912966591 - 50 -114.9006616575818 - 51 -156.4878117659684 - 73 - 1 - 72 - 2 - 10 -2.636203773812854 - 20 -2.850131072655588 - 40 -1.031552791296577 - 50 -156.4878117659688 - 51 -180.6082887577103 - 73 - 1 - 72 - 2 - 10 -1.952094170360633 - 20 -2.842867853274917 - 40 -0.3474046319836055 - 50 -180.6082887577101 - 51 -213.6393369978933 - 73 - 1 - 72 - 2 - 10 -1.964644164547905 - 20 -2.851218474936612 - 40 -0.3624789557242355 - 50 -213.6393369978933 - 51 -250.0019612921961 - 73 - 1 - 72 - 2 - 10 -1.936208898089171 - 20 -2.773084900679217 - 40 -0.2793319786004991 - 50 -250.001961292196 - 51 -277.1510978346906 - 73 - 1 - 72 - 2 - 10 -1.924151714798597 - 20 -2.869186907390317 - 40 -0.3761873933319576 - 50 -277.1510978346908 - 51 -294.7396939671547 - 73 - 1 - 72 - 2 - 10 -1.804450685812644 - 20 -3.128961400613437 - 40 -0.6622138320917775 - 50 -294.7396939671549 - 51 -310.9621228179628 - 73 - 1 - 72 - 2 - 10 -1.959203223948364 - 20 -2.950701101027533 - 40 -0.4261522247349184 - 50 -310.9621228179625 - 51 -357.7626023297964 - 73 - 1 - 72 - 2 - 10 -0.9685713550985386 - 20 -2.989404907072427 - 40 -1.417539880590719 - 50 -357.7626023297966 - 51 -367.3820705420636 - 73 - 1 - 72 - 2 - 10 -2.2125235694189 - 20 -3.150570273791624 - 40 -0.1631908912969642 - 50 -7.382070542063584 - 51 -53.5251061991567 - 73 - 1 - 72 - 2 - 10 -1.924407631021267 - 20 -3.452788946261674 - 40 -0.4213817967382122 - 50 -23.94086726929591 - 51 -38.56090658709021 - 73 - 0 - 72 - 2 - 10 -2.174464534980624 - 20 -3.253450334179865 - 40 -0.1015938396722196 - 50 -38.56090658709 - 51 -128.8844964337146 - 73 - 0 - 72 - 1 - 10 -2.110688753100606 - 20 -3.174368364648643 - 11 -2.049360338450518 - 21 -3.223826763560005 - 72 - 1 - 10 -2.049360338450518 - 20 -3.223826763560005 - 11 -2.020698206844207 - 21 -3.208114453397319 - 72 - 2 - 10 -1.961644849992286 - 20 -3.289054064709398 - 40 -0.1001924130602254 - 50 -53.88559445512062 - 51 -115.5479523260344 - 73 - 0 - 72 - 2 - 10 -2.0110372932182 - 20 -3.39238482801838 - 40 -0.2147212744613677 - 50 -115.5479523260344 - 51 -163.3991489022965 - 73 - 0 - 72 - 2 - 10 -2.161160122792123 - 20 -3.437140815427867 - 40 -0.371373635976537 - 50 -163.3991489022961 - 51 -169.5663152899231 - 73 - 0 - 97 - 1 -330 -4C9 - 92 - 16 - 93 - 4 - 72 - 2 - 10 -1.788320029910184 - 20 -2.673441487468005 - 40 -0.2481310319481923 - 50 -339.5601350117603 - 51 -365.5770490458945 - 73 - 1 - 72 - 2 - 10 -2.015684652568724 - 20 -2.695642836263502 - 40 -0.0196850393700789 - 50 -5.57704904589411 - 51 -185.5770490458954 - 73 - 1 - 72 - 2 - 10 -1.788320029910183 - 20 -2.673441487468005 - 40 -0.2087609532080352 - 50 -354.4229509541054 - 51 -380.4398649882396 - 73 - 0 - 72 - 2 - 10 -2.002382887993199 - 20 -2.593662641184479 - 40 -0.0196850393700787 - 50 -159.5601350117616 - 51 -339.5601350117602 - 73 - 1 - 97 - 1 -330 -138 - 92 - 16 - 93 - 4 - 72 - 2 - 10 -1.988631326711838 - 20 -2.675424154108706 - 40 -0.2917786076489145 - 50 -176.6618056290539 - 51 -192.1921376659049 - 73 - 0 - 72 - 2 - 10 -1.722674860472906 - 20 -2.732887777074972 - 40 -0.0196850393700788 - 50 -192.1921376659057 - 51 -372.1921376659045 - 73 - 0 - 72 - 2 - 10 -1.988631326711838 - 20 -2.675424154108705 - 40 -0.2524085289087564 - 50 -167.807862334095 - 51 -183.338194370946 - 73 - 1 - 72 - 2 - 10 -1.716999440920682 - 20 -2.659580274525414 - 40 -0.0196850393700787 - 50 -356.6618056290538 - 51 -536.6618056290539 - 73 - 0 - 97 - 1 -330 -14E - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -C24 -330 -1F -100 -AcDbEntity - 8 -HATCH-BLACK -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 4 - 72 - 2 - 10 -1.788320029910184 - 20 -2.673441487468005 - 40 -0.2481310319481923 - 50 -339.5601350117603 - 51 -365.5770490458945 - 73 - 1 - 72 - 2 - 10 -2.015684652568724 - 20 -2.695642836263502 - 40 -0.0196850393700789 - 50 -5.57704904589411 - 51 -185.5770490458954 - 73 - 1 - 72 - 2 - 10 -1.788320029910183 - 20 -2.673441487468005 - 40 -0.2087609532080352 - 50 -354.4229509541054 - 51 -380.4398649882396 - 73 - 0 - 72 - 2 - 10 -2.002382887993199 - 20 -2.593662641184479 - 40 -0.0196850393700787 - 50 -159.5601350117616 - 51 -339.5601350117602 - 73 - 1 - 97 - 1 -330 -138 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -C25 -330 -1F -100 -AcDbEntity - 8 -HATCH-BLACK -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 4 - 72 - 2 - 10 -1.988631326711838 - 20 -2.675424154108706 - 40 -0.2917786076489145 - 50 -176.6618056290539 - 51 -192.1921376659049 - 73 - 0 - 72 - 2 - 10 -1.722674860472906 - 20 -2.732887777074972 - 40 -0.0196850393700788 - 50 -192.1921376659057 - 51 -372.1921376659045 - 73 - 0 - 72 - 2 - 10 -1.988631326711838 - 20 -2.675424154108705 - 40 -0.2524085289087564 - 50 -167.807862334095 - 51 -183.338194370946 - 73 - 1 - 72 - 2 - 10 -1.716999440920682 - 20 -2.659580274525414 - 40 -0.0196850393700787 - 50 -356.6618056290538 - 51 -536.6618056290539 - 73 - 0 - 97 - 1 -330 -14E - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -C28 -330 -1F -100 -AcDbEntity - 8 -HATCH-BLACK -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 27 - 92 - 1 - 93 - 48 - 72 - 2 - 10 -3.031233358735754 - 20 -1.618783385319762 - 40 -0.1683378964507315 - 50 -268.8981266360797 - 51 -328.3124434184161 - 73 - 0 - 72 - 2 - 10 -2.805854019540958 - 20 -1.479653877718506 - 40 -0.4332017603907771 - 50 -328.312443418416 - 51 -355.7300930418278 - 73 - 0 - 72 - 2 - 10 -2.720654010687053 - 20 -1.47329265706769 - 40 -0.5186389106058562 - 50 -355.7300930418277 - 51 -387.0857403971304 - 73 - 0 - 72 - 2 - 10 -3.019270278182164 - 20 -1.320576760853129 - 40 -0.1832379264550515 - 50 -27.08574039713041 - 51 -62.91425960287025 - 73 - 0 - 72 - 2 - 10 -2.617288604059704 - 20 -2.106600155295556 - 40 -1.066086748701018 - 50 -62.91425960286999 - 51 -83.90565057843106 - 73 - 0 - 72 - 2 - 10 -2.527478440588518 - 20 -2.94776010601788 - 40 -1.912027602521132 - 50 -83.90565057843116 - 51 -95.51019307772863 - 73 - 0 - 72 - 2 - 10 -2.411367250189849 - 20 -1.266852136052576 - 40 -0.2323033958896882 - 50 -106.8886617051031 - 51 -145.0036277051946 - 73 - 0 - 72 - 2 - 10 -1.842733556184506 - 20 -1.606506575382589 - 40 -0.6056050775775568 - 50 -51.33837874710574 - 51 -83.82931909093898 - 73 - 0 - 72 - 2 - 10 -1.867289566555309 - 20 -1.379382243234547 - 40 -0.3771571406224918 - 50 -83.82931909093904 - 51 -106.1706809090618 - 73 - 0 - 72 - 2 - 10 -1.872170704325742 - 20 -1.396215376152872 - 40 -0.3946836881941034 - 50 -106.1706809090621 - 51 -118.8560326885956 - 73 - 0 - 72 - 2 - 10 -1.542373482613905 - 20 -1.83573967301926 - 40 -0.7974660552058795 - 50 -79.93869473201835 - 51 -101.5302981560868 - 73 - 0 - 72 - 2 - 10 -1.584035429735764 - 20 -2.039961850738246 - 40 -1.00589449786731 - 50 -101.530298156087 - 51 -115.9981291148674 - 73 - 0 - 72 - 2 - 10 -1.03401257104743 - 20 -0.477027467195177 - 40 -0.6677997785619737 - 50 -80.5975463145049 - 51 -115.6894538187781 - 73 - 1 - 72 - 2 - 10 -0.7359925636398887 - 20 -1.096559104863404 - 40 -0.0196850393700787 - 50 -64.3105461812228 - 51 -178.3982111381467 - 73 - 0 - 72 - 2 - 10 -0.9476260308821786 - 20 -1.102477175547731 - 40 -0.2314012362413102 - 50 -178.3982111381469 - 51 -253.5469306045596 - 73 - 0 - 72 - 2 - 10 -1.168606309785877 - 20 -1.558605525778289 - 40 -0.3700601913995847 - 50 -140.7373098431768 - 51 -182.1149161181871 - 73 - 0 - 72 - 2 - 10 -1.060157361703604 - 20 -1.562610439508386 - 40 -0.2615373197358793 - 50 -182.1149161181871 - 51 -235.7398592611448 - 73 - 0 - 72 - 2 - 10 -1.268369849054956 - 20 -1.977371145189359 - 40 -0.4071662414854006 - 50 -150.8060111759436 - 51 -152.0052969205898 - 73 - 0 - 72 - 2 - 10 -1.065938622495786 - 20 -1.869760556959495 - 40 -0.1779099652672192 - 50 -152.0052969205898 - 51 -197.9947030794108 - 73 - 0 - 72 - 2 - 10 -1.163637847655054 - 20 -1.838026139816656 - 40 -0.2806339246346285 - 50 -197.9947030794104 - 51 -242.0052969205895 - 73 - 0 - 72 - 2 - 10 -1.134374454956794 - 20 -1.893074853652674 - 40 -0.2182904642942491 - 50 -242.0052969205897 - 51 -278.7513848946688 - 73 - 0 - 72 - 2 - 10 -1.318324160529893 - 20 -2.123002906229338 - 40 -0.1514028023784197 - 50 -174.626341759492 - 51 -287.1653967341294 - 73 - 0 - 72 - 2 - 10 -1.134452552508395 - 20 -1.527737292608446 - 40 -0.7744195910734504 - 50 -287.1653967341294 - 51 -311.2425077735102 - 73 - 0 - 72 - 2 - 10 --0.1012307034243847 - 20 -3.010931950741654 - 40 -1.964911005810923 - 50 -332.7104062850323 - 51 -333.8293190909388 - 73 - 1 - 72 - 2 - 10 -4.316192387813981 - 20 -0.8400973818280608 - 40 -2.957095647231735 - 50 -206.1706809090621 - 51 -209.2027098803458 - 73 - 0 - 72 - 2 - 10 -2.043049297315993 - 20 -2.110655210550981 - 40 -0.3529649465932583 - 50 -209.2027098803451 - 51 -225.0870679104569 - 73 - 0 - 72 - 2 - 10 -2.105362384851456 - 20 -2.371962053549119 - 40 -0.3117239109915287 - 50 -177.914487685338 - 51 -200.1246558462194 - 73 - 0 - 72 - 2 - 10 -1.964644164547905 - 20 -2.851218474936612 - 40 -0.4018490344643929 - 50 -112.2213810159718 - 51 -146.3606630021067 - 73 - 0 - 72 - 2 - 10 -1.952094170360633 - 20 -2.842867853274918 - 40 -0.3867747107237632 - 50 -146.3606630021067 - 51 -179.3917112422899 - 73 - 0 - 72 - 2 - 10 -2.636203773812854 - 20 -2.850131072655586 - 40 -1.070922870036734 - 50 -179.3917112422899 - 51 -203.5121882340314 - 73 - 0 - 72 - 2 - 10 -1.885608931176689 - 20 -3.176688874055116 - 40 -0.2523676700368166 - 50 -203.5121882340314 - 51 -247.919074760323 - 73 - 0 - 72 - 2 - 10 -2.161160122792124 - 20 -3.437140815427865 - 40 -0.3713736359765378 - 50 -175.8934715069597 - 51 -235.3701061614485 - 73 - 0 - 72 - 2 - 10 -2.010334078755422 - 20 -3.655531747894149 - 40 -0.1059624550830902 - 50 -235.3701061614487 - 51 -321.8826468892163 - 73 - 0 - 72 - 2 - 10 -1.984695044370156 - 20 -3.635415634546031 - 40 -0.1385510742689834 - 50 -321.8826468892165 - 51 -353.8787479269093 - 73 - 0 - 72 - 2 - 10 -2.205371433700895 - 20 -3.565115244906948 - 40 -0.1187965099453075 - 50 -225.7363985376375 - 51 -338.2090024626373 - 73 - 0 - 72 - 2 - 10 -1.924407631021267 - 20 -3.452788946261673 - 40 -0.4213817967382119 - 50 -338.2090024626376 - 51 -378.4288669894065 - 73 - 0 - 72 - 2 - 10 -2.2125235694189 - 20 -3.150570273791623 - 40 -0.2025609700371219 - 50 -303.4508923017655 - 51 -352.6179294579363 - 73 - 0 - 72 - 2 - 10 -0.968571355098534 - 20 -2.989404907072428 - 40 -1.456909959330881 - 50 -352.6179294579365 - 51 -362.2328550433406 - 73 - 0 - 72 - 2 - 10 -1.052072097282865 - 20 -2.970247608757846 - 40 -1.372818190612224 - 50 -1.569678067828868 - 51 -24.90118303007151 - 73 - 0 - 72 - 2 - 10 --37.185068533585 - 20 -20.72029698201224 - 40 -43.52899420762941 - 50 -24.90118303007369 - 51 -25.09881696993027 - 73 - 0 - 72 - 2 - 10 -3.496410384846288 - 20 -1.664724034128535 - 40 -1.394246852682421 - 50 -154.9011830300731 - 51 -163.0124653299814 - 73 - 1 - 72 - 2 - 10 -3.303260542295614 - 20 -0.6149685670603104 - 40 -1.850230401171077 - 50 -231.9548675004806 - 51 -245.3730203642641 - 73 - 0 - 72 - 2 - 10 -2.643315164634613 - 20 -2.054622849494737 - 40 -0.2665219827973205 - 50 -245.373020364264 - 51 -271.0025820049138 - 73 - 0 - 72 - 2 - 10 -2.646437101489009 - 20 -2.233017781588249 - 40 -0.0880997356240162 - 50 -271.0025820049141 - 51 -338.9974179950867 - 73 - 0 - 72 - 2 - 10 -2.583746606177169 - 20 -2.208949913643178 - 40 -0.1552515075281532 - 50 -338.9974179950864 - 51 -373.3205824975591 - 73 - 0 - 72 - 2 - 10 -2.833454996760046 - 20 -2.010774243926277 - 40 -0.1900112320680552 - 50 -238.728482917094 - 51 -295.0 - 73 - 0 - 72 - 2 - 10 -2.807174025728471 - 20 -1.954414519671351 - 40 -0.2521973073297553 - 50 -294.9999999999998 - 51 -365.0000000000006 - 73 - 0 - 72 - 2 - 10 -2.435514026542535 - 20 -1.986930556286176 - 40 -0.6252769873339419 - 50 -5.000000000000452 - 51 -18.63891789885247 - 73 - 0 - 97 - 1 -330 -8B3 - 92 - 16 - 93 - 5 - 72 - 2 - 10 -2.506661351932912 - 20 -2.343882490801413 - 40 -1.137317969685161 - 50 -295.2104838476032 - 51 -307.4903876208237 - 73 - 1 - 72 - 2 - 10 -2.72065401068705 - 20 -1.473292657067691 - 40 -0.4792688318657009 - 50 -3.806985506611603 - 51 -27.08574039713036 - 73 - 0 - 72 - 2 - 10 -3.019270278182163 - 20 -1.32057676085313 - 40 -0.1438678477148946 - 50 -27.08574039713062 - 51 -62.91425960287042 - 73 - 0 - 72 - 2 - 10 -2.617288604059699 - 20 -2.106600155295566 - 40 -1.026716669960872 - 50 -62.91425960286999 - 51 -74.08618998756283 - 73 - 0 - 72 - 2 - 10 -2.502316662315185 - 20 -1.425846770903515 - 40 -0.5012141309808816 - 50 -322.28430360547 - 51 -347.21072780023 - 73 - 1 - 97 - 1 -330 -4AD - 92 - 0 - 93 - 4 - 72 - 2 - 10 -2.35834385692291 - 20 -2.560871504972433 - 40 -1.017884167165215 - 50 -264.8798691909198 - 51 -277.0962125668474 - 73 - 1 - 72 - 2 - 10 -2.157099264484859 - 20 -1.761255447038774 - 40 -0.3888707645596128 - 50 -327.2321171951457 - 51 -344.8146293833702 - 73 - 1 - 72 - 2 - 10 -2.232025923290449 - 20 -2.762062415766465 - 40 -1.14284661053556 - 50 -74.76238100741742 - 51 -87.73997032522614 - 73 - 0 - 72 - 2 - 10 -1.875100795739506 - 20 -1.635718008880588 - 40 -0.4022960678253824 - 50 -2.224226079808037 - 51 -12.73296995122379 - 73 - 0 - 97 - 1 -330 -4C1 - 92 - 16 - 93 - 6 - 72 - 2 - 10 -2.506661351932914 - 20 -2.343882490801411 - 40 -1.097947890945 - 50 -252.9025993502986 - 51 -309.129589783908 - 73 - 1 - 72 - 2 - 10 -2.720654010687031 - 20 -1.473292657067699 - 40 -0.4792688318657188 - 50 -2.258737765182703 - 51 -4.269906958171121 - 73 - 1 - 72 - 2 - 10 -2.805854019540959 - 20 -1.479653877718507 - 40 -0.3938316816506187 - 50 -4.26990695817209 - 51 -31.68755658158391 - 73 - 1 - 72 - 2 - 10 -3.031233358735755 - 20 -1.618783385319762 - 40 -0.1289678177105734 - 50 -31.68755658158397 - 51 -88.75077942665364 - 73 - 1 - 72 - 2 - 10 -2.358343856922911 - 20 -2.560871504972435 - 40 -1.057254245905374 - 50 -50.27455552545634 - 51 -103.1717867618754 - 73 - 0 - 72 - 2 - 10 -3.174161319020478 - 20 -1.699913413586489 - 40 -1.070082152487853 - 50 -189.0587348045097 - 51 -202.2656996106713 - 73 - 1 - 97 - 1 -330 -4B5 - 92 - 16 - 93 - 5 - 72 - 2 - 10 -2.202541654133554 - 20 -1.362543685931673 - 40 -0.5298157619216942 - 50 -14.96903515149527 - 51 -32.33949759932654 - 73 - 0 - 72 - 2 - 10 -2.527478440588518 - 20 -2.947760106017868 - 40 -1.872657523780963 - 50 -273.7568474686516 - 51 -276.0943494215687 - 73 - 1 - 72 - 2 - 10 -2.617288604059703 - 20 -2.10660015529557 - 40 -1.026716669960875 - 50 -276.0943494215687 - 51 -282.0831632762506 - 73 - 1 - 72 - 2 - 10 -2.502316662315184 - 20 -1.425846770903515 - 40 -0.4618440522407246 - 50 -315.5859663701619 - 51 -343.4723636742463 - 73 - 1 - 72 - 2 - 10 -2.506661351932922 - 20 -2.3438824908014 - 40 -1.137317969685146 - 50 -67.32624731613089 - 51 -79.47656760874074 - 73 - 0 - 97 - 1 -330 -4B9 - 92 - 16 - 93 - 4 - 72 - 2 - 10 -2.05395636253349 - 20 -1.311094011306242 - 40 -0.40360054374194 - 50 -325.1586938734879 - 51 -345.2415144983743 - 73 - 1 - 72 - 2 - 10 -2.506661351932912 - 20 -2.343882490801414 - 40 -1.137317969685161 - 50 -266.8538285473494 - 51 -278.3272010683704 - 73 - 1 - 72 - 2 - 10 -2.202541654133556 - 20 -1.362543685931675 - 40 -0.4904456831815359 - 50 -17.0728403884595 - 51 -35.67171941040231 - 73 - 0 - 72 - 2 - 10 -2.527478440588521 - 20 -2.947760106017855 - 40 -1.87265752378095 - 50 -87.75100742187989 - 51 -94.35714735717728 - 73 - 0 - 97 - 1 -330 -4BA - 92 - 16 - 93 - 4 - 72 - 2 - 10 -2.506661351932914 - 20 -2.343882490801417 - 40 -1.137317969685164 - 50 -254.5896536710559 - 51 -264.8320604814776 - 73 - 1 - 72 - 2 - 10 -2.053956362533489 - 20 -1.311094011306244 - 40 -0.3642304650017842 - 50 -15.91994768566973 - 51 -37.94378452603665 - 73 - 0 - 72 - 2 - 10 -2.41136725018985 - 20 -1.266852136052575 - 40 -0.1929333171495304 - 50 -111.3287610035634 - 51 -150.8157377309437 - 73 - 0 - 72 - 2 - 10 -3.174161319020494 - 20 -1.699913413586516 - 40 -1.070082152487879 - 50 -150.4873427015391 - 51 -154.9868167954895 - 73 - 0 - 97 - 1 -330 -4BC - 92 - 0 - 93 - 4 - 72 - 2 - 10 -2.358343856922912 - 20 -2.56087150497244 - 40 -1.017884167165223 - 50 -255.9706947110459 - 51 -262.6477274601202 - 73 - 1 - 72 - 2 - 10 -1.875100795739507 - 20 -1.635718008880588 - 40 -0.3629259890852237 - 50 -346.5587102880505 - 51 -357.396057379031 - 73 - 1 - 72 - 2 - 10 -2.23202592329045 - 20 -2.762062415766459 - 40 -1.142846610535554 - 50 -89.71793740532951 - 51 -96.29947398788597 - 73 - 0 - 72 - 2 - 10 -3.174161319020505 - 20 -1.699913413586497 - 40 -1.070082152487882 - 50 -183.9544802865682 - 51 -186.7925864334441 - 73 - 1 - 97 - 1 -330 -4C0 - 92 - 16 - 93 - 4 - 72 - 2 - 10 -2.157099264484858 - 20 -1.761255447038777 - 40 -0.4282408432997721 - 50 -12.00230574940428 - 51 -28.29091643485702 - 73 - 0 - 72 - 2 - 10 -2.358343856922911 - 20 -2.560871504972434 - 40 -1.017884167165216 - 50 -279.9480036533407 - 51 -296.005896865796 - 73 - 1 - 72 - 2 - 10 -2.43480848147727 - 20 -1.74176023846554 - 40 -0.3820244196138822 - 50 -345.4907424301736 - 51 -365.6076870699981 - 73 - 1 - 72 - 2 - 10 -2.232025923290445 - 20 -2.762062415766465 - 40 -1.142846610535562 - 50 -59.32877074017064 - 51 -72.48465458233305 - 73 - 0 - 97 - 1 -330 -4C3 - 92 - 16 - 93 - 7 - 72 - 2 - 10 -3.174161319020492 - 20 -1.69991341358649 - 40 -1.070082152487867 - 50 -178.182030269148 - 51 -186.2319675330486 - 73 - 0 - 72 - 2 - 10 -3.496410384846752 - 20 -1.66472403412841 - 40 -1.394246852682911 - 50 -186.2319675330462 - 51 -188.4100158185151 - 73 - 0 - 72 - 2 - 10 -2.05576545700618 - 20 -2.861012413940887 - 40 -0.994268550367224 - 50 -273.5399568619239 - 51 -308.9576328012706 - 73 - 1 - 72 - 1 - 10 -2.680907394207461 - 20 -2.087858154687554 - 11 -2.747050780866419 - 21 -2.134172252628876 - 72 - 2 - 10 -2.833454996760046 - 20 -2.010774243926277 - 40 -0.1506411533278984 - 50 -235.0000000000002 - 51 -295.0 - 73 - 0 - 72 - 2 - 10 -2.807174025728471 - 20 -1.954414519671351 - 40 -0.2128272285895981 - 50 -294.9999999999998 - 51 -351.1901840561478 - 73 - 0 - 72 - 2 - 10 -2.232025923290446 - 20 -2.76206241576646 - 40 -1.1034765317954 - 50 -44.6177154324492 - 51 -96.63019658365178 - 73 - 0 - 97 - 1 -330 -4C7 - 92 - 16 - 93 - 6 - 72 - 2 - 10 -2.05576545700618 - 20 -2.861012413940887 - 40 -0.9548984716270655 - 50 -274.0763809413058 - 51 -308.9974179950865 - 73 - 1 - 72 - 2 - 10 -2.583746606177169 - 20 -2.208949913643178 - 40 -0.1158814287879965 - 50 -308.9974179950865 - 51 -381.0025820049136 - 73 - 1 - 72 - 2 - 10 -2.64643710148901 - 20 -2.233017781588249 - 40 -0.0487296568838581 - 50 -21.00258200491355 - 51 -88.99741799508618 - 73 - 1 - 72 - 2 - 10 -2.643315164634613 - 20 -2.054622849494738 - 40 -0.2271519040571613 - 50 -88.99741799508604 - 51 -114.6269796357359 - 73 - 1 - 72 - 2 - 10 -3.303260542295614 - 20 -0.6149685670603082 - 40 -1.810860322430921 - 50 -114.6269796357358 - 51 -129.7728051417874 - 73 - 1 - 72 - 2 - 10 -3.496410384846758 - 20 -1.664724034128341 - 40 -1.394246852682927 - 50 -165.7987430109054 - 51 -169.9291703474848 - 73 - 1 - 97 - 1 -330 -4C8 - 92 - 16 - 93 - 4 - 72 - 2 - 10 -1.034012571047431 - 20 -0.4770274671951757 - 40 -0.7071698573021327 - 50 -88.2250617963899 - 51 -113.037640194644 - 73 - 1 - 72 - 2 - 10 -0.9476260308821789 - 20 -1.102477175547732 - 40 -0.1920311575011529 - 50 -187.577294301379 - 51 -259.5173177193701 - 73 - 0 - 72 - 2 - 10 -1.168606309785881 - 20 -1.558605525778299 - 40 -0.3700601913995948 - 50 -226.2464306309096 - 51 -229.2045371712558 - 73 - 1 - 72 - 2 - 10 -1.584035429735768 - 20 -2.03996185073825 - 40 -1.005894497867316 - 50 -229.2045371712552 - 51 -238.3301051192357 - 73 - 1 - 97 - 1 -330 -4E7 - 92 - 16 - 93 - 4 - 72 - 2 - 10 -1.365920530767478 - 20 -1.285919869338796 - 40 -0.3113711740675595 - 50 -169.2458500319289 - 51 -182.205842988757 - 73 - 0 - 72 - 2 - 10 -1.454717916970979 - 20 -2.022108206218515 - 40 -0.827297613601817 - 50 -241.09054843511 - 51 -254.5550649161042 - 73 - 1 - 72 - 2 - 10 -1.606711922375474 - 20 -1.348933253591385 - 40 -0.3924976718251174 - 50 -198.4545948543501 - 51 -215.6989500329358 - 73 - 1 - 72 - 2 - 10 -1.584035429735761 - 20 -2.039961850738243 - 40 -0.9665244191271488 - 50 -107.8377726397921 - 51 -122.8312626374707 - 73 - 0 - 97 - 1 -330 -4EB - 92 - 0 - 93 - 4 - 72 - 2 - 10 -1.454717916970981 - 20 -2.022108206218515 - 40 -0.8272976136018175 - 50 -223.615566083045 - 51 -238.0440774153107 - 73 - 1 - 72 - 2 - 10 -1.365920530767478 - 20 -1.285919869338796 - 40 -0.3507412528077177 - 50 -174.3939645983117 - 51 -184.6071947080589 - 73 - 1 - 72 - 2 - 10 -1.584035429735767 - 20 -2.039961850738251 - 40 -0.9665244191271588 - 50 -125.9717238731088 - 51 -130.7954628287447 - 73 - 0 - 72 - 2 - 10 -1.168606309785878 - 20 -1.558605525778289 - 40 -0.3306901126594289 - 50 -130.7954628287448 - 51 -161.0882096390424 - 73 - 0 - 97 - 1 -330 -4F0 - 92 - 0 - 93 - 4 - 72 - 2 - 10 -1.448830865211245 - 20 -2.213371853903018 - 40 -0.5803064835681306 - 50 -252.3365152710513 - 51 -268.8118268997819 - 73 - 1 - 72 - 2 - 10 -2.244252791706375 - 20 -1.579066020312691 - 40 -0.8092671391653076 - 50 -176.1651718242215 - 51 -179.7775214345853 - 73 - 1 - 72 - 2 - 10 -1.382209127764961 - 20 -2.180776385554781 - 40 -0.6008907212088166 - 50 -84.96060718028212 - 51 -99.52487731460255 - 73 - 0 - 72 - 2 - 10 -1.754426611671092 - 20 -1.690434343062297 - 40 -0.4826097226376628 - 50 -167.7663152513758 - 51 -176.4348368363554 - 73 - 0 - 97 - 1 -330 -620 - 92 - 16 - 93 - 6 - 72 - 2 - 10 -1.268369849054951 - 20 -1.97737114518936 - 40 -0.4071662414853972 - 50 -214.7414744545867 - 51 -240.7656835685936 - 73 - 1 - 72 - 2 - 10 -1.382209127764962 - 20 -2.180776385554782 - 40 -0.6402607999489762 - 50 -240.7656835685933 - 51 -274.8013992041994 - 73 - 1 - 72 - 2 - 10 -2.244252791706376 - 20 -1.579066020312693 - 40 -0.8092671391653085 - 50 -182.5711456908801 - 51 -205.0661840751609 - 73 - 1 - 72 - 2 - 10 -1.454717916970982 - 20 -2.022108206218515 - 40 -0.78792753486166 - 50 -85.88902674875129 - 51 -141.3773954764613 - 73 - 0 - 72 - 2 - 10 -1.168606309785876 - 20 -1.558605525778289 - 40 -0.3306901126594269 - 50 -175.0885918849935 - 51 -182.1149161181871 - 73 - 0 - 72 - 2 - 10 -1.060157361703603 - 20 -1.562610439508386 - 40 -0.2221672409957212 - 50 -182.1149161181872 - 51 -235.3333452342021 - 73 - 0 - 97 - 1 -330 -4EE - 92 - 16 - 93 - 11 - 72 - 2 - 10 -1.735391678484751 - 20 -1.622446814297793 - 40 -0.3637008069698632 - 50 -46.50828210019076 - 51 -127.3801843342055 - 73 - 0 - 72 - 2 - 10 -2.244252791706377 - 20 -1.579066020312692 - 40 -0.7698970604251519 - 50 -198.604632170139 - 51 -206.170680909061 - 73 - 1 - 72 - 2 - 10 -1.87217070432574 - 20 -1.396215376152875 - 40 -0.3553136094539483 - 50 -206.170680909061 - 51 -220.7958011940912 - 73 - 1 - 72 - 2 - 10 -1.754854449164134 - 20 -1.637701886096329 - 40 -0.4973281664865742 - 50 -252.2434918237404 - 51 -291.0055844420299 - 73 - 1 - 72 - 2 - 10 -1.940182455435743 - 20 -1.155046537921708 - 40 -0.0196850393700786 - 50 -248.9944155579697 - 51 -428.9944155579707 - 73 - 0 - 72 - 2 - 10 -1.754854449164133 - 20 -1.637701886096329 - 40 -0.5366982452267322 - 50 -68.99441555797011 - 51 -99.84027979757452 - 73 - 0 - 72 - 2 - 10 -1.872170704325739 - 20 -1.396215376152874 - 40 -0.3553136094539469 - 50 -233.9619057741986 - 51 -253.8293190909382 - 73 - 1 - 72 - 2 - 10 -1.867289566555308 - 20 -1.379382243234548 - 40 -0.3377870618823355 - 50 -253.8293190909384 - 51 -276.1706809090611 - 73 - 1 - 72 - 2 - 10 -1.842733556184505 - 20 -1.606506575382589 - 40 -0.5662349988373994 - 50 -276.170680909061 - 51 -300.6079669543535 - 73 - 1 - 72 - 2 - 10 -2.448387279831183 - 20 -1.47470612641788 - 40 -0.4765713362946238 - 50 -131.7514141291648 - 51 -162.7742566190203 - 73 - 0 - 72 - 2 - 10 -3.245154141911026 - 20 -1.721739021653879 - 40 -1.31075517924367 - 50 -162.7742566190193 - 51 -163.9156492780123 - 73 - 0 - 97 - 1 -330 -4F4 - 92 - 16 - 93 - 36 - 72 - 2 - 10 -2.043049297315998 - 20 -2.110655210550977 - 40 -0.3135948678531067 - 50 -140.7856547310828 - 51 -150.7972901196548 - 73 - 1 - 72 - 2 - 10 -4.316192387813921 - 20 -0.8400973818280717 - 40 -2.91772556849152 - 50 -150.7972901196538 - 51 -151.5606552199046 - 73 - 1 - 72 - 2 - 10 -1.82896029060598 - 20 -2.312110103765454 - 40 -0.1138088004365485 - 50 -226.4676036039469 - 51 -253.8346334294888 - 73 - 1 - 72 - 2 - 10 -1.791794192050712 - 20 -2.183894323205893 - 40 -0.0196850393700787 - 50 -286.1653665705111 - 51 -466.1653665705111 - 73 - 0 - 72 - 2 - 10 -1.82896029060598 - 20 -2.312110103765454 - 40 -0.153178879176706 - 50 -106.1653665705111 - 51 -129.487348884315 - 73 - 0 - 72 - 2 - 10 -4.31619238781396 - 20 -0.8400973818280881 - 40 -2.917725568491546 - 50 -152.3551430085055 - 51 -153.8293190909382 - 73 - 1 - 72 - 2 - 10 --0.1012307034243785 - 20 -3.010931950741638 - 40 -2.004281084551068 - 50 -26.17068090906094 - 51 -27.44285015917365 - 73 - 0 - 72 - 2 - 10 -1.869973878918131 - 20 -2.229032723885394 - 40 -0.2390599525801008 - 50 -216.3816426472188 - 51 -279.0739534633693 - 73 - 1 - 72 - 2 - 10 -1.910780338072042 - 20 -1.973525769477851 - 40 -0.0196850393700789 - 50 -260.9260465366305 - 51 -440.9260465366307 - 73 - 0 - 72 - 2 - 10 -1.869973878918132 - 20 -2.229032723885395 - 40 -0.278430031320259 - 50 -80.92604653663092 - 51 -139.8013610445865 - 73 - 0 - 72 - 2 - 10 --0.101230703424352 - 20 -3.01093195074165 - 40 -2.004281084551049 - 50 -28.67087156360686 - 51 -33.18792433993601 - 73 - 0 - 72 - 2 - 10 -1.813793246529746 - 20 -2.127914574971419 - 40 -0.3198926968250738 - 50 -222.0119914468626 - 51 -273.6941141002521 - 73 - 1 - 72 - 2 - 10 -1.835672170020508 - 20 -1.78904239903142 - 40 -0.0196850393700788 - 50 -266.3058858997472 - 51 -446.3058858997478 - 73 - 0 - 72 - 2 - 10 -1.813793246529746 - 20 -2.127914574971419 - 40 -0.3592627755652315 - 50 -86.30588589974785 - 51 -136.3371185375852 - 73 - 0 - 72 - 2 - 10 -1.995105659775399 - 20 -1.606003070595645 - 40 -0.5192979821599312 - 50 -148.1708625321174 - 51 -171.6429565217715 - 73 - 1 - 72 - 2 - 10 -1.774379750743404 - 20 -1.9596864265737 - 40 -0.4040824222682091 - 50 -223.5109336967462 - 51 -281.1199173397384 - 73 - 1 - 72 - 2 - 10 -1.85610884645455 - 20 -1.543874911031386 - 40 -0.0196850393700787 - 50 -258.8800826602615 - 51 -438.8800826602615 - 73 - 0 - 72 - 2 - 10 -1.774379750743404 - 20 -1.9596864265737 - 40 -0.4434525010083663 - 50 -78.88008266026162 - 51 -132.2628434475095 - 73 - 0 - 72 - 2 - 10 -2.244252791706375 - 20 -1.579066020312694 - 40 -0.7698970604251502 - 50 -176.0947114644605 - 51 -193.0143530481955 - 73 - 1 - 72 - 2 - 10 -1.735391678484751 - 20 -1.622446814297793 - 40 -0.3243307282297058 - 50 -221.9378076910892 - 51 -317.3250616801697 - 73 - 1 - 72 - 2 - 10 -3.245154141910992 - 20 -1.721739021653846 - 40 -1.310755179243628 - 50 -165.9082787983328 - 51 -187.2257433809798 - 73 - 0 - 72 - 2 - 10 -2.601728566753492 - 20 -1.803316300498068 - 40 -0.6621787973190414 - 50 -187.2257433809798 - 51 -200.265282453191 - 73 - 0 - 72 - 2 - 10 -1.486332025585369 - 20 -2.215145842661859 - 40 -0.5268178451693419 - 50 -339.734717546809 - 51 -365.875687911445 - 73 - 1 - 72 - 2 - 10 -1.780100104900293 - 20 -2.245377841414935 - 40 -0.231498258665186 - 50 -5.875687911445098 - 51 -34.12431208855465 - 73 - 1 - 72 - 2 - 10 -1.928818024879454 - 20 -2.346159501416084 - 40 -0.0518487033762426 - 50 -34.12431208855484 - 51 -115.8756879114452 - 73 - 1 - 72 - 2 - 10 -2.043049297315996 - 20 -2.110655210550977 - 40 -0.3135948678531048 - 50 -115.8756879114451 - 51 -131.7156800642676 - 73 - 1 - 72 - 2 - 10 -2.105362384851459 - 20 -2.371962053549119 - 40 -0.2723538322513749 - 50 -185.7363493931126 - 51 -196.6535421822968 - 73 - 1 - 72 - 2 - 10 -2.224366300494004 - 20 -2.407559786221583 - 40 -0.3965678834278744 - 50 -196.6535421822967 - 51 -214.2452636527788 - 73 - 1 - 72 - 2 - 10 -1.775114796299714 - 20 -2.101729675474409 - 40 -0.1469014999420266 - 50 -325.7547363472213 - 51 -394.2452636527789 - 73 - 0 - 72 - 2 - 10 -1.880276536811822 - 20 -2.030140317515856 - 40 -0.0196850393700786 - 50 -34.24526365277875 - 51 -214.2452636527787 - 73 - 0 - 72 - 2 - 10 -1.775114796299714 - 20 -2.101729675474409 - 40 -0.1075314212018693 - 50 -325.7547363472211 - 51 -383.6864830926802 - 73 - 1 - 72 - 2 - 10 -1.724258670730545 - 20 -2.179559731729328 - 40 -0.1532919477378671 - 50 -13.05681211459937 - 51 -58.88974415557702 - 73 - 0 - 72 - 2 - 10 -1.793291568736173 - 20 -2.065168888754275 - 40 -0.0196850393700787 - 50 -58.88974415557702 - 51 -238.8897441555765 - 73 - 0 - 72 - 2 - 10 -1.724258670730541 - 20 -2.179559731729329 - 40 -0.1139218689977123 - 50 -301.1102558444241 - 51 -381.2576330469557 - 73 - 1 - 72 - 2 - 10 -2.224366300494005 - 20 -2.407559786221586 - 40 -0.435937962168034 - 50 -154.6425959514791 - 51 -163.3464578177032 - 73 - 0 - 72 - 2 - 10 -2.105362384851463 - 20 -2.371962053549115 - 40 -0.3117239109915352 - 50 -163.3464578177044 - 51 -168.3316806257954 - 73 - 0 - 97 - 1 -330 -4F7 - 92 - 16 - 93 - 7 - 72 - 2 - 10 -1.995105659775398 - 20 -1.606003070595649 - 40 -0.5586680609000869 - 50 -153.1774302023765 - 51 -173.1639087815069 - 73 - 1 - 72 - 2 - 10 -1.448830865211247 - 20 -2.213371853903018 - 40 -0.5409364048279738 - 50 -90.89204265530425 - 51 -153.6751728635248 - 73 - 0 - 72 - 2 - 10 -1.163637847655053 - 20 -1.838026139816656 - 40 -0.2412638458944706 - 50 -214.15747754694 - 51 -242.0052969205898 - 73 - 0 - 72 - 2 - 10 -1.134374454956795 - 20 -1.893074853652674 - 40 -0.1789203855540918 - 50 -242.0052969205894 - 51 -284.046994134434 - 73 - 0 - 72 - 2 - 10 -1.318324160529892 - 20 -2.123002906229338 - 40 -0.1514028023784195 - 50 -201.853727881165 - 51 -212.2168526331622 - 73 - 1 - 72 - 2 - 10 -1.492137893232153 - 20 -2.232530667257897 - 40 -0.3568475494804613 - 50 -212.2168526331617 - 51 -237.7831473668378 - 73 - 1 - 72 - 2 - 10 -1.573128668857933 - 20 -2.361057982102735 - 40 -0.5087645544459671 - 50 -237.7831473668379 - 51 -261.3425166986952 - 73 - 1 - 97 - 1 -330 -505 - 92 - 16 - 93 - 5 - 72 - 2 - 10 -1.75442661167109 - 20 -1.690434343062299 - 40 -0.5219798013778194 - 50 -181.7138221824677 - 51 -190.3415069086127 - 73 - 1 - 72 - 2 - 10 -1.382209127764958 - 20 -2.180776385554784 - 40 -0.6008907212088186 - 50 -103.5988396513469 - 51 -119.2343164314062 - 73 - 0 - 72 - 2 - 10 -1.26836984905495 - 20 -1.977371145189357 - 40 -0.3677961627452375 - 50 -119.2343164314065 - 51 -126.2926725539458 - 73 - 0 - 72 - 2 - 10 -1.365613936631298 - 20 -1.696475315724717 - 40 -0.3153299658786926 - 50 -177.17352188641 - 51 -195.5421431149888 - 73 - 0 - 72 - 2 - 10 -1.448830865211245 - 20 -2.213371853903018 - 40 -0.5803064835681301 - 50 -228.1704174204192 - 51 -248.1315658423051 - 73 - 1 - 97 - 1 -330 -507 - 92 - 16 - 93 - 5 - 72 - 2 - 10 -1.365613936631296 - 20 -1.696475315724716 - 40 -0.3547000446188475 - 50 -161.0626247765776 - 51 -177.1237827075663 - 73 - 1 - 72 - 2 - 10 -1.26836984905495 - 20 -1.977371145189359 - 40 -0.3677961627452389 - 50 -134.3293201388803 - 51 -152.0052969205894 - 73 - 0 - 72 - 2 - 10 -1.065938622495786 - 20 -1.869760556959495 - 40 -0.1385398865270621 - 50 -152.0052969205897 - 51 -197.9947030794107 - 73 - 0 - 72 - 2 - 10 -1.163637847655055 - 20 -1.838026139816656 - 40 -0.2412638458944715 - 50 -197.9947030794104 - 51 -202.8905358909278 - 73 - 0 - 72 - 2 - 10 -1.448830865211249 - 20 -2.213371853903019 - 40 -0.5803064835681331 - 50 -209.0183706588869 - 51 -223.8176444671686 - 73 - 1 - 97 - 1 -330 -509 - 92 - 16 - 93 - 6 - 72 - 2 - 10 -1.573128668857933 - 20 -2.361057982102735 - 40 -0.4693944757058101 - 50 -96.86618894004766 - 51 -122.2168526331621 - 73 - 0 - 72 - 2 - 10 -1.492137893232154 - 20 -2.232530667257898 - 40 -0.3174774707403054 - 50 -122.2168526331621 - 51 -147.7831473668382 - 73 - 0 - 72 - 2 - 10 -1.318324160529893 - 20 -2.123002906229338 - 40 -0.1120327236382623 - 50 -147.783147366838 - 51 -287.1653967341294 - 73 - 0 - 72 - 2 - 10 -1.134452552508394 - 20 -1.527737292608446 - 40 -0.7350495123332927 - 50 -287.1653967341295 - 51 -311.9725813008354 - 73 - 0 - 72 - 2 - 10 --0.1012307034243558 - 20 -3.010931950741639 - 40 -1.964911005810889 - 50 -28.47135626072658 - 51 -33.82931909093841 - 73 - 0 - 72 - 2 - 10 -1.9951056597754 - 20 -1.606003070595648 - 40 -0.5586680609000885 - 50 -146.1706809090616 - 51 -148.8453401595469 - 73 - 1 - 97 - 1 -330 -50B - 92 - 16 - 93 - 4 - 72 - 2 - 10 -2.434808481477273 - 20 -1.741760238465535 - 40 -0.4213944983540373 - 50 -350.138398092684 - 51 -368.2079411900966 - 73 - 1 - 72 - 2 - 10 -2.232025923290449 - 20 -2.76206241576646 - 40 -1.142846610535555 - 50 -302.8460023643591 - 51 -313.5174616433824 - 73 - 1 - 72 - 2 - 10 -2.435514026542539 - 20 -1.986930556286178 - 40 -0.5859069085937808 - 50 -5.250840664227033 - 51 -24.12657987446927 - 73 - 0 - 72 - 2 - 10 -2.358343856922903 - 20 -2.560871504972432 - 40 -1.017884167165218 - 50 -53.04812421612736 - 51 -61.11882105703474 - 73 - 0 - 97 - 1 -330 -510 - 92 - 16 - 93 - 5 - 72 - 2 - 10 -1.606711922375474 - 20 -1.348933253591385 - 40 -0.3531275930849602 - 50 -135.3746912145926 - 51 -157.4176362906217 - 73 - 0 - 72 - 2 - 10 -1.454717916970981 - 20 -2.022108206218514 - 40 -0.827297613601817 - 50 -257.8545362072944 - 51 -275.2691677284761 - 73 - 1 - 72 - 2 - 10 -1.872170704325741 - 20 -1.396215376152876 - 40 -0.3946836881941063 - 50 -210.0950891144055 - 51 -232.5295145799341 - 73 - 1 - 72 - 2 - 10 -1.542373482613905 - 20 -1.835739673019258 - 40 -0.75809597646572 - 50 -83.20542127045559 - 51 -101.5302981560868 - 73 - 0 - 72 - 2 - 10 -1.584035429735767 - 20 -2.039961850738253 - 40 -0.9665244191271609 - 50 -101.5302981560871 - 51 -103.684145503982 - 73 - 0 - 97 - 1 -330 -559 - 92 - 16 - 93 - 17 - 72 - 2 - 10 -2.10536238485146 - 20 -2.371962053549118 - 40 -0.2723538322513761 - 50 -159.7337422418206 - 51 -175.1380365575864 - 73 - 1 - 72 - 2 - 10 -2.043049297315996 - 20 -2.110655210550977 - 40 -0.352964946593263 - 50 -233.6796832772765 - 51 -244.1243120885548 - 73 - 0 - 72 - 2 - 10 -1.928818024879453 - 20 -2.346159501416084 - 40 -0.0912187821164004 - 50 -244.1243120885551 - 51 -325.8756879114455 - 73 - 0 - 72 - 2 - 10 -1.780100104900293 - 20 -2.245377841414934 - 40 -0.2708683374053446 - 50 -325.8756879114452 - 51 -354.1243120885547 - 73 - 0 - 72 - 2 - 10 -1.486332025585371 - 20 -2.215145842661859 - 40 -0.5661879239094977 - 50 -354.124312088555 - 51 -380.265282453191 - 73 - 0 - 72 - 2 - 10 -2.601728566753494 - 20 -1.803316300498069 - 40 -0.622808718578886 - 50 -159.7347175468091 - 51 -172.7742566190203 - 73 - 1 - 72 - 2 - 10 -3.245154141910993 - 20 -1.721739021653846 - 40 -1.271385100503472 - 50 -172.7742566190202 - 51 -197.2257433809798 - 73 - 1 - 72 - 2 - 10 -2.448387279831183 - 20 -1.474706126417881 - 40 -0.4372012575544668 - 50 -197.2257433809797 - 51 -229.6909739682446 - 73 - 1 - 72 - 2 - 10 -1.84273355618451 - 20 -1.606506575382588 - 40 -0.5662349988373949 - 50 -304.7588400511317 - 51 -309.2074896477569 - 73 - 1 - 72 - 2 - 10 -3.174161319020478 - 20 -1.699913413586492 - 40 -1.109452231228011 - 50 -151.3367493281762 - 51 -186.2319675330486 - 73 - 0 - 72 - 2 - 10 -3.49641038484678 - 20 -1.664724034128332 - 40 -1.433616931423104 - 50 -186.2319675330492 - 51 -205.0988169699291 - 73 - 0 - 72 - 2 - 10 --37.1850685335689 - 20 -20.72029698200291 - 40 -43.48962412887072 - 50 -334.901183030072 - 51 -335.0988169699286 - 73 - 1 - 72 - 2 - 10 -1.05207209728287 - 20 -2.970247608757844 - 40 -1.33344811187206 - 50 -335.0988169699285 - 51 -348.9886439523909 - 73 - 1 - 72 - 2 - 10 -1.959203223948364 - 20 -2.950701101027533 - 40 -0.4655223034750759 - 50 -30.33963089325502 - 51 -49.03787718203768 - 73 - 0 - 72 - 2 - 10 -1.804450685812644 - 20 -3.128961400613438 - 40 -0.701583910831935 - 50 -49.03787718203728 - 51 -65.26030603284518 - 73 - 0 - 72 - 2 - 10 -1.924151714798596 - 20 -2.869186907390315 - 40 -0.4155574720721139 - 50 -65.26030603284511 - 51 -82.84890216530907 - 73 - 0 - 72 - 2 - 10 -1.936208898089171 - 20 -2.773084900679216 - 40 -0.318702057340656 - 50 -82.84890216530943 - 51 -105.7184590811235 - 73 - 0 - 97 - 1 -330 -4F3 - 92 - 16 - 93 - 17 - 72 - 2 - 10 -1.885608931176688 - 20 -3.176688874055116 - 40 -0.2129975912966591 - 50 -114.9006616575818 - 51 -156.4878117659684 - 73 - 1 - 72 - 2 - 10 -2.636203773812854 - 20 -2.850131072655588 - 40 -1.031552791296577 - 50 -156.4878117659688 - 51 -180.6082887577103 - 73 - 1 - 72 - 2 - 10 -1.952094170360633 - 20 -2.842867853274917 - 40 -0.3474046319836055 - 50 -180.6082887577101 - 51 -213.6393369978933 - 73 - 1 - 72 - 2 - 10 -1.964644164547905 - 20 -2.851218474936612 - 40 -0.3624789557242355 - 50 -213.6393369978933 - 51 -250.0019612921961 - 73 - 1 - 72 - 2 - 10 -1.936208898089171 - 20 -2.773084900679217 - 40 -0.2793319786004991 - 50 -250.001961292196 - 51 -277.1510978346906 - 73 - 1 - 72 - 2 - 10 -1.924151714798597 - 20 -2.869186907390317 - 40 -0.3761873933319576 - 50 -277.1510978346908 - 51 -294.7396939671547 - 73 - 1 - 72 - 2 - 10 -1.804450685812644 - 20 -3.128961400613437 - 40 -0.6622138320917775 - 50 -294.7396939671549 - 51 -310.9621228179628 - 73 - 1 - 72 - 2 - 10 -1.959203223948364 - 20 -2.950701101027533 - 40 -0.4261522247349184 - 50 -310.9621228179625 - 51 -357.7626023297964 - 73 - 1 - 72 - 2 - 10 -0.9685713550985386 - 20 -2.989404907072427 - 40 -1.417539880590719 - 50 -357.7626023297966 - 51 -367.3820705420636 - 73 - 1 - 72 - 2 - 10 -2.2125235694189 - 20 -3.150570273791624 - 40 -0.1631908912969642 - 50 -7.382070542063584 - 51 -53.5251061991567 - 73 - 1 - 72 - 2 - 10 -1.924407631021267 - 20 -3.452788946261674 - 40 -0.4213817967382122 - 50 -23.94086726929591 - 51 -38.56090658709021 - 73 - 0 - 72 - 2 - 10 -2.174464534980624 - 20 -3.253450334179865 - 40 -0.1015938396722196 - 50 -38.56090658709 - 51 -128.8844964337146 - 73 - 0 - 72 - 1 - 10 -2.110688753100606 - 20 -3.174368364648643 - 11 -2.049360338450518 - 21 -3.223826763560005 - 72 - 1 - 10 -2.049360338450518 - 20 -3.223826763560005 - 11 -2.020698206844207 - 21 -3.208114453397319 - 72 - 2 - 10 -1.961644849992286 - 20 -3.289054064709398 - 40 -0.1001924130602254 - 50 -53.88559445512062 - 51 -115.5479523260344 - 73 - 0 - 72 - 2 - 10 -2.0110372932182 - 20 -3.39238482801838 - 40 -0.2147212744613677 - 50 -115.5479523260344 - 51 -163.3991489022965 - 73 - 0 - 72 - 2 - 10 -2.161160122792123 - 20 -3.437140815427867 - 40 -0.371373635976537 - 50 -163.3991489022961 - 51 -169.5663152899231 - 73 - 0 - 97 - 1 -330 -4C9 - 92 - 16 - 93 - 13 - 72 - 1 - 10 -2.053553115266256 - 20 -3.271022854778554 - 11 -2.135403416533275 - 21 -3.205014547305152 - 72 - 2 - 10 -2.174464534980624 - 20 -3.253450334179865 - 40 -0.0622237609320623 - 50 -231.1155035662852 - 51 -321.4390934129098 - 73 - 1 - 72 - 2 - 10 -1.924407631021268 - 20 -3.452788946261673 - 40 -0.3820117179980535 - 50 -321.4390934129098 - 51 -381.7909975373624 - 73 - 1 - 72 - 2 - 10 -2.205371433700895 - 20 -3.565115244906947 - 40 -0.0794264312051501 - 50 -21.79099753736259 - 51 -138.4608414339663 - 73 - 1 - 72 - 2 - 10 -2.359201923855247 - 20 -3.432035664951207 - 40 -0.2828284405938025 - 50 -138.9469336075647 - 51 -155.609089205736 - 73 - 1 - 72 - 2 - 10 -2.083688019187524 - 20 -3.556961618598168 - 40 -0.0196850393700788 - 50 -24.39091079426373 - 51 -197.0763607466141 - 73 - 0 - 72 - 1 - 10 -2.064870809553132 - 20 -3.562742050811843 - 11 -2.082872800905891 - 21 -3.621344458486482 - 72 - 2 - 10 -1.984695044370157 - 20 -3.635415634546031 - 40 -0.099180995528825 - 50 -351.8437155425206 - 51 -398.1173531107838 - 73 - 1 - 72 - 2 - 10 -2.010334078755422 - 20 -3.655531747894149 - 40 -0.066592376342933 - 50 -38.11735311078365 - 51 -124.6298938385513 - 73 - 1 - 72 - 2 - 10 -2.161160122792124 - 20 -3.437140815427865 - 40 -0.3320035572363805 - 50 -124.6298938385515 - 51 -196.6008510977037 - 73 - 1 - 72 - 2 - 10 -2.011037293218199 - 20 -3.39238482801838 - 40 -0.1753511957212102 - 50 -196.6008510977036 - 51 -244.4520476739657 - 73 - 1 - 72 - 2 - 10 -1.961644849992285 - 20 -3.289054064709398 - 40 -0.0608223343200681 - 50 -244.4520476739658 - 51 -308.2116001220994 - 73 - 1 - 72 - 1 - 10 -1.999267568517967 - 20 -3.241264030153233 - 11 -2.053553115266256 - 21 -3.271022854778554 - 97 - 1 -330 -4CB - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -C40 -330 -1F -100 -AcDbEntity - 8 -HATCH-WHITE -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 3 - 92 - 1 - 93 - 13 - 72 - 1 - 10 -2.053553115266256 - 20 -3.271022854778554 - 11 -2.135403416533275 - 21 -3.205014547305152 - 72 - 2 - 10 -2.174464534980624 - 20 -3.253450334179865 - 40 -0.0622237609320623 - 50 -231.1155035662852 - 51 -321.4390934129098 - 73 - 1 - 72 - 2 - 10 -1.924407631021268 - 20 -3.452788946261673 - 40 -0.3820117179980535 - 50 -321.4390934129098 - 51 -381.7909975373624 - 73 - 1 - 72 - 2 - 10 -2.205371433700895 - 20 -3.565115244906947 - 40 -0.0794264312051501 - 50 -21.79099753736259 - 51 -138.4608414339663 - 73 - 1 - 72 - 2 - 10 -2.359201923855247 - 20 -3.432035664951207 - 40 -0.2828284405938025 - 50 -138.9469336075647 - 51 -155.609089205736 - 73 - 1 - 72 - 2 - 10 -2.083688019187524 - 20 -3.556961618598168 - 40 -0.0196850393700788 - 50 -24.39091079426373 - 51 -197.0763607466141 - 73 - 0 - 72 - 1 - 10 -2.064870809553132 - 20 -3.562742050811843 - 11 -2.082872800905891 - 21 -3.621344458486482 - 72 - 2 - 10 -1.984695044370157 - 20 -3.635415634546031 - 40 -0.099180995528825 - 50 -351.8437155425206 - 51 -398.1173531107838 - 73 - 1 - 72 - 2 - 10 -2.010334078755422 - 20 -3.655531747894149 - 40 -0.066592376342933 - 50 -38.11735311078365 - 51 -124.6298938385513 - 73 - 1 - 72 - 2 - 10 -2.161160122792124 - 20 -3.437140815427865 - 40 -0.3320035572363805 - 50 -124.6298938385515 - 51 -196.6008510977037 - 73 - 1 - 72 - 2 - 10 -2.011037293218199 - 20 -3.39238482801838 - 40 -0.1753511957212102 - 50 -196.6008510977036 - 51 -244.4520476739657 - 73 - 1 - 72 - 2 - 10 -1.961644849992285 - 20 -3.289054064709398 - 40 -0.0608223343200681 - 50 -244.4520476739658 - 51 -308.2116001220994 - 73 - 1 - 72 - 1 - 10 -1.999267568517967 - 20 -3.241264030153233 - 11 -2.053553115266256 - 21 -3.271022854778554 - 97 - 1 -330 -4CB - 92 - 16 - 93 - 8 - 72 - 2 - 10 -2.10076671703864 - 20 -3.325655213407455 - 40 -0.0599397668605327 - 50 -267.8793336511986 - 51 -377.8793336511989 - 73 - 1 - 72 - 2 - 10 -2.052741812238583 - 20 -3.310162719091439 - 40 -0.1104017214519507 - 50 -17.87933365119892 - 51 -43.7673166448306 - 73 - 1 - 72 - 2 - 10 -2.103395451769339 - 20 -3.340116557206334 - 40 -0.0547683672910658 - 50 -57.93744139888317 - 51 -187.77563216475 - 73 - 1 - 72 - 2 - 10 -2.068634698539837 - 20 -3.335369986556996 - 40 -0.0196850393700788 - 50 -187.7756321647501 - 51 -367.7756321647502 - 73 - 1 - 72 - 2 - 10 -2.103395451769339 - 20 -3.340116557206334 - 40 -0.0153982885509082 - 50 -172.2243678352504 - 51 -287.334302618237 - 73 - 0 - 72 - 2 - 10 -2.052741812238584 - 20 -3.310162719091439 - 40 -0.0710316427117921 - 50 -321.0507208994834 - 51 -342.1206663488011 - 73 - 0 - 72 - 2 - 10 -2.100766717038639 - 20 -3.325655213407456 - 40 -0.0205696881203755 - 50 -342.1206663488009 - 51 -452.1206663488013 - 73 - 0 - 72 - 2 - 10 -2.099277124665835 - 20 -3.285428055915363 - 40 -0.0196850393700787 - 50 -87.8793336512005 - 51 -267.8793336511979 - 73 - 1 - 97 - 1 -330 -235 - 92 - 16 - 93 - 8 - 72 - 2 - 10 -1.921485017130019 - 20 -3.343003198213819 - 40 -0.0771903814552135 - 50 -359.5978819190761 - 51 -374.2374903606301 - 73 - 1 - 72 - 2 - 10 -1.980044176928186 - 20 -3.357861720825169 - 40 -0.0167755580220592 - 50 -14.23749036062933 - 51 -155.7625096393687 - 73 - 1 - 72 - 2 - 10 -2.003282808101446 - 20 -3.34739958355454 - 40 -0.0422606574936387 - 50 -155.7625096393692 - 51 -241.4329313324614 - 73 - 1 - 72 - 2 - 10 -1.973661171909946 - 20 -3.292995281984995 - 40 -0.0196850393700789 - 50 -298.5670686675385 - 51 -478.5670686675385 - 73 - 0 - 72 - 2 - 10 -2.003282808101446 - 20 -3.34739958355454 - 40 -0.0816307362337962 - 50 -118.5670686675387 - 51 -204.2374903606309 - 73 - 0 - 72 - 2 - 10 -1.980044176928186 - 20 -3.357861720825169 - 40 -0.0561456367622165 - 50 -204.2374903606306 - 51 -345.7625096393699 - 73 - 0 - 72 - 2 - 10 -1.921485017130019 - 20 -3.34300319821382 - 40 -0.1165604601953712 - 50 -345.76250963937 - 51 -360.4021180809241 - 73 - 0 - 72 - 2 - 10 -2.018358052101874 - 20 -3.342323304531541 - 40 -0.0196850393700787 - 50 -0.4021180809244088 - 51 -180.4021180809231 - 73 - 0 - 97 - 1 -330 -267 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -LWPOLYLINE - 5 -CB7 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 2 - 70 - 0 - 43 -0.0 - 10 -1.999999999999999 - 20 -0.5021900451212454 - 10 -1.999999999999998 - 20 -0.2137188753069325 - 0 -LWPOLYLINE - 5 -129E -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -1.699999999999999 - 20 -0.4263456413348424 - 10 -1.590116389297469 - 20 -0.3629043091162095 - 10 -1.590116389297469 - 20 -0.2153520942475884 - 0 -LWPOLYLINE - 5 -12B7 -102 -{ACAD_REACTORS -330 -1B2B -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 68 - 70 - 1 - 43 -0.0 - 10 -0.211518030839291 - 20 -1.132195865069596 - 10 -0.2115180308392921 - 20 -0.8856214579511849 - 10 -0.3800563547419098 - 20 -0.8242785247175163 - 10 -0.4819904717841743 - 20 -0.8831302146314739 - 42 --0.9999999999999999 - 10 -0.501675511154253 - 20 -0.8490347262935038 - 10 -0.4283509058011884 - 20 -0.8067007456546893 - 10 -0.4606008219772955 - 20 -0.7949627361090064 - 10 -0.56253493901956 - 20 -0.8538144260229641 - 42 --0.9999999999999999 - 10 -0.5822199783896387 - 20 -0.8197189376849939 - 10 -0.5088953730365742 - 20 -0.7773849570461795 - 10 -0.5411452892126811 - 20 -0.7656469475004968 - 10 -0.6430794062549456 - 20 -0.8244986374144544 - 42 --0.9999999999999999 - 10 -0.6627644456250243 - 20 -0.7904031490764842 - 10 -0.5894398402719598 - 20 -0.7480691684376697 - 10 -0.6216897564480669 - 20 -0.736331158891987 - 10 -0.7236238734903314 - 20 -0.7951828488059446 - 42 --0.9999999999999999 - 10 -0.7433089128604101 - 20 -0.7610873604679744 - 10 -0.6699843075073457 - 20 -0.7187533798291599 - 10 -0.7022342236834526 - 20 -0.7070153702834772 - 10 -0.8041683407257171 - 20 -0.7658670601974349 - 42 --0.9999999999999999 - 10 -0.8238533800957958 - 20 -0.7317715718594647 - 10 -0.7505287747427313 - 20 -0.6894375912206502 - 10 -0.7827786909188382 - 20 -0.6776995816749674 - 10 -0.8847128079611027 - 20 -0.7365512715889251 - 42 --0.9999999999999999 - 10 -0.9043978473311814 - 20 -0.7024557832509549 - 10 -0.8310732419781172 - 20 -0.6601218026121404 - 10 -0.8633231581542239 - 20 -0.6483837930664577 - 10 -0.9652572751964884 - 20 -0.7072354829804153 - 42 --0.9999999999999999 - 10 -0.9849423145665671 - 20 -0.6731399946424452 - 10 -0.9116177092135024 - 20 -0.6308060140036307 - 10 -0.9438676253896097 - 20 -0.619068004457948 - 10 -1.045801742431874 - 20 -0.6779196943719056 - 42 --0.9999999999999999 - 10 -1.065486781801953 - 20 -0.6438242060339354 - 10 -0.992162176448888 - 20 -0.6014902253951211 - 10 -1.024412092624995 - 20 -0.5897522158494382 - 10 -1.12634620966726 - 20 -0.6486039057633959 - 42 --0.9999999999999999 - 10 -1.146031249037339 - 20 -0.6145084174254256 - 10 -1.072706643684274 - 20 -0.5721744367866111 - 10 -1.104956559860381 - 20 -0.5604364272409283 - 10 -1.206890676902646 - 20 -0.6192881171548861 - 42 --0.9999999999999999 - 10 -1.226575716272724 - 20 -0.5851926288169159 - 10 -1.15325111091966 - 20 -0.5428586481781015 - 10 -1.185501027095767 - 20 -0.5311206386324185 - 10 -1.287435144138031 - 20 -0.5899723285463763 - 42 --0.9999999999999999 - 10 -1.30712018350811 - 20 -0.5558768402084061 - 10 -1.233795578155045 - 20 -0.5135428595695918 - 10 -1.266045494331153 - 20 -0.5018048500239088 - 10 -1.367979611373417 - 20 -0.5606565399378665 - 42 --0.9999999999999999 - 10 -1.387664650743496 - 20 -0.5265610515998964 - 10 -1.314340045390431 - 20 -0.4842270709610819 - 10 -1.346589961566538 - 20 -0.4724890614153991 - 10 -1.448524078608803 - 20 -0.5313407513293568 - 42 --0.9999999999999999 - 10 -1.468209117978881 - 20 -0.4972452629913866 - 10 -1.394884512625817 - 20 -0.4549112823525721 - 10 -1.427134428801924 - 20 -0.4431732728068893 - 10 -1.529068545844188 - 20 -0.5020249627208471 - 42 --0.9999999999999999 - 10 -1.548753585214267 - 20 -0.4679294743828769 - 10 -1.475428979861203 - 20 -0.4255954937440624 - 10 -1.50767889603731 - 20 -0.4138574841983796 - 10 -1.609613013079574 - 20 -0.4727091741123373 - 42 --0.9999999999999999 - 10 -1.629298052449653 - 20 -0.4386136857743671 - 10 -1.555973447096588 - 20 -0.3962797051355528 - 10 -1.588223363272695 - 20 -0.3845416955898698 - 10 -1.69015748031496 - 20 -0.4433933855038275 - 42 --0.9999999999999999 - 10 -1.709842519685038 - 20 -0.4092978971658573 - 10 -1.636517914331974 - 20 -0.366963916527043 - 10 -1.980314960629922 - 20 -0.2418320250459505 - 10 -1.980314960629921 - 20 -0.4884064321643613 - 0 -LWPOLYLINE - 5 -12FB -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -0.4918329914692137 - 20 -0.8660824704624889 - 10 -0.3819493807666841 - 20 -0.802641138243856 - 10 -0.3819493807666836 - 20 -0.6550889233752348 - 0 -LWPOLYLINE - 5 -133B -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -1.619455532764613 - 20 -0.4556614299433522 - 10 -1.509571922062084 - 20 -0.3922200977247193 - 10 -1.509571922062083 - 20 -0.2446678828560982 - 0 -LWPOLYLINE - 5 -136A -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -1.538911065529228 - 20 -0.4849772185518619 - 10 -1.429027454826698 - 20 -0.421535886333229 - 10 -1.429027454826698 - 20 -0.2739836714646079 - 0 -LWPOLYLINE - 5 -1399 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -1.458366598293842 - 20 -0.5142930071603717 - 10 -1.348482987591312 - 20 -0.4508516749417388 - 10 -1.348482987591312 - 20 -0.3032994600731177 - 0 -LWPOLYLINE - 5 -13C8 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -1.377822131058456 - 20 -0.5436087957688814 - 10 -1.267938520355927 - 20 -0.4801674635502485 - 10 -1.267938520355926 - 20 -0.3326152486816275 - 0 -LWPOLYLINE - 5 -13F7 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -1.297277663823071 - 20 -0.5729245843773911 - 10 -1.187394053120541 - 20 -0.5094832521587582 - 10 -1.18739405312054 - 20 -0.3619310372901372 - 0 -LWPOLYLINE - 5 -1426 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -1.216733196587685 - 20 -0.6022403729859009 - 10 -1.106849585885155 - 20 -0.538799040767268 - 10 -1.106849585885155 - 20 -0.391246825898647 - 0 -LWPOLYLINE - 5 -1455 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -1.136188729352299 - 20 -0.6315561615944107 - 10 -1.02630511864977 - 20 -0.5681148293757778 - 10 -1.026305118649769 - 20 -0.4205626145071568 - 0 -LWPOLYLINE - 5 -1484 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -1.055644262116914 - 20 -0.6608719502029206 - 10 -0.9457606514143839 - 20 -0.5974306179842876 - 10 -0.9457606514143835 - 20 -0.4498784031156665 - 0 -LWPOLYLINE - 5 -14B3 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -0.9750997948815278 - 20 -0.6901877388114303 - 10 -0.8652161841789981 - 20 -0.6267464065927973 - 10 -0.8652161841789977 - 20 -0.4791941917241763 - 0 -LWPOLYLINE - 5 -14E2 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -0.8945553276461421 - 20 -0.71950352741994 - 10 -0.7846717169436125 - 20 -0.656062195201307 - 10 -0.784671716943612 - 20 -0.508509980332686 - 0 -LWPOLYLINE - 5 -1511 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -0.8140108604107564 - 20 -0.7488193160284498 - 10 -0.7041272497082268 - 20 -0.6853779838098168 - 10 -0.7041272497082264 - 20 -0.5378257689411958 - 0 -LWPOLYLINE - 5 -1540 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -0.7334663931753708 - 20 -0.7781351046369596 - 10 -0.6235827824728412 - 20 -0.7146937724183267 - 10 -0.6235827824728407 - 20 -0.5671415575497055 - 0 -LWPOLYLINE - 5 -156F -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -0.652921925939985 - 20 -0.8074508932454694 - 10 -0.5430383152374554 - 20 -0.7440095610268365 - 10 -0.5430383152374549 - 20 -0.5964573461582153 - 0 -LWPOLYLINE - 5 -159E -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -0.5723774587045993 - 20 -0.836766681853979 - 10 -0.4624938480020697 - 20 -0.773325349635346 - 10 -0.4624938480020693 - 20 -0.625773134766725 - 0 -LWPOLYLINE - 5 -19B1 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -2.300000000000002 - 20 -0.4263456413348424 - 10 -2.409883610702532 - 20 -0.3629043091162095 - 10 -2.409883610702533 - 20 -0.2153520942475884 - 0 -LWPOLYLINE - 5 -19B2 -102 -{ACAD_REACTORS -330 -1B2B -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 68 - 70 - 1 - 43 -0.0 - 10 -3.788481969160711 - 20 -1.132195865069596 - 10 -3.78848196916071 - 20 -0.8856214579511849 - 10 -3.619943645258092 - 20 -0.8242785247175163 - 10 -3.518009528215828 - 20 -0.8831302146314739 - 42 -0.9999999999999999 - 10 -3.498324488845749 - 20 -0.8490347262935038 - 10 -3.571649094198813 - 20 -0.8067007456546893 - 10 -3.539399178022706 - 20 -0.7949627361090064 - 10 -3.437465060980442 - 20 -0.8538144260229641 - 42 -0.9999999999999999 - 10 -3.417780021610363 - 20 -0.8197189376849939 - 10 -3.491104626963428 - 20 -0.7773849570461795 - 10 -3.458854710787321 - 20 -0.7656469475004968 - 10 -3.356920593745056 - 20 -0.8244986374144544 - 42 -0.9999999999999999 - 10 -3.337235554374978 - 20 -0.7904031490764842 - 10 -3.410560159728042 - 20 -0.7480691684376697 - 10 -3.378310243551935 - 20 -0.736331158891987 - 10 -3.27637612650967 - 20 -0.7951828488059446 - 42 -0.9999999999999999 - 10 -3.256691087139592 - 20 -0.7610873604679744 - 10 -3.330015692492656 - 20 -0.7187533798291599 - 10 -3.297765776316549 - 20 -0.7070153702834772 - 10 -3.195831659274285 - 20 -0.7658670601974349 - 42 -0.9999999999999999 - 10 -3.176146619904206 - 20 -0.7317715718594647 - 10 -3.24947122525727 - 20 -0.6894375912206502 - 10 -3.217221309081164 - 20 -0.6776995816749674 - 10 -3.115287192038899 - 20 -0.7365512715889251 - 42 -0.9999999999999999 - 10 -3.09560215266882 - 20 -0.7024557832509549 - 10 -3.168926758021885 - 20 -0.6601218026121404 - 10 -3.136676841845778 - 20 -0.6483837930664577 - 10 -3.034742724803513 - 20 -0.7072354829804153 - 42 -0.9999999999999999 - 10 -3.015057685433435 - 20 -0.6731399946424452 - 10 -3.0883822907865 - 20 -0.6308060140036307 - 10 -3.056132374610392 - 20 -0.619068004457948 - 10 -2.954198257568128 - 20 -0.6779196943719056 - 42 -0.9999999999999999 - 10 -2.934513218198049 - 20 -0.6438242060339354 - 10 -3.007837823551114 - 20 -0.6014902253951211 - 10 -2.975587907375006 - 20 -0.5897522158494382 - 10 -2.873653790332742 - 20 -0.6486039057633959 - 42 -0.9999999999999999 - 10 -2.853968750962663 - 20 -0.6145084174254256 - 10 -2.927293356315728 - 20 -0.5721744367866111 - 10 -2.895043440139621 - 20 -0.5604364272409283 - 10 -2.793109323097356 - 20 -0.6192881171548861 - 42 -0.9999999999999999 - 10 -2.773424283727278 - 20 -0.5851926288169159 - 10 -2.846748889080342 - 20 -0.5428586481781015 - 10 -2.814498972904235 - 20 -0.5311206386324185 - 10 -2.712564855861971 - 20 -0.5899723285463763 - 42 -0.9999999999999999 - 10 -2.692879816491892 - 20 -0.5558768402084061 - 10 -2.766204421844956 - 20 -0.5135428595695918 - 10 -2.733954505668849 - 20 -0.5018048500239088 - 10 -2.632020388626585 - 20 -0.5606565399378665 - 42 -0.9999999999999999 - 10 -2.612335349256506 - 20 -0.5265610515998964 - 10 -2.68565995460957 - 20 -0.4842270709610819 - 10 -2.653410038433464 - 20 -0.4724890614153991 - 10 -2.551475921391199 - 20 -0.5313407513293568 - 42 -0.9999999999999999 - 10 -2.53179088202112 - 20 -0.4972452629913866 - 10 -2.605115487374185 - 20 -0.4549112823525721 - 10 -2.572865571198078 - 20 -0.4431732728068893 - 10 -2.470931454155814 - 20 -0.5020249627208471 - 42 -0.9999999999999999 - 10 -2.451246414785735 - 20 -0.4679294743828769 - 10 -2.524571020138799 - 20 -0.4255954937440624 - 10 -2.492321103962692 - 20 -0.4138574841983796 - 10 -2.390386986920428 - 20 -0.4727091741123373 - 42 -0.9999999999999999 - 10 -2.370701947550349 - 20 -0.4386136857743671 - 10 -2.444026552903414 - 20 -0.3962797051355528 - 10 -2.411776636727307 - 20 -0.3845416955898698 - 10 -2.309842519685042 - 20 -0.4433933855038275 - 42 -0.9999999999999999 - 10 -2.290157480314964 - 20 -0.4092978971658573 - 10 -2.363482085668028 - 20 -0.366963916527043 - 10 -2.01968503937008 - 20 -0.2418320250459505 - 10 -2.019685039370081 - 20 -0.4884064321643613 - 0 -LWPOLYLINE - 5 -19B3 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -2.461088934470774 - 20 -0.4849772185518619 - 10 -2.570972545173304 - 20 -0.421535886333229 - 10 -2.570972545173304 - 20 -0.2739836714646079 - 0 -LWPOLYLINE - 5 -19B4 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -2.380544467235389 - 20 -0.4556614299433522 - 10 -2.490428077937918 - 20 -0.3922200977247193 - 10 -2.490428077937918 - 20 -0.2446678828560982 - 0 -LWPOLYLINE - 5 -19B5 -102 -{ACAD_REACTORS -330 -1B2B -102 -} -330 -1F -100 -AcDbEntity - 8 -OUTLINE -100 -AcDbPolyline - 90 - 145 - 70 - 1 - 43 -0.0 - 10 -0.1721479520991344 - 20 -0.8718378449943008 - 42 -0.3152987888789827 - 10 -0.1851003114824874 - 20 -0.8533399587583579 - 10 -0.3622643413966053 - 20 -0.7888575252869718 - 10 -0.3622643413966049 - 20 -0.6550889233752349 - 42 -0.9999999999999999 - 10 -0.4016344201367623 - 20 -0.6550889233752348 - 10 -0.4016344201367628 - 20 -0.7745279885048381 - 10 -0.442808808631991 - 20 -0.759541736678462 - 10 -0.4428088086319906 - 20 -0.625773134766725 - 42 -0.9999999999999999 - 10 -0.482178887372148 - 20 -0.625773134766725 - 10 -0.4821788873721484 - 20 -0.7452121998963283 - 10 -0.5233532758673767 - 20 -0.7302259480699523 - 10 -0.5233532758673762 - 20 -0.5964573461582154 - 42 -0.9999999999999999 - 10 -0.5627233546075336 - 20 -0.5964573461582152 - 10 -0.5627233546075341 - 20 -0.7158964112878186 - 10 -0.6038977431027625 - 20 -0.7009101594614425 - 10 -0.603897743102762 - 20 -0.5671415575497056 - 42 -0.9999999999999999 - 10 -0.6432678218429194 - 20 -0.5671415575497054 - 10 -0.6432678218429199 - 20 -0.6865806226793086 - 10 -0.6844422103381481 - 20 -0.6715943708529328 - 10 -0.6844422103381477 - 20 -0.5378257689411958 - 42 -0.9999999999999999 - 10 -0.7238122890783051 - 20 -0.5378257689411958 - 10 -0.7238122890783055 - 20 -0.6572648340707989 - 10 -0.7649866775735338 - 20 -0.642278582244423 - 10 -0.7649866775735333 - 20 -0.508509980332686 - 42 -0.9999999999999999 - 10 -0.8043567563136907 - 20 -0.508509980332686 - 10 -0.8043567563136912 - 20 -0.6279490454622892 - 10 -0.8455311448089194 - 20 -0.6129627936359132 - 10 -0.845531144808919 - 20 -0.4791941917241763 - 42 -0.9999999999999999 - 10 -0.8849012235490764 - 20 -0.4791941917241762 - 10 -0.8849012235490769 - 20 -0.5986332568537795 - 10 -0.9260756120443052 - 20 -0.5836470050274035 - 10 -0.9260756120443048 - 20 -0.4498784031156666 - 42 -0.9999999999999999 - 10 -0.9654456907844622 - 20 -0.4498784031156665 - 10 -0.9654456907844626 - 20 -0.5693174682452696 - 10 -1.006620079279691 - 20 -0.5543312164188938 - 10 -1.00662007927969 - 20 -0.4205626145071568 - 42 -0.9999999999999999 - 10 -1.045990158019848 - 20 -0.4205626145071567 - 10 -1.045990158019848 - 20 -0.5400016796367598 - 10 -1.087164546515077 - 20 -0.525015427810384 - 10 -1.087164546515076 - 20 -0.3912468258986471 - 42 -0.9999999999999999 - 10 -1.126534625255234 - 20 -0.391246825898647 - 10 -1.126534625255234 - 20 -0.5106858910282501 - 10 -1.167709013750462 - 20 -0.4956996392018742 - 10 -1.167709013750462 - 20 -0.3619310372901373 - 42 -0.9999999999999999 - 10 -1.207079092490619 - 20 -0.3619310372901371 - 10 -1.20707909249062 - 20 -0.4813701024197403 - 10 -1.248253480985848 - 20 -0.4663838505933645 - 10 -1.248253480985848 - 20 -0.3326152486816275 - 42 -0.9999999999999999 - 10 -1.287623559726005 - 20 -0.3326152486816274 - 10 -1.287623559726006 - 20 -0.4520543138112305 - 10 -1.328797948221234 - 20 -0.4370680619848547 - 10 -1.328797948221233 - 20 -0.3032994600731178 - 42 -0.9999999999999999 - 10 -1.368168026961391 - 20 -0.3032994600731176 - 10 -1.368168026961391 - 20 -0.4227385252027208 - 10 -1.409342415456619 - 20 -0.407752273376345 - 10 -1.409342415456619 - 20 -0.273983671464608 - 42 -0.9999999999999999 - 10 -1.448712494196776 - 20 -0.2739836714646079 - 10 -1.448712494196777 - 20 -0.393422736594211 - 10 -1.489886882692005 - 20 -0.3784364847678352 - 10 -1.489886882692005 - 20 -0.2446678828560983 - 42 -0.9999999999999999 - 10 -1.529256961432162 - 20 -0.2446678828560981 - 10 -1.529256961432162 - 20 -0.3641069479857013 - 10 -1.570431349927391 - 20 -0.3491206961593254 - 10 -1.57043134992739 - 20 -0.2153520942475885 - 42 -0.9999999999999999 - 10 -1.609801428667548 - 20 -0.2153520942475884 - 10 -1.609801428667548 - 20 -0.3347911593771915 - 10 -1.993267320013264 - 20 -0.1952209890709761 - 42 -0.1763269807087526 - 10 -2.006732679986736 - 20 -0.1952209890709762 - 10 -2.390198571332454 - 20 -0.3347911593771915 - 10 -2.390198571332454 - 20 -0.2153520942475884 - 42 -0.9999999999999999 - 10 -2.429568650072611 - 20 -0.2153520942475885 - 10 -2.429568650072611 - 20 -0.3491206961593254 - 10 -2.470743038567839 - 20 -0.3641069479857013 - 10 -2.47074303856784 - 20 -0.2446678828560981 - 42 -0.9999999999999999 - 10 -2.510113117307997 - 20 -0.2446678828560983 - 10 -2.510113117307997 - 20 -0.3784364847678352 - 10 -2.551287505803225 - 20 -0.393422736594211 - 10 -2.551287505803225 - 20 -0.2739836714646079 - 42 -0.9999999999999999 - 10 -2.590657584543383 - 20 -0.273983671464608 - 10 -2.590657584543382 - 20 -0.407752273376345 - 10 -2.631831973038611 - 20 -0.4227385252027208 - 10 -2.631831973038611 - 20 -0.3032994600731176 - 42 -0.9999999999999999 - 10 -2.671202051778768 - 20 -0.3032994600731178 - 10 -2.671202051778768 - 20 -0.4370680619848547 - 10 -2.712376440273996 - 20 -0.4520543138112305 - 10 -2.712376440273997 - 20 -0.3326152486816274 - 42 -0.9999999999999999 - 10 -2.751746519014154 - 20 -0.3326152486816275 - 10 -2.751746519014154 - 20 -0.4663838505933645 - 10 -2.792920907509382 - 20 -0.4813701024197403 - 10 -2.792920907509383 - 20 -0.3619310372901371 - 42 -0.9999999999999999 - 10 -2.83229098624954 - 20 -0.3619310372901373 - 10 -2.832290986249539 - 20 -0.4956996392018742 - 10 -2.873465374744768 - 20 -0.5106858910282501 - 10 -2.873465374744768 - 20 -0.391246825898647 - 42 -0.9999999999999999 - 10 -2.912835453484925 - 20 -0.3912468258986471 - 10 -2.912835453484925 - 20 -0.525015427810384 - 10 -2.954009841980153 - 20 -0.5400016796367598 - 10 -2.954009841980154 - 20 -0.4205626145071567 - 42 -0.9999999999999999 - 10 -2.993379920720312 - 20 -0.4205626145071568 - 10 -2.993379920720311 - 20 -0.5543312164188938 - 10 -3.034554309215539 - 20 -0.5693174682452696 - 10 -3.034554309215539 - 20 -0.4498784031156665 - 42 -0.9999999999999999 - 10 -3.073924387955697 - 20 -0.4498784031156666 - 10 -3.073924387955697 - 20 -0.5836470050274035 - 10 -3.115098776450925 - 20 -0.5986332568537795 - 10 -3.115098776450925 - 20 -0.4791941917241762 - 42 -0.9999999999999999 - 10 -3.154468855191083 - 20 -0.4791941917241763 - 10 -3.154468855191082 - 20 -0.6129627936359132 - 10 -3.195643243686311 - 20 -0.6279490454622892 - 10 -3.195643243686311 - 20 -0.508509980332686 - 42 -0.9999999999999999 - 10 -3.235013322426469 - 20 -0.508509980332686 - 10 -3.235013322426468 - 20 -0.642278582244423 - 10 -3.276187710921696 - 20 -0.6572648340707989 - 10 -3.276187710921697 - 20 -0.5378257689411958 - 42 -0.9999999999999999 - 10 -3.315557789661854 - 20 -0.5378257689411958 - 10 -3.315557789661854 - 20 -0.6715943708529328 - 10 -3.356732178157082 - 20 -0.6865806226793086 - 10 -3.356732178157082 - 20 -0.5671415575497054 - 42 -0.9999999999999999 - 10 -3.39610225689724 - 20 -0.5671415575497056 - 10 -3.396102256897239 - 20 -0.7009101594614425 - 10 -3.437276645392468 - 20 -0.7158964112878186 - 10 -3.437276645392468 - 20 -0.5964573461582152 - 42 -0.9999999999999999 - 10 -3.476646724132626 - 20 -0.5964573461582154 - 10 -3.476646724132625 - 20 -0.7302259480699523 - 10 -3.517821112627853 - 20 -0.7452121998963283 - 10 -3.517821112627854 - 20 -0.625773134766725 - 42 -0.9999999999999999 - 10 -3.557191191368011 - 20 -0.625773134766725 - 10 -3.557191191368011 - 20 -0.759541736678462 - 10 -3.598365579863239 - 20 -0.7745279885048381 - 10 -3.598365579863239 - 20 -0.6550889233752348 - 42 -0.9999999999999999 - 10 -3.637735658603397 - 20 -0.6550889233752349 - 10 -3.637735658603396 - 20 -0.7888575252869718 - 10 -3.814899688517512 - 20 -0.853339958758357 - 42 -0.3152987888789825 - 10 -3.827852047900865 - 20 -0.8718378449942998 - 10 -3.827852047900866 - 20 -1.160309014808614 - 42 -0.2914734195860939 - 10 -3.816486265651666 - 20 -1.17814971927784 - 10 -3.302025394556464 - 20 -1.418046763290625 - 42 -0.9999999999999994 - 10 -3.285386880314704 - 20 -1.382365354352174 - 10 -3.756776480718013 - 20 -1.162552773709486 - 10 -2.0 - 20 -0.5231384264691965 - 10 -0.2432235192819858 - 20 -1.162552773709486 - 10 -0.7689601562847856 - 20 -1.407707793716547 - 42 -1.000000000000008 - 10 -0.7523216420430257 - 20 -1.443389202654997 - 10 -0.1835137343483321 - 20 -1.178149719277839 - 42 -0.2914734195860883 - 10 -0.1721479520991333 - 20 -1.160309014808614 - 0 -LWPOLYLINE - 5 -19B6 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -2.702722336176931 - 20 -0.5729245843773911 - 10 -2.812605946879461 - 20 -0.5094832521587582 - 10 -2.812605946879462 - 20 -0.3619310372901372 - 0 -LWPOLYLINE - 5 -19B7 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -2.622177868941545 - 20 -0.5436087957688814 - 10 -2.732061479644075 - 20 -0.4801674635502485 - 10 -2.732061479644075 - 20 -0.3326152486816275 - 0 -LWPOLYLINE - 5 -19B8 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -2.54163340170616 - 20 -0.5142930071603717 - 10 -2.651517012408689 - 20 -0.4508516749417388 - 10 -2.65151701240869 - 20 -0.3032994600731177 - 0 -LWPOLYLINE - 5 -19B9 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -2.863811270647703 - 20 -0.6315561615944107 - 10 -2.973694881350232 - 20 -0.5681148293757778 - 10 -2.973694881350233 - 20 -0.4205626145071568 - 0 -LWPOLYLINE - 5 -19BA -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -2.783266803412317 - 20 -0.6022403729859009 - 10 -2.893150414114847 - 20 -0.538799040767268 - 10 -2.893150414114847 - 20 -0.391246825898647 - 0 -LWPOLYLINE - 5 -19BB -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -3.10544467235386 - 20 -0.71950352741994 - 10 -3.215328283056389 - 20 -0.656062195201307 - 10 -3.21532828305639 - 20 -0.508509980332686 - 0 -LWPOLYLINE - 5 -19BC -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -2.944355737883088 - 20 -0.6608719502029206 - 10 -3.054239348585618 - 20 -0.5974306179842876 - 10 -3.054239348585618 - 20 -0.4498784031156665 - 0 -LWPOLYLINE - 5 -19BD -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -3.024900205118474 - 20 -0.6901877388114303 - 10 -3.134783815821004 - 20 -0.6267464065927973 - 10 -3.134783815821004 - 20 -0.4791941917241763 - 0 -LWPOLYLINE - 5 -19BE -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -3.508167008530788 - 20 -0.8660824704624889 - 10 -3.618050619233318 - 20 -0.802641138243856 - 10 -3.618050619233318 - 20 -0.6550889233752348 - 0 -LWPOLYLINE - 5 -19BF -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -3.185989139589245 - 20 -0.7488193160284498 - 10 -3.295872750291775 - 20 -0.6853779838098168 - 10 -3.295872750291776 - 20 -0.5378257689411958 - 0 -LWPOLYLINE - 5 -19C0 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -3.266533606824631 - 20 -0.7781351046369596 - 10 -3.376417217527161 - 20 -0.7146937724183267 - 10 -3.376417217527161 - 20 -0.5671415575497055 - 0 -LWPOLYLINE - 5 -19C1 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -3.347078074060017 - 20 -0.8074508932454694 - 10 -3.456961684762546 - 20 -0.7440095610268365 - 10 -3.456961684762547 - 20 -0.5964573461582153 - 0 -LWPOLYLINE - 5 -19C2 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 3 - 70 - 0 - 43 -0.0 - 10 -3.427622541295403 - 20 -0.836766681853979 - 10 -3.537506151997932 - 20 -0.773325349635346 - 10 -3.537506151997933 - 20 -0.625773134766725 - 0 -LWPOLYLINE - 5 -1A86 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 5 - 70 - 0 - 43 -0.0 - 10 -3.808167008530787 - 20 -1.160309014808614 - 10 -3.808167008530789 - 20 -0.8718378449943008 - 10 -2.000000000000001 - 20 -0.2137188753069324 - 10 -0.1918329914692131 - 20 -0.8718378449943008 - 10 -0.1918329914692121 - 20 -1.160309014808614 - 0 -LWPOLYLINE - 5 -1A88 -330 -1F -100 -AcDbEntity - 8 -CENTERLINE -100 -AcDbPolyline - 90 - 5 - 70 - 0 - 43 -0.0 - 10 -0.7606408991639058 - 20 -1.425548498185772 - 10 -0.1918329914692121 - 20 -1.160309014808614 - 10 -1.999999999999999 - 20 -0.5021900451212454 - 10 -3.808167008530787 - 20 -1.160309014808614 - 10 -3.293706137435584 - 20 -1.4002060588214 - 0 -HATCH - 5 -1B2B -330 -1F -100 -AcDbEntity - 8 -HATCH-BLACK -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 3 - 92 - 1 - 93 - 145 - 72 - 2 - 10 -0.1918329914692131 - 20 -0.871837844994301 - 40 -0.0196850393700787 - 50 -180.0000000000002 - 51 -250.0 - 73 - 1 - 72 - 1 - 10 -0.1851003114824874 - 20 -0.8533399587583579 - 11 -0.3622643413966053 - 21 -0.7888575252869718 - 72 - 1 - 10 -0.3622643413966053 - 20 -0.7888575252869718 - 11 -0.3622643413966049 - 21 -0.6550889233752349 - 72 - 2 - 10 -0.3819493807666836 - 20 -0.6550889233752349 - 40 -0.0196850393700787 - 50 -179.9999999999998 - 51 -359.9999999999998 - 73 - 1 - 72 - 1 - 10 -0.4016344201367623 - 20 -0.6550889233752348 - 11 -0.4016344201367628 - 21 -0.7745279885048381 - 72 - 1 - 10 -0.4016344201367628 - 20 -0.7745279885048381 - 11 -0.442808808631991 - 21 -0.759541736678462 - 72 - 1 - 10 -0.442808808631991 - 20 -0.759541736678462 - 11 -0.4428088086319906 - 21 -0.625773134766725 - 72 - 2 - 10 -0.4624938480020693 - 20 -0.625773134766725 - 40 -0.0196850393700787 - 50 -180.0 - 51 -360.0 - 73 - 1 - 72 - 1 - 10 -0.482178887372148 - 20 -0.625773134766725 - 11 -0.4821788873721484 - 21 -0.7452121998963283 - 72 - 1 - 10 -0.4821788873721484 - 20 -0.7452121998963283 - 11 -0.5233532758673767 - 21 -0.7302259480699523 - 72 - 1 - 10 -0.5233532758673767 - 20 -0.7302259480699523 - 11 -0.5233532758673762 - 21 -0.5964573461582154 - 72 - 2 - 10 -0.5430383152374549 - 20 -0.5964573461582153 - 40 -0.0196850393700787 - 50 -179.9999999999997 - 51 -359.9999999999997 - 73 - 1 - 72 - 1 - 10 -0.5627233546075336 - 20 -0.5964573461582152 - 11 -0.5627233546075341 - 21 -0.7158964112878186 - 72 - 1 - 10 -0.5627233546075341 - 20 -0.7158964112878186 - 11 -0.6038977431027625 - 21 -0.7009101594614425 - 72 - 1 - 10 -0.6038977431027625 - 20 -0.7009101594614425 - 11 -0.603897743102762 - 21 -0.5671415575497056 - 72 - 2 - 10 -0.6235827824728407 - 20 -0.5671415575497055 - 40 -0.0196850393700787 - 50 -179.9999999999997 - 51 -359.9999999999997 - 73 - 1 - 72 - 1 - 10 -0.6432678218429194 - 20 -0.5671415575497054 - 11 -0.6432678218429199 - 21 -0.6865806226793086 - 72 - 1 - 10 -0.6432678218429199 - 20 -0.6865806226793086 - 11 -0.6844422103381481 - 21 -0.6715943708529328 - 72 - 1 - 10 -0.6844422103381481 - 20 -0.6715943708529328 - 11 -0.6844422103381477 - 21 -0.5378257689411958 - 72 - 2 - 10 -0.7041272497082264 - 20 -0.5378257689411958 - 40 -0.0196850393700787 - 50 -180.0 - 51 -360.0 - 73 - 1 - 72 - 1 - 10 -0.7238122890783051 - 20 -0.5378257689411958 - 11 -0.7238122890783055 - 21 -0.6572648340707989 - 72 - 1 - 10 -0.7238122890783055 - 20 -0.6572648340707989 - 11 -0.7649866775735338 - 21 -0.642278582244423 - 72 - 1 - 10 -0.7649866775735338 - 20 -0.642278582244423 - 11 -0.7649866775735333 - 21 -0.508509980332686 - 72 - 2 - 10 -0.784671716943612 - 20 -0.508509980332686 - 40 -0.0196850393700787 - 50 -180.0 - 51 -360.0 - 73 - 1 - 72 - 1 - 10 -0.8043567563136907 - 20 -0.508509980332686 - 11 -0.8043567563136912 - 21 -0.6279490454622892 - 72 - 1 - 10 -0.8043567563136912 - 20 -0.6279490454622892 - 11 -0.8455311448089194 - 21 -0.6129627936359132 - 72 - 1 - 10 -0.8455311448089194 - 20 -0.6129627936359132 - 11 -0.845531144808919 - 21 -0.4791941917241763 - 72 - 2 - 10 -0.8652161841789977 - 20 -0.4791941917241763 - 40 -0.0196850393700787 - 50 -179.9999999999998 - 51 -359.9999999999998 - 73 - 1 - 72 - 1 - 10 -0.8849012235490764 - 20 -0.4791941917241762 - 11 -0.8849012235490769 - 21 -0.5986332568537795 - 72 - 1 - 10 -0.8849012235490769 - 20 -0.5986332568537795 - 11 -0.9260756120443052 - 21 -0.5836470050274035 - 72 - 1 - 10 -0.9260756120443052 - 20 -0.5836470050274035 - 11 -0.9260756120443048 - 21 -0.4498784031156666 - 72 - 2 - 10 -0.9457606514143835 - 20 -0.4498784031156665 - 40 -0.0196850393700787 - 50 -179.9999999999998 - 51 -359.9999999999998 - 73 - 1 - 72 - 1 - 10 -0.9654456907844622 - 20 -0.4498784031156665 - 11 -0.9654456907844626 - 21 -0.5693174682452696 - 72 - 1 - 10 -0.9654456907844626 - 20 -0.5693174682452696 - 11 -1.006620079279691 - 21 -0.5543312164188938 - 72 - 1 - 10 -1.006620079279691 - 20 -0.5543312164188938 - 11 -1.00662007927969 - 21 -0.4205626145071568 - 72 - 2 - 10 -1.026305118649769 - 20 -0.4205626145071568 - 40 -0.0196850393700787 - 50 -179.9999999999998 - 51 -359.9999999999998 - 73 - 1 - 72 - 1 - 10 -1.045990158019848 - 20 -0.4205626145071567 - 11 -1.045990158019848 - 21 -0.5400016796367598 - 72 - 1 - 10 -1.045990158019848 - 20 -0.5400016796367598 - 11 -1.087164546515077 - 21 -0.525015427810384 - 72 - 1 - 10 -1.087164546515077 - 20 -0.525015427810384 - 11 -1.087164546515076 - 21 -0.3912468258986471 - 72 - 2 - 10 -1.106849585885155 - 20 -0.391246825898647 - 40 -0.0196850393700787 - 50 -179.9999999999998 - 51 -359.9999999999998 - 73 - 1 - 72 - 1 - 10 -1.126534625255234 - 20 -0.391246825898647 - 11 -1.126534625255234 - 21 -0.5106858910282501 - 72 - 1 - 10 -1.126534625255234 - 20 -0.5106858910282501 - 11 -1.167709013750462 - 21 -0.4956996392018742 - 72 - 1 - 10 -1.167709013750462 - 20 -0.4956996392018742 - 11 -1.167709013750462 - 21 -0.3619310372901373 - 72 - 2 - 10 -1.18739405312054 - 20 -0.3619310372901372 - 40 -0.0196850393700787 - 50 -179.9999999999998 - 51 -359.9999999999998 - 73 - 1 - 72 - 1 - 10 -1.207079092490619 - 20 -0.3619310372901371 - 11 -1.20707909249062 - 21 -0.4813701024197403 - 72 - 1 - 10 -1.20707909249062 - 20 -0.4813701024197403 - 11 -1.248253480985848 - 21 -0.4663838505933645 - 72 - 1 - 10 -1.248253480985848 - 20 -0.4663838505933645 - 11 -1.248253480985848 - 21 -0.3326152486816275 - 72 - 2 - 10 -1.267938520355926 - 20 -0.3326152486816275 - 40 -0.0196850393700787 - 50 -179.9999999999998 - 51 -359.9999999999998 - 73 - 1 - 72 - 1 - 10 -1.287623559726005 - 20 -0.3326152486816274 - 11 -1.287623559726006 - 21 -0.4520543138112305 - 72 - 1 - 10 -1.287623559726006 - 20 -0.4520543138112305 - 11 -1.328797948221234 - 21 -0.4370680619848547 - 72 - 1 - 10 -1.328797948221234 - 20 -0.4370680619848547 - 11 -1.328797948221233 - 21 -0.3032994600731178 - 72 - 2 - 10 -1.348482987591312 - 20 -0.3032994600731177 - 40 -0.0196850393700787 - 50 -179.9999999999998 - 51 -359.9999999999998 - 73 - 1 - 72 - 1 - 10 -1.368168026961391 - 20 -0.3032994600731176 - 11 -1.368168026961391 - 21 -0.4227385252027208 - 72 - 1 - 10 -1.368168026961391 - 20 -0.4227385252027208 - 11 -1.409342415456619 - 21 -0.407752273376345 - 72 - 1 - 10 -1.409342415456619 - 20 -0.407752273376345 - 11 -1.409342415456619 - 21 -0.273983671464608 - 72 - 2 - 10 -1.429027454826698 - 20 -0.2739836714646079 - 40 -0.0196850393700787 - 50 -179.9999999999998 - 51 -359.9999999999998 - 73 - 1 - 72 - 1 - 10 -1.448712494196776 - 20 -0.2739836714646079 - 11 -1.448712494196777 - 21 -0.393422736594211 - 72 - 1 - 10 -1.448712494196777 - 20 -0.393422736594211 - 11 -1.489886882692005 - 21 -0.3784364847678352 - 72 - 1 - 10 -1.489886882692005 - 20 -0.3784364847678352 - 11 -1.489886882692005 - 21 -0.2446678828560983 - 72 - 2 - 10 -1.509571922062083 - 20 -0.2446678828560982 - 40 -0.0196850393700787 - 50 -179.9999999999998 - 51 -359.9999999999998 - 73 - 1 - 72 - 1 - 10 -1.529256961432162 - 20 -0.2446678828560981 - 11 -1.529256961432162 - 21 -0.3641069479857013 - 72 - 1 - 10 -1.529256961432162 - 20 -0.3641069479857013 - 11 -1.570431349927391 - 21 -0.3491206961593254 - 72 - 1 - 10 -1.570431349927391 - 20 -0.3491206961593254 - 11 -1.57043134992739 - 21 -0.2153520942475885 - 72 - 2 - 10 -1.590116389297469 - 20 -0.2153520942475884 - 40 -0.0196850393700787 - 50 -179.9999999999998 - 51 -359.9999999999998 - 73 - 1 - 72 - 1 - 10 -1.609801428667548 - 20 -0.2153520942475884 - 11 -1.609801428667548 - 21 -0.3347911593771915 - 72 - 1 - 10 -1.609801428667548 - 20 -0.3347911593771915 - 11 -1.993267320013264 - 21 -0.1952209890709761 - 72 - 2 - 10 -2.0 - 20 -0.2137188753069149 - 40 -0.0196850393700781 - 50 -249.9999999999685 - 51 -290.0000000000325 - 73 - 1 - 72 - 1 - 10 -2.006732679986736 - 20 -0.1952209890709762 - 11 -2.390198571332454 - 21 -0.3347911593771915 - 72 - 1 - 10 -2.390198571332454 - 20 -0.3347911593771915 - 11 -2.390198571332454 - 21 -0.2153520942475884 - 72 - 2 - 10 -2.409883610702533 - 20 -0.2153520942475884 - 40 -0.0196850393700787 - 50 -180.0000000000002 - 51 -360.0000000000002 - 73 - 1 - 72 - 1 - 10 -2.429568650072611 - 20 -0.2153520942475885 - 11 -2.429568650072611 - 21 -0.3491206961593254 - 72 - 1 - 10 -2.429568650072611 - 20 -0.3491206961593254 - 11 -2.470743038567839 - 21 -0.3641069479857013 - 72 - 1 - 10 -2.470743038567839 - 20 -0.3641069479857013 - 11 -2.47074303856784 - 21 -0.2446678828560981 - 72 - 2 - 10 -2.490428077937918 - 20 -0.2446678828560982 - 40 -0.0196850393700787 - 50 -180.0000000000002 - 51 -360.0000000000002 - 73 - 1 - 72 - 1 - 10 -2.510113117307997 - 20 -0.2446678828560983 - 11 -2.510113117307997 - 21 -0.3784364847678352 - 72 - 1 - 10 -2.510113117307997 - 20 -0.3784364847678352 - 11 -2.551287505803225 - 21 -0.393422736594211 - 72 - 1 - 10 -2.551287505803225 - 20 -0.393422736594211 - 11 -2.551287505803225 - 21 -0.2739836714646079 - 72 - 2 - 10 -2.570972545173304 - 20 -0.2739836714646079 - 40 -0.0196850393700787 - 50 -180.0000000000002 - 51 -360.0000000000002 - 73 - 1 - 72 - 1 - 10 -2.590657584543383 - 20 -0.273983671464608 - 11 -2.590657584543382 - 21 -0.407752273376345 - 72 - 1 - 10 -2.590657584543382 - 20 -0.407752273376345 - 11 -2.631831973038611 - 21 -0.4227385252027208 - 72 - 1 - 10 -2.631831973038611 - 20 -0.4227385252027208 - 11 -2.631831973038611 - 21 -0.3032994600731176 - 72 - 2 - 10 -2.65151701240869 - 20 -0.3032994600731177 - 40 -0.0196850393700787 - 50 -180.0000000000002 - 51 -360.0000000000002 - 73 - 1 - 72 - 1 - 10 -2.671202051778768 - 20 -0.3032994600731178 - 11 -2.671202051778768 - 21 -0.4370680619848547 - 72 - 1 - 10 -2.671202051778768 - 20 -0.4370680619848547 - 11 -2.712376440273996 - 21 -0.4520543138112305 - 72 - 1 - 10 -2.712376440273996 - 20 -0.4520543138112305 - 11 -2.712376440273997 - 21 -0.3326152486816274 - 72 - 2 - 10 -2.732061479644075 - 20 -0.3326152486816275 - 40 -0.0196850393700787 - 50 -180.0000000000002 - 51 -360.0000000000002 - 73 - 1 - 72 - 1 - 10 -2.751746519014154 - 20 -0.3326152486816275 - 11 -2.751746519014154 - 21 -0.4663838505933645 - 72 - 1 - 10 -2.751746519014154 - 20 -0.4663838505933645 - 11 -2.792920907509382 - 21 -0.4813701024197403 - 72 - 1 - 10 -2.792920907509382 - 20 -0.4813701024197403 - 11 -2.792920907509383 - 21 -0.3619310372901371 - 72 - 2 - 10 -2.812605946879462 - 20 -0.3619310372901372 - 40 -0.0196850393700787 - 50 -180.0000000000002 - 51 -360.0000000000002 - 73 - 1 - 72 - 1 - 10 -2.83229098624954 - 20 -0.3619310372901373 - 11 -2.832290986249539 - 21 -0.4956996392018742 - 72 - 1 - 10 -2.832290986249539 - 20 -0.4956996392018742 - 11 -2.873465374744768 - 21 -0.5106858910282501 - 72 - 1 - 10 -2.873465374744768 - 20 -0.5106858910282501 - 11 -2.873465374744768 - 21 -0.391246825898647 - 72 - 2 - 10 -2.893150414114847 - 20 -0.391246825898647 - 40 -0.0196850393700787 - 50 -180.0000000000002 - 51 -360.0000000000002 - 73 - 1 - 72 - 1 - 10 -2.912835453484925 - 20 -0.3912468258986471 - 11 -2.912835453484925 - 21 -0.525015427810384 - 72 - 1 - 10 -2.912835453484925 - 20 -0.525015427810384 - 11 -2.954009841980153 - 21 -0.5400016796367598 - 72 - 1 - 10 -2.954009841980153 - 20 -0.5400016796367598 - 11 -2.954009841980154 - 21 -0.4205626145071567 - 72 - 2 - 10 -2.973694881350233 - 20 -0.4205626145071568 - 40 -0.0196850393700787 - 50 -180.0000000000002 - 51 -360.0000000000002 - 73 - 1 - 72 - 1 - 10 -2.993379920720312 - 20 -0.4205626145071568 - 11 -2.993379920720311 - 21 -0.5543312164188938 - 72 - 1 - 10 -2.993379920720311 - 20 -0.5543312164188938 - 11 -3.034554309215539 - 21 -0.5693174682452696 - 72 - 1 - 10 -3.034554309215539 - 20 -0.5693174682452696 - 11 -3.034554309215539 - 21 -0.4498784031156665 - 72 - 2 - 10 -3.054239348585618 - 20 -0.4498784031156665 - 40 -0.0196850393700787 - 50 -180.0000000000002 - 51 -360.0000000000002 - 73 - 1 - 72 - 1 - 10 -3.073924387955697 - 20 -0.4498784031156666 - 11 -3.073924387955697 - 21 -0.5836470050274035 - 72 - 1 - 10 -3.073924387955697 - 20 -0.5836470050274035 - 11 -3.115098776450925 - 21 -0.5986332568537795 - 72 - 1 - 10 -3.115098776450925 - 20 -0.5986332568537795 - 11 -3.115098776450925 - 21 -0.4791941917241762 - 72 - 2 - 10 -3.134783815821004 - 20 -0.4791941917241763 - 40 -0.0196850393700787 - 50 -180.0000000000002 - 51 -360.0000000000002 - 73 - 1 - 72 - 1 - 10 -3.154468855191083 - 20 -0.4791941917241763 - 11 -3.154468855191082 - 21 -0.6129627936359132 - 72 - 1 - 10 -3.154468855191082 - 20 -0.6129627936359132 - 11 -3.195643243686311 - 21 -0.6279490454622892 - 72 - 1 - 10 -3.195643243686311 - 20 -0.6279490454622892 - 11 -3.195643243686311 - 21 -0.508509980332686 - 72 - 2 - 10 -3.21532828305639 - 20 -0.508509980332686 - 40 -0.0196850393700787 - 50 -180.0 - 51 -360.0 - 73 - 1 - 72 - 1 - 10 -3.235013322426469 - 20 -0.508509980332686 - 11 -3.235013322426468 - 21 -0.642278582244423 - 72 - 1 - 10 -3.235013322426468 - 20 -0.642278582244423 - 11 -3.276187710921696 - 21 -0.6572648340707989 - 72 - 1 - 10 -3.276187710921696 - 20 -0.6572648340707989 - 11 -3.276187710921697 - 21 -0.5378257689411958 - 72 - 2 - 10 -3.295872750291776 - 20 -0.5378257689411958 - 40 -0.0196850393700787 - 50 -180.0 - 51 -360.0 - 73 - 1 - 72 - 1 - 10 -3.315557789661854 - 20 -0.5378257689411958 - 11 -3.315557789661854 - 21 -0.6715943708529328 - 72 - 1 - 10 -3.315557789661854 - 20 -0.6715943708529328 - 11 -3.356732178157082 - 21 -0.6865806226793086 - 72 - 1 - 10 -3.356732178157082 - 20 -0.6865806226793086 - 11 -3.356732178157082 - 21 -0.5671415575497054 - 72 - 2 - 10 -3.376417217527161 - 20 -0.5671415575497055 - 40 -0.0196850393700787 - 50 -180.0000000000003 - 51 -360.0000000000003 - 73 - 1 - 72 - 1 - 10 -3.39610225689724 - 20 -0.5671415575497056 - 11 -3.396102256897239 - 21 -0.7009101594614425 - 72 - 1 - 10 -3.396102256897239 - 20 -0.7009101594614425 - 11 -3.437276645392468 - 21 -0.7158964112878186 - 72 - 1 - 10 -3.437276645392468 - 20 -0.7158964112878186 - 11 -3.437276645392468 - 21 -0.5964573461582152 - 72 - 2 - 10 -3.456961684762547 - 20 -0.5964573461582153 - 40 -0.0196850393700787 - 50 -180.0000000000003 - 51 -360.0000000000003 - 73 - 1 - 72 - 1 - 10 -3.476646724132626 - 20 -0.5964573461582154 - 11 -3.476646724132625 - 21 -0.7302259480699523 - 72 - 1 - 10 -3.476646724132625 - 20 -0.7302259480699523 - 11 -3.517821112627853 - 21 -0.7452121998963283 - 72 - 1 - 10 -3.517821112627853 - 20 -0.7452121998963283 - 11 -3.517821112627854 - 21 -0.625773134766725 - 72 - 2 - 10 -3.537506151997933 - 20 -0.625773134766725 - 40 -0.0196850393700787 - 50 -180.0 - 51 -360.0 - 73 - 1 - 72 - 1 - 10 -3.557191191368011 - 20 -0.625773134766725 - 11 -3.557191191368011 - 21 -0.759541736678462 - 72 - 1 - 10 -3.557191191368011 - 20 -0.759541736678462 - 11 -3.598365579863239 - 21 -0.7745279885048381 - 72 - 1 - 10 -3.598365579863239 - 20 -0.7745279885048381 - 11 -3.598365579863239 - 21 -0.6550889233752348 - 72 - 2 - 10 -3.618050619233318 - 20 -0.6550889233752349 - 40 -0.0196850393700787 - 50 -180.0000000000002 - 51 -360.0000000000002 - 73 - 1 - 72 - 1 - 10 -3.637735658603397 - 20 -0.6550889233752349 - 11 -3.637735658603396 - 21 -0.7888575252869718 - 72 - 1 - 10 -3.637735658603396 - 20 -0.7888575252869718 - 11 -3.814899688517512 - 21 -0.853339958758357 - 72 - 2 - 10 -3.808167008530786 - 20 -0.8718378449942998 - 40 -0.0196850393700785 - 50 -290.0000000000003 - 51 -360.0000000000001 - 73 - 1 - 72 - 1 - 10 -3.827852047900865 - 20 -0.8718378449942998 - 11 -3.827852047900866 - 21 -1.160309014808614 - 72 - 2 - 10 -3.808167008530787 - 20 -1.160309014808614 - 40 -0.0196850393700788 - 50 -359.9999999999999 - 51 -425.0000000000013 - 73 - 1 - 72 - 1 - 10 -3.816486265651666 - 20 -1.17814971927784 - 11 -3.302025394556464 - 21 -1.418046763290625 - 72 - 2 - 10 -3.293706137435584 - 20 -1.4002060588214 - 40 -0.0196850393700788 - 50 -65.00000000000018 - 51 -245.0000000000001 - 73 - 1 - 72 - 1 - 10 -3.285386880314704 - 20 -1.382365354352174 - 11 -3.756776480718013 - 21 -1.162552773709486 - 72 - 1 - 10 -3.756776480718013 - 20 -1.162552773709486 - 11 -2.0 - 21 -0.5231384264691965 - 72 - 1 - 10 -2.0 - 20 -0.5231384264691965 - 11 -0.2432235192819858 - 21 -1.162552773709486 - 72 - 1 - 10 -0.2432235192819858 - 20 -1.162552773709486 - 11 -0.7689601562847856 - 21 -1.407707793716547 - 72 - 2 - 10 -0.7606408991639058 - 20 -1.425548498185772 - 40 -0.0196850393700788 - 50 -294.9999999999998 - 51 -475.0000000000007 - 73 - 1 - 72 - 1 - 10 -0.7523216420430257 - 20 -1.443389202654997 - 11 -0.1835137343483322 - 21 -1.178149719277839 - 72 - 2 - 10 -0.1918329914692121 - 20 -1.160309014808614 - 40 -0.0196850393700788 - 50 -115.0000000000001 - 51 -180.0000000000002 - 73 - 1 - 72 - 1 - 10 -0.1721479520991333 - 20 -1.160309014808614 - 11 -0.1721479520991344 - 21 -0.8718378449943008 - 97 - 1 -330 -19B5 - 92 - 16 - 93 - 68 - 72 - 1 - 10 -3.788481969160711 - 20 -1.132195865069596 - 11 -3.78848196916071 - 21 -0.8856214579511849 - 72 - 1 - 10 -3.78848196916071 - 20 -0.8856214579511849 - 11 -3.619943645258092 - 21 -0.8242785247175163 - 72 - 1 - 10 -3.619943645258092 - 20 -0.8242785247175163 - 11 -3.518009528215828 - 21 -0.8831302146314739 - 72 - 2 - 10 -3.508167008530788 - 20 -0.8660824704624889 - 40 -0.0196850393700787 - 50 -60.00000000000008 - 51 -240.0000000000001 - 73 - 1 - 72 - 1 - 10 -3.498324488845749 - 20 -0.8490347262935038 - 11 -3.571649094198813 - 21 -0.8067007456546893 - 72 - 1 - 10 -3.571649094198813 - 20 -0.8067007456546893 - 11 -3.539399178022706 - 21 -0.7949627361090064 - 72 - 1 - 10 -3.539399178022706 - 20 -0.7949627361090064 - 11 -3.437465060980442 - 21 -0.8538144260229641 - 72 - 2 - 10 -3.427622541295402 - 20 -0.836766681853979 - 40 -0.0196850393700788 - 50 -60.00000000000015 - 51 -240.0000000000001 - 73 - 1 - 72 - 1 - 10 -3.417780021610363 - 20 -0.8197189376849939 - 11 -3.491104626963428 - 21 -0.7773849570461795 - 72 - 1 - 10 -3.491104626963428 - 20 -0.7773849570461795 - 11 -3.458854710787321 - 21 -0.7656469475004968 - 72 - 1 - 10 -3.458854710787321 - 20 -0.7656469475004968 - 11 -3.356920593745056 - 21 -0.8244986374144544 - 72 - 2 - 10 -3.347078074060017 - 20 -0.8074508932454694 - 40 -0.0196850393700788 - 50 -60.00000000000015 - 51 -240.0000000000001 - 73 - 1 - 72 - 1 - 10 -3.337235554374978 - 20 -0.7904031490764842 - 11 -3.410560159728042 - 21 -0.7480691684376697 - 72 - 1 - 10 -3.410560159728042 - 20 -0.7480691684376697 - 11 -3.378310243551935 - 21 -0.736331158891987 - 72 - 1 - 10 -3.378310243551935 - 20 -0.736331158891987 - 11 -3.27637612650967 - 21 -0.7951828488059446 - 72 - 2 - 10 -3.266533606824631 - 20 -0.7781351046369596 - 40 -0.0196850393700788 - 50 -60.00000000000015 - 51 -240.0000000000001 - 73 - 1 - 72 - 1 - 10 -3.256691087139592 - 20 -0.7610873604679744 - 11 -3.330015692492656 - 21 -0.7187533798291599 - 72 - 1 - 10 -3.330015692492656 - 20 -0.7187533798291599 - 11 -3.297765776316549 - 21 -0.7070153702834772 - 72 - 1 - 10 -3.297765776316549 - 20 -0.7070153702834772 - 11 -3.195831659274285 - 21 -0.7658670601974349 - 72 - 2 - 10 -3.185989139589245 - 20 -0.7488193160284498 - 40 -0.0196850393700788 - 50 -60.00000000000015 - 51 -240.0000000000001 - 73 - 1 - 72 - 1 - 10 -3.176146619904206 - 20 -0.7317715718594647 - 11 -3.24947122525727 - 21 -0.6894375912206502 - 72 - 1 - 10 -3.24947122525727 - 20 -0.6894375912206502 - 11 -3.217221309081164 - 21 -0.6776995816749674 - 72 - 1 - 10 -3.217221309081164 - 20 -0.6776995816749674 - 11 -3.115287192038899 - 21 -0.7365512715889251 - 72 - 2 - 10 -3.10544467235386 - 20 -0.71950352741994 - 40 -0.0196850393700788 - 50 -60.00000000000015 - 51 -240.0000000000001 - 73 - 1 - 72 - 1 - 10 -3.09560215266882 - 20 -0.7024557832509549 - 11 -3.168926758021885 - 21 -0.6601218026121404 - 72 - 1 - 10 -3.168926758021885 - 20 -0.6601218026121404 - 11 -3.136676841845778 - 21 -0.6483837930664577 - 72 - 1 - 10 -3.136676841845778 - 20 -0.6483837930664577 - 11 -3.034742724803513 - 21 -0.7072354829804153 - 72 - 2 - 10 -3.024900205118474 - 20 -0.6901877388114303 - 40 -0.0196850393700787 - 50 -60.00000000000008 - 51 -240.0000000000001 - 73 - 1 - 72 - 1 - 10 -3.015057685433435 - 20 -0.6731399946424452 - 11 -3.0883822907865 - 21 -0.6308060140036307 - 72 - 1 - 10 -3.0883822907865 - 20 -0.6308060140036307 - 11 -3.056132374610392 - 21 -0.619068004457948 - 72 - 1 - 10 -3.056132374610392 - 20 -0.619068004457948 - 11 -2.954198257568128 - 21 -0.6779196943719056 - 72 - 2 - 10 -2.944355737883088 - 20 -0.6608719502029206 - 40 -0.0196850393700788 - 50 -60.00000000000015 - 51 -240.0000000000001 - 73 - 1 - 72 - 1 - 10 -2.934513218198049 - 20 -0.6438242060339354 - 11 -3.007837823551114 - 21 -0.6014902253951211 - 72 - 1 - 10 -3.007837823551114 - 20 -0.6014902253951211 - 11 -2.975587907375006 - 21 -0.5897522158494382 - 72 - 1 - 10 -2.975587907375006 - 20 -0.5897522158494382 - 11 -2.873653790332742 - 21 -0.6486039057633959 - 72 - 2 - 10 -2.863811270647703 - 20 -0.6315561615944107 - 40 -0.0196850393700788 - 50 -60.00000000000023 - 51 -240.0000000000002 - 73 - 1 - 72 - 1 - 10 -2.853968750962663 - 20 -0.6145084174254256 - 11 -2.927293356315728 - 21 -0.5721744367866111 - 72 - 1 - 10 -2.927293356315728 - 20 -0.5721744367866111 - 11 -2.895043440139621 - 21 -0.5604364272409283 - 72 - 1 - 10 -2.895043440139621 - 20 -0.5604364272409283 - 11 -2.793109323097356 - 21 -0.6192881171548861 - 72 - 2 - 10 -2.783266803412317 - 20 -0.6022403729859009 - 40 -0.0196850393700788 - 50 -60.00000000000015 - 51 -240.0000000000001 - 73 - 1 - 72 - 1 - 10 -2.773424283727278 - 20 -0.5851926288169159 - 11 -2.846748889080342 - 21 -0.5428586481781015 - 72 - 1 - 10 -2.846748889080342 - 20 -0.5428586481781015 - 11 -2.814498972904235 - 21 -0.5311206386324185 - 72 - 1 - 10 -2.814498972904235 - 20 -0.5311206386324185 - 11 -2.712564855861971 - 21 -0.5899723285463763 - 72 - 2 - 10 -2.702722336176931 - 20 -0.5729245843773911 - 40 -0.0196850393700788 - 50 -60.00000000000015 - 51 -240.0000000000001 - 73 - 1 - 72 - 1 - 10 -2.692879816491892 - 20 -0.5558768402084061 - 11 -2.766204421844956 - 21 -0.5135428595695918 - 72 - 1 - 10 -2.766204421844956 - 20 -0.5135428595695918 - 11 -2.733954505668849 - 21 -0.5018048500239088 - 72 - 1 - 10 -2.733954505668849 - 20 -0.5018048500239088 - 11 -2.632020388626585 - 21 -0.5606565399378665 - 72 - 2 - 10 -2.622177868941546 - 20 -0.5436087957688814 - 40 -0.0196850393700787 - 50 -60.00000000000008 - 51 -240.0000000000001 - 73 - 1 - 72 - 1 - 10 -2.612335349256506 - 20 -0.5265610515998964 - 11 -2.68565995460957 - 21 -0.4842270709610819 - 72 - 1 - 10 -2.68565995460957 - 20 -0.4842270709610819 - 11 -2.653410038433464 - 21 -0.4724890614153991 - 72 - 1 - 10 -2.653410038433464 - 20 -0.4724890614153991 - 11 -2.551475921391199 - 21 -0.5313407513293568 - 72 - 2 - 10 -2.541633401706159 - 20 -0.5142930071603717 - 40 -0.0196850393700788 - 50 -60.00000000000015 - 51 -240.0000000000001 - 73 - 1 - 72 - 1 - 10 -2.53179088202112 - 20 -0.4972452629913866 - 11 -2.605115487374185 - 21 -0.4549112823525721 - 72 - 1 - 10 -2.605115487374185 - 20 -0.4549112823525721 - 11 -2.572865571198078 - 21 -0.4431732728068893 - 72 - 1 - 10 -2.572865571198078 - 20 -0.4431732728068893 - 11 -2.470931454155814 - 21 -0.5020249627208471 - 72 - 2 - 10 -2.461088934470774 - 20 -0.4849772185518619 - 40 -0.0196850393700788 - 50 -60.00000000000018 - 51 -240.0000000000002 - 73 - 1 - 72 - 1 - 10 -2.451246414785735 - 20 -0.4679294743828769 - 11 -2.524571020138799 - 21 -0.4255954937440624 - 72 - 1 - 10 -2.524571020138799 - 20 -0.4255954937440624 - 11 -2.492321103962692 - 21 -0.4138574841983796 - 72 - 1 - 10 -2.492321103962692 - 20 -0.4138574841983796 - 11 -2.390386986920428 - 21 -0.4727091741123373 - 72 - 2 - 10 -2.380544467235388 - 20 -0.4556614299433522 - 40 -0.0196850393700788 - 50 -60.00000000000015 - 51 -240.0000000000001 - 73 - 1 - 72 - 1 - 10 -2.370701947550349 - 20 -0.4386136857743671 - 11 -2.444026552903414 - 21 -0.3962797051355528 - 72 - 1 - 10 -2.444026552903414 - 20 -0.3962797051355528 - 11 -2.411776636727307 - 21 -0.3845416955898698 - 72 - 1 - 10 -2.411776636727307 - 20 -0.3845416955898698 - 11 -2.309842519685042 - 21 -0.4433933855038275 - 72 - 2 - 10 -2.300000000000003 - 20 -0.4263456413348424 - 40 -0.0196850393700788 - 50 -60.00000000000015 - 51 -240.0000000000001 - 73 - 1 - 72 - 1 - 10 -2.290157480314964 - 20 -0.4092978971658573 - 11 -2.363482085668028 - 21 -0.366963916527043 - 72 - 1 - 10 -2.363482085668028 - 20 -0.366963916527043 - 11 -2.01968503937008 - 21 -0.2418320250459505 - 72 - 1 - 10 -2.01968503937008 - 20 -0.2418320250459505 - 11 -2.019685039370081 - 21 -0.4884064321643613 - 72 - 1 - 10 -2.019685039370081 - 20 -0.4884064321643613 - 11 -3.788481969160711 - 21 -1.132195865069596 - 97 - 1 -330 -19B2 - 92 - 16 - 93 - 68 - 72 - 1 - 10 -0.211518030839291 - 20 -1.132195865069596 - 11 -0.2115180308392921 - 21 -0.8856214579511849 - 72 - 1 - 10 -0.2115180308392921 - 20 -0.8856214579511849 - 11 -0.3800563547419098 - 21 -0.8242785247175163 - 72 - 1 - 10 -0.3800563547419098 - 20 -0.8242785247175163 - 11 -0.4819904717841743 - 21 -0.8831302146314739 - 72 - 2 - 10 -0.4918329914692137 - 20 -0.8660824704624889 - 40 -0.0196850393700787 - 50 -240.0 - 51 -420.0 - 73 - 0 - 72 - 1 - 10 -0.501675511154253 - 20 -0.8490347262935038 - 11 -0.4283509058011884 - 21 -0.8067007456546893 - 72 - 1 - 10 -0.4283509058011884 - 20 -0.8067007456546893 - 11 -0.4606008219772955 - 21 -0.7949627361090064 - 72 - 1 - 10 -0.4606008219772955 - 20 -0.7949627361090064 - 11 -0.56253493901956 - 21 -0.8538144260229641 - 72 - 2 - 10 -0.5723774587045993 - 20 -0.836766681853979 - 40 -0.0196850393700788 - 50 -240.0000000000001 - 51 -420.0000000000001 - 73 - 0 - 72 - 1 - 10 -0.5822199783896387 - 20 -0.8197189376849939 - 11 -0.5088953730365742 - 21 -0.7773849570461795 - 72 - 1 - 10 -0.5088953730365742 - 20 -0.7773849570461795 - 11 -0.5411452892126811 - 21 -0.7656469475004968 - 72 - 1 - 10 -0.5411452892126811 - 20 -0.7656469475004968 - 11 -0.6430794062549456 - 21 -0.8244986374144544 - 72 - 2 - 10 -0.652921925939985 - 20 -0.8074508932454694 - 40 -0.0196850393700788 - 50 -240.0000000000001 - 51 -420.0000000000001 - 73 - 0 - 72 - 1 - 10 -0.6627644456250243 - 20 -0.7904031490764842 - 11 -0.5894398402719598 - 21 -0.7480691684376697 - 72 - 1 - 10 -0.5894398402719598 - 20 -0.7480691684376697 - 11 -0.6216897564480669 - 21 -0.736331158891987 - 72 - 1 - 10 -0.6216897564480669 - 20 -0.736331158891987 - 11 -0.7236238734903314 - 21 -0.7951828488059446 - 72 - 2 - 10 -0.7334663931753708 - 20 -0.7781351046369596 - 40 -0.0196850393700788 - 50 -240.0000000000001 - 51 -420.0000000000001 - 73 - 0 - 72 - 1 - 10 -0.7433089128604101 - 20 -0.7610873604679744 - 11 -0.6699843075073457 - 21 -0.7187533798291599 - 72 - 1 - 10 -0.6699843075073457 - 20 -0.7187533798291599 - 11 -0.7022342236834526 - 21 -0.7070153702834772 - 72 - 1 - 10 -0.7022342236834526 - 20 -0.7070153702834772 - 11 -0.8041683407257171 - 21 -0.7658670601974349 - 72 - 2 - 10 -0.8140108604107564 - 20 -0.7488193160284498 - 40 -0.0196850393700788 - 50 -240.0000000000001 - 51 -420.0000000000001 - 73 - 0 - 72 - 1 - 10 -0.8238533800957958 - 20 -0.7317715718594647 - 11 -0.7505287747427313 - 21 -0.6894375912206502 - 72 - 1 - 10 -0.7505287747427313 - 20 -0.6894375912206502 - 11 -0.7827786909188382 - 21 -0.6776995816749674 - 72 - 1 - 10 -0.7827786909188382 - 20 -0.6776995816749674 - 11 -0.8847128079611027 - 21 -0.7365512715889251 - 72 - 2 - 10 -0.8945553276461421 - 20 -0.71950352741994 - 40 -0.0196850393700788 - 50 -240.0000000000001 - 51 -420.0000000000001 - 73 - 0 - 72 - 1 - 10 -0.9043978473311814 - 20 -0.7024557832509549 - 11 -0.8310732419781172 - 21 -0.6601218026121404 - 72 - 1 - 10 -0.8310732419781172 - 20 -0.6601218026121404 - 11 -0.8633231581542239 - 21 -0.6483837930664577 - 72 - 1 - 10 -0.8633231581542239 - 20 -0.6483837930664577 - 11 -0.9652572751964884 - 21 -0.7072354829804153 - 72 - 2 - 10 -0.9750997948815278 - 20 -0.6901877388114303 - 40 -0.0196850393700787 - 50 -240.0 - 51 -420.0 - 73 - 0 - 72 - 1 - 10 -0.9849423145665671 - 20 -0.6731399946424452 - 11 -0.9116177092135024 - 21 -0.6308060140036307 - 72 - 1 - 10 -0.9116177092135024 - 20 -0.6308060140036307 - 11 -0.9438676253896097 - 21 -0.619068004457948 - 72 - 1 - 10 -0.9438676253896097 - 20 -0.619068004457948 - 11 -1.045801742431874 - 21 -0.6779196943719056 - 72 - 2 - 10 -1.055644262116914 - 20 -0.6608719502029206 - 40 -0.0196850393700788 - 50 -240.0000000000001 - 51 -420.0000000000001 - 73 - 0 - 72 - 1 - 10 -1.065486781801953 - 20 -0.6438242060339354 - 11 -0.992162176448888 - 21 -0.6014902253951211 - 72 - 1 - 10 -0.992162176448888 - 20 -0.6014902253951211 - 11 -1.024412092624995 - 21 -0.5897522158494382 - 72 - 1 - 10 -1.024412092624995 - 20 -0.5897522158494382 - 11 -1.12634620966726 - 21 -0.6486039057633959 - 72 - 2 - 10 -1.136188729352299 - 20 -0.6315561615944107 - 40 -0.0196850393700788 - 50 -240.0000000000002 - 51 -420.0000000000003 - 73 - 0 - 72 - 1 - 10 -1.146031249037339 - 20 -0.6145084174254256 - 11 -1.072706643684274 - 21 -0.5721744367866111 - 72 - 1 - 10 -1.072706643684274 - 20 -0.5721744367866111 - 11 -1.104956559860381 - 21 -0.5604364272409283 - 72 - 1 - 10 -1.104956559860381 - 20 -0.5604364272409283 - 11 -1.206890676902646 - 21 -0.6192881171548861 - 72 - 2 - 10 -1.216733196587685 - 20 -0.6022403729859009 - 40 -0.0196850393700788 - 50 -240.0000000000001 - 51 -420.0000000000001 - 73 - 0 - 72 - 1 - 10 -1.226575716272724 - 20 -0.5851926288169159 - 11 -1.15325111091966 - 21 -0.5428586481781015 - 72 - 1 - 10 -1.15325111091966 - 20 -0.5428586481781015 - 11 -1.185501027095767 - 21 -0.5311206386324185 - 72 - 1 - 10 -1.185501027095767 - 20 -0.5311206386324185 - 11 -1.287435144138031 - 21 -0.5899723285463763 - 72 - 2 - 10 -1.297277663823071 - 20 -0.5729245843773911 - 40 -0.0196850393700788 - 50 -240.0000000000001 - 51 -420.0000000000001 - 73 - 0 - 72 - 1 - 10 -1.30712018350811 - 20 -0.5558768402084061 - 11 -1.233795578155045 - 21 -0.5135428595695918 - 72 - 1 - 10 -1.233795578155045 - 20 -0.5135428595695918 - 11 -1.266045494331153 - 21 -0.5018048500239088 - 72 - 1 - 10 -1.266045494331153 - 20 -0.5018048500239088 - 11 -1.367979611373417 - 21 -0.5606565399378665 - 72 - 2 - 10 -1.377822131058456 - 20 -0.5436087957688814 - 40 -0.0196850393700787 - 50 -240.0 - 51 -420.0 - 73 - 0 - 72 - 1 - 10 -1.387664650743496 - 20 -0.5265610515998964 - 11 -1.314340045390431 - 21 -0.4842270709610819 - 72 - 1 - 10 -1.314340045390431 - 20 -0.4842270709610819 - 11 -1.346589961566538 - 21 -0.4724890614153991 - 72 - 1 - 10 -1.346589961566538 - 20 -0.4724890614153991 - 11 -1.448524078608803 - 21 -0.5313407513293568 - 72 - 2 - 10 -1.458366598293842 - 20 -0.5142930071603717 - 40 -0.0196850393700788 - 50 -240.0000000000001 - 51 -420.0000000000001 - 73 - 0 - 72 - 1 - 10 -1.468209117978881 - 20 -0.4972452629913866 - 11 -1.394884512625817 - 21 -0.4549112823525721 - 72 - 1 - 10 -1.394884512625817 - 20 -0.4549112823525721 - 11 -1.427134428801924 - 21 -0.4431732728068893 - 72 - 1 - 10 -1.427134428801924 - 20 -0.4431732728068893 - 11 -1.529068545844188 - 21 -0.5020249627208471 - 72 - 2 - 10 -1.538911065529228 - 20 -0.4849772185518619 - 40 -0.0196850393700788 - 50 -240.0000000000002 - 51 -420.0000000000002 - 73 - 0 - 72 - 1 - 10 -1.548753585214267 - 20 -0.4679294743828769 - 11 -1.475428979861203 - 21 -0.4255954937440624 - 72 - 1 - 10 -1.475428979861203 - 20 -0.4255954937440624 - 11 -1.50767889603731 - 21 -0.4138574841983796 - 72 - 1 - 10 -1.50767889603731 - 20 -0.4138574841983796 - 11 -1.609613013079574 - 21 -0.4727091741123373 - 72 - 2 - 10 -1.619455532764613 - 20 -0.4556614299433522 - 40 -0.0196850393700788 - 50 -240.0000000000001 - 51 -420.0000000000001 - 73 - 0 - 72 - 1 - 10 -1.629298052449653 - 20 -0.4386136857743671 - 11 -1.555973447096588 - 21 -0.3962797051355528 - 72 - 1 - 10 -1.555973447096588 - 20 -0.3962797051355528 - 11 -1.588223363272695 - 21 -0.3845416955898698 - 72 - 1 - 10 -1.588223363272695 - 20 -0.3845416955898698 - 11 -1.69015748031496 - 21 -0.4433933855038275 - 72 - 2 - 10 -1.699999999999999 - 20 -0.4263456413348424 - 40 -0.0196850393700788 - 50 -240.0000000000001 - 51 -420.0000000000001 - 73 - 0 - 72 - 1 - 10 -1.709842519685038 - 20 -0.4092978971658573 - 11 -1.636517914331974 - 21 -0.366963916527043 - 72 - 1 - 10 -1.636517914331974 - 20 -0.366963916527043 - 11 -1.980314960629922 - 21 -0.2418320250459505 - 72 - 1 - 10 -1.980314960629922 - 20 -0.2418320250459505 - 11 -1.980314960629921 - 21 -0.4884064321643613 - 72 - 1 - 10 -1.980314960629921 - 20 -0.4884064321643613 - 11 -0.211518030839291 - 21 -1.132195865069596 - 97 - 1 -330 -12B7 - 75 - 0 - 76 - 1 - 98 - 1 - 10 -0.0 - 20 -0.0 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -ENDSEC - 0 -SECTION - 2 -OBJECTS - 0 -DICTIONARY - 5 -C -330 -0 -100 -AcDbDictionary -281 - 1 - 3 -ACAD_DETAILVIEWSTYLE -350 -122 - 3 -ACAD_GROUP -350 -D - 3 -ACAD_IMAGE_DICT -350 -124 - 3 -ACAD_IMAGE_VARS -350 -DC - 3 -ACAD_LAYOUT -350 -1A - 3 -ACAD_MLINESTYLE -350 -17 - 3 -ACAD_PLOTSETTINGS -350 -19 - 3 -ACAD_PLOTSTYLENAME -350 -E - 3 -ACAD_SCALELIST -350 -B6 - 3 -ACAD_SECTIONVIEWSTYLE -350 -123 - 3 -AcDbVariableDictionary -350 -66 - 3 -APPDATA -350 -E1 - 3 -DWGPROPS -350 -1B44 - 0 -DICTIONARY - 5 -133 -330 -2 -100 -AcDbDictionary -280 - 1 -281 - 1 - 3 -ACAD_LAYERSTATES -360 -134 - 3 -ACLYDICTIONARY -360 -C6B - 0 -DICTIONARY - 5 -C3A -330 -1F -100 -AcDbDictionary -280 - 1 -281 - 1 - 3 -ACAD_SORTENTS -360 -C3B - 0 -DICTIONARY - 5 -122 -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 0 -DICTIONARY - 5 -D -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 0 -DICTIONARY - 5 -124 -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 0 -RASTERVARIABLES - 5 -DC -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbRasterVariables - 90 - 0 - 70 - 1 - 71 - 1 - 72 - 5 - 0 -DICTIONARY - 5 -1A -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 3 -Model -350 -22 - 3 -Sheet1 -350 -59 - 3 -Sheet2 -350 -5E - 0 -DICTIONARY - 5 -17 -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 3 -Standard -350 -18 - 0 -DICTIONARY - 5 -19 -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 0 -ACDBDICTIONARYWDFLT - 5 -E -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 3 -Normal -350 -F -100 -AcDbDictionaryWithDefault -340 -F - 0 -DICTIONARY - 5 -B6 -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 3 -A0 -350 -B7 - 3 -A1 -350 -B8 - 3 -A2 -350 -B9 - 3 -A3 -350 -BA - 3 -A4 -350 -BB - 3 -A5 -350 -BC - 3 -A6 -350 -BD - 3 -A7 -350 -BE - 3 -A8 -350 -BF - 3 -A9 -350 -C0 - 3 -B0 -350 -C1 - 3 -B1 -350 -C2 - 3 -B2 -350 -C3 - 3 -B3 -350 -C4 - 3 -B4 -350 -C5 - 3 -B5 -350 -C6 - 3 -B6 -350 -C7 - 3 -B7 -350 -C8 - 3 -B8 -350 -C9 - 3 -B9 -350 -CA - 3 -C0 -350 -CB - 3 -C1 -350 -CC - 3 -C2 -350 -CD - 3 -C3 -350 -CE - 3 -C4 -350 -CF - 3 -C5 -350 -D0 - 3 -C6 -350 -D1 - 3 -C7 -350 -D2 - 3 -C8 -350 -D3 - 3 -C9 -350 -D4 - 3 -D0 -350 -D5 - 3 -D1 -350 -D6 - 3 -D2 -350 -D7 - 0 -DICTIONARY - 5 -123 -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 0 -DICTIONARY - 5 -66 -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 3 -DIMASSOC -350 -67 - 3 -HIDETEXT -350 -6B - 0 -DICTIONARY - 5 -E1 -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 0 -XRECORD - 5 -1B44 -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbXrecord -280 - 1 - 1 -DWGPROPS COOKIE - 2 -vector-logo - 3 - - 4 -Jonathan Greig - 6 -Original Art by Damien George - 7 -micropython logo - 8 - - 9 - -300 -= -301 -= -302 -= -303 -= -304 -= -305 -= -306 -= -307 -= -308 -= -309 -= - 40 -0.0 - 41 -2452643.063384271 - 42 -2456661.002361111 - 1 - - 90 - 0 - 0 -DICTIONARY - 5 -134 -102 -{ACAD_REACTORS -330 -133 -102 -} -330 -133 -100 -AcDbDictionary -281 - 1 - 3 -ARGON_LAYERP_1 -350 -135 - 3 -ARGON_LAYERP_10 -350 -C21 - 3 -ARGON_LAYERP_11 -350 -C22 - 3 -ARGON_LAYERP_12 -350 -C23 - 3 -ARGON_LAYERP_13 -350 -C26 - 3 -ARGON_LAYERP_14 -350 -C29 - 3 -ARGON_LAYERP_15 -350 -C2A - 3 -ARGON_LAYERP_16 -350 -C2B - 3 -ARGON_LAYERP_17 -350 -C2D - 3 -ARGON_LAYERP_18 -350 -C30 - 3 -ARGON_LAYERP_19 -350 -C31 - 3 -ARGON_LAYERP_2 -350 -4B1 - 3 -ARGON_LAYERP_20 -350 -C33 - 3 -ARGON_LAYERP_21 -350 -C38 - 3 -ARGON_LAYERP_22 -350 -C3C - 3 -ARGON_LAYERP_23 -350 -C3D - 3 -ARGON_LAYERP_24 -350 -C3E - 3 -ARGON_LAYERP_25 -350 -C41 - 3 -ARGON_LAYERP_26 -350 -C42 - 3 -ARGON_LAYERP_27 -350 -C43 - 3 -ARGON_LAYERP_28 -350 -C44 - 3 -ARGON_LAYERP_29 -350 -C46 - 3 -ARGON_LAYERP_3 -350 -6CF - 3 -ARGON_LAYERP_30 -350 -C49 - 3 -ARGON_LAYERP_31 -350 -C4C - 3 -ARGON_LAYERP_32 -350 -C4F - 3 -ARGON_LAYERP_33 -350 -C52 - 3 -ARGON_LAYERP_34 -350 -C54 - 3 -ARGON_LAYERP_35 -350 -C55 - 3 -ARGON_LAYERP_36 -350 -C56 - 3 -ARGON_LAYERP_37 -350 -C57 - 3 -ARGON_LAYERP_38 -350 -C58 - 3 -ARGON_LAYERP_39 -350 -C59 - 3 -ARGON_LAYERP_4 -350 -B84 - 3 -ARGON_LAYERP_40 -350 -C5A - 3 -ARGON_LAYERP_41 -350 -C5B - 3 -ARGON_LAYERP_42 -350 -C5D - 3 -ARGON_LAYERP_43 -350 -C5F - 3 -ARGON_LAYERP_44 -350 -C60 - 3 -ARGON_LAYERP_45 -350 -C61 - 3 -ARGON_LAYERP_46 -350 -C62 - 3 -ARGON_LAYERP_47 -350 -C63 - 3 -ARGON_LAYERP_48 -350 -C64 - 3 -ARGON_LAYERP_49 -350 -C65 - 3 -ARGON_LAYERP_5 -350 -B89 - 3 -ARGON_LAYERP_50 -350 -C66 - 3 -ARGON_LAYERP_51 -350 -C67 - 3 -ARGON_LAYERP_52 -350 -C68 - 3 -ARGON_LAYERP_53 -350 -C6A - 3 -ARGON_LAYERP_54 -350 -C6F - 3 -ARGON_LAYERP_55 -350 -C70 - 3 -ARGON_LAYERP_56 -350 -C71 - 3 -ARGON_LAYERP_57 -350 -C72 - 3 -ARGON_LAYERP_58 -350 -C73 - 3 -ARGON_LAYERP_59 -350 -D92 - 3 -ARGON_LAYERP_6 -350 -BB5 - 3 -ARGON_LAYERP_60 -350 -D93 - 3 -ARGON_LAYERP_61 -350 -1244 - 3 -ARGON_LAYERP_62 -350 -1B1D - 3 -ARGON_LAYERP_63 -350 -1B1E - 3 -ARGON_LAYERP_64 -350 -1B1F - 3 -ARGON_LAYERP_65 -350 -1B20 - 3 -ARGON_LAYERP_66 -350 -1B21 - 3 -ARGON_LAYERP_67 -350 -1B22 - 3 -ARGON_LAYERP_68 -350 -1B23 - 3 -ARGON_LAYERP_69 -350 -1B24 - 3 -ARGON_LAYERP_7 -350 -BF7 - 3 -ARGON_LAYERP_70 -350 -1B25 - 3 -ARGON_LAYERP_71 -350 -1B26 - 3 -ARGON_LAYERP_72 -350 -1B27 - 3 -ARGON_LAYERP_73 -350 -1B28 - 3 -ARGON_LAYERP_74 -350 -1B29 - 3 -ARGON_LAYERP_75 -350 -1B2C - 3 -ARGON_LAYERP_76 -350 -1B2D - 3 -ARGON_LAYERP_77 -350 -1B2E - 3 -ARGON_LAYERP_78 -350 -1B2F - 3 -ARGON_LAYERP_79 -350 -1B30 - 3 -ARGON_LAYERP_8 -350 -BF9 - 3 -ARGON_LAYERP_80 -350 -1B31 - 3 -ARGON_LAYERP_81 -350 -1B32 - 3 -ARGON_LAYERP_82 -350 -1B33 - 3 -ARGON_LAYERP_83 -350 -1B34 - 3 -ARGON_LAYERP_84 -350 -1B35 - 3 -ARGON_LAYERP_85 -350 -1B36 - 3 -ARGON_LAYERP_86 -350 -1B37 - 3 -ARGON_LAYERP_87 -350 -1B38 - 3 -ARGON_LAYERP_88 -350 -1B39 - 3 -ARGON_LAYERP_89 -350 -1B3A - 3 -ARGON_LAYERP_9 -350 -BFF - 3 -ARGON_LAYERP_90 -350 -1B3B - 3 -ARGON_LAYERP_91 -350 -1B3C - 3 -ARGON_LAYERP_92 -350 -1B3D - 3 -ARGON_LAYERP_93 -350 -1B3E - 0 -DICTIONARY - 5 -C6B -102 -{ACAD_REACTORS -330 -133 -102 -} -330 -133 -100 -AcDbDictionary -281 - 1 -1001 -ACAD -1000 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/logo/vector-logo.svg b/logo/vector-logo.svg deleted file mode 100644 index d5fb7347d15..00000000000 --- a/logo/vector-logo.svg +++ /dev/null @@ -1,523 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/logo/vector-text-R2000.dxf b/logo/vector-text-R2000.dxf deleted file mode 100644 index a963203b3f3..00000000000 --- a/logo/vector-text-R2000.dxf +++ /dev/null @@ -1,9888 +0,0 @@ - 0 -SECTION - 2 -HEADER - 9 -$ACADVER - 1 -AC1015 - 9 -$ACADMAINTVER - 70 - 6 - 9 -$DWGCODEPAGE - 3 -ANSI_1252 - 9 -$INSBASE - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$EXTMIN - 10 -0.0000000000000001 - 20 -0.0 - 30 -0.0 - 9 -$EXTMAX - 10 -3.692708053216686 - 20 -0.6839852852251591 - 30 -0.0 - 9 -$LIMMIN - 10 -0.0 - 20 -0.0 - 9 -$LIMMAX - 10 -12.0 - 20 -9.0 - 9 -$ORTHOMODE - 70 - 0 - 9 -$REGENMODE - 70 - 1 - 9 -$FILLMODE - 70 - 1 - 9 -$QTEXTMODE - 70 - 0 - 9 -$MIRRTEXT - 70 - 1 - 9 -$LTSCALE - 40 -1.0 - 9 -$ATTMODE - 70 - 1 - 9 -$TEXTSIZE - 40 -0.2 - 9 -$TRACEWID - 40 -0.05 - 9 -$TEXTSTYLE - 7 -Standard - 9 -$CLAYER - 8 -TEXT-RED - 9 -$CELTYPE - 6 -ByLayer - 9 -$CECOLOR - 62 - 256 - 9 -$CELTSCALE - 40 -1.0 - 9 -$DISPSILH - 70 - 0 - 9 -$DIMSCALE - 40 -1.0 - 9 -$DIMASZ - 40 -0.18 - 9 -$DIMEXO - 40 -0.0625 - 9 -$DIMDLI - 40 -0.38 - 9 -$DIMRND - 40 -0.0 - 9 -$DIMDLE - 40 -0.0 - 9 -$DIMEXE - 40 -0.18 - 9 -$DIMTP - 40 -0.0 - 9 -$DIMTM - 40 -0.0 - 9 -$DIMTXT - 40 -0.18 - 9 -$DIMCEN - 40 -0.09 - 9 -$DIMTSZ - 40 -0.0 - 9 -$DIMTOL - 70 - 0 - 9 -$DIMLIM - 70 - 0 - 9 -$DIMTIH - 70 - 1 - 9 -$DIMTOH - 70 - 1 - 9 -$DIMSE1 - 70 - 0 - 9 -$DIMSE2 - 70 - 0 - 9 -$DIMTAD - 70 - 0 - 9 -$DIMZIN - 70 - 0 - 9 -$DIMBLK - 1 - - 9 -$DIMASO - 70 - 1 - 9 -$DIMSHO - 70 - 1 - 9 -$DIMPOST - 1 - - 9 -$DIMAPOST - 1 - - 9 -$DIMALT - 70 - 0 - 9 -$DIMALTD - 70 - 2 - 9 -$DIMALTF - 40 -25.4 - 9 -$DIMLFAC - 40 -1.0 - 9 -$DIMTOFL - 70 - 0 - 9 -$DIMTVP - 40 -0.0 - 9 -$DIMTIX - 70 - 0 - 9 -$DIMSOXD - 70 - 0 - 9 -$DIMSAH - 70 - 0 - 9 -$DIMBLK1 - 1 - - 9 -$DIMBLK2 - 1 - - 9 -$DIMSTYLE - 2 -Standard - 9 -$DIMCLRD - 70 - 0 - 9 -$DIMCLRE - 70 - 0 - 9 -$DIMCLRT - 70 - 0 - 9 -$DIMTFAC - 40 -1.0 - 9 -$DIMGAP - 40 -0.09 - 9 -$DIMJUST - 70 - 0 - 9 -$DIMSD1 - 70 - 0 - 9 -$DIMSD2 - 70 - 0 - 9 -$DIMTOLJ - 70 - 1 - 9 -$DIMTZIN - 70 - 0 - 9 -$DIMALTZ - 70 - 0 - 9 -$DIMALTTZ - 70 - 0 - 9 -$DIMUPT - 70 - 0 - 9 -$DIMDEC - 70 - 3 - 9 -$DIMTDEC - 70 - 3 - 9 -$DIMALTU - 70 - 2 - 9 -$DIMALTTD - 70 - 2 - 9 -$DIMTXSTY - 7 -Standard - 9 -$DIMAUNIT - 70 - 0 - 9 -$DIMADEC - 70 - 0 - 9 -$DIMALTRND - 40 -0.0 - 9 -$DIMAZIN - 70 - 0 - 9 -$DIMDSEP - 70 - 46 - 9 -$DIMATFIT - 70 - 3 - 9 -$DIMFRAC - 70 - 0 - 9 -$DIMLDRBLK - 1 - - 9 -$DIMLUNIT - 70 - 2 - 9 -$DIMLWD - 70 - -2 - 9 -$DIMLWE - 70 - -2 - 9 -$DIMTMOVE - 70 - 2 - 9 -$LUNITS - 70 - 2 - 9 -$LUPREC - 70 - 3 - 9 -$SKETCHINC - 40 -0.1 - 9 -$FILLETRAD - 40 -0.5 - 9 -$AUNITS - 70 - 0 - 9 -$AUPREC - 70 - 0 - 9 -$MENU - 1 -. - 9 -$ELEVATION - 40 -0.0 - 9 -$PELEVATION - 40 -0.0 - 9 -$THICKNESS - 40 -0.0 - 9 -$LIMCHECK - 70 - 0 - 9 -$CHAMFERA - 40 -0.0 - 9 -$CHAMFERB - 40 -0.0 - 9 -$CHAMFERC - 40 -0.0 - 9 -$CHAMFERD - 40 -0.0 - 9 -$SKPOLY - 70 - 0 - 9 -$TDCREATE - 40 -2456662.269745891 - 9 -$TDUCREATE - 40 -2456662.519745903 - 9 -$TDUPDATE - 40 -2456662.282164352 - 9 -$TDUUPDATE - 40 -2456662.532164352 - 9 -$TDINDWG - 40 -0.0000000116 - 9 -$TDUSRTIMER - 40 -2456662.519895833 - 9 -$USRTIMER - 70 - 1 - 9 -$ANGBASE - 50 -0.0 - 9 -$ANGDIR - 70 - 0 - 9 -$PDMODE - 70 - 0 - 9 -$PDSIZE - 40 -0.0 - 9 -$PLINEWID - 40 -0.0 - 9 -$SPLFRAME - 70 - 0 - 9 -$SPLINETYPE - 70 - 6 - 9 -$SPLINESEGS - 70 - 8 - 9 -$HANDSEED - 5 -1D7 - 9 -$SURFTAB1 - 70 - 6 - 9 -$SURFTAB2 - 70 - 6 - 9 -$SURFTYPE - 70 - 6 - 9 -$SURFU - 70 - 6 - 9 -$SURFV - 70 - 6 - 9 -$UCSBASE - 2 - - 9 -$UCSNAME - 2 - - 9 -$UCSORG - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$UCSXDIR - 10 -1.0 - 20 -0.0 - 30 -0.0 - 9 -$UCSYDIR - 10 -0.0 - 20 -1.0 - 30 -0.0 - 9 -$UCSORTHOREF - 2 - - 9 -$UCSORTHOVIEW - 70 - 0 - 9 -$UCSORGTOP - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$UCSORGBOTTOM - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$UCSORGLEFT - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$UCSORGRIGHT - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$UCSORGFRONT - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$UCSORGBACK - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PUCSBASE - 2 - - 9 -$PUCSNAME - 2 - - 9 -$PUCSORG - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PUCSXDIR - 10 -1.0 - 20 -0.0 - 30 -0.0 - 9 -$PUCSYDIR - 10 -0.0 - 20 -1.0 - 30 -0.0 - 9 -$PUCSORTHOREF - 2 - - 9 -$PUCSORTHOVIEW - 70 - 0 - 9 -$PUCSORGTOP - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PUCSORGBOTTOM - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PUCSORGLEFT - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PUCSORGRIGHT - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PUCSORGFRONT - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PUCSORGBACK - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$USERI1 - 70 - 0 - 9 -$USERI2 - 70 - 0 - 9 -$USERI3 - 70 - 0 - 9 -$USERI4 - 70 - 0 - 9 -$USERI5 - 70 - 0 - 9 -$USERR1 - 40 -0.0 - 9 -$USERR2 - 40 -0.0 - 9 -$USERR3 - 40 -0.0 - 9 -$USERR4 - 40 -0.0 - 9 -$USERR5 - 40 -0.0 - 9 -$WORLDVIEW - 70 - 1 - 9 -$SHADEDGE - 70 - 3 - 9 -$SHADEDIF - 70 - 70 - 9 -$TILEMODE - 70 - 1 - 9 -$MAXACTVP - 70 - 64 - 9 -$PINSBASE - 10 -0.0 - 20 -0.0 - 30 -0.0 - 9 -$PLIMCHECK - 70 - 0 - 9 -$PEXTMIN - 10 -1.000000000000000E+20 - 20 -1.000000000000000E+20 - 30 -1.000000000000000E+20 - 9 -$PEXTMAX - 10 --1.000000000000000E+20 - 20 --1.000000000000000E+20 - 30 --1.000000000000000E+20 - 9 -$PLIMMIN - 10 -0.0 - 20 -0.0 - 9 -$PLIMMAX - 10 -0.0 - 20 -0.0 - 9 -$UNITMODE - 70 - 0 - 9 -$VISRETAIN - 70 - 1 - 9 -$PLINEGEN - 70 - 0 - 9 -$PSLTSCALE - 70 - 1 - 9 -$TREEDEPTH - 70 - 3020 - 9 -$CMLSTYLE - 2 -Standard - 9 -$CMLJUST - 70 - 0 - 9 -$CMLSCALE - 40 -1.0 - 9 -$PROXYGRAPHICS - 70 - 1 - 9 -$MEASUREMENT - 70 - 0 - 9 -$CELWEIGHT -370 - -1 - 9 -$ENDCAPS -280 - 0 - 9 -$JOINSTYLE -280 - 0 - 9 -$LWDISPLAY -290 - 0 - 9 -$INSUNITS - 70 - 0 - 9 -$HYPERLINKBASE - 1 - - 9 -$STYLESHEET - 1 - - 9 -$XEDIT -290 - 1 - 9 -$CEPSNTYPE -380 - 0 - 9 -$PSTYLEMODE -290 - 1 - 9 -$FINGERPRINTGUID - 2 -{394BC0E0-D500-95D9-65ED-9BB4C8BE75F1} - 9 -$VERSIONGUID - 2 -{FAEB1C32-E019-11D5-929B-00C0DF256EC4} - 9 -$EXTNAMES -290 - 1 - 9 -$PSVPSCALE - 40 -0.0 - 9 -$OLESTARTUP -290 - 0 - 0 -ENDSEC - 0 -SECTION - 2 -CLASSES - 0 -CLASS - 1 -ACDBDICTIONARYWDFLT - 2 -AcDbDictionaryWithDefault - 3 -ObjectDBX Classes - 90 - 0 -280 - 0 -281 - 0 - 0 -CLASS - 1 -SCALE - 2 -AcDbScale - 3 -ObjectDBX Classes - 90 - 1153 -280 - 0 -281 - 0 - 0 -CLASS - 1 -VISUALSTYLE - 2 -AcDbVisualStyle - 3 -ObjectDBX Classes - 90 - 4095 -280 - 0 -281 - 0 - 0 -CLASS - 1 -MATERIAL - 2 -AcDbMaterial - 3 -ObjectDBX Classes - 90 - 1153 -280 - 0 -281 - 0 - 0 -CLASS - 1 -TABLESTYLE - 2 -AcDbTableStyle - 3 -ObjectDBX Classes - 90 - 4095 -280 - 0 -281 - 0 - 0 -CLASS - 1 -SUN - 2 -AcDbSun - 3 -SCENEOE - 90 - 1153 -280 - 0 -281 - 0 - 0 -CLASS - 1 -RASTERVARIABLES - 2 -AcDbRasterVariables - 3 -ISM - 90 - 0 -280 - 0 -281 - 0 - 0 -CLASS - 1 -DICTIONARYVAR - 2 -AcDbDictionaryVar - 3 -ObjectDBX Classes - 90 - 0 -280 - 0 -281 - 0 - 0 -CLASS - 1 -ACDBPLACEHOLDER - 2 -AcDbPlaceHolder - 3 -ObjectDBX Classes - 90 - 0 -280 - 0 -281 - 0 - 0 -CLASS - 1 -LAYOUT - 2 -AcDbLayout - 3 -ObjectDBX Classes - 90 - 0 -280 - 0 -281 - 0 - 0 -ENDSEC - 0 -SECTION - 2 -TABLES - 0 -TABLE - 2 -VPORT - 5 -8 -330 -0 -100 -AcDbSymbolTable - 70 - 1 - 0 -VPORT - 5 -22 -330 -8 -100 -AcDbSymbolTableRecord -100 -AcDbViewportTableRecord - 2 -*ACTIVE - 70 - 0 - 10 -0.0 - 20 -0.0 - 11 -1.0 - 21 -1.0 - 12 -1.846354026608343 - 22 -0.3419926426125796 - 13 -0.0 - 23 -0.0 - 14 -10.0 - 24 -10.0 - 15 -10.0 - 25 -10.0 - 16 -0.0 - 26 -0.0 - 36 -1.0 - 17 -0.0 - 27 -0.0 - 37 -0.0 - 40 -1.733730323509535 - 41 -2.172519083969465 - 42 -50.0 - 43 -0.0 - 44 -0.0 - 50 -0.0 - 51 -0.0 - 71 - 16 - 72 - 100 - 73 - 1 - 74 - 1 - 75 - 0 - 76 - 0 - 77 - 0 - 78 - 0 -281 - 0 - 65 - 0 -110 -0.0 -120 -0.0 -130 -0.0 -111 -1.0 -121 -0.0 -131 -0.0 -112 -0.0 -122 -1.0 -132 -0.0 - 79 - 0 -146 -0.0 - 0 -ENDTAB - 0 -TABLE - 2 -LTYPE - 5 -5 -330 -0 -100 -AcDbSymbolTable - 70 - 1 - 0 -LTYPE - 5 -14 -330 -5 -100 -AcDbSymbolTableRecord -100 -AcDbLinetypeTableRecord - 2 -ByBlock - 70 - 0 - 3 - - 72 - 65 - 73 - 0 - 40 -0.0 - 0 -LTYPE - 5 -15 -330 -5 -100 -AcDbSymbolTableRecord -100 -AcDbLinetypeTableRecord - 2 -ByLayer - 70 - 0 - 3 - - 72 - 65 - 73 - 0 - 40 -0.0 - 0 -LTYPE - 5 -16 -330 -5 -100 -AcDbSymbolTableRecord -100 -AcDbLinetypeTableRecord - 2 -CONTINUOUS - 70 - 0 - 3 -Solid line - 72 - 65 - 73 - 0 - 40 -0.0 - 0 -ENDTAB - 0 -TABLE - 2 -LAYER - 5 -2 -102 -{ACAD_XDICTIONARY -360 -1B3 -102 -} -330 -0 -100 -AcDbSymbolTable - 70 - 3 - 0 -LAYER - 5 -10 -330 -2 -100 -AcDbSymbolTableRecord -100 -AcDbLayerTableRecord - 2 -0 - 70 - 0 - 62 - 7 - 6 -CONTINUOUS -370 - -3 -390 -F - 0 -LAYER - 5 -21 -330 -2 -100 -AcDbSymbolTableRecord -100 -AcDbLayerTableRecord - 2 -TEXT-GRAY - 70 - 0 - 62 - 254 - 6 -CONTINUOUS -370 - -3 -390 -F - 0 -LAYER - 5 -1B9 -330 -2 -100 -AcDbSymbolTableRecord -100 -AcDbLayerTableRecord - 2 -TEXT-RED - 70 - 0 - 62 - 1 - 6 -CONTINUOUS -370 - -3 -390 -F -1001 -AcAecLayerStandard -1000 - -1000 - - 0 -ENDTAB - 0 -TABLE - 2 -STYLE - 5 -3 -330 -0 -100 -AcDbSymbolTable - 70 - 1 - 0 -STYLE - 5 -11 -330 -3 -100 -AcDbSymbolTableRecord -100 -AcDbTextStyleTableRecord - 2 -Standard - 70 - 0 - 40 -0.0 - 41 -1.0 - 50 -0.0 - 71 - 0 - 42 -0.2 - 3 -txt - 4 - - 0 -ENDTAB - 0 -TABLE - 2 -VIEW - 5 -6 -330 -0 -100 -AcDbSymbolTable - 70 - 0 - 0 -ENDTAB - 0 -TABLE - 2 -UCS - 5 -7 -330 -0 -100 -AcDbSymbolTable - 70 - 0 - 0 -ENDTAB - 0 -TABLE - 2 -APPID - 5 -9 -330 -0 -100 -AcDbSymbolTable - 70 - 2 - 0 -APPID - 5 -12 -330 -9 -100 -AcDbSymbolTableRecord -100 -AcDbRegAppTableRecord - 2 -ACAD - 70 - 0 - 0 -APPID - 5 -1BA -330 -9 -100 -AcDbSymbolTableRecord -100 -AcDbRegAppTableRecord - 2 -AcAecLayerStandard - 70 - 0 - 0 -ENDTAB - 0 -TABLE - 2 -DIMSTYLE - 5 -A -330 -0 -100 -AcDbSymbolTable - 70 - 1 -100 -AcDbDimStyleTable - 0 -DIMSTYLE -105 -23 -330 -A -100 -AcDbSymbolTableRecord -100 -AcDbDimStyleTableRecord - 2 -Standard - 70 - 0 -178 - 0 -340 -11 - 0 -ENDTAB - 0 -TABLE - 2 -BLOCK_RECORD - 5 -1 -330 -0 -100 -AcDbSymbolTable - 70 - 0 - 0 -BLOCK_RECORD - 5 -1D -330 -1 -100 -AcDbSymbolTableRecord -100 -AcDbBlockTableRecord - 2 -*Model_Space -340 -1E - 0 -BLOCK_RECORD - 5 -1B -330 -1 -100 -AcDbSymbolTableRecord -100 -AcDbBlockTableRecord - 2 -*Paper_Space -340 -1C - 0 -ENDTAB - 0 -ENDSEC - 0 -SECTION - 2 -BLOCKS - 0 -BLOCK - 5 -18D -330 -1D -100 -AcDbEntity - 8 -0 -100 -AcDbBlockBegin - 2 -*Model_Space - 70 - 0 - 10 -0.0 - 20 -0.0 - 30 -0.0 - 3 -*Model_Space - 1 -*Model_Space - 0 -ENDBLK - 5 -18E -330 -1D -100 -AcDbEntity - 8 -0 -100 -AcDbBlockEnd - 0 -BLOCK - 5 -18F -330 -1B -100 -AcDbEntity - 67 - 1 - 8 -0 -100 -AcDbBlockBegin - 2 -*Paper_Space - 70 - 0 - 10 -0.0 - 20 -0.0 - 30 -0.0 - 3 -*Paper_Space - 1 -*Paper_Space - 0 -ENDBLK - 5 -190 -330 -1B -100 -AcDbEntity - 67 - 1 - 8 -0 -100 -AcDbBlockEnd - 0 -ENDSEC - 0 -SECTION - 2 -ENTITIES - 0 -LWPOLYLINE - 5 -24 -102 -{ACAD_REACTORS -330 -1BD -102 -} -330 -1D -100 -AcDbEntity - 8 -TEXT-GRAY -100 -AcDbPolyline - 90 - 14 - 70 - 1 - 43 -0.0 - 10 -0.0000000000000001 - 20 -0.1752767944487085 - 10 -0.0416193345059499 - 20 -0.6506897567371471 - 10 -0.1681431038010463 - 20 -0.6506897567371471 - 10 -0.247338516041492 - 20 -0.3260572124180542 - 10 -0.3260590389156172 - 20 -0.6506897567371471 - 10 -0.4521056357224397 - 20 -0.6506897567371471 - 10 -0.4963403625301471 - 20 -0.1752767944487085 - 10 -0.4066806413363264 - 20 -0.1752767944487085 - 10 -0.3752877144762009 - 20 -0.4930112663057366 - 10 -0.2987087599944248 - 20 -0.1752767944487085 - 10 -0.1973944622688229 - 20 -0.1752767944487085 - 10 -0.1174851938975943 - 20 -0.4930112663057366 - 10 -0.0896600256100814 - 20 -0.1752767944487085 - 10 -0.0000000000000001 - 20 -0.1752767944487085 - 0 -LWPOLYLINE - 5 -34 -102 -{ACAD_REACTORS -330 -1BE -102 -} -330 -1D -100 -AcDbEntity - 8 -TEXT-GRAY -100 -AcDbPolyline - 90 - 5 - 70 - 1 - 43 -0.0 - 10 -0.5505660310062117 - 20 -0.1752767944487085 - 10 -0.5505660310062117 - 20 -0.5201225784624666 - 10 -0.6416519423802962 - 20 -0.5201225784624666 - 10 -0.6416519423802962 - 20 -0.1752767944487085 - 10 -0.5505660310062117 - 20 -0.1752767944487085 - 0 -LWPOLYLINE - 5 -3B -102 -{ACAD_REACTORS -330 -1BF -102 -} -330 -1D -100 -AcDbEntity - 8 -TEXT-GRAY -100 -AcDbPolyline - 90 - 13 - 70 - 1 - 43 -0.0 - 10 -0.5474731617999196 - 20 -0.5714928224153991 - 10 -0.5474731617999196 - 20 -0.6288098380164536 - 42 --0.1883074803638932 - 10 -0.5513377262264826 - 20 -0.6414735544516654 - 42 --0.2159435161643535 - 10 -0.5629314195061711 - 20 -0.6456942859029685 - 10 -0.6311876334269211 - 20 -0.6456942859029685 - 42 --0.2288445935800111 - 10 -0.6418909091447587 - 20 -0.6414735544516654 - 42 --0.1763562374232752 - 10 -0.6454571456360689 - 20 -0.6288098380164536 - 10 -0.6454571456360689 - 20 -0.5714928224153991 - 42 --0.1943541296589125 - 10 -0.6418909091447587 - 20 -0.5602568182417533 - 42 --0.2096410684182619 - 10 -0.6311876334269211 - 20 -0.5565109761567706 - 10 -0.5629314195061711 - 20 -0.5565109761567706 - 42 --0.1965331617699563 - 10 -0.551636054161735 - 20 -0.5604349017541234 - 42 --0.2135460038275524 - 10 -0.5474731617999196 - 20 -0.5714928224153991 - 0 -LWPOLYLINE - 5 -4A -102 -{ACAD_REACTORS -330 -1C5 -102 -} -330 -1D -100 -AcDbEntity - 8 -TEXT-RED -100 -AcDbPolyline - 90 - 12 - 70 - 1 - 43 -0.0 - 10 -1.855753791898883 - 20 -0.5703040769182958 - 10 -1.749208100737245 - 20 -0.5703040769182958 - 10 -1.749208100737245 - 20 -0.4311767133994287 - 10 -1.855281946695168 - 20 -0.4311767133994287 - 42 -0.1378892503752188 - 10 -1.880487613061407 - 20 -0.4371219629662482 - 42 -0.1061516643405155 - 10 -1.890061504452931 - 20 -0.4460702789425233 - 42 -0.0752237691491799 - 10 -1.896895649500299 - 20 -0.460071904842465 - 42 -0.0778530288832081 - 10 -1.902359921375588 - 20 -0.5032381305759515 - 42 -0.0564276025149389 - 10 -1.899452746088178 - 20 -0.5325792918405643 - 42 -0.095076106856608 - 10 -1.890715999412924 - 20 -0.5535383513733607 - 42 -0.1319298941216669 - 10 -1.876149681349825 - 20 -0.5661122650117364 - 42 -0.1129501247093477 - 10 -1.855753791898883 - 20 -0.5703040769182958 - 0 -LWPOLYLINE - 5 -58 -102 -{ACAD_REACTORS -330 -1C7 -102 -} -330 -1D -100 -AcDbEntity - 8 -TEXT-RED -100 -AcDbPolyline - 90 - 23 - 70 - 1 - 43 -0.0 - 10 -2.401085080890193 - 20 -0.451391475175396 - 10 -2.401085080890193 - 20 -0.502049385078848 - 10 -2.456975906310984 - 20 -0.5208364345932495 - 10 -2.471953186325706 - 20 -0.6169178168015124 - 10 -2.547828939245814 - 20 -0.6169178168015124 - 10 -2.547828939245814 - 20 -0.5208364345932495 - 10 -2.625120227777072 - 20 -0.5208364345932495 - 10 -2.625120227777072 - 20 -0.451391475175396 - 10 -2.547828939245814 - 20 -0.451391475175396 - 10 -2.547828939245814 - 20 -0.312977967787312 - 42 -0.0356379455033458 - 10 -2.549609774369517 - 20 -0.2833386307955768 - 42 -0.0811642329835157 - 10 -2.554952279740622 - 20 -0.2643422951021078 - 42 -0.1858874482849488 - 10 -2.577068121063173 - 20 -0.244721753866562 - 42 -0.0076184446139192 - 10 -2.607448863857263 - 20 -0.2345547073915278 - 42 -0.0469611640188665 - 10 -2.620599646309214 - 20 -0.2311657933719365 - 10 -2.620599646309214 - 20 -0.1752767944487085 - 10 -2.541405756150071 - 20 -0.1752767944487085 - 42 --0.1146121843643247 - 10 -2.504464842943029 - 20 -0.1829913113213321 - 42 --0.132229815857891 - 10 -2.478071953160988 - 20 -0.2061345575229422 - 42 --0.0940182241125145 - 10 -2.462242307616974 - 20 -0.2447068374697993 - 42 --0.0555506677049525 - 10 -2.456975906310984 - 20 -0.2987081511619036 - 10 -2.456975906310984 - 20 -0.451391475175396 - 10 -2.401085080890193 - 20 -0.451391475175396 - 0 -LWPOLYLINE - 5 -71 -102 -{ACAD_REACTORS -330 -1CA -102 -} -330 -1D -100 -AcDbEntity - 8 -TEXT-RED -100 -AcDbPolyline - 90 - 22 - 70 - 1 - 43 -0.0 - 10 -3.589495720107105 - 20 -0.5260693501105883 - 42 --0.0932412511784359 - 10 -3.634655872346617 - 20 -0.5185183047698327 - 42 --0.1254375778784052 - 10 -3.666908775142547 - 20 -0.4958651687475662 - 42 --0.1084619648488494 - 10 -3.686254428494896 - 20 -0.4581099420437885 - 42 --0.0689905889343237 - 10 -3.692708053216686 - 20 -0.4052541467398021 - 10 -3.692708053216686 - 20 -0.1752767944487085 - 10 -3.601870241094878 - 20 -0.1752767944487085 - 10 -3.601870241094878 - 20 -0.4064428922369056 - 42 -0.0660852200863579 - 10 -3.59946535263723 - 20 -0.4269407611351025 - 42 -0.1056585132217627 - 10 -3.592296349703354 - 20 -0.4415816611820138 - 42 -0.1272161701661909 - 10 -3.580317569854181 - 20 -0.4503655923776398 - 42 -0.0972102752618352 - 10 -3.56357467552878 - 20 -0.4532940768032824 - 42 -0.0885878555139059 - 10 -3.519221226379493 - 20 -0.4465162487641 - 42 -0.077710311269079 - 10 -3.480332049105495 - 20 -0.4233288622047228 - 10 -3.480332049105495 - 20 -0.1752767944487085 - 10 -3.389479016170664 - 20 -0.1752767944487085 - 10 -3.389479016170664 - 20 -0.5201225784624666 - 10 -3.462264944047086 - 20 -0.5201225784624666 - 10 -3.480332049105495 - 20 -0.4832608134831443 - 42 --0.0353892151285229 - 10 -3.522843779878989 - 20 -0.5102534032982943 - 42 --0.0728322192286089 - 10 -3.555720736008866 - 20 -0.5227390362211358 - 42 --0.0544633437581111 - 10 -3.589495720107105 - 20 -0.5260693501105883 - 0 -LWPOLYLINE - 5 -89 -102 -{ACAD_REACTORS -330 -1C6 -102 -} -330 -1D -100 -AcDbEntity - 8 -TEXT-RED -100 -AcDbPolyline - 90 - 17 - 70 - 1 - 43 -0.0 - 10 -2.026516093204943 - 20 -0.5201225784624666 - 10 -2.12187448679461 - 20 -0.5201225784624666 - 10 -2.181814048479542 - 20 -0.2784929327615455 - 42 -0.1680883445175794 - 10 -2.192925241986399 - 20 -0.2601209548182838 - 42 -0.1691212946679427 - 10 -2.213442897941526 - 20 -0.2539970129065732 - 42 -0.0518086164809523 - 10 -2.216060877781497 - 20 -0.2532834611920508 - 10 -2.285026381589124 - 20 -0.5201225784624666 - 10 -2.379912929975073 - 20 -0.5201225784624666 - 10 -2.2602925604266 - 20 -0.0661149499446615 - 10 -2.21297105273781 - 20 -0.0 - 10 -2.147795531372934 - 20 -0.0 - 10 -2.196547795485895 - 20 -0.1752767944487085 - 42 --0.0815316895695442 - 10 -2.160444026995122 - 20 -0.1807616144215795 - 42 --0.0970784439939463 - 10 -2.131326611681949 - 20 -0.1972162265483224 - 42 --0.0875143454723418 - 10 -2.109195549546374 - 20 -0.2246403264126769 - 42 --0.0638836232247607 - 10 -2.094050840588399 - 20 -0.2630342184309034 - 10 -2.026516093204943 - 20 -0.5201225784624666 - 0 -LWPOLYLINE - 5 -9C -102 -{ACAD_REACTORS -330 -1C8 -102 -} -330 -1D -100 -AcDbEntity - 8 -TEXT-RED -100 -AcDbPolyline - 90 - 22 - 70 - 1 - 43 -0.0 - 10 -2.66863653221009 - 20 -0.1752767944487085 - 10 -2.66863653221009 - 20 -0.683985285225159 - 10 -2.758774186932835 - 20 -0.683985285225159 - 10 -2.758774186932835 - 20 -0.4832608134831443 - 42 --0.0349812911378511 - 10 -2.80104238469796 - 20 -0.5100159586151339 - 42 --0.0697958386932639 - 10 -2.834162873836206 - 20 -0.5227390362211358 - 42 --0.0522006296457192 - 10 -2.868653236146531 - 20 -0.5260693501105883 - 42 --0.0932412511784358 - 10 -2.913798167573019 - 20 -0.5185183047698327 - 42 --0.1254375778784047 - 10 -2.946066291181972 - 20 -0.4958651687475662 - 42 --0.1084619648488494 - 10 -2.965411944534321 - 20 -0.4581099420437885 - 42 --0.0689905889343073 - 10 -2.971865569256112 - 20 -0.4052541467398021 - 10 -2.971865569256112 - 20 -0.1752767944487085 - 10 -2.881012536321281 - 20 -0.1752767944487085 - 10 -2.881012536321281 - 20 -0.4064428922369056 - 42 -0.0660852200863579 - 10 -2.878622868676655 - 20 -0.4269407611351025 - 42 -0.1056585132217627 - 10 -2.871438644929757 - 20 -0.4415816611820138 - 42 -0.1272161701661909 - 10 -2.859475085893608 - 20 -0.4503655923776398 - 42 -0.0972102752618352 - 10 -2.842716970755184 - 20 -0.4532940768032824 - 42 -0.088587855513906 - 10 -2.798363521605896 - 20 -0.4465162487641 - 42 -0.0777103112690791 - 10 -2.759489565144921 - 20 -0.4233288622047228 - 10 -2.759489565144921 - 20 -0.1752767944487085 - 10 -2.66863653221009 - 20 -0.1752767944487085 - 0 -LWPOLYLINE - 5 -B4 -102 -{ACAD_REACTORS -330 -1C0 -102 -} -330 -1D -100 -AcDbEntity - 8 -TEXT-GRAY -100 -AcDbPolyline - 90 - 34 - 70 - 1 - 43 -0.0 - 10 -0.6946873432779551 - 20 -0.3481760979032103 - 42 --0.0229891281782208 - 10 -0.6967086672474216 - 20 -0.3959192221127403 - 42 --0.0328228697904816 - 10 -0.7027741612371234 - 20 -0.4354583281028243 - 42 --0.0483316739793035 - 10 -0.7128214199136659 - 20 -0.4666716493692773 - 42 --0.0727828188712317 - 10 -0.7267941262688635 - 20 -0.489443507733124 - 42 --0.1227899169725496 - 10 -0.762229701067922 - 20 -0.5157237634987931 - 42 --0.0944303865644604 - 10 -0.8083670295035159 - 20 -0.5234528923519188 - 42 --0.0315898411800418 - 10 -0.8956492597031299 - 20 -0.5183995824282526 - 42 --0.0456865147865019 - 10 -0.9667593760657095 - 20 -0.5032381305759515 - 10 -0.9667593760657095 - 20 -0.448776539498029 - 42 -0.0070437593452633 - 10 -0.8389882611433709 - 20 -0.4484492920180325 - 42 -0.0290350112768282 - 10 -0.82418297631581 - 20 -0.4474675495780431 - 42 -0.0847606935358247 - 10 -0.8076546954540353 - 20 -0.4410458885636011 - 42 -0.1825489438203349 - 10 -0.7945739287419907 - 20 -0.4249924970681467 - 42 -0.0517789759014607 - 10 -0.7877961007028083 - 20 -0.3930348780448645 - 42 -0.0296456838705223 - 10 -0.7855358099688792 - 20 -0.3499599771895165 - 42 -0.0216618761660938 - 10 -0.7870822445720254 - 20 -0.3081910220915498 - 42 -0.0471796273319681 - 10 -0.7917200263001613 - 20 -0.280157633081881 - 42 -0.072662787539697 - 10 -0.7993608744377529 - 20 -0.262588400817457 - 42 -0.1214661602111968 - 10 -0.8099134641066621 - 20 -0.2522132858283972 - 42 -0.0832516876593145 - 10 -0.8254021634389597 - 20 -0.247129686486815 - 42 -0.0435906078463293 - 10 -0.8478467743228099 - 20 -0.2454353055810845 - 42 -0.021166726074658 - 10 -0.9539175761181276 - 20 -0.2499539083432495 - 10 -0.9712784354522652 - 20 -0.2513808595641643 - 10 -0.9712784354522652 - 20 -0.1940650616281518 - 42 --0.0978017422898016 - 10 -0.9130101190372676 - 20 -0.1759903461632311 - 42 --0.0233934475797722 - 10 -0.8395225116804813 - 20 -0.1719472415999074 - 10 -0.8357173084247086 - 20 -0.1719472415999074 - 42 --0.1019475670653864 - 10 -0.7625265069218723 - 20 -0.1805684623043164 - 42 --0.117873950403685 - 10 -0.7277454270828068 - 20 -0.2064319722094134 - 42 --0.0715503088956374 - 10 -0.7132826105482655 - 20 -0.2296496481867064 - 42 --0.0491245187935067 - 10 -0.7029522447494936 - 20 -0.2610127422533067 - 42 --0.0334830700706472 - 10 -0.6967528076051885 - 20 -0.3005215588254747 - 42 --0.023527584931374 - 10 -0.6946873432779551 - 20 -0.3481760979032103 - 0 -LWPOLYLINE - 5 -D8 -102 -{ACAD_REACTORS -330 -1C1 -102 -} -330 -1D -100 -AcDbEntity - 8 -TEXT-GRAY -100 -AcDbPolyline - 90 - 16 - 70 - 1 - 43 -0.0 - 10 -1.020746077777311 - 20 -0.1752767944487085 - 10 -1.020746077777311 - 20 -0.5201225784624666 - 10 -1.097325032259088 - 20 -0.5201225784624666 - 10 -1.111594544468236 - 20 -0.4766017077855419 - 42 --0.0805753976673698 - 10 -1.160646658597752 - 20 -0.5117404767306502 - 42 --0.1124747672601628 - 10 -1.210292384435168 - 20 -0.5234528923519188 - 42 --0.0241299749672376 - 10 -1.233896821271378 - 20 -0.5225015915379756 - 42 --0.060832138395251 - 10 -1.248581861676056 - 20 -0.519647689096146 - 10 -1.248581861676056 - 20 -0.4318905695302117 - 42 -0.0248536783236681 - 10 -1.199353186115472 - 20 -0.4337931711580981 - 42 -0.0387057739818888 - 10 -1.170873522867967 - 20 -0.4317718471886316 - 42 -0.0551847743452131 - 10 -1.147743975398077 - 20 -0.4257063531989297 - 42 -0.080499651857314 - 10 -1.128480514436053 - 20 -0.4141126599192412 - 42 -0.0645077730986141 - 10 -1.111594544468236 - 20 -0.39550369391721 - 10 -1.111594544468236 - 20 -0.1752767944487085 - 10 -1.020746077777311 - 20 -0.1752767944487085 - 0 -LWPOLYLINE - 5 -EA -102 -{ACAD_REACTORS -330 -1C9 -102 -} -330 -1D -100 -AcDbEntity - 8 -TEXT-RED -100 -AcDbPolyline - 90 - 30 - 70 - 1 - 43 -0.0 - 10 -3.020617833369073 - 20 -0.3410405807579851 - 42 --0.0409081205529831 - 10 -3.025732026544832 - 20 -0.4159559003763376 - 42 --0.0781599297384411 - 10 -3.041896529975355 - 20 -0.4673261443292702 - 42 --0.1364366144086533 - 10 -3.072459922525721 - 20 -0.5006216728172821 - 42 --0.0882009175036989 - 10 -3.116752488422916 - 20 -0.5177450874682596 - 42 --0.0529086836461284 - 10 -3.177818390271558 - 20 -0.5234528923519188 - 42 --0.0321103580647159 - 10 -3.218868922994835 - 20 -0.5210145181056196 - 42 --0.0444041287441238 - 10 -3.253054869044698 - 20 -0.5137024395293266 - 42 --0.0605636228964518 - 10 -3.280406670047193 - 20 -0.5015136124604352 - 42 --0.0762678881360705 - 10 -3.300893884376273 - 20 -0.4844495589802478 - 42 --0.0695139514449708 - 10 -3.315825501951926 - 20 -0.4611571488110112 - 42 --0.0499044136612151 - 10 -3.326495291881113 - 20 -0.4302847737562754 - 42 --0.0350340529330662 - 10 -3.332888033350811 - 20 -0.3918309117347381 - 42 --0.0250615206333876 - 10 -3.335018947174044 - 20 -0.3457970848277011 - 42 --0.0247570817049555 - 10 -3.332933695789881 - 20 -0.2998822846785048 - 42 --0.035093333100506 - 10 -3.326632279198321 - 20 -0.2617856551386192 - 42 --0.0509721690967282 - 10 -3.316160359838434 - 20 -0.2315076528324352 - 42 --0.0726634493786117 - 10 -3.301487496084174 - 20 -0.2090479733436921 - 42 --0.0773754337522631 - 10 -3.281182931511371 - 20 -0.1928163461277374 - 42 --0.0591962390389137 - 10 -3.253800688882829 - 20 -0.1812223484317884 - 42 --0.0423681953096553 - 10 -3.219355989011574 - 20 -0.174265980255845 - 42 --0.0302514249026995 - 10 -3.177818390271558 - 20 -0.1719472415999074 - 42 --0.0327640807112059 - 10 -3.136935286491535 - 20 -0.1744296039958433 - 42 --0.0448781589059774 - 10 -3.10273411962865 - 20 -0.1818763867673907 - 42 --0.060332284523739 - 10 -3.075214889682901 - 20 -0.1942878943308099 - 42 --0.0746618379907621 - 10 -3.054392817467312 - 20 -0.2116639744779708 - 42 --0.0666236365557017 - 10 -3.03961340802189 - 20 -0.2341087375699512 - 42 --0.0504061851560683 - 10 -3.029065384596889 - 20 -0.2631532451887439 - 42 --0.0367317311855017 - 10 -3.022733526379283 - 20 -0.2987971929180886 - 42 --0.0269050519350767 - 10 -3.020617833369073 - 20 -0.3410405807579851 - 0 -LWPOLYLINE - 5 -10A -102 -{ACAD_REACTORS -330 -1C2 -102 -} -330 -1D -100 -AcDbEntity - 8 -TEXT-GRAY -100 -AcDbPolyline - 90 - 21 - 70 - 1 - 43 -0.0 - 10 -1.390325682953593 - 20 -0.4318905695302117 - 42 -0.0242919032698246 - 10 -1.38033778544784 - 20 -0.3839084785562191 - 42 -0.0375411437912006 - 10 -1.377007471558388 - 20 -0.3446083393305977 - 42 -0.0398730504554166 - 10 -1.38033778544784 - 20 -0.2901464438364147 - 42 -0.0541422102818605 - 10 -1.38500448672072 - 20 -0.2730230291854372 - 42 -0.0823828350418203 - 10 -1.392347006923059 - 20 -0.2606561186041756 - 42 -0.1602559612730944 - 10 -1.412086879332706 - 20 -0.2480513067153631 - 42 -0.0555482263236158 - 10 -1.442053616012568 - 20 -0.2454353055810845 - 42 -0.0316904222703728 - 10 -1.470353673666401 - 20 -0.2467432300441587 - 42 -0.1007429782984575 - 10 -1.488551677716809 - 20 -0.2532834611920508 - 42 -0.1818370389300056 - 10 -1.501154510899928 - 20 -0.2694555750290851 - 42 -0.0526041808970857 - 10 -1.507395044239396 - 20 -0.2969244240837275 - 42 -0.0324432335036989 - 10 -1.50948029562356 - 20 -0.3327178401969589 - 42 -0.018652937942289 - 10 -1.507927772695204 - 20 -0.3912220792138144 - 42 -0.0530768467862457 - 10 -1.502463500819915 - 20 -0.4224962837323597 - 42 -0.1914595274942226 - 10 -1.48998243414098 - 20 -0.4402133100912379 - 42 -0.0889989641192241 - 10 -1.472167994578754 - 20 -0.4475269107488332 - 42 -0.0570509400215991 - 10 -1.448236310262548 - 20 -0.4499652849951324 - 42 -0.0204219730568417 - 10 -1.425137204418705 - 20 -0.4491616260675131 - 42 -0.045760246847436 - 10 -1.409828110680079 - 20 -0.4467536934472601 - 42 -0.1785155631256146 - 10 -1.390325682953593 - 20 -0.4318905695302117 - 0 -LWPOLYLINE - 5 -121 -102 -{ACAD_REACTORS -330 -1C9 -102 -} -330 -1D -100 -AcDbEntity - 8 -TEXT-RED -100 -AcDbPolyline - 90 - 21 - 70 - 1 - 43 -0.0 - 10 -3.124789077699108 - 20 -0.4318905695302117 - 42 -0.0242919032698246 - 10 -3.114804224355961 - 20 -0.3839084785562191 - 42 -0.0375411437912007 - 10 -3.111470866303904 - 20 -0.3446083393305977 - 42 -0.0398730504554166 - 10 -3.114804224355961 - 20 -0.2901464438364147 - 42 -0.0541422102818607 - 10 -3.119461793141027 - 20 -0.2730230291854372 - 42 -0.0823828350418199 - 10 -3.12681344583118 - 20 -0.2606561186041756 - 42 -0.1602559612730945 - 10 -3.146539619509106 - 20 -0.2480513067153631 - 42 -0.0555482263236158 - 10 -3.176509400351572 - 20 -0.2454353055810845 - 42 -0.0316904222703728 - 10 -3.204820112574522 - 20 -0.2467432300441587 - 42 -0.1007429782984576 - 10 -3.223008984137115 - 20 -0.2532834611920508 - 42 -0.1818370389300056 - 10 -3.235611817320236 - 20 -0.2694555750290851 - 42 -0.0526041808970857 - 10 -3.241852350659703 - 20 -0.2969244240837275 - 42 -0.0324432335036989 - 10 -3.243937602043866 - 20 -0.3327178401969589 - 42 -0.018652937942289 - 10 -3.242385079115511 - 20 -0.3912220792138144 - 42 -0.0530768467862456 - 10 -3.236920807240222 - 20 -0.4224962837323597 - 42 -0.1914595274942226 - 10 -3.224439740561286 - 20 -0.4402133100912379 - 42 -0.0889989641192241 - 10 -3.20663138932427 - 20 -0.4475269107488332 - 42 -0.0570509400215991 - 10 -3.182689050438947 - 20 -0.4499652849951324 - 42 -0.0204219730568417 - 10 -3.159599077082918 - 20 -0.4491616260675131 - 42 -0.045760246847436 - 10 -3.144286939181689 - 20 -0.4467536934472601 - 42 -0.178515563125615 - 10 -3.124789077699108 - 20 -0.4318905695302117 - 0 -LWPOLYLINE - 5 -138 -102 -{ACAD_REACTORS -330 -1C5 -102 -} -330 -1D -100 -AcDbEntity - 8 -TEXT-RED -100 -AcDbPolyline - 90 - 17 - 70 - 1 - 43 -0.0 - 10 -1.658111534794044 - 20 -0.1752767944487085 - 10 -1.658111534794044 - 20 -0.6506897567371471 - 10 -1.862892353206713 - 20 -0.6506897567371471 - 42 --0.0918352741933524 - 10 -1.923821267738147 - 20 -0.6408190594916725 - 42 --0.133922059302927 - 10 -1.965389308104209 - 20 -0.6112100119178533 - 42 --0.1060028202258852 - 10 -1.987322499670483 - 20 -0.566558234833313 - 42 --0.0661506729116568 - 10 -1.99464371073459 - 20 -0.5039519867067345 - 42 --0.0710178368558241 - 10 -1.985846080807243 - 20 -0.4324841812381122 - 42 --0.0374247138640044 - 10 -1.976089539659442 - 20 -0.4061156447569091 - 42 --0.057718769966508 - 10 -1.964430396883754 - 20 -0.3867030198272586 - 42 --0.1271250474471338 - 10 -1.932329702218055 - 20 -0.3624456101123582 - 42 --0.110827379232239 - 10 -1.875723498585179 - 20 -0.3505535888974171 - 42 --0.0258396192335467 - 10 -1.802480946318064 - 20 -0.3564988384642365 - 42 --0.0037744416271255 - 10 -1.763835302052436 - 20 -0.3612568646152548 - 42 --0.0304647996844293 - 10 -1.749208100737245 - 20 -0.3636343556094617 - 10 -1.749208100737245 - 20 -0.1752767944487085 - 10 -1.658111534794044 - 20 -0.1752767944487085 - 0 -LWPOLYLINE - 5 -14B -102 -{ACAD_REACTORS -330 -1C2 -102 -} -330 -1D -100 -AcDbEntity - 8 -TEXT-GRAY -100 -AcDbPolyline - 90 - 30 - 70 - 1 - 43 -0.0 - 10 -1.286159004867464 - 20 -0.3410405807579851 - 42 --0.040908120552983 - 10 -1.29127167596192 - 20 -0.4159559003763376 - 42 --0.0781599297384411 - 10 -1.307443789798954 - 20 -0.4673261443292702 - 42 --0.1364366144086534 - 10 -1.338004138186717 - 20 -0.5006216728172821 - 42 --0.088200917503699 - 10 -1.382299748246516 - 20 -0.5177450874682596 - 42 --0.0529086836461285 - 10 -1.443361083851251 - 20 -0.5234528923519188 - 42 --0.0321103580647177 - 10 -1.484408572411924 - 20 -0.5210145181056196 - 42 --0.0444041287441238 - 10 -1.518597562624391 - 20 -0.5137024395293266 - 42 --0.0605636228964518 - 10 -1.545949363626886 - 20 -0.5015136124604352 - 42 --0.0762678881361016 - 10 -1.566436577955966 - 20 -0.4844495589802478 - 42 --0.0695139514449315 - 10 -1.581368195531619 - 20 -0.4611571488110112 - 42 --0.0499044136612151 - 10 -1.592037985460806 - 20 -0.4302847737562754 - 42 --0.0350340529330662 - 10 -1.598430726930504 - 20 -0.3918309117347381 - 42 --0.0250615206333974 - 10 -1.600561640753737 - 20 -0.3457970848277011 - 42 --0.0247570817049556 - 10 -1.59846116855655 - 20 -0.2998822846785048 - 42 --0.035093333100506 - 10 -1.592174972778014 - 20 -0.2617856551386192 - 42 --0.0509721690967282 - 10 -1.581703053418127 - 20 -0.2315076528324352 - 42 --0.0726634493786118 - 10 -1.567030189663867 - 20 -0.2090479733436921 - 42 --0.0773754337522942 - 10 -1.546725625091063 - 20 -0.1928163461277374 - 42 --0.0591962390389137 - 10 -1.519343382462522 - 20 -0.1812223484317884 - 42 --0.0423681953096553 - 10 -1.484891072184755 - 20 -0.174265980255845 - 42 --0.0302514249026978 - 10 -1.443361083851251 - 20 -0.1719472415999074 - 42 --0.0327640807112059 - 10 -1.402470369664717 - 20 -0.1744296039958433 - 42 --0.0448781589059774 - 10 -1.368267680720529 - 20 -0.1818763867673907 - 42 --0.060332284523739 - 10 -1.340754539099989 - 20 -0.1942878943308099 - 42 --0.0746618379907621 - 10 -1.319929422721796 - 20 -0.2116639744779708 - 42 --0.0666236365556613 - 10 -1.305154579520281 - 20 -0.2341087375699512 - 42 --0.0504061851560684 - 10 -1.294601989851372 - 20 -0.2631532451887439 - 42 --0.0367317311855017 - 10 -1.288268609552464 - 20 -0.2987971929180886 - 42 --0.0269050519351071 - 10 -1.286159004867464 - 20 -0.3410405807579851 - 0 -HATCH - 5 -1BD -330 -1D -100 -AcDbEntity - 8 -TEXT-GRAY -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 14 - 72 - 1 - 10 -0.0000000000000001 - 20 -0.1752767944487085 - 11 -0.0416193345059499 - 21 -0.6506897567371471 - 72 - 1 - 10 -0.0416193345059499 - 20 -0.6506897567371471 - 11 -0.1681431038010463 - 21 -0.6506897567371471 - 72 - 1 - 10 -0.1681431038010463 - 20 -0.6506897567371471 - 11 -0.247338516041492 - 21 -0.3260572124180542 - 72 - 1 - 10 -0.247338516041492 - 20 -0.3260572124180542 - 11 -0.3260590389156172 - 21 -0.6506897567371471 - 72 - 1 - 10 -0.3260590389156172 - 20 -0.6506897567371471 - 11 -0.4521056357224397 - 21 -0.6506897567371471 - 72 - 1 - 10 -0.4521056357224397 - 20 -0.6506897567371471 - 11 -0.4963403625301471 - 21 -0.1752767944487085 - 72 - 1 - 10 -0.4963403625301471 - 20 -0.1752767944487085 - 11 -0.4066806413363264 - 21 -0.1752767944487085 - 72 - 1 - 10 -0.4066806413363264 - 20 -0.1752767944487085 - 11 -0.3752877144762009 - 21 -0.4930112663057366 - 72 - 1 - 10 -0.3752877144762009 - 20 -0.4930112663057366 - 11 -0.2987087599944248 - 21 -0.1752767944487085 - 72 - 1 - 10 -0.2987087599944248 - 20 -0.1752767944487085 - 11 -0.1973944622688229 - 21 -0.1752767944487085 - 72 - 1 - 10 -0.1973944622688229 - 20 -0.1752767944487085 - 11 -0.1174851938975943 - 21 -0.4930112663057366 - 72 - 1 - 10 -0.1174851938975943 - 20 -0.4930112663057366 - 11 -0.0896600256100814 - 21 -0.1752767944487085 - 72 - 1 - 10 -0.0896600256100814 - 20 -0.1752767944487085 - 11 -0.0000000000000001 - 21 -0.1752767944487085 - 72 - 1 - 10 -0.0000000000000001 - 20 -0.1752767944487085 - 11 -0.0000000000000001 - 21 -0.1752767944487085 - 97 - 1 -330 -24 - 75 - 0 - 76 - 1 - 98 - 1 - 10 --0.0349603810164775 - 20 -0.1524455749140718 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -1BE -330 -1D -100 -AcDbEntity - 8 -TEXT-GRAY -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 5 - 72 - 1 - 10 -0.5505660310062117 - 20 -0.1752767944487085 - 11 -0.5505660310062117 - 21 -0.5201225784624666 - 72 - 1 - 10 -0.5505660310062117 - 20 -0.5201225784624666 - 11 -0.6416519423802962 - 21 -0.5201225784624666 - 72 - 1 - 10 -0.6416519423802962 - 20 -0.5201225784624666 - 11 -0.6416519423802962 - 21 -0.1752767944487085 - 72 - 1 - 10 -0.6416519423802962 - 20 -0.1752767944487085 - 11 -0.5505660310062117 - 21 -0.1752767944487085 - 72 - 1 - 10 -0.5505660310062117 - 20 -0.1752767944487085 - 11 -0.5505660310062117 - 21 -0.1752767944487085 - 97 - 1 -330 -34 - 75 - 0 - 76 - 1 - 98 - 1 - 10 --0.0349603810164775 - 20 -0.1524455749140718 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -1BF -330 -1D -100 -AcDbEntity - 8 -TEXT-GRAY -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 13 - 72 - 1 - 10 -0.5474731617999196 - 20 -0.5714928224153991 - 11 -0.5474731617999196 - 21 -0.6288098380164536 - 72 - 2 - 10 -0.5656218268345913 - 20 -0.630192970755272 - 40 -0.0182012938747197 - 50 -175.6418407014946 - 51 -218.2992114073367 - 73 - 0 - 72 - 2 - 10 -0.5617930966007493 - 20 -0.6307876795407876 - 40 -0.0149500064305679 - 50 -225.6246753032742 - 51 -274.3668398711414 - 73 - 0 - 72 - 1 - 10 -0.5629314195061711 - 20 -0.6456942859029685 - 11 -0.6311876334269211 - 21 -0.6456942859029685 - 72 - 2 - 10 -0.6321698296440981 - 20 -0.6325035330064808 - 40 -0.0132272699898821 - 50 -265.7415594617891 - 51 -317.3010585925538 - 73 - 0 - 72 - 2 - 10 -0.6262804611730807 - 20 -0.6302434840168466 - 40 -0.0192301993709753 - 50 -324.2689673804306 - 51 -364.2754703081528 - 73 - 0 - 72 - 1 - 10 -0.6454571456360689 - 20 -0.6288098380164536 - 11 -0.6454571456360689 - 21 -0.5714928224153991 - 72 - 2 - 10 -0.6297669641888812 - 20 -0.5702888340215038 - 40 -0.0157363077593922 - 50 -355.611999000231 - 51 -399.6062175218991 - 73 - 0 - 72 - 2 - 10 -0.6322686211170757 - 20 -0.5705867464421508 - 40 -0.0141172179806454 - 50 -47.03124341518984 - 51 -94.39156764264102 - 73 - 0 - 72 - 1 - 10 -0.6311876334269211 - 20 -0.5565109761567706 - 11 -0.5629314195061711 - 21 -0.5565109761567706 - 72 - 2 - 10 -0.5620823708457157 - 20 -0.572286229491247 - 40 -0.0157980853711685 - 50 -86.91922452913958 - 51 -131.3944660406891 - 73 - 0 - 72 - 2 - 10 -0.5619098596911134 - 20 -0.570615150925454 - 40 -0.0144633520750158 - 50 -135.2620677004958 - 51 -183.4789850614727 - 73 - 0 - 72 - 1 - 10 -0.5474731617999196 - 20 -0.5714928224153991 - 11 -0.5474731617999196 - 21 -0.5714928224153991 - 97 - 1 -330 -3B - 75 - 0 - 76 - 1 - 98 - 1 - 10 --0.0349603810164775 - 20 -0.1524455749140718 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -1C0 -330 -1D -100 -AcDbEntity - 8 -TEXT-GRAY -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 34 - 72 - 2 - 10 -1.214616030315336 - 20 -0.350077974119305 - 40 -0.5199321655154222 - 50 -179.7904154992175 - 51 -185.0582076977404 - 73 - 0 - 72 - 2 - 10 -1.000572124284262 - 20 -0.3695398595471971 - 40 -0.3050063463138826 - 50 -184.961591177561 - 51 -192.4813391512255 - 73 - 0 - 72 - 2 - 10 -0.8688743989493632 - 20 -0.3992160253637114 - 40 -0.170008215907044 - 50 -192.3087569665484 - 51 -203.3769478223085 - 73 - 0 - 72 - 2 - 10 -0.7976119460679242 - 20 -0.4303172999651613 - 40 -0.0922554716323781 - 50 -203.2074684948184 - 51 -219.8587008780153 - 73 - 0 - 72 - 2 - 10 -0.7972117188097253 - 20 -0.4315246663413517 - 40 -0.0911769133466147 - 50 -219.4374770529955 - 51 -247.4386863416477 - 73 - 0 - 72 - 2 - 10 -0.8055784036639897 - 20 -0.398531115770543 - 40 -0.124952897918856 - 50 -249.7009350090099 - 51 -271.2787999327404 - 73 - 0 - 72 - 2 - 10 -0.8120564786102148 - 20 --0.1691304899318403 - 40 -0.6925932092147039 - 50 -269.6947835186498 - 51 -276.9322349981942 - 73 - 0 - 72 - 2 - 10 -0.8484128964611991 - 20 -0.1225112149529162 - 40 -0.3986964678983381 - 50 -276.8042143326444 - 51 -287.2675164228719 - 73 - 0 - 72 - 1 - 10 -0.9667593760657095 - 20 -0.5032381305759515 - 11 -0.9667593760657095 - 21 -0.448776539498029 - 72 - 2 - 10 -0.9144880443227094 - 20 --4.086066981505726 - 40 -4.535144766389704 - 50 -89.3396036583715 - 51 -90.9538876909594 - 73 - 1 - 72 - 2 - 10 -0.8400315841062043 - 20 -0.3205880251107224 - 40 -0.1278655234922502 - 50 -90.46751199340585 - 51 -97.1199774171112 - 73 - 1 - 72 - 2 - 10 -0.8347233227483223 - 20 -0.3958571165940125 - 40 -0.0526757600392865 - 50 -101.54272561012 - 51 -120.9221245987022 - 73 - 1 - 72 - 2 - 10 -0.8223667308685831 - 20 -0.4157021086294436 - 40 -0.029304456442492 - 50 -120.1351163505028 - 51 -161.5166003585789 - 73 - 1 - 72 - 2 - 10 -0.9450695696956614 - 20 -0.3763766174814469 - 40 -0.1581532222056973 - 50 -162.0975481756131 - 51 -173.9538270794763 - 73 - 1 - 72 - 2 - 10 -1.149594366372439 - 20 -0.3524533042818777 - 40 -0.3640670943255288 - 50 -173.6000944629489 - 51 -180.3923953532557 - 73 - 1 - 72 - 2 - 10 -1.268138893295446 - 20 -0.346914547227496 - 40 -0.4826126922076991 - 50 -179.638444150984 - 51 -184.6022041776311 - 73 - 1 - 72 - 2 - 10 -0.9376165336263994 - 20 -0.3186947544718952 - 40 -0.1509003001157511 - 50 -183.9914206989488 - 51 -194.7961827171795 - 73 - 1 - 72 - 2 - 10 -0.8556691262907683 - 20 -0.2975229405501065 - 40 -0.0662649326044679 - 50 -195.1922580686626 - 51 -211.8161260167849 - 73 - 1 - 72 - 2 - 10 -0.8256760335810848 - 20 -0.2787995943136916 - 40 -0.0309077724093995 - 50 -211.6347351863199 - 51 -239.3370203444206 - 73 - 1 - 72 - 2 - 10 -0.8328177638353177 - 20 -0.2958607887822569 - 40 -0.0492921034260791 - 50 -242.3114767787511 - 51 -261.3474606529535 - 73 - 1 - 72 - 2 - 10 -0.8463235842781011 - 20 -0.3747617950344397 - 40 -0.1293354591063143 - 50 -260.6908797927596 - 51 -270.6747908046021 - 73 - 1 - 72 - 2 - 10 -0.8475369120546362 - 20 -1.499934543466537 - 40 -1.25449927615356 - 50 -270.0141521009336 - 51 -274.864484102984 - 73 - 1 - 72 - 1 - 10 -0.9539175761181276 - 20 -0.2499539083432495 - 11 -0.9712784354522652 - 21 -0.2513808595641643 - 72 - 1 - 10 -0.9712784354522652 - 20 -0.2513808595641643 - 11 -0.9712784354522652 - 21 -0.1940650616281518 - 72 - 2 - 10 -0.8963837746081258 - 20 -0.3325480038481863 - 40 -0.1574380370459314 - 50 -61.59448955636654 - 51 -83.93793890179708 - 73 - 0 - 72 - 2 - 10 -0.8330823004026875 - 20 -0.9588829323823655 - 40 -0.7869620433976263 - 50 -84.17070136778845 - 51 -89.53110693540054 - 73 - 0 - 72 - 1 - 10 -0.8395225116804813 - 20 -0.1719472415999074 - 11 -0.8357173084247086 - 21 -0.1719472415999074 - 72 - 2 - 10 -0.8200434901136805 - 20 -0.3538739274501789 - 40 -0.1826006232325358 - 50 -85.075865127039 - 51 -108.3600821200968 - 73 - 0 - 72 - 2 - 10 -0.7992279764644755 - 20 -0.2662427996310877 - 40 -0.093204559668334 - 50 -113.1894915396505 - 51 -140.0801272454766 - 73 - 0 - 72 - 2 - 10 -0.8012223158134221 - 20 -0.2683158374418412 - 40 -0.0960649049009913 - 50 -139.8951733394063 - 51 -156.2653987660679 - 73 - 0 - 72 - 2 - 10 -0.867342438096846 - 20 -0.2977766777590661 - 40 -0.168450950198126 - 50 -156.1444339138709 - 51 -167.3939009796797 - 73 - 0 - 72 - 2 - 10 -0.99451280167804 - 20 -0.3270031053307328 - 40 -0.2989352544876143 - 50 -167.2468323736907 - 51 -174.9177209790342 - 73 - 0 - 72 - 2 - 10 -1.20180856877263 - 20 -0.3462839419889538 - 40 -0.5071247554608478 - 50 -174.8226486749857 - 51 -180.2137793480696 - 73 - 0 - 72 - 1 - 10 -0.6946873432779551 - 20 -0.3481760979032103 - 11 -0.6946873432779551 - 21 -0.3481760979032103 - 97 - 1 -330 -B4 - 75 - 0 - 76 - 1 - 98 - 1 - 10 --0.0349603810164775 - 20 -0.1524455749140718 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -1C1 -330 -1D -100 -AcDbEntity - 8 -TEXT-GRAY -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 16 - 72 - 1 - 10 -1.020746077777311 - 20 -0.1752767944487085 - 11 -1.020746077777311 - 21 -0.5201225784624666 - 72 - 1 - 10 -1.020746077777311 - 20 -0.5201225784624666 - 11 -1.097325032259088 - 21 -0.5201225784624666 - 72 - 1 - 10 -1.097325032259088 - 20 -0.5201225784624666 - 11 -1.111594544468236 - 21 -0.4766017077855419 - 72 - 2 - 10 -1.244437268897258 - 20 -0.3429659792394641 - 40 -0.1884295554783436 - 50 -225.1705040479414 - 51 -243.5972159016927 - 73 - 0 - 72 - 2 - 10 -1.211173613045121 - 20 -0.4086440720149234 - 40 -0.114812202274129 - 50 -243.8907918763913 - 51 -269.5602281386679 - 73 - 0 - 72 - 2 - 10 -1.212244334515651 - 20 -0.2785645037372034 - 40 -0.2448961677679514 - 50 -269.5433179430547 - 51 -275.0724278925614 - 73 - 0 - 72 - 2 - 10 -1.229554147138809 - 20 -0.4609473043473566 - 40 -0.0617072855517635 - 50 -274.0355485122913 - 51 -287.9600884366593 - 73 - 0 - 72 - 1 - 10 -1.248581861676056 - 20 -0.519647689096146 - 11 -1.248581861676056 - 21 -0.4318905695302117 - 72 - 2 - 10 -1.204841316941958 - 20 --0.0620372588614032 - 40 -0.4958608019528185 - 50 -84.9392850010685 - 51 -90.63415610337293 - 73 - 1 - 72 - 2 - 10 -1.198149495755201 - 20 -0.2491083832840643 - 40 -0.1846887103819838 - 50 -89.62657779356016 - 51 -98.49286189291752 - 73 - 1 - 72 - 2 - 10 -1.186703181985212 - 20 -0.32427591283572 - 40 -0.1086552070090232 - 50 -98.37706810352306 - 51 -111.0116715202816 - 73 - 1 - 72 - 2 - 10 -1.173884337196004 - 20 -0.3604725103818166 - 40 -0.070276402608659 - 50 -111.8368548044861 - 51 -130.2463188715139 - 73 - 1 - 72 - 2 - 10 -1.191856507616234 - 20 -0.3396388865736808 - 40 -0.0977898738515406 - 50 -130.3972532514171 - 51 -145.1608900952568 - 73 - 1 - 72 - 1 - 10 -1.111594544468236 - 20 -0.39550369391721 - 11 -1.111594544468236 - 21 -0.1752767944487085 - 72 - 1 - 10 -1.111594544468236 - 20 -0.1752767944487085 - 11 -1.020746077777311 - 21 -0.1752767944487085 - 72 - 1 - 10 -1.020746077777311 - 20 -0.1752767944487085 - 11 -1.020746077777311 - 21 -0.1752767944487085 - 97 - 1 -330 -D8 - 75 - 0 - 76 - 1 - 98 - 1 - 10 --0.0349603810164775 - 20 -0.1524455749140718 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -1C2 -330 -1D -100 -AcDbEntity - 8 -TEXT-GRAY -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 2 - 92 - 1 - 93 - 30 - 72 - 2 - 10 -1.745775880860402 - 20 -0.3473056857538349 - 40 -0.4596595742917985 - 50 -179.219041199578 - 51 -188.5892672078823 - 73 - 0 - 72 - 2 - 10 -1.462665276168372 - 20 -0.3902293883547505 - 40 -0.1733136452000416 - 50 -188.5364777731353 - 51 -206.4130707393759 - 73 - 0 - 72 - 2 - 10 -1.382597433515457 - 20 -0.4290189590384098 - 40 -0.0843534860499277 - 50 -207.0087701028281 - 51 -238.085854021312 - 73 - 0 - 72 - 2 - 10 -1.408309618919584 - 20 -0.3846069642931946 - 40 -0.1356549785854117 - 50 -238.7839320009168 - 51 -258.9459185787553 - 73 - 0 - 72 - 2 - 10 -1.439724993974423 - 20 -0.2328843812063898 - 40 -0.29059126074079 - 50 -258.6024639297659 - 51 -270.7169453069864 - 73 - 0 - 72 - 2 - 10 -1.444920074652102 - 20 -0.2029818501508946 - 40 -0.3204748341784855 - 50 -269.7212762564572 - 51 -277.0779005236373 - 73 - 0 - 72 - 2 - 10 -1.460416453713881 - 20 -0.3252503357550985 - 40 -0.1972288945641309 - 50 -276.9871111277841 - 51 -287.1571071678799 - 73 - 0 - 72 - 2 - 10 -1.482143870267849 - 20 -0.3951169191449219 - 40 -0.1240620704779083 - 50 -287.0876504098538 - 51 -300.9508770078874 - 73 - 0 - 72 - 2 - 10 -1.500583736465673 - 20 -0.4262167749073336 - 40 -0.0879070752171196 - 50 -301.0685629566324 - 51 -318.5141019927507 - 73 - 0 - 72 - 2 - 10 -1.490538341293795 - 20 -0.4193627680062952 - 40 -0.0999841621843878 - 50 -319.38514811862 - 51 -335.2909851831375 - 73 - 0 - 72 - 2 - 10 -1.432430719209494 - 20 -0.3924029450769723 - 40 -0.1640411911207225 - 50 -335.220473520381 - 51 -346.6482421759119 - 73 - 0 - 72 - 2 - 10 -1.321167690210193 - 20 -0.3654957782609066 - 40 -0.2785109168173717 - 50 -346.5482508793782 - 51 -354.5741818072581 - 73 - 0 - 72 - 2 - 10 -1.140576365463508 - 20 -0.34757052037717 - 40 -0.459988693945271 - 50 -354.4784226911817 - 51 -360.2208980900735 - 73 - 0 - 72 - 2 - 10 -1.136142388530695 - 20 -0.3440375062016253 - 40 -0.4644225855321327 - 50 -359.7829203976418 - 51 -365.4556667991741 - 73 - 0 - 72 - 2 - 10 -1.324257241032597 - 20 -0.3255607991203732 - 40 -0.2754036673203588 - 50 -5.350003779949623 - 51 -13.38950403845408 - 73 - 0 - 72 - 2 - 10 -1.438822228558409 - 20 -0.2978741757969074 - 40 -0.1575418848528459 - 50 -13.24247481022855 - 51 -24.9143339913515 - 73 - 0 - 72 - 2 - 10 -1.49750166023149 - 20 -0.2704935387993822 - 40 -0.0927888674313809 - 50 -24.84449572776879 - 51 -41.46851456153187 - 73 - 0 - 72 - 2 - 10 -1.504747507691185 - 20 -0.2661434323058319 - 40 -0.0844927447051385 - 50 -42.51194694689715 - 51 -60.20982750498259 - 73 - 0 - 72 - 2 - 10 -1.484241834436404 - 20 -0.3022559330899828 - 40 -0.1260208208552944 - 50 -60.27608629427618 - 51 -73.82705129133484 - 73 - 0 - 72 - 2 - 10 -1.461143797848464 - 20 -0.3806703565348255 - 40 -0.2077659731176355 - 50 -73.73258141531123 - 51 -83.43685270361343 - 73 - 0 - 72 - 2 - 10 -1.444981387538941 - 20 -0.5159994031828512 - 40 -0.3440559769484268 - 50 -83.33882871764017 - 51 -90.26983081888446 - 73 - 0 - 72 - 2 - 10 -1.441836581268094 - 20 -0.4848621958152928 - 40 -0.3129186678351786 - 50 -89.72086066320244 - 51 -97.22714964633519 - 73 - 0 - 72 - 2 - 10 -1.426768810557204 - 20 -0.3683000729345016 - 40 -0.1953872384683834 - 50 -97.14382290172345 - 51 -107.4222425802834 - 73 - 0 - 72 - 2 - 10 -1.405753699036433 - 20 -0.3016738701941614 - 40 -0.1255254500273459 - 50 -107.3755052356472 - 51 -121.1859060075268 - 73 - 0 - 72 - 2 - 10 -1.388200250824436 - 20 -0.2723186857145772 - 40 -0.091323052757868 - 50 -121.3012045363258 - 51 -138.3807483919028 - 73 - 0 - 72 - 2 - 10 -1.396390386155313 - 20 -0.2780817143578742 - 40 -0.1012797862356359 - 50 -139.0208188923022 - 51 -154.2673000625914 - 73 - 0 - 72 - 2 - 10 -1.443564578953644 - 20 -0.3008357842563767 - 40 -0.153654894821596 - 50 -154.2614231301619 - 51 -165.8039007823683 - 73 - 0 - 72 - 2 - 10 -1.533704415876427 - 20 -0.3240227080426966 - 40 -0.2467287207424286 - 50 -165.7173228384291 - 51 -174.1318325417901 - 73 - 0 - 72 - 2 - 10 -1.679452490871063 - 20 -0.3395070071807061 - 40 -0.3932964759323175 - 50 -174.0587164483615 - 51 -180.2234129253398 - 73 - 0 - 72 - 1 - 10 -1.286159004867464 - 20 -0.3410405807579851 - 11 -1.286159004867464 - 21 -0.3410405807579851 - 97 - 1 -330 -14B - 92 - 16 - 93 - 21 - 72 - 2 - 10 -1.87884778741299 - 20 -0.3051697834906549 - 40 -0.5046900079850218 - 50 -165.4581922653545 - 51 -171.0243917073363 - 73 - 1 - 72 - 2 - 10 -1.640017569701684 - 20 -0.3421119050184488 - 40 -0.2630219456806235 - 50 -170.856419407449 - 51 -179.4561773269252 - 73 - 1 - 72 - 2 - 10 -1.719600323247084 - 20 -0.3382249259339413 - 40 -0.342652316488281 - 50 -178.9325511963493 - 51 -188.0659430044691 - 73 - 1 - 72 - 2 - 10 -1.461506204624639 - 20 -0.3030699205237911 - 40 -0.0821908055767169 - 50 -189.0465869719995 - 51 -201.4429641704123 - 73 - 1 - 72 - 2 - 10 -1.425949825821255 - 20 -0.2889700547677836 - 40 -0.0439411927350844 - 50 -201.2794750422889 - 51 -220.1176890207309 - 73 - 1 - 72 - 2 - 10 -1.421375505703486 - 20 -0.2843571418367111 - 40 -0.0374752217300239 - 50 -219.2307545260716 - 51 -255.6490576647813 - 73 - 1 - 72 - 2 - 10 -1.438807477461641 - 20 -0.3811952640733502 - 40 -0.1357987619432282 - 50 -258.6520849549118 - 51 -271.3697308658793 - 73 - 1 - 72 - 2 - 10 -1.445896027874007 - 20 -0.4691190853840432 - 40 -0.2237167796028082 - 50 -269.0158770897956 - 51 -276.276357003502 - 73 - 1 - 72 - 2 - 10 -1.463387403735492 - 20 -0.2947145002894463 - 40 -0.0484744436347309 - 50 -278.2625944015626 - 51 -301.2735466815289 - 73 - 1 - 72 - 2 - 10 -1.473353916121774 - 20 -0.2781237012056268 - 40 -0.0291206023535156 - 50 -301.4591386210279 - 51 -342.6827079184787 - 73 - 1 - 72 - 2 - 10 -1.374091031750538 - 20 -0.3127659022243659 - 40 -0.1342419911030445 - 50 -341.1780241039497 - 51 -353.2229122868627 - 73 - 1 - 72 - 2 - 10 -1.232912256678613 - 20 -0.3308726804904729 - 40 -0.2765741939881523 - 50 -352.9494162843384 - 51 -360.3822505868759 - 73 - 1 - 72 - 2 - 10 -0.7248612462910731 - 20 -0.3411691780724345 - 40 -0.7846645638024572 - 50 -359.3828759745637 - 51 -363.6573187603917 - 73 - 1 - 72 - 2 - 10 -1.358304373290006 - 20 -0.3811941386031548 - 40 -0.1499590652226746 - 50 -3.834298057692314 - 51 -15.98721166096502 - 73 - 1 - 72 - 2 - 10 -1.473936824340389 - 20 -0.4156549366241289 - 40 -0.0293355637618033 - 50 -13.48613242730697 - 51 -56.84075856181408 - 73 - 1 - 72 - 2 - 10 -1.460693878894012 - 20 -0.3942253340844751 - 40 -0.054522595367914 - 50 -57.50799133160251 - 51 -77.8514521481949 - 73 - 1 - 72 - 2 - 10 -1.449551855505779 - 20 -0.3442176219715277 - 40 -0.1057558456740848 - 50 -77.65179244717869 - 51 -90.71274674017063 - 73 - 1 - 72 - 2 - 10 -1.446520818841627 - 20 -0.1669086878434607 - 40 -0.2830617955533721 - 50 -89.65275773185921 - 51 -94.33247869604129 - 73 - 1 - 72 - 2 - 10 -1.430610265978255 - 20 -0.3644952794934767 - 40 -0.0848430589089613 - 50 -93.69860806412952 - 51 -104.1787730439532 - 73 - 1 - 72 - 2 - 10 -1.420228457430697 - 20 -0.4128805599428683 - 40 -0.0354338310931719 - 50 -107.0684876277999 - 51 -147.5547663680418 - 73 - 1 - 72 - 1 - 10 -1.390325682953593 - 20 -0.4318905695302117 - 11 -1.390325682953593 - 21 -0.4318905695302117 - 97 - 1 -330 -10A - 75 - 0 - 76 - 1 - 98 - 1 - 10 --0.0349603810164775 - 20 -0.1524455749140718 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -1C5 -330 -1D -100 -AcDbEntity - 8 -TEXT-RED -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 2 - 92 - 1 - 93 - 17 - 72 - 1 - 10 -1.658111534794044 - 20 -0.1752767944487085 - 11 -1.658111534794044 - 21 -0.6506897567371471 - 72 - 1 - 10 -1.658111534794044 - 20 -0.6506897567371471 - 11 -1.862892353206713 - 21 -0.6506897567371471 - 72 - 2 - 10 -1.866712771298765 - 20 -0.4812885811102773 - 40 -0.1694442501183315 - 50 -268.7080565864779 - 51 -289.696280270266 - 73 - 0 - 72 - 2 - 10 -1.890323704356795 - 20 -0.5498088066581733 - 40 -0.0969791362784035 - 50 -290.2068256429989 - 51 -320.7179581453081 - 73 - 0 - 72 - 2 - 10 -1.872231214265821 - 20 -0.5377375192902893 - 40 -0.1186450067238793 - 50 -321.7376468722154 - 51 -345.941318148983 - 73 - 0 - 72 - 2 - 10 -1.755413737650509 - 20 -0.5077074919349243 - 40 -0.239259448802611 - 50 -345.7608112632561 - 51 -360.8993727822122 - 73 - 0 - 72 - 2 - 10 -1.739929769421669 - 20 -0.4990316766439469 - 40 -0.2547614597035357 - 50 -358.8933548673149 - 51 -375.1421636632072 - 73 - 0 - 72 - 2 - 10 -1.805070643979139 - 20 -0.4843830829172414 - 40 -0.1880777885766737 - 50 -16.01826700445136 - 51 -24.59137858751017 - 73 - 0 - 72 - 2 - 10 -1.886457278838033 - 20 -0.4467408832612785 - 40 -0.098409106202089 - 50 -24.38210075542359 - 51 -37.59560803165674 - 73 - 0 - 72 - 2 - 10 -1.901447144532471 - 20 -0.4366823005906129 - 40 -0.0804040955571766 - 50 -38.43315571073376 - 51 -67.41262732859074 - 73 - 0 - 72 - 2 - 10 -1.877530541683213 - 20 -0.482621245957908 - 40 -0.1320800191028363 - 50 -65.48738102872184 - 51 -90.78391246376287 - 73 - 0 - 72 - 2 - 10 -1.89658449370416 - 20 -1.061679540017775 - 40 -0.711431865658397 - 50 -91.68029910103571 - 51 -97.60098612101147 - 73 - 0 - 72 - 2 - 10 -2.098301318614009 - 20 -2.918534187606983 - 40 -2.579056963876972 - 50 -96.58637858697409 - 51 -97.45141278012369 - 73 - 0 - 72 - 2 - 10 -1.776013741879782 - 20 -0.4823678310216308 - 40 -0.1217217342158525 - 50 -95.74213501202033 - 51 -102.7219939836472 - 73 - 0 - 72 - 1 - 10 -1.749208100737245 - 20 -0.3636343556094617 - 11 -1.749208100737245 - 21 -0.1752767944487085 - 72 - 1 - 10 -1.749208100737245 - 20 -0.1752767944487085 - 11 -1.658111534794044 - 21 -0.1752767944487085 - 72 - 1 - 10 -1.658111534794044 - 20 -0.1752767944487085 - 11 -1.658111534794044 - 21 -0.1752767944487085 - 97 - 1 -330 -138 - 92 - 16 - 93 - 12 - 72 - 1 - 10 -1.855753791898883 - 20 -0.5703040769182958 - 11 -1.749208100737245 - 21 -0.5703040769182958 - 72 - 1 - 10 -1.749208100737245 - 20 -0.5703040769182958 - 11 -1.749208100737245 - 21 -0.4311767133994287 - 72 - 1 - 10 -1.749208100737245 - 20 -0.4311767133994287 - 11 -1.855281946695168 - 21 -0.4311767133994287 - 72 - 2 - 10 -1.857310696196809 - 20 -0.4789795547126073 - 40 -0.0478458719447492 - 50 -267.5698291459668 - 51 -298.9736848744403 - 73 - 1 - 72 - 2 - 10 -1.864437662714773 - 20 -0.4638897212446849 - 40 -0.0312107960389064 - 50 -300.9469057674883 - 51 -325.1843100261158 - 73 - 1 - 72 - 2 - 10 -1.847208640489655 - 20 -0.4756552874383635 - 40 -0.0520734162270339 - 50 -325.3793523193102 - 51 -342.5869620344669 - 73 - 1 - 72 - 2 - 10 -1.761853469548879 - 20 -0.499095419473726 - 40 -0.1405675106851083 - 50 -343.8821453186945 - 51 -361.6888272002417 - 73 - 1 - 72 - 2 - 10 -1.771325527872711 - 20 -0.505069610767784 - 40 -0.1310471922643137 - 50 -359.1992235790916 - 51 -372.1177778779552 - 73 - 1 - 72 - 2 - 10 -1.840471280377904 - 20 -0.5202934512206887 - 40 -0.0602474495482526 - 50 -11.76645972748428 - 51 -33.49099599484823 - 73 - 1 - 72 - 2 - 10 -1.86002067419837 - 20 -0.5327033580204925 - 40 -0.0370985166555385 - 50 -34.16739135196509 - 51 -64.22988058382727 - 73 - 1 - 72 - 2 - 10 -1.856792087819456 - 20 -0.5236405260900577 - 40 -0.0466751007960158 - 50 -65.49764645855024 - 51 -91.27465994990668 - 73 - 1 - 72 - 1 - 10 -1.855753791898883 - 20 -0.5703040769182958 - 11 -1.855753791898883 - 21 -0.5703040769182958 - 97 - 1 -330 -4A - 75 - 0 - 76 - 1 - 98 - 1 - 10 --0.0349603810164775 - 20 -0.1524455749140718 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -1C6 -330 -1D -100 -AcDbEntity - 8 -TEXT-RED -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 17 - 72 - 1 - 10 -2.026516093204943 - 20 -0.5201225784624666 - 11 -2.12187448679461 - 21 -0.5201225784624666 - 72 - 1 - 10 -2.12187448679461 - 20 -0.5201225784624666 - 11 -2.181814048479542 - 21 -0.2784929327615455 - 72 - 2 - 10 -2.213922500215711 - 20 -0.2853658521330381 - 40 -0.0328357989636449 - 50 -192.0820235727047 - 51 -230.2482576268844 - 73 - 1 - 72 - 2 - 10 -2.211977736162895 - 20 -0.2865212844941371 - 40 -0.0325572563546005 - 50 -234.1829062182941 - 51 -272.5793312178134 - 73 - 1 - 72 - 2 - 10 -2.218185855487651 - 20 -0.2662392650291758 - 40 -0.0131289140189778 - 50 -248.8223744883709 - 51 -260.6854283382104 - 73 - 1 - 72 - 1 - 10 -2.216060877781497 - 20 -0.2532834611920508 - 11 -2.285026381589124 - 21 -0.5201225784624666 - 72 - 1 - 10 -2.285026381589124 - 20 -0.5201225784624666 - 11 -2.379912929975073 - 21 -0.5201225784624666 - 72 - 1 - 10 -2.379912929975073 - 20 -0.5201225784624666 - 11 -2.2602925604266 - 21 -0.0661149499446615 - 72 - 1 - 10 -2.2602925604266 - 20 -0.0661149499446615 - 11 -2.21297105273781 - 21 -0.0 - 72 - 1 - 10 -2.21297105273781 - 20 -0.0 - 11 -2.147795531372934 - 21 -0.0 - 72 - 1 - 10 -2.147795531372934 - 20 -0.0 - 11 -2.196547795485895 - 21 -0.1752767944487085 - 72 - 2 - 10 -2.195202176373045 - 20 -0.2879880150203464 - 40 -0.1127192527190687 - 50 -89.31599859402309 - 51 -107.9604459396842 - 73 - 0 - 72 - 2 - 10 -2.187860498124107 - 20 -0.2632664971382323 - 40 -0.0869408911919764 - 50 -108.3817089051841 - 51 -130.5609495896915 - 73 - 0 - 72 - 2 - 10 -2.198002807128255 - 20 -0.2736653212156158 - 40 -0.101440520082671 - 50 -131.0937856248721 - 51 -151.0996267706195 - 73 - 0 - 72 - 2 - 10 -2.251259362016389 - 20 -0.3028621870346081 - 40 -0.1621751716283119 - 50 -151.1623473832895 - 51 -165.7835266974244 - 73 - 0 - 72 - 1 - 10 -2.094050840588399 - 20 -0.2630342184309034 - 11 -2.026516093204943 - 21 -0.5201225784624666 - 72 - 1 - 10 -2.026516093204943 - 20 -0.5201225784624666 - 11 -2.026516093204943 - 21 -0.5201225784624666 - 97 - 1 -330 -89 - 75 - 0 - 76 - 1 - 98 - 1 - 10 --0.0349603810164775 - 20 -0.1524455749140718 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -1C7 -330 -1D -100 -AcDbEntity - 8 -TEXT-RED -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 23 - 72 - 1 - 10 -2.401085080890193 - 20 -0.451391475175396 - 11 -2.401085080890193 - 21 -0.502049385078848 - 72 - 1 - 10 -2.401085080890193 - 20 -0.502049385078848 - 11 -2.456975906310984 - 21 -0.5208364345932495 - 72 - 1 - 10 -2.456975906310984 - 20 -0.5208364345932495 - 11 -2.471953186325706 - 21 -0.6169178168015124 - 72 - 1 - 10 -2.471953186325706 - 20 -0.6169178168015124 - 11 -2.547828939245814 - 21 -0.6169178168015124 - 72 - 1 - 10 -2.547828939245814 - 20 -0.6169178168015124 - 11 -2.547828939245814 - 21 -0.5208364345932495 - 72 - 1 - 10 -2.547828939245814 - 20 -0.5208364345932495 - 11 -2.625120227777072 - 21 -0.5208364345932495 - 72 - 1 - 10 -2.625120227777072 - 20 -0.5208364345932495 - 11 -2.625120227777072 - 21 -0.451391475175396 - 72 - 1 - 10 -2.625120227777072 - 20 -0.451391475175396 - 11 -2.547828939245814 - 21 -0.451391475175396 - 72 - 1 - 10 -2.547828939245814 - 20 -0.451391475175396 - 11 -2.547828939245814 - 21 -0.312977967787312 - 72 - 2 - 10 -2.756375078424425 - 20 -0.3106349819782397 - 40 -0.208559300317214 - 50 -179.3563172584847 - 51 -187.5204775666663 - 73 - 1 - 72 - 2 - 10 -2.610407599922477 - 20 -0.2901879066221412 - 40 -0.0611824171745163 - 50 -186.4276465021346 - 51 -204.9884326299174 - 73 - 1 - 72 - 2 - 10 -2.591486060141609 - 20 -0.2832478516776391 - 40 -0.0411355950463604 - 50 -207.3607300982318 - 51 -249.4822289731461 - 73 - 1 - 72 - 2 - 10 -2.925871745813213 - 20 -1.236527392855755 - 40 -1.05135264976578 - 50 -250.6239679589966 - 51 -252.369953071448 - 73 - 1 - 72 - 2 - 10 -2.632025513918952 - 20 -0.3027146749676596 - 40 -0.0724554546479011 - 50 -250.172060625216 - 51 -260.9268652271251 - 73 - 1 - 72 - 1 - 10 -2.620599646309214 - 20 -0.2311657933719365 - 11 -2.620599646309214 - 21 -0.1752767944487085 - 72 - 1 - 10 -2.620599646309214 - 20 -0.1752767944487085 - 11 -2.541405756150071 - 21 -0.1752767944487085 - 72 - 2 - 10 -2.539541691321775 - 20 -0.2586536504670411 - 40 -0.0833976909583584 - 50 -88.71924580725035 - 51 -114.8723068619946 - 73 - 0 - 72 - 2 - 10 -2.534259066943731 - 20 -0.2435901096002027 - 40 -0.0675271066805567 - 50 -116.1816665503854 - 51 -146.3117142175992 - 73 - 0 - 72 - 2 - 10 -2.571816472169667 - 20 -0.2671405893161746 - 40 -0.1118470865035182 - 50 -146.9451672649385 - 51 -168.4294027765594 - 73 - 0 - 72 - 2 - 10 -2.701886448180166 - 20 -0.2953352474010394 - 40 -0.2449337665542188 - 50 -168.070822892956 - 51 -180.7890266060776 - 73 - 0 - 72 - 1 - 10 -2.456975906310984 - 20 -0.2987081511619036 - 11 -2.456975906310984 - 21 -0.451391475175396 - 72 - 1 - 10 -2.456975906310984 - 20 -0.451391475175396 - 11 -2.401085080890193 - 21 -0.451391475175396 - 72 - 1 - 10 -2.401085080890193 - 20 -0.451391475175396 - 11 -2.401085080890193 - 21 -0.451391475175396 - 97 - 1 -330 -58 - 75 - 0 - 76 - 1 - 98 - 1 - 10 --0.0349603810164775 - 20 -0.1524455749140718 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -1C8 -330 -1D -100 -AcDbEntity - 8 -TEXT-RED -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 22 - 72 - 1 - 10 -2.66863653221009 - 20 -0.1752767944487085 - 11 -2.66863653221009 - 21 -0.6839852852251591 - 72 - 1 - 10 -2.66863653221009 - 20 -0.683985285225159 - 11 -2.758774186932835 - 21 -0.683985285225159 - 72 - 1 - 10 -2.758774186932835 - 20 -0.683985285225159 - 11 -2.758774186932835 - 21 -0.4832608134831443 - 72 - 2 - 10 -2.970884692343786 - 20 -0.1949308647558484 - 40 -0.3579455626750722 - 50 -233.6598667174819 - 51 -241.6737203338166 - 73 - 0 - 72 - 2 - 10 -2.862953103918855 - 20 -0.398321949096261 - 40 -0.1277046941848677 - 50 -241.0008951743301 - 51 -256.9710241053807 - 73 - 0 - 72 - 2 - 10 -2.867314180648163 - 20 -0.3596725627348979 - 40 -0.1664021752218955 - 50 -258.5084157090225 - 51 -270.4610700343784 - 73 - 0 - 72 - 2 - 10 -2.871155730201377 - 20 -0.4023028257494028 - 40 -0.1237918213330042 - 50 -268.8416672957483 - 51 -290.1493812176847 - 73 - 0 - 72 - 2 - 10 -2.88549439287798 - 20 -0.4438925273392474 - 40 -0.0798129708700709 - 50 -290.7705399537808 - 51 -319.3693426350027 - 73 - 0 - 72 - 2 - 10 -2.86973875277353 - 20 -0.4329212526250472 - 40 -0.0989334609539707 - 50 -320.4891190671877 - 51 -345.2499775321184 - 73 - 0 - 72 - 2 - 10 -2.778017766714932 - 20 -0.4084074663129932 - 40 -0.1938734483480787 - 50 -345.1454837561613 - 51 -360.9319474711875 - 73 - 0 - 72 - 1 - 10 -2.971865569256112 - 20 -0.4052541467398021 - 11 -2.971865569256112 - 21 -0.1752767944487085 - 72 - 1 - 10 -2.971865569256112 - 20 -0.1752767944487085 - 11 -2.881012536321281 - 21 -0.1752767944487085 - 72 - 1 - 10 -2.881012536321281 - 20 -0.1752767944487085 - 11 -2.881012536321281 - 21 -0.4064428922369056 - 72 - 2 - 10 -2.802613036220481 - 20 -0.4076912084297279 - 40 -0.0784094376294883 - 50 -359.0877849241664 - 51 -374.2114110518409 - 73 - 1 - 72 - 2 - 10 -2.840775464266772 - 20 -0.4174522933113873 - 40 -0.0390186755568009 - 50 -14.07416101436572 - 51 -38.19979694511947 - 73 - 1 - 72 - 2 - 10 -2.848474408609313 - 20 -0.4228438207727886 - 40 -0.0296388733419943 - 50 -39.21298268016682 - 51 -68.21300572178883 - 73 - 1 - 72 - 2 - 10 -2.843635884024977 - 20 -0.4091395078042849 - 40 -0.0441641298463429 - 50 -68.98305490508943 - 51 -91.1922266305568 - 73 - 1 - 72 - 2 - 10 -2.839517556631515 - 20 -0.3257194842430624 - 40 -0.1276147049428117 - 50 -88.56339333889899 - 51 -108.8133720429226 - 73 - 1 - 72 - 2 - 10 -2.853071660183995 - 20 -0.3106172986056333 - 40 -0.146497457591775 - 50 -111.9279820567162 - 51 -129.7021521663467 - 73 - 1 - 72 - 1 - 10 -2.759489565144921 - 20 -0.4233288622047228 - 11 -2.759489565144921 - 21 -0.1752767944487085 - 72 - 1 - 10 -2.759489565144921 - 20 -0.1752767944487085 - 11 -2.66863653221009 - 21 -0.1752767944487085 - 72 - 1 - 10 -2.66863653221009 - 20 -0.1752767944487085 - 11 -2.66863653221009 - 21 -0.1752767944487085 - 97 - 1 -330 -9C - 75 - 0 - 76 - 1 - 98 - 1 - 10 --0.0349603810164775 - 20 -0.1524455749140718 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -1C9 -330 -1D -100 -AcDbEntity - 8 -TEXT-RED -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 2 - 92 - 1 - 93 - 30 - 72 - 2 - 10 -3.480235470402663 - 20 -0.3472963994916086 - 40 -0.4596602087851077 - 50 -179.2201999001178 - 51 -188.5904259084221 - 73 - 0 - 72 - 2 - 10 -3.197121821548028 - 20 -0.3902535820648669 - 40 -0.1733062924357386 - 50 -188.5287545821982 - 51 -206.4053475484388 - 73 - 0 - 72 - 2 - 10 -3.11705169577316 - 20 -0.4290134848926255 - 40 -0.084357328189102 - 50 -207.0116131808711 - 51 -238.088697099355 - 73 - 0 - 72 - 2 - 10 -3.142763881177286 - 20 -0.3846155256577634 - 40 -0.1356468679361114 - 50 -238.7826076590414 - 51 -258.9445942368799 - 73 - 0 - 72 - 2 - 10 -3.174180017272777 - 20 -0.2328628655440478 - 40 -0.2906128032937941 - 50 -258.6028609455173 - 51 -270.7173423227377 - 73 - 0 - 72 - 2 - 10 -3.179378903153711 - 20 -0.2029581738044638 - 40 -0.3204985176522159 - 50 -269.7210247461867 - 51 -277.0776490133664 - 73 - 0 - 72 - 2 - 10 -3.19487528221549 - 20 -0.325267440923209 - 40 -0.1972121016147459 - 50 -276.9881545773719 - 51 -287.1581506174676 - 73 - 0 - 72 - 2 - 10 -3.216601176688156 - 20 -0.3951169191449229 - 40 -0.1240620704779073 - 50 -287.0876504098541 - 51 -300.9508770078876 - 73 - 0 - 72 - 2 - 10 -3.235041042885957 - 20 -0.4262167749073067 - 40 -0.0879070752171545 - 50 -301.0685629566362 - 51 -318.5141019927475 - 73 - 0 - 72 - 2 - 10 -3.22499564771415 - 20 -0.4193627680063226 - 40 -0.0999841621843335 - 50 -319.385148118614 - 51 -335.2909851831404 - 73 - 0 - 72 - 2 - 10 -3.166888025629801 - 20 -0.3924029450769745 - 40 -0.1640411911207218 - 50 -335.2204735203817 - 51 -346.6482421759127 - 73 - 0 - 72 - 2 - 10 -3.055624996630501 - 20 -0.3654957782609082 - 40 -0.2785109168173713 - 50 -346.5482508793785 - 51 -354.5741818072585 - 73 - 0 - 72 - 2 - 10 -2.875033671883636 - 20 -0.3475705203771616 - 40 -0.4599886939454501 - 50 -354.4784226911829 - 51 -360.2208980900725 - 73 - 0 - 72 - 2 - 10 -2.870607305357513 - 20 -0.3438838987998202 - 40 -0.4644155825717984 - 50 -359.7639661566379 - 51 -365.4367125581701 - 73 - 0 - 72 - 2 - 10 -3.058722157859415 - 20 -0.3256690965276672 - 40 -0.2754213630050057 - 50 -5.372287081245953 - 51 -13.41178733975041 - 73 - 0 - 72 - 2 - 10 -3.173279534978716 - 20 -0.2978741757969097 - 40 -0.1575418848528468 - 50 -13.24247481022931 - 51 -24.91433399135224 - 73 - 0 - 72 - 2 - 10 -3.231958966651797 - 20 -0.27049353879938 - 40 -0.0927888674313799 - 50 -24.84449572776762 - 51 -41.46851456153065 - 73 - 0 - 72 - 2 - 10 -3.239204814111471 - 20 -0.2661434323058576 - 40 -0.0844927447051714 - 50 -42.51194694690035 - 51 -60.20982750497873 - 73 - 0 - 72 - 2 - 10 -3.218699140856711 - 20 -0.3022559330899847 - 40 -0.1260208208552961 - 50 -60.27608629427653 - 51 -73.8270512913352 - 73 - 0 - 72 - 2 - 10 -3.195604909472027 - 20 -0.3806255307799783 - 40 -0.207721876247583 - 50 -73.73012549511914 - 51 -83.43439678342133 - 73 - 0 - 72 - 2 - 10 -3.179442499162505 - 20 -0.5160622385854792 - 40 -0.3441188295924385 - 50 -83.33941300651419 - 51 -90.27041510775888 - 73 - 0 - 72 - 2 - 10 -3.176297692891656 - 20 -0.4848041884129171 - 40 -0.3128606426025486 - 50 -89.72150576644664 - 51 -97.22779474957937 - 73 - 0 - 72 - 2 - 10 -3.161234488424673 - 20 -0.3682916110468403 - 40 -0.1953789369211231 - 50 -97.14435294680244 - 51 -107.4227726253624 - 73 - 0 - 72 - 2 - 10 -3.140217093781949 - 20 -0.301699006668967 - 40 -0.1255485308215694 - 50 -107.370753656409 - 51 -121.1811544282885 - 73 - 0 - 72 - 2 - 10 -3.12266212348865 - 20 -0.2723085493673603 - 40 -0.0913151827909786 - 50 -121.3053248468621 - 51 -138.3848687024391 - 73 - 0 - 72 - 2 - 10 -3.130851497778824 - 20 -0.2780987727770228 - 40 -0.1012892502687907 - 50 -139.0126872013657 - 51 -154.2591683716641 - 73 - 0 - 72 - 2 - 10 -3.178025690577206 - 20 -0.3008131945580285 - 40 -0.1536471429745666 - 50 -154.2693808990751 - 51 -165.8118585512815 - 73 - 0 - 72 - 2 - 10 -3.268168571662594 - 20 -0.3240123625755021 - 40 -0.2467269061818614 - 50 -165.7196946403268 - 51 -174.1342043436877 - 73 - 0 - 72 - 2 - 10 -3.413914363535721 - 20 -0.3395635385525735 - 40 -0.3932993037049538 - 50 -174.0504793005304 - 51 -180.2151757775018 - 73 - 0 - 72 - 1 - 10 -3.020617833369073 - 20 -0.3410405807579851 - 11 -3.020617833369073 - 21 -0.3410405807579851 - 97 - 1 -330 -EA - 92 - 16 - 93 - 21 - 72 - 2 - 10 -3.613312704239808 - 20 -0.3052010939876257 - 40 -0.5046836205998101 - 50 -165.4616764010741 - 51 -171.0278758430559 - 73 - 1 - 72 - 2 - 10 -3.374482486528501 - 20 -0.3420916614133984 - 40 -0.2630236606104225 - 50 -170.85201298578 - 51 -179.4517709052564 - 73 - 1 - 72 - 2 - 10 -3.454065240073902 - 20 -0.3382439821810626 - 40 -0.3426534838299237 - 50 -178.9357418182288 - 51 -188.0691336263486 - 73 - 1 - 72 - 2 - 10 -3.195968077288853 - 20 -0.3030278751539043 - 40 -0.0821796951545775 - 50 -189.0181381128171 - 51 -201.4145153112299 - 73 - 1 - 72 - 2 - 10 -3.160411698485469 - 20 -0.2889975802415061 - 40 -0.0439554436806379 - 50 -201.3107480863471 - 51 -220.1489620647889 - 73 - 1 - 72 - 2 - 10 -3.155835095245747 - 20 -0.2843363205812091 - 40 -0.037456749731058 - 50 -219.2127101386138 - 51 -255.6310132773234 - 73 - 1 - 72 - 2 - 10 -3.173261739719343 - 20 -0.3812089223380726 - 40 -0.1358124526943521 - 50 -258.6525891616267 - 51 -271.3702350725942 - 73 - 1 - 72 - 2 - 10 -3.180357139497569 - 20 -0.4692030529375931 - 40 -0.2238008263021876 - 50 -269.0148826539333 - 51 -276.2753625676396 - 73 - 1 - 72 - 2 - 10 -3.197849276399706 - 20 -0.2946920674583943 - 40 -0.0484529004947375 - 50 -278.2717501461559 - 51 -301.2827024261222 - 73 - 1 - 72 - 2 - 10 -3.207811222542081 - 20 -0.2781237012056277 - 40 -0.0291206023535162 - 50 -301.4591386210265 - 51 -342.6827079184772 - 73 - 1 - 72 - 2 - 10 -3.108548338170845 - 20 -0.3127659022243659 - 40 -0.1342419911030445 - 50 -341.1780241039497 - 51 -353.2229122868627 - 73 - 1 - 72 - 2 - 10 -2.967369563098919 - 20 -0.330872680490466 - 40 -0.2765741939881519 - 50 -352.9494162843399 - 51 -360.3822505868774 - 73 - 1 - 72 - 2 - 10 -2.459318552711379 - 20 -0.3411691780724464 - 40 -0.7846645638024574 - 50 -359.3828759745628 - 51 -363.6573187603909 - 73 - 1 - 72 - 2 - 10 -3.092761679710313 - 20 -0.3811941386031558 - 40 -0.1499590652226746 - 50 -3.834298057691928 - 51 -15.98721166096461 - 73 - 1 - 72 - 2 - 10 -3.208394130760695 - 20 -0.4156549366241278 - 40 -0.029335563761804 - 50 -13.48613242730889 - 51 -56.84075856181601 - 73 - 1 - 72 - 2 - 10 -3.195154229476923 - 20 -0.3942423008569769 - 40 -0.0545066495896497 - 50 -57.50110974384233 - 51 -77.84457056043473 - 73 - 1 - 72 - 2 - 10 -3.184009922966737 - 20 -0.344171085093621 - 40 -0.1058024453263516 - 50 -77.65436364628005 - 51 -90.71531793927198 - 73 - 1 - 72 - 2 - 10 -3.180978125261934 - 20 -0.1670204385423348 - 40 -0.2829500192598661 - 50 -89.65354521146901 - 51 -94.33326617565109 - 73 - 1 - 72 - 2 - 10 -3.165070616561166 - 20 -0.3644786832754941 - 40 -0.084859522413094 - 50 -93.69685967486203 - 51 -104.1770246546857 - 73 - 1 - 72 - 2 - 10 -3.15468956905426 - 20 -0.4128867508985087 - 40 -0.0354285831761041 - 50 -107.0749560136262 - 51 -147.5612347538681 - 73 - 1 - 72 - 1 - 10 -3.124789077699108 - 20 -0.4318905695302117 - 11 -3.124789077699108 - 21 -0.4318905695302117 - 97 - 1 -330 -121 - 75 - 0 - 76 - 1 - 98 - 1 - 10 --0.0349603810164775 - 20 -0.1524455749140718 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -HATCH - 5 -1CA -330 -1D -100 -AcDbEntity - 8 -TEXT-RED -100 -AcDbHatch - 10 -0.0 - 20 -0.0 - 30 -0.0 -210 -0.0 -220 -0.0 -230 -1.0 - 2 -SOLID - 70 - 1 - 71 - 1 - 91 - 1 - 92 - 1 - 93 - 22 - 72 - 2 - 10 -3.592005824568463 - 20 -0.4022623702532142 - 40 -0.1238324225952604 - 50 -268.8385251676425 - 51 -290.1462390895788 - 73 - 0 - 72 - 2 - 10 -3.606344487245067 - 20 -0.4439223854568978 - 40 -0.0797877541011788 - 50 -290.7832534290268 - 51 -319.3820561102488 - 73 - 0 - 72 - 2 - 10 -3.590581236734105 - 20 -0.4329212526250472 - 40 -0.0989334609539707 - 50 -320.4891190671877 - 51 -345.2499775321184 - 73 - 0 - 72 - 2 - 10 -3.498860250675552 - 20 -0.4084074663130021 - 40 -0.1938734483480326 - 50 -345.1454837561604 - 51 -360.9319474711903 - 73 - 0 - 72 - 1 - 10 -3.692708053216686 - 20 -0.4052541467398021 - 11 -3.692708053216686 - 21 -0.1752767944487085 - 72 - 1 - 10 -3.692708053216686 - 20 -0.1752767944487085 - 11 -3.601870241094878 - 21 -0.1752767944487085 - 72 - 1 - 10 -3.601870241094878 - 20 -0.1752767944487085 - 11 -3.601870241094878 - 21 -0.4064428922369056 - 72 - 2 - 10 -3.523463130587567 - 20 -0.4076338796510298 - 40 -0.0784161554089863 - 50 -359.1297561618085 - 51 -374.2533822894829 - 73 - 1 - 72 - 2 - 10 -3.561625558633858 - 20 -0.4174879054254667 - 40 -0.0390026472343202 - 50 -14.02613509500026 - 51 -38.15177102575402 - 73 - 1 - 72 - 2 - 10 -3.569324502976398 - 20 -0.4228143935386817 - 40 -0.029663379390137 - 50 -39.24772886833219 - 51 -68.2477519099542 - 73 - 1 - 72 - 2 - 10 -3.564485978392062 - 20 -0.4091782819430569 - 40 -0.0441252062777969 - 50 -68.97422263922098 - 51 -91.18339436468834 - 73 - 1 - 72 - 2 - 10 -3.560375261405112 - 20 -0.3257194842430623 - 40 -0.1276147049428117 - 50 -88.56339333889899 - 51 -108.8133720429226 - 73 - 1 - 72 - 2 - 10 -3.573921754551081 - 20 -0.3105686277924473 - 40 -0.1465397674015583 - 50 -111.9181151967782 - 51 -129.6922853064086 - 73 - 1 - 72 - 1 - 10 -3.480332049105495 - 20 -0.4233288622047228 - 11 -3.480332049105495 - 21 -0.1752767944487085 - 72 - 1 - 10 -3.480332049105495 - 20 -0.1752767944487085 - 11 -3.389479016170664 - 21 -0.1752767944487085 - 72 - 1 - 10 -3.389479016170664 - 20 -0.1752767944487085 - 11 -3.389479016170664 - 21 -0.5201225784624666 - 72 - 1 - 10 -3.389479016170664 - 20 -0.5201225784624666 - 11 -3.462264944047086 - 21 -0.5201225784624666 - 72 - 1 - 10 -3.462264944047086 - 20 -0.5201225784624666 - 11 -3.480332049105495 - 21 -0.4832608134831443 - 72 - 2 - 10 -3.692032830344103 - 20 -0.1968176418438357 - 40 -0.3561838168078713 - 50 -233.5331050519283 - 51 -241.6403323622616 - 73 - 0 - 72 - 2 - 10 -3.581912438010629 - 20 -0.4042431550954748 - 40 -0.1213560014894028 - 50 -240.8735520743203 - 51 -257.5360464861715 - 73 - 0 - 72 - 2 - 10 -3.587849834142919 - 20 -0.3698286725878678 - 40 -0.1562493464094038 - 50 -258.1337893490277 - 51 -270.603548530042 - 73 - 0 - 72 - 1 - 10 -3.589495720107105 - 20 -0.5260693501105883 - 11 -3.589495720107105 - 21 -0.5260693501105883 - 97 - 1 -330 -71 - 75 - 0 - 76 - 1 - 98 - 1 - 10 --0.0349603810164775 - 20 -0.1524455749140718 -1001 -ACAD -1010 -0.0 -1020 -0.0 -1030 -0.0 - 0 -ENDSEC - 0 -SECTION - 2 -OBJECTS - 0 -DICTIONARY - 5 -C -330 -0 -100 -AcDbDictionary -281 - 1 - 3 -ACAD_DETAILVIEWSTYLE -350 -1D4 - 3 -ACAD_GROUP -350 -D - 3 -ACAD_IMAGE_VARS -350 -1B2 - 3 -ACAD_LAYOUT -350 -1A - 3 -ACAD_MLINESTYLE -350 -17 - 3 -ACAD_PLOTSETTINGS -350 -19 - 3 -ACAD_PLOTSTYLENAME -350 -E - 3 -ACAD_SCALELIST -350 -16B - 3 -ACAD_SECTIONVIEWSTYLE -350 -1D5 - 3 -AcDbVariableDictionary -350 -1CF - 3 -APPDATA -350 -1B0 - 3 -DWGPROPS -350 -1D6 - 0 -DICTIONARY - 5 -1B3 -330 -2 -100 -AcDbDictionary -280 - 1 -281 - 1 - 3 -ACAD_LAYERSTATES -360 -1B4 - 3 -ACLYDICTIONARY -360 -1BB - 0 -DICTIONARY - 5 -1D4 -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 0 -DICTIONARY - 5 -D -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 0 -RASTERVARIABLES - 5 -1B2 -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbRasterVariables - 90 - 0 - 70 - 1 - 71 - 1 - 72 - 0 - 0 -DICTIONARY - 5 -1A -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 3 -Model -350 -1E - 3 -Sheet 1 -350 -1C - 0 -DICTIONARY - 5 -17 -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 3 -Standard -350 -18 - 0 -DICTIONARY - 5 -19 -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 0 -ACDBDICTIONARYWDFLT - 5 -E -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 3 -Normal -350 -F -100 -AcDbDictionaryWithDefault -340 -F - 0 -DICTIONARY - 5 -16B -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 3 -A0 -350 -16C - 3 -A1 -350 -16D - 3 -A2 -350 -16E - 3 -A3 -350 -16F - 3 -A4 -350 -170 - 3 -A5 -350 -171 - 3 -A6 -350 -172 - 3 -A7 -350 -173 - 3 -A8 -350 -174 - 3 -A9 -350 -175 - 3 -B0 -350 -176 - 3 -B1 -350 -177 - 3 -B2 -350 -178 - 3 -B3 -350 -179 - 3 -B4 -350 -17A - 3 -B5 -350 -17B - 3 -B6 -350 -17C - 3 -B7 -350 -17D - 3 -B8 -350 -17E - 3 -B9 -350 -17F - 3 -C0 -350 -180 - 3 -C1 -350 -181 - 3 -C2 -350 -182 - 3 -C3 -350 -183 - 3 -C4 -350 -184 - 3 -C5 -350 -185 - 3 -C6 -350 -186 - 3 -C7 -350 -187 - 3 -C8 -350 -188 - 3 -C9 -350 -189 - 3 -D0 -350 -18A - 3 -D1 -350 -18B - 3 -D2 -350 -18C - 0 -DICTIONARY - 5 -1D5 -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 0 -DICTIONARY - 5 -1CF -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 0 -DICTIONARY - 5 -1B0 -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbDictionary -281 - 1 - 0 -XRECORD - 5 -1D6 -102 -{ACAD_REACTORS -330 -C -102 -} -330 -C -100 -AcDbXrecord -280 - 1 - 1 -DWGPROPS COOKIE - 2 -vector-text - 3 - - 4 -Jonathan Greig - 6 -Generated outlines with CNCFontFab using the "Exo Bold" font. - 7 -MicroPython Text - 8 - - 9 - -300 -= -301 -= -302 -= -303 -= -304 -= -305 -= -306 -= -307 -= -308 -= -309 -= - 40 -0.0 - 41 -2456662.519745903 - 42 -2456662.532164352 - 1 - - 90 - 0 - 0 -DICTIONARY - 5 -1B4 -102 -{ACAD_REACTORS -330 -1B3 -102 -} -330 -1B3 -100 -AcDbDictionary -281 - 1 - 3 -ARGON_LAYERP_1 -350 -1B5 - 3 -ARGON_LAYERP_2 -350 -1B8 - 3 -ARGON_LAYERP_3 -350 -1C3 - 0 -DICTIONARY - 5 -1BB -102 -{ACAD_REACTORS -330 -1B3 -102 -} -330 -1B3 -100 -AcDbDictionary -281 - 1 -1001 -ACAD -1000 - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/main.c b/main.c new file mode 100755 index 00000000000..6b56f5ff6fc --- /dev/null +++ b/main.c @@ -0,0 +1,499 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016-2017 Scott Shawcroft for Adafruit Industries + * + * 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 +#include + +#include "extmod/vfs.h" +#include "extmod/vfs_fat.h" + +#include "genhdr/mpversion.h" +#include "py/nlr.h" +#include "py/compile.h" +#include "py/frozenmod.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "py/repl.h" +#include "py/gc.h" +#include "py/stackctrl.h" + +#include "lib/mp-readline/readline.h" +#include "lib/utils/pyexec.h" + +#include "background.h" +#include "mpconfigboard.h" +#include "supervisor/cpu.h" +#include "supervisor/memory.h" +#include "supervisor/port.h" +#include "supervisor/filesystem.h" +#include "supervisor/shared/autoreload.h" +#include "supervisor/shared/translate.h" +#include "supervisor/shared/rgb_led_status.h" +#include "supervisor/shared/safe_mode.h" +#include "supervisor/shared/status_leds.h" +#include "supervisor/shared/stack.h" +#include "supervisor/serial.h" + +#if CIRCUITPY_DISPLAYIO +#include "shared-module/displayio/__init__.h" +#endif + +#if CIRCUITPY_NETWORK +#include "shared-module/network/__init__.h" +#endif + +#if CIRCUITPY_BOARD +#include "shared-module/board/__init__.h" +#endif + +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) { + //printf("MemoryError: lexer could not allocate memory\n"); + 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); + } +} + +void start_mp(supervisor_allocation* heap) { + reset_status_led(); + autoreload_stop(); + + background_tasks_reset(); + + // Stack limit should be less than real stack size, so we have a chance + // to recover from limit hit. (Limit is measured in bytes.) + mp_stack_ctrl_init(); + mp_stack_set_limit(stack_alloc->length - 1024); + +#if MICROPY_MAX_STACK_USAGE + // _ezero (same as _ebss) is an int, so start 4 bytes above it. + mp_stack_set_bottom(stack_alloc->ptr); + mp_stack_fill_with_sentinel(); +#endif + + // Sync the file systems in case any used RAM from the GC to cache. As soon + // as we re-init the GC all bets are off on the cache. + filesystem_flush(); + + // Clear the readline history. It references the heap we're about to destroy. + readline_init0(); + + #if MICROPY_ENABLE_GC + gc_init(heap->ptr, heap->ptr + heap->length / 4); + #endif + mp_init(); + mp_obj_list_init(mp_sys_path, 0); + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_)); + // Frozen modules are in their own pseudo-dir, e.g., ".frozen". + // Prioritize .frozen over /lib. + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_FROZEN_FAKE_DIR_QSTR)); + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); + + mp_obj_list_init(mp_sys_argv, 0); + + #if CIRCUITPY_NETWORK + network_module_init(); + #endif +} + +void stop_mp(void) { + #if CIRCUITPY_NETWORK + network_module_deinit(); + #endif + + #if MICROPY_VFS + mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); + + // Unmount all heap allocated vfs mounts. + while (gc_nbytes(vfs) > 0) { + vfs = vfs->next; + } + MP_STATE_VM(vfs_mount_table) = vfs; + MP_STATE_VM(vfs_cur) = vfs; + #endif + + gc_deinit(); +} + +#define STRING_LIST(...) {__VA_ARGS__, ""} + +// Look for the first file that exists in the list of filenames, using mp_import_stat(). +// Return its index. If no file found, return -1. +const char* first_existing_file_in_list(const char ** filenames) { + for (int i = 0; filenames[i] != (char*)""; i++) { + mp_import_stat_t stat = mp_import_stat(filenames[i]); + if (stat == MP_IMPORT_STAT_FILE) { + return filenames[i]; + } + } + return NULL; +} + +bool maybe_run_list(const char ** filenames, pyexec_result_t* exec_result) { + const char* filename = first_existing_file_in_list(filenames); + if (filename == NULL) { + return false; + } + mp_hal_stdout_tx_str(filename); + const compressed_string_t* compressed = translate(" output:\n"); + char decompressed[compressed->length]; + decompress(compressed, decompressed); + mp_hal_stdout_tx_str(decompressed); + pyexec_file(filename, exec_result); + return true; +} + +void cleanup_after_vm(supervisor_allocation* heap) { + // Turn off the display and flush the fileystem before the heap disappears. + #if CIRCUITPY_DISPLAYIO + reset_displays(); + #endif + filesystem_flush(); + stop_mp(); + free_memory(heap); + supervisor_move_memory(); + + reset_port(); + #if CIRCUITPY_BOARD + reset_board_busses(); + #endif + reset_board(); + reset_status_led(); +} + +bool run_code_py(safe_mode_t safe_mode) { + bool serial_connected_at_start = serial_connected(); + #ifdef CIRCUITPY_AUTORELOAD_DELAY_MS + if (serial_connected_at_start) { + serial_write("\n"); + if (autoreload_is_enabled()) { + serial_write_compressed(translate("Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\n")); + } else if (safe_mode != NO_SAFE_MODE) { + serial_write_compressed(translate("Running in safe mode! Auto-reload is off.\n")); + } else if (!autoreload_is_enabled()) { + serial_write_compressed(translate("Auto-reload is off.\n")); + } + } + #endif + + pyexec_result_t result; + + result.return_code = 0; + result.exception_type = NULL; + result.exception_line = 0; + + bool found_main = false; + + if (safe_mode != NO_SAFE_MODE) { + serial_write_compressed(translate("Running in safe mode! Not running saved code.\n")); + } else { + new_status_color(MAIN_RUNNING); + + static const char *supported_filenames[] = STRING_LIST("code.txt", "code.py", "main.py", "main.txt"); + static const char *double_extension_filenames[] = STRING_LIST("code.txt.py", "code.py.txt", "code.txt.txt","code.py.py", + "main.txt.py", "main.py.txt", "main.txt.txt","main.py.py"); + + stack_resize(); + filesystem_flush(); + supervisor_allocation* heap = allocate_remaining_memory(); + start_mp(heap); + found_main = maybe_run_list(supported_filenames, &result); + if (!found_main){ + found_main = maybe_run_list(double_extension_filenames, &result); + if (found_main) { + serial_write_compressed(translate("WARNING: Your code filename has two extensions\n")); + } + } + cleanup_after_vm(heap); + + if (result.return_code & PYEXEC_FORCED_EXIT) { + return reload_requested; + } + } + + // Wait for connection or character. + if (!serial_connected_at_start) { + serial_write_compressed(translate("\nCode done running. Waiting for reload.\n")); + } + + bool serial_connected_before_animation = false; + #if CIRCUITPY_DISPLAYIO + bool refreshed_epaper_display = false; + #endif + rgb_status_animation_t animation; + prep_rgb_status_animation(&result, found_main, safe_mode, &animation); + while (true) { + #ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP + #endif + if (reload_requested) { + reload_requested = false; + return true; + } + + if (serial_connected() && serial_bytes_available()) { + // Skip REPL if reload was requested. + return (serial_read() == CHAR_CTRL_D); + } + + if (!serial_connected_before_animation && serial_connected()) { + if (serial_connected_at_start) { + serial_write("\n\n"); + } + + if (!serial_connected_at_start) { + if (autoreload_is_enabled()) { + serial_write_compressed(translate("Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\n")); + } else { + serial_write_compressed(translate("Auto-reload is off.\n")); + } + } + print_safe_mode_message(safe_mode); + serial_write("\n"); + serial_write_compressed(translate("Press any key to enter the REPL. Use CTRL-D to reload.")); + } + if (serial_connected_before_animation && !serial_connected()) { + serial_connected_at_start = false; + } + serial_connected_before_animation = serial_connected(); + + // Refresh the ePaper display if we have one. That way it'll show an error message. + #if CIRCUITPY_DISPLAYIO + if (!refreshed_epaper_display) { + refreshed_epaper_display = maybe_refresh_epaperdisplay(); + } + #endif + + tick_rgb_status_animation(&animation); + } +} + +void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { + // If not in safe mode, run boot before initing USB and capture output in a + // file. + if (filesystem_present() && safe_mode == NO_SAFE_MODE && MP_STATE_VM(vfs_mount_table) != NULL) { + static const char *boot_py_filenames[] = STRING_LIST("settings.txt", "settings.py", "boot.py", "boot.txt"); + + new_status_color(BOOT_RUNNING); + + #ifdef CIRCUITPY_BOOT_OUTPUT_FILE + FIL file_pointer; + boot_output_file = &file_pointer; + + // Get the base filesystem. + FATFS *fs = &((fs_user_mount_t *) MP_STATE_VM(vfs_mount_table)->obj)->fatfs; + + bool have_boot_py = first_existing_file_in_list(boot_py_filenames) != NULL; + + bool skip_boot_output = false; + + // If there's no boot.py file that might write some changing output, + // read the existing copy of CIRCUITPY_BOOT_OUTPUT_FILE and see if its contents + // match the version info we would print anyway. If so, skip writing CIRCUITPY_BOOT_OUTPUT_FILE. + // This saves wear and tear on the flash and also prevents filesystem damage if power is lost + // during the write, which may happen due to bobbling the power connector or weak power. + + static const size_t NUM_CHARS_TO_COMPARE = 160; + if (!have_boot_py && f_open(fs, boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_READ) == FR_OK) { + + char file_contents[NUM_CHARS_TO_COMPARE]; + UINT chars_read = 0; + f_read(boot_output_file, file_contents, NUM_CHARS_TO_COMPARE, &chars_read); + f_close(boot_output_file); + skip_boot_output = + // + 2 accounts for \r\n. + chars_read == strlen(MICROPY_FULL_VERSION_INFO) + 2 && + strncmp(file_contents, MICROPY_FULL_VERSION_INFO, strlen(MICROPY_FULL_VERSION_INFO)) == 0; + } + + if (!skip_boot_output) { + // Wait 1.5 seconds before opening CIRCUITPY_BOOT_OUTPUT_FILE for write, + // in case power is momentary or will fail shortly due to, say a low, battery. + mp_hal_delay_ms(1500); + + // USB isn't up, so we can write the file. + filesystem_set_internal_writable_by_usb(false); + f_open(fs, boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_WRITE | FA_CREATE_ALWAYS); + + // Switch the filesystem back to non-writable by Python now instead of later, + // since boot.py might change it back to writable. + filesystem_set_internal_writable_by_usb(true); + + // Write version info to boot_out.txt. + mp_hal_stdout_tx_str(MICROPY_FULL_VERSION_INFO); + mp_hal_stdout_tx_str("\r\n"); + } + #endif + + // TODO(tannewt): Allocate temporary space to hold custom usb descriptors. + filesystem_flush(); + supervisor_allocation* heap = allocate_remaining_memory(); + start_mp(heap); + + // TODO(tannewt): Re-add support for flashing boot error output. + bool found_boot = maybe_run_list(boot_py_filenames, NULL); + (void) found_boot; + + #ifdef CIRCUITPY_BOOT_OUTPUT_FILE + if (!skip_boot_output) { + f_close(boot_output_file); + filesystem_flush(); + } + boot_output_file = NULL; + #endif + + cleanup_after_vm(heap); + } +} + +int run_repl(void) { + int exit_code = PYEXEC_FORCED_EXIT; + stack_resize(); + filesystem_flush(); + supervisor_allocation* heap = allocate_remaining_memory(); + start_mp(heap); + autoreload_suspend(); + new_status_color(REPL_RUNNING); + if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { + exit_code = pyexec_raw_repl(); + } else { + exit_code = pyexec_friendly_repl(); + } + cleanup_after_vm(heap); + autoreload_resume(); + return exit_code; +} + +int __attribute__((used)) main(void) { + memory_init(); + + // initialise the cpu and peripherals + safe_mode_t safe_mode = port_init(); + + // Turn on LEDs + init_status_leds(); + rgb_led_status_init(); + + // Wait briefly to give a reset window where we'll enter safe mode after the reset. + if (safe_mode == NO_SAFE_MODE) { + safe_mode = wait_for_safe_mode_reset(); + } + + stack_init(); + + // Create a new filesystem only if we're not in a safe mode. + // A power brownout here could make it appear as if there's + // no SPI flash filesystem, and we might erase the existing one. + filesystem_init(safe_mode == NO_SAFE_MODE, false); + + // Reset everything and prep MicroPython to run boot.py. + reset_port(); + reset_board(); + + // Turn on autoreload by default but before boot.py in case it wants to change it. + autoreload_enable(); + + // By default our internal flash is readonly to local python code and + // writable over USB. Set it here so that boot.py can change it. + filesystem_set_internal_concurrent_write_protection(true); + filesystem_set_internal_writable_by_usb(true); + + run_boot_py(safe_mode); + + // Start serial and HID after giving boot.py a chance to tweak behavior. + serial_init(); + + // Boot script is finished, so now go into REPL/main mode. + int exit_code = PYEXEC_FORCED_EXIT; + bool skip_repl = true; + bool first_run = true; + for (;;) { + if (!skip_repl) { + exit_code = run_repl(); + } + if (exit_code == PYEXEC_FORCED_EXIT) { + if (!first_run) { + serial_write_compressed(translate("soft reboot\n")); + } + first_run = false; + skip_repl = run_code_py(safe_mode); + } else if (exit_code != 0) { + break; + } + } + mp_deinit(); + return 0; +} + +void gc_collect(void) { + gc_collect_start(); + + mp_uint_t regs[10]; + mp_uint_t sp = cpu_get_regs_and_sp(regs); + + // This collects root pointers from the VFS mount table. Some of them may + // have lost their references in the VM even though they are mounted. + gc_collect_root((void**)&MP_STATE_VM(vfs_mount_table), sizeof(mp_vfs_mount_t) / sizeof(mp_uint_t)); + + #if CIRCUITPY_DISPLAYIO + displayio_gc_collect(); + #endif + + // This naively collects all object references from an approximate stack + // range. + gc_collect_root((void**)sp, ((uint32_t)&_estack - sp) / sizeof(uint32_t)); + gc_collect_end(); +} + +void NORETURN nlr_jump_fail(void *val) { + reset_into_safe_mode(MICROPY_NLR_JUMP_FAIL); + while (true) {} +} + +void NORETURN __fatal_error(const char *msg) { + reset_into_safe_mode(MICROPY_FATAL_ERROR); + while (true) {} +} + +#ifndef NDEBUG +void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) { + mp_printf(&mp_plat_print, "Assertion '%s' failed, at file %s:%d\n", expr, file, line); + __fatal_error("Assertion failed"); +} +#endif diff --git a/mpy-cross/Makefile b/mpy-cross/Makefile index 53ce50c7ff6..42dbace9841 100644 --- a/mpy-cross/Makefile +++ b/mpy-cross/Makefile @@ -14,7 +14,13 @@ endif include ../py/mkenv.mk # define main target + +ifeq ($(OS),Windows_NT) +# Detect a MINGW32 build, and change the name of the final executable. +PROG = mpy-cross.exe +else PROG = mpy-cross +endif # qstr definitions (must come before including py.mk) QSTR_DEFS = qstrdefsport.h @@ -35,6 +41,13 @@ CWARN += -Wpointer-arith -Wuninitialized CFLAGS = $(INC) $(CWARN) -std=gnu99 $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA) CFLAGS += -fdata-sections -ffunction-sections -fno-asynchronous-unwind-tables +# Build a static executable. +# Useful for Windows builds, etc., that must run on multiple operating system versions. +ifdef STATIC_BUILD +CFLAGS += -static -static-libgcc -static-libstdc++ +endif + + # Debugging/Optimization ifdef DEBUG CFLAGS += -g @@ -57,10 +70,17 @@ LDFLAGS_ARCH = -Wl,-Map=$@.map,--cref -Wl,--gc-sections endif LDFLAGS = $(LDFLAGS_MOD) $(LDFLAGS_ARCH) -lm $(LDFLAGS_EXTRA) +ifdef STATIC_BUILD +LDFLAGS += -static -static-libgcc -static-libstdc++ +endif + # source files SRC_C = \ main.c \ gccollect.c \ + supervisor/stub/safe_mode.c \ + supervisor/stub/stack.c \ + supervisor/shared/translate.c # Add fmode when compiling with mingw gcc COMPILER_TARGET := $(shell $(CC) -dumpmachine) diff --git a/mpy-cross/mpconfigport.h b/mpy-cross/mpconfigport.h index e227d1be548..04f9a24d5c6 100644 --- a/mpy-cross/mpconfigport.h +++ b/mpy-cross/mpconfigport.h @@ -85,6 +85,50 @@ #define MICROPY_PY_IO (0) #define MICROPY_PY_SYS (0) +// MINGW only handles these errno names. +#ifdef __MINGW32__ +#define MICROPY_PY_UERRNO_LIST \ + X(EPERM) \ + X(ENOENT) \ + X(ESRCH) \ + X(EINTR) \ + X(EIO) \ + X(ENXIO) \ + X(E2BIG) \ + X(ENOEXEC) \ + X(EBADF) \ + X(ECHILD) \ + X(EAGAIN) \ + X(ENOMEM) \ + X(EACCES) \ + X(EFAULT) \ + X(EBUSY) \ + X(EEXIST) \ + X(EXDEV) \ + X(ENODEV) \ + X(ENOTDIR) \ + X(EISDIR) \ + X(EINVAL) \ + X(ENFILE) \ + X(EMFILE) \ + X(ENOTTY) \ + X(EFBIG) \ + X(ENOSPC) \ + X(ESPIPE) \ + X(EROFS) \ + X(EMLINK) \ + X(EPIPE) \ + X(EDOM) \ + X(ERANGE) \ + X(EDEADLOCK) \ + X(EDEADLK) \ + X(ENAMETOOLONG) \ + X(ENOLCK) \ + X(ENOSYS) \ + X(ENOTEMPTY) \ + X(EILSEQ) +#endif + // type definitions for the specific machine #ifdef __LP64__ diff --git a/ports/atmel-samd/.gitattributes b/ports/atmel-samd/.gitattributes new file mode 100644 index 00000000000..09bba615b1c --- /dev/null +++ b/ports/atmel-samd/.gitattributes @@ -0,0 +1,2 @@ +tools/bossac* binary +asf/**/*.a binary diff --git a/ports/atmel-samd/.gitignore b/ports/atmel-samd/.gitignore new file mode 100644 index 00000000000..414487d53eb --- /dev/null +++ b/ports/atmel-samd/.gitignore @@ -0,0 +1 @@ +build-*/ diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile new file mode 100644 index 00000000000..11e6874edd6 --- /dev/null +++ b/ports/atmel-samd/Makefile @@ -0,0 +1,331 @@ +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# Copyright (c) 2019 Dan Halbert for Adafruit Industries +# +# 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. + +# Select the board to build for. +ifeq ($(BOARD),) + $(error You must provide a BOARD parameter) +else + ifeq ($(wildcard boards/$(BOARD)/.),) + $(error Invalid BOARD specified) + endif +endif + +# If the build directory is not given, make it reflect the board name. +BUILD ?= build-$(BOARD) + +include ../../py/mkenv.mk +# Board-specific +include boards/$(BOARD)/mpconfigboard.mk +# Port-specific +include mpconfigport.mk +# CircuitPython-specific +include $(TOP)/py/circuitpy_mpconfig.mk + +# qstr definitions (must come before including py.mk) +QSTR_DEFS = qstrdefsport.h + +# include py core make definitions +include $(TOP)/py/py.mk + +include $(TOP)/supervisor/supervisor.mk + +# Include make rules and variables common across CircuitPython builds. +include $(TOP)/py/circuitpy_defns.mk + +CROSS_COMPILE = arm-none-eabi- + +HAL_DIR=hal/$(MCU_SERIES) + +INC += -I. \ + -I../.. \ + -I../lib/mp-readline \ + -I../lib/timeutils \ + -Iasf4/$(CHIP_FAMILY) \ + -Iasf4/$(CHIP_FAMILY)/hal/include \ + -Iasf4/$(CHIP_FAMILY)/hal/utils/include \ + -Iasf4/$(CHIP_FAMILY)/hri \ + -Iasf4/$(CHIP_FAMILY)/hpl/core \ + -Iasf4/$(CHIP_FAMILY)/hpl/gclk \ + -Iasf4/$(CHIP_FAMILY)/hpl/pm \ + -Iasf4/$(CHIP_FAMILY)/hpl/port \ + -Iasf4/$(CHIP_FAMILY)/hpl/rtc \ + -Iasf4/$(CHIP_FAMILY)/hpl/tc \ + -Iasf4/$(CHIP_FAMILY)/include \ + -Iasf4/$(CHIP_FAMILY)/CMSIS/Include \ + -Iasf4_conf/$(CHIP_FAMILY) \ + -Iboards/$(BOARD) \ + -Iboards/ \ + -Iperipherals/ \ + -Ifreetouch \ + -I../../lib/tinyusb/src \ + -I../../supervisor/shared/usb \ + -I$(BUILD) + + +# NDEBUG disables assert() statements. This reduces code size pretty dramatically, per tannewt. + +ifeq ($(CHIP_FAMILY), samd21) +CFLAGS += -Os -DNDEBUG +# TinyUSB defines +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD21 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_CDC_RX_BUFSIZE=128 -DCFG_TUD_MIDI_TX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=128 -DCFG_TUD_MSC_BUFSIZE=512 +endif + +ifeq ($(CHIP_FAMILY), samd51) +CFLAGS += -Os -DNDEBUG +# TinyUSB defines +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD51 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_CDC_RX_BUFSIZE=256 -DCFG_TUD_MIDI_TX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=256 -DCFG_TUD_MSC_BUFSIZE=1024 +endif + +#Debugging/Optimization +ifeq ($(DEBUG), 1) + CFLAGS += -ggdb + # You may want to disable -flto if it interferes with debugging. + CFLAGS += -flto -flto-partition=none + # You may want to enable these flags to make setting breakpoints easier. + # CFLAGS += -fno-inline -fno-ipa-sra + ifeq ($(CHIP_FAMILY), samd21) + CFLAGS += -DENABLE_MICRO_TRACE_BUFFER + endif +else + # -finline-limit can shrink the image size. + # -finline-limit=80 or so is similar to not having it on. + # There is no simple default value, though. + + # Do a default shrink for small builds. + ifndef CFLAGS_INLINE_LIMIT + ifeq ($(CIRCUITPY_SMALL_BUILD),1) + CFLAGS_INLINE_LIMIT = 50 + endif + endif + + ifdef CFLAGS_INLINE_LIMIT + CFLAGS += -finline-limit=$(CFLAGS_INLINE_LIMIT) + endif + CFLAGS += -flto -flto-partition=none +endif + +CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) + +ifeq ($(CHIP_FAMILY), samd21) +CFLAGS += \ + -mthumb \ + -mabi=aapcs-linux \ + -mcpu=cortex-m0plus \ + -msoft-float \ + -mfloat-abi=soft \ + -DSAMD21 +endif +ifeq ($(CHIP_FAMILY), samd51) +CFLAGS += \ + -mthumb \ + -mabi=aapcs-linux \ + -mcpu=cortex-m4 \ + -mfloat-abi=hard \ + -mfpu=fpv4-sp-d16 \ + -DSAMD51 +endif + + + +LDFLAGS = $(CFLAGS) -nostartfiles -fshort-enums -Wl,-nostdlib -Wl,-T,$(LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections -specs=nano.specs +LIBS := -lgcc -lc + +# Use toolchain libm if we're not using our own. +ifndef INTERNAL_LIBM +LIBS += -lm +endif + +ifeq ($(CHIP_FAMILY), samd21) +LDFLAGS += -mthumb -mcpu=cortex-m0plus -Lasf/thirdparty/CMSIS/Lib/GCC/ +BOOTLOADER_SIZE := 0x2000 +else ifeq ($(CHIP_FAMILY), samd51) +LDFLAGS += -mthumb -mcpu=cortex-m4 +BOOTLOADER_SIZE := 0x4000 +endif + +SRC_ASF := \ + gcc/gcc/startup_$(CHIP_FAMILY).c \ + gcc/system_$(CHIP_FAMILY).c \ + hal/src/hal_adc_sync.c \ + hal/src/hal_atomic.c \ + hal/src/hal_calendar.c \ + hal/src/hal_dac_sync.c \ + hal/src/hal_delay.c \ + hal/src/hal_flash.c \ + hal/src/hal_i2c_m_sync.c \ + hal/src/hal_io.c \ + hal/src/hal_sleep.c \ + hal/src/hal_spi_m_sync.c \ + hal/src/hal_timer.c \ + hal/src/hal_usart_async.c \ + hpl/adc/hpl_adc.c \ + hpl/core/hpl_init.c \ + hpl/dac/hpl_dac.c \ + hpl/gclk/hpl_gclk.c \ + hpl/nvmctrl/hpl_nvmctrl.c \ + hpl/pm/hpl_pm.c \ + hpl/rtc/hpl_rtc.c \ + hpl/sercom/hpl_sercom.c \ + hpl/systick/hpl_systick.c \ + hal/utils/src/utils_list.c \ + hal/utils/src/utils_ringbuffer.c \ + +ifeq ($(CHIP_FAMILY), samd21) +SRC_ASF += \ + hpl/core/hpl_core_m0plus_base.c \ + hpl/sysctrl/hpl_sysctrl.c \ + +else ifeq ($(CHIP_FAMILY), samd51) +SRC_ASF += \ + hal/src/hal_rand_sync.c \ + hpl/core/hpl_core_m4.c \ + hpl/mclk/hpl_mclk.c \ + hpl/osc32kctrl/hpl_osc32kctrl.c \ + hpl/oscctrl/hpl_oscctrl.c \ + hpl/trng/hpl_trng.c \ + +endif + +SRC_ASF := $(addprefix asf4/$(CHIP_FAMILY)/, $(SRC_ASF)) + +SRC_C = \ + audio_dma.c \ + background.c \ + bindings/samd/Clock.c \ + bindings/samd/__init__.c \ + boards/$(BOARD)/board.c \ + boards/$(BOARD)/pins.c \ + eic_handler.c \ + fatfs_port.c \ + freetouch/adafruit_ptc.c \ + lib/libc/string0.c \ + lib/mp-readline/readline.c \ + lib/oofatfs/ff.c \ + lib/oofatfs/option/ccsbcs.c \ + lib/timeutils/timeutils.c \ + lib/tinyusb/src/portable/microchip/$(CHIP_FAMILY)/dcd_$(CHIP_FAMILY).c \ + lib/utils/buffer_helper.c \ + lib/utils/context_manager_helpers.c \ + lib/utils/interrupt_char.c \ + lib/utils/pyexec.c \ + lib/utils/stdout_helpers.c \ + lib/utils/sys_stdio_mphal.c \ + mphalport.c \ + peripherals/samd/$(CHIP_FAMILY)/adc.c \ + peripherals/samd/$(CHIP_FAMILY)/cache.c \ + peripherals/samd/$(CHIP_FAMILY)/clocks.c \ + peripherals/samd/$(CHIP_FAMILY)/dma.c \ + peripherals/samd/$(CHIP_FAMILY)/events.c \ + peripherals/samd/$(CHIP_FAMILY)/external_interrupts.c \ + peripherals/samd/$(CHIP_FAMILY)/pins.c \ + peripherals/samd/$(CHIP_FAMILY)/sercom.c \ + peripherals/samd/$(CHIP_FAMILY)/timers.c \ + peripherals/samd/clocks.c \ + peripherals/samd/dma.c \ + peripherals/samd/events.c \ + peripherals/samd/external_interrupts.c \ + peripherals/samd/sercom.c \ + peripherals/samd/timers.c \ + reset.c \ + supervisor/shared/memory.c \ + tick.c \ + timer_handler.c \ + + +ifeq ($(CIRCUITPY_NETWORK),1) +CFLAGS += -DMICROPY_PY_NETWORK=1 + +SRC_MOD += lib/netutils/netutils.c + +ifneq ($(MICROPY_PY_WIZNET5K),0) +WIZNET5K_DIR=drivers/wiznet5k +INC += -I$(TOP)/$(WIZNET5K_DIR) +CFLAGS_MOD += -DMICROPY_PY_WIZNET5K=$(MICROPY_PY_WIZNET5K) -D_WIZCHIP_=$(MICROPY_PY_WIZNET5K) +SRC_MOD += $(addprefix $(WIZNET5K_DIR)/,\ + ethernet/w$(MICROPY_PY_WIZNET5K)/w$(MICROPY_PY_WIZNET5K).c \ + ethernet/wizchip_conf.c \ + ethernet/socket.c \ + internet/dns/dns.c \ + internet/dhcp/dhcp.c \ + ) + +endif # MICROPY_PY_WIZNET5K +endif # CIRCUITPY_NETWORK + +ifeq ($(CIRCUITPY_NETWORK),1) +ifneq ($(MICROPY_PY_WIZNET5K),0) +SRC_SHARED_MODULE += wiznet/__init__.c wiznet/wiznet5k.c +endif +endif + +# The smallest SAMD51 packages don't have I2S. Everything else does. +ifeq ($(CIRCUITPY_AUDIOBUSIO),1) +SRC_C += peripherals/samd/i2s.c peripherals/samd/$(CHIP_FAMILY)/i2s.c +endif + +SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ + $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ + $(addprefix common-hal/, $(SRC_COMMON_HAL)) + +SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ + $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ + $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) + +SRC_S = supervisor/$(CHIP_FAMILY)_cpu.s + +OBJ = $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_ASF:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_EXPANDED:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o)) +ifeq ($(INTERNAL_LIBM),1) +OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) +endif +OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) + +SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) +# Sources that only hold QSTRs after pre-processing. +SRC_QSTR_PREPROCESSOR += peripherals/samd/$(CHIP_FAMILY)/clocks.c + +all: $(BUILD)/firmware.bin $(BUILD)/firmware.uf2 + +$(BUILD)/firmware.elf: $(OBJ) + $(STEPECHO) "LINK $@" + $(Q)$(CC) -o $@ $(LDFLAGS) $^ -Wl,--start-group $(LIBS) -Wl,--end-group + $(Q)$(SIZE) $@ | $(PYTHON3) $(TOP)/tools/build_memory_info.py $(LD_FILE) + +$(BUILD)/firmware.bin: $(BUILD)/firmware.elf + $(STEPECHO) "Create $@" + $(Q)$(OBJCOPY) -O binary -j .vectors -j .text -j .data $^ $@ + +$(BUILD)/firmware.uf2: $(BUILD)/firmware.bin + $(STEPECHO) "Create $@" + $(Q)$(PYTHON3) $(TOP)/tools/uf2/utils/uf2conv.py -b $(BOOTLOADER_SIZE) -c -o $@ $^ + +include $(TOP)/py/mkrules.mk + +# Print out the value of a make variable. +# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile +print-%: + @echo $* = $($*) diff --git a/ports/atmel-samd/README.rst b/ports/atmel-samd/README.rst new file mode 100644 index 00000000000..9afa19b837f --- /dev/null +++ b/ports/atmel-samd/README.rst @@ -0,0 +1,245 @@ +SAMD21x18 +========= + +This port brings MicroPython to SAMD21x18 based development boards under the name +CircuitPython. Supported boards include: + +- Adafruit CircuitPlayground Express +- Adafruit Feather M0 Basic +- Adafruit Feather M0 Express +- Adafruit Metro M0 Express +- Adafruit M0 Bluefruit LE +- Arduino Zero +- Arduino MKR Zero + + +Pinout +------ + +All of the boards share the same core pin functionality but call pins by +different names. The table below matches the pin order in +`the datasheet `_ +and omits the pins only available on the largest package because all supported +boards use smaller version. + +===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================================ ====================== ================ +`microcontroller.pin` `board` +--------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Datasheet arduino_mkrzero arduino_zero circuitplayground_express feather_m0_adalogger feather_m0_basic feather_m0_express gemma_m0 metro_m0_express sparkfun_samd21_mini sparkfun_samd21_dev trinket_m0 +===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================================ ====================== ================ +PA00 ``ACCELEROMETER_SDA`` ``APA102_MOSI`` ``APA102_MOSI`` +PA01 ``ACCELEROMETER_SCL`` ``APA102_SCK`` ``APA102_SCK`` +PA02 ``A0`` ``A0`` ``A0`` / ``SPEAKER`` ``A0`` ``A0`` ``A0`` ``A0`` / ``D1`` ``A0`` ``A0`` ``A0`` ``D1`` / ``A0`` +PA03 +PB08 ``L`` ``A1`` ``A7`` / ``TX`` ``A1`` ``A1`` ``A1`` ``A1`` ``A1`` ``A1`` +PB09 ``BATTERY`` ``A2`` ``A6`` / ``RX`` ``A2`` ``A2`` ``A2`` ``A2`` ``A2`` ``A2`` +PA04 ``A3`` ``A3`` ``IR_PROXIMITY`` ``A3`` ``A3`` ``A3`` ``D0`` / ``TX`` / ``SDA`` ``A3`` ``A3`` ``A3`` +PA05 ``A4`` ``A4`` ``A1`` ``A4`` ``A4`` ``A4`` ``D2`` / ``RX`` / ``SCL`` ``A4`` ``A4`` +PA06 ``A5`` ``D8`` ``A2`` ``D8`` / ``GREEN_LED`` ``NEOPIXEL`` ``D8`` ``D8`` ``D8`` ``D4`` / ``TX`` +PA07 ``A6`` ``D9`` ``A3`` ``D9`` ``D9`` ``D9`` ``D9`` ``D9`` ``D9`` ``D3`` / ``RX`` +PA08 ``D11`` / ``SDA`` ``D4`` ``MICROPHONE_DO`` ``D4`` / ``SD_CS`` ``D4`` ``D4`` ``D4`` ``D0`` / ``SDA`` +PA09 ``D12`` / ``SCL`` ``D3`` ``TEMPERATURE`` / ``A9`` ``D3`` ``D3`` ``D3`` ``D2`` / ``SCL`` +PA10 ``D2`` ``D1`` / ``TX`` ``MICROPHONE_SCK`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D1`` / ``TX`` ``D13`` +PA11 ``D3`` ``D0`` / ``RX`` ``LIGHT`` / ``A8`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` ``D0`` / ``RX`` +PB10 ``D4`` ``MOSI`` ``MOSI`` ``MOSI`` ``MOSI`` ``MOSI`` ``MOSI`` +PB11 ``D5`` ``SCK`` ``SCK`` ``SCK`` ``SCK`` ``SCK`` ``SCK`` +PA12 ``SD_MOSI`` ``MISO`` ``REMOTEIN`` / ``IR_RX`` ``MISO`` ``MISO`` ``MISO`` ``MISO`` ``MISO`` +PA13 ``SD_SCK`` ``ACCELEROMETER_INTERRUPT`` ``FLASH_CS`` ``D38`` +PA14 ``SD_CS`` ``D2`` ``BUTTON_B`` / ``D5`` ``D2`` ``D2`` ``D2`` +PA15 ``SD_MISO`` ``D5`` ``SLIDE_SWITCH`` / ``D7`` ``D5`` ``D5`` ``D5`` ``D5`` ``D5`` ``D5`` +PA16 ``D8`` / ``MOSI`` ``D11`` ``MISO`` ``D11`` ``D11`` ``D11`` ``D11`` ``D11`` / ``MOSI`` ``D11`` +PA17 ``D9`` / ``SCK`` ``D13`` ``D13`` ``D13`` / ``RED_LED`` ``D13`` ``D13`` ``D13`` ``D13`` / ``SCK`` / ``BLUE_LED`` ``D13`` / ``BLUE_LED`` +PA18 ``D10`` ``D10`` ``D10`` ``D10`` ``D10`` ``D10`` ``D10`` +PA19 ``D10`` / ``MISO`` ``D12`` ``D12`` ``D12`` ``D12`` ``D12`` ``D12`` / ``MISO`` ``D12`` +PA20 ``D6`` ``D6`` ``MOSI`` ``D6`` ``D6`` ``D6`` ``D6`` ``D6`` ``D6`` +PA21 ``D7`` ``D7`` ``SCK`` ``D7`` / ``SD_CD`` ``D7`` ``D7`` ``D7`` +PA22 ``D0`` ``SDA`` ``SDA`` ``SDA`` ``SDA`` ``SDA`` ``SDA`` ``SDA`` +PA23 ``D1`` ``SCL`` ``REMOTEOUT`` / ``IR_TX`` ``SCL`` ``SCL`` ``SCL`` ``L`` / ``D13`` ``SCL`` ``SCL`` ``SCL`` +PA24 +PA25 +PB22 ``D14`` / ``TX`` ``FLASH_CS`` ``D30`` / ``TX1`` +PB23 ``D13`` / ``RX`` ``NEOPIXEL`` / ``D8`` ``D31`` / ``RX1`` +PA27 ``SD_CD`` ``GREEN_LED`` ``GREEN_LED`` +PA28 ``BUTTON_A`` / ``D4`` +PA29 +PA30 ``SPEAKER_ENABLE`` ``NEOPIXEL`` +PA31 +PB02 ``A1`` ``A5`` ``A5`` / ``SDA`` ``A5`` ``A5`` ``A5`` ``A5`` ``A5`` +PB03 ``A2`` ``A4`` / ``SCL`` ``YELLOW_LED`` ``YELLOW_LED`` +===================== =================== =============== =========================== ====================== ================ ================== ========================= ================ ================================ ====================== ================ + +Here is a table about which pins can do what in CircuitPython terms. However, +just because something is listed, doesn't mean it will always work. Existing use +of other pins and functionality will impact your ability to use a pin for your +desired purpose. For example, only certain combinations of SPI pins will work +because they use shared hardware internally. + +===================== ======== ========= ========= ======= ======= ======= ========= ========= ======= ========== ========== ========= ========= ========= ============ ======= ======= ========= +`microcontroller.pin` `analogio` `audioio` `bitbangio` `busio` `digitalio` `pulseio` `touchio` +--------------------- ------------------- --------- ------------------------- -------------------------------------------------------------------------------------- ------------ ---------------- --------- +Datasheet AnalogIn AnalogOut AudioOut I2C OneWire SPI I2C - SDA I2C - SCL OneWire SPI - MISO SPI - MOSI SPI - SCK UART - RX UART - TX DigitalInOut PulseIn PWMOut TouchIn +===================== ======== ========= ========= ======= ======= ======= ========= ========= ======= ========== ========== ========= ========= ========= ============ ======= ======= ========= +PA00 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA01 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA02 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA03 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PB08 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PB09 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA04 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA05 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA06 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA07 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA08 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA09 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA10 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA11 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PB10 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PB11 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA12 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA13 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA14 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA15 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA16 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA17 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA18 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA19 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA20 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA21 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA22 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA23 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA24 +PA25 +PB22 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PB23 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA27 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA28 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA29 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA30 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PA31 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PB02 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +PB03 **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** **Yes** +===================== ======== ========= ========= ======= ======= ======= ========= ========= ======= ========== ========== ========= ========= ========= ============ ======= ======= ========= + +Setup +----- + +An ARM compiler is required for the build, along with the associated binary +utilities. They can be installed as follows: + +- Ubuntu + + .. code-block:: shell + + sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa + sudo apt-get install gcc-arm-embedded + +- Arch Linux + + .. code-block:: shell + + sudo pacman -S arm-none-eabi-gcc arm-none-eabi-newlib + +For other systems, the `GNU Arm Embedded Toolchain `_ +may be available in binary form. + +The latest available package from team-gcc-arm-embedded is used to produce the +binaries shipped by AdaFruit. Other compiler versions, particularly older +ones, may not work properly. In particular, the ``gcc-arm-none-eabi`` package +in Debian Stretch is too old. + +The compiler can be changed using the ``CROSS_COMPILE`` variable when invoking +``make``. + +Building +-------- + +Before building the firmware for a given board, there are two additional steps. +These commands should be executed from the root directory of the repository +(``circuitpython/``). + +1. There are various submodules that reside in different repositories. In order + to have these submodules locally, you must pull them into your clone, using: + +.. code-block:: shell + + git submodule update --init --recursive + +2. The MicroPython cross-compiler must be built; it will be used to pre-compile + some of the built-in scripts to bytecode. The cross-compiler is built and + run on the host machine, using: + +.. code-block:: shell + + make -C mpy-cross + + +Build commands are run from the ``circuitpython/ports/atmel-samd`` directory. + +To build for a given board you must specify it by setting ``BOARD``. For example: + +.. code-block:: shell + + make BOARD=feather_m0_basic + +Board names are the directory names in the `boards `_ folder. + +Deploying +--------- + +Arduino Bootloader +^^^^^^^^^^^^^^^^^^ + +If your board has an existing Arduino bootloader on it then you can use bossac +to flash MicroPython. First, activate the bootloader. On Adafruit Feathers you +can double click the reset button and the #13 will fade in and out. Finally, +run bossac: + + tools/bossac_osx -e -w -v -b -R build-feather_m0_basic/firmware.bin + +No Bootloader via GDB +^^^^^^^^^^^^^^^^^^^^^ + +This method works for loading MicroPython onto the Arduino Zero via the +programming port rather than the native USB port. + +Note: These instructions are tested on Mac OSX and will vary for different +platforms. + + openocd -f ~/Library/Arduino15/packages/arduino/hardware/samd/1.6.6/variants/arduino_zero/openocd_scripts/arduino_zero.cfg + +In another terminal from ``micropython/atmel-samd``: + + arm-none-eabi-gdb build-arduino_zero/firmware.elf + (gdb) tar ext :3333 + ... + (gdb) load + ... + (gdb) monitor reset init + ... + (gdb) continue + +Connecting +---------- + +Serial +^^^^^^ + +All boards are currently configured to work over USB rather than UART. To +connect to it from OSX do something like this: + + screen /dev/tty.usbmodem142422 115200 + +You may not see a prompt immediately because it doesn't know you connected. To +get one either hit enter to get `>>>` or do CTRL-B to get the full header. + +Mass storage +^^^^^^^^^^^^ + +All boards will also show up as a mass storage device. Make sure to eject it +before resetting or disconnecting the board. + +Port Specific modules +--------------------- + +.. toctree:: + bindings/samd/__init__ diff --git a/ports/atmel-samd/asf4 b/ports/atmel-samd/asf4 new file mode 160000 index 00000000000..039b5f3bbc3 --- /dev/null +++ b/ports/atmel-samd/asf4 @@ -0,0 +1 @@ +Subproject commit 039b5f3bbc3f4ba4421e581db290560d59fef625 diff --git a/ports/atmel-samd/asf4_conf/samd21/hpl_adc_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_adc_config.h new file mode 100644 index 00000000000..627f4e9bd47 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_adc_config.h @@ -0,0 +1,296 @@ +/* Auto-generated config file hpl_adc_config.h */ +#ifndef HPL_ADC_CONFIG_H +#define HPL_ADC_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +#ifndef CONF_ADC_0_ENABLE +#define CONF_ADC_0_ENABLE 1 +#endif + +// Basic Configuration + +// Conversion resolution +// <0x0=>12-bit +// <0x1=>16-bit (averaging must be enabled) +// <0x2=>10-bit +// <0x3=>8-bit +// Defines the bit resolution for the ADC sample values (RESSEL) +// adc_resolution +#ifndef CONF_ADC_0_RESSEL +#define CONF_ADC_0_RESSEL 0x0 +#endif + +// Reference Selection +// <0x0=>1.0V voltage reference +// <0x1=>1/1.48 VDDANA +// <0x2=>1/2 VDDANA (only for VDDANA > 2.0V) +// <0x3=>External reference A +// <0x4=>External reference B +// Select the reference for the ADC (REFSEL) +// adc_reference +#ifndef CONF_ADC_0_REFSEL +#define CONF_ADC_0_REFSEL 0x2 +#endif + +// Prescaler configuration +// <0x0=>Peripheral clock divided by 4 +// <0x1=>Peripheral clock divided by 8 +// <0x2=>Peripheral clock divided by 16 +// <0x3=>Peripheral clock divided by 32 +// <0x4=>Peripheral clock divided by 64 +// <0x5=>Peripheral clock divided by 128 +// <0x6=>Peripheral clock divided by 256 +// <0x7=>Peripheral clock divided by 512 +// These bits define the ADC clock relative to the peripheral clock (PRESCALER) +// adc_prescaler +#ifndef CONF_ADC_0_PRESCALER +#define CONF_ADC_0_PRESCALER 0x3 +#endif + +// Free Running Mode +// When enabled, the ADC is in free running mode and a new conversion will be initiated when a previous conversion completes. (FREERUN) +// adc_freerunning_mode +#ifndef CONF_ADC_0_FREERUN +#define CONF_ADC_0_FREERUN 0 +#endif + +// Differential Mode +// In differential mode, the voltage difference between the MUXPOS and MUXNEG inputs will be converted by the ADC. (DIFFMODE) +// adc_differential_mode +#ifndef CONF_ADC_0_DIFFMODE +#define CONF_ADC_0_DIFFMODE 0 +#endif + +// Positive Mux Input Selection +// <0x00=>ADC AIN0 pin +// <0x01=>ADC AIN1 pin +// <0x02=>ADC AIN2 pin +// <0x03=>ADC AIN3 pin +// <0x04=>ADC AIN4 pin +// <0x05=>ADC AIN5 pin +// <0x06=>ADC AIN6 pin +// <0x07=>ADC AIN7 pin +// <0x08=>ADC AIN8 pin +// <0x09=>ADC AIN9 pin +// <0x0A=>ADC AIN10 pin +// <0x0B=>ADC AIN11 pin +// <0x0C=>ADC AIN12 pin +// <0x0D=>ADC AIN13 pin +// <0x0E=>ADC AIN14 pin +// <0x0F=>ADC AIN15 pin +// <0x10=>ADC AIN16 pin +// <0x11=>ADC AIN17 pin +// <0x12=>ADC AIN18 pin +// <0x13=>ADC AIN19 pin +// <0x18=>Temperature reference +// <0x19=>Bandgap voltage +// <0x1A=>1/4 scaled core supply +// <0x1B=>1/4 scaled I/O supply +// <0x1C=>DAC output +// These bits define the Mux selection for the positive ADC input. (MUXPOS) +// adc_pinmux_positive +#ifndef CONF_ADC_0_MUXPOS +#define CONF_ADC_0_MUXPOS 0x02 +#endif + +// Negative Mux Input Selection +// <0x00=>ADC AIN0 pin +// <0x01=>ADC AIN1 pin +// <0x02=>ADC AIN2 pin +// <0x03=>ADC AIN3 pin +// <0x04=>ADC AIN4 pin +// <0x05=>ADC AIN5 pin +// <0x06=>ADC AIN6 pin +// <0x07=>ADC AIN7 pin +// <0x18=>Internal ground +// <0x19=>I/O ground +// These bits define the Mux selection for the negative ADC input. (MUXNEG) +// adc_pinmux_negative +#ifndef CONF_ADC_0_MUXNEG +#define CONF_ADC_0_MUXNEG 0x18 +#endif + +// + +// Advanced Configuration +// adc_advanced_settings +#ifndef CONF_ADC_0_ADVANCED_CONFIG +#define CONF_ADC_0_ADVANCED_CONFIG 0 +#endif + +// Run in standby +// Indicates whether the ADC will continue running in standby sleep mode or not (RUNSTDBY) +// adc_arch_runstdby +#ifndef CONF_ADC_0_RUNSTDBY +#define CONF_ADC_0_RUNSTDBY 0 +#endif + +// Debug Run +// If enabled, the ADC is running if the CPU is halted by an external debugger. (DBGRUN) +// adc_arch_dbgrun +#ifndef CONF_ADC_0_DBGRUN +#define CONF_ADC_0_DBGRUN 0 +#endif + +// Left-Adjusted Result +// When enabled, the ADC conversion result is left-adjusted in the RESULT register. The high byte of the 12-bit result will be present in the upper part of the result register. (LEFTADJ) +// adc_arch_leftadj +#ifndef CONF_ADC_0_LEFTADJ +#define CONF_ADC_0_LEFTADJ 0 +#endif + +// Reference Buffer Offset Compensation Enable +// The accuracy of the gain stage can be increased by enabling the reference buffer offset compensation. This will decrease the input impedance and thus increase the start-up time of the reference. (REFCOMP) +// adc_arch_refcomp +#ifndef CONF_ADC_0_REFCOMP +#define CONF_ADC_0_REFCOMP 0 +#endif + +// Digital Correction Logic Enabled +// When enabled, the ADC conversion result in the RESULT register is then corrected for gain and offset based on the values in the GAINCAL and OFFSETCAL registers. (CORREN) +// adc_arch_corren +#ifndef CONF_ADC_0_CORREN +#define CONF_ADC_0_CORREN 0 +#endif + +// Offset Correction Value <0-4095> +// If the digital correction logic is enabled (CTRLB.CORREN = 1), these bits define how the ADC conversion result is compensated for offset error before being written to the Result register. (OFFSETCORR) +// adc_arch_offsetcorr +#ifndef CONF_ADC_0_OFFSETCORR +#define CONF_ADC_0_OFFSETCORR 0 +#endif + +// Gain Correction Value <0-4095> +// If the digital correction logic is enabled (CTRLB.CORREN = 1), these bits define how the ADC conversion result is compensated for gain error before being written to the result register. (GAINCORR) +// adc_arch_gaincorr +#ifndef CONF_ADC_0_GAINCORR +#define CONF_ADC_0_GAINCORR 0 +#endif + +// Gain Factor Selection +// <0x0=>1x +// <0x1=>2x +// <0x2=>4x +// <0x3=>8x +// <0x4=>16x +// <0xF=>1/2x +// These bits set the gain factor of the ADC gain stage. (GAIN) +// adc_arch_gain +#ifndef CONF_ADC_0_GAIN +#define CONF_ADC_0_GAIN 0x0 +#endif + +// Adjusting Result / Division Coefficient <0-7> +// These bits define the division coefficient in 2n steps. (ADJRES) +// adc_arch_adjres +#ifndef CONF_ADC_0_ADJRES +#define CONF_ADC_0_ADJRES 0x0 +#endif + +// Number of Samples to be Collected +// <0x0=>1 sample +// <0x1=>2 samples +// <0x2=>4 samples +// <0x3=>8 samples +// <0x4=>16 samples +// <0x5=>32 samples +// <0x6=>64 samples +// <0x7=>128 samples +// <0x8=>256 samples +// <0x9=>512 samples +// <0xA=>1024 samples +// Define how many samples should be added together.The result will be available in the Result register (SAMPLENUM) +// adc_arch_samplenum +#ifndef CONF_ADC_0_SAMPLENUM +#define CONF_ADC_0_SAMPLENUM 0x0 +#endif + +// Sampling Time Length <0-63> +// These bits control the ADC sampling time in number of half CLK_ADC cycles, depending of the prescaler value, thus controlling the ADC input impedance. (SAMPLEN) +// adc_arch_samplen +#ifndef CONF_ADC_0_SAMPLEN +#define CONF_ADC_0_SAMPLEN 0 +#endif + +// Window Monitor Mode +// <0x0=>No window mode +// <0x1=>Mode 1: RESULT above lower threshold +// <0x2=>Mode 2: RESULT beneath upper threshold +// <0x3=>Mode 3: RESULT inside lower and upper threshold +// <0x4=>Mode 4: RESULT outside lower and upper threshold +// These bits enable and define the window monitor mode. (WINMODE) +// adc_arch_winmode +#ifndef CONF_ADC_0_WINMODE +#define CONF_ADC_0_WINMODE 0x0 +#endif + +// Window Monitor Lower Threshold <0-65535> +// If the window monitor is enabled, these bits define the lower threshold value. (WINLT) +// adc_arch_winlt +#ifndef CONF_ADC_0_WINLT +#define CONF_ADC_0_WINLT 0 +#endif + +// Window Monitor Upper Threshold <0-65535> +// If the window monitor is enabled, these bits define the lower threshold value. (WINUT) +// adc_arch_winut +#ifndef CONF_ADC_0_WINUT +#define CONF_ADC_0_WINUT 0 +#endif + +// Number of Input Channels Included in Scan <0-15> +// This register gives the number of input sources included in pin scan. The number of input sources included is INPUTSCAN + 1. 0 disables the input scan feature. (INPUTSCAN) +// adc_arch_inputscan +#ifndef CONF_ADC_0_INPUTSCAN +#define CONF_ADC_0_INPUTSCAN 0 +#endif + +// Positive Mux Setting Offset <0-15> +// When inputscan is enabled this value define the pin offset, which means that the actual input pin sampled is the muxpos pin + input offset. (INPUTOFFSET) +// adc_arch_inputoffset +#ifndef CONF_ADC_0_INPUTOFFSET +#define CONF_ADC_0_INPUTOFFSET 0 +#endif + +// + +// Event Control +// adc_arch_event_settings +#ifndef CONF_ADC_0_EVENT_CONFIG +#define CONF_ADC_0_EVENT_CONFIG 0 +#endif + +// Window Monitor Event Out +// Enables event output on window event (WINMONEO) +// adc_arch_winmoneo +#ifndef CONF_ADC_0_WINMONEO +#define CONF_ADC_0_WINMONEO 0 +#endif + +// Result Ready Event Out +// Enables event output on result ready event (RESRDEO) +// adc_arch_resrdyeo +#ifndef CONF_ADC_0_RESRDYEO +#define CONF_ADC_0_RESRDYEO 0 +#endif + +// Trigger Synchronization On Event +// Trigger a flush operation and a new conversion on event in (SYNCEI) +// adc_arch_syncei +#ifndef CONF_ADC_0_SYNCEI +#define CONF_ADC_0_SYNCEI 0 +#endif + +// Trigger Conversion On Event +// Trigger a conversion on event. (STARTEI) +// adc_arch_startei +#ifndef CONF_ADC_0_STARTEI +#define CONF_ADC_0_STARTEI 0 +#endif + +// + +// <<< end of configuration section >>> + +#endif // HPL_ADC_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd21/hpl_dac_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_dac_config.h new file mode 100644 index 00000000000..42b893a3591 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_dac_config.h @@ -0,0 +1,86 @@ +/* Auto-generated config file hpl_dac_config.h */ +#ifndef HPL_DAC_CONFIG_H +#define HPL_DAC_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Basic configuration +// Reference Selection +// <0x00=> Internal 1.0v reference +// <0x01=> AVCC +// <0x02=> External reference +// dac_arch_refsel +#ifndef CONF_DAC_REFSEL +#define CONF_DAC_REFSEL 1 +#endif +// + +// Advanced Configuration +// dac_advanced_settings +#ifndef CONF_DAC_ADVANCED_CONFIG +#define CONF_DAC_ADVANCED_CONFIG 0 +#endif + +// Run in standby +// Indicates whether the DAC will continue running in standby sleep mode or not +// dac_arch_runstdby +#ifndef CONF_DAC_RUNSTDBY +#define CONF_DAC_RUNSTDBY 0 +#endif + +// Bypass DATABUF Write Protection +// Indicate whether DATABUF write protection is bypass +// dac_arch_bdwp +#ifndef CONF_DAC_BDWP +#define CONF_DAC_BDWP 0 +#endif + +// Voltage Pump Disable +// Indicate whether voltage pump is disable or not +// dac_arch_vpd +#ifndef CONF_DAC_VPD +#define CONF_DAC_VPD 0 +#endif + +// Left Adjusted Data +// Indicate how the data is adjusted in the Data and Data Buffer register +// dac_arch_leftadj +#ifndef CONF_DAC_LEFTADJ +#define CONF_DAC_LEFTADJ 1 +#endif + +// Internal Output Enable +// Indicate whether internal output is enable or not +// dac_arch_ioen +#ifndef CONF_DAC_IOEN +#define CONF_DAC_IOEN 0 +#endif + +// External Output Enable +// Indicate whether external output is enable or not +// dac_arch_eoen +#ifndef CONF_DAC_EOEN +#define CONF_DAC_EOEN 1 +#endif + +// + +// Event configuration +// Data Buffer Empty Event Output +// Indicate whether Data Buffer Empty Event is enabled and generated when the Data Buffer register is empty or not +// dac_arch_emptyeo +#ifndef CONF_DAC_EMPTYEO +#define CONF_DAC_EMPTYEO 0 +#endif + +// Start Conversion on Event Input +// Indicate whether Start Conversion is enabled and data are loaded from the Data Buffer register to the Data register upon event reception or not +// dac_arch_startei +#ifndef CONF_DAC_STARTEI +#define CONF_DAC_STARTEI 0 +#endif +// + +// <<< end of configuration section >>> + +#endif // HPL_DAC_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd21/hpl_dmac_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_dmac_config.h new file mode 100644 index 00000000000..3667e873ba3 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_dmac_config.h @@ -0,0 +1,3057 @@ +/* Auto-generated config file hpl_dmac_config.h */ +#ifndef HPL_DMAC_CONFIG_H +#define HPL_DMAC_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// DMAC enable +// Indicates whether dmac is enabled or not +// dmac_enable +#ifndef CONF_DMAC_ENABLE +#define CONF_DMAC_ENABLE 0 +#endif + +// Priority Level 0 +// Indicates whether Priority Level 0 is enabled or not +// dmac_lvlen0 +#ifndef CONF_DMAC_LVLEN0 +#define CONF_DMAC_LVLEN0 0 +#endif + +// Level 0 Round-Robin Arbitration +// <0=> Static arbitration scheme for channel with priority 0 +// <1=> Round-robin arbitration scheme for channel with priority 0 +// Defines Level 0 Arbitration for DMA channels +// dmac_rrlvlen0 +#ifndef CONF_DMAC_RRLVLEN0 +#define CONF_DMAC_RRLVLEN0 0 +#endif + +// Level 0 Channel Priority Number <0x00-0xFF> +// dmac_lvlpri0 +#ifndef CONF_DMAC_LVLPRI0 +#define CONF_DMAC_LVLPRI0 0 +#endif + +// Priority Level 1 +// Indicates whether Priority Level 1 is enabled or not +// dmac_lvlen1 +#ifndef CONF_DMAC_LVLEN1 +#define CONF_DMAC_LVLEN1 0 +#endif + +// Level 1 Round-Robin Arbitration +// <0=> Static arbitration scheme for channel with priority 1 +// <1=> Round-robin arbitration scheme for channel with priority 1 +// Defines Level 1 Arbitration for DMA channels +// dmac_rrlvlen1 +#ifndef CONF_DMAC_RRLVLEN1 +#define CONF_DMAC_RRLVLEN1 0 +#endif + +// Level 1 Channel Priority Number <0x00-0xFF> +// dmac_lvlpri1 +#ifndef CONF_DMAC_LVLPRI1 +#define CONF_DMAC_LVLPRI1 0 +#endif + +// Priority Level 2 +// Indicates whether Priority Level 2 is enabled or not +// dmac_lvlen2 +#ifndef CONF_DMAC_LVLEN2 +#define CONF_DMAC_LVLEN2 0 +#endif + +// Level 2 Round-Robin Arbitration +// <0=> Static arbitration scheme for channel with priority 2 +// <1=> Round-robin arbitration scheme for channel with priority 2 +// Defines Level 2 Arbitration for DMA channels +// dmac_rrlvlen2 +#ifndef CONF_DMAC_RRLVLEN2 +#define CONF_DMAC_RRLVLEN2 0 +#endif + +// Level 2 Channel Priority Number <0x00-0xFF> +// dmac_lvlpri2 +#ifndef CONF_DMAC_LVLPRI2 +#define CONF_DMAC_LVLPRI2 0 +#endif + +// Priority Level 3 +// Indicates whether Priority Level 3 is enabled or not +// dmac_lvlen3 +#ifndef CONF_DMAC_LVLEN3 +#define CONF_DMAC_LVLEN3 0 +#endif + +// Level 3 Round-Robin Arbitration +// <0=> Static arbitration scheme for channel with priority 3 +// <1=> Round-robin arbitration scheme for channel with priority 3 +// Defines Level 3 Arbitration for DMA channels +// dmac_rrlvlen3 +#ifndef CONF_DMAC_RRLVLEN3 +#define CONF_DMAC_RRLVLEN3 0 +#endif + +// Level 3 Channel Priority Number <0x00-0xFF> +// dmac_lvlpri3 +#ifndef CONF_DMAC_LVLPRI3 +#define CONF_DMAC_LVLPRI3 0 +#endif + +// Debug Run +// Indicates whether Debug Run is enabled or not +// dmac_dbgrun +#ifndef CONF_DMAC_DBGRUN +#define CONF_DMAC_DBGRUN 0 +#endif + +// Channel 0 settings +// dmac_channel_0_settings +#ifndef CONF_DMAC_CHANNEL_0_SETTINGS +#define CONF_DMAC_CHANNEL_0_SETTINGS 0 +#endif + +// Channel Enable +// Indicates whether channel 0 is enabled or not +// dmac_enable_0 +#ifndef CONF_DMAC_ENABLE_0 +#define CONF_DMAC_ENABLE_0 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_0 +#ifndef CONF_DMAC_TRIGACT_0 +#define CONF_DMAC_TRIGACT_0 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> SERCOM0 RX Trigger +// <0x02=> SERCOM0 TX Trigger +// <0x03=> SERCOM1 RX Trigger +// <0x04=> SERCOM1 TX Trigger +// <0x05=> SERCOM2 RX Trigger +// <0x06=> SERCOM2 TX Trigger +// <0x07=> SERCOM3 RX Trigger +// <0x08=> SERCOM3 TX Trigger +// <0x09=> SERCOM4 RX Trigger +// <0x0A=> SERCOM4 TX Trigger +// <0x0B=> SERCOM5 RX Trigger +// <0x0C=> SERCOM5 TX Trigger +// <0x0D=> TCC0 Overflow Trigger +// <0x0E=> TCC0 Match/Compare 0 Trigger +// <0x0F=> TCC0 Match/Compare 1 Trigger +// <0x10=> TCC0 Match/Compare 2 Trigger +// <0x11=> TCC0 Match/Compare 3 Trigger +// <0x12=> TCC1 Overflow Trigger +// <0x13=> TCC1 Match/Compare 0 Trigger +// <0x14=> TCC1 Match/Compare 1 Trigger +// <0x15=> TCC2 Overflow Trigger +// <0x16=> TCC2 Match/Compare 0 Trigger +// <0x17=> TCC2 Match/Compare 1 Trigger +// <0x18=> TC3 Overflow Trigger +// <0x19=> TC3 Match/Compare 0 Trigger +// <0x1A=> TC3 Match/Compare 1 Trigger +// <0x1B=> TC4 Overflow Trigger +// <0x1C=> TC4 Match/Compare 0 Trigger +// <0x1D=> TC4 Match/Compare 1 Trigger +// <0x1E=> TC5 Overflow Trigger +// <0x1F=> TC5 Match/Compare 0 Trigger +// <0x20=> TC5 Match/Compare 1 Trigger +// <0x21=> TC6 Overflow Trigger +// <0x22=> TC6 Match/Compare 0 Trigger +// <0x23=> TC6 Match/Compare 1 Trigger +// <0x24=> TC7 Overflow Trigger +// <0x25=> TC7 Match/Compare 0 Trigger +// <0x26=> TC7 Match/Compare 1 Trigger +// <0x27=> ADC Result Ready Trigger +// <0x28=> DAC Empty Trigger +// <0x29=> I2S Rx 0 Trigger +// <0x2A=> I2S Rx 1 Trigger +// <0x2B=> I2S Tx 0 Trigger +// <0x2C=> I2S Tx 1 Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_0 +#ifndef CONF_DMAC_TRIGSRC_0 +#define CONF_DMAC_TRIGSRC_0 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_0 +#ifndef CONF_DMAC_LVL_0 +#define CONF_DMAC_LVL_0 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_0 +#ifndef CONF_DMAC_EVOE_0 +#define CONF_DMAC_EVOE_0 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_0 +#ifndef CONF_DMAC_EVIE_0 +#define CONF_DMAC_EVIE_0 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_0 +#ifndef CONF_DMAC_EVACT_0 +#define CONF_DMAC_EVACT_0 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_0 +#ifndef CONF_DMAC_STEPSIZE_0 +#define CONF_DMAC_STEPSIZE_0 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_0 +#ifndef CONF_DMAC_STEPSEL_0 +#define CONF_DMAC_STEPSEL_0 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_0 +#ifndef CONF_DMAC_SRCINC_0 +#define CONF_DMAC_SRCINC_0 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_0 +#ifndef CONF_DMAC_DSTINC_0 +#define CONF_DMAC_DSTINC_0 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_0 +#ifndef CONF_DMAC_BEATSIZE_0 +#define CONF_DMAC_BEATSIZE_0 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_0 +#ifndef CONF_DMAC_BLOCKACT_0 +#define CONF_DMAC_BLOCKACT_0 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_0 +#ifndef CONF_DMAC_EVOSEL_0 +#define CONF_DMAC_EVOSEL_0 0 +#endif +// + +// Channel 1 settings +// dmac_channel_1_settings +#ifndef CONF_DMAC_CHANNEL_1_SETTINGS +#define CONF_DMAC_CHANNEL_1_SETTINGS 0 +#endif + +// Channel Enable +// Indicates whether channel 1 is enabled or not +// dmac_enable_1 +#ifndef CONF_DMAC_ENABLE_1 +#define CONF_DMAC_ENABLE_1 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_1 +#ifndef CONF_DMAC_TRIGACT_1 +#define CONF_DMAC_TRIGACT_1 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> SERCOM0 RX Trigger +// <0x02=> SERCOM0 TX Trigger +// <0x03=> SERCOM1 RX Trigger +// <0x04=> SERCOM1 TX Trigger +// <0x05=> SERCOM2 RX Trigger +// <0x06=> SERCOM2 TX Trigger +// <0x07=> SERCOM3 RX Trigger +// <0x08=> SERCOM3 TX Trigger +// <0x09=> SERCOM4 RX Trigger +// <0x0A=> SERCOM4 TX Trigger +// <0x0B=> SERCOM5 RX Trigger +// <0x0C=> SERCOM5 TX Trigger +// <0x0D=> TCC0 Overflow Trigger +// <0x0E=> TCC0 Match/Compare 0 Trigger +// <0x0F=> TCC0 Match/Compare 1 Trigger +// <0x10=> TCC0 Match/Compare 2 Trigger +// <0x11=> TCC0 Match/Compare 3 Trigger +// <0x12=> TCC1 Overflow Trigger +// <0x13=> TCC1 Match/Compare 0 Trigger +// <0x14=> TCC1 Match/Compare 1 Trigger +// <0x15=> TCC2 Overflow Trigger +// <0x16=> TCC2 Match/Compare 0 Trigger +// <0x17=> TCC2 Match/Compare 1 Trigger +// <0x18=> TC3 Overflow Trigger +// <0x19=> TC3 Match/Compare 0 Trigger +// <0x1A=> TC3 Match/Compare 1 Trigger +// <0x1B=> TC4 Overflow Trigger +// <0x1C=> TC4 Match/Compare 0 Trigger +// <0x1D=> TC4 Match/Compare 1 Trigger +// <0x1E=> TC5 Overflow Trigger +// <0x1F=> TC5 Match/Compare 0 Trigger +// <0x20=> TC5 Match/Compare 1 Trigger +// <0x21=> TC6 Overflow Trigger +// <0x22=> TC6 Match/Compare 0 Trigger +// <0x23=> TC6 Match/Compare 1 Trigger +// <0x24=> TC7 Overflow Trigger +// <0x25=> TC7 Match/Compare 0 Trigger +// <0x26=> TC7 Match/Compare 1 Trigger +// <0x27=> ADC Result Ready Trigger +// <0x28=> DAC Empty Trigger +// <0x29=> I2S Rx 0 Trigger +// <0x2A=> I2S Rx 1 Trigger +// <0x2B=> I2S Tx 0 Trigger +// <0x2C=> I2S Tx 1 Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_1 +#ifndef CONF_DMAC_TRIGSRC_1 +#define CONF_DMAC_TRIGSRC_1 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_1 +#ifndef CONF_DMAC_LVL_1 +#define CONF_DMAC_LVL_1 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_1 +#ifndef CONF_DMAC_EVOE_1 +#define CONF_DMAC_EVOE_1 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_1 +#ifndef CONF_DMAC_EVIE_1 +#define CONF_DMAC_EVIE_1 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_1 +#ifndef CONF_DMAC_EVACT_1 +#define CONF_DMAC_EVACT_1 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_1 +#ifndef CONF_DMAC_STEPSIZE_1 +#define CONF_DMAC_STEPSIZE_1 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_1 +#ifndef CONF_DMAC_STEPSEL_1 +#define CONF_DMAC_STEPSEL_1 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_1 +#ifndef CONF_DMAC_SRCINC_1 +#define CONF_DMAC_SRCINC_1 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_1 +#ifndef CONF_DMAC_DSTINC_1 +#define CONF_DMAC_DSTINC_1 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_1 +#ifndef CONF_DMAC_BEATSIZE_1 +#define CONF_DMAC_BEATSIZE_1 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_1 +#ifndef CONF_DMAC_BLOCKACT_1 +#define CONF_DMAC_BLOCKACT_1 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_1 +#ifndef CONF_DMAC_EVOSEL_1 +#define CONF_DMAC_EVOSEL_1 0 +#endif +// + +// Channel 2 settings +// dmac_channel_2_settings +#ifndef CONF_DMAC_CHANNEL_2_SETTINGS +#define CONF_DMAC_CHANNEL_2_SETTINGS 0 +#endif + +// Channel Enable +// Indicates whether channel 2 is enabled or not +// dmac_enable_2 +#ifndef CONF_DMAC_ENABLE_2 +#define CONF_DMAC_ENABLE_2 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_2 +#ifndef CONF_DMAC_TRIGACT_2 +#define CONF_DMAC_TRIGACT_2 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> SERCOM0 RX Trigger +// <0x02=> SERCOM0 TX Trigger +// <0x03=> SERCOM1 RX Trigger +// <0x04=> SERCOM1 TX Trigger +// <0x05=> SERCOM2 RX Trigger +// <0x06=> SERCOM2 TX Trigger +// <0x07=> SERCOM3 RX Trigger +// <0x08=> SERCOM3 TX Trigger +// <0x09=> SERCOM4 RX Trigger +// <0x0A=> SERCOM4 TX Trigger +// <0x0B=> SERCOM5 RX Trigger +// <0x0C=> SERCOM5 TX Trigger +// <0x0D=> TCC0 Overflow Trigger +// <0x0E=> TCC0 Match/Compare 0 Trigger +// <0x0F=> TCC0 Match/Compare 1 Trigger +// <0x10=> TCC0 Match/Compare 2 Trigger +// <0x11=> TCC0 Match/Compare 3 Trigger +// <0x12=> TCC1 Overflow Trigger +// <0x13=> TCC1 Match/Compare 0 Trigger +// <0x14=> TCC1 Match/Compare 1 Trigger +// <0x15=> TCC2 Overflow Trigger +// <0x16=> TCC2 Match/Compare 0 Trigger +// <0x17=> TCC2 Match/Compare 1 Trigger +// <0x18=> TC3 Overflow Trigger +// <0x19=> TC3 Match/Compare 0 Trigger +// <0x1A=> TC3 Match/Compare 1 Trigger +// <0x1B=> TC4 Overflow Trigger +// <0x1C=> TC4 Match/Compare 0 Trigger +// <0x1D=> TC4 Match/Compare 1 Trigger +// <0x1E=> TC5 Overflow Trigger +// <0x1F=> TC5 Match/Compare 0 Trigger +// <0x20=> TC5 Match/Compare 1 Trigger +// <0x21=> TC6 Overflow Trigger +// <0x22=> TC6 Match/Compare 0 Trigger +// <0x23=> TC6 Match/Compare 1 Trigger +// <0x24=> TC7 Overflow Trigger +// <0x25=> TC7 Match/Compare 0 Trigger +// <0x26=> TC7 Match/Compare 1 Trigger +// <0x27=> ADC Result Ready Trigger +// <0x28=> DAC Empty Trigger +// <0x29=> I2S Rx 0 Trigger +// <0x2A=> I2S Rx 1 Trigger +// <0x2B=> I2S Tx 0 Trigger +// <0x2C=> I2S Tx 1 Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_2 +#ifndef CONF_DMAC_TRIGSRC_2 +#define CONF_DMAC_TRIGSRC_2 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_2 +#ifndef CONF_DMAC_LVL_2 +#define CONF_DMAC_LVL_2 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_2 +#ifndef CONF_DMAC_EVOE_2 +#define CONF_DMAC_EVOE_2 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_2 +#ifndef CONF_DMAC_EVIE_2 +#define CONF_DMAC_EVIE_2 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_2 +#ifndef CONF_DMAC_EVACT_2 +#define CONF_DMAC_EVACT_2 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_2 +#ifndef CONF_DMAC_STEPSIZE_2 +#define CONF_DMAC_STEPSIZE_2 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_2 +#ifndef CONF_DMAC_STEPSEL_2 +#define CONF_DMAC_STEPSEL_2 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_2 +#ifndef CONF_DMAC_SRCINC_2 +#define CONF_DMAC_SRCINC_2 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_2 +#ifndef CONF_DMAC_DSTINC_2 +#define CONF_DMAC_DSTINC_2 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_2 +#ifndef CONF_DMAC_BEATSIZE_2 +#define CONF_DMAC_BEATSIZE_2 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_2 +#ifndef CONF_DMAC_BLOCKACT_2 +#define CONF_DMAC_BLOCKACT_2 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_2 +#ifndef CONF_DMAC_EVOSEL_2 +#define CONF_DMAC_EVOSEL_2 0 +#endif +// + +// Channel 3 settings +// dmac_channel_3_settings +#ifndef CONF_DMAC_CHANNEL_3_SETTINGS +#define CONF_DMAC_CHANNEL_3_SETTINGS 0 +#endif + +// Channel Enable +// Indicates whether channel 3 is enabled or not +// dmac_enable_3 +#ifndef CONF_DMAC_ENABLE_3 +#define CONF_DMAC_ENABLE_3 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_3 +#ifndef CONF_DMAC_TRIGACT_3 +#define CONF_DMAC_TRIGACT_3 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> SERCOM0 RX Trigger +// <0x02=> SERCOM0 TX Trigger +// <0x03=> SERCOM1 RX Trigger +// <0x04=> SERCOM1 TX Trigger +// <0x05=> SERCOM2 RX Trigger +// <0x06=> SERCOM2 TX Trigger +// <0x07=> SERCOM3 RX Trigger +// <0x08=> SERCOM3 TX Trigger +// <0x09=> SERCOM4 RX Trigger +// <0x0A=> SERCOM4 TX Trigger +// <0x0B=> SERCOM5 RX Trigger +// <0x0C=> SERCOM5 TX Trigger +// <0x0D=> TCC0 Overflow Trigger +// <0x0E=> TCC0 Match/Compare 0 Trigger +// <0x0F=> TCC0 Match/Compare 1 Trigger +// <0x10=> TCC0 Match/Compare 2 Trigger +// <0x11=> TCC0 Match/Compare 3 Trigger +// <0x12=> TCC1 Overflow Trigger +// <0x13=> TCC1 Match/Compare 0 Trigger +// <0x14=> TCC1 Match/Compare 1 Trigger +// <0x15=> TCC2 Overflow Trigger +// <0x16=> TCC2 Match/Compare 0 Trigger +// <0x17=> TCC2 Match/Compare 1 Trigger +// <0x18=> TC3 Overflow Trigger +// <0x19=> TC3 Match/Compare 0 Trigger +// <0x1A=> TC3 Match/Compare 1 Trigger +// <0x1B=> TC4 Overflow Trigger +// <0x1C=> TC4 Match/Compare 0 Trigger +// <0x1D=> TC4 Match/Compare 1 Trigger +// <0x1E=> TC5 Overflow Trigger +// <0x1F=> TC5 Match/Compare 0 Trigger +// <0x20=> TC5 Match/Compare 1 Trigger +// <0x21=> TC6 Overflow Trigger +// <0x22=> TC6 Match/Compare 0 Trigger +// <0x23=> TC6 Match/Compare 1 Trigger +// <0x24=> TC7 Overflow Trigger +// <0x25=> TC7 Match/Compare 0 Trigger +// <0x26=> TC7 Match/Compare 1 Trigger +// <0x27=> ADC Result Ready Trigger +// <0x28=> DAC Empty Trigger +// <0x29=> I2S Rx 0 Trigger +// <0x2A=> I2S Rx 1 Trigger +// <0x2B=> I2S Tx 0 Trigger +// <0x2C=> I2S Tx 1 Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_3 +#ifndef CONF_DMAC_TRIGSRC_3 +#define CONF_DMAC_TRIGSRC_3 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_3 +#ifndef CONF_DMAC_LVL_3 +#define CONF_DMAC_LVL_3 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_3 +#ifndef CONF_DMAC_EVOE_3 +#define CONF_DMAC_EVOE_3 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_3 +#ifndef CONF_DMAC_EVIE_3 +#define CONF_DMAC_EVIE_3 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_3 +#ifndef CONF_DMAC_EVACT_3 +#define CONF_DMAC_EVACT_3 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_3 +#ifndef CONF_DMAC_STEPSIZE_3 +#define CONF_DMAC_STEPSIZE_3 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_3 +#ifndef CONF_DMAC_STEPSEL_3 +#define CONF_DMAC_STEPSEL_3 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_3 +#ifndef CONF_DMAC_SRCINC_3 +#define CONF_DMAC_SRCINC_3 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_3 +#ifndef CONF_DMAC_DSTINC_3 +#define CONF_DMAC_DSTINC_3 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_3 +#ifndef CONF_DMAC_BEATSIZE_3 +#define CONF_DMAC_BEATSIZE_3 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_3 +#ifndef CONF_DMAC_BLOCKACT_3 +#define CONF_DMAC_BLOCKACT_3 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_3 +#ifndef CONF_DMAC_EVOSEL_3 +#define CONF_DMAC_EVOSEL_3 0 +#endif +// + +// Channel 4 settings +// dmac_channel_4_settings +#ifndef CONF_DMAC_CHANNEL_4_SETTINGS +#define CONF_DMAC_CHANNEL_4_SETTINGS 0 +#endif + +// Channel Enable +// Indicates whether channel 4 is enabled or not +// dmac_enable_4 +#ifndef CONF_DMAC_ENABLE_4 +#define CONF_DMAC_ENABLE_4 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_4 +#ifndef CONF_DMAC_TRIGACT_4 +#define CONF_DMAC_TRIGACT_4 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> SERCOM0 RX Trigger +// <0x02=> SERCOM0 TX Trigger +// <0x03=> SERCOM1 RX Trigger +// <0x04=> SERCOM1 TX Trigger +// <0x05=> SERCOM2 RX Trigger +// <0x06=> SERCOM2 TX Trigger +// <0x07=> SERCOM3 RX Trigger +// <0x08=> SERCOM3 TX Trigger +// <0x09=> SERCOM4 RX Trigger +// <0x0A=> SERCOM4 TX Trigger +// <0x0B=> SERCOM5 RX Trigger +// <0x0C=> SERCOM5 TX Trigger +// <0x0D=> TCC0 Overflow Trigger +// <0x0E=> TCC0 Match/Compare 0 Trigger +// <0x0F=> TCC0 Match/Compare 1 Trigger +// <0x10=> TCC0 Match/Compare 2 Trigger +// <0x11=> TCC0 Match/Compare 3 Trigger +// <0x12=> TCC1 Overflow Trigger +// <0x13=> TCC1 Match/Compare 0 Trigger +// <0x14=> TCC1 Match/Compare 1 Trigger +// <0x15=> TCC2 Overflow Trigger +// <0x16=> TCC2 Match/Compare 0 Trigger +// <0x17=> TCC2 Match/Compare 1 Trigger +// <0x18=> TC3 Overflow Trigger +// <0x19=> TC3 Match/Compare 0 Trigger +// <0x1A=> TC3 Match/Compare 1 Trigger +// <0x1B=> TC4 Overflow Trigger +// <0x1C=> TC4 Match/Compare 0 Trigger +// <0x1D=> TC4 Match/Compare 1 Trigger +// <0x1E=> TC5 Overflow Trigger +// <0x1F=> TC5 Match/Compare 0 Trigger +// <0x20=> TC5 Match/Compare 1 Trigger +// <0x21=> TC6 Overflow Trigger +// <0x22=> TC6 Match/Compare 0 Trigger +// <0x23=> TC6 Match/Compare 1 Trigger +// <0x24=> TC7 Overflow Trigger +// <0x25=> TC7 Match/Compare 0 Trigger +// <0x26=> TC7 Match/Compare 1 Trigger +// <0x27=> ADC Result Ready Trigger +// <0x28=> DAC Empty Trigger +// <0x29=> I2S Rx 0 Trigger +// <0x2A=> I2S Rx 1 Trigger +// <0x2B=> I2S Tx 0 Trigger +// <0x2C=> I2S Tx 1 Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_4 +#ifndef CONF_DMAC_TRIGSRC_4 +#define CONF_DMAC_TRIGSRC_4 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_4 +#ifndef CONF_DMAC_LVL_4 +#define CONF_DMAC_LVL_4 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_4 +#ifndef CONF_DMAC_EVOE_4 +#define CONF_DMAC_EVOE_4 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_4 +#ifndef CONF_DMAC_EVIE_4 +#define CONF_DMAC_EVIE_4 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_4 +#ifndef CONF_DMAC_EVACT_4 +#define CONF_DMAC_EVACT_4 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_4 +#ifndef CONF_DMAC_STEPSIZE_4 +#define CONF_DMAC_STEPSIZE_4 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_4 +#ifndef CONF_DMAC_STEPSEL_4 +#define CONF_DMAC_STEPSEL_4 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_4 +#ifndef CONF_DMAC_SRCINC_4 +#define CONF_DMAC_SRCINC_4 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_4 +#ifndef CONF_DMAC_DSTINC_4 +#define CONF_DMAC_DSTINC_4 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_4 +#ifndef CONF_DMAC_BEATSIZE_4 +#define CONF_DMAC_BEATSIZE_4 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_4 +#ifndef CONF_DMAC_BLOCKACT_4 +#define CONF_DMAC_BLOCKACT_4 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_4 +#ifndef CONF_DMAC_EVOSEL_4 +#define CONF_DMAC_EVOSEL_4 0 +#endif +// + +// Channel 5 settings +// dmac_channel_5_settings +#ifndef CONF_DMAC_CHANNEL_5_SETTINGS +#define CONF_DMAC_CHANNEL_5_SETTINGS 0 +#endif + +// Channel Enable +// Indicates whether channel 5 is enabled or not +// dmac_enable_5 +#ifndef CONF_DMAC_ENABLE_5 +#define CONF_DMAC_ENABLE_5 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_5 +#ifndef CONF_DMAC_TRIGACT_5 +#define CONF_DMAC_TRIGACT_5 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> SERCOM0 RX Trigger +// <0x02=> SERCOM0 TX Trigger +// <0x03=> SERCOM1 RX Trigger +// <0x04=> SERCOM1 TX Trigger +// <0x05=> SERCOM2 RX Trigger +// <0x06=> SERCOM2 TX Trigger +// <0x07=> SERCOM3 RX Trigger +// <0x08=> SERCOM3 TX Trigger +// <0x09=> SERCOM4 RX Trigger +// <0x0A=> SERCOM4 TX Trigger +// <0x0B=> SERCOM5 RX Trigger +// <0x0C=> SERCOM5 TX Trigger +// <0x0D=> TCC0 Overflow Trigger +// <0x0E=> TCC0 Match/Compare 0 Trigger +// <0x0F=> TCC0 Match/Compare 1 Trigger +// <0x10=> TCC0 Match/Compare 2 Trigger +// <0x11=> TCC0 Match/Compare 3 Trigger +// <0x12=> TCC1 Overflow Trigger +// <0x13=> TCC1 Match/Compare 0 Trigger +// <0x14=> TCC1 Match/Compare 1 Trigger +// <0x15=> TCC2 Overflow Trigger +// <0x16=> TCC2 Match/Compare 0 Trigger +// <0x17=> TCC2 Match/Compare 1 Trigger +// <0x18=> TC3 Overflow Trigger +// <0x19=> TC3 Match/Compare 0 Trigger +// <0x1A=> TC3 Match/Compare 1 Trigger +// <0x1B=> TC4 Overflow Trigger +// <0x1C=> TC4 Match/Compare 0 Trigger +// <0x1D=> TC4 Match/Compare 1 Trigger +// <0x1E=> TC5 Overflow Trigger +// <0x1F=> TC5 Match/Compare 0 Trigger +// <0x20=> TC5 Match/Compare 1 Trigger +// <0x21=> TC6 Overflow Trigger +// <0x22=> TC6 Match/Compare 0 Trigger +// <0x23=> TC6 Match/Compare 1 Trigger +// <0x24=> TC7 Overflow Trigger +// <0x25=> TC7 Match/Compare 0 Trigger +// <0x26=> TC7 Match/Compare 1 Trigger +// <0x27=> ADC Result Ready Trigger +// <0x28=> DAC Empty Trigger +// <0x29=> I2S Rx 0 Trigger +// <0x2A=> I2S Rx 1 Trigger +// <0x2B=> I2S Tx 0 Trigger +// <0x2C=> I2S Tx 1 Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_5 +#ifndef CONF_DMAC_TRIGSRC_5 +#define CONF_DMAC_TRIGSRC_5 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_5 +#ifndef CONF_DMAC_LVL_5 +#define CONF_DMAC_LVL_5 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_5 +#ifndef CONF_DMAC_EVOE_5 +#define CONF_DMAC_EVOE_5 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_5 +#ifndef CONF_DMAC_EVIE_5 +#define CONF_DMAC_EVIE_5 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_5 +#ifndef CONF_DMAC_EVACT_5 +#define CONF_DMAC_EVACT_5 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_5 +#ifndef CONF_DMAC_STEPSIZE_5 +#define CONF_DMAC_STEPSIZE_5 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_5 +#ifndef CONF_DMAC_STEPSEL_5 +#define CONF_DMAC_STEPSEL_5 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_5 +#ifndef CONF_DMAC_SRCINC_5 +#define CONF_DMAC_SRCINC_5 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_5 +#ifndef CONF_DMAC_DSTINC_5 +#define CONF_DMAC_DSTINC_5 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_5 +#ifndef CONF_DMAC_BEATSIZE_5 +#define CONF_DMAC_BEATSIZE_5 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_5 +#ifndef CONF_DMAC_BLOCKACT_5 +#define CONF_DMAC_BLOCKACT_5 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_5 +#ifndef CONF_DMAC_EVOSEL_5 +#define CONF_DMAC_EVOSEL_5 0 +#endif +// + +// Channel 6 settings +// dmac_channel_6_settings +#ifndef CONF_DMAC_CHANNEL_6_SETTINGS +#define CONF_DMAC_CHANNEL_6_SETTINGS 0 +#endif + +// Channel Enable +// Indicates whether channel 6 is enabled or not +// dmac_enable_6 +#ifndef CONF_DMAC_ENABLE_6 +#define CONF_DMAC_ENABLE_6 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_6 +#ifndef CONF_DMAC_TRIGACT_6 +#define CONF_DMAC_TRIGACT_6 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> SERCOM0 RX Trigger +// <0x02=> SERCOM0 TX Trigger +// <0x03=> SERCOM1 RX Trigger +// <0x04=> SERCOM1 TX Trigger +// <0x05=> SERCOM2 RX Trigger +// <0x06=> SERCOM2 TX Trigger +// <0x07=> SERCOM3 RX Trigger +// <0x08=> SERCOM3 TX Trigger +// <0x09=> SERCOM4 RX Trigger +// <0x0A=> SERCOM4 TX Trigger +// <0x0B=> SERCOM5 RX Trigger +// <0x0C=> SERCOM5 TX Trigger +// <0x0D=> TCC0 Overflow Trigger +// <0x0E=> TCC0 Match/Compare 0 Trigger +// <0x0F=> TCC0 Match/Compare 1 Trigger +// <0x10=> TCC0 Match/Compare 2 Trigger +// <0x11=> TCC0 Match/Compare 3 Trigger +// <0x12=> TCC1 Overflow Trigger +// <0x13=> TCC1 Match/Compare 0 Trigger +// <0x14=> TCC1 Match/Compare 1 Trigger +// <0x15=> TCC2 Overflow Trigger +// <0x16=> TCC2 Match/Compare 0 Trigger +// <0x17=> TCC2 Match/Compare 1 Trigger +// <0x18=> TC3 Overflow Trigger +// <0x19=> TC3 Match/Compare 0 Trigger +// <0x1A=> TC3 Match/Compare 1 Trigger +// <0x1B=> TC4 Overflow Trigger +// <0x1C=> TC4 Match/Compare 0 Trigger +// <0x1D=> TC4 Match/Compare 1 Trigger +// <0x1E=> TC5 Overflow Trigger +// <0x1F=> TC5 Match/Compare 0 Trigger +// <0x20=> TC5 Match/Compare 1 Trigger +// <0x21=> TC6 Overflow Trigger +// <0x22=> TC6 Match/Compare 0 Trigger +// <0x23=> TC6 Match/Compare 1 Trigger +// <0x24=> TC7 Overflow Trigger +// <0x25=> TC7 Match/Compare 0 Trigger +// <0x26=> TC7 Match/Compare 1 Trigger +// <0x27=> ADC Result Ready Trigger +// <0x28=> DAC Empty Trigger +// <0x29=> I2S Rx 0 Trigger +// <0x2A=> I2S Rx 1 Trigger +// <0x2B=> I2S Tx 0 Trigger +// <0x2C=> I2S Tx 1 Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_6 +#ifndef CONF_DMAC_TRIGSRC_6 +#define CONF_DMAC_TRIGSRC_6 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_6 +#ifndef CONF_DMAC_LVL_6 +#define CONF_DMAC_LVL_6 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_6 +#ifndef CONF_DMAC_EVOE_6 +#define CONF_DMAC_EVOE_6 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_6 +#ifndef CONF_DMAC_EVIE_6 +#define CONF_DMAC_EVIE_6 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_6 +#ifndef CONF_DMAC_EVACT_6 +#define CONF_DMAC_EVACT_6 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_6 +#ifndef CONF_DMAC_STEPSIZE_6 +#define CONF_DMAC_STEPSIZE_6 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_6 +#ifndef CONF_DMAC_STEPSEL_6 +#define CONF_DMAC_STEPSEL_6 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_6 +#ifndef CONF_DMAC_SRCINC_6 +#define CONF_DMAC_SRCINC_6 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_6 +#ifndef CONF_DMAC_DSTINC_6 +#define CONF_DMAC_DSTINC_6 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_6 +#ifndef CONF_DMAC_BEATSIZE_6 +#define CONF_DMAC_BEATSIZE_6 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_6 +#ifndef CONF_DMAC_BLOCKACT_6 +#define CONF_DMAC_BLOCKACT_6 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_6 +#ifndef CONF_DMAC_EVOSEL_6 +#define CONF_DMAC_EVOSEL_6 0 +#endif +// + +// Channel 7 settings +// dmac_channel_7_settings +#ifndef CONF_DMAC_CHANNEL_7_SETTINGS +#define CONF_DMAC_CHANNEL_7_SETTINGS 0 +#endif + +// Channel Enable +// Indicates whether channel 7 is enabled or not +// dmac_enable_7 +#ifndef CONF_DMAC_ENABLE_7 +#define CONF_DMAC_ENABLE_7 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_7 +#ifndef CONF_DMAC_TRIGACT_7 +#define CONF_DMAC_TRIGACT_7 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> SERCOM0 RX Trigger +// <0x02=> SERCOM0 TX Trigger +// <0x03=> SERCOM1 RX Trigger +// <0x04=> SERCOM1 TX Trigger +// <0x05=> SERCOM2 RX Trigger +// <0x06=> SERCOM2 TX Trigger +// <0x07=> SERCOM3 RX Trigger +// <0x08=> SERCOM3 TX Trigger +// <0x09=> SERCOM4 RX Trigger +// <0x0A=> SERCOM4 TX Trigger +// <0x0B=> SERCOM5 RX Trigger +// <0x0C=> SERCOM5 TX Trigger +// <0x0D=> TCC0 Overflow Trigger +// <0x0E=> TCC0 Match/Compare 0 Trigger +// <0x0F=> TCC0 Match/Compare 1 Trigger +// <0x10=> TCC0 Match/Compare 2 Trigger +// <0x11=> TCC0 Match/Compare 3 Trigger +// <0x12=> TCC1 Overflow Trigger +// <0x13=> TCC1 Match/Compare 0 Trigger +// <0x14=> TCC1 Match/Compare 1 Trigger +// <0x15=> TCC2 Overflow Trigger +// <0x16=> TCC2 Match/Compare 0 Trigger +// <0x17=> TCC2 Match/Compare 1 Trigger +// <0x18=> TC3 Overflow Trigger +// <0x19=> TC3 Match/Compare 0 Trigger +// <0x1A=> TC3 Match/Compare 1 Trigger +// <0x1B=> TC4 Overflow Trigger +// <0x1C=> TC4 Match/Compare 0 Trigger +// <0x1D=> TC4 Match/Compare 1 Trigger +// <0x1E=> TC5 Overflow Trigger +// <0x1F=> TC5 Match/Compare 0 Trigger +// <0x20=> TC5 Match/Compare 1 Trigger +// <0x21=> TC6 Overflow Trigger +// <0x22=> TC6 Match/Compare 0 Trigger +// <0x23=> TC6 Match/Compare 1 Trigger +// <0x24=> TC7 Overflow Trigger +// <0x25=> TC7 Match/Compare 0 Trigger +// <0x26=> TC7 Match/Compare 1 Trigger +// <0x27=> ADC Result Ready Trigger +// <0x28=> DAC Empty Trigger +// <0x29=> I2S Rx 0 Trigger +// <0x2A=> I2S Rx 1 Trigger +// <0x2B=> I2S Tx 0 Trigger +// <0x2C=> I2S Tx 1 Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_7 +#ifndef CONF_DMAC_TRIGSRC_7 +#define CONF_DMAC_TRIGSRC_7 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_7 +#ifndef CONF_DMAC_LVL_7 +#define CONF_DMAC_LVL_7 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_7 +#ifndef CONF_DMAC_EVOE_7 +#define CONF_DMAC_EVOE_7 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_7 +#ifndef CONF_DMAC_EVIE_7 +#define CONF_DMAC_EVIE_7 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_7 +#ifndef CONF_DMAC_EVACT_7 +#define CONF_DMAC_EVACT_7 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_7 +#ifndef CONF_DMAC_STEPSIZE_7 +#define CONF_DMAC_STEPSIZE_7 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_7 +#ifndef CONF_DMAC_STEPSEL_7 +#define CONF_DMAC_STEPSEL_7 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_7 +#ifndef CONF_DMAC_SRCINC_7 +#define CONF_DMAC_SRCINC_7 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_7 +#ifndef CONF_DMAC_DSTINC_7 +#define CONF_DMAC_DSTINC_7 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_7 +#ifndef CONF_DMAC_BEATSIZE_7 +#define CONF_DMAC_BEATSIZE_7 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_7 +#ifndef CONF_DMAC_BLOCKACT_7 +#define CONF_DMAC_BLOCKACT_7 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_7 +#ifndef CONF_DMAC_EVOSEL_7 +#define CONF_DMAC_EVOSEL_7 0 +#endif +// + +// Channel 8 settings +// dmac_channel_8_settings +#ifndef CONF_DMAC_CHANNEL_8_SETTINGS +#define CONF_DMAC_CHANNEL_8_SETTINGS 0 +#endif + +// Channel Enable +// Indicates whether channel 8 is enabled or not +// dmac_enable_8 +#ifndef CONF_DMAC_ENABLE_8 +#define CONF_DMAC_ENABLE_8 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_8 +#ifndef CONF_DMAC_TRIGACT_8 +#define CONF_DMAC_TRIGACT_8 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> SERCOM0 RX Trigger +// <0x02=> SERCOM0 TX Trigger +// <0x03=> SERCOM1 RX Trigger +// <0x04=> SERCOM1 TX Trigger +// <0x05=> SERCOM2 RX Trigger +// <0x06=> SERCOM2 TX Trigger +// <0x07=> SERCOM3 RX Trigger +// <0x08=> SERCOM3 TX Trigger +// <0x09=> SERCOM4 RX Trigger +// <0x0A=> SERCOM4 TX Trigger +// <0x0B=> SERCOM5 RX Trigger +// <0x0C=> SERCOM5 TX Trigger +// <0x0D=> TCC0 Overflow Trigger +// <0x0E=> TCC0 Match/Compare 0 Trigger +// <0x0F=> TCC0 Match/Compare 1 Trigger +// <0x10=> TCC0 Match/Compare 2 Trigger +// <0x11=> TCC0 Match/Compare 3 Trigger +// <0x12=> TCC1 Overflow Trigger +// <0x13=> TCC1 Match/Compare 0 Trigger +// <0x14=> TCC1 Match/Compare 1 Trigger +// <0x15=> TCC2 Overflow Trigger +// <0x16=> TCC2 Match/Compare 0 Trigger +// <0x17=> TCC2 Match/Compare 1 Trigger +// <0x18=> TC3 Overflow Trigger +// <0x19=> TC3 Match/Compare 0 Trigger +// <0x1A=> TC3 Match/Compare 1 Trigger +// <0x1B=> TC4 Overflow Trigger +// <0x1C=> TC4 Match/Compare 0 Trigger +// <0x1D=> TC4 Match/Compare 1 Trigger +// <0x1E=> TC5 Overflow Trigger +// <0x1F=> TC5 Match/Compare 0 Trigger +// <0x20=> TC5 Match/Compare 1 Trigger +// <0x21=> TC6 Overflow Trigger +// <0x22=> TC6 Match/Compare 0 Trigger +// <0x23=> TC6 Match/Compare 1 Trigger +// <0x24=> TC7 Overflow Trigger +// <0x25=> TC7 Match/Compare 0 Trigger +// <0x26=> TC7 Match/Compare 1 Trigger +// <0x27=> ADC Result Ready Trigger +// <0x28=> DAC Empty Trigger +// <0x29=> I2S Rx 0 Trigger +// <0x2A=> I2S Rx 1 Trigger +// <0x2B=> I2S Tx 0 Trigger +// <0x2C=> I2S Tx 1 Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_8 +#ifndef CONF_DMAC_TRIGSRC_8 +#define CONF_DMAC_TRIGSRC_8 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_8 +#ifndef CONF_DMAC_LVL_8 +#define CONF_DMAC_LVL_8 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_8 +#ifndef CONF_DMAC_EVOE_8 +#define CONF_DMAC_EVOE_8 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_8 +#ifndef CONF_DMAC_EVIE_8 +#define CONF_DMAC_EVIE_8 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_8 +#ifndef CONF_DMAC_EVACT_8 +#define CONF_DMAC_EVACT_8 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_8 +#ifndef CONF_DMAC_STEPSIZE_8 +#define CONF_DMAC_STEPSIZE_8 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_8 +#ifndef CONF_DMAC_STEPSEL_8 +#define CONF_DMAC_STEPSEL_8 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_8 +#ifndef CONF_DMAC_SRCINC_8 +#define CONF_DMAC_SRCINC_8 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_8 +#ifndef CONF_DMAC_DSTINC_8 +#define CONF_DMAC_DSTINC_8 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_8 +#ifndef CONF_DMAC_BEATSIZE_8 +#define CONF_DMAC_BEATSIZE_8 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_8 +#ifndef CONF_DMAC_BLOCKACT_8 +#define CONF_DMAC_BLOCKACT_8 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_8 +#ifndef CONF_DMAC_EVOSEL_8 +#define CONF_DMAC_EVOSEL_8 0 +#endif +// + +// Channel 9 settings +// dmac_channel_9_settings +#ifndef CONF_DMAC_CHANNEL_9_SETTINGS +#define CONF_DMAC_CHANNEL_9_SETTINGS 0 +#endif + +// Channel Enable +// Indicates whether channel 9 is enabled or not +// dmac_enable_9 +#ifndef CONF_DMAC_ENABLE_9 +#define CONF_DMAC_ENABLE_9 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_9 +#ifndef CONF_DMAC_TRIGACT_9 +#define CONF_DMAC_TRIGACT_9 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> SERCOM0 RX Trigger +// <0x02=> SERCOM0 TX Trigger +// <0x03=> SERCOM1 RX Trigger +// <0x04=> SERCOM1 TX Trigger +// <0x05=> SERCOM2 RX Trigger +// <0x06=> SERCOM2 TX Trigger +// <0x07=> SERCOM3 RX Trigger +// <0x08=> SERCOM3 TX Trigger +// <0x09=> SERCOM4 RX Trigger +// <0x0A=> SERCOM4 TX Trigger +// <0x0B=> SERCOM5 RX Trigger +// <0x0C=> SERCOM5 TX Trigger +// <0x0D=> TCC0 Overflow Trigger +// <0x0E=> TCC0 Match/Compare 0 Trigger +// <0x0F=> TCC0 Match/Compare 1 Trigger +// <0x10=> TCC0 Match/Compare 2 Trigger +// <0x11=> TCC0 Match/Compare 3 Trigger +// <0x12=> TCC1 Overflow Trigger +// <0x13=> TCC1 Match/Compare 0 Trigger +// <0x14=> TCC1 Match/Compare 1 Trigger +// <0x15=> TCC2 Overflow Trigger +// <0x16=> TCC2 Match/Compare 0 Trigger +// <0x17=> TCC2 Match/Compare 1 Trigger +// <0x18=> TC3 Overflow Trigger +// <0x19=> TC3 Match/Compare 0 Trigger +// <0x1A=> TC3 Match/Compare 1 Trigger +// <0x1B=> TC4 Overflow Trigger +// <0x1C=> TC4 Match/Compare 0 Trigger +// <0x1D=> TC4 Match/Compare 1 Trigger +// <0x1E=> TC5 Overflow Trigger +// <0x1F=> TC5 Match/Compare 0 Trigger +// <0x20=> TC5 Match/Compare 1 Trigger +// <0x21=> TC6 Overflow Trigger +// <0x22=> TC6 Match/Compare 0 Trigger +// <0x23=> TC6 Match/Compare 1 Trigger +// <0x24=> TC7 Overflow Trigger +// <0x25=> TC7 Match/Compare 0 Trigger +// <0x26=> TC7 Match/Compare 1 Trigger +// <0x27=> ADC Result Ready Trigger +// <0x28=> DAC Empty Trigger +// <0x29=> I2S Rx 0 Trigger +// <0x2A=> I2S Rx 1 Trigger +// <0x2B=> I2S Tx 0 Trigger +// <0x2C=> I2S Tx 1 Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_9 +#ifndef CONF_DMAC_TRIGSRC_9 +#define CONF_DMAC_TRIGSRC_9 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_9 +#ifndef CONF_DMAC_LVL_9 +#define CONF_DMAC_LVL_9 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_9 +#ifndef CONF_DMAC_EVOE_9 +#define CONF_DMAC_EVOE_9 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_9 +#ifndef CONF_DMAC_EVIE_9 +#define CONF_DMAC_EVIE_9 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_9 +#ifndef CONF_DMAC_EVACT_9 +#define CONF_DMAC_EVACT_9 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_9 +#ifndef CONF_DMAC_STEPSIZE_9 +#define CONF_DMAC_STEPSIZE_9 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_9 +#ifndef CONF_DMAC_STEPSEL_9 +#define CONF_DMAC_STEPSEL_9 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_9 +#ifndef CONF_DMAC_SRCINC_9 +#define CONF_DMAC_SRCINC_9 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_9 +#ifndef CONF_DMAC_DSTINC_9 +#define CONF_DMAC_DSTINC_9 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_9 +#ifndef CONF_DMAC_BEATSIZE_9 +#define CONF_DMAC_BEATSIZE_9 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_9 +#ifndef CONF_DMAC_BLOCKACT_9 +#define CONF_DMAC_BLOCKACT_9 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_9 +#ifndef CONF_DMAC_EVOSEL_9 +#define CONF_DMAC_EVOSEL_9 0 +#endif +// + +// Channel 10 settings +// dmac_channel_10_settings +#ifndef CONF_DMAC_CHANNEL_10_SETTINGS +#define CONF_DMAC_CHANNEL_10_SETTINGS 0 +#endif + +// Channel Enable +// Indicates whether channel 10 is enabled or not +// dmac_enable_10 +#ifndef CONF_DMAC_ENABLE_10 +#define CONF_DMAC_ENABLE_10 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_10 +#ifndef CONF_DMAC_TRIGACT_10 +#define CONF_DMAC_TRIGACT_10 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> SERCOM0 RX Trigger +// <0x02=> SERCOM0 TX Trigger +// <0x03=> SERCOM1 RX Trigger +// <0x04=> SERCOM1 TX Trigger +// <0x05=> SERCOM2 RX Trigger +// <0x06=> SERCOM2 TX Trigger +// <0x07=> SERCOM3 RX Trigger +// <0x08=> SERCOM3 TX Trigger +// <0x09=> SERCOM4 RX Trigger +// <0x0A=> SERCOM4 TX Trigger +// <0x0B=> SERCOM5 RX Trigger +// <0x0C=> SERCOM5 TX Trigger +// <0x0D=> TCC0 Overflow Trigger +// <0x0E=> TCC0 Match/Compare 0 Trigger +// <0x0F=> TCC0 Match/Compare 1 Trigger +// <0x10=> TCC0 Match/Compare 2 Trigger +// <0x11=> TCC0 Match/Compare 3 Trigger +// <0x12=> TCC1 Overflow Trigger +// <0x13=> TCC1 Match/Compare 0 Trigger +// <0x14=> TCC1 Match/Compare 1 Trigger +// <0x15=> TCC2 Overflow Trigger +// <0x16=> TCC2 Match/Compare 0 Trigger +// <0x17=> TCC2 Match/Compare 1 Trigger +// <0x18=> TC3 Overflow Trigger +// <0x19=> TC3 Match/Compare 0 Trigger +// <0x1A=> TC3 Match/Compare 1 Trigger +// <0x1B=> TC4 Overflow Trigger +// <0x1C=> TC4 Match/Compare 0 Trigger +// <0x1D=> TC4 Match/Compare 1 Trigger +// <0x1E=> TC5 Overflow Trigger +// <0x1F=> TC5 Match/Compare 0 Trigger +// <0x20=> TC5 Match/Compare 1 Trigger +// <0x21=> TC6 Overflow Trigger +// <0x22=> TC6 Match/Compare 0 Trigger +// <0x23=> TC6 Match/Compare 1 Trigger +// <0x24=> TC7 Overflow Trigger +// <0x25=> TC7 Match/Compare 0 Trigger +// <0x26=> TC7 Match/Compare 1 Trigger +// <0x27=> ADC Result Ready Trigger +// <0x28=> DAC Empty Trigger +// <0x29=> I2S Rx 0 Trigger +// <0x2A=> I2S Rx 1 Trigger +// <0x2B=> I2S Tx 0 Trigger +// <0x2C=> I2S Tx 1 Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_10 +#ifndef CONF_DMAC_TRIGSRC_10 +#define CONF_DMAC_TRIGSRC_10 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_10 +#ifndef CONF_DMAC_LVL_10 +#define CONF_DMAC_LVL_10 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_10 +#ifndef CONF_DMAC_EVOE_10 +#define CONF_DMAC_EVOE_10 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_10 +#ifndef CONF_DMAC_EVIE_10 +#define CONF_DMAC_EVIE_10 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_10 +#ifndef CONF_DMAC_EVACT_10 +#define CONF_DMAC_EVACT_10 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_10 +#ifndef CONF_DMAC_STEPSIZE_10 +#define CONF_DMAC_STEPSIZE_10 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_10 +#ifndef CONF_DMAC_STEPSEL_10 +#define CONF_DMAC_STEPSEL_10 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_10 +#ifndef CONF_DMAC_SRCINC_10 +#define CONF_DMAC_SRCINC_10 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_10 +#ifndef CONF_DMAC_DSTINC_10 +#define CONF_DMAC_DSTINC_10 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_10 +#ifndef CONF_DMAC_BEATSIZE_10 +#define CONF_DMAC_BEATSIZE_10 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_10 +#ifndef CONF_DMAC_BLOCKACT_10 +#define CONF_DMAC_BLOCKACT_10 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_10 +#ifndef CONF_DMAC_EVOSEL_10 +#define CONF_DMAC_EVOSEL_10 0 +#endif +// + +// Channel 11 settings +// dmac_channel_11_settings +#ifndef CONF_DMAC_CHANNEL_11_SETTINGS +#define CONF_DMAC_CHANNEL_11_SETTINGS 0 +#endif + +// Channel Enable +// Indicates whether channel 11 is enabled or not +// dmac_enable_11 +#ifndef CONF_DMAC_ENABLE_11 +#define CONF_DMAC_ENABLE_11 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_11 +#ifndef CONF_DMAC_TRIGACT_11 +#define CONF_DMAC_TRIGACT_11 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> SERCOM0 RX Trigger +// <0x02=> SERCOM0 TX Trigger +// <0x03=> SERCOM1 RX Trigger +// <0x04=> SERCOM1 TX Trigger +// <0x05=> SERCOM2 RX Trigger +// <0x06=> SERCOM2 TX Trigger +// <0x07=> SERCOM3 RX Trigger +// <0x08=> SERCOM3 TX Trigger +// <0x09=> SERCOM4 RX Trigger +// <0x0A=> SERCOM4 TX Trigger +// <0x0B=> SERCOM5 RX Trigger +// <0x0C=> SERCOM5 TX Trigger +// <0x0D=> TCC0 Overflow Trigger +// <0x0E=> TCC0 Match/Compare 0 Trigger +// <0x0F=> TCC0 Match/Compare 1 Trigger +// <0x10=> TCC0 Match/Compare 2 Trigger +// <0x11=> TCC0 Match/Compare 3 Trigger +// <0x12=> TCC1 Overflow Trigger +// <0x13=> TCC1 Match/Compare 0 Trigger +// <0x14=> TCC1 Match/Compare 1 Trigger +// <0x15=> TCC2 Overflow Trigger +// <0x16=> TCC2 Match/Compare 0 Trigger +// <0x17=> TCC2 Match/Compare 1 Trigger +// <0x18=> TC3 Overflow Trigger +// <0x19=> TC3 Match/Compare 0 Trigger +// <0x1A=> TC3 Match/Compare 1 Trigger +// <0x1B=> TC4 Overflow Trigger +// <0x1C=> TC4 Match/Compare 0 Trigger +// <0x1D=> TC4 Match/Compare 1 Trigger +// <0x1E=> TC5 Overflow Trigger +// <0x1F=> TC5 Match/Compare 0 Trigger +// <0x20=> TC5 Match/Compare 1 Trigger +// <0x21=> TC6 Overflow Trigger +// <0x22=> TC6 Match/Compare 0 Trigger +// <0x23=> TC6 Match/Compare 1 Trigger +// <0x24=> TC7 Overflow Trigger +// <0x25=> TC7 Match/Compare 0 Trigger +// <0x26=> TC7 Match/Compare 1 Trigger +// <0x27=> ADC Result Ready Trigger +// <0x28=> DAC Empty Trigger +// <0x29=> I2S Rx 0 Trigger +// <0x2A=> I2S Rx 1 Trigger +// <0x2B=> I2S Tx 0 Trigger +// <0x2C=> I2S Tx 1 Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_11 +#ifndef CONF_DMAC_TRIGSRC_11 +#define CONF_DMAC_TRIGSRC_11 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_11 +#ifndef CONF_DMAC_LVL_11 +#define CONF_DMAC_LVL_11 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_11 +#ifndef CONF_DMAC_EVOE_11 +#define CONF_DMAC_EVOE_11 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_11 +#ifndef CONF_DMAC_EVIE_11 +#define CONF_DMAC_EVIE_11 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_11 +#ifndef CONF_DMAC_EVACT_11 +#define CONF_DMAC_EVACT_11 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_11 +#ifndef CONF_DMAC_STEPSIZE_11 +#define CONF_DMAC_STEPSIZE_11 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_11 +#ifndef CONF_DMAC_STEPSEL_11 +#define CONF_DMAC_STEPSEL_11 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_11 +#ifndef CONF_DMAC_SRCINC_11 +#define CONF_DMAC_SRCINC_11 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_11 +#ifndef CONF_DMAC_DSTINC_11 +#define CONF_DMAC_DSTINC_11 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_11 +#ifndef CONF_DMAC_BEATSIZE_11 +#define CONF_DMAC_BEATSIZE_11 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_11 +#ifndef CONF_DMAC_BLOCKACT_11 +#define CONF_DMAC_BLOCKACT_11 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_11 +#ifndef CONF_DMAC_EVOSEL_11 +#define CONF_DMAC_EVOSEL_11 0 +#endif +// + +// Channel 12 settings +// dmac_channel_12_settings +#ifndef CONF_DMAC_CHANNEL_12_SETTINGS +#define CONF_DMAC_CHANNEL_12_SETTINGS 0 +#endif + +// Channel Enable +// Indicates whether channel 12 is enabled or not +// dmac_enable_12 +#ifndef CONF_DMAC_ENABLE_12 +#define CONF_DMAC_ENABLE_12 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_12 +#ifndef CONF_DMAC_TRIGACT_12 +#define CONF_DMAC_TRIGACT_12 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> SERCOM0 RX Trigger +// <0x02=> SERCOM0 TX Trigger +// <0x03=> SERCOM1 RX Trigger +// <0x04=> SERCOM1 TX Trigger +// <0x05=> SERCOM2 RX Trigger +// <0x06=> SERCOM2 TX Trigger +// <0x07=> SERCOM3 RX Trigger +// <0x08=> SERCOM3 TX Trigger +// <0x09=> SERCOM4 RX Trigger +// <0x0A=> SERCOM4 TX Trigger +// <0x0B=> SERCOM5 RX Trigger +// <0x0C=> SERCOM5 TX Trigger +// <0x0D=> TCC0 Overflow Trigger +// <0x0E=> TCC0 Match/Compare 0 Trigger +// <0x0F=> TCC0 Match/Compare 1 Trigger +// <0x10=> TCC0 Match/Compare 2 Trigger +// <0x11=> TCC0 Match/Compare 3 Trigger +// <0x12=> TCC1 Overflow Trigger +// <0x13=> TCC1 Match/Compare 0 Trigger +// <0x14=> TCC1 Match/Compare 1 Trigger +// <0x15=> TCC2 Overflow Trigger +// <0x16=> TCC2 Match/Compare 0 Trigger +// <0x17=> TCC2 Match/Compare 1 Trigger +// <0x18=> TC3 Overflow Trigger +// <0x19=> TC3 Match/Compare 0 Trigger +// <0x1A=> TC3 Match/Compare 1 Trigger +// <0x1B=> TC4 Overflow Trigger +// <0x1C=> TC4 Match/Compare 0 Trigger +// <0x1D=> TC4 Match/Compare 1 Trigger +// <0x1E=> TC5 Overflow Trigger +// <0x1F=> TC5 Match/Compare 0 Trigger +// <0x20=> TC5 Match/Compare 1 Trigger +// <0x21=> TC6 Overflow Trigger +// <0x22=> TC6 Match/Compare 0 Trigger +// <0x23=> TC6 Match/Compare 1 Trigger +// <0x24=> TC7 Overflow Trigger +// <0x25=> TC7 Match/Compare 0 Trigger +// <0x26=> TC7 Match/Compare 1 Trigger +// <0x27=> ADC Result Ready Trigger +// <0x28=> DAC Empty Trigger +// <0x29=> I2S Rx 0 Trigger +// <0x2A=> I2S Rx 1 Trigger +// <0x2B=> I2S Tx 0 Trigger +// <0x2C=> I2S Tx 1 Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_12 +#ifndef CONF_DMAC_TRIGSRC_12 +#define CONF_DMAC_TRIGSRC_12 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_12 +#ifndef CONF_DMAC_LVL_12 +#define CONF_DMAC_LVL_12 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_12 +#ifndef CONF_DMAC_EVOE_12 +#define CONF_DMAC_EVOE_12 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_12 +#ifndef CONF_DMAC_EVIE_12 +#define CONF_DMAC_EVIE_12 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_12 +#ifndef CONF_DMAC_EVACT_12 +#define CONF_DMAC_EVACT_12 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_12 +#ifndef CONF_DMAC_STEPSIZE_12 +#define CONF_DMAC_STEPSIZE_12 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_12 +#ifndef CONF_DMAC_STEPSEL_12 +#define CONF_DMAC_STEPSEL_12 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_12 +#ifndef CONF_DMAC_SRCINC_12 +#define CONF_DMAC_SRCINC_12 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_12 +#ifndef CONF_DMAC_DSTINC_12 +#define CONF_DMAC_DSTINC_12 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_12 +#ifndef CONF_DMAC_BEATSIZE_12 +#define CONF_DMAC_BEATSIZE_12 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_12 +#ifndef CONF_DMAC_BLOCKACT_12 +#define CONF_DMAC_BLOCKACT_12 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_12 +#ifndef CONF_DMAC_EVOSEL_12 +#define CONF_DMAC_EVOSEL_12 0 +#endif +// + +// Channel 13 settings +// dmac_channel_13_settings +#ifndef CONF_DMAC_CHANNEL_13_SETTINGS +#define CONF_DMAC_CHANNEL_13_SETTINGS 0 +#endif + +// Channel Enable +// Indicates whether channel 13 is enabled or not +// dmac_enable_13 +#ifndef CONF_DMAC_ENABLE_13 +#define CONF_DMAC_ENABLE_13 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_13 +#ifndef CONF_DMAC_TRIGACT_13 +#define CONF_DMAC_TRIGACT_13 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> SERCOM0 RX Trigger +// <0x02=> SERCOM0 TX Trigger +// <0x03=> SERCOM1 RX Trigger +// <0x04=> SERCOM1 TX Trigger +// <0x05=> SERCOM2 RX Trigger +// <0x06=> SERCOM2 TX Trigger +// <0x07=> SERCOM3 RX Trigger +// <0x08=> SERCOM3 TX Trigger +// <0x09=> SERCOM4 RX Trigger +// <0x0A=> SERCOM4 TX Trigger +// <0x0B=> SERCOM5 RX Trigger +// <0x0C=> SERCOM5 TX Trigger +// <0x0D=> TCC0 Overflow Trigger +// <0x0E=> TCC0 Match/Compare 0 Trigger +// <0x0F=> TCC0 Match/Compare 1 Trigger +// <0x10=> TCC0 Match/Compare 2 Trigger +// <0x11=> TCC0 Match/Compare 3 Trigger +// <0x12=> TCC1 Overflow Trigger +// <0x13=> TCC1 Match/Compare 0 Trigger +// <0x14=> TCC1 Match/Compare 1 Trigger +// <0x15=> TCC2 Overflow Trigger +// <0x16=> TCC2 Match/Compare 0 Trigger +// <0x17=> TCC2 Match/Compare 1 Trigger +// <0x18=> TC3 Overflow Trigger +// <0x19=> TC3 Match/Compare 0 Trigger +// <0x1A=> TC3 Match/Compare 1 Trigger +// <0x1B=> TC4 Overflow Trigger +// <0x1C=> TC4 Match/Compare 0 Trigger +// <0x1D=> TC4 Match/Compare 1 Trigger +// <0x1E=> TC5 Overflow Trigger +// <0x1F=> TC5 Match/Compare 0 Trigger +// <0x20=> TC5 Match/Compare 1 Trigger +// <0x21=> TC6 Overflow Trigger +// <0x22=> TC6 Match/Compare 0 Trigger +// <0x23=> TC6 Match/Compare 1 Trigger +// <0x24=> TC7 Overflow Trigger +// <0x25=> TC7 Match/Compare 0 Trigger +// <0x26=> TC7 Match/Compare 1 Trigger +// <0x27=> ADC Result Ready Trigger +// <0x28=> DAC Empty Trigger +// <0x29=> I2S Rx 0 Trigger +// <0x2A=> I2S Rx 1 Trigger +// <0x2B=> I2S Tx 0 Trigger +// <0x2C=> I2S Tx 1 Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_13 +#ifndef CONF_DMAC_TRIGSRC_13 +#define CONF_DMAC_TRIGSRC_13 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_13 +#ifndef CONF_DMAC_LVL_13 +#define CONF_DMAC_LVL_13 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_13 +#ifndef CONF_DMAC_EVOE_13 +#define CONF_DMAC_EVOE_13 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_13 +#ifndef CONF_DMAC_EVIE_13 +#define CONF_DMAC_EVIE_13 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_13 +#ifndef CONF_DMAC_EVACT_13 +#define CONF_DMAC_EVACT_13 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_13 +#ifndef CONF_DMAC_STEPSIZE_13 +#define CONF_DMAC_STEPSIZE_13 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_13 +#ifndef CONF_DMAC_STEPSEL_13 +#define CONF_DMAC_STEPSEL_13 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_13 +#ifndef CONF_DMAC_SRCINC_13 +#define CONF_DMAC_SRCINC_13 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_13 +#ifndef CONF_DMAC_DSTINC_13 +#define CONF_DMAC_DSTINC_13 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_13 +#ifndef CONF_DMAC_BEATSIZE_13 +#define CONF_DMAC_BEATSIZE_13 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_13 +#ifndef CONF_DMAC_BLOCKACT_13 +#define CONF_DMAC_BLOCKACT_13 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_13 +#ifndef CONF_DMAC_EVOSEL_13 +#define CONF_DMAC_EVOSEL_13 0 +#endif +// + +// Channel 14 settings +// dmac_channel_14_settings +#ifndef CONF_DMAC_CHANNEL_14_SETTINGS +#define CONF_DMAC_CHANNEL_14_SETTINGS 0 +#endif + +// Channel Enable +// Indicates whether channel 14 is enabled or not +// dmac_enable_14 +#ifndef CONF_DMAC_ENABLE_14 +#define CONF_DMAC_ENABLE_14 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_14 +#ifndef CONF_DMAC_TRIGACT_14 +#define CONF_DMAC_TRIGACT_14 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> SERCOM0 RX Trigger +// <0x02=> SERCOM0 TX Trigger +// <0x03=> SERCOM1 RX Trigger +// <0x04=> SERCOM1 TX Trigger +// <0x05=> SERCOM2 RX Trigger +// <0x06=> SERCOM2 TX Trigger +// <0x07=> SERCOM3 RX Trigger +// <0x08=> SERCOM3 TX Trigger +// <0x09=> SERCOM4 RX Trigger +// <0x0A=> SERCOM4 TX Trigger +// <0x0B=> SERCOM5 RX Trigger +// <0x0C=> SERCOM5 TX Trigger +// <0x0D=> TCC0 Overflow Trigger +// <0x0E=> TCC0 Match/Compare 0 Trigger +// <0x0F=> TCC0 Match/Compare 1 Trigger +// <0x10=> TCC0 Match/Compare 2 Trigger +// <0x11=> TCC0 Match/Compare 3 Trigger +// <0x12=> TCC1 Overflow Trigger +// <0x13=> TCC1 Match/Compare 0 Trigger +// <0x14=> TCC1 Match/Compare 1 Trigger +// <0x15=> TCC2 Overflow Trigger +// <0x16=> TCC2 Match/Compare 0 Trigger +// <0x17=> TCC2 Match/Compare 1 Trigger +// <0x18=> TC3 Overflow Trigger +// <0x19=> TC3 Match/Compare 0 Trigger +// <0x1A=> TC3 Match/Compare 1 Trigger +// <0x1B=> TC4 Overflow Trigger +// <0x1C=> TC4 Match/Compare 0 Trigger +// <0x1D=> TC4 Match/Compare 1 Trigger +// <0x1E=> TC5 Overflow Trigger +// <0x1F=> TC5 Match/Compare 0 Trigger +// <0x20=> TC5 Match/Compare 1 Trigger +// <0x21=> TC6 Overflow Trigger +// <0x22=> TC6 Match/Compare 0 Trigger +// <0x23=> TC6 Match/Compare 1 Trigger +// <0x24=> TC7 Overflow Trigger +// <0x25=> TC7 Match/Compare 0 Trigger +// <0x26=> TC7 Match/Compare 1 Trigger +// <0x27=> ADC Result Ready Trigger +// <0x28=> DAC Empty Trigger +// <0x29=> I2S Rx 0 Trigger +// <0x2A=> I2S Rx 1 Trigger +// <0x2B=> I2S Tx 0 Trigger +// <0x2C=> I2S Tx 1 Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_14 +#ifndef CONF_DMAC_TRIGSRC_14 +#define CONF_DMAC_TRIGSRC_14 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_14 +#ifndef CONF_DMAC_LVL_14 +#define CONF_DMAC_LVL_14 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_14 +#ifndef CONF_DMAC_EVOE_14 +#define CONF_DMAC_EVOE_14 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_14 +#ifndef CONF_DMAC_EVIE_14 +#define CONF_DMAC_EVIE_14 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_14 +#ifndef CONF_DMAC_EVACT_14 +#define CONF_DMAC_EVACT_14 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_14 +#ifndef CONF_DMAC_STEPSIZE_14 +#define CONF_DMAC_STEPSIZE_14 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_14 +#ifndef CONF_DMAC_STEPSEL_14 +#define CONF_DMAC_STEPSEL_14 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_14 +#ifndef CONF_DMAC_SRCINC_14 +#define CONF_DMAC_SRCINC_14 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_14 +#ifndef CONF_DMAC_DSTINC_14 +#define CONF_DMAC_DSTINC_14 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_14 +#ifndef CONF_DMAC_BEATSIZE_14 +#define CONF_DMAC_BEATSIZE_14 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_14 +#ifndef CONF_DMAC_BLOCKACT_14 +#define CONF_DMAC_BLOCKACT_14 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_14 +#ifndef CONF_DMAC_EVOSEL_14 +#define CONF_DMAC_EVOSEL_14 0 +#endif +// + +// Channel 15 settings +// dmac_channel_15_settings +#ifndef CONF_DMAC_CHANNEL_15_SETTINGS +#define CONF_DMAC_CHANNEL_15_SETTINGS 0 +#endif + +// Channel Enable +// Indicates whether channel 15 is enabled or not +// dmac_enable_15 +#ifndef CONF_DMAC_ENABLE_15 +#define CONF_DMAC_ENABLE_15 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_15 +#ifndef CONF_DMAC_TRIGACT_15 +#define CONF_DMAC_TRIGACT_15 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> SERCOM0 RX Trigger +// <0x02=> SERCOM0 TX Trigger +// <0x03=> SERCOM1 RX Trigger +// <0x04=> SERCOM1 TX Trigger +// <0x05=> SERCOM2 RX Trigger +// <0x06=> SERCOM2 TX Trigger +// <0x07=> SERCOM3 RX Trigger +// <0x08=> SERCOM3 TX Trigger +// <0x09=> SERCOM4 RX Trigger +// <0x0A=> SERCOM4 TX Trigger +// <0x0B=> SERCOM5 RX Trigger +// <0x0C=> SERCOM5 TX Trigger +// <0x0D=> TCC0 Overflow Trigger +// <0x0E=> TCC0 Match/Compare 0 Trigger +// <0x0F=> TCC0 Match/Compare 1 Trigger +// <0x10=> TCC0 Match/Compare 2 Trigger +// <0x11=> TCC0 Match/Compare 3 Trigger +// <0x12=> TCC1 Overflow Trigger +// <0x13=> TCC1 Match/Compare 0 Trigger +// <0x14=> TCC1 Match/Compare 1 Trigger +// <0x15=> TCC2 Overflow Trigger +// <0x16=> TCC2 Match/Compare 0 Trigger +// <0x17=> TCC2 Match/Compare 1 Trigger +// <0x18=> TC3 Overflow Trigger +// <0x19=> TC3 Match/Compare 0 Trigger +// <0x1A=> TC3 Match/Compare 1 Trigger +// <0x1B=> TC4 Overflow Trigger +// <0x1C=> TC4 Match/Compare 0 Trigger +// <0x1D=> TC4 Match/Compare 1 Trigger +// <0x1E=> TC5 Overflow Trigger +// <0x1F=> TC5 Match/Compare 0 Trigger +// <0x20=> TC5 Match/Compare 1 Trigger +// <0x21=> TC6 Overflow Trigger +// <0x22=> TC6 Match/Compare 0 Trigger +// <0x23=> TC6 Match/Compare 1 Trigger +// <0x24=> TC7 Overflow Trigger +// <0x25=> TC7 Match/Compare 0 Trigger +// <0x26=> TC7 Match/Compare 1 Trigger +// <0x27=> ADC Result Ready Trigger +// <0x28=> DAC Empty Trigger +// <0x29=> I2S Rx 0 Trigger +// <0x2A=> I2S Rx 1 Trigger +// <0x2B=> I2S Tx 0 Trigger +// <0x2C=> I2S Tx 1 Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_15 +#ifndef CONF_DMAC_TRIGSRC_15 +#define CONF_DMAC_TRIGSRC_15 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_15 +#ifndef CONF_DMAC_LVL_15 +#define CONF_DMAC_LVL_15 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_15 +#ifndef CONF_DMAC_EVOE_15 +#define CONF_DMAC_EVOE_15 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_15 +#ifndef CONF_DMAC_EVIE_15 +#define CONF_DMAC_EVIE_15 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_15 +#ifndef CONF_DMAC_EVACT_15 +#define CONF_DMAC_EVACT_15 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_15 +#ifndef CONF_DMAC_STEPSIZE_15 +#define CONF_DMAC_STEPSIZE_15 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_15 +#ifndef CONF_DMAC_STEPSEL_15 +#define CONF_DMAC_STEPSEL_15 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_15 +#ifndef CONF_DMAC_SRCINC_15 +#define CONF_DMAC_SRCINC_15 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_15 +#ifndef CONF_DMAC_DSTINC_15 +#define CONF_DMAC_DSTINC_15 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_15 +#ifndef CONF_DMAC_BEATSIZE_15 +#define CONF_DMAC_BEATSIZE_15 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_15 +#ifndef CONF_DMAC_BLOCKACT_15 +#define CONF_DMAC_BLOCKACT_15 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_15 +#ifndef CONF_DMAC_EVOSEL_15 +#define CONF_DMAC_EVOSEL_15 0 +#endif +// + +// + +// <<< end of configuration section >>> + +#endif // HPL_DMAC_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd21/hpl_gclk_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_gclk_config.h new file mode 100644 index 00000000000..b97131f0bc2 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_gclk_config.h @@ -0,0 +1,709 @@ +// Circuit Python SAMD21 clock tree: +// DFLL48M (with USBCRM on to sync with external USB ref) -> GCLK0, GCLK1 +// GCLK0 (48MHz) -> peripherals +// GLCK1 (48MHz divided by 150 = 320Khz) -> DAC peripheral (DAC requires 350KHz or lower) + +// We'd like to use XOSC32K as a ref for DFLL48M on boards with a 32kHz crystal, +// but haven't figured that out yet. + +// Used in hpl/core/hpl_init.c to define which clocks should be initialized first. +#define CIRCUITPY_GCLK_INIT_1ST (1 << 0 | 1 << 1) + + +/* Auto-generated config file hpl_gclk_config.h */ +#ifndef HPL_GCLK_CONFIG_H +#define HPL_GCLK_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Generic clock generator 0 configuration +// Indicates whether generic clock 0 configuration is enabled or not +// enable_gclk_gen_0 +#ifndef CONF_GCLK_GENERATOR_0_CONFIG +#define CONF_GCLK_GENERATOR_0_CONFIG 1 +#endif + +// Generic Clock Generator Control +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_0_RUNSTDBY +#ifndef CONF_GCLK_GEN_0_RUNSTDBY +#define CONF_GCLK_GEN_0_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_0_div_sel +#ifndef CONF_GCLK_GEN_0_DIVSEL +#define CONF_GCLK_GEN_0_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_0_oe +#ifndef CONF_GCLK_GEN_0_OE +#define CONF_GCLK_GEN_0_OE 1 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_0_oov +#ifndef CONF_GCLK_GEN_0_OOV +#define CONF_GCLK_GEN_0_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_0_idc +#ifndef CONF_GCLK_GEN_0_IDC +#define CONF_GCLK_GEN_0_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_0_enable +#ifndef CONF_GCLK_GEN_0_GENEN +#define CONF_GCLK_GEN_0_GENEN 1 +#endif + +// Generic clock generator 0 source + +// External Crystal Oscillator 0.4-32MHz (XOSC) + +// Generic clock generator input pad + +// Generic clock generator 1 + +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) + +// 32kHz High Accuracy Internal Oscillator (OSC32K) + +// 32kHz External Crystal Oscillator (XOSC32K) + +// 8MHz Internal Oscillator (OSC8M) + +// Digital Frequency Locked Loop (DFLL48M) + +// Fractional Digital Phase Locked Loop (FDPLL96M) + +// This defines the clock source for generic clock generator 0 +// gclk_gen_0_oscillator +#ifndef CONF_GCLK_GEN_0_SRC +#define CONF_GCLK_GEN_0_SRC GCLK_GENCTRL_SRC_DFLL48M +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 0 division <0x0000-0xFFFF> +// +// gclk_gen_0_div +#ifndef CONF_GCLK_GEN_0_DIV +#define CONF_GCLK_GEN_0_DIV 1 +#endif + +// +// // Generic clock generator 1 configuration +// Indicates whether generic clock 1 configuration is enabled or not +// enable_gclk_gen_1 +#ifndef CONF_GCLK_GENERATOR_1_CONFIG +#define CONF_GCLK_GENERATOR_1_CONFIG 1 +#endif + +// Generic Clock Generator Control +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_1_RUNSTDBY +#ifndef CONF_GCLK_GEN_1_RUNSTDBY +#define CONF_GCLK_GEN_1_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_1_div_sel +#ifndef CONF_GCLK_GEN_1_DIVSEL +#define CONF_GCLK_GEN_1_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_1_oe +#ifndef CONF_GCLK_GEN_1_OE +#define CONF_GCLK_GEN_1_OE 1 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_1_oov +#ifndef CONF_GCLK_GEN_1_OOV +#define CONF_GCLK_GEN_1_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_1_idc +#ifndef CONF_GCLK_GEN_1_IDC +#define CONF_GCLK_GEN_1_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_1_enable +#ifndef CONF_GCLK_GEN_1_GENEN +#define CONF_GCLK_GEN_1_GENEN 1 +#endif + +// Generic clock generator 1 source + +// External Crystal Oscillator 0.4-32MHz (XOSC) + +// Generic clock generator input pad + +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) + +// 32kHz High Accuracy Internal Oscillator (OSC32K) + +// 32kHz External Crystal Oscillator (XOSC32K) + +// 8MHz Internal Oscillator (OSC8M) + +// Digital Frequency Locked Loop (DFLL48M) + +// Fractional Digital Phase Locked Loop (FDPLL96M) + +// This defines the clock source for generic clock generator 1 +// gclk_gen_1_oscillator +#ifndef CONF_GCLK_GEN_1_SRC +#define CONF_GCLK_GEN_1_SRC GCLK_GENCTRL_SRC_DFLL48M +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 1 division <0x0000-0xFFFF> +// +// gclk_gen_1_div +#ifndef CONF_GCLK_GEN_1_DIV +#define CONF_GCLK_GEN_1_DIV 150 +#endif + +// +// // Generic clock generator 2 configuration +// Indicates whether generic clock 2 configuration is enabled or not +// enable_gclk_gen_2 +#ifndef CONF_GCLK_GENERATOR_2_CONFIG +#define CONF_GCLK_GENERATOR_2_CONFIG 1 +#endif + +// Generic Clock Generator Control +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_2_RUNSTDBY +#ifndef CONF_GCLK_GEN_2_RUNSTDBY +#define CONF_GCLK_GEN_2_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_2_div_sel +#ifndef CONF_GCLK_GEN_2_DIVSEL +#define CONF_GCLK_GEN_2_DIVSEL 1 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_2_oe +#ifndef CONF_GCLK_GEN_2_OE +#define CONF_GCLK_GEN_2_OE 0 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_2_oov +#ifndef CONF_GCLK_GEN_2_OOV +#define CONF_GCLK_GEN_2_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_2_idc +#ifndef CONF_GCLK_GEN_2_IDC +#define CONF_GCLK_GEN_2_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_2_enable +#ifndef CONF_GCLK_GEN_2_GENEN +#define CONF_GCLK_GEN_2_GENEN 1 +#endif + +// Generic clock generator 2 source + +// External Crystal Oscillator 0.4-32MHz (XOSC) + +// Generic clock generator input pad + +// Generic clock generator 1 + +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) + +// 32kHz High Accuracy Internal Oscillator (OSC32K) + +// 32kHz External Crystal Oscillator (XOSC32K) + +// 8MHz Internal Oscillator (OSC8M) + +// Digital Frequency Locked Loop (DFLL48M) + +// Fractional Digital Phase Locked Loop (FDPLL96M) + +// This defines the clock source for generic clock generator 2 +// gclk_gen_2_oscillator +#ifndef CONF_GCLK_GEN_2_SRC +#define CONF_GCLK_GEN_2_SRC GCLK_GENCTRL_SRC_OSC32K +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 2 division <0x0000-0xFFFF> +// +// gclk_gen_2_div +#ifndef CONF_GCLK_GEN_2_DIV +#define CONF_GCLK_GEN_2_DIV 4 +#endif + +// +// // Generic clock generator 3 configuration +// Indicates whether generic clock 3 configuration is enabled or not +// enable_gclk_gen_3 +#ifndef CONF_GCLK_GENERATOR_3_CONFIG +#define CONF_GCLK_GENERATOR_3_CONFIG 0 +#endif + +// Generic Clock Generator Control +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_3_RUNSTDBY +#ifndef CONF_GCLK_GEN_3_RUNSTDBY +#define CONF_GCLK_GEN_3_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_3_div_sel +#ifndef CONF_GCLK_GEN_3_DIVSEL +#define CONF_GCLK_GEN_3_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_3_oe +#ifndef CONF_GCLK_GEN_3_OE +#define CONF_GCLK_GEN_3_OE 0 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_3_oov +#ifndef CONF_GCLK_GEN_3_OOV +#define CONF_GCLK_GEN_3_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_3_idc +#ifndef CONF_GCLK_GEN_3_IDC +#define CONF_GCLK_GEN_3_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_3_enable +#ifndef CONF_GCLK_GEN_3_GENEN +#define CONF_GCLK_GEN_3_GENEN 0 +#endif + +// Generic clock generator 3 source + +// External Crystal Oscillator 0.4-32MHz (XOSC) + +// Generic clock generator input pad + +// Generic clock generator 1 + +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) + +// 32kHz High Accuracy Internal Oscillator (OSC32K) + +// 32kHz External Crystal Oscillator (XOSC32K) + +// 8MHz Internal Oscillator (OSC8M) + +// Digital Frequency Locked Loop (DFLL48M) + +// Fractional Digital Phase Locked Loop (FDPLL96M) + +// This defines the clock source for generic clock generator 3 +// gclk_gen_3_oscillator +#ifndef CONF_GCLK_GEN_3_SRC +#define CONF_GCLK_GEN_3_SRC GCLK_GENCTRL_SRC_OSCULP32K +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 3 division <0x0000-0xFFFF> +// +// gclk_gen_3_div +#ifndef CONF_GCLK_GEN_3_DIV +#define CONF_GCLK_GEN_3_DIV 1 +#endif + +// +// // Generic clock generator 4 configuration +// Indicates whether generic clock 4 configuration is enabled or not +// enable_gclk_gen_4 +#ifndef CONF_GCLK_GENERATOR_4_CONFIG +#define CONF_GCLK_GENERATOR_4_CONFIG 0 +#endif + +// Generic Clock Generator Control +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_4_RUNSTDBY +#ifndef CONF_GCLK_GEN_4_RUNSTDBY +#define CONF_GCLK_GEN_4_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_4_div_sel +#ifndef CONF_GCLK_GEN_4_DIVSEL +#define CONF_GCLK_GEN_4_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_4_oe +#ifndef CONF_GCLK_GEN_4_OE +#define CONF_GCLK_GEN_4_OE 0 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_4_oov +#ifndef CONF_GCLK_GEN_4_OOV +#define CONF_GCLK_GEN_4_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_4_idc +#ifndef CONF_GCLK_GEN_4_IDC +#define CONF_GCLK_GEN_4_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_4_enable +#ifndef CONF_GCLK_GEN_4_GENEN +#define CONF_GCLK_GEN_4_GENEN 0 +#endif + +// Generic clock generator 4 source + +// External Crystal Oscillator 0.4-32MHz (XOSC) + +// Generic clock generator input pad + +// Generic clock generator 1 + +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) + +// 32kHz High Accuracy Internal Oscillator (OSC32K) + +// 32kHz External Crystal Oscillator (XOSC32K) + +// 8MHz Internal Oscillator (OSC8M) + +// Digital Frequency Locked Loop (DFLL48M) + +// Fractional Digital Phase Locked Loop (FDPLL96M) + +// This defines the clock source for generic clock generator 4 +// gclk_gen_4_oscillator +#ifndef CONF_GCLK_GEN_4_SRC +#define CONF_GCLK_GEN_4_SRC GCLK_GENCTRL_SRC_OSCULP32K +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 4 division <0x0000-0xFFFF> +// +// gclk_gen_4_div +#ifndef CONF_GCLK_GEN_4_DIV +#define CONF_GCLK_GEN_4_DIV 1 +#endif + +// +// // Generic clock generator 5 configuration +// Indicates whether generic clock 5 configuration is enabled or not +// enable_gclk_gen_5 +#ifndef CONF_GCLK_GENERATOR_5_CONFIG +#define CONF_GCLK_GENERATOR_5_CONFIG 0 +#endif + +// Generic Clock Generator Control +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_5_RUNSTDBY +#ifndef CONF_GCLK_GEN_5_RUNSTDBY +#define CONF_GCLK_GEN_5_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_5_div_sel +#ifndef CONF_GCLK_GEN_5_DIVSEL +#define CONF_GCLK_GEN_5_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_5_oe +#ifndef CONF_GCLK_GEN_5_OE +#define CONF_GCLK_GEN_5_OE 0 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_5_oov +#ifndef CONF_GCLK_GEN_5_OOV +#define CONF_GCLK_GEN_5_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_5_idc +#ifndef CONF_GCLK_GEN_5_IDC +#define CONF_GCLK_GEN_5_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_5_enable +#ifndef CONF_GCLK_GEN_5_GENEN +#define CONF_GCLK_GEN_5_GENEN 0 +#endif + +// Generic clock generator 5 source + +// External Crystal Oscillator 0.4-32MHz (XOSC) + +// Generic clock generator input pad + +// Generic clock generator 1 + +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) + +// 32kHz High Accuracy Internal Oscillator (OSC32K) + +// 32kHz External Crystal Oscillator (XOSC32K) + +// 8MHz Internal Oscillator (OSC8M) + +// Digital Frequency Locked Loop (DFLL48M) + +// Fractional Digital Phase Locked Loop (FDPLL96M) + +// This defines the clock source for generic clock generator 5 +// gclk_gen_5_oscillator +#ifndef CONF_GCLK_GEN_5_SRC +#define CONF_GCLK_GEN_5_SRC GCLK_GENCTRL_SRC_OSC32K +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 5 division <0x0000-0xFFFF> +// +// gclk_gen_5_div +#ifndef CONF_GCLK_GEN_5_DIV +#define CONF_GCLK_GEN_5_DIV 1 +#endif + +// +// // Generic clock generator 6 configuration +// Indicates whether generic clock 6 configuration is enabled or not +// enable_gclk_gen_6 +#ifndef CONF_GCLK_GENERATOR_6_CONFIG +#define CONF_GCLK_GENERATOR_6_CONFIG 0 +#endif + +// Generic Clock Generator Control +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_6_RUNSTDBY +#ifndef CONF_GCLK_GEN_6_RUNSTDBY +#define CONF_GCLK_GEN_6_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_6_div_sel +#ifndef CONF_GCLK_GEN_6_DIVSEL +#define CONF_GCLK_GEN_6_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_6_oe +#ifndef CONF_GCLK_GEN_6_OE +#define CONF_GCLK_GEN_6_OE 0 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_6_oov +#ifndef CONF_GCLK_GEN_6_OOV +#define CONF_GCLK_GEN_6_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_6_idc +#ifndef CONF_GCLK_GEN_6_IDC +#define CONF_GCLK_GEN_6_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_6_enable +#ifndef CONF_GCLK_GEN_6_GENEN +#define CONF_GCLK_GEN_6_GENEN 0 +#endif + +// Generic clock generator 6 source + +// External Crystal Oscillator 0.4-32MHz (XOSC) + +// Generic clock generator input pad + +// Generic clock generator 1 + +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) + +// 32kHz High Accuracy Internal Oscillator (OSC32K) + +// 32kHz External Crystal Oscillator (XOSC32K) + +// 8MHz Internal Oscillator (OSC8M) + +// Digital Frequency Locked Loop (DFLL48M) + +// Fractional Digital Phase Locked Loop (FDPLL96M) + +// This defines the clock source for generic clock generator 6 +// gclk_gen_6_oscillator +#ifndef CONF_GCLK_GEN_6_SRC +#define CONF_GCLK_GEN_6_SRC GCLK_GENCTRL_SRC_OSC32K +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 6 division <0x0000-0xFFFF> +// +// gclk_gen_6_div +#ifndef CONF_GCLK_GEN_6_DIV +#define CONF_GCLK_GEN_6_DIV 1 +#endif + +// +// // Generic clock generator 7 configuration +// Indicates whether generic clock 7 configuration is enabled or not +// enable_gclk_gen_7 +#ifndef CONF_GCLK_GENERATOR_7_CONFIG +#define CONF_GCLK_GENERATOR_7_CONFIG 0 +#endif + +// Generic Clock Generator Control +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_7_RUNSTDBY +#ifndef CONF_GCLK_GEN_7_RUNSTDBY +#define CONF_GCLK_GEN_7_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_7_div_sel +#ifndef CONF_GCLK_GEN_7_DIVSEL +#define CONF_GCLK_GEN_7_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_7_oe +#ifndef CONF_GCLK_GEN_7_OE +#define CONF_GCLK_GEN_7_OE 0 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_7_oov +#ifndef CONF_GCLK_GEN_7_OOV +#define CONF_GCLK_GEN_7_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_7_idc +#ifndef CONF_GCLK_GEN_7_IDC +#define CONF_GCLK_GEN_7_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_7_enable +#ifndef CONF_GCLK_GEN_7_GENEN +#define CONF_GCLK_GEN_7_GENEN 0 +#endif + +// Generic clock generator 7 source + +// External Crystal Oscillator 0.4-32MHz (XOSC) + +// Generic clock generator input pad + +// Generic clock generator 1 + +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) + +// 32kHz High Accuracy Internal Oscillator (OSC32K) + +// 32kHz External Crystal Oscillator (XOSC32K) + +// 8MHz Internal Oscillator (OSC8M) + +// Digital Frequency Locked Loop (DFLL48M) + +// Fractional Digital Phase Locked Loop (FDPLL96M) + +// This defines the clock source for generic clock generator 7 +// gclk_gen_7_oscillator +#ifndef CONF_GCLK_GEN_7_SRC +#define CONF_GCLK_GEN_7_SRC GCLK_GENCTRL_SRC_OSC32K +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 7 division <0x0000-0xFFFF> +// +// gclk_gen_7_div +#ifndef CONF_GCLK_GEN_7_DIV +#define CONF_GCLK_GEN_7_DIV 1 +#endif + +// +// + +// <<< end of configuration section >>> + +#endif // HPL_GCLK_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd21/hpl_nvmctrl_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_nvmctrl_config.h new file mode 100644 index 00000000000..88d6bb93ff4 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_nvmctrl_config.h @@ -0,0 +1,38 @@ +/* Auto-generated config file hpl_nvmctrl_config.h */ +#ifndef HPL_NVMCTRL_CONFIG_H +#define HPL_NVMCTRL_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Basic Settings + +// Read Mode Selection +// <0x00=> No Miss Penalty +// <0x01=> Low Power +// <0x02=> Deterministic +// nvm_arch_read_mode +#ifndef CONF_NVM_READ_MODE +#define CONF_NVM_READ_MODE 0 +#endif + +// Power Reduction Mode During Sleep +// <0x00=> Wake On Access +// <0x01=> Wake Up Instant +// <0x03=> Disabled +// nvm_arch_sleepprm +#ifndef CONF_NVM_SLEEPPRM +#define CONF_NVM_SLEEPPRM 0 +#endif + +// Cache Disable +// Indicate whether cache is disable or not +// nvm_arch_cache +#ifndef CONF_NVM_CACHE +#define CONF_NVM_CACHE 0 +#endif + +// + +// <<< end of configuration section >>> + +#endif // HPL_NVMCTRL_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd21/hpl_pm_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_pm_config.h new file mode 100644 index 00000000000..1d24dffaa2b --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_pm_config.h @@ -0,0 +1,134 @@ +/* Auto-generated config file hpl_pm_config.h */ +#ifndef HPL_PM_CONFIG_H +#define HPL_PM_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +#include + +// System Configuration +// Indicates whether configuration for system is enabled or not +// enable_cpu_clock +#ifndef CONF_SYSTEM_CONFIG +#define CONF_SYSTEM_CONFIG 1 +#endif + +// CPU Clock Settings +// CPU Clock source +// Generic clock generator 0 +// This defines the clock source for the CPU +// cpu_clock_source +#ifndef CONF_CPU_SRC +#define CONF_CPU_SRC GCLK_CLKCTRL_GEN_GCLK0_Val +#endif + +// CPU clock Prescalar +// 1 +// 2 +// 4 +// 8 +// 16 +// 32 +// 64 +// 128 +// Prescalar for Main CPU clock +// cpu_div +#ifndef CONF_CPU_DIV +#define CONF_CPU_DIV PM_CPUSEL_CPUDIV_DIV1_Val +#endif +// + +// NVM Settings +// NVM Wait States +// These bits select the number of wait states for a read operation. +// <0=> 0 +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 +// <8=> 8 +// <9=> 9 +// <10=> 10 +// <11=> 11 +// <12=> 12 +// <13=> 13 +// <14=> 14 +// <15=> 15 +// nvm_wait_states +#ifndef CONF_NVM_WAIT_STATE +#define CONF_NVM_WAIT_STATE 2 +#endif + +// + +// APBA Clock Select +// APBA clock prescalar +// 1 +// 2 +// 4 +// 8 +// 16 +// 32 +// 64 +// 128 +// APBA clock prescalar +// apba_div +#ifndef CONF_APBA_DIV +#define CONF_APBA_DIV PM_APBASEL_APBADIV_DIV1 +#endif +// + +#if CONF_APBA_DIV < CONF_CPU_DIV +#warning APBA DIV cannot less than CPU DIV +#endif + +// APBB Clock Select +// APBB clock prescalar +// 1 +// 2 +// 4 +// 8 +// 16 +// 32 +// 64 +// 128 +// APBB clock prescalar +// apbb_div +#ifndef CONF_APBB_DIV +#define CONF_APBB_DIV PM_APBBSEL_APBBDIV_DIV1 +#endif +// + +#if CONF_APBB_DIV < CONF_CPU_DIV +#warning APBB DIV cannot less than CPU DIV +#endif + +// APBC Clock Select +// APBC clock prescalar +// 1 +// 2 +// 4 +// 8 +// 16 +// 32 +// 64 +// 128 +// APBC clock prescalar +// apbc_div +#ifndef CONF_APBC_DIV +#define CONF_APBC_DIV PM_APBCSEL_APBCDIV_DIV1 +#endif +// + +#if CONF_APBC_DIV < CONF_CPU_DIV +#warning APBC DIV cannot less than CPU DIV +#endif + +// + +// <<< end of configuration section >>> + +#endif // HPL_PM_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd21/hpl_rtc_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_rtc_config.h new file mode 100644 index 00000000000..7b77d903108 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_rtc_config.h @@ -0,0 +1,125 @@ +/* Auto-generated config file hpl_rtc_config.h */ +#ifndef HPL_RTC_CONFIG_H +#define HPL_RTC_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Basic settings + +#ifndef CONF_RTC_ENABLE +#define CONF_RTC_ENABLE 1 +#endif + +// Force reset RTC on initialization +// Force RTC to reset on initialization, else init is not going on if RTC is already enabled. +// Note that the previous power down data in RTC is lost if it's enabled. +// rtc_arch_init_reset +#ifndef CONF_RTC_INIT_RESET +#define CONF_RTC_INIT_RESET 0 +#endif + +// Prescaler configuration +// <0x0=>Peripheral clock divided by 1 +// <0x1=>Peripheral clock divided by 2 +// <0x2=>Peripheral clock divided by 4 +// <0x3=>Peripheral clock divided by 8 +// <0x4=>Peripheral clock divided by 16 +// <0x5=>Peripheral clock divided by 32 +// <0x6=>Peripheral clock divided by 64 +// <0x7=>Peripheral clock divided by 128 +// <0x8=>Peripheral clock divided by 256 +// <0x9=>Peripheral clock divided by 512 +// <0xA=>Peripheral clock divided by 1024 +// These bits define the RTC clock relative to the peripheral clock +// rtc_arch_prescaler +#ifndef CONF_RTC_PRESCALER +#define CONF_RTC_PRESCALER 0xa + +#endif + +// Compare Value <1-4294967295> +// These bits define the RTC Compare value, the ticks period is equal to reciprocal of (rtc clock/prescaler/compare value), +// by default 1M clock input, 1 prescaler, 1024 compare value, the ticks period equals to 1ms. +// rtc_arch_comp_val + +#ifndef CONF_RTC_COMP_VAL +#define CONF_RTC_COMP_VAL 1024 + +#endif + +// Event control +// rtc_event_control +#ifndef CONF_RTC_EVENT_CONTROL_ENABLE +#define CONF_RTC_EVENT_CONTROL_ENABLE 0 +#endif + +// Periodic Interval 0 Event Output +// This bit indicates whether Periodic interval 0 event is enabled and will be generated +// rtc_pereo0 +#ifndef CONF_RTC_PEREO0 +#define CONF_RTC_PEREO0 0 +#endif +// Periodic Interval 1 Event Output +// This bit indicates whether Periodic interval 1 event is enabled and will be generated +// rtc_pereo1 +#ifndef CONF_RTC_PEREO1 +#define CONF_RTC_PEREO1 0 +#endif +// Periodic Interval 2 Event Output +// This bit indicates whether Periodic interval 2 event is enabled and will be generated +// rtc_pereo2 +#ifndef CONF_RTC_PEREO2 +#define CONF_RTC_PEREO2 0 +#endif +// Periodic Interval 3 Event Output +// This bit indicates whether Periodic interval 3 event is enabled and will be generated +// rtc_pereo3 +#ifndef CONF_RTC_PEREO3 +#define CONF_RTC_PEREO3 0 +#endif +// Periodic Interval 4 Event Output +// This bit indicates whether Periodic interval 4 event is enabled and will be generated +// rtc_pereo4 +#ifndef CONF_RTC_PEREO4 +#define CONF_RTC_PEREO4 0 +#endif +// Periodic Interval 5 Event Output +// This bit indicates whether Periodic interval 5 event is enabled and will be generated +// rtc_pereo5 +#ifndef CONF_RTC_PEREO5 +#define CONF_RTC_PEREO5 0 +#endif +// Periodic Interval 6 Event Output +// This bit indicates whether Periodic interval 6 event is enabled and will be generated +// rtc_pereo6 +#ifndef CONF_RTC_PEREO6 +#define CONF_RTC_PEREO6 0 +#endif +// Periodic Interval 7 Event Output +// This bit indicates whether Periodic interval 7 event is enabled and will be generated +// rtc_pereo7 +#ifndef CONF_RTC_PEREO7 +#define CONF_RTC_PEREO7 0 +#endif + +// Compare 0 Event Output +// This bit indicates whether Compare O event is enabled and will be generated +// rtc_cmpeo0 +#ifndef CONF_RTC_COMPE0 +#define CONF_RTC_COMPE0 0 +#endif + +// Overflow Event Output +// This bit indicates whether Overflow event is enabled and will be generated +// rtc_ovfeo +#ifndef CONF_RTC_OVFEO +#define CONF_RTC_OVFEO 0 +#endif + +// + +// + +// <<< end of configuration section >>> + +#endif // HPL_RTC_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd21/hpl_sercom_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_sercom_config.h new file mode 100644 index 00000000000..85d05fc5043 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_sercom_config.h @@ -0,0 +1,732 @@ +// For CircuitPython, use SERCOM settings as prototypes to set +// the default settings. This file defines these SERCOMs +// +// SERCOM0: SPI with hal_spi_m_sync.c driver: spi master synchronous +// SERCOM1: I2C with hal_i2c_m_sync.c driver: i2c master synchronous +// SERCOM2: USART with hal_usart_async.c driver: usart asynchronous +// SERCOM3: SPI with hal_spi_m_dma.c: spi master DMA + +#define PROTOTYPE_SERCOM_SPI_M_SYNC SERCOM0 +#define PROTOTYPE_SERCOM_SPI_M_SYNC_CLOCK_FREQUENCY CONF_GCLK_SERCOM0_CORE_FREQUENCY + +#define PROTOTYPE_SERCOM_I2CM_SYNC SERCOM1 + +#define PROTOTYPE_SERCOM_USART_ASYNC SERCOM2 +#define PROTOTYPE_SERCOM_USART_ASYNC_CLOCK_FREQUENCY CONF_GCLK_SERCOM2_CORE_FREQUENCY + +/* Auto-generated config file hpl_sercom_config.h */ +#ifndef HPL_SERCOM_CONFIG_H +#define HPL_SERCOM_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +#include + +// Enable configuration of module +#ifndef CONF_SERCOM_0_SPI_ENABLE +#define CONF_SERCOM_0_SPI_ENABLE 1 +#endif + +// Set module in SPI Master mode +#ifndef CONF_SERCOM_0_SPI_MODE +#define CONF_SERCOM_0_SPI_MODE 0x03 +#endif + +// Basic Configuration + +// Receive buffer enable +// Enable receive buffer to receive data from slave (RXEN) +// spi_master_rx_enable +#ifndef CONF_SERCOM_0_SPI_RXEN +#define CONF_SERCOM_0_SPI_RXEN 0x1 +#endif + +// Character Size +// Bit size for all characters sent over the SPI bus (CHSIZE) +// <0x0=>8 bits +// <0x1=>9 bits +// spi_master_character_size +#ifndef CONF_SERCOM_0_SPI_CHSIZE +#define CONF_SERCOM_0_SPI_CHSIZE 0x0 +#endif + +// Baud rate <1-12000000> +// The SPI data transfer rate +// spi_master_baud_rate +#ifndef CONF_SERCOM_0_SPI_BAUD +#define CONF_SERCOM_0_SPI_BAUD 50000 +#endif + +// + +// Advanced Configuration +// spi_master_advanced +#ifndef CONF_SERCOM_0_SPI_ADVANCED +#define CONF_SERCOM_0_SPI_ADVANCED 0 +#endif + +// Dummy byte <0x00-0x1ff> +// spi_master_dummybyte +// Dummy byte used when reading data from the slave without sending any data +#ifndef CONF_SERCOM_0_SPI_DUMMYBYTE +#define CONF_SERCOM_0_SPI_DUMMYBYTE 0x1ff +#endif + +// Data Order +// <0=>MSB first +// <1=>LSB first +// I least significant or most significant bit is shifted out first (DORD) +// spi_master_arch_dord +#ifndef CONF_SERCOM_0_SPI_DORD +#define CONF_SERCOM_0_SPI_DORD 0x0 +#endif + +// Clock Polarity +// <0=>SCK is low when idle +// <1=>SCK is high when idle +// Determines if the leading edge is rising or falling with a corresponding opposite edge at the trailing edge. (CPOL) +// spi_master_arch_cpol +#ifndef CONF_SERCOM_0_SPI_CPOL +#define CONF_SERCOM_0_SPI_CPOL 0x0 +#endif + +// Clock Phase +// <0x0=>Sample input on leading edge +// <0x1=>Sample input on trailing edge +// Determines if input data is sampled on leading or trailing SCK edge. (CPHA) +// spi_master_arch_cpha +#ifndef CONF_SERCOM_0_SPI_CPHA +#define CONF_SERCOM_0_SPI_CPHA 0x0 +#endif + +// Immediate Buffer Overflow Notification +// Controls when OVF is asserted (IBON) +// <0x0=>In data stream +// <0x1=>On buffer overflow +// spi_master_arch_ibon +#ifndef CONF_SERCOM_0_SPI_IBON +#define CONF_SERCOM_0_SPI_IBON 0x0 +#endif + +// Run in stand-by +// Module stays active in stand-by sleep mode. (RUNSTDBY) +// spi_master_arch_runstdby +#ifndef CONF_SERCOM_0_SPI_RUNSTDBY +#define CONF_SERCOM_0_SPI_RUNSTDBY 0x0 +#endif + +// Debug Stop Mode +// Behavior of the baud-rate generator when CPU is halted by external debugger. (DBGSTOP) +// <0=>Keep running +// <1=>Halt +// spi_master_arch_dbgstop +#ifndef CONF_SERCOM_0_SPI_DBGSTOP +#define CONF_SERCOM_0_SPI_DBGSTOP 0 +#endif + +// + +// Address mode disabled in master mode +#ifndef CONF_SERCOM_0_SPI_AMODE_EN +#define CONF_SERCOM_0_SPI_AMODE_EN 0 +#endif + +#ifndef CONF_SERCOM_0_SPI_AMODE +#define CONF_SERCOM_0_SPI_AMODE 0 +#endif + +#ifndef CONF_SERCOM_0_SPI_ADDR +#define CONF_SERCOM_0_SPI_ADDR 0 +#endif + +#ifndef CONF_SERCOM_0_SPI_ADDRMASK +#define CONF_SERCOM_0_SPI_ADDRMASK 0 +#endif + +#ifndef CONF_SERCOM_0_SPI_SSDE +#define CONF_SERCOM_0_SPI_SSDE 0 +#endif + +#ifndef CONF_SERCOM_0_SPI_MSSEN +#define CONF_SERCOM_0_SPI_MSSEN 0x0 +#endif + +#ifndef CONF_SERCOM_0_SPI_PLOADEN +#define CONF_SERCOM_0_SPI_PLOADEN 0 +#endif + +// Receive Data Pinout +// <0x0=>PAD[0] +// <0x1=>PAD[1] +// <0x2=>PAD[2] +// <0x3=>PAD[3] +// spi_master_rxpo +#ifndef CONF_SERCOM_0_SPI_RXPO +#define CONF_SERCOM_0_SPI_RXPO 2 +#endif + +// Transmit Data Pinout +// <0x0=>PAD[0,1]_DO_SCK +// <0x1=>PAD[2,3]_DO_SCK +// <0x2=>PAD[3,1]_DO_SCK +// <0x3=>PAD[0,3]_DO_SCK +// spi_master_txpo +#ifndef CONF_SERCOM_0_SPI_TXPO +#define CONF_SERCOM_0_SPI_TXPO 0 +#endif + +// Calculate baud register value from requested baudrate value +#ifndef CONF_SERCOM_0_SPI_BAUD_RATE +#define CONF_SERCOM_0_SPI_BAUD_RATE ((float)CONF_GCLK_SERCOM0_CORE_FREQUENCY / (float)(2 * CONF_SERCOM_0_SPI_BAUD)) - 1 +#endif + +#include + +#ifndef SERCOM_I2CM_CTRLA_MODE_I2C_MASTER +#define SERCOM_I2CM_CTRLA_MODE_I2C_MASTER (5 << 2) +#endif + +#ifndef CONF_SERCOM_1_I2CM_ENABLE +#define CONF_SERCOM_1_I2CM_ENABLE 1 +#endif + +// Basic + +// I2C Bus clock speed (Hz) <1-400000> +// I2C Bus clock (SCL) speed measured in Hz +// i2c_master_baud_rate +#ifndef CONF_SERCOM_1_I2CM_BAUD +#define CONF_SERCOM_1_I2CM_BAUD 100000 +#endif + +// + +// Advanced +// i2c_master_advanced +#ifndef CONF_SERCOM_1_I2CM_ADVANCED_CONFIG +#define CONF_SERCOM_1_I2CM_ADVANCED_CONFIG 0 +#endif + +// TRise (ns) <0-300> +// Determined by the bus impedance, check electric characteristics in the datasheet +// Standard Fast Mode: typical 215ns, max 300ns +// Fast Mode +: typical 60ns, max 100ns +// High Speed Mode: typical 20ns, max 40ns +// i2c_master_arch_trise + +#ifndef CONF_SERCOM_1_I2CM_TRISE +#define CONF_SERCOM_1_I2CM_TRISE 215 +#endif + +// Master SCL Low Extended Time-Out (MEXTTOEN) +// This enables the master SCL low extend time-out +// i2c_master_arch_mexttoen +#ifndef CONF_SERCOM_1_I2CM_MEXTTOEN +#define CONF_SERCOM_1_I2CM_MEXTTOEN 0 +#endif + +// Slave SCL Low Extend Time-Out (SEXTTOEN) +// Enables the slave SCL low extend time-out. If SCL is cumulatively held low for greater than 25ms from the initial START to a STOP, the slave will release its clock hold if enabled and reset the internal state machine +// i2c_master_arch_sexttoen +#ifndef CONF_SERCOM_1_I2CM_SEXTTOEN +#define CONF_SERCOM_1_I2CM_SEXTTOEN 0 +#endif + +// SCL Low Time-Out (LOWTOUT) +// Enables SCL low time-out. If SCL is held low for 25ms-35ms, the master will release it's clock hold +// i2c_master_arch_lowtout +#ifndef CONF_SERCOM_1_I2CM_LOWTOUT +#define CONF_SERCOM_1_I2CM_LOWTOUT 0 +#endif + +// Inactive Time-Out (INACTOUT) +// <0x0=>Disabled +// <0x1=>5-6 SCL cycle time-out(50-60us) +// <0x2=>10-11 SCL cycle time-out(100-110us) +// <0x3=>20-21 SCL cycle time-out(200-210us) +// Defines if inactivity time-out should be enabled, and how long the time-out should be +// i2c_master_arch_inactout +#ifndef CONF_SERCOM_1_I2CM_INACTOUT +#define CONF_SERCOM_1_I2CM_INACTOUT 0x0 +#endif + +// SDA Hold Time (SDAHOLD) +// <0=>Disabled +// <1=>50-100ns hold time +// <2=>300-600ns hold time +// <3=>400-800ns hold time +// Defines the SDA hold time with respect to the negative edge of SCL +// i2c_master_arch_sdahold +#ifndef CONF_SERCOM_1_I2CM_SDAHOLD +#define CONF_SERCOM_1_I2CM_SDAHOLD 0x2 +#endif + +// Run in stand-by +// Determine if the module shall run in standby sleep mode +// i2c_master_arch_runstdby +#ifndef CONF_SERCOM_1_I2CM_RUNSTDBY +#define CONF_SERCOM_1_I2CM_RUNSTDBY 0 +#endif + +// Debug Stop Mode +// Behavior of the baud-rate generator when CPU is halted by external debugger. +// <0=>Keep running +// <1=>Halt +// i2c_master_arch_dbgstop +#ifndef CONF_SERCOM_1_I2CM_DEBUG_STOP_MODE +#define CONF_SERCOM_1_I2CM_DEBUG_STOP_MODE 0 +#endif + +// + +#ifndef CONF_SERCOM_1_I2CM_SPEED +#define CONF_SERCOM_1_I2CM_SPEED 0x00 // Speed: Standard/Fast mode +#endif +#if CONF_SERCOM_1_I2CM_TRISE < 215 || CONF_SERCOM_1_I2CM_TRISE > 300 +#warning Bad I2C Rise time for Standard/Fast mode, reset to 215ns +#undef CONF_SERCOM_1_I2CM_TRISE +#define CONF_SERCOM_1_I2CM_TRISE 215 +#endif + +// gclk_freq - (i2c_scl_freq * 10) - (gclk_freq * i2c_scl_freq * Trise) +// BAUD + BAUDLOW = -------------------------------------------------------------------- +// i2c_scl_freq +// BAUD: register value low [7:0] +// BAUDLOW: register value high [15:8], only used for odd BAUD + BAUDLOW +#define CONF_SERCOM_1_I2CM_BAUD_BAUDLOW \ + (((CONF_GCLK_SERCOM1_CORE_FREQUENCY - (CONF_SERCOM_1_I2CM_BAUD * 10) \ + - (CONF_SERCOM_1_I2CM_TRISE * (CONF_SERCOM_1_I2CM_BAUD / 100) * (CONF_GCLK_SERCOM1_CORE_FREQUENCY / 10000) \ + / 1000)) \ + * 10 \ + + 5) \ + / (CONF_SERCOM_1_I2CM_BAUD * 10)) +#ifndef CONF_SERCOM_1_I2CM_BAUD_RATE +#if CONF_SERCOM_1_I2CM_BAUD_BAUDLOW > (0xFF * 2) +#warning Requested I2C baudrate too low, please check +#define CONF_SERCOM_1_I2CM_BAUD_RATE 0xFF +#elif CONF_SERCOM_1_I2CM_BAUD_BAUDLOW <= 1 +#warning Requested I2C baudrate too high, please check +#define CONF_SERCOM_1_I2CM_BAUD_RATE 1 +#else +#define CONF_SERCOM_1_I2CM_BAUD_RATE \ + ((CONF_SERCOM_1_I2CM_BAUD_BAUDLOW & 0x1) \ + ? (CONF_SERCOM_1_I2CM_BAUD_BAUDLOW / 2) + ((CONF_SERCOM_1_I2CM_BAUD_BAUDLOW / 2 + 1) << 8) \ + : (CONF_SERCOM_1_I2CM_BAUD_BAUDLOW / 2)) +#endif +#endif + +#include + +#ifndef CONF_SERCOM_2_USART_ENABLE +#define CONF_SERCOM_2_USART_ENABLE 1 +#endif + +// Basic Configuration + +// Receive buffer enable +// Enable input buffer in SERCOM module +// usart_rx_enable +#ifndef CONF_SERCOM_2_USART_RXEN +#define CONF_SERCOM_2_USART_RXEN 1 +#endif + +// Transmitt buffer enable +// Enable output buffer in SERCOM module +// usart_tx_enable +#ifndef CONF_SERCOM_2_USART_TXEN +#define CONF_SERCOM_2_USART_TXEN 1 +#endif + +// Frame parity +// <0x0=>No parity +// <0x1=>Even parity +// <0x2=>Odd parity +// Parity bit mode for USART frame +// usart_parity +#ifndef CONF_SERCOM_2_USART_PARITY +#define CONF_SERCOM_2_USART_PARITY 0x0 +#endif + +// Character Size +// <0x0=>8 bits +// <0x1=>9 bits +// <0x5=>5 bits +// <0x6=>6 bits +// <0x7=>7 bits +// Data character size in USART frame +// usart_character_size +#ifndef CONF_SERCOM_2_USART_CHSIZE +#define CONF_SERCOM_2_USART_CHSIZE 0x0 +#endif + +// Stop Bit +// <0=>One stop bit +// <1=>Two stop bits +// Number of stop bits in USART frame +// usart_stop_bit +#ifndef CONF_SERCOM_2_USART_SBMODE +#define CONF_SERCOM_2_USART_SBMODE 0 +#endif + +// Baud rate <1-3000000> +// USART baud rate setting +// usart_baud_rate +#ifndef CONF_SERCOM_2_USART_BAUD +#define CONF_SERCOM_2_USART_BAUD 9600 +#endif + +// + +// Advanced configuration +// usart_advanced +#ifndef CONF_SERCOM_2_USART_ADVANCED_CONFIG +#define CONF_SERCOM_2_USART_ADVANCED_CONFIG 0 +#endif + +// Run in stand-by +// Keep the module running in standby sleep mode +// usart_arch_runstdby +#ifndef CONF_SERCOM_2_USART_RUNSTDBY +#define CONF_SERCOM_2_USART_RUNSTDBY 0 +#endif + +// Immediate Buffer Overflow Notification +// Controls when the BUFOVF status bit is asserted +// usart_arch_ibon +#ifndef CONF_SERCOM_2_USART_IBON +#define CONF_SERCOM_2_USART_IBON 0 +#endif + +// Start of Frame Detection Enable +// Will wake the device from any sleep mode if usart_init and usart_enable was run priort to going to sleep. (receive buffer must be enabled) +// usart_arch_sfde +#ifndef CONF_SERCOM_2_USART_SFDE +#define CONF_SERCOM_2_USART_SFDE 0 +#endif + +// Collision Detection Enable +// Collision detection enable +// usart_arch_cloden +#ifndef CONF_SERCOM_2_USART_CLODEN +#define CONF_SERCOM_2_USART_CLODEN 0 +#endif + +// Operating Mode +// <0x0=>USART with external clock +// <0x1=>USART with internal clock +// Drive the shift register by an internal clock generated by the baud rate generator or an external clock supplied on the XCK pin. +// usart_arch_clock_mode +#ifndef CONF_SERCOM_2_USART_MODE +#define CONF_SERCOM_2_USART_MODE 0x1 +#endif + +// Sample Rate +// <0x0=>16x arithmetic +// <0x1=>16x fractional +// <0x2=>8x arithmetic +// <0x3=>8x fractional +// <0x3=>3x +// How many over-sampling bits used when samling data state +// usart_arch_sampr +#ifndef CONF_SERCOM_2_USART_SAMPR +#define CONF_SERCOM_2_USART_SAMPR 0x0 +#endif + +// Sample Adjustment +// <0x0=>7-8-9 (3-4-5 8-bit over-sampling) +// <0x1=>9-10-11 (4-5-6 8-bit over-sampling) +// <0x2=>11-12-13 (5-6-7 8-bit over-sampling) +// <0x3=>13-14-15 (6-7-8 8-bit over-sampling) +// Adjust which samples to use for data sampling in asynchronous mode +// usart_arch_sampa +#ifndef CONF_SERCOM_2_USART_SAMPA +#define CONF_SERCOM_2_USART_SAMPA 0x0 +#endif + +// Fractional Part <0-7> +// Fractional part of the baud rate if baud rate generator is in fractional mode +// usart_arch_fractional +#ifndef CONF_SERCOM_2_USART_FRACTIONAL +#define CONF_SERCOM_2_USART_FRACTIONAL 0x0 +#endif + +// Data Order +// <0=>MSB is transmitted first +// <1=>LSB is transmitted first +// Data order of the data bits in the frame +// usart_arch_dord +#ifndef CONF_SERCOM_2_USART_DORD +#define CONF_SERCOM_2_USART_DORD 1 +#endif + +// Does not do anything in UART mode +#define CONF_SERCOM_2_USART_CPOL 0 + +// Encoding Format +// <0=>No encoding +// <1=>IrDA encoded +// usart_arch_enc +#ifndef CONF_SERCOM_2_USART_ENC +#define CONF_SERCOM_2_USART_ENC 0 +#endif + +// Debug Stop Mode +// Behavior of the baud-rate generator when CPU is halted by external debugger. +// <0=>Keep running +// <1=>Halt +// usart_arch_dbgstop +#ifndef CONF_SERCOM_2_USART_DEBUG_STOP_MODE +#define CONF_SERCOM_2_USART_DEBUG_STOP_MODE 0 +#endif + +// + +#ifndef CONF_SERCOM_2_USART_CMODE +#define CONF_SERCOM_2_USART_CMODE 0 +#endif + +#ifndef CONF_SERCOM_2_USART_RXPO +#define CONF_SERCOM_2_USART_RXPO 1 /* RX is on PIN_PA09 */ +#endif + +#ifndef CONF_SERCOM_2_USART_TXPO +#define CONF_SERCOM_2_USART_TXPO 0 /* TX is on PIN_PA08 */ +#endif + +/* Set correct parity settings in register interface based on PARITY setting */ +#if CONF_SERCOM_2_USART_PARITY == 0 +#define CONF_SERCOM_2_USART_PMODE 0 +#define CONF_SERCOM_2_USART_FORM 0 +#else +#define CONF_SERCOM_2_USART_PMODE CONF_SERCOM_2_USART_PARITY - 1 +#define CONF_SERCOM_2_USART_FORM 1 +#endif + +// Calculate BAUD register value in UART mode +#if CONF_SERCOM_2_USART_SAMPR == 0 +#ifndef CONF_SERCOM_2_USART_BAUD_RATE +#define CONF_SERCOM_2_USART_BAUD_RATE \ + 65536 - ((65536 * 16.0f * CONF_SERCOM_2_USART_BAUD) / CONF_GCLK_SERCOM2_CORE_FREQUENCY) +#endif +#ifndef CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH +#define CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH 0 +#endif +#elif CONF_SERCOM_2_USART_SAMPR == 1 +#ifndef CONF_SERCOM_2_USART_BAUD_RATE +#define CONF_SERCOM_2_USART_BAUD_RATE \ + ((CONF_GCLK_SERCOM2_CORE_FREQUENCY) / (CONF_SERCOM_2_USART_BAUD * 16)) - (CONF_SERCOM_2_USART_FRACTIONAL / 8) +#endif +#ifndef CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH +#define CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH 0 +#endif +#elif CONF_SERCOM_2_USART_SAMPR == 2 +#ifndef CONF_SERCOM_2_USART_BAUD_RATE +#define CONF_SERCOM_2_USART_BAUD_RATE \ + 65536 - ((65536 * 8.0f * CONF_SERCOM_2_USART_BAUD) / CONF_GCLK_SERCOM2_CORE_FREQUENCY) +#endif +#ifndef CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH +#define CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH 0 +#endif +#elif CONF_SERCOM_2_USART_SAMPR == 3 +#ifndef CONF_SERCOM_2_USART_BAUD_RATE +#define CONF_SERCOM_2_USART_BAUD_RATE \ + ((CONF_GCLK_SERCOM2_CORE_FREQUENCY) / (CONF_SERCOM_2_USART_BAUD * 8)) - (CONF_SERCOM_2_USART_FRACTIONAL / 8) +#endif +#ifndef CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH +#define CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH 0 +#endif +#elif CONF_SERCOM_2_USART_SAMPR == 4 +#ifndef CONF_SERCOM_2_USART_BAUD_RATE +#define CONF_SERCOM_2_USART_BAUD_RATE \ + 65536 - ((65536 * 3.0f * CONF_SERCOM_2_USART_BAUD) / CONF_GCLK_SERCOM2_CORE_FREQUENCY) +#endif +#ifndef CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH +#define CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH 0 +#endif +#endif + +#include + +// Enable configuration of module +#ifndef CONF_SERCOM_3_SPI_ENABLE +#define CONF_SERCOM_3_SPI_ENABLE 1 +#endif + +// SPI DMA TX Channel <0-32> +// This defines DMA channel to be used +// spi_master_dma_tx_channel +#ifndef CONF_SERCOM_3_SPI_M_DMA_TX_CHANNEL +#define CONF_SERCOM_3_SPI_M_DMA_TX_CHANNEL 0 +#endif + +// SPI RX Channel Enable +// spi_master_rx_channel +#ifndef CONF_SERCOM_3_SPI_RX_CHANNEL +#define CONF_SERCOM_3_SPI_RX_CHANNEL 1 +#endif + +// DMA Channel <0-32> +// This defines DMA channel to be used +// spi_master_dma_rx_channel +#ifndef CONF_SERCOM_3_SPI_M_DMA_RX_CHANNEL +#define CONF_SERCOM_3_SPI_M_DMA_RX_CHANNEL 1 +#endif + +// + +// Set module in SPI Master mode +#ifndef CONF_SERCOM_3_SPI_MODE +#define CONF_SERCOM_3_SPI_MODE 0x03 +#endif + +// Basic Configuration + +// Receive buffer enable +// Enable receive buffer to receive data from slave (RXEN) +// spi_master_rx_enable +#ifndef CONF_SERCOM_3_SPI_RXEN +#define CONF_SERCOM_3_SPI_RXEN 0x1 +#endif + +// Character Size +// Bit size for all characters sent over the SPI bus (CHSIZE) +// <0x0=>8 bits +// <0x1=>9 bits +// spi_master_character_size +#ifndef CONF_SERCOM_3_SPI_CHSIZE +#define CONF_SERCOM_3_SPI_CHSIZE 0x0 +#endif + +// Baud rate <1-12000000> +// The SPI data transfer rate +// spi_master_baud_rate +#ifndef CONF_SERCOM_3_SPI_BAUD +#define CONF_SERCOM_3_SPI_BAUD 50000 +#endif + +// + +// Advanced Configuration +// spi_master_advanced +#ifndef CONF_SERCOM_3_SPI_ADVANCED +#define CONF_SERCOM_3_SPI_ADVANCED 0 +#endif + +// Dummy byte <0x00-0x1ff> +// spi_master_dummybyte +// Dummy byte used when reading data from the slave without sending any data +#ifndef CONF_SERCOM_3_SPI_DUMMYBYTE +#define CONF_SERCOM_3_SPI_DUMMYBYTE 0x1ff +#endif + +// Data Order +// <0=>MSB first +// <1=>LSB first +// I least significant or most significant bit is shifted out first (DORD) +// spi_master_arch_dord +#ifndef CONF_SERCOM_3_SPI_DORD +#define CONF_SERCOM_3_SPI_DORD 0x0 +#endif + +// Clock Polarity +// <0=>SCK is low when idle +// <1=>SCK is high when idle +// Determines if the leading edge is rising or falling with a corresponding opposite edge at the trailing edge. (CPOL) +// spi_master_arch_cpol +#ifndef CONF_SERCOM_3_SPI_CPOL +#define CONF_SERCOM_3_SPI_CPOL 0x0 +#endif + +// Clock Phase +// <0x0=>Sample input on leading edge +// <0x1=>Sample input on trailing edge +// Determines if input data is sampled on leading or trailing SCK edge. (CPHA) +// spi_master_arch_cpha +#ifndef CONF_SERCOM_3_SPI_CPHA +#define CONF_SERCOM_3_SPI_CPHA 0x0 +#endif + +// Immediate Buffer Overflow Notification +// Controls when OVF is asserted (IBON) +// <0x0=>In data stream +// <0x1=>On buffer overflow +// spi_master_arch_ibon +#ifndef CONF_SERCOM_3_SPI_IBON +#define CONF_SERCOM_3_SPI_IBON 0x0 +#endif + +// Run in stand-by +// Module stays active in stand-by sleep mode. (RUNSTDBY) +// spi_master_arch_runstdby +#ifndef CONF_SERCOM_3_SPI_RUNSTDBY +#define CONF_SERCOM_3_SPI_RUNSTDBY 0x0 +#endif + +// Debug Stop Mode +// Behavior of the baud-rate generator when CPU is halted by external debugger. (DBGSTOP) +// <0=>Keep running +// <1=>Halt +// spi_master_arch_dbgstop +#ifndef CONF_SERCOM_3_SPI_DBGSTOP +#define CONF_SERCOM_3_SPI_DBGSTOP 0 +#endif + +// + +// Address mode disabled in master mode +#ifndef CONF_SERCOM_3_SPI_AMODE_EN +#define CONF_SERCOM_3_SPI_AMODE_EN 0 +#endif + +#ifndef CONF_SERCOM_3_SPI_AMODE +#define CONF_SERCOM_3_SPI_AMODE 0 +#endif + +#ifndef CONF_SERCOM_3_SPI_ADDR +#define CONF_SERCOM_3_SPI_ADDR 0 +#endif + +#ifndef CONF_SERCOM_3_SPI_ADDRMASK +#define CONF_SERCOM_3_SPI_ADDRMASK 0 +#endif + +#ifndef CONF_SERCOM_3_SPI_SSDE +#define CONF_SERCOM_3_SPI_SSDE 0 +#endif + +#ifndef CONF_SERCOM_3_SPI_MSSEN +#define CONF_SERCOM_3_SPI_MSSEN 0x0 +#endif + +#ifndef CONF_SERCOM_3_SPI_PLOADEN +#define CONF_SERCOM_3_SPI_PLOADEN 0 +#endif + +// Receive Data Pinout +// <0x0=>PAD[0] +// <0x1=>PAD[1] +// <0x2=>PAD[2] +// <0x3=>PAD[3] +// spi_master_rxpo +#ifndef CONF_SERCOM_3_SPI_RXPO +#define CONF_SERCOM_3_SPI_RXPO 0 +#endif + +// Transmit Data Pinout +// <0x0=>PAD[0,1]_DO_SCK +// <0x1=>PAD[2,3]_DO_SCK +// <0x2=>PAD[3,1]_DO_SCK +// <0x3=>PAD[0,3]_DO_SCK +// spi_master_txpo +#ifndef CONF_SERCOM_3_SPI_TXPO +#define CONF_SERCOM_3_SPI_TXPO 1 +#endif + +// Calculate baud register value from requested baudrate value +#ifndef CONF_SERCOM_3_SPI_BAUD_RATE +#define CONF_SERCOM_3_SPI_BAUD_RATE ((float)CONF_GCLK_SERCOM3_CORE_FREQUENCY / (float)(2 * CONF_SERCOM_3_SPI_BAUD)) - 1 +#endif + +// <<< end of configuration section >>> + +#endif // HPL_SERCOM_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd21/hpl_sysctrl_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_sysctrl_config.h new file mode 100644 index 00000000000..74ec2bee953 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_sysctrl_config.h @@ -0,0 +1,678 @@ +/* Auto-generated config file hpl_sysctrl_config.h */ +#ifndef HPL_SYSCTRL_CONFIG_H +#define HPL_SYSCTRL_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +#define CONF_DFLL_OPEN_LOOP_MODE 0 +#define CONF_DFLL_CLOSED_LOOP_MODE 1 + +#define CONF_XOSC_STARTUP_TIME_31MCS 0 +#define CONF_XOSC_STARTUP_TIME_61MCS 1 +#define CONF_XOSC_STARTUP_TIME_122MCS 2 +#define CONF_XOSC_STARTUP_TIME_244MCS 3 +#define CONF_XOSC_STARTUP_TIME_488MCS 4 +#define CONF_XOSC_STARTUP_TIME_977MCS 5 +#define CONF_XOSC_STARTUP_TIME_1953MCS 6 +#define CONF_XOSC_STARTUP_TIME_3906MCS 7 +#define CONF_XOSC_STARTUP_TIME_7813MCS 8 +#define CONF_XOSC_STARTUP_TIME_15625MCS 9 +#define CONF_XOSC_STARTUP_TIME_31250MCS 10 +#define CONF_XOSC_STARTUP_TIME_62500MCS 11 +#define CONF_XOSC_STARTUP_TIME_125000MCS 12 +#define CONF_XOSC_STARTUP_TIME_250000MCS 13 +#define CONF_XOSC_STARTUP_TIME_500000MCS 14 +#define CONF_XOSC_STARTUP_TIME_1000000MCS 15 + +#define CONF_OSC_STARTUP_TIME_92MCS 0 +#define CONF_OSC_STARTUP_TIME_122MCS 1 +#define CONF_OSC_STARTUP_TIME_183MCS 2 +#define CONF_OSC_STARTUP_TIME_305MCS 3 +#define CONF_OSC_STARTUP_TIME_549MCS 4 +#define CONF_OSC_STARTUP_TIME_1038MCS 5 +#define CONF_OSC_STARTUP_TIME_2014MCS 6 +#define CONF_OSC_STARTUP_TIME_3967MCS 7 + +#define CONF_XOSC32K_STARTUP_TIME_122MCS 0 +#define CONF_XOSC32K_STARTUP_TIME_1068MCS 1 +#define CONF_XOSC32K_STARTUP_TIME_65592MCS 2 +#define CONF_XOSC32K_STARTUP_TIME_125092MCS 3 +#define CONF_XOSC32K_STARTUP_TIME_500092MCS 4 +#define CONF_XOSC32K_STARTUP_TIME_1000092MCS 5 +#define CONF_XOSC32K_STARTUP_TIME_2000092MCS 6 +#define CONF_XOSC32K_STARTUP_TIME_4000092MCS 7 + +// 8MHz Internal Oscillator Configuration +// Indicates whether configuration for OSC8M is enabled or not +// enable_osc8m +#ifndef CONF_OSC8M_CONFIG +#define CONF_OSC8M_CONFIG 1 +#endif + +// 8MHz Internal Oscillator (OSC8M) Control +// Internal 8M Oscillator Enable +// Indicates whether Internal 8 Mhz Oscillator is enabled or not +// osc8m_arch_enable +#ifndef CONF_OSC8M_ENABLE +#define CONF_OSC8M_ENABLE 1 +#endif + +// On Demand Control +// Indicates whether On Demand Control is enabled or not. +// If enabled, the oscillator will only be running when requested by a peripheral. +// If disabled, the oscillator will always be running when enabled. +// osc8m_arch_ondemand +#ifndef CONF_OSC8M_ONDEMAND +#define CONF_OSC8M_ONDEMAND 1 +#endif + +// Run In Standby +// Run In standby Mode +// If this bit is 0: The oscillator is disabled in standby sleep mode. +// If this bit is 1: The oscillator is not stopped in standby sleep mode. +// osc8m_arch_runstdby +#ifndef CONF_OSC8M_RUNSTDBY +#define CONF_OSC8M_RUNSTDBY 0 +#endif + +// Prescaler +// 1 +// 2 +// 4 +// 8 +// Prescaler for Internal 8Mhz OSC +// Default: No Prescaling +// osc8m_presc +#ifndef CONF_OSC8M_PRESC +#define CONF_OSC8M_PRESC SYSCTRL_OSC8M_PRESC_3_Val +#endif + +// Overwrite Default Osc Calibration +// Overwrite Default Osc Calibration +// osc8m_arch_overwrite_calibration +#ifndef CONF_OSC8M_OVERWRITE_CALIBRATION +#define CONF_OSC8M_OVERWRITE_CALIBRATION 0 +#endif + +// Osc Calibration Value <0-65535> +// Set the Oscillator Calibration Value +// Default: 1 +// osc8m_arch_calib +#ifndef CONF_OSC8M_CALIB +#define CONF_OSC8M_CALIB 0 +#endif + +// +// + +// 32kHz Internal Oscillator Configuration +// Indicates whether configuration for OSC32K is enabled or not +// enable_osc32k +#ifndef CONF_OSC32K_CONFIG +#define CONF_OSC32K_CONFIG 1 +#endif + +// 32kHz Internal Oscillator (OSC32K) Control +// Internal 32K Oscillator Enable +// Indicates whether Internal 32K Oscillator is enabled or not +// osc32k_arch_enable +#ifndef CONF_OSC32K_ENABLE +#define CONF_OSC32K_ENABLE 1 +#endif + +// On Demand Control +// Enable On Demand +// If this bit is 0: The oscillator is always on, if enabled. +// If this bit is 1, the oscillator will only be running when requested by a peripheral. +// osc32k_arch_ondemand +#ifndef CONF_OSC32K_ONDEMAND +#define CONF_OSC32K_ONDEMAND 1 +#endif + +// Run In Standby +// Run In standby Mode +// If this bit is 0: The oscillator is disabled in standby sleep mode. +// If this bit is 1: The oscillator is not stopped in standby sleep mode. +// osc32k_arch_runstdby +#ifndef CONF_OSC32K_RUNSTDBY +#define CONF_OSC32K_RUNSTDBY 0 +#endif + +// Enable 32Khz Output +// Enable 32 Khz Output +// osc32k_arch_en32k +#ifndef CONF_OSC32K_EN32K +#define CONF_OSC32K_EN32K 1 +#endif + +// Enable 1K +// Enable 1K +// osc32k_arch_en1k +#ifndef CONF_OSC32K_EN1K +#define CONF_OSC32K_EN1K 0 +#endif + +// Write Lock +// Write Lock +// osc32k_arch_wrtlock +#ifndef CONF_OSC32K_WRTLOCK +#define CONF_OSC32K_WRTLOCK 0 +#endif + +// Start up time for the 32K Oscillator +// 3 Clock Cycles (92us) +// 4 Clock Cycles (122us) +// 6 Clock Cycles (183us) +// 10 Clock Cycles (305us) +// 18 Clock Cycles (549us) +// 34 Clock Cycles (1038us) +// 66 Clock Cycles (2014us) +// 130 Clock Cycles (3967us) +// Start Up Time for the 32K Oscillator +// Default: 10 Clock Cycles (305us) +// osc32k_arch_startup +#ifndef CONF_OSC32K_STARTUP +#define CONF_OSC32K_STARTUP CONF_OSC_STARTUP_TIME_92MCS +#endif + +// Overwrite Default Osc Calibration +// Overwrite Default Osc Calibration +// osc32k_arch_overwrite_calibration +#ifndef CONF_OSC32K_OVERWRITE_CALIBRATION +#define CONF_OSC32K_OVERWRITE_CALIBRATION 0 +#endif + +// Osc Calibration Value <0-65535> +// Set the Oscillator Calibration Value +// Default: 0 +// osc32k_arch_calib +#ifndef CONF_OSC32K_CALIB +#define CONF_OSC32K_CALIB 0 +#endif + +// +// + +// 32kHz External Crystal Oscillator Configuration +// Indicates whether configuration for External 32K Osc is enabled or not +// enable_xosc32k +#ifndef CONF_XOSC32K_CONFIG +#define CONF_XOSC32K_CONFIG 0 +#endif + +// 32kHz External Crystal Oscillator (XOSC32K) Control +// External 32K Oscillator Enable +// Indicates whether External 32K Oscillator is enabled or not +// xosc32k_arch_enable +#ifndef CONF_XOSC32K_ENABLE +#define CONF_XOSC32K_ENABLE 0 +#endif + +// On Demand +// Enable On Demand. +// If this bit is 0: The oscillator is always on, if enabled. +// If this bit is 1: the oscillator will only be running when requested by a peripheral. +// xosc32k_arch_ondemand +#ifndef CONF_XOSC32K_ONDEMAND +#define CONF_XOSC32K_ONDEMAND 1 +#endif + +// Run In Standby +// Run In standby Mode +// If this bit is 0: The oscillator is disabled in standby sleep mode. +// If this bit is 1: The oscillator is not stopped in standby sleep mode. +// xosc32k_arch_runstdby +#ifndef CONF_XOSC32K_RUNSTDBY +#define CONF_XOSC32K_RUNSTDBY 0 +#endif + +// Enable 1K +// Enable 1K +// xosc32k_arch_en1k +#ifndef CONF_XOSC32K_EN1K +#define CONF_XOSC32K_EN1K 0 +#endif + +// Enable 32Khz Output +// Enable 32 Khz Output +// xosc32k_arch_en32k +#ifndef CONF_XOSC32K_EN32K +#define CONF_XOSC32K_EN32K 0 +#endif + +// Enable XTAL +// Enable XTAL +// xosc32k_arch_xtalen +#ifndef CONF_XOSC32K_XTALEN +#define CONF_XOSC32K_XTALEN 0 +#endif + +// Write Lock +// Write Lock +// xosc32k_arch_wrtlock +#ifndef CONF_XOSC32K_WRTLOCK +#define CONF_XOSC32K_WRTLOCK 0 +#endif + +// Automatic Amplitude Control Enable +// Indicates whether Automatic Amplitude Control is Enabled or not +// xosc32k_arch_aampen +#ifndef CONF_XOSC32K_AAMPEN +#define CONF_XOSC32K_AAMPEN 0 +#endif + +// Start up time for the 32K Oscillator +// 122 us +// 1068 us +// 62592 us +// 1125092 us +// 500092 us +// 1000092 us +// 2000092 us +// 4000092 us +// Start Up Time for the 32K Oscillator +// Default: 122 us +// xosc32k_arch_startup +#ifndef CONF_XOSC32K_STARTUP +#define CONF_XOSC32K_STARTUP CONF_XOSC32K_STARTUP_TIME_2000092MCS +#endif + +// +// + +// External Multipurpose Crystal Oscillator Configuration +// Indicates whether configuration for External Multipurpose Osc is enabled or not +// enable_xosc +#ifndef CONF_XOSC_CONFIG +#define CONF_XOSC_CONFIG 0 +#endif + +// Frequency <400000-32000000> +// Oscillation frequency of the resonator connected to the External Multipurpose Crystal Oscillator. +// xosc_frequency +#ifndef CONF_XOSC_FREQUENCY +#define CONF_XOSC_FREQUENCY 400000 +#endif + +// External Multipurpose Crystal Oscillator (XOSC) Control +// Enable +// Indicates whether External Multipurpose Oscillator is enabled or not +// xosc_arch_enable +#ifndef CONF_XOSC_ENABLE +#define CONF_XOSC_ENABLE 0 +#endif + +// On Demand +// Enable On Demand +// If this bit is 0: The oscillator is always on, if enabled. +// If this bit is 1: the oscillator will only be running when requested by a peripheral. +// xosc_arch_ondemand +#ifndef CONF_XOSC_ONDEMAND +#define CONF_XOSC_ONDEMAND 1 +#endif + +// Run In Standby +// Run In standby Mode +// If this bit is 0: The oscillator is disabled in standby sleep mode. +// If this bit is 1: The oscillator is not stopped in standby sleep mode. +// xosc_arch_runstdby +#ifndef CONF_XOSC_RUNSTDBY +#define CONF_XOSC_RUNSTDBY 0 +#endif + +// Enable XTAL +// Enable XTAL +// xosc_arch_xtalen +#ifndef CONF_XOSC_XTALEN +#define CONF_XOSC_XTALEN 0 +#endif + +// Automatic Amplitude Control Enable +// Indicates whether Automatic Amplitude Control is Enabled or not +// xosc_arch_ampgc +#ifndef CONF_XOSC_AMPGC +#define CONF_XOSC_AMPGC 0 +#endif + +// Gain of the Oscillator +// 2Mhz +// 4Mhz +// 8Mhz +// 16Mhz +// 30Mhz +// Select the Gain of the oscillator +// xosc_arch_gain +#ifndef CONF_XOSC_GAIN +#define CONF_XOSC_GAIN SYSCTRL_XOSC_GAIN_0_Val +#endif + +// Start up time for the External Oscillator +// 31 us +// 61 us +// 122 us +// 244 us +// 488 us +// 977 us +// 1953 us +// 3906 us +// 7813 us +// 15625 us +// 31250 us +// 62500 us +// 125000 us +// 250000 us +// 500000 us +// 1000000 us +// Start Up Time for the External Oscillator +// Default: 31 us +// xosc_arch_startup +#ifndef CONF_XOSC_STARTUP +#define CONF_XOSC_STARTUP CONF_XOSC_STARTUP_TIME_31MCS +#endif + +// +// + +// 32kHz Ultra Low Power Internal Oscillator Configuration +// Indicates whether configuration for OSCULP32K is enabled or not +// enable_osculp32k +#ifndef CONF_OSCULP32K_CONFIG +#define CONF_OSCULP32K_CONFIG 1 +#endif + +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) Control +// Write Lock +// Locks the OSCULP32K register for future writes to fix the OSCULP32K configuration +// osculp32k_arch_wrtlock +#ifndef CONF_OSCULP32K_WRTLOCK +#define CONF_OSCULP32K_WRTLOCK 0 +#endif + +// Overwrite Default Osc Calibration +// Overwrite Default Osc Calibration +// osculp32k_arch_overwrite_calibration +#ifndef CONF_OSCULP32K_OVERWRITE_CALIBRATION +#define CONF_OSCULP32K_OVERWRITE_CALIBRATION 0 +#endif + +// Osc Calibration Value <0-255> +// Set the Oscillator Calibration Value +// Default: 0 +// osculp32k_arch_calib +#ifndef CONF_OSCULP32K_CALIB +#define CONF_OSCULP32K_CALIB 0 +#endif + +// +// + +// DFLL Configuration +// Indicates whether configuration for DFLL is enabled or not +// enable_dfll48m +#ifndef CONF_DFLL_CONFIG +#define CONF_DFLL_CONFIG 1 +#endif + +// Reference Clock Source +// Generic clock generator 0 +// Generic clock generator 1 +// Generic clock generator 2 +// Generic clock generator 3 +// Generic clock generator 4 +// Generic clock generator 5 +// Generic clock generator 6 +// Generic clock generator 7 +// Select the clock source. +// dfll48m_ref_clock +#ifndef CONF_DFLL_GCLK +#define CONF_DFLL_GCLK GCLK_CLKCTRL_GEN_GCLK4_Val +#endif + +// DFLL Control +// DFLL Enable +// Indicates whether DFLL is enabled or not +// dfll48m_arch_enable +#ifndef CONF_DFLL_ENABLE +#define CONF_DFLL_ENABLE 1 +#endif + +// Wait Lock +// Indicates whether Wait Lock is Enables or not +// dfll48m_arch_waitlock +#ifndef CONF_DFLL_WAITLOCK +#define CONF_DFLL_WAITLOCK 0 +#endif + +// Bypass Coarse Lock +// Indicates whether Bypass coarse lock is enabled or not +// dfll48m_arch_bplckc +#ifndef CONF_DFLL_BPLCKC +#define CONF_DFLL_BPLCKC 0 +#endif + +// Quick Lock Disable +// Quick Lock Disable +// dfll48m_arch_qldis +#ifndef CONF_DFLL_QLDIS +#define CONF_DFLL_QLDIS 0 +#endif + +// Chill Cycle Disable +// Chill Cycle Disable +// dfll48m_arch_ccdis +#ifndef CONF_DFLL_CCDIS +#define CONF_DFLL_CCDIS 1 +#endif + +// On Demand +// Enable On Demand +// If this bit is 0: The DFLL is always on, if enabled. +// If this bit is 1: the DFLL will only be running when requested by a peripheral. +// dfll48m_arch_ondemand +#ifndef CONF_DFLL_ONDEMAND +#define CONF_DFLL_ONDEMAND 0 +#endif + +// Run In Standby +// Run In standby Mode +// If this bit is 0: The DFLL is disabled in standby sleep mode. +// If this bit is 1: The DFLL is not stopped in standby sleep mode. +// dfll48m_arch_runstdby +#ifndef CONF_DFLL_RUNSTDBY +#define CONF_DFLL_RUNSTDBY 0 +#endif + +// USB Clock Recovery Mode +// USB Clock Recovery Mode +// dfll48m_arch_usbcrm +#ifndef CONF_DFLL_USBCRM +#define CONF_DFLL_USBCRM 1 +#endif + +#if CONF_DFLL_USBCRM == 1 +#if CONF_DFLL_QLDIS == 1 +#warning QLDIS must be cleared to speed up the lock phase +#endif +#if CONF_DFLL_CCDIS == 0 +#warning CCDIS should be set to speed up the lock phase +#endif +#endif + +// Lose Lock After Wake +// Lose Lock After Wake +// dfll48m_arch_llaw +#ifndef CONF_DFLL_LLAW +#define CONF_DFLL_LLAW 0 +#endif + +// Stable DFLL Frequency +// Stable DFLL Frequency +// If 0: FINE calibration tracks changes in output frequency. +// If 1: FINE calibration register value will be fixed after a fine lock. +// dfll48m_arch_stable +#ifndef CONF_DFLL_STABLE +#define CONF_DFLL_STABLE 0 +#endif + +// Operating Mode Selection +// Open Loop Mode +// Closed Loop Mode +// Mode +// dfll48m_mode +#ifndef CONF_DFLL_MODE +#define CONF_DFLL_MODE CONF_DFLL_CLOSED_LOOP_MODE +#endif + +// Coarse Maximum Step <0x0-0x1F> +// dfll_arch_cstep +#ifndef CONF_DFLL_CSTEP +#define CONF_DFLL_CSTEP 1 +#endif + +// Fine Maximum Step <0x0-0x3FF> +// dfll_arch_fstep +#ifndef CONF_DFLL_FSTEP +#define CONF_DFLL_FSTEP 1 +#endif + +// DFLL Multiply Factor<0-65535> +// Set the DFLL Multiply Factor +// Default: 0 +// dfll48m_mul +#ifndef CONF_DFLL_MUL +#define CONF_DFLL_MUL 48000 +#endif + +// DFLL Calibration Overwrite +// Indicates whether Overwrite Calibration value of DFLL +// dfll48m_arch_calibration +#ifndef CONF_DFLL_OVERWRITE_CALIBRATION +#define CONF_DFLL_OVERWRITE_CALIBRATION 0 +#endif + +// Coarse Value <0x0-0x3F> +// dfll48m_arch_coarse +#ifndef CONF_DFLL_COARSE +#define CONF_DFLL_COARSE (0x1f) +#endif + +// Fine Value <0x0-0x3FF> +// dfll48m_arch_fine +#ifndef CONF_DFLL_FINE +#define CONF_DFLL_FINE (0x200) +#endif + +#if CONF_DFLL_OVERWRITE_CALIBRATION == 0 +#define CONF_DEFAULT_CORASE \ + ((FUSES_DFLL48M_COARSE_CAL_Msk & (*((uint32_t *)FUSES_DFLL48M_COARSE_CAL_ADDR))) >> FUSES_DFLL48M_COARSE_CAL_Pos) + +#define CONF_DFLLVAL \ + SYSCTRL_DFLLVAL_COARSE(((CONF_DEFAULT_CORASE) == 0x3F) ? 0x1F : (CONF_DEFAULT_CORASE)) \ + | SYSCTRL_DFLLVAL_FINE(512) + +#else +#define CONF_DFLLVAL SYSCTRL_DFLLVAL_COARSE(CONF_DFLL_COARSE) | SYSCTRL_DFLLVAL_FINE(CONF_DFLL_FINE) + +#endif +// + +// +// + +// DPLL Configuration +// Indicates whether configuration for DPLL is enabled or not +// enable_fdpll96m +#ifndef CONF_DPLL_CONFIG +#define CONF_DPLL_CONFIG 0 +#endif + +// Reference Clock Source +// 32kHz External Crystal Oscillator (XOSC32K) +// External Crystal Oscillator 0.4-32MHz (XOSC) +// Generic clock generator 0 +// Generic clock generator 1 +// Generic clock generator 2 +// Generic clock generator 3 +// Generic clock generator 4 +// Generic clock generator 5 +// Generic clock generator 6 +// Generic clock generator 7 +// Select the clock source. +// fdpll96m_ref_clock +#ifndef CONF_DPLL_GCLK +#define CONF_DPLL_GCLK GCLK_CLKCTRL_GEN_GCLK3_Val +#endif + +#if (CONF_DPLL_GCLK == GCLK_GENCTRL_SRC_XOSC32K) +#define CONF_DPLL_REFCLK SYSCTRL_DPLLCTRLB_REFCLK_REF0_Val +#elif (CONF_DPLL_GCLK == GCLK_GENCTRL_SRC_XOSC) +#define CONF_DPLL_REFCLK SYSCTRL_DPLLCTRLB_REFCLK_REF1_Val +#else +#define CONF_DPLL_REFCLK SYSCTRL_DPLLCTRLB_REFCLK_GCLK_Val +#endif + +// DPLL Control +// ON Demand +// Enable On Demand +// If this bit is 0: The DFLL is always on, if enabled. +// If this bit is 1: the DFLL will only be running when requested by a peripheral. +// fdpll96m_arch_ondemand +#ifndef CONF_DPLL_ONDEMAND +#define CONF_DPLL_ONDEMAND 1 +#endif + +// Run In Standby +// Run In standby Mode +// If this bit is 0: The DFLL is disabled in standby sleep mode. +// If this bit is 1: The DFLL is not stopped in standby sleep mode. +// fdpll96m_arch_runstdby +#ifndef CONF_DPLL_RUNSTDBY +#define CONF_DPLL_RUNSTDBY 0 +#endif + +// DPLL Enable +// Indicates whether DPLL is enabled or not +// fdpll96m_arch_enable +#ifndef CONF_DPLL_ENABLE +#define CONF_DPLL_ENABLE 0 +#endif + +// Lock ByPass +// Enabling it makes the CLK_FDPLL96M always running otherwise it will be turned off when lock signal is low +// fdpll96m_arch_lbypass +#ifndef CONF_DPLL_LBYPASS +#define CONF_DPLL_LBYPASS 0 +#endif + +// Clock Divider <0-2047> +// Clock Division Factor (Applicable if reference clock is XOSC) +// fdpll96m_clock_div +#ifndef CONF_DPLL_DIV +#define CONF_DPLL_DIV 0 +#endif + +// DPLL LDRFRAC<0-15> +// Set the fractional part of the frequency multiplier. +// fdpll96m_ldrfrac +#ifndef CONF_DPLL_LDRFRAC +#define CONF_DPLL_LDRFRAC 13 +#endif + +// DPLL LDR <0-4095> +// Set the integer part of the frequency multiplier. +// fdpll96m_ldr +#ifndef CONF_DPLL_LDR +#define CONF_DPLL_LDR 1463 +#endif + +// +// + +#define CONF_DPLL_LTIME SYSCTRL_DPLLCTRLB_LTIME_DEFAULT_Val +#define CONF_DPLL_WUF 0 +#define CONF_DPLL_LPEN 0 +#define CONF_DPLL_FILTER SYSCTRL_DPLLCTRLB_FILTER_DEFAULT_Val + +// <<< end of configuration section >>> + +#endif // HPL_SYSCTRL_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd21/hpl_systick_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_systick_config.h new file mode 100644 index 00000000000..a7f2f36208f --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_systick_config.h @@ -0,0 +1,18 @@ +/* Auto-generated config file hpl_systick_config.h */ +#ifndef HPL_SYSTICK_CONFIG_H +#define HPL_SYSTICK_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Advanced settings +// SysTick exception request +// Indicates whether the generation of SysTick exception is enabled or not +// systick_arch_tickint +#ifndef CONF_SYSTICK_TICKINT +#define CONF_SYSTICK_TICKINT 0 +#endif +// + +// <<< end of configuration section >>> + +#endif // HPL_SYSTICK_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd21/hpl_tc_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_tc_config.h new file mode 100644 index 00000000000..90e9b073574 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_tc_config.h @@ -0,0 +1,181 @@ +/* Auto-generated config file hpl_tc_config.h */ +#ifndef HPL_TC_CONFIG_H +#define HPL_TC_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +#include + +#ifndef CONF_TC3_ENABLE +#define CONF_TC3_ENABLE 1 +#endif + +// Basic settings + +// Prescaler +// No division +// Divide by 2 +// Divide by 4 +// Divide by 8 +// Divide by 16 +// Divide by 64 +// Divide by 256 +// Divide by 1024 +// This defines the prescaler value +// tc_prescaler +#ifndef CONF_TC3_PRESCALER +#define CONF_TC3_PRESCALER TC_CTRLA_PRESCALER_DIV8_Val +#endif + +// Period Value <0x00000000-0xFFFFFFFF> +// tc_per +#ifndef CONF_TC3_PER +#define CONF_TC3_PER 0x32 +#endif +// + +// PWM Waveform Output settings +// Waveform Period Value (uS) <0x00-0xFFFFFFFF> +// The unit of this value is us. +// tc_arch_wave_per_val +#ifndef CONF_TC3_WAVE_PER_VAL +#define CONF_TC3_WAVE_PER_VAL 0x3e8 +#endif + +// Waveform Duty Value (0.1%) <0x00-0x03E8> +// The unit of this value is 1/1000. +// tc_arch_wave_duty_val +#ifndef CONF_TC3_WAVE_DUTY_VAL +#define CONF_TC3_WAVE_DUTY_VAL 0x1f4 +#endif + +/* Caculate pwm ccx register value based on WAVE_PER_VAL and Waveform Duty Value */ +#if CONF_TC3_PRESCALER < TC_CTRLA_PRESCALER_DIV64_Val +#define CONF_TC3_CC0 \ + ((uint32_t)(((double)CONF_TC3_WAVE_PER_VAL * CONF_GCLK_TC3_FREQUENCY) / 1000000 / (1 << CONF_TC3_PRESCALER) - 1)) +#define CONF_TC3_CC1 ((CONF_TC3_CC0 * CONF_TC3_WAVE_DUTY_VAL) / 1000) + +#elif CONF_TC3_PRESCALER == TC_CTRLA_PRESCALER_DIV64_Val +#define CONF_TC3_CC0 ((uint32_t)(((double)CONF_TC3_WAVE_PER_VAL * CONF_GCLK_TC3_FREQUENCY) / 64000000 - 1)) +#define CONF_TC3_CC1 ((CONF_TC3_CC0 * CONF_TC3_WAVE_DUTY_VAL) / 1000) + +#elif CONF_TC3_PRESCALER == TC_CTRLA_PRESCALER_DIV256_Val +#define CONF_TC3_CC0 ((uint32_t)(((double)CONF_TC3_WAVE_PER_VAL * CONF_GCLK_TC3_FREQUENCY) / 256000000 - 1)) +#define CONF_TC3_CC1 ((CONF_TC3_CC0 * CONF_TC3_WAVE_DUTY_VAL) / 1000) + +#elif CONF_TC3_PRESCALER == TC_CTRLA_PRESCALER_DIV1024_Val +#define CONF_TC3_CC0 ((uint32_t)(((double)CONF_TC3_WAVE_PER_VAL * CONF_GCLK_TC3_FREQUENCY) / 1024000000 - 1)) +#define CONF_TC3_CC1 ((CONF_TC3_CC0 * CONF_TC3_WAVE_DUTY_VAL) / 1000) +#endif + +// + +// Advanced settings +// Mode +// Counter in 16-bit mode +// Counter in 32-bit mode +// These bits mode +// tc_arch_mode +#ifndef CONF_TC3_MODE +#define CONF_TC3_MODE TC_CTRLA_MODE_COUNT16_Val +#endif +// + +// Advanced settings +/* Commented intentionally. Timer uses fixed value. May be used by other abstractions based on TC. */ +//#define CONF_TC3_WAVEGEN TC_CTRLA_WAVEGEN_MFRQ_Val + +// Run in standby +// Indicates whether the will continue running in standby sleep mode or not +// tc_arch_runstdby +#ifndef CONF_TC3_RUNSTDBY +#define CONF_TC3_RUNSTDBY 0 +#endif + +// Prescaler and Counter Synchronization Selection +// Reload or reset counter on next GCLK +// Reload or reset counter on next prescaler clock +// Reload or reset counter on next GCLK and reset prescaler counter +// These bits select if on retrigger event, the Counter should be cleared or reloaded on the next GCLK_TCx clock or on the next prescaled GCLK_TCx clock. +// tc_arch_presync +#ifndef CONF_TC3_PRESCSYNC +#define CONF_TC3_PRESCSYNC TC_CTRLA_PRESCSYNC_GCLK_Val +#endif + +/* Commented intentionally. Timer uses fixed value. May be used by other abstractions based on TC. */ +//#define CONF_TC3_DIR 0 +//#define CONF_TC3_ONESHOT 0 + +/* Commented intentionally. Timer uses fixed value. May be used by other abstractions based on TC. */ +//#define CONF_TC3_INVEN0 0 +//#define CONF_TC3_INVEN1 0 +//#define CONF_TC3_CPTEN0 0 +//#define CONF_TC3_CPTEN1 0 + +// Debug Running Mode +// Indicates whether the Debug Running Mode is enabled or not +// tc_arch_dbgrun +#ifndef CONF_TC3_DBGRUN +#define CONF_TC3_DBGRUN 0 +#endif + +// + +// Event control +// timer_event_control +#ifndef CONF_TC3_EVENT_CONTROL_ENABLE +#define CONF_TC3_EVENT_CONTROL_ENABLE 0 +#endif + +// Overflow/Underflow Event Output +// Generates event for counter overflows/underflows +// tc_arch_ovfeo +#ifndef CONF_TC3_OVFEO +#define CONF_TC3_OVFEO 0 +#endif + +// TC Event Asynchronous input +// Enables Asynchronous input events to the TC +// tc_arch_tcei +#ifndef CONF_TC3_TCEI +#define CONF_TC3_TCEI 0 +#endif + +// TC Inverted Event Input Polarity +// Used to invert the asynchronous input event source +// tc_arch_tceinv +#ifndef CONF_TC3_TCINV +#define CONF_TC3_TCINV 0 +#endif + +// Event Action +// Defines the event action the TC will perform on an event +// Event action disabled +// Start, restart or retrigger TC on event +// Count on event +// Start TC on event +// Period captured in CC0, pulse width in CC1 +// Period captured in CC1, pulse width in CC0 +// tc_arch_evact +#ifndef CONF_TC3_EVACT +#define CONF_TC3_EVACT TC_EVCTRL_EVACT_OFF_Val +#endif + +// Match/Capture channel 0 Event +// Enables the generation of an event for every match or capture on channel 0 +// tc_arch_mceo0 +#ifndef CONF_TC3_MCEO0 +#define CONF_TC3_MCEO0 0 +#endif +// Match/Capture channel 1 Event +// Enables the generation of an event for every match or capture on channel 1 +// tc_arch_mceo1 +#ifndef CONF_TC3_MCEO1 +#define CONF_TC3_MCEO1 0 +#endif + +// + +// <<< end of configuration section >>> + +#endif // HPL_TC_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd21/hpl_usb_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_usb_config.h new file mode 100644 index 00000000000..d1bb42fe451 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_usb_config.h @@ -0,0 +1,413 @@ +/* Auto-generated config file hpl_usb_config.h */ +#ifndef HPL_USB_CONFIG_H +#define HPL_USB_CONFIG_H + +// CIRCUITPY: + +// Use 64-byte USB buffers for endpoint directions that are in use. They're set to 0 below otherwise. + +#include "genhdr/autogen_usb_descriptor.h" + +#if defined(USB_ENDPOINT_1_OUT_USED) && USB_ENDPOINT_1_OUT_USED +#define CONF_USB_EP1_CACHE 64 +#endif +#if defined(USB_ENDPOINT_1_IN_USED) && USB_ENDPOINT_1_IN_USED +#define CONF_USB_EP1_I_CACHE 64 +#endif + +#if defined(USB_ENDPOINT_2_OUT_USED) && USB_ENDPOINT_2_OUT_USED +#define CONF_USB_EP2_CACHE 64 +#endif +#if defined(USB_ENDPOINT_2_IN_USED) && USB_ENDPOINT_2_IN_USED +#define CONF_USB_EP2_I_CACHE 64 +#endif + +#if defined(USB_ENDPOINT_3_OUT_USED) && USB_ENDPOINT_3_OUT_USED +#define CONF_USB_EP3_CACHE 64 +#endif +#if defined(USB_ENDPOINT_3_IN_USED) && USB_ENDPOINT_3_IN_USED +#define CONF_USB_EP3_I_CACHE 64 +#endif + +#if defined(USB_ENDPOINT_4_OUT_USED) && USB_ENDPOINT_4_OUT_USED +#define CONF_USB_EP4_CACHE 64 +#endif +#if defined(USB_ENDPOINT_4_IN_USED) && USB_ENDPOINT_4_IN_USED +#define CONF_USB_EP4_I_CACHE 64 +#endif + +#if defined(USB_ENDPOINT_5_OUT_USED) && USB_ENDPOINT_5_OUT_USED +#define CONF_USB_EP5_CACHE 64 +#endif +#if defined(USB_ENDPOINT_5_IN_USED) && USB_ENDPOINT_5_IN_USED +#define CONF_USB_EP5_I_CACHE 64 +#endif + +#if defined(USB_ENDPOINT_6_OUT_USED) && USB_ENDPOINT_6_OUT_USED +#define CONF_USB_EP6_CACHE 64 +#endif +#if defined(USB_ENDPOINT_6_IN_USED) && USB_ENDPOINT_6_IN_USED +#define CONF_USB_EP6_I_CACHE 64 +#endif + +#if defined(USB_ENDPOINT_7_OUT_USED) && USB_ENDPOINT_7_OUT_USED +#define CONF_USB_EP7_CACHE 64 +#endif +#if defined(USB_ENDPOINT_7_IN_USED) && USB_ENDPOINT_7_IN_USED +#define CONF_USB_EP7_I_CACHE 64 +#endif + + +// <<< Use Configuration Wizard in Context Menu >>> + +#define CONF_USB_N_0 0 +#define CONF_USB_N_1 1 +#define CONF_USB_N_2 2 +#define CONF_USB_N_3 3 +#define CONF_USB_N_4 4 +#define CONF_USB_N_5 5 +#define CONF_USB_N_6 6 +#define CONF_USB_N_7 7 +#define CONF_USB_N_8 8 +#define CONF_USB_N_9 9 +#define CONF_USB_N_10 10 +#define CONF_USB_N_11 11 +#define CONF_USB_N_12 12 +#define CONF_USB_N_13 13 +#define CONF_USB_N_14 14 +#define CONF_USB_N_15 15 + +#define CONF_USB_D_EP_N_MAX (USB_EPT_NUM - 1) +#define CONF_USB_D_N_EP_MAX (CONF_USB_D_EP_N_MAX * 2 - 1) + +// USB Device HAL Configuration + +// Max number of endpoints supported +// Limits the number of endpoints (described by EP address) can be used in app. +// NOTE(tannewt): This not only limits the number of endpoints but also the +// addresses. In other words, even if you use endpoint 6 you need to set this to 11. +// 1 (EP0 only) +// 2 (EP0 + 1 endpoint) +// 3 (EP0 + 2 endpoints) +// 4 (EP0 + 3 endpoints) +// 5 (EP0 + 4 endpoints) +// 6 (EP0 + 5 endpoints) +// 7 (EP0 + 6 endpoints) +// 8 (EP0 + 7 endpoints) +// Max possible (by "Max Endpoint Number" config) +// usbd_num_ep_sp +#ifndef CONF_USB_D_NUM_EP_SP +#define CONF_USB_D_NUM_EP_SP CONF_USB_D_N_EP_MAX +#endif + +// + +// Max Endpoint Number supported +// Limits the max endpoint number. +// USB endpoint address is constructed by direction and endpoint number. Bit 8 of address set indicates the direction is IN. E.g., EP0x81 and EP0x01 have the same endpoint number, 1. +// Reduce the value according to specific device design, to cut-off memory usage. +// 0 (only EP0) +// 1 (EP 0x81 or 0x01) +// 2 (EP 0x82 or 0x02) +// 3 (EP 0x83 or 0x03) +// 4 (EP 0x84 or 0x04) +// 5 (EP 0x85 or 0x05) +// 6 (EP 0x86 or 0x06) +// 7 (EP 0x87 or 0x07) +// Max possible (by HW) +// The number of physical endpoints - 1 +// usbd_arch_max_ep_n +#ifndef CONF_USB_D_MAX_EP_N +#define CONF_USB_D_MAX_EP_N CONF_USB_D_EP_N_MAX +#endif + +// USB Speed Limit +// Limits the working speed of the device. +// Full speed +// Low Speed +// usbd_arch_speed +#ifndef CONF_USB_D_SPEED +#define CONF_USB_D_SPEED USB_SPEED_FS +#endif + +// Cache buffer size for EP0 +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// EP0 is default control endpoint, so cache must be used to be able to receive SETUP packet at any time. +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// usb_arch_ep0_cache +#ifndef CONF_USB_EP0_CACHE +#define CONF_USB_EP0_CACHE 64 +#endif + +// Cache configuration EP1 +// Cache buffer size for EP1 OUT +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_arch_ep1_cache +#ifndef CONF_USB_EP1_CACHE +#define CONF_USB_EP1_CACHE 0 +#endif + +// Cache buffer size for EP1 IN +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must not be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_ep1_I_CACHE +#ifndef CONF_USB_EP1_I_CACHE +#define CONF_USB_EP1_I_CACHE 0 +#endif +// + +// Cache configuration EP2 +// Cache buffer size for EP2 OUT +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_arch_ep2_cache +#ifndef CONF_USB_EP2_CACHE +#define CONF_USB_EP2_CACHE 0 +#endif + +// Cache buffer size for EP2 IN +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must not be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_ep2_I_CACHE +#ifndef CONF_USB_EP2_I_CACHE +#define CONF_USB_EP2_I_CACHE 0 +#endif +// + +// Cache configuration EP3 +// Cache buffer size for EP3 OUT +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_arch_ep3_cache +#ifndef CONF_USB_EP3_CACHE +#define CONF_USB_EP3_CACHE 0 +#endif + +// Cache buffer size for EP3 IN +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must not be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_ep3_I_CACHE +#ifndef CONF_USB_EP3_I_CACHE +#define CONF_USB_EP3_I_CACHE 0 +#endif +// + +// Cache configuration EP4 +// Cache buffer size for EP4 OUT +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_arch_ep4_cache +#ifndef CONF_USB_EP4_CACHE +#define CONF_USB_EP4_CACHE 0 +#endif + +// Cache buffer size for EP4 IN +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must not be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_ep4_I_CACHE +#ifndef CONF_USB_EP4_I_CACHE +#define CONF_USB_EP4_I_CACHE 0 +#endif +// + +// Cache configuration EP5 +// Cache buffer size for EP5 OUT +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_arch_ep5_cache +#ifndef CONF_USB_EP5_CACHE +#define CONF_USB_EP5_CACHE 0 +#endif + +// Cache buffer size for EP5 IN +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must not be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_ep5_I_CACHE +#ifndef CONF_USB_EP5_I_CACHE +#define CONF_USB_EP5_I_CACHE 0 +#endif +// + +// Cache configuration EP6 +// Cache buffer size for EP6 OUT +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_arch_ep6_cache +#ifndef CONF_USB_EP6_CACHE +#define CONF_USB_EP6_CACHE 0 +#endif + +// Cache buffer size for EP6 IN +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must not be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_ep6_I_CACHE +#ifndef CONF_USB_EP6_I_CACHE +#define CONF_USB_EP6_I_CACHE 0 +#endif +// + +// Cache configuration EP7 +// Cache buffer size for EP7 OUT +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_arch_ep7_cache +#ifndef CONF_USB_EP7_CACHE +#define CONF_USB_EP7_CACHE 0 +#endif + +// Cache buffer size for EP7 IN +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must not be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_ep7_I_CACHE +#ifndef CONF_USB_EP7_I_CACHE +#define CONF_USB_EP7_I_CACHE 0 +#endif +// + +// <<< end of configuration section >>> + +#endif // HPL_USB_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd21/peripheral_clk_config.h b/ports/atmel-samd/asf4_conf/samd21/peripheral_clk_config.h new file mode 100644 index 00000000000..2e1e238aab3 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd21/peripheral_clk_config.h @@ -0,0 +1,433 @@ +/* Auto-generated config file peripheral_clk_config.h */ +#ifndef PERIPHERAL_CLK_CONFIG_H +#define PERIPHERAL_CLK_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// ADC Clock Source +// adc_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Select the clock source for ADC. +#ifndef CONF_GCLK_ADC_SRC +#define CONF_GCLK_ADC_SRC GCLK_CLKCTRL_GEN_GCLK0_Val +#endif + +/** + * \def CONF_GCLK_ADC_FREQUENCY + * \brief ADC's Clock frequency + */ +#ifndef CONF_GCLK_ADC_FREQUENCY +#define CONF_GCLK_ADC_FREQUENCY 48000000 +#endif + +/** + * \def CONF_CPU_FREQUENCY + * \brief CPU's Clock frequency + */ +#ifndef CONF_CPU_FREQUENCY +#define CONF_CPU_FREQUENCY 48000000 +#endif + +// Core Clock Source +// core_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Select the clock source for CORE. +#ifndef CONF_GCLK_SERCOM0_CORE_SRC +#define CONF_GCLK_SERCOM0_CORE_SRC GCLK_CLKCTRL_GEN_GCLK0_Val +#endif + +// Slow Clock Source +// slow_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Select the slow clock source. +#ifndef CONF_GCLK_SERCOM0_SLOW_SRC +#define CONF_GCLK_SERCOM0_SLOW_SRC GCLK_CLKCTRL_GEN_GCLK3_Val +#endif + +/** + * \def CONF_GCLK_SERCOM0_CORE_FREQUENCY + * \brief SERCOM0's Core Clock frequency + */ +#ifndef CONF_GCLK_SERCOM0_CORE_FREQUENCY +#define CONF_GCLK_SERCOM0_CORE_FREQUENCY 48000000 +#endif + +/** + * \def CONF_GCLK_SERCOM0_SLOW_FREQUENCY + * \brief SERCOM0's Slow Clock frequency + */ +#ifndef CONF_GCLK_SERCOM0_SLOW_FREQUENCY +#define CONF_GCLK_SERCOM0_SLOW_FREQUENCY 400000 +#endif + +// Core Clock Source +// core_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Select the clock source for CORE. +#ifndef CONF_GCLK_SERCOM1_CORE_SRC +#define CONF_GCLK_SERCOM1_CORE_SRC GCLK_CLKCTRL_GEN_GCLK0_Val +#endif + +// Slow Clock Source +// slow_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Select the slow clock source. +#ifndef CONF_GCLK_SERCOM1_SLOW_SRC +#define CONF_GCLK_SERCOM1_SLOW_SRC GCLK_CLKCTRL_GEN_GCLK3_Val +#endif + +/** + * \def CONF_GCLK_SERCOM1_CORE_FREQUENCY + * \brief SERCOM1's Core Clock frequency + */ +#ifndef CONF_GCLK_SERCOM1_CORE_FREQUENCY +#define CONF_GCLK_SERCOM1_CORE_FREQUENCY 48000000 +#endif + +/** + * \def CONF_GCLK_SERCOM1_SLOW_FREQUENCY + * \brief SERCOM1's Slow Clock frequency + */ +#ifndef CONF_GCLK_SERCOM1_SLOW_FREQUENCY +#define CONF_GCLK_SERCOM1_SLOW_FREQUENCY 400000 +#endif + +// Core Clock Source +// core_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Select the clock source for CORE. +#ifndef CONF_GCLK_SERCOM2_CORE_SRC +#define CONF_GCLK_SERCOM2_CORE_SRC GCLK_CLKCTRL_GEN_GCLK0_Val +#endif + +// Slow Clock Source +// slow_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Select the slow clock source. +#ifndef CONF_GCLK_SERCOM2_SLOW_SRC +#define CONF_GCLK_SERCOM2_SLOW_SRC GCLK_CLKCTRL_GEN_GCLK3_Val +#endif + +/** + * \def CONF_GCLK_SERCOM2_CORE_FREQUENCY + * \brief SERCOM2's Core Clock frequency + */ +#ifndef CONF_GCLK_SERCOM2_CORE_FREQUENCY +#define CONF_GCLK_SERCOM2_CORE_FREQUENCY 48000000 +#endif + +/** + * \def CONF_GCLK_SERCOM2_SLOW_FREQUENCY + * \brief SERCOM2's Slow Clock frequency + */ +#ifndef CONF_GCLK_SERCOM2_SLOW_FREQUENCY +#define CONF_GCLK_SERCOM2_SLOW_FREQUENCY 400000 +#endif + +// Core Clock Source +// core_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Select the clock source for CORE. +#ifndef CONF_GCLK_SERCOM3_CORE_SRC +#define CONF_GCLK_SERCOM3_CORE_SRC GCLK_CLKCTRL_GEN_GCLK0_Val +#endif + +// Slow Clock Source +// slow_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Select the slow clock source. +#ifndef CONF_GCLK_SERCOM3_SLOW_SRC +#define CONF_GCLK_SERCOM3_SLOW_SRC GCLK_CLKCTRL_GEN_GCLK3_Val +#endif + +/** + * \def CONF_GCLK_SERCOM3_CORE_FREQUENCY + * \brief SERCOM3's Core Clock frequency + */ +#ifndef CONF_GCLK_SERCOM3_CORE_FREQUENCY +#define CONF_GCLK_SERCOM3_CORE_FREQUENCY 48000000 +#endif + +/** + * \def CONF_GCLK_SERCOM3_SLOW_FREQUENCY + * \brief SERCOM3's Slow Clock frequency + */ +#ifndef CONF_GCLK_SERCOM3_SLOW_FREQUENCY +#define CONF_GCLK_SERCOM3_SLOW_FREQUENCY 400000 +#endif + +// RTC Clock Source +// rtc_clk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Select the clock source for RTC. +#ifndef CONF_GCLK_RTC_SRC +#define CONF_GCLK_RTC_SRC GCLK_CLKCTRL_GEN_GCLK2_Val +#endif + +/** + * \def CONF_GCLK_RTC_FREQUENCY + * \brief RTC's Clock frequency + */ +#ifndef CONF_GCLK_RTC_FREQUENCY +#define CONF_GCLK_RTC_FREQUENCY 48000000 +#endif + +// TC Clock Source +// tc_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Select the clock source for TC. +#ifndef CONF_GCLK_TC3_SRC +#define CONF_GCLK_TC3_SRC GCLK_CLKCTRL_GEN_GCLK0_Val +#endif + +/** + * \def CONF_GCLK_TC3_FREQUENCY + * \brief TC3's Clock frequency + */ +#ifndef CONF_GCLK_TC3_FREQUENCY +#define CONF_GCLK_TC3_FREQUENCY 48000000 +#endif + +// DAC Clock Source +// dac_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Select the clock source for DAC. +#ifndef CONF_GCLK_DAC_SRC +#define CONF_GCLK_DAC_SRC GCLK_CLKCTRL_GEN_GCLK0_Val +#endif + +/** + * \def CONF_GCLK_DAC_FREQUENCY + * \brief DAC's Clock frequency + */ +#ifndef CONF_GCLK_DAC_FREQUENCY +#define CONF_GCLK_DAC_FREQUENCY 48000000 +#endif + +// USB Clock Source +// usb_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Select the clock source for USB. +#ifndef CONF_GCLK_USB_SRC +#define CONF_GCLK_USB_SRC GCLK_CLKCTRL_GEN_GCLK0_Val +#endif + +/** + * \def CONF_GCLK_USB_FREQUENCY + * \brief USB's Clock frequency + */ +#ifndef CONF_GCLK_USB_FREQUENCY +#define CONF_GCLK_USB_FREQUENCY 48000000 +#endif + +// <<< end of configuration section >>> + +#endif // PERIPHERAL_CLK_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd21/usbd_config.h b/ports/atmel-samd/asf4_conf/samd21/usbd_config.h new file mode 100644 index 00000000000..df6dac3f788 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd21/usbd_config.h @@ -0,0 +1,850 @@ +/* Auto-generated config file usbd_config.h */ +#ifndef USBD_CONFIG_H +#define USBD_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// ---- USB Device Stack Core Options ---- + +// High Speed Support +// Enable high speed specific descriptors support, e.g., DeviceQualifierDescriptor and OtherSpeedConfiguration Descriptor. +// High speed support require descriptors description array on start, for LS/FS and HS support in first and second place. +// usbd_hs_sp +#ifndef CONF_USBD_HS_SP +#define CONF_USBD_HS_SP 0 +#endif + +// ---- USB Device Stack Composite Options ---- + +// Enable String Descriptors +// usb_composite_str_en +#ifndef CONF_USB_COMPOSITE_STR_EN +#define CONF_USB_COMPOSITE_STR_EN 0 +#endif +// Language IDs +// Language IDs in c format, split by comma (E.g., 0x0409 ...) +// usb_composite_langid +#ifndef CONF_USB_COMPOSITE_LANGID +#define CONF_USB_COMPOSITE_LANGID "0x0409" +#endif + +#ifndef CONF_USB_COMPOSITE_LANGID_DESC +#define CONF_USB_COMPOSITE_LANGID_DESC +#endif +// + +// Composite Device Descriptor + +// bcdUSB +// <0x0200=> USB 2.0 version +// <0x0210=> USB 2.1 version +// usb_composite_bcdusb +#ifndef CONF_USB_COMPOSITE_BCDUSB +#define CONF_USB_COMPOSITE_BCDUSB 0x200 +#endif + +// bMaxPackeSize0 +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes +// usb_composite_bmaxpksz0 +#ifndef CONF_USB_COMPOSITE_BMAXPKSZ0 +#define CONF_USB_COMPOSITE_BMAXPKSZ0 0x40 +#endif + +// idVender <0x0000-0xFFFF> +// usb_composite_idvender +#ifndef CONF_USB_COMPOSITE_IDVENDER +#define CONF_USB_COMPOSITE_IDVENDER 0x3eb +#endif + +// idProduct <0x0000-0xFFFF> +// usb_composite_idproduct +#ifndef CONF_USB_COMPOSITE_IDPRODUCT +#define CONF_USB_COMPOSITE_IDPRODUCT 0x2421 +#endif + +// bcdDevice <0x0000-0xFFFF> +// usb_composite_bcddevice +#ifndef CONF_USB_COMPOSITE_BCDDEVICE +#define CONF_USB_COMPOSITE_BCDDEVICE 0x100 +#endif + +// Enable string descriptor of iManufact +// usb_composite_imanufact_en +#ifndef CONF_USB_COMPOSITE_IMANUFACT_EN +#define CONF_USB_COMPOSITE_IMANUFACT_EN 0 +#endif + +#ifndef CONF_USB_COMPOSITE_IMANUFACT +#define CONF_USB_COMPOSITE_IMANUFACT (CONF_USB_COMPOSITE_IMANUFACT_EN * (CONF_USB_COMPOSITE_IMANUFACT_EN)) +#endif + +// Unicode string of iManufact +// usb_composite_imanufact_str +#ifndef CONF_USB_COMPOSITE_IMANUFACT_STR +#define CONF_USB_COMPOSITE_IMANUFACT_STR "Atmel" +#endif + +#ifndef CONF_USB_COMPOSITE_IMANUFACT_STR_DESC +#define CONF_USB_COMPOSITE_IMANUFACT_STR_DESC +#endif + +// + +// Enable string descriptor of iProduct +// usb_composite_iproduct_en +#ifndef CONF_USB_COMPOSITE_IPRODUCT_EN +#define CONF_USB_COMPOSITE_IPRODUCT_EN 0 +#endif + +#ifndef CONF_USB_COMPOSITE_IPRODUCT +#define CONF_USB_COMPOSITE_IPRODUCT \ + (CONF_USB_COMPOSITE_IPRODUCT_EN * (CONF_USB_COMPOSITE_IMANUFACT_EN + CONF_USB_COMPOSITE_IPRODUCT_EN)) +#endif + +// Unicode string of iProduct +// usb_composite_iproduct_str +#ifndef CONF_USB_COMPOSITE_IPRODUCT_STR +#define CONF_USB_COMPOSITE_IPRODUCT_STR "Composite Demo" +#endif + +#ifndef CONF_USB_COMPOSITE_IPRODUCT_STR_DESC +#define CONF_USB_COMPOSITE_IPRODUCT_STR_DESC +#endif + +// + +// Enable string descriptor of iSerialNum +// usb_composite_iserialnum_en +#ifndef CONF_USB_COMPOSITE_ISERIALNUM_EN +#define CONF_USB_COMPOSITE_ISERIALNUM_EN 0 +#endif + +#ifndef CONF_USB_COMPOSITE_ISERIALNUM +#define CONF_USB_COMPOSITE_ISERIALNUM \ + (CONF_USB_COMPOSITE_ISERIALNUM_EN \ + * (CONF_USB_COMPOSITE_IMANUFACT_EN + CONF_USB_COMPOSITE_IPRODUCT_EN + CONF_USB_COMPOSITE_ISERIALNUM_EN)) +#endif + +// Unicode string of iSerialNum +// usb_composite_iserialnum_str +#ifndef CONF_USB_COMPOSITE_ISERIALNUM_STR +#define CONF_USB_COMPOSITE_ISERIALNUM_STR "123456789ABCDEF" +#endif + +#ifndef CONF_USB_COMPOSITE_ISERIALNUM_STR_DESC +#define CONF_USB_COMPOSITE_ISERIALNUM_STR_DESC +#endif + +// + +// bNumConfigurations <0x01-0xFF> +// usb_composite_bnumconfig +#ifndef CONF_USB_COMPOSITE_BNUMCONFIG +#define CONF_USB_COMPOSITE_BNUMCONFIG 0x1 +#endif + +// + +// Composite Configuration Descriptor +// bConfigurationValue <0x01-0xFF> +// usb_composite_bconfigval +#ifndef CONF_USB_COMPOSITE_BCONFIGVAL +#define CONF_USB_COMPOSITE_BCONFIGVAL 0x1 +#endif +// Enable string descriptor of iConfig +// usb_composite_iconfig_en +#ifndef CONF_USB_COMPOSITE_ICONFIG_EN +#define CONF_USB_COMPOSITE_ICONFIG_EN 0 +#endif + +#ifndef CONF_USB_COMPOSITE_ICONFIG +#define CONF_USB_COMPOSITE_ICONFIG \ + (CONF_USB_COMPOSITE_ICONFIG_EN \ + * (CONF_USB_COMPOSITE_IMANUFACT_EN + CONF_USB_COMPOSITE_IPRODUCT_EN + CONF_USB_COMPOSITE_ISERIALNUM_EN \ + + CONF_USB_COMPOSITE_ICONFIG_EN)) +#endif + +// Unicode string of iConfig +// usb_composite_iconfig_str +#ifndef CONF_USB_COMPOSITE_ICONFIG_STR +#define CONF_USB_COMPOSITE_ICONFIG_STR "" +#endif + +#ifndef CONF_USB_COMPOSITE_ICONFIG_STR_DESC +#define CONF_USB_COMPOSITE_ICONFIG_STR_DESC +#endif + +// + +// bmAttributes +// <0x80=> Bus power supply, not support for remote wakeup +// <0xA0=> Bus power supply, support for remote wakeup +// <0xC0=> Self powered, not support for remote wakeup +// <0xE0=> Self powered, support for remote wakeup +// usb_composite_bmattri +#ifndef CONF_USB_COMPOSITE_BMATTRI +#define CONF_USB_COMPOSITE_BMATTRI 0x80 +#endif + +// bMaxPower <0x00-0xFF> +// usb_composite_bmaxpower +#ifndef CONF_USB_COMPOSITE_BMAXPOWER +#define CONF_USB_COMPOSITE_BMAXPOWER 0x32 +#endif +// + +// CDC ACM Support +// usb_composite_cdc_acm_support +#ifndef CONF_USB_COMPOSITE_CDC_ACM_EN +#define CONF_USB_COMPOSITE_CDC_ACM_EN 1 +#endif + +// CDC ACM Comm Interrupt IN Endpoint Address +// <0x81=> EndpointAddress = 0x81 +// <0x82=> EndpointAddress = 0x82 +// <0x83=> EndpointAddress = 0x83 +// <0x84=> EndpointAddress = 0x84 +// <0x85=> EndpointAddress = 0x85 +// <0x86=> EndpointAddress = 0x86 +// <0x87=> EndpointAddress = 0x87 +// <0x88=> EndpointAddress = 0x88 +// <0x89=> EndpointAddress = 0x89 + +// usb_composite_cdc_acm_epaddr +#ifndef CONF_USB_COMPOSITE_CDC_ACM_COMM_INT_EPADDR +#define CONF_USB_COMPOSITE_CDC_ACM_COMM_INT_EPADDR 0x82 +#endif + +// CDC ACM Comm Interrupt IN Endpoint wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes + +// usb_composite_cdc_acm_comm_int_maxpksz +#ifndef CONF_USB_COMPOSITE_CDC_ACM_COMM_INT_MAXPKSZ +#define CONF_USB_COMPOSITE_CDC_ACM_COMM_INT_MAXPKSZ 0x40 +#endif + +// CDC ACM Data BULK IN Endpoint Address +// <0x81=> EndpointAddress = 0x81 +// <0x82=> EndpointAddress = 0x82 +// <0x83=> EndpointAddress = 0x83 +// <0x84=> EndpointAddress = 0x84 +// <0x85=> EndpointAddress = 0x85 +// <0x86=> EndpointAddress = 0x86 +// <0x87=> EndpointAddress = 0x87 +// <0x88=> EndpointAddress = 0x88 +// <0x89=> EndpointAddress = 0x89 + +// usb_composite_cdc_acm_data_bulkin_epaddr +#ifndef CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKIN_EPADDR +#define CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKIN_EPADDR 0x81 +#endif + +// CDC ACM Data BULK IN Endpoint wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes + +// usb_composite_cdc_acm_data_builin_maxpksz +#ifndef CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKIN_MAXPKSZ +#define CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKIN_MAXPKSZ 0x40 +#endif + +// CDC ACM Data BULK IN Endpoint wMaxPacketSize for High Speed +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes +// <0x0080=> 128 bytes +// <0x0100=> 256 bytes +// <0x0200=> 512 bytes + +// usb_composite_cdc_acm_data_builin_maxpksz_hs +#ifndef CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKIN_MAXPKSZ_HS +#define CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKIN_MAXPKSZ_HS 0x0200 +#endif + +// CDC ACM Data BULK OUT Endpoint Address +// <0x01=> EndpointAddress = 0x01 +// <0x02=> EndpointAddress = 0x02 +// <0x03=> EndpointAddress = 0x03 +// <0x04=> EndpointAddress = 0x04 +// <0x05=> EndpointAddress = 0x05 +// <0x06=> EndpointAddress = 0x06 +// <0x07=> EndpointAddress = 0x07 +// <0x08=> EndpointAddress = 0x08 +// <0x09=> EndpointAddress = 0x09 + +// usb_composite_cdc_acm_data_bulkout_epaddr +#ifndef CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKOUT_EPADDR +#define CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKOUT_EPADDR 0x1 +#endif + +// CDC ACM Data BULK OUT Endpoint wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes + +// usb_composite_cdc_acm_data_buckout_maxpksz +#ifndef CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKOUT_MAXPKSZ +#define CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKOUT_MAXPKSZ 0x40 +#endif + +// CDC ACM Data BULK OUT Endpoint wMaxPacketSize for High Speed +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes +// <0x0080=> 128 bytes +// <0x0100=> 256 bytes +// <0x0200=> 512 bytes + +// usb_composite_cdc_acm_data_buckout_maxpksz_hs +#ifndef CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKOUT_MAXPKSZ_HS +#define CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKOUT_MAXPKSZ_HS 0x0200 +#endif + +// CDC ACM Echo Demo generation +// conf_usb_composite_cdc_echo_demo +// Invoke cdcdf_acm_demo_init(buf[wMaxPacketSize]) to enable the echo demo. +// Buf is packet buffer for data receive and echo back. +// The buffer is 4 byte aligned to support DMA. +#ifndef CONF_USB_COMPOSITE_CDC_ECHO_DEMO +#define CONF_USB_COMPOSITE_CDC_ECHO_DEMO 0 +#endif + +// + +// HID Mouse Support +// usb_composite_hid_mouse_support +#ifndef CONF_USB_COMPOSITE_HID_MOUSE_EN +#define CONF_USB_COMPOSITE_HID_MOUSE_EN 0 +#endif + +// HID Mouse INTERRUPT IN Endpoint Address +// <0x81=> EndpointAddress = 0x81 +// <0x82=> EndpointAddress = 0x82 +// <0x83=> EndpointAddress = 0x83 +// <0x84=> EndpointAddress = 0x84 +// <0x85=> EndpointAddress = 0x85 +// <0x86=> EndpointAddress = 0x86 +// <0x87=> EndpointAddress = 0x87 +// <0x88=> EndpointAddress = 0x88 +// <0x89=> EndpointAddress = 0x89 + +// usb_composite_hid_mouse_intin_epaddr +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_MOUSE_INTIN_EPADDR +#define CONF_USB_COMPOSITE_HID_MOUSE_INTIN_EPADDR 0x83 +#endif + +// HID Mouse INTERRUPT IN Endpoint wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes + +// usb_composite_hid_mouse_intin_maxpksz +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_MOUSE_INTIN_MAXPKSZ +#define CONF_USB_COMPOSITE_HID_MOUSE_INTIN_MAXPKSZ 0x8 +#endif + +// HID Mouse Move Demo generation +// conf_usb_composite_hid_mouse_demo +// Invoke hiddf_demo_init(button1, button2, button3) to enabled the move demo. +// Button1 and button3 are the pins used for mouse moving left and right. +#ifndef CONF_USB_COMPOSITE_HID_MOUSE_DEMO +#define CONF_USB_COMPOSITE_HID_MOUSE_DEMO 0 +#endif + +// + +// HID Keyboard Support +// usb_composite_hid_keyboard_support +#ifndef CONF_USB_COMPOSITE_HID_KEYBOARD_EN +#define CONF_USB_COMPOSITE_HID_KEYBOARD_EN 0 +#endif + +// HID Keyboard INTERRUPT IN Endpoint Address +// <0x81=> EndpointAddress = 0x81 +// <0x82=> EndpointAddress = 0x82 +// <0x83=> EndpointAddress = 0x83 +// <0x84=> EndpointAddress = 0x84 +// <0x85=> EndpointAddress = 0x85 +// <0x86=> EndpointAddress = 0x86 +// <0x87=> EndpointAddress = 0x87 +// <0x88=> EndpointAddress = 0x88 +// <0x89=> EndpointAddress = 0x89 + +// usb_composite_hid_keyboard_intin_epaddr +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_KEYBOARD_INTIN_EPADDR +#define CONF_USB_COMPOSITE_HID_KEYBOARD_INTIN_EPADDR 0x84 +#endif + +// HID Keyboard INTERRUPT IN Endpoint wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes + +// usb_composite_hid_keyboard_intin_maxpksz +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_KEYBOARD_INTIN_MAXPKSZ +#define CONF_USB_COMPOSITE_HID_KEYBOARD_INTIN_MAXPKSZ 0x8 +#endif + +// HID Keyboard INTERRUPT OUT Endpoint Address +// <0x01=> EndpointAddress = 0x01 +// <0x02=> EndpointAddress = 0x02 +// <0x03=> EndpointAddress = 0x03 +// <0x04=> EndpointAddress = 0x04 +// <0x05=> EndpointAddress = 0x05 +// <0x06=> EndpointAddress = 0x06 +// <0x07=> EndpointAddress = 0x07 +// <0x08=> EndpointAddress = 0x08 +// <0x09=> EndpointAddress = 0x09 + +// usb_composite_hid_keyboard_intout_epaddr +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_KEYBOARD_INTOUT_EPADDR +#define CONF_USB_COMPOSITE_HID_KEYBOARD_INTOUT_EPADDR 0x2 +#endif + +// HID Keyboard INTERRUPT OUT Endpoint wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes + +// usb_composite_hid_keyboard_intout_maxpksz +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_KEYBOARD_INTOUT_MAXPKSZ +#define CONF_USB_COMPOSITE_HID_KEYBOARD_INTOUT_MAXPKSZ 0x8 +#endif + +// HID Keyboard Caps Lock Demo generation +// conf_usb_composite_hid_keyboard_demo +// Invoke hiddf_demo_init(button1, button2, button3) to enabled the move demo. +// Buffon2 is the pin used for keyboard CAPS LOCK simulation. +#ifndef CONF_USB_COMPOSITE_HID_KEYBOARD_DEMO +#define CONF_USB_COMPOSITE_HID_KEYBOARD_DEMO 0 +#endif + +// + +// HID Generic Support +// usb_composite_hid_generic_support +#ifndef CONF_USB_COMPOSITE_HID_GENERIC_EN +#define CONF_USB_COMPOSITE_HID_GENERIC_EN 0 +#endif + +#ifndef CONF_USB_COMPOSITE_HID_GENERIC_REPORT_LEN +#define CONF_USB_COMPOSITE_HID_GENERIC_REPORT_LEN 53 +#endif + +#ifndef CONF_USB_COMPOSITE_HID_GENERIC_REPORT +#define CONF_USB_COMPOSITE_HID_GENERIC_REPORT \ + 0x06, 0xFF, 0xFF, 0x09, 0x01, 0xA1, 0x01, 0x09, 0x02, 0x09, 0x03, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, \ + 0x40, 0x81, 0x02, 0x09, 0x04, 0x09, 0x05, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x40, 0x91, 0x02, \ + 0x09, 0x06, 0x09, 0x07, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x04, 0xB1, 0x02, 0xC0 +#endif + +// HID Generic INTERRUPT IN Endpoint Address +// <0x81=> EndpointAddress = 0x81 +// <0x82=> EndpointAddress = 0x82 +// <0x83=> EndpointAddress = 0x83 +// <0x84=> EndpointAddress = 0x84 +// <0x85=> EndpointAddress = 0x85 +// <0x86=> EndpointAddress = 0x86 +// <0x87=> EndpointAddress = 0x87 +// <0x88=> EndpointAddress = 0x88 +// <0x89=> EndpointAddress = 0x89 + +// usb_composite_hid_generic_intin_epaddr +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_GENERIC_INTIN_EPADDR +#define CONF_USB_COMPOSITE_HID_GENERIC_INTIN_EPADDR 0x85 +#endif + +// HID Generic INTERRUPT IN Endpoint wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes + +// usb_composite_hid_generic_intin_maxpksz +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_GENERIC_INTIN_MAXPKSZ +#define CONF_USB_COMPOSITE_HID_GENERIC_INTIN_MAXPKSZ 0x40 +#endif + +// HID Generic INTERRUPT OUT Endpoint Address +// <0x01=> EndpointAddress = 0x01 +// <0x02=> EndpointAddress = 0x02 +// <0x03=> EndpointAddress = 0x03 +// <0x04=> EndpointAddress = 0x04 +// <0x05=> EndpointAddress = 0x05 +// <0x06=> EndpointAddress = 0x06 +// <0x07=> EndpointAddress = 0x07 +// <0x08=> EndpointAddress = 0x08 +// <0x09=> EndpointAddress = 0x09 + +// usb_composite_hid_generic_intout_epaddr +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_GENERIC_INTOUT_EPADDR +#define CONF_USB_COMPOSITE_HID_GENERIC_INTOUT_EPADDR 0x3 +#endif + +// HID Generic INTERRUPT OUT Endpoint wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes +// usb_composite_hid_generic_intout_maxpksz +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_GENERIC_INTOUT_MAXPKSZ +#define CONF_USB_COMPOSITE_HID_GENERIC_INTOUT_MAXPKSZ 0x40 +#endif + +// + +// MSC Support +// usb_composite_msc_support +#ifndef CONF_USB_COMPOSITE_MSC_EN +#define CONF_USB_COMPOSITE_MSC_EN 0 +#endif + +// MSC BULK Endpoints wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes + +// usb_composite_msc_bulk_maxpksz +#ifndef CONF_USB_COMPOSITE_MSC_BULK_MAXPKSZ +#define CONF_USB_COMPOSITE_MSC_BULK_MAXPKSZ 0x0040 +#endif + +// MSC BULK Endpoints wMaxPacketSize for High Speed +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes +// <0x0080=> 128 bytes +// <0x0100=> 256 bytes +// <0x0200=> 512 bytes + +// usb_composite_msc_bulk_maxpksz_hs +#ifndef CONF_USB_COMPOSITE_MSC_BULK_MAXPKSZ_HS +#define CONF_USB_COMPOSITE_MSC_BULK_MAXPKSZ_HS 0x0200 +#endif + +// MSC BULK IN Endpoint Address +// <0x81=> EndpointAddress = 0x81 +// <0x82=> EndpointAddress = 0x82 +// <0x83=> EndpointAddress = 0x83 +// <0x84=> EndpointAddress = 0x84 +// <0x85=> EndpointAddress = 0x85 +// <0x86=> EndpointAddress = 0x86 +// <0x87=> EndpointAddress = 0x87 +// <0x88=> EndpointAddress = 0x88 +// <0x89=> EndpointAddress = 0x89 + +// usb_composite_msc_bulkin_epaddr +#ifndef CONF_USB_COMPOSITE_MSC_BULKIN_EPADDR +#define CONF_USB_COMPOSITE_MSC_BULKIN_EPADDR 0x86 +#endif + +// MSC BULK OUT Endpoint Address +// <0x01=> EndpointAddress = 0x01 +// <0x02=> EndpointAddress = 0x02 +// <0x03=> EndpointAddress = 0x03 +// <0x04=> EndpointAddress = 0x04 +// <0x05=> EndpointAddress = 0x05 +// <0x06=> EndpointAddress = 0x06 +// <0x07=> EndpointAddress = 0x07 +// <0x08=> EndpointAddress = 0x08 +// <0x09=> EndpointAddress = 0x09 + +// usb_composite_msc_bulkout_epaddr +#ifndef CONF_USB_COMPOSITE_MSC_BULKOUT_EPADDR +#define CONF_USB_COMPOSITE_MSC_BULKOUT_EPADDR 0x04 +#endif + +// Enable Demo code for Disk LUN handling +// usb_composite_msc_demo_en +#ifndef CONF_USB_COMPOSITE_MSC_LUN_DEMO +#define CONF_USB_COMPOSITE_MSC_LUN_DEMO 1 +#endif + +// Disk access cache/buffer of sectors if non-RAM disk (e.g., SD/MMC) enabled <1-64> +// conf_usb_msc_lun_buf_sectors +#ifndef CONF_USB_MSC_LUN_BUF_SECTORS +#define CONF_USB_MSC_LUN_BUF_SECTORS 4 +#endif + +// Enable Demo for RAM Disk +// conf_usb_msc_lun0_enable +#ifndef CONF_USB_MSC_LUN0_ENABLE +#define CONF_USB_MSC_LUN0_ENABLE 1 +#endif + +#ifndef CONF_USB_MSC_LUN0_TYPE +#define CONF_USB_MSC_LUN0_TYPE 0x00 +#endif + +// The disk is removable +// conf_usb_msc_lun0_rmb +#ifndef CONF_USB_MSC_LUN0_RMB +#define CONF_USB_MSC_LUN0_RMB 0x01 +#endif + +#ifndef CONF_USB_MSC_LUN0_ISO +#define CONF_USB_MSC_LUN0_ISO 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN0_ECMA +#define CONF_USB_MSC_LUN0_ECMA 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN0_ANSI +#define CONF_USB_MSC_LUN0_ANSI 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN0_REPO +#define CONF_USB_MSC_LUN0_REPO 0x01 +#endif + +#ifndef CONF_USB_MSC_LUN0_FACTORY +#define CONF_USB_MSC_LUN0_FACTORY 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN0_PRODUCT +#define CONF_USB_MSC_LUN0_PRODUCT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN0_PRODUCT_VERSION +#define CONF_USB_MSC_LUN0_PRODUCT_VERSION 0x00, 0x00, 0x00, 0x00 +#endif + +// Disk Size (in KB) <0x1-0xFFFFFFFF> +// Windows will not show disk less than 20K, so 22K is used to reserve more RAM for APP +// conf_usb_msc_lun0_capacity + +#ifndef CONF_USB_MSC_LUN0_CAPACITY +#define CONF_USB_MSC_LUN0_CAPACITY 22 +#endif + +#ifndef CONF_USB_MSC_LUN0_BLOCK_SIZE +#define CONF_USB_MSC_LUN0_BLOCK_SIZE 512 +#endif + +#ifndef CONF_USB_MSC_LUN0_LAST_BLOCK_ADDR +#define CONF_USB_MSC_LUN0_LAST_BLOCK_ADDR \ + ((uint32_t)CONF_USB_MSC_LUN0_CAPACITY * 1024 / CONF_USB_MSC_LUN0_BLOCK_SIZE - 1) +#endif + +// + +// Enable Demo for SD/MMC Disk +// SD/MMC stack must be added before enable SD/MMC demo +// SD/MMC insert/eject not supported by this simple demo +// conf_usb_msc_lun1_enable +#ifndef CONF_USB_MSC_LUN1_ENABLE +#define CONF_USB_MSC_LUN1_ENABLE 0 +#endif + +#ifndef CONF_USB_MSC_LUN1_TYPE +#define CONF_USB_MSC_LUN1_TYPE 0x00 +#endif + +// The disk is removable +// SD/MMC stack must be added before enable SD/MMC demo +// SD/MMC insert/eject not supported by this simple demo +// conf_usb_msc_lun1_rmb +#ifndef CONF_USB_MSC_LUN1_RMB +#define CONF_USB_MSC_LUN1_RMB 0x01 +#endif + +#ifndef CONF_USB_MSC_LUN1_ISO +#define CONF_USB_MSC_LUN1_ISO 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN1_ECMA +#define CONF_USB_MSC_LUN1_ECMA 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN1_ANSI +#define CONF_USB_MSC_LUN1_ANSI 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN1_REPO +#define CONF_USB_MSC_LUN1_REPO 0x01 +#endif + +#ifndef CONF_USB_MSC_LUN1_FACTORY +#define CONF_USB_MSC_LUN1_FACTORY 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN1_PRODUCT +#define CONF_USB_MSC_LUN1_PRODUCT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN1_PRODUCT_VERSION +#define CONF_USB_MSC_LUN1_PRODUCT_VERSION 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN1_CAPACITY +#define CONF_USB_MSC_LUN1_CAPACITY 22 +#endif + +#ifndef CONF_USB_MSC_LUN1_BLOCK_SIZE +#define CONF_USB_MSC_LUN1_BLOCK_SIZE 512 +#endif + +#ifndef CONF_USB_MSC_LUN1_LAST_BLOCK_ADDR +#define CONF_USB_MSC_LUN1_LAST_BLOCK_ADDR \ + ((uint32_t)CONF_USB_MSC_LUN1_CAPACITY * 1024 / CONF_USB_MSC_LUN1_BLOCK_SIZE - 1) +#endif + +// + +// Enable Demo for LUN 2 +// conf_usb_msc_lun2_enable +#ifndef CONF_USB_MSC_LUN2_ENABLE +#define CONF_USB_MSC_LUN2_ENABLE 0 +#endif + +#ifndef CONF_USB_MSC_LUN2_TYPE +#define CONF_USB_MSC_LUN2_TYPE 0x00 +#endif + +// The disk is removable +// conf_usb_msc_lun2_rmb +#ifndef CONF_USB_MSC_LUN2_RMB +#define CONF_USB_MSC_LUN2_RMB 0x01 +#endif + +#ifndef CONF_USB_MSC_LUN2_ISO +#define CONF_USB_MSC_LUN2_ISO 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN2_ECMA +#define CONF_USB_MSC_LUN2_ECMA 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN2_ANSI +#define CONF_USB_MSC_LUN2_ANSI 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN2_REPO +#define CONF_USB_MSC_LUN2_REPO 0x01 +#endif + +#ifndef CONF_USB_MSC_LUN2_FACTORY +#define CONF_USB_MSC_LUN2_FACTORY 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN2_PRODUCT +#define CONF_USB_MSC_LUN2_PRODUCT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN2_PRODUCT_VERSION +#define CONF_USB_MSC_LUN2_PRODUCT_VERSION 0x00, 0x00, 0x00, 0x00 +#endif + +// Disk Size (in KB) <0x1-0xFFFFFFFF> +// conf_usb_msc_lun2_capacity + +#ifndef CONF_USB_MSC_LUN2_CAPACITY +#define CONF_USB_MSC_LUN2_CAPACITY 22 +#endif + +#ifndef CONF_USB_MSC_LUN2_BLOCK_SIZE +#define CONF_USB_MSC_LUN2_BLOCK_SIZE 512 +#endif + +#ifndef CONF_USB_MSC_LUN2_LAST_BLOCK_ADDR +#define CONF_USB_MSC_LUN2_LAST_BLOCK_ADDR \ + ((uint32_t)CONF_USB_MSC_LUN2_CAPACITY * 1024 / CONF_USB_MSC_LUN2_BLOCK_SIZE - 1) +#endif + +// + +// Enable Demo for LUN 3 +// conf_usb_msc_lun3_enable +#ifndef CONF_USB_MSC_LUN3_ENABLE +#define CONF_USB_MSC_LUN3_ENABLE 0 +#endif + +#ifndef CONF_USB_MSC_LUN3_TYPE +#define CONF_USB_MSC_LUN3_TYPE 0x00 +#endif + +// The disk is removable +// conf_usb_msc_lun3_rmb +#ifndef CONF_USB_MSC_LUN3_RMB +#define CONF_USB_MSC_LUN3_RMB 0x01 +#endif + +#ifndef CONF_USB_MSC_LUN3_ISO +#define CONF_USB_MSC_LUN3_ISO 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN3_ECMA +#define CONF_USB_MSC_LUN3_ECMA 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN3_ANSI +#define CONF_USB_MSC_LUN3_ANSI 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN3_REPO +#define CONF_USB_MSC_LUN3_REPO 0x01 +#endif + +#ifndef CONF_USB_MSC_LUN3_FACTORY +#define CONF_USB_MSC_LUN3_FACTORY 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN3_PRODUCT +#define CONF_USB_MSC_LUN3_PRODUCT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN3_PRODUCT_VERSION +#define CONF_USB_MSC_LUN3_PRODUCT_VERSION 0x00, 0x00, 0x00, 0x00 +#endif + +// Disk Size (in KB) <0x1-0xFFFFFFFF> +// conf_usb_msc_lun3_capacity + +#ifndef CONF_USB_MSC_LUN3_CAPACITY +#define CONF_USB_MSC_LUN3_CAPACITY 22 +#endif + +#ifndef CONF_USB_MSC_LUN3_BLOCK_SIZE +#define CONF_USB_MSC_LUN3_BLOCK_SIZE 512 +#endif + +#ifndef CONF_USB_MSC_LUN3_LAST_BLOCK_ADDR +#define CONF_USB_MSC_LUN3_LAST_BLOCK_ADDR \ + ((uint32_t)CONF_USB_MSC_LUN3_CAPACITY * 1024 / CONF_USB_MSC_LUN3_BLOCK_SIZE - 1) +#endif + +// + +// +// + +// <<< end of configuration section >>> + +#endif // USBD_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_adc_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_adc_config.h new file mode 100644 index 00000000000..13d8151028d --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_adc_config.h @@ -0,0 +1,303 @@ +/* Auto-generated config file hpl_adc_config.h */ +#ifndef HPL_ADC_CONFIG_H +#define HPL_ADC_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +#ifndef CONF_ADC_0_ENABLE +#define CONF_ADC_0_ENABLE 1 +#endif + +// Basic Configuration + +// Conversion Result Resolution +// <0x0=>12-bit +// <0x1=>16-bit (averaging must be enabled) +// <0x2=>10-bit +// <0x3=>8-bit +// Defines the bit resolution for the ADC sample values (RESSEL) +// adc_resolution +#ifndef CONF_ADC_0_RESSEL +#define CONF_ADC_0_RESSEL 0x0 +#endif + +// Reference Selection +// <0x0=>Internal bandgap reference +// <0x2=>1/2 VDDANA (only for VDDANA > 2.0V) +// <0x3=>VDDANA +// <0x4=>External reference A +// <0x5=>External reference B +// <0x6=>External reference C +// Select the reference for the ADC (REFSEL) +// adc_reference +#ifndef CONF_ADC_0_REFSEL +#define CONF_ADC_0_REFSEL 0x0 +#endif + +// Prescaler configuration +// <0x0=>Peripheral clock divided by 2 +// <0x1=>Peripheral clock divided by 4 +// <0x2=>Peripheral clock divided by 8 +// <0x3=>Peripheral clock divided by 16 +// <0x4=>Peripheral clock divided by 32 +// <0x5=>Peripheral clock divided by 64 +// <0x6=>Peripheral clock divided by 128 +// <0x7=>Peripheral clock divided by 256 +// These bits define the ADC clock relative to the peripheral clock (PRESCALER) +// adc_prescaler +#ifndef CONF_ADC_0_PRESCALER +#define CONF_ADC_0_PRESCALER 0x3 +#endif + +// Free Running Mode +// When enabled, the ADC is in free running mode and a new conversion will be initiated when a previous conversion completes. (FREERUN) +// adc_freerunning_mode +#ifndef CONF_ADC_0_FREERUN +#define CONF_ADC_0_FREERUN 0 +#endif + +// Differential Mode +// In differential mode, the voltage difference between the MUXPOS and MUXNEG inputs will be converted by the ADC. (DIFFMODE) +// adc_differential_mode +#ifndef CONF_ADC_0_DIFFMODE +#define CONF_ADC_0_DIFFMODE 0 +#endif + +// Positive Mux Input Selection +// <0x00=>ADC AIN0 pin +// <0x01=>ADC AIN1 pin +// <0x02=>ADC AIN2 pin +// <0x03=>ADC AIN3 pin +// <0x04=>ADC AIN4 pin +// <0x05=>ADC AIN5 pin +// <0x06=>ADC AIN6 pin +// <0x07=>ADC AIN7 pin +// <0x08=>ADC AIN8 pin +// <0x09=>ADC AIN9 pin +// <0x0A=>ADC AIN10 pin +// <0x0B=>ADC AIN11 pin +// <0x0C=>ADC AIN12 pin +// <0x0D=>ADC AIN13 pin +// <0x0E=>ADC AIN14 pin +// <0x0F=>ADC AIN15 pin +// <0x18=>1/4 scaled core supply +// <0x19=>1/4 Scaled VBAT Supply +// <0x1A=>1/4 scaled I/O supply +// <0x1B=>Bandgap voltage +// <0x1C=>Temperature reference (PTAT) +// <0x1D=>Temperature reference (CTAT) +// <0x1E=>DAC Output +// These bits define the Mux selection for the positive ADC input. (MUXPOS) +// adc_pinmux_positive +#ifndef CONF_ADC_0_MUXPOS +#define CONF_ADC_0_MUXPOS 0x0 +#endif + +// Negative Mux Input Selection +// <0x00=>ADC AIN0 pin +// <0x01=>ADC AIN1 pin +// <0x02=>ADC AIN2 pin +// <0x03=>ADC AIN3 pin +// <0x04=>ADC AIN4 pin +// <0x05=>ADC AIN5 pin +// <0x06=>ADC AIN6 pin +// <0x07=>ADC AIN7 pin +// <0x18=>Internal ground +// <0x19=>I/O ground +// These bits define the Mux selection for the negative ADC input. (MUXNEG) +// adc_pinmux_negative +#ifndef CONF_ADC_0_MUXNEG +#define CONF_ADC_0_MUXNEG 0x0 +#endif + +// + +// Advanced Configuration +// adc_advanced_settings +#ifndef CONF_ADC_0_ADVANCED +#define CONF_ADC_0_ADVANCED 0 +#endif + +// Run in standby +// Indicates whether the ADC will continue running in standby sleep mode or not (RUNSTDBY) +// adc_arch_runstdby +#ifndef CONF_ADC_0_RUNSTDBY +#define CONF_ADC_0_RUNSTDBY 0 +#endif + +// Debug Run +// If enabled, the ADC is running if the CPU is halted by an external debugger. (DBGRUN) +// adc_arch_dbgrun +#ifndef CONF_ADC_0_DBGRUN +#define CONF_ADC_0_DBGRUN 0 +#endif + +// On Demand Control +// Will keep the ADC peripheral running if requested by other peripherals (ONDEMAND) +// adc_arch_ondemand +#ifndef CONF_ADC_0_ONDEMAND +#define CONF_ADC_0_ONDEMAND 0 +#endif + +// Left-Adjusted Result +// When enabled, the ADC conversion result is left-adjusted in the RESULT register. The high byte of the 12-bit result will be present in the upper part of the result register. (LEFTADJ) +// adc_arch_leftadj +#ifndef CONF_ADC_0_LEFTADJ +#define CONF_ADC_0_LEFTADJ 0 +#endif + +// Reference Buffer Offset Compensation Enable +// The accuracy of the gain stage can be increased by enabling the reference buffer offset compensation. This will decrease the input impedance and thus increase the start-up time of the reference. (REFCOMP) +// adc_arch_refcomp +#ifndef CONF_ADC_0_REFCOMP +#define CONF_ADC_0_REFCOMP 0 +#endif + +// Comparator Offset Compensation Enable +// This bit indicates whether the Comparator Offset Compensation is enabled or not (OFFCOMP) +// adc_arch_offcomp +#ifndef CONF_ADC_0_OFFCOMP +#define CONF_ADC_0_OFFCOMP 0 +#endif + +// Digital Correction Logic Enabled +// When enabled, the ADC conversion result in the RESULT register is then corrected for gain and offset based on the values in the GAINCAL and OFFSETCAL registers. (CORREN) +// adc_arch_corren +#ifndef CONF_ADC_0_CORREN +#define CONF_ADC_0_CORREN 0 +#endif + +// Offset Correction Value <0-4095> +// If the digital correction logic is enabled (CTRLB.CORREN = 1), these bits define how the ADC conversion result is compensated for offset error before being written to the Result register. (OFFSETCORR) +// adc_arch_offsetcorr +#ifndef CONF_ADC_0_OFFSETCORR +#define CONF_ADC_0_OFFSETCORR 0 +#endif + +// Gain Correction Value <0-4095> +// If the digital correction logic is enabled (CTRLB.CORREN = 1), these bits define how the ADC conversion result is compensated for gain error before being written to the result register. (GAINCORR) +// adc_arch_gaincorr +#ifndef CONF_ADC_0_GAINCORR +#define CONF_ADC_0_GAINCORR 0 +#endif + +// Adjusting Result / Division Coefficient <0-7> +// These bits define the division coefficient in 2n steps. (ADJRES) +// adc_arch_adjres +#ifndef CONF_ADC_0_ADJRES +#define CONF_ADC_0_ADJRES 0x0 +#endif + +// Number of Samples to be Collected +// <0x0=>1 sample +// <0x1=>2 samples +// <0x2=>4 samples +// <0x3=>8 samples +// <0x4=>16 samples +// <0x5=>32 samples +// <0x6=>64 samples +// <0x7=>128 samples +// <0x8=>256 samples +// <0x9=>512 samples +// <0xA=>1024 samples +// Define how many samples should be added together.The result will be available in the Result register (SAMPLENUM) +// adc_arch_samplenum +#ifndef CONF_ADC_0_SAMPLENUM +#define CONF_ADC_0_SAMPLENUM 0x0 +#endif + +// Sampling Time Length <0-63> +// These bits control the ADC sampling time in number of half CLK_ADC cycles, depending of the prescaler value, thus controlling the ADC input impedance. (SAMPLEN) +// adc_arch_samplen +#ifndef CONF_ADC_0_SAMPLEN +#define CONF_ADC_0_SAMPLEN 0 +#endif + +// Window Monitor Mode +// <0x0=>No window mode +// <0x1=>Mode 1: RESULT above lower threshold +// <0x2=>Mode 2: RESULT beneath upper threshold +// <0x3=>Mode 3: RESULT inside lower and upper threshold +// <0x4=>Mode 4: RESULT outside lower and upper threshold +// These bits enable and define the window monitor mode. (WINMODE) +// adc_arch_winmode +#ifndef CONF_ADC_0_WINMODE +#define CONF_ADC_0_WINMODE 0x0 +#endif + +// Window Monitor Lower Threshold <0-65535> +// If the window monitor is enabled, these bits define the lower threshold value. (WINLT) +// adc_arch_winlt +#ifndef CONF_ADC_0_WINLT +#define CONF_ADC_0_WINLT 0 +#endif + +// Window Monitor Upper Threshold <0-65535> +// If the window monitor is enabled, these bits define the lower threshold value. (WINUT) +// adc_arch_winut +#ifndef CONF_ADC_0_WINUT +#define CONF_ADC_0_WINUT 0 +#endif + +// Bitmask for positive input sequence <0-4294967295> +// Use this parameter to input the bitmask for positive input sequence control (refer to datasheet for the device). +// adc_arch_seqen +#ifndef CONF_ADC_0_SEQEN +#define CONF_ADC_0_SEQEN 0x0 +#endif + +// + +// Event Control +// adc_arch_event_settings +#ifndef CONF_ADC_0_EVENT_CONTROL +#define CONF_ADC_0_EVENT_CONTROL 0 +#endif + +// Window Monitor Event Out +// Enables event output on window event (WINMONEO) +// adc_arch_winmoneo +#ifndef CONF_ADC_0_WINMONEO +#define CONF_ADC_0_WINMONEO 0 +#endif + +// Result Ready Event Out +// Enables event output on result ready event (RESRDEO) +// adc_arch_resrdyeo +#ifndef CONF_ADC_0_RESRDYEO +#define CONF_ADC_0_RESRDYEO 0 +#endif + +// Invert flush Event Signal +// Invert the flush event input signal (FLUSHINV) +// adc_arch_flushinv +#ifndef CONF_ADC_0_FLUSHINV +#define CONF_ADC_0_FLUSHINV 0 +#endif + +// Trigger Flush On Event +// Trigger an ADC pipeline flush on event (FLUSHEI) +// adc_arch_flushei +#ifndef CONF_ADC_0_FLUSHEI +#define CONF_ADC_0_FLUSHEI 0 +#endif + +// Invert Start Conversion Event Signal +// Invert the start conversion event input signal (STARTINV) +// adc_arch_startinv +#ifndef CONF_ADC_0_STARTINV +#define CONF_ADC_0_STARTINV 0 +#endif + +// Trigger Conversion On Event +// Trigger a conversion on event. (STARTEI) +// adc_arch_startei +#ifndef CONF_ADC_0_STARTEI +#define CONF_ADC_0_STARTEI 0 +#endif + +// + +// <<< end of configuration section >>> + +#endif // HPL_ADC_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_dac_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_dac_config.h new file mode 100644 index 00000000000..d6f1898db88 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_dac_config.h @@ -0,0 +1,169 @@ +/* Auto-generated config file hpl_dac_config.h */ +#ifndef HPL_DAC_CONFIG_H +#define HPL_DAC_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Basic configuration +// Reference Selection +// <0x00=> Unbuffered external voltage reference +// <0x01=> Voltage supply +// <0x02=> Buffered external voltage reference +// <0x03=> Internal bandgap reference +// dac_arch_refsel +#ifndef CONF_DAC_REFSEL +#define CONF_DAC_REFSEL 0 +#endif + +// Differential mode +// Indicates whether the differential mode is enabled or not +// dac_arch_diff +#ifndef CONF_DAC_DIFF +#define CONF_DAC_DIFF 0 +#endif +// + +// Advanced Configuration +// dac_advanced_settings +#ifndef CONF_DAC_ADVANCED_CONFIG +#define CONF_DAC_ADVANCED_CONFIG 0 +#endif + +// Debug Run +// Indicate whether running when CPU is halted +// adc_arch_dbgrun +#ifndef CONF_DAC_DBGRUN +#define CONF_DAC_DBGRUN 1 +#endif + +// Channel 0 configuration +// Left Adjusted Data +// Indicate how the data is adjusted in the Data and Data Buffer register +// dac0_arch_leftadj +#ifndef CONF_DAC0_LEFTADJ +#define CONF_DAC0_LEFTADJ 1 +#endif + +// Current control +// <0=> GCLK_DAC <= 1.2MHz (100kSPS) +// <1=> 1.2MHz < GCLK_DAC <= 6MHz (500kSPS) +// <2=> 6MHz < GCLK_DAC <= 12MHz (1MSPS) +// This defines the current in output buffer according to conversion rate +// dac0_arch_cctrl +#ifndef CONF_DAC0_CCTRL +#define CONF_DAC0_CCTRL 1 +#endif + +// Run in standby +// Indicates whether the DAC channel will continue running in standby sleep mode or not +// dac0_arch_runstdby +#ifndef CONF_DAC0_RUNSTDBY +#define CONF_DAC0_RUNSTDBY 0 +#endif + +// Dithering Mode +// Indicate whether dithering mode is enabled +// dac0_arch_ditrher +#ifndef CONF_DAC0_DITHER +#define CONF_DAC0_DITHER 0 +#endif + +// Refresh period <0x00-0xFF> +// This defines the refresh period. If it is 0, the refresh mode is disabled, else the refresh period is: value * 500us +// dac0_arch_refresh +#ifndef CONF_DAC0_REFRESH +#define CONF_DAC0_REFRESH 2 +#endif +// +// Channel 1 configuration +// Left Adjusted Data +// Indicate how the data is adjusted in the Data and Data Buffer register +// dac1_arch_leftadj +#ifndef CONF_DAC1_LEFTADJ +#define CONF_DAC1_LEFTADJ 1 +#endif + +// Current control +// <0=> GCLK_DAC <= 1.2MHz (100kSPS) +// <1=> 1.2MHz < GCLK_DAC <= 6MHz (500kSPS) +// <2=> 6MHz < GCLK_DAC <= 12MHz (1MSPS) +// This defines the current in output buffer according to conversion rate +// dac1_arch_cctrl +#ifndef CONF_DAC1_CCTRL +#define CONF_DAC1_CCTRL 1 +#endif + +// Run in standby +// Indicates whether the DAC channel will continue running in standby sleep mode or not +// dac1_arch_runstdby +#ifndef CONF_DAC1_RUNSTDBY +#define CONF_DAC1_RUNSTDBY 0 +#endif + +// Dithering Mode +// Indicate whether dithering mode is enabled +// dac1_arch_ditrher +#ifndef CONF_DAC1_DITHER +#define CONF_DAC1_DITHER 0 +#endif + +// Refresh period <0x00-0xFF> +// This defines the refresh period. If it is 0, the refresh mode is disabled, else the refresh period is: value * 500us +// dac1_arch_refresh +#ifndef CONF_DAC1_REFRESH +#define CONF_DAC1_REFRESH 2 +#endif +// + +// Event configuration +// Inversion of DAC 0 event +// <0=> Detection on rising edge pf the input event +// <1=> Detection on falling edge pf the input event +// This defines the edge detection of the input event +// dac_arch_invei0 +#ifndef CONF_DAC_INVEI0 +#define CONF_DAC_INVEI0 0 +#endif + +// Data Buffer of DAC 0 Empty Event Output +// Indicate whether Data Buffer Empty Event is enabled and generated when the Data Buffer register is empty or not +// dac_arch_emptyeo_0 +#ifndef CONF_DAC_EMPTYEO0 +#define CONF_DAC_EMPTYEO0 0 +#endif + +// Start Conversion Event Input DAC 0 +// Indicate whether Start input event is enabled +// dac_arch_startei_0 +#ifndef CONF_DAC_STARTEI0 +#define CONF_DAC_STARTEI0 0 +#endif +// Inversion of DAC 1 event +// <0=> Detection on rising edge pf the input event +// <1=> Detection on falling edge pf the input event +// This defines the edge detection of the input event +// dac_arch_invei1 +#ifndef CONF_DAC_INVEI1 +#define CONF_DAC_INVEI1 0 +#endif + +// Data Buffer of DAC 1 Empty Event Output +// Indicate whether Data Buffer Empty Event is enabled and generated when the Data Buffer register is empty or not +// dac_arch_emptyeo_1 +#ifndef CONF_DAC_EMPTYEO1 +#define CONF_DAC_EMPTYEO1 0 +#endif + +// Start Conversion Event Input DAC 1 +// Indicate whether Start input event is enabled +// dac_arch_startei_1 +#ifndef CONF_DAC_STARTEI1 +#define CONF_DAC_STARTEI1 0 +#endif + +// +// + +// <<< end of configuration section >>> + +#endif // HPL_DAC_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_dmac_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_dmac_config.h new file mode 100644 index 00000000000..90499fc27fe --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_dmac_config.h @@ -0,0 +1,7277 @@ +/* Auto-generated config file hpl_dmac_config.h */ +#ifndef HPL_DMAC_CONFIG_H +#define HPL_DMAC_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// DMAC enable +// Indicates whether dmac is enabled or not +// dmac_enable +#ifndef CONF_DMAC_ENABLE +#define CONF_DMAC_ENABLE 0 +#endif + +// Priority Level 0 +// Indicates whether Priority Level 0 is enabled or not +// dmac_lvlen0 +#ifndef CONF_DMAC_LVLEN0 +#define CONF_DMAC_LVLEN0 1 +#endif + +// Level 0 Round-Robin Arbitration +// <0=> Static arbitration scheme for channel with priority 0 +// <1=> Round-robin arbitration scheme for channel with priority 0 +// Defines Level 0 Arbitration for DMA channels +// dmac_rrlvlen0 +#ifndef CONF_DMAC_RRLVLEN0 +#define CONF_DMAC_RRLVLEN0 0 +#endif + +// Level 0 Channel Priority Number <0x00-0xFF> +// dmac_lvlpri0 +#ifndef CONF_DMAC_LVLPRI0 +#define CONF_DMAC_LVLPRI0 0 +#endif +// Priority Level 1 +// Indicates whether Priority Level 1 is enabled or not +// dmac_lvlen1 +#ifndef CONF_DMAC_LVLEN1 +#define CONF_DMAC_LVLEN1 1 +#endif + +// Level 1 Round-Robin Arbitration +// <0=> Static arbitration scheme for channel with priority 1 +// <1=> Round-robin arbitration scheme for channel with priority 1 +// Defines Level 1 Arbitration for DMA channels +// dmac_rrlvlen1 +#ifndef CONF_DMAC_RRLVLEN1 +#define CONF_DMAC_RRLVLEN1 0 +#endif + +// Level 1 Channel Priority Number <0x00-0xFF> +// dmac_lvlpri1 +#ifndef CONF_DMAC_LVLPRI1 +#define CONF_DMAC_LVLPRI1 0 +#endif +// Priority Level 2 +// Indicates whether Priority Level 2 is enabled or not +// dmac_lvlen2 +#ifndef CONF_DMAC_LVLEN2 +#define CONF_DMAC_LVLEN2 1 +#endif + +// Level 2 Round-Robin Arbitration +// <0=> Static arbitration scheme for channel with priority 2 +// <1=> Round-robin arbitration scheme for channel with priority 2 +// Defines Level 2 Arbitration for DMA channels +// dmac_rrlvlen2 +#ifndef CONF_DMAC_RRLVLEN2 +#define CONF_DMAC_RRLVLEN2 0 +#endif + +// Level 2 Channel Priority Number <0x00-0xFF> +// dmac_lvlpri2 +#ifndef CONF_DMAC_LVLPRI2 +#define CONF_DMAC_LVLPRI2 0 +#endif +// Priority Level 3 +// Indicates whether Priority Level 3 is enabled or not +// dmac_lvlen3 +#ifndef CONF_DMAC_LVLEN3 +#define CONF_DMAC_LVLEN3 1 +#endif + +// Level 3 Round-Robin Arbitration +// <0=> Static arbitration scheme for channel with priority 3 +// <1=> Round-robin arbitration scheme for channel with priority 3 +// Defines Level 3 Arbitration for DMA channels +// dmac_rrlvlen3 +#ifndef CONF_DMAC_RRLVLEN3 +#define CONF_DMAC_RRLVLEN3 0 +#endif + +// Level 3 Channel Priority Number <0x00-0xFF> +// dmac_lvlpri3 +#ifndef CONF_DMAC_LVLPRI3 +#define CONF_DMAC_LVLPRI3 0 +#endif +// Debug Run +// Indicates whether Debug Run is enabled or not +// dmac_dbgrun +#ifndef CONF_DMAC_DBGRUN +#define CONF_DMAC_DBGRUN 0 +#endif + +// Channel 0 settings +// dmac_channel_0_settings +#ifndef CONF_DMAC_CHANNEL_0_SETTINGS +#define CONF_DMAC_CHANNEL_0_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 0 is running in standby mode or not +// dmac_runstdby_0 +#ifndef CONF_DMAC_RUNSTDBY_0 +#define CONF_DMAC_RUNSTDBY_0 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_0 +#ifndef CONF_DMAC_TRIGACT_0 +#define CONF_DMAC_TRIGACT_0 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_0 +#ifndef CONF_DMAC_TRIGSRC_0 +#define CONF_DMAC_TRIGSRC_0 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_0 +#ifndef CONF_DMAC_LVL_0 +#define CONF_DMAC_LVL_0 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_0 +#ifndef CONF_DMAC_EVOE_0 +#define CONF_DMAC_EVOE_0 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_0 +#ifndef CONF_DMAC_EVIE_0 +#define CONF_DMAC_EVIE_0 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_0 +#ifndef CONF_DMAC_EVACT_0 +#define CONF_DMAC_EVACT_0 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_0 +#ifndef CONF_DMAC_STEPSIZE_0 +#define CONF_DMAC_STEPSIZE_0 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_0 +#ifndef CONF_DMAC_STEPSEL_0 +#define CONF_DMAC_STEPSEL_0 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_0 +#ifndef CONF_DMAC_SRCINC_0 +#define CONF_DMAC_SRCINC_0 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_0 +#ifndef CONF_DMAC_DSTINC_0 +#define CONF_DMAC_DSTINC_0 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_0 +#ifndef CONF_DMAC_BEATSIZE_0 +#define CONF_DMAC_BEATSIZE_0 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_0 +#ifndef CONF_DMAC_BLOCKACT_0 +#define CONF_DMAC_BLOCKACT_0 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_0 +#ifndef CONF_DMAC_EVOSEL_0 +#define CONF_DMAC_EVOSEL_0 0 +#endif +// + +// Channel 1 settings +// dmac_channel_1_settings +#ifndef CONF_DMAC_CHANNEL_1_SETTINGS +#define CONF_DMAC_CHANNEL_1_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 1 is running in standby mode or not +// dmac_runstdby_1 +#ifndef CONF_DMAC_RUNSTDBY_1 +#define CONF_DMAC_RUNSTDBY_1 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_1 +#ifndef CONF_DMAC_TRIGACT_1 +#define CONF_DMAC_TRIGACT_1 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_1 +#ifndef CONF_DMAC_TRIGSRC_1 +#define CONF_DMAC_TRIGSRC_1 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_1 +#ifndef CONF_DMAC_LVL_1 +#define CONF_DMAC_LVL_1 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_1 +#ifndef CONF_DMAC_EVOE_1 +#define CONF_DMAC_EVOE_1 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_1 +#ifndef CONF_DMAC_EVIE_1 +#define CONF_DMAC_EVIE_1 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_1 +#ifndef CONF_DMAC_EVACT_1 +#define CONF_DMAC_EVACT_1 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_1 +#ifndef CONF_DMAC_STEPSIZE_1 +#define CONF_DMAC_STEPSIZE_1 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_1 +#ifndef CONF_DMAC_STEPSEL_1 +#define CONF_DMAC_STEPSEL_1 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_1 +#ifndef CONF_DMAC_SRCINC_1 +#define CONF_DMAC_SRCINC_1 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_1 +#ifndef CONF_DMAC_DSTINC_1 +#define CONF_DMAC_DSTINC_1 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_1 +#ifndef CONF_DMAC_BEATSIZE_1 +#define CONF_DMAC_BEATSIZE_1 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_1 +#ifndef CONF_DMAC_BLOCKACT_1 +#define CONF_DMAC_BLOCKACT_1 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_1 +#ifndef CONF_DMAC_EVOSEL_1 +#define CONF_DMAC_EVOSEL_1 0 +#endif +// + +// Channel 2 settings +// dmac_channel_2_settings +#ifndef CONF_DMAC_CHANNEL_2_SETTINGS +#define CONF_DMAC_CHANNEL_2_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 2 is running in standby mode or not +// dmac_runstdby_2 +#ifndef CONF_DMAC_RUNSTDBY_2 +#define CONF_DMAC_RUNSTDBY_2 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_2 +#ifndef CONF_DMAC_TRIGACT_2 +#define CONF_DMAC_TRIGACT_2 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_2 +#ifndef CONF_DMAC_TRIGSRC_2 +#define CONF_DMAC_TRIGSRC_2 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_2 +#ifndef CONF_DMAC_LVL_2 +#define CONF_DMAC_LVL_2 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_2 +#ifndef CONF_DMAC_EVOE_2 +#define CONF_DMAC_EVOE_2 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_2 +#ifndef CONF_DMAC_EVIE_2 +#define CONF_DMAC_EVIE_2 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_2 +#ifndef CONF_DMAC_EVACT_2 +#define CONF_DMAC_EVACT_2 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_2 +#ifndef CONF_DMAC_STEPSIZE_2 +#define CONF_DMAC_STEPSIZE_2 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_2 +#ifndef CONF_DMAC_STEPSEL_2 +#define CONF_DMAC_STEPSEL_2 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_2 +#ifndef CONF_DMAC_SRCINC_2 +#define CONF_DMAC_SRCINC_2 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_2 +#ifndef CONF_DMAC_DSTINC_2 +#define CONF_DMAC_DSTINC_2 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_2 +#ifndef CONF_DMAC_BEATSIZE_2 +#define CONF_DMAC_BEATSIZE_2 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_2 +#ifndef CONF_DMAC_BLOCKACT_2 +#define CONF_DMAC_BLOCKACT_2 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_2 +#ifndef CONF_DMAC_EVOSEL_2 +#define CONF_DMAC_EVOSEL_2 0 +#endif +// + +// Channel 3 settings +// dmac_channel_3_settings +#ifndef CONF_DMAC_CHANNEL_3_SETTINGS +#define CONF_DMAC_CHANNEL_3_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 3 is running in standby mode or not +// dmac_runstdby_3 +#ifndef CONF_DMAC_RUNSTDBY_3 +#define CONF_DMAC_RUNSTDBY_3 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_3 +#ifndef CONF_DMAC_TRIGACT_3 +#define CONF_DMAC_TRIGACT_3 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_3 +#ifndef CONF_DMAC_TRIGSRC_3 +#define CONF_DMAC_TRIGSRC_3 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_3 +#ifndef CONF_DMAC_LVL_3 +#define CONF_DMAC_LVL_3 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_3 +#ifndef CONF_DMAC_EVOE_3 +#define CONF_DMAC_EVOE_3 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_3 +#ifndef CONF_DMAC_EVIE_3 +#define CONF_DMAC_EVIE_3 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_3 +#ifndef CONF_DMAC_EVACT_3 +#define CONF_DMAC_EVACT_3 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_3 +#ifndef CONF_DMAC_STEPSIZE_3 +#define CONF_DMAC_STEPSIZE_3 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_3 +#ifndef CONF_DMAC_STEPSEL_3 +#define CONF_DMAC_STEPSEL_3 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_3 +#ifndef CONF_DMAC_SRCINC_3 +#define CONF_DMAC_SRCINC_3 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_3 +#ifndef CONF_DMAC_DSTINC_3 +#define CONF_DMAC_DSTINC_3 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_3 +#ifndef CONF_DMAC_BEATSIZE_3 +#define CONF_DMAC_BEATSIZE_3 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_3 +#ifndef CONF_DMAC_BLOCKACT_3 +#define CONF_DMAC_BLOCKACT_3 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_3 +#ifndef CONF_DMAC_EVOSEL_3 +#define CONF_DMAC_EVOSEL_3 0 +#endif +// + +// Channel 4 settings +// dmac_channel_4_settings +#ifndef CONF_DMAC_CHANNEL_4_SETTINGS +#define CONF_DMAC_CHANNEL_4_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 4 is running in standby mode or not +// dmac_runstdby_4 +#ifndef CONF_DMAC_RUNSTDBY_4 +#define CONF_DMAC_RUNSTDBY_4 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_4 +#ifndef CONF_DMAC_TRIGACT_4 +#define CONF_DMAC_TRIGACT_4 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_4 +#ifndef CONF_DMAC_TRIGSRC_4 +#define CONF_DMAC_TRIGSRC_4 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_4 +#ifndef CONF_DMAC_LVL_4 +#define CONF_DMAC_LVL_4 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_4 +#ifndef CONF_DMAC_EVOE_4 +#define CONF_DMAC_EVOE_4 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_4 +#ifndef CONF_DMAC_EVIE_4 +#define CONF_DMAC_EVIE_4 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_4 +#ifndef CONF_DMAC_EVACT_4 +#define CONF_DMAC_EVACT_4 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_4 +#ifndef CONF_DMAC_STEPSIZE_4 +#define CONF_DMAC_STEPSIZE_4 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_4 +#ifndef CONF_DMAC_STEPSEL_4 +#define CONF_DMAC_STEPSEL_4 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_4 +#ifndef CONF_DMAC_SRCINC_4 +#define CONF_DMAC_SRCINC_4 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_4 +#ifndef CONF_DMAC_DSTINC_4 +#define CONF_DMAC_DSTINC_4 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_4 +#ifndef CONF_DMAC_BEATSIZE_4 +#define CONF_DMAC_BEATSIZE_4 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_4 +#ifndef CONF_DMAC_BLOCKACT_4 +#define CONF_DMAC_BLOCKACT_4 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_4 +#ifndef CONF_DMAC_EVOSEL_4 +#define CONF_DMAC_EVOSEL_4 0 +#endif +// + +// Channel 5 settings +// dmac_channel_5_settings +#ifndef CONF_DMAC_CHANNEL_5_SETTINGS +#define CONF_DMAC_CHANNEL_5_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 5 is running in standby mode or not +// dmac_runstdby_5 +#ifndef CONF_DMAC_RUNSTDBY_5 +#define CONF_DMAC_RUNSTDBY_5 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_5 +#ifndef CONF_DMAC_TRIGACT_5 +#define CONF_DMAC_TRIGACT_5 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_5 +#ifndef CONF_DMAC_TRIGSRC_5 +#define CONF_DMAC_TRIGSRC_5 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_5 +#ifndef CONF_DMAC_LVL_5 +#define CONF_DMAC_LVL_5 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_5 +#ifndef CONF_DMAC_EVOE_5 +#define CONF_DMAC_EVOE_5 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_5 +#ifndef CONF_DMAC_EVIE_5 +#define CONF_DMAC_EVIE_5 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_5 +#ifndef CONF_DMAC_EVACT_5 +#define CONF_DMAC_EVACT_5 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_5 +#ifndef CONF_DMAC_STEPSIZE_5 +#define CONF_DMAC_STEPSIZE_5 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_5 +#ifndef CONF_DMAC_STEPSEL_5 +#define CONF_DMAC_STEPSEL_5 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_5 +#ifndef CONF_DMAC_SRCINC_5 +#define CONF_DMAC_SRCINC_5 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_5 +#ifndef CONF_DMAC_DSTINC_5 +#define CONF_DMAC_DSTINC_5 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_5 +#ifndef CONF_DMAC_BEATSIZE_5 +#define CONF_DMAC_BEATSIZE_5 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_5 +#ifndef CONF_DMAC_BLOCKACT_5 +#define CONF_DMAC_BLOCKACT_5 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_5 +#ifndef CONF_DMAC_EVOSEL_5 +#define CONF_DMAC_EVOSEL_5 0 +#endif +// + +// Channel 6 settings +// dmac_channel_6_settings +#ifndef CONF_DMAC_CHANNEL_6_SETTINGS +#define CONF_DMAC_CHANNEL_6_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 6 is running in standby mode or not +// dmac_runstdby_6 +#ifndef CONF_DMAC_RUNSTDBY_6 +#define CONF_DMAC_RUNSTDBY_6 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_6 +#ifndef CONF_DMAC_TRIGACT_6 +#define CONF_DMAC_TRIGACT_6 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_6 +#ifndef CONF_DMAC_TRIGSRC_6 +#define CONF_DMAC_TRIGSRC_6 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_6 +#ifndef CONF_DMAC_LVL_6 +#define CONF_DMAC_LVL_6 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_6 +#ifndef CONF_DMAC_EVOE_6 +#define CONF_DMAC_EVOE_6 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_6 +#ifndef CONF_DMAC_EVIE_6 +#define CONF_DMAC_EVIE_6 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_6 +#ifndef CONF_DMAC_EVACT_6 +#define CONF_DMAC_EVACT_6 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_6 +#ifndef CONF_DMAC_STEPSIZE_6 +#define CONF_DMAC_STEPSIZE_6 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_6 +#ifndef CONF_DMAC_STEPSEL_6 +#define CONF_DMAC_STEPSEL_6 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_6 +#ifndef CONF_DMAC_SRCINC_6 +#define CONF_DMAC_SRCINC_6 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_6 +#ifndef CONF_DMAC_DSTINC_6 +#define CONF_DMAC_DSTINC_6 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_6 +#ifndef CONF_DMAC_BEATSIZE_6 +#define CONF_DMAC_BEATSIZE_6 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_6 +#ifndef CONF_DMAC_BLOCKACT_6 +#define CONF_DMAC_BLOCKACT_6 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_6 +#ifndef CONF_DMAC_EVOSEL_6 +#define CONF_DMAC_EVOSEL_6 0 +#endif +// + +// Channel 7 settings +// dmac_channel_7_settings +#ifndef CONF_DMAC_CHANNEL_7_SETTINGS +#define CONF_DMAC_CHANNEL_7_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 7 is running in standby mode or not +// dmac_runstdby_7 +#ifndef CONF_DMAC_RUNSTDBY_7 +#define CONF_DMAC_RUNSTDBY_7 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_7 +#ifndef CONF_DMAC_TRIGACT_7 +#define CONF_DMAC_TRIGACT_7 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_7 +#ifndef CONF_DMAC_TRIGSRC_7 +#define CONF_DMAC_TRIGSRC_7 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_7 +#ifndef CONF_DMAC_LVL_7 +#define CONF_DMAC_LVL_7 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_7 +#ifndef CONF_DMAC_EVOE_7 +#define CONF_DMAC_EVOE_7 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_7 +#ifndef CONF_DMAC_EVIE_7 +#define CONF_DMAC_EVIE_7 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_7 +#ifndef CONF_DMAC_EVACT_7 +#define CONF_DMAC_EVACT_7 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_7 +#ifndef CONF_DMAC_STEPSIZE_7 +#define CONF_DMAC_STEPSIZE_7 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_7 +#ifndef CONF_DMAC_STEPSEL_7 +#define CONF_DMAC_STEPSEL_7 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_7 +#ifndef CONF_DMAC_SRCINC_7 +#define CONF_DMAC_SRCINC_7 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_7 +#ifndef CONF_DMAC_DSTINC_7 +#define CONF_DMAC_DSTINC_7 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_7 +#ifndef CONF_DMAC_BEATSIZE_7 +#define CONF_DMAC_BEATSIZE_7 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_7 +#ifndef CONF_DMAC_BLOCKACT_7 +#define CONF_DMAC_BLOCKACT_7 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_7 +#ifndef CONF_DMAC_EVOSEL_7 +#define CONF_DMAC_EVOSEL_7 0 +#endif +// + +// Channel 8 settings +// dmac_channel_8_settings +#ifndef CONF_DMAC_CHANNEL_8_SETTINGS +#define CONF_DMAC_CHANNEL_8_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 8 is running in standby mode or not +// dmac_runstdby_8 +#ifndef CONF_DMAC_RUNSTDBY_8 +#define CONF_DMAC_RUNSTDBY_8 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_8 +#ifndef CONF_DMAC_TRIGACT_8 +#define CONF_DMAC_TRIGACT_8 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_8 +#ifndef CONF_DMAC_TRIGSRC_8 +#define CONF_DMAC_TRIGSRC_8 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_8 +#ifndef CONF_DMAC_LVL_8 +#define CONF_DMAC_LVL_8 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_8 +#ifndef CONF_DMAC_EVOE_8 +#define CONF_DMAC_EVOE_8 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_8 +#ifndef CONF_DMAC_EVIE_8 +#define CONF_DMAC_EVIE_8 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_8 +#ifndef CONF_DMAC_EVACT_8 +#define CONF_DMAC_EVACT_8 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_8 +#ifndef CONF_DMAC_STEPSIZE_8 +#define CONF_DMAC_STEPSIZE_8 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_8 +#ifndef CONF_DMAC_STEPSEL_8 +#define CONF_DMAC_STEPSEL_8 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_8 +#ifndef CONF_DMAC_SRCINC_8 +#define CONF_DMAC_SRCINC_8 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_8 +#ifndef CONF_DMAC_DSTINC_8 +#define CONF_DMAC_DSTINC_8 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_8 +#ifndef CONF_DMAC_BEATSIZE_8 +#define CONF_DMAC_BEATSIZE_8 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_8 +#ifndef CONF_DMAC_BLOCKACT_8 +#define CONF_DMAC_BLOCKACT_8 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_8 +#ifndef CONF_DMAC_EVOSEL_8 +#define CONF_DMAC_EVOSEL_8 0 +#endif +// + +// Channel 9 settings +// dmac_channel_9_settings +#ifndef CONF_DMAC_CHANNEL_9_SETTINGS +#define CONF_DMAC_CHANNEL_9_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 9 is running in standby mode or not +// dmac_runstdby_9 +#ifndef CONF_DMAC_RUNSTDBY_9 +#define CONF_DMAC_RUNSTDBY_9 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_9 +#ifndef CONF_DMAC_TRIGACT_9 +#define CONF_DMAC_TRIGACT_9 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_9 +#ifndef CONF_DMAC_TRIGSRC_9 +#define CONF_DMAC_TRIGSRC_9 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_9 +#ifndef CONF_DMAC_LVL_9 +#define CONF_DMAC_LVL_9 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_9 +#ifndef CONF_DMAC_EVOE_9 +#define CONF_DMAC_EVOE_9 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_9 +#ifndef CONF_DMAC_EVIE_9 +#define CONF_DMAC_EVIE_9 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_9 +#ifndef CONF_DMAC_EVACT_9 +#define CONF_DMAC_EVACT_9 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_9 +#ifndef CONF_DMAC_STEPSIZE_9 +#define CONF_DMAC_STEPSIZE_9 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_9 +#ifndef CONF_DMAC_STEPSEL_9 +#define CONF_DMAC_STEPSEL_9 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_9 +#ifndef CONF_DMAC_SRCINC_9 +#define CONF_DMAC_SRCINC_9 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_9 +#ifndef CONF_DMAC_DSTINC_9 +#define CONF_DMAC_DSTINC_9 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_9 +#ifndef CONF_DMAC_BEATSIZE_9 +#define CONF_DMAC_BEATSIZE_9 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_9 +#ifndef CONF_DMAC_BLOCKACT_9 +#define CONF_DMAC_BLOCKACT_9 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_9 +#ifndef CONF_DMAC_EVOSEL_9 +#define CONF_DMAC_EVOSEL_9 0 +#endif +// + +// Channel 10 settings +// dmac_channel_10_settings +#ifndef CONF_DMAC_CHANNEL_10_SETTINGS +#define CONF_DMAC_CHANNEL_10_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 10 is running in standby mode or not +// dmac_runstdby_10 +#ifndef CONF_DMAC_RUNSTDBY_10 +#define CONF_DMAC_RUNSTDBY_10 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_10 +#ifndef CONF_DMAC_TRIGACT_10 +#define CONF_DMAC_TRIGACT_10 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_10 +#ifndef CONF_DMAC_TRIGSRC_10 +#define CONF_DMAC_TRIGSRC_10 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_10 +#ifndef CONF_DMAC_LVL_10 +#define CONF_DMAC_LVL_10 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_10 +#ifndef CONF_DMAC_EVOE_10 +#define CONF_DMAC_EVOE_10 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_10 +#ifndef CONF_DMAC_EVIE_10 +#define CONF_DMAC_EVIE_10 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_10 +#ifndef CONF_DMAC_EVACT_10 +#define CONF_DMAC_EVACT_10 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_10 +#ifndef CONF_DMAC_STEPSIZE_10 +#define CONF_DMAC_STEPSIZE_10 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_10 +#ifndef CONF_DMAC_STEPSEL_10 +#define CONF_DMAC_STEPSEL_10 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_10 +#ifndef CONF_DMAC_SRCINC_10 +#define CONF_DMAC_SRCINC_10 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_10 +#ifndef CONF_DMAC_DSTINC_10 +#define CONF_DMAC_DSTINC_10 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_10 +#ifndef CONF_DMAC_BEATSIZE_10 +#define CONF_DMAC_BEATSIZE_10 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_10 +#ifndef CONF_DMAC_BLOCKACT_10 +#define CONF_DMAC_BLOCKACT_10 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_10 +#ifndef CONF_DMAC_EVOSEL_10 +#define CONF_DMAC_EVOSEL_10 0 +#endif +// + +// Channel 11 settings +// dmac_channel_11_settings +#ifndef CONF_DMAC_CHANNEL_11_SETTINGS +#define CONF_DMAC_CHANNEL_11_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 11 is running in standby mode or not +// dmac_runstdby_11 +#ifndef CONF_DMAC_RUNSTDBY_11 +#define CONF_DMAC_RUNSTDBY_11 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_11 +#ifndef CONF_DMAC_TRIGACT_11 +#define CONF_DMAC_TRIGACT_11 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_11 +#ifndef CONF_DMAC_TRIGSRC_11 +#define CONF_DMAC_TRIGSRC_11 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_11 +#ifndef CONF_DMAC_LVL_11 +#define CONF_DMAC_LVL_11 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_11 +#ifndef CONF_DMAC_EVOE_11 +#define CONF_DMAC_EVOE_11 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_11 +#ifndef CONF_DMAC_EVIE_11 +#define CONF_DMAC_EVIE_11 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_11 +#ifndef CONF_DMAC_EVACT_11 +#define CONF_DMAC_EVACT_11 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_11 +#ifndef CONF_DMAC_STEPSIZE_11 +#define CONF_DMAC_STEPSIZE_11 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_11 +#ifndef CONF_DMAC_STEPSEL_11 +#define CONF_DMAC_STEPSEL_11 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_11 +#ifndef CONF_DMAC_SRCINC_11 +#define CONF_DMAC_SRCINC_11 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_11 +#ifndef CONF_DMAC_DSTINC_11 +#define CONF_DMAC_DSTINC_11 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_11 +#ifndef CONF_DMAC_BEATSIZE_11 +#define CONF_DMAC_BEATSIZE_11 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_11 +#ifndef CONF_DMAC_BLOCKACT_11 +#define CONF_DMAC_BLOCKACT_11 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_11 +#ifndef CONF_DMAC_EVOSEL_11 +#define CONF_DMAC_EVOSEL_11 0 +#endif +// + +// Channel 12 settings +// dmac_channel_12_settings +#ifndef CONF_DMAC_CHANNEL_12_SETTINGS +#define CONF_DMAC_CHANNEL_12_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 12 is running in standby mode or not +// dmac_runstdby_12 +#ifndef CONF_DMAC_RUNSTDBY_12 +#define CONF_DMAC_RUNSTDBY_12 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_12 +#ifndef CONF_DMAC_TRIGACT_12 +#define CONF_DMAC_TRIGACT_12 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_12 +#ifndef CONF_DMAC_TRIGSRC_12 +#define CONF_DMAC_TRIGSRC_12 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_12 +#ifndef CONF_DMAC_LVL_12 +#define CONF_DMAC_LVL_12 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_12 +#ifndef CONF_DMAC_EVOE_12 +#define CONF_DMAC_EVOE_12 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_12 +#ifndef CONF_DMAC_EVIE_12 +#define CONF_DMAC_EVIE_12 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_12 +#ifndef CONF_DMAC_EVACT_12 +#define CONF_DMAC_EVACT_12 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_12 +#ifndef CONF_DMAC_STEPSIZE_12 +#define CONF_DMAC_STEPSIZE_12 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_12 +#ifndef CONF_DMAC_STEPSEL_12 +#define CONF_DMAC_STEPSEL_12 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_12 +#ifndef CONF_DMAC_SRCINC_12 +#define CONF_DMAC_SRCINC_12 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_12 +#ifndef CONF_DMAC_DSTINC_12 +#define CONF_DMAC_DSTINC_12 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_12 +#ifndef CONF_DMAC_BEATSIZE_12 +#define CONF_DMAC_BEATSIZE_12 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_12 +#ifndef CONF_DMAC_BLOCKACT_12 +#define CONF_DMAC_BLOCKACT_12 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_12 +#ifndef CONF_DMAC_EVOSEL_12 +#define CONF_DMAC_EVOSEL_12 0 +#endif +// + +// Channel 13 settings +// dmac_channel_13_settings +#ifndef CONF_DMAC_CHANNEL_13_SETTINGS +#define CONF_DMAC_CHANNEL_13_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 13 is running in standby mode or not +// dmac_runstdby_13 +#ifndef CONF_DMAC_RUNSTDBY_13 +#define CONF_DMAC_RUNSTDBY_13 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_13 +#ifndef CONF_DMAC_TRIGACT_13 +#define CONF_DMAC_TRIGACT_13 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_13 +#ifndef CONF_DMAC_TRIGSRC_13 +#define CONF_DMAC_TRIGSRC_13 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_13 +#ifndef CONF_DMAC_LVL_13 +#define CONF_DMAC_LVL_13 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_13 +#ifndef CONF_DMAC_EVOE_13 +#define CONF_DMAC_EVOE_13 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_13 +#ifndef CONF_DMAC_EVIE_13 +#define CONF_DMAC_EVIE_13 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_13 +#ifndef CONF_DMAC_EVACT_13 +#define CONF_DMAC_EVACT_13 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_13 +#ifndef CONF_DMAC_STEPSIZE_13 +#define CONF_DMAC_STEPSIZE_13 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_13 +#ifndef CONF_DMAC_STEPSEL_13 +#define CONF_DMAC_STEPSEL_13 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_13 +#ifndef CONF_DMAC_SRCINC_13 +#define CONF_DMAC_SRCINC_13 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_13 +#ifndef CONF_DMAC_DSTINC_13 +#define CONF_DMAC_DSTINC_13 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_13 +#ifndef CONF_DMAC_BEATSIZE_13 +#define CONF_DMAC_BEATSIZE_13 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_13 +#ifndef CONF_DMAC_BLOCKACT_13 +#define CONF_DMAC_BLOCKACT_13 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_13 +#ifndef CONF_DMAC_EVOSEL_13 +#define CONF_DMAC_EVOSEL_13 0 +#endif +// + +// Channel 14 settings +// dmac_channel_14_settings +#ifndef CONF_DMAC_CHANNEL_14_SETTINGS +#define CONF_DMAC_CHANNEL_14_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 14 is running in standby mode or not +// dmac_runstdby_14 +#ifndef CONF_DMAC_RUNSTDBY_14 +#define CONF_DMAC_RUNSTDBY_14 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_14 +#ifndef CONF_DMAC_TRIGACT_14 +#define CONF_DMAC_TRIGACT_14 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_14 +#ifndef CONF_DMAC_TRIGSRC_14 +#define CONF_DMAC_TRIGSRC_14 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_14 +#ifndef CONF_DMAC_LVL_14 +#define CONF_DMAC_LVL_14 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_14 +#ifndef CONF_DMAC_EVOE_14 +#define CONF_DMAC_EVOE_14 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_14 +#ifndef CONF_DMAC_EVIE_14 +#define CONF_DMAC_EVIE_14 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_14 +#ifndef CONF_DMAC_EVACT_14 +#define CONF_DMAC_EVACT_14 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_14 +#ifndef CONF_DMAC_STEPSIZE_14 +#define CONF_DMAC_STEPSIZE_14 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_14 +#ifndef CONF_DMAC_STEPSEL_14 +#define CONF_DMAC_STEPSEL_14 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_14 +#ifndef CONF_DMAC_SRCINC_14 +#define CONF_DMAC_SRCINC_14 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_14 +#ifndef CONF_DMAC_DSTINC_14 +#define CONF_DMAC_DSTINC_14 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_14 +#ifndef CONF_DMAC_BEATSIZE_14 +#define CONF_DMAC_BEATSIZE_14 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_14 +#ifndef CONF_DMAC_BLOCKACT_14 +#define CONF_DMAC_BLOCKACT_14 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_14 +#ifndef CONF_DMAC_EVOSEL_14 +#define CONF_DMAC_EVOSEL_14 0 +#endif +// + +// Channel 15 settings +// dmac_channel_15_settings +#ifndef CONF_DMAC_CHANNEL_15_SETTINGS +#define CONF_DMAC_CHANNEL_15_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 15 is running in standby mode or not +// dmac_runstdby_15 +#ifndef CONF_DMAC_RUNSTDBY_15 +#define CONF_DMAC_RUNSTDBY_15 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_15 +#ifndef CONF_DMAC_TRIGACT_15 +#define CONF_DMAC_TRIGACT_15 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_15 +#ifndef CONF_DMAC_TRIGSRC_15 +#define CONF_DMAC_TRIGSRC_15 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_15 +#ifndef CONF_DMAC_LVL_15 +#define CONF_DMAC_LVL_15 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_15 +#ifndef CONF_DMAC_EVOE_15 +#define CONF_DMAC_EVOE_15 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_15 +#ifndef CONF_DMAC_EVIE_15 +#define CONF_DMAC_EVIE_15 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_15 +#ifndef CONF_DMAC_EVACT_15 +#define CONF_DMAC_EVACT_15 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_15 +#ifndef CONF_DMAC_STEPSIZE_15 +#define CONF_DMAC_STEPSIZE_15 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_15 +#ifndef CONF_DMAC_STEPSEL_15 +#define CONF_DMAC_STEPSEL_15 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_15 +#ifndef CONF_DMAC_SRCINC_15 +#define CONF_DMAC_SRCINC_15 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_15 +#ifndef CONF_DMAC_DSTINC_15 +#define CONF_DMAC_DSTINC_15 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_15 +#ifndef CONF_DMAC_BEATSIZE_15 +#define CONF_DMAC_BEATSIZE_15 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_15 +#ifndef CONF_DMAC_BLOCKACT_15 +#define CONF_DMAC_BLOCKACT_15 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_15 +#ifndef CONF_DMAC_EVOSEL_15 +#define CONF_DMAC_EVOSEL_15 0 +#endif +// + +// Channel 16 settings +// dmac_channel_16_settings +#ifndef CONF_DMAC_CHANNEL_16_SETTINGS +#define CONF_DMAC_CHANNEL_16_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 16 is running in standby mode or not +// dmac_runstdby_16 +#ifndef CONF_DMAC_RUNSTDBY_16 +#define CONF_DMAC_RUNSTDBY_16 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_16 +#ifndef CONF_DMAC_TRIGACT_16 +#define CONF_DMAC_TRIGACT_16 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_16 +#ifndef CONF_DMAC_TRIGSRC_16 +#define CONF_DMAC_TRIGSRC_16 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_16 +#ifndef CONF_DMAC_LVL_16 +#define CONF_DMAC_LVL_16 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_16 +#ifndef CONF_DMAC_EVOE_16 +#define CONF_DMAC_EVOE_16 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_16 +#ifndef CONF_DMAC_EVIE_16 +#define CONF_DMAC_EVIE_16 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_16 +#ifndef CONF_DMAC_EVACT_16 +#define CONF_DMAC_EVACT_16 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_16 +#ifndef CONF_DMAC_STEPSIZE_16 +#define CONF_DMAC_STEPSIZE_16 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_16 +#ifndef CONF_DMAC_STEPSEL_16 +#define CONF_DMAC_STEPSEL_16 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_16 +#ifndef CONF_DMAC_SRCINC_16 +#define CONF_DMAC_SRCINC_16 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_16 +#ifndef CONF_DMAC_DSTINC_16 +#define CONF_DMAC_DSTINC_16 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_16 +#ifndef CONF_DMAC_BEATSIZE_16 +#define CONF_DMAC_BEATSIZE_16 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_16 +#ifndef CONF_DMAC_BLOCKACT_16 +#define CONF_DMAC_BLOCKACT_16 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_16 +#ifndef CONF_DMAC_EVOSEL_16 +#define CONF_DMAC_EVOSEL_16 0 +#endif +// + +// Channel 17 settings +// dmac_channel_17_settings +#ifndef CONF_DMAC_CHANNEL_17_SETTINGS +#define CONF_DMAC_CHANNEL_17_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 17 is running in standby mode or not +// dmac_runstdby_17 +#ifndef CONF_DMAC_RUNSTDBY_17 +#define CONF_DMAC_RUNSTDBY_17 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_17 +#ifndef CONF_DMAC_TRIGACT_17 +#define CONF_DMAC_TRIGACT_17 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_17 +#ifndef CONF_DMAC_TRIGSRC_17 +#define CONF_DMAC_TRIGSRC_17 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_17 +#ifndef CONF_DMAC_LVL_17 +#define CONF_DMAC_LVL_17 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_17 +#ifndef CONF_DMAC_EVOE_17 +#define CONF_DMAC_EVOE_17 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_17 +#ifndef CONF_DMAC_EVIE_17 +#define CONF_DMAC_EVIE_17 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_17 +#ifndef CONF_DMAC_EVACT_17 +#define CONF_DMAC_EVACT_17 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_17 +#ifndef CONF_DMAC_STEPSIZE_17 +#define CONF_DMAC_STEPSIZE_17 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_17 +#ifndef CONF_DMAC_STEPSEL_17 +#define CONF_DMAC_STEPSEL_17 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_17 +#ifndef CONF_DMAC_SRCINC_17 +#define CONF_DMAC_SRCINC_17 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_17 +#ifndef CONF_DMAC_DSTINC_17 +#define CONF_DMAC_DSTINC_17 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_17 +#ifndef CONF_DMAC_BEATSIZE_17 +#define CONF_DMAC_BEATSIZE_17 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_17 +#ifndef CONF_DMAC_BLOCKACT_17 +#define CONF_DMAC_BLOCKACT_17 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_17 +#ifndef CONF_DMAC_EVOSEL_17 +#define CONF_DMAC_EVOSEL_17 0 +#endif +// + +// Channel 18 settings +// dmac_channel_18_settings +#ifndef CONF_DMAC_CHANNEL_18_SETTINGS +#define CONF_DMAC_CHANNEL_18_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 18 is running in standby mode or not +// dmac_runstdby_18 +#ifndef CONF_DMAC_RUNSTDBY_18 +#define CONF_DMAC_RUNSTDBY_18 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_18 +#ifndef CONF_DMAC_TRIGACT_18 +#define CONF_DMAC_TRIGACT_18 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_18 +#ifndef CONF_DMAC_TRIGSRC_18 +#define CONF_DMAC_TRIGSRC_18 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_18 +#ifndef CONF_DMAC_LVL_18 +#define CONF_DMAC_LVL_18 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_18 +#ifndef CONF_DMAC_EVOE_18 +#define CONF_DMAC_EVOE_18 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_18 +#ifndef CONF_DMAC_EVIE_18 +#define CONF_DMAC_EVIE_18 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_18 +#ifndef CONF_DMAC_EVACT_18 +#define CONF_DMAC_EVACT_18 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_18 +#ifndef CONF_DMAC_STEPSIZE_18 +#define CONF_DMAC_STEPSIZE_18 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_18 +#ifndef CONF_DMAC_STEPSEL_18 +#define CONF_DMAC_STEPSEL_18 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_18 +#ifndef CONF_DMAC_SRCINC_18 +#define CONF_DMAC_SRCINC_18 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_18 +#ifndef CONF_DMAC_DSTINC_18 +#define CONF_DMAC_DSTINC_18 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_18 +#ifndef CONF_DMAC_BEATSIZE_18 +#define CONF_DMAC_BEATSIZE_18 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_18 +#ifndef CONF_DMAC_BLOCKACT_18 +#define CONF_DMAC_BLOCKACT_18 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_18 +#ifndef CONF_DMAC_EVOSEL_18 +#define CONF_DMAC_EVOSEL_18 0 +#endif +// + +// Channel 19 settings +// dmac_channel_19_settings +#ifndef CONF_DMAC_CHANNEL_19_SETTINGS +#define CONF_DMAC_CHANNEL_19_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 19 is running in standby mode or not +// dmac_runstdby_19 +#ifndef CONF_DMAC_RUNSTDBY_19 +#define CONF_DMAC_RUNSTDBY_19 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_19 +#ifndef CONF_DMAC_TRIGACT_19 +#define CONF_DMAC_TRIGACT_19 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_19 +#ifndef CONF_DMAC_TRIGSRC_19 +#define CONF_DMAC_TRIGSRC_19 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_19 +#ifndef CONF_DMAC_LVL_19 +#define CONF_DMAC_LVL_19 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_19 +#ifndef CONF_DMAC_EVOE_19 +#define CONF_DMAC_EVOE_19 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_19 +#ifndef CONF_DMAC_EVIE_19 +#define CONF_DMAC_EVIE_19 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_19 +#ifndef CONF_DMAC_EVACT_19 +#define CONF_DMAC_EVACT_19 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_19 +#ifndef CONF_DMAC_STEPSIZE_19 +#define CONF_DMAC_STEPSIZE_19 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_19 +#ifndef CONF_DMAC_STEPSEL_19 +#define CONF_DMAC_STEPSEL_19 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_19 +#ifndef CONF_DMAC_SRCINC_19 +#define CONF_DMAC_SRCINC_19 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_19 +#ifndef CONF_DMAC_DSTINC_19 +#define CONF_DMAC_DSTINC_19 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_19 +#ifndef CONF_DMAC_BEATSIZE_19 +#define CONF_DMAC_BEATSIZE_19 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_19 +#ifndef CONF_DMAC_BLOCKACT_19 +#define CONF_DMAC_BLOCKACT_19 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_19 +#ifndef CONF_DMAC_EVOSEL_19 +#define CONF_DMAC_EVOSEL_19 0 +#endif +// + +// Channel 20 settings +// dmac_channel_20_settings +#ifndef CONF_DMAC_CHANNEL_20_SETTINGS +#define CONF_DMAC_CHANNEL_20_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 20 is running in standby mode or not +// dmac_runstdby_20 +#ifndef CONF_DMAC_RUNSTDBY_20 +#define CONF_DMAC_RUNSTDBY_20 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_20 +#ifndef CONF_DMAC_TRIGACT_20 +#define CONF_DMAC_TRIGACT_20 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_20 +#ifndef CONF_DMAC_TRIGSRC_20 +#define CONF_DMAC_TRIGSRC_20 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_20 +#ifndef CONF_DMAC_LVL_20 +#define CONF_DMAC_LVL_20 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_20 +#ifndef CONF_DMAC_EVOE_20 +#define CONF_DMAC_EVOE_20 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_20 +#ifndef CONF_DMAC_EVIE_20 +#define CONF_DMAC_EVIE_20 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_20 +#ifndef CONF_DMAC_EVACT_20 +#define CONF_DMAC_EVACT_20 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_20 +#ifndef CONF_DMAC_STEPSIZE_20 +#define CONF_DMAC_STEPSIZE_20 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_20 +#ifndef CONF_DMAC_STEPSEL_20 +#define CONF_DMAC_STEPSEL_20 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_20 +#ifndef CONF_DMAC_SRCINC_20 +#define CONF_DMAC_SRCINC_20 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_20 +#ifndef CONF_DMAC_DSTINC_20 +#define CONF_DMAC_DSTINC_20 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_20 +#ifndef CONF_DMAC_BEATSIZE_20 +#define CONF_DMAC_BEATSIZE_20 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_20 +#ifndef CONF_DMAC_BLOCKACT_20 +#define CONF_DMAC_BLOCKACT_20 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_20 +#ifndef CONF_DMAC_EVOSEL_20 +#define CONF_DMAC_EVOSEL_20 0 +#endif +// + +// Channel 21 settings +// dmac_channel_21_settings +#ifndef CONF_DMAC_CHANNEL_21_SETTINGS +#define CONF_DMAC_CHANNEL_21_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 21 is running in standby mode or not +// dmac_runstdby_21 +#ifndef CONF_DMAC_RUNSTDBY_21 +#define CONF_DMAC_RUNSTDBY_21 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_21 +#ifndef CONF_DMAC_TRIGACT_21 +#define CONF_DMAC_TRIGACT_21 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_21 +#ifndef CONF_DMAC_TRIGSRC_21 +#define CONF_DMAC_TRIGSRC_21 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_21 +#ifndef CONF_DMAC_LVL_21 +#define CONF_DMAC_LVL_21 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_21 +#ifndef CONF_DMAC_EVOE_21 +#define CONF_DMAC_EVOE_21 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_21 +#ifndef CONF_DMAC_EVIE_21 +#define CONF_DMAC_EVIE_21 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_21 +#ifndef CONF_DMAC_EVACT_21 +#define CONF_DMAC_EVACT_21 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_21 +#ifndef CONF_DMAC_STEPSIZE_21 +#define CONF_DMAC_STEPSIZE_21 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_21 +#ifndef CONF_DMAC_STEPSEL_21 +#define CONF_DMAC_STEPSEL_21 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_21 +#ifndef CONF_DMAC_SRCINC_21 +#define CONF_DMAC_SRCINC_21 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_21 +#ifndef CONF_DMAC_DSTINC_21 +#define CONF_DMAC_DSTINC_21 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_21 +#ifndef CONF_DMAC_BEATSIZE_21 +#define CONF_DMAC_BEATSIZE_21 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_21 +#ifndef CONF_DMAC_BLOCKACT_21 +#define CONF_DMAC_BLOCKACT_21 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_21 +#ifndef CONF_DMAC_EVOSEL_21 +#define CONF_DMAC_EVOSEL_21 0 +#endif +// + +// Channel 22 settings +// dmac_channel_22_settings +#ifndef CONF_DMAC_CHANNEL_22_SETTINGS +#define CONF_DMAC_CHANNEL_22_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 22 is running in standby mode or not +// dmac_runstdby_22 +#ifndef CONF_DMAC_RUNSTDBY_22 +#define CONF_DMAC_RUNSTDBY_22 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_22 +#ifndef CONF_DMAC_TRIGACT_22 +#define CONF_DMAC_TRIGACT_22 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_22 +#ifndef CONF_DMAC_TRIGSRC_22 +#define CONF_DMAC_TRIGSRC_22 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_22 +#ifndef CONF_DMAC_LVL_22 +#define CONF_DMAC_LVL_22 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_22 +#ifndef CONF_DMAC_EVOE_22 +#define CONF_DMAC_EVOE_22 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_22 +#ifndef CONF_DMAC_EVIE_22 +#define CONF_DMAC_EVIE_22 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_22 +#ifndef CONF_DMAC_EVACT_22 +#define CONF_DMAC_EVACT_22 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_22 +#ifndef CONF_DMAC_STEPSIZE_22 +#define CONF_DMAC_STEPSIZE_22 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_22 +#ifndef CONF_DMAC_STEPSEL_22 +#define CONF_DMAC_STEPSEL_22 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_22 +#ifndef CONF_DMAC_SRCINC_22 +#define CONF_DMAC_SRCINC_22 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_22 +#ifndef CONF_DMAC_DSTINC_22 +#define CONF_DMAC_DSTINC_22 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_22 +#ifndef CONF_DMAC_BEATSIZE_22 +#define CONF_DMAC_BEATSIZE_22 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_22 +#ifndef CONF_DMAC_BLOCKACT_22 +#define CONF_DMAC_BLOCKACT_22 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_22 +#ifndef CONF_DMAC_EVOSEL_22 +#define CONF_DMAC_EVOSEL_22 0 +#endif +// + +// Channel 23 settings +// dmac_channel_23_settings +#ifndef CONF_DMAC_CHANNEL_23_SETTINGS +#define CONF_DMAC_CHANNEL_23_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 23 is running in standby mode or not +// dmac_runstdby_23 +#ifndef CONF_DMAC_RUNSTDBY_23 +#define CONF_DMAC_RUNSTDBY_23 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_23 +#ifndef CONF_DMAC_TRIGACT_23 +#define CONF_DMAC_TRIGACT_23 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_23 +#ifndef CONF_DMAC_TRIGSRC_23 +#define CONF_DMAC_TRIGSRC_23 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_23 +#ifndef CONF_DMAC_LVL_23 +#define CONF_DMAC_LVL_23 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_23 +#ifndef CONF_DMAC_EVOE_23 +#define CONF_DMAC_EVOE_23 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_23 +#ifndef CONF_DMAC_EVIE_23 +#define CONF_DMAC_EVIE_23 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_23 +#ifndef CONF_DMAC_EVACT_23 +#define CONF_DMAC_EVACT_23 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_23 +#ifndef CONF_DMAC_STEPSIZE_23 +#define CONF_DMAC_STEPSIZE_23 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_23 +#ifndef CONF_DMAC_STEPSEL_23 +#define CONF_DMAC_STEPSEL_23 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_23 +#ifndef CONF_DMAC_SRCINC_23 +#define CONF_DMAC_SRCINC_23 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_23 +#ifndef CONF_DMAC_DSTINC_23 +#define CONF_DMAC_DSTINC_23 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_23 +#ifndef CONF_DMAC_BEATSIZE_23 +#define CONF_DMAC_BEATSIZE_23 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_23 +#ifndef CONF_DMAC_BLOCKACT_23 +#define CONF_DMAC_BLOCKACT_23 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_23 +#ifndef CONF_DMAC_EVOSEL_23 +#define CONF_DMAC_EVOSEL_23 0 +#endif +// + +// Channel 24 settings +// dmac_channel_24_settings +#ifndef CONF_DMAC_CHANNEL_24_SETTINGS +#define CONF_DMAC_CHANNEL_24_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 24 is running in standby mode or not +// dmac_runstdby_24 +#ifndef CONF_DMAC_RUNSTDBY_24 +#define CONF_DMAC_RUNSTDBY_24 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_24 +#ifndef CONF_DMAC_TRIGACT_24 +#define CONF_DMAC_TRIGACT_24 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_24 +#ifndef CONF_DMAC_TRIGSRC_24 +#define CONF_DMAC_TRIGSRC_24 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_24 +#ifndef CONF_DMAC_LVL_24 +#define CONF_DMAC_LVL_24 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_24 +#ifndef CONF_DMAC_EVOE_24 +#define CONF_DMAC_EVOE_24 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_24 +#ifndef CONF_DMAC_EVIE_24 +#define CONF_DMAC_EVIE_24 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_24 +#ifndef CONF_DMAC_EVACT_24 +#define CONF_DMAC_EVACT_24 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_24 +#ifndef CONF_DMAC_STEPSIZE_24 +#define CONF_DMAC_STEPSIZE_24 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_24 +#ifndef CONF_DMAC_STEPSEL_24 +#define CONF_DMAC_STEPSEL_24 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_24 +#ifndef CONF_DMAC_SRCINC_24 +#define CONF_DMAC_SRCINC_24 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_24 +#ifndef CONF_DMAC_DSTINC_24 +#define CONF_DMAC_DSTINC_24 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_24 +#ifndef CONF_DMAC_BEATSIZE_24 +#define CONF_DMAC_BEATSIZE_24 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_24 +#ifndef CONF_DMAC_BLOCKACT_24 +#define CONF_DMAC_BLOCKACT_24 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_24 +#ifndef CONF_DMAC_EVOSEL_24 +#define CONF_DMAC_EVOSEL_24 0 +#endif +// + +// Channel 25 settings +// dmac_channel_25_settings +#ifndef CONF_DMAC_CHANNEL_25_SETTINGS +#define CONF_DMAC_CHANNEL_25_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 25 is running in standby mode or not +// dmac_runstdby_25 +#ifndef CONF_DMAC_RUNSTDBY_25 +#define CONF_DMAC_RUNSTDBY_25 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_25 +#ifndef CONF_DMAC_TRIGACT_25 +#define CONF_DMAC_TRIGACT_25 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_25 +#ifndef CONF_DMAC_TRIGSRC_25 +#define CONF_DMAC_TRIGSRC_25 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_25 +#ifndef CONF_DMAC_LVL_25 +#define CONF_DMAC_LVL_25 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_25 +#ifndef CONF_DMAC_EVOE_25 +#define CONF_DMAC_EVOE_25 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_25 +#ifndef CONF_DMAC_EVIE_25 +#define CONF_DMAC_EVIE_25 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_25 +#ifndef CONF_DMAC_EVACT_25 +#define CONF_DMAC_EVACT_25 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_25 +#ifndef CONF_DMAC_STEPSIZE_25 +#define CONF_DMAC_STEPSIZE_25 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_25 +#ifndef CONF_DMAC_STEPSEL_25 +#define CONF_DMAC_STEPSEL_25 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_25 +#ifndef CONF_DMAC_SRCINC_25 +#define CONF_DMAC_SRCINC_25 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_25 +#ifndef CONF_DMAC_DSTINC_25 +#define CONF_DMAC_DSTINC_25 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_25 +#ifndef CONF_DMAC_BEATSIZE_25 +#define CONF_DMAC_BEATSIZE_25 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_25 +#ifndef CONF_DMAC_BLOCKACT_25 +#define CONF_DMAC_BLOCKACT_25 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_25 +#ifndef CONF_DMAC_EVOSEL_25 +#define CONF_DMAC_EVOSEL_25 0 +#endif +// + +// Channel 26 settings +// dmac_channel_26_settings +#ifndef CONF_DMAC_CHANNEL_26_SETTINGS +#define CONF_DMAC_CHANNEL_26_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 26 is running in standby mode or not +// dmac_runstdby_26 +#ifndef CONF_DMAC_RUNSTDBY_26 +#define CONF_DMAC_RUNSTDBY_26 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_26 +#ifndef CONF_DMAC_TRIGACT_26 +#define CONF_DMAC_TRIGACT_26 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_26 +#ifndef CONF_DMAC_TRIGSRC_26 +#define CONF_DMAC_TRIGSRC_26 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_26 +#ifndef CONF_DMAC_LVL_26 +#define CONF_DMAC_LVL_26 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_26 +#ifndef CONF_DMAC_EVOE_26 +#define CONF_DMAC_EVOE_26 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_26 +#ifndef CONF_DMAC_EVIE_26 +#define CONF_DMAC_EVIE_26 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_26 +#ifndef CONF_DMAC_EVACT_26 +#define CONF_DMAC_EVACT_26 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_26 +#ifndef CONF_DMAC_STEPSIZE_26 +#define CONF_DMAC_STEPSIZE_26 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_26 +#ifndef CONF_DMAC_STEPSEL_26 +#define CONF_DMAC_STEPSEL_26 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_26 +#ifndef CONF_DMAC_SRCINC_26 +#define CONF_DMAC_SRCINC_26 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_26 +#ifndef CONF_DMAC_DSTINC_26 +#define CONF_DMAC_DSTINC_26 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_26 +#ifndef CONF_DMAC_BEATSIZE_26 +#define CONF_DMAC_BEATSIZE_26 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_26 +#ifndef CONF_DMAC_BLOCKACT_26 +#define CONF_DMAC_BLOCKACT_26 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_26 +#ifndef CONF_DMAC_EVOSEL_26 +#define CONF_DMAC_EVOSEL_26 0 +#endif +// + +// Channel 27 settings +// dmac_channel_27_settings +#ifndef CONF_DMAC_CHANNEL_27_SETTINGS +#define CONF_DMAC_CHANNEL_27_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 27 is running in standby mode or not +// dmac_runstdby_27 +#ifndef CONF_DMAC_RUNSTDBY_27 +#define CONF_DMAC_RUNSTDBY_27 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_27 +#ifndef CONF_DMAC_TRIGACT_27 +#define CONF_DMAC_TRIGACT_27 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_27 +#ifndef CONF_DMAC_TRIGSRC_27 +#define CONF_DMAC_TRIGSRC_27 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_27 +#ifndef CONF_DMAC_LVL_27 +#define CONF_DMAC_LVL_27 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_27 +#ifndef CONF_DMAC_EVOE_27 +#define CONF_DMAC_EVOE_27 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_27 +#ifndef CONF_DMAC_EVIE_27 +#define CONF_DMAC_EVIE_27 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_27 +#ifndef CONF_DMAC_EVACT_27 +#define CONF_DMAC_EVACT_27 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_27 +#ifndef CONF_DMAC_STEPSIZE_27 +#define CONF_DMAC_STEPSIZE_27 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_27 +#ifndef CONF_DMAC_STEPSEL_27 +#define CONF_DMAC_STEPSEL_27 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_27 +#ifndef CONF_DMAC_SRCINC_27 +#define CONF_DMAC_SRCINC_27 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_27 +#ifndef CONF_DMAC_DSTINC_27 +#define CONF_DMAC_DSTINC_27 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_27 +#ifndef CONF_DMAC_BEATSIZE_27 +#define CONF_DMAC_BEATSIZE_27 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_27 +#ifndef CONF_DMAC_BLOCKACT_27 +#define CONF_DMAC_BLOCKACT_27 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_27 +#ifndef CONF_DMAC_EVOSEL_27 +#define CONF_DMAC_EVOSEL_27 0 +#endif +// + +// Channel 28 settings +// dmac_channel_28_settings +#ifndef CONF_DMAC_CHANNEL_28_SETTINGS +#define CONF_DMAC_CHANNEL_28_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 28 is running in standby mode or not +// dmac_runstdby_28 +#ifndef CONF_DMAC_RUNSTDBY_28 +#define CONF_DMAC_RUNSTDBY_28 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_28 +#ifndef CONF_DMAC_TRIGACT_28 +#define CONF_DMAC_TRIGACT_28 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_28 +#ifndef CONF_DMAC_TRIGSRC_28 +#define CONF_DMAC_TRIGSRC_28 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_28 +#ifndef CONF_DMAC_LVL_28 +#define CONF_DMAC_LVL_28 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_28 +#ifndef CONF_DMAC_EVOE_28 +#define CONF_DMAC_EVOE_28 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_28 +#ifndef CONF_DMAC_EVIE_28 +#define CONF_DMAC_EVIE_28 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_28 +#ifndef CONF_DMAC_EVACT_28 +#define CONF_DMAC_EVACT_28 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_28 +#ifndef CONF_DMAC_STEPSIZE_28 +#define CONF_DMAC_STEPSIZE_28 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_28 +#ifndef CONF_DMAC_STEPSEL_28 +#define CONF_DMAC_STEPSEL_28 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_28 +#ifndef CONF_DMAC_SRCINC_28 +#define CONF_DMAC_SRCINC_28 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_28 +#ifndef CONF_DMAC_DSTINC_28 +#define CONF_DMAC_DSTINC_28 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_28 +#ifndef CONF_DMAC_BEATSIZE_28 +#define CONF_DMAC_BEATSIZE_28 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_28 +#ifndef CONF_DMAC_BLOCKACT_28 +#define CONF_DMAC_BLOCKACT_28 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_28 +#ifndef CONF_DMAC_EVOSEL_28 +#define CONF_DMAC_EVOSEL_28 0 +#endif +// + +// Channel 29 settings +// dmac_channel_29_settings +#ifndef CONF_DMAC_CHANNEL_29_SETTINGS +#define CONF_DMAC_CHANNEL_29_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 29 is running in standby mode or not +// dmac_runstdby_29 +#ifndef CONF_DMAC_RUNSTDBY_29 +#define CONF_DMAC_RUNSTDBY_29 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_29 +#ifndef CONF_DMAC_TRIGACT_29 +#define CONF_DMAC_TRIGACT_29 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_29 +#ifndef CONF_DMAC_TRIGSRC_29 +#define CONF_DMAC_TRIGSRC_29 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_29 +#ifndef CONF_DMAC_LVL_29 +#define CONF_DMAC_LVL_29 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_29 +#ifndef CONF_DMAC_EVOE_29 +#define CONF_DMAC_EVOE_29 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_29 +#ifndef CONF_DMAC_EVIE_29 +#define CONF_DMAC_EVIE_29 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_29 +#ifndef CONF_DMAC_EVACT_29 +#define CONF_DMAC_EVACT_29 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_29 +#ifndef CONF_DMAC_STEPSIZE_29 +#define CONF_DMAC_STEPSIZE_29 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_29 +#ifndef CONF_DMAC_STEPSEL_29 +#define CONF_DMAC_STEPSEL_29 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_29 +#ifndef CONF_DMAC_SRCINC_29 +#define CONF_DMAC_SRCINC_29 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_29 +#ifndef CONF_DMAC_DSTINC_29 +#define CONF_DMAC_DSTINC_29 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_29 +#ifndef CONF_DMAC_BEATSIZE_29 +#define CONF_DMAC_BEATSIZE_29 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_29 +#ifndef CONF_DMAC_BLOCKACT_29 +#define CONF_DMAC_BLOCKACT_29 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_29 +#ifndef CONF_DMAC_EVOSEL_29 +#define CONF_DMAC_EVOSEL_29 0 +#endif +// + +// Channel 30 settings +// dmac_channel_30_settings +#ifndef CONF_DMAC_CHANNEL_30_SETTINGS +#define CONF_DMAC_CHANNEL_30_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 30 is running in standby mode or not +// dmac_runstdby_30 +#ifndef CONF_DMAC_RUNSTDBY_30 +#define CONF_DMAC_RUNSTDBY_30 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_30 +#ifndef CONF_DMAC_TRIGACT_30 +#define CONF_DMAC_TRIGACT_30 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_30 +#ifndef CONF_DMAC_TRIGSRC_30 +#define CONF_DMAC_TRIGSRC_30 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_30 +#ifndef CONF_DMAC_LVL_30 +#define CONF_DMAC_LVL_30 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_30 +#ifndef CONF_DMAC_EVOE_30 +#define CONF_DMAC_EVOE_30 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_30 +#ifndef CONF_DMAC_EVIE_30 +#define CONF_DMAC_EVIE_30 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_30 +#ifndef CONF_DMAC_EVACT_30 +#define CONF_DMAC_EVACT_30 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_30 +#ifndef CONF_DMAC_STEPSIZE_30 +#define CONF_DMAC_STEPSIZE_30 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_30 +#ifndef CONF_DMAC_STEPSEL_30 +#define CONF_DMAC_STEPSEL_30 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_30 +#ifndef CONF_DMAC_SRCINC_30 +#define CONF_DMAC_SRCINC_30 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_30 +#ifndef CONF_DMAC_DSTINC_30 +#define CONF_DMAC_DSTINC_30 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_30 +#ifndef CONF_DMAC_BEATSIZE_30 +#define CONF_DMAC_BEATSIZE_30 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_30 +#ifndef CONF_DMAC_BLOCKACT_30 +#define CONF_DMAC_BLOCKACT_30 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_30 +#ifndef CONF_DMAC_EVOSEL_30 +#define CONF_DMAC_EVOSEL_30 0 +#endif +// + +// Channel 31 settings +// dmac_channel_31_settings +#ifndef CONF_DMAC_CHANNEL_31_SETTINGS +#define CONF_DMAC_CHANNEL_31_SETTINGS 0 +#endif + +// Channel Run in Standby +// Indicates whether channel 31 is running in standby mode or not +// dmac_runstdby_31 +#ifndef CONF_DMAC_RUNSTDBY_31 +#define CONF_DMAC_RUNSTDBY_31 0 +#endif + +// Trigger action +// <0=> One trigger required for each block transfer +// <2=> One trigger required for each beat transfer +// <3=> One trigger required for each transaction +// Defines the trigger action used for a transfer +// dmac_trigact_31 +#ifndef CONF_DMAC_TRIGACT_31 +#define CONF_DMAC_TRIGACT_31 0 +#endif + +// Trigger source +// <0x00=> Only software/event triggers +// <0x01=> RTC Time Stamp Trigger +// <0x02=> DSU Debug Communication Channel 0 Trigger +// <0x03=> DSU Debug Communication Channel 1 Trigger +// <0x04=> SERCOM0 RX Trigger +// <0x05=> SERCOM0 TX Trigger +// <0x06=> SERCOM1 RX Trigger +// <0x07=> SERCOM1 TX Trigger +// <0x08=> SERCOM2 RX Trigger +// <0x09=> SERCOM2 TX Trigger +// <0x0A=> SERCOM3 RX Trigger +// <0x0B=> SERCOM3 TX Trigger +// <0x0C=> SERCOM4 RX Trigger +// <0x0D=> SERCOM4 TX Trigger +// <0x0E=> SERCOM5 RX Trigger +// <0x0F=> SERCOM5 TX Trigger +// <0x10=> SERCOM6 RX Trigger +// <0x11=> SERCOM6 TX Trigger +// <0x12=> SERCOM7 RX Trigger +// <0x13=> SERCOM7 TX Trigger +// <0x14=> CAN0 DEBUG Trigger +// <0x15=> CAN1 DEBUG Trigger +// <0x16=> TCC0 Overflow Trigger Trigger +// <0x17=> TCC0 Match/Compare 0 Trigger Trigger +// <0x18=> TCC0 Match/Compare 1 Trigger Trigger +// <0x19=> TCC0 Match/Compare 2 Trigger Trigger +// <0x1A=> TCC0 Match/Compare 3 Trigger Trigger +// <0x1B=> TCC0 Match/Compare 4 Trigger Trigger +// <0x1C=> TCC0 Match/Compare 5 Trigger Trigger +// <0x1D=> TCC1 Overflow Trigger Trigger +// <0x1E=> TCC1 Match/Compare 0 Trigger Trigger +// <0x1F=> TCC1 Match/Compare 1 Trigger Trigger +// <0x20=> TCC1 Match/Compare 2 Trigger Trigger +// <0x21=> TCC1 Match/Compare 3 Trigger Trigger +// <0x22=> TCC2 Overflow Trigger Trigger +// <0x23=> TCC2 Match/Compare 0 Trigger Trigger +// <0x24=> TCC2 Match/Compare 1 Trigger Trigger +// <0x25=> TCC2 Match/Compare 2 Trigger Trigger +// <0x26=> TCC3 Overflow Trigger Trigger +// <0x27=> TCC3 Match/Compare 0 Trigger Trigger +// <0x28=> TCC3 Match/Compare 1 Trigger Trigger +// <0x29=> TCC4 Overflow Trigger Trigger +// <0x2A=> TCC4 Match/Compare 0 Trigger Trigger +// <0x2B=> TCC4 Match/Compare 1 Trigger Trigger +// <0x2C=> TC0 Overflow Trigger +// <0x2D=> TC0 Match/Compare 0 Trigger +// <0x2E=> TC0 Match/Compare 1 Trigger +// <0x2F=> TC1 Overflow Trigger +// <0x30=> TC1 Match/Compare 0 Trigger +// <0x31=> TC1 Match/Compare 1 Trigger +// <0x32=> TC2 Overflow Trigger +// <0x33=> TC2 Match/Compare 0 Trigger +// <0x34=> TC2 Match/Compare 1 Trigger +// <0x35=> TC3 Overflow Trigger +// <0x36=> TC3 Match/Compare 0 Trigger +// <0x37=> TC3 Match/Compare 1 Trigger +// <0x38=> TC4 Overflow Trigger +// <0x39=> TC4 Match/Compare 0 Trigger +// <0x3A=> TC4 Match/Compare 1 Trigger +// <0x3B=> TC5 Overflow Trigger +// <0x3C=> TC5 Match/Compare 0 Trigger +// <0x3D=> TC5 Match/Compare 1 Trigger +// <0x3E=> TC6 Overflow Trigger +// <0x3F=> TC6 Match/Compare 0 Trigger +// <0x40=> TC6 Match/Compare 1 Trigger +// <0x41=> TC7 Overflow Trigger +// <0x42=> TC7 Match/Compare 0 Trigger +// <0x43=> TC7 Match/Compare 1 Trigger +// <0x44=> ADC0 Result Ready Trigger +// <0x45=> ADC0 Sequencing Trigger +// <0x46=> ADC1 Result Ready Trigger +// <0x47=> ADC1 Sequencing Trigger +// <0x48=> DAC Empty 0 Trigger +// <0x49=> DAC Empty 1 Trigger +// <0x4A=> DAC Result Ready 0 Trigger +// <0x4B=> DAC Result Ready 1 Trigger +// <0x4C=> I2S Rx 0 Trigger +// <0x4D=> I2S Rx 1 Trigger +// <0x4E=> I2S Tx 0 Trigger +// <0x4F=> I2S Tx 1 Trigger +// <0x50=> PCC RX Trigger +// <0x51=> AES Write Trigger +// <0x52=> AES Read Trigger +// <0x53=> QSPI Rx Trigger +// <0x54=> QSPI Tx Trigger +// Defines the peripheral trigger which is source of the transfer +// dmac_trifsrc_31 +#ifndef CONF_DMAC_TRIGSRC_31 +#define CONF_DMAC_TRIGSRC_31 0 +#endif + +// Channel Arbitration Level +// <0=> Channel priority 0 +// <1=> Channel priority 1 +// <2=> Channel priority 2 +// <3=> Channel priority 3 +// Defines the arbitration level for this channel +// dmac_lvl_31 +#ifndef CONF_DMAC_LVL_31 +#define CONF_DMAC_LVL_31 0 +#endif + +// Channel Event Output +// Indicates whether channel event generation is enabled or not +// dmac_evoe_31 +#ifndef CONF_DMAC_EVOE_31 +#define CONF_DMAC_EVOE_31 0 +#endif + +// Channel Event Input +// Indicates whether channel event reception is enabled or not +// dmac_evie_31 +#ifndef CONF_DMAC_EVIE_31 +#define CONF_DMAC_EVIE_31 0 +#endif + +// Event Input Action +// <0=> No action +// <1=> Normal transfer and conditional transfer on strobe trigger +// <2=> Conditional transfer trigger +// <3=> Conditional block transfer +// <4=> Channel suspend operation +// <5=> Channel resume operation +// <6=> Skip next block suspend action +// Defines the event input action +// dmac_evact_31 +#ifndef CONF_DMAC_EVACT_31 +#define CONF_DMAC_EVACT_31 0 +#endif + +// Address Increment Step Size +// <0=> Next ADDR = ADDR + (BEATSIZE + 1) * 1 +// <1=> Next ADDR = ADDR + (BEATSIZE + 1) * 2 +// <2=> Next ADDR = ADDR + (BEATSIZE + 1) * 4 +// <3=> Next ADDR = ADDR + (BEATSIZE + 1) * 8 +// <4=> Next ADDR = ADDR + (BEATSIZE + 1) * 16 +// <5=> Next ADDR = ADDR + (BEATSIZE + 1) * 32 +// <6=> Next ADDR = ADDR + (BEATSIZE + 1) * 64 +// <7=> Next ADDR = ADDR + (BEATSIZE + 1) * 128 +// Defines the address increment step size, applies to source or destination address +// dmac_stepsize_31 +#ifndef CONF_DMAC_STEPSIZE_31 +#define CONF_DMAC_STEPSIZE_31 0 +#endif + +// Step Selection +// <0=> Step size settings apply to the destination address +// <1=> Step size settings apply to the source address +// Defines whether source or destination addresses are using the step size settings +// dmac_stepsel_31 +#ifndef CONF_DMAC_STEPSEL_31 +#define CONF_DMAC_STEPSEL_31 0 +#endif + +// Source Address Increment +// Indicates whether the source address incrementation is enabled or not +// dmac_srcinc_31 +#ifndef CONF_DMAC_SRCINC_31 +#define CONF_DMAC_SRCINC_31 0 +#endif + +// Destination Address Increment +// Indicates whether the destination address incrementation is enabled or not +// dmac_dstinc_31 +#ifndef CONF_DMAC_DSTINC_31 +#define CONF_DMAC_DSTINC_31 0 +#endif + +// Beat Size +// <0=> 8-bit bus transfer +// <1=> 16-bit bus transfer +// <2=> 32-bit bus transfer +// Defines the size of one beat +// dmac_beatsize_31 +#ifndef CONF_DMAC_BEATSIZE_31 +#define CONF_DMAC_BEATSIZE_31 0 +#endif + +// Block Action +// <0=> Channel will be disabled if it is the last block transfer in the transaction +// <1=> Channel will be disabled if it is the last block transfer in the transaction and block interrupt +// <2=> Channel suspend operation is complete +// <3=> Both channel suspend operation and block interrupt +// Defines the the DMAC should take after a block transfer has completed +// dmac_blockact_31 +#ifndef CONF_DMAC_BLOCKACT_31 +#define CONF_DMAC_BLOCKACT_31 0 +#endif + +// Event Output Selection +// <0=> Event generation disabled +// <1=> Event strobe when block transfer complete +// <3=> Event strobe when beat transfer complete +// Defines the event output selection +// dmac_evosel_31 +#ifndef CONF_DMAC_EVOSEL_31 +#define CONF_DMAC_EVOSEL_31 0 +#endif +// + +// + +// <<< end of configuration section >>> + +#endif // HPL_DMAC_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_gclk_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_gclk_config.h new file mode 100644 index 00000000000..a0748d0fa80 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_gclk_config.h @@ -0,0 +1,923 @@ +// Circuit Python SAMD51 clock tree: +// DFLL48M (with USBCRM on to sync with external USB ref) -> GCLK1, GCLK5 +// GCLK1 (48MHz) -> 48 MHz peripherals +// GCLK5 (48 MHz divided down to 2 MHz) -> DPLL0, DAC peripherals +// DPLL0 (multiplied up to 120 MHz) -> GCLK0, GCLK4 (output for monitoring) + +// We'd like to use XOSC32K as a ref for DFLL48M on boards with a 32kHz crystal, +// but haven't figured that out yet. + +// Used in hpl/core/hpl_init.c to define which clocks should be initialized first. +// Not clear why all these need to be specified, but it doesn't work properly otherwise. + +//#define CIRCUITPY_GCLK_INIT_1ST (1 << 0 | 1 << 1 | 1 << 3 | 1 <<5) +#define CIRCUITPY_GCLK_INIT_1ST 0xffff + +/* Auto-generated config file hpl_gclk_config.h */ +#ifndef HPL_GCLK_CONFIG_H +#define HPL_GCLK_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Generic clock generator 0 configuration +// Indicates whether generic clock 0 configuration is enabled or not +// enable_gclk_gen_0 +#ifndef CONF_GCLK_GENERATOR_0_CONFIG +#define CONF_GCLK_GENERATOR_0_CONFIG 1 +#endif + +// Generic Clock Generator Control +// Generic clock generator 0 source// External Crystal Oscillator 8-48MHz (XOSC0) +// External Crystal Oscillator 8-48MHz (XOSC1) +// Generic clock generator input pad +// Generic clock generator 1 +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) +// 32kHz External Crystal Oscillator (XOSC32K) +// Digital Frequency Locked Loop (DFLL48M) +// Digital Phase Locked Loop (DPLL0) +// Digital Phase Locked Loop (DPLL1) +// This defines the clock source for generic clock generator 0 +// gclk_gen_0_oscillator +#ifndef CONF_GCLK_GEN_0_SOURCE +#define CONF_GCLK_GEN_0_SOURCE GCLK_GENCTRL_SRC_DPLL0 +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_0_runstdby +#ifndef CONF_GCLK_GEN_0_RUNSTDBY +#define CONF_GCLK_GEN_0_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_0_div_sel +#ifndef CONF_GCLK_GEN_0_DIVSEL +#define CONF_GCLK_GEN_0_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_0_oe +#ifndef CONF_GCLK_GEN_0_OE +#define CONF_GCLK_GEN_0_OE 1 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_0_oov +#ifndef CONF_GCLK_GEN_0_OOV +#define CONF_GCLK_GEN_0_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_0_idc +#ifndef CONF_GCLK_GEN_0_IDC +#define CONF_GCLK_GEN_0_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_0_enable +#ifndef CONF_GCLK_GEN_0_GENEN +#define CONF_GCLK_GEN_0_GENEN 1 +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 0 division <0x0000-0xFFFF> +// gclk_gen_0_div +#ifndef CONF_GCLK_GEN_0_DIV +#define CONF_GCLK_GEN_0_DIV 1 +#endif +// +// + +// Generic clock generator 1 configuration +// Indicates whether generic clock 1 configuration is enabled or not +// enable_gclk_gen_1 +#ifndef CONF_GCLK_GENERATOR_1_CONFIG +#define CONF_GCLK_GENERATOR_1_CONFIG 1 +#endif + +// Generic Clock Generator Control +// Generic clock generator 1 source// External Crystal Oscillator 8-48MHz (XOSC0) +// External Crystal Oscillator 8-48MHz (XOSC1) +// Generic clock generator input pad +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) +// 32kHz External Crystal Oscillator (XOSC32K) +// Digital Frequency Locked Loop (DFLL48M) +// Digital Phase Locked Loop (DPLL0) +// Digital Phase Locked Loop (DPLL1) +// This defines the clock source for generic clock generator 1 +// gclk_gen_1_oscillator +#ifndef CONF_GCLK_GEN_1_SOURCE +#define CONF_GCLK_GEN_1_SOURCE GCLK_GENCTRL_SRC_DFLL +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_1_runstdby +#ifndef CONF_GCLK_GEN_1_RUNSTDBY +#define CONF_GCLK_GEN_1_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_1_div_sel +#ifndef CONF_GCLK_GEN_1_DIVSEL +#define CONF_GCLK_GEN_1_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_1_oe +#ifndef CONF_GCLK_GEN_1_OE +#define CONF_GCLK_GEN_1_OE 1 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_1_oov +#ifndef CONF_GCLK_GEN_1_OOV +#define CONF_GCLK_GEN_1_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_1_idc +#ifndef CONF_GCLK_GEN_1_IDC +#define CONF_GCLK_GEN_1_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_1_enable +#ifndef CONF_GCLK_GEN_1_GENEN +#define CONF_GCLK_GEN_1_GENEN 1 +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 1 division <0x0000-0xFFFF> +// gclk_gen_1_div +#ifndef CONF_GCLK_GEN_1_DIV +#define CONF_GCLK_GEN_1_DIV 1 +#endif +// +// + +// Generic clock generator 2 configuration +// Indicates whether generic clock 2 configuration is enabled or not +// enable_gclk_gen_2 +#ifndef CONF_GCLK_GENERATOR_2_CONFIG +#define CONF_GCLK_GENERATOR_2_CONFIG 1 +#endif + +// Generic Clock Generator Control +// Generic clock generator 2 source// External Crystal Oscillator 8-48MHz (XOSC0) +// External Crystal Oscillator 8-48MHz (XOSC1) +// Generic clock generator input pad +// Generic clock generator 1 +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) +// 32kHz External Crystal Oscillator (XOSC32K) +// Digital Frequency Locked Loop (DFLL48M) +// Digital Phase Locked Loop (DPLL0) +// Digital Phase Locked Loop (DPLL1) +// This defines the clock source for generic clock generator 2 +// gclk_gen_2_oscillator +#ifndef CONF_GCLK_GEN_2_SOURCE +#define CONF_GCLK_GEN_2_SOURCE GCLK_GENCTRL_SRC_OSCULP32K +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_2_runstdby +#ifndef CONF_GCLK_GEN_2_RUNSTDBY +#define CONF_GCLK_GEN_2_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_2_div_sel +#ifndef CONF_GCLK_GEN_2_DIVSEL +#define CONF_GCLK_GEN_2_DIVSEL 1 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_2_oe +#ifndef CONF_GCLK_GEN_2_OE +#define CONF_GCLK_GEN_2_OE 0 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_2_oov +#ifndef CONF_GCLK_GEN_2_OOV +#define CONF_GCLK_GEN_2_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_2_idc +#ifndef CONF_GCLK_GEN_2_IDC +#define CONF_GCLK_GEN_2_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_2_enable +#ifndef CONF_GCLK_GEN_2_GENEN +#define CONF_GCLK_GEN_2_GENEN 1 +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 2 division <0x0000-0xFFFF> +// gclk_gen_2_div +#ifndef CONF_GCLK_GEN_2_DIV +#define CONF_GCLK_GEN_2_DIV 4 +#endif +// +// + +// Generic clock generator 3 configuration +// Indicates whether generic clock 3 configuration is enabled or not +// enable_gclk_gen_3 +#ifndef CONF_GCLK_GENERATOR_3_CONFIG +#define CONF_GCLK_GENERATOR_3_CONFIG 0 +#endif + +// Generic Clock Generator Control +// Generic clock generator 3 source// External Crystal Oscillator 8-48MHz (XOSC0) +// External Crystal Oscillator 8-48MHz (XOSC1) +// Generic clock generator input pad +// Generic clock generator 1 +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) +// 32kHz External Crystal Oscillator (XOSC32K) +// Digital Frequency Locked Loop (DFLL48M) +// Digital Phase Locked Loop (DPLL0) +// Digital Phase Locked Loop (DPLL1) +// This defines the clock source for generic clock generator 3 +// gclk_gen_3_oscillator +#ifndef CONF_GCLK_GEN_3_SOURCE +#define CONF_GCLK_GEN_3_SOURCE GCLK_GENCTRL_SRC_XOSC32K +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_3_runstdby +#ifndef CONF_GCLK_GEN_3_RUNSTDBY +#define CONF_GCLK_GEN_3_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_3_div_sel +#ifndef CONF_GCLK_GEN_3_DIVSEL +#define CONF_GCLK_GEN_3_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_3_oe +#ifndef CONF_GCLK_GEN_3_OE +#define CONF_GCLK_GEN_3_OE 0 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_3_oov +#ifndef CONF_GCLK_GEN_3_OOV +#define CONF_GCLK_GEN_3_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_3_idc +#ifndef CONF_GCLK_GEN_3_IDC +#define CONF_GCLK_GEN_3_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_3_enable +#ifndef CONF_GCLK_GEN_3_GENEN +#define CONF_GCLK_GEN_3_GENEN 0 +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 3 division <0x0000-0xFFFF> +// gclk_gen_3_div +#ifndef CONF_GCLK_GEN_3_DIV +#define CONF_GCLK_GEN_3_DIV 1 +#endif +// +// + +// Generic clock generator 4 configuration +// Indicates whether generic clock 4 configuration is enabled or not +// enable_gclk_gen_4 +#ifndef CONF_GCLK_GENERATOR_4_CONFIG +#define CONF_GCLK_GENERATOR_4_CONFIG 1 +#endif + +// Generic Clock Generator Control +// Generic clock generator 4 source// External Crystal Oscillator 8-48MHz (XOSC0) +// External Crystal Oscillator 8-48MHz (XOSC1) +// Generic clock generator input pad +// Generic clock generator 1 +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) +// 32kHz External Crystal Oscillator (XOSC32K) +// Digital Frequency Locked Loop (DFLL48M) +// Digital Phase Locked Loop (DPLL0) +// Digital Phase Locked Loop (DPLL1) +// This defines the clock source for generic clock generator 4 +// gclk_gen_4_oscillator +#ifndef CONF_GCLK_GEN_4_SOURCE +#define CONF_GCLK_GEN_4_SOURCE GCLK_GENCTRL_SRC_DPLL0 +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_4_runstdby +#ifndef CONF_GCLK_GEN_4_RUNSTDBY +#define CONF_GCLK_GEN_4_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_4_div_sel +#ifndef CONF_GCLK_GEN_4_DIVSEL +#define CONF_GCLK_GEN_4_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_4_oe +#ifndef CONF_GCLK_GEN_4_OE +#define CONF_GCLK_GEN_4_OE 1 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_4_oov +#ifndef CONF_GCLK_GEN_4_OOV +#define CONF_GCLK_GEN_4_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_4_idc +#ifndef CONF_GCLK_GEN_4_IDC +#define CONF_GCLK_GEN_4_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_4_enable +#ifndef CONF_GCLK_GEN_4_GENEN +#define CONF_GCLK_GEN_4_GENEN 1 +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 4 division <0x0000-0xFFFF> +// gclk_gen_4_div +#ifndef CONF_GCLK_GEN_4_DIV +#define CONF_GCLK_GEN_4_DIV 1 +#endif +// +// + +// Generic clock generator 5 configuration +// Indicates whether generic clock 5 configuration is enabled or not +// enable_gclk_gen_5 +#ifndef CONF_GCLK_GENERATOR_5_CONFIG +#define CONF_GCLK_GENERATOR_5_CONFIG 1 +#endif + +// Generic Clock Generator Control +// Generic clock generator 5 source// External Crystal Oscillator 8-48MHz (XOSC0) +// External Crystal Oscillator 8-48MHz (XOSC1) +// Generic clock generator input pad +// Generic clock generator 1 +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) +// 32kHz External Crystal Oscillator (XOSC32K) +// Digital Frequency Locked Loop (DFLL48M) +// Digital Phase Locked Loop (DPLL0) +// Digital Phase Locked Loop (DPLL1) +// This defines the clock source for generic clock generator 5 +// gclk_gen_5_oscillator +#ifndef CONF_GCLK_GEN_5_SOURCE +#define CONF_GCLK_GEN_5_SOURCE GCLK_GENCTRL_SRC_DFLL +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_5_runstdby +#ifndef CONF_GCLK_GEN_5_RUNSTDBY +#define CONF_GCLK_GEN_5_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_5_div_sel +#ifndef CONF_GCLK_GEN_5_DIVSEL +#define CONF_GCLK_GEN_5_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_5_oe +#ifndef CONF_GCLK_GEN_5_OE +#define CONF_GCLK_GEN_5_OE 1 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_5_oov +#ifndef CONF_GCLK_GEN_5_OOV +#define CONF_GCLK_GEN_5_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_5_idc +#ifndef CONF_GCLK_GEN_5_IDC +#define CONF_GCLK_GEN_5_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_5_enable +#ifndef CONF_GCLK_GEN_5_GENEN +#define CONF_GCLK_GEN_5_GENEN 1 +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 5 division <0x0000-0xFFFF> +// gclk_gen_5_div +#ifndef CONF_GCLK_GEN_5_DIV +#define CONF_GCLK_GEN_5_DIV 24 +#endif +// +// + +// Generic clock generator 6 configuration +// Indicates whether generic clock 6 configuration is enabled or not +// enable_gclk_gen_6 +#ifndef CONF_GCLK_GENERATOR_6_CONFIG +#define CONF_GCLK_GENERATOR_6_CONFIG 0 +#endif + +// Generic Clock Generator Control +// Generic clock generator 6 source// External Crystal Oscillator 8-48MHz (XOSC0) +// External Crystal Oscillator 8-48MHz (XOSC1) +// Generic clock generator input pad +// Generic clock generator 1 +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) +// 32kHz External Crystal Oscillator (XOSC32K) +// Digital Frequency Locked Loop (DFLL48M) +// Digital Phase Locked Loop (DPLL0) +// Digital Phase Locked Loop (DPLL1) +// This defines the clock source for generic clock generator 6 +// gclk_gen_6_oscillator +#ifndef CONF_GCLK_GEN_6_SOURCE +#define CONF_GCLK_GEN_6_SOURCE GCLK_GENCTRL_SRC_XOSC1 +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_6_runstdby +#ifndef CONF_GCLK_GEN_6_RUNSTDBY +#define CONF_GCLK_GEN_6_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_6_div_sel +#ifndef CONF_GCLK_GEN_6_DIVSEL +#define CONF_GCLK_GEN_6_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_6_oe +#ifndef CONF_GCLK_GEN_6_OE +#define CONF_GCLK_GEN_6_OE 0 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_6_oov +#ifndef CONF_GCLK_GEN_6_OOV +#define CONF_GCLK_GEN_6_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_6_idc +#ifndef CONF_GCLK_GEN_6_IDC +#define CONF_GCLK_GEN_6_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_6_enable +#ifndef CONF_GCLK_GEN_6_GENEN +#define CONF_GCLK_GEN_6_GENEN 0 +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 6 division <0x0000-0xFFFF> +// gclk_gen_6_div +#ifndef CONF_GCLK_GEN_6_DIV +#define CONF_GCLK_GEN_6_DIV 1 +#endif +// +// + +// Generic clock generator 7 configuration +// Indicates whether generic clock 7 configuration is enabled or not +// enable_gclk_gen_7 +#ifndef CONF_GCLK_GENERATOR_7_CONFIG +#define CONF_GCLK_GENERATOR_7_CONFIG 0 +#endif + +// Generic Clock Generator Control +// Generic clock generator 7 source// External Crystal Oscillator 8-48MHz (XOSC0) +// External Crystal Oscillator 8-48MHz (XOSC1) +// Generic clock generator input pad +// Generic clock generator 1 +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) +// 32kHz External Crystal Oscillator (XOSC32K) +// Digital Frequency Locked Loop (DFLL48M) +// Digital Phase Locked Loop (DPLL0) +// Digital Phase Locked Loop (DPLL1) +// This defines the clock source for generic clock generator 7 +// gclk_gen_7_oscillator +#ifndef CONF_GCLK_GEN_7_SOURCE +#define CONF_GCLK_GEN_7_SOURCE GCLK_GENCTRL_SRC_XOSC1 +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_7_runstdby +#ifndef CONF_GCLK_GEN_7_RUNSTDBY +#define CONF_GCLK_GEN_7_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_7_div_sel +#ifndef CONF_GCLK_GEN_7_DIVSEL +#define CONF_GCLK_GEN_7_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_7_oe +#ifndef CONF_GCLK_GEN_7_OE +#define CONF_GCLK_GEN_7_OE 0 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_7_oov +#ifndef CONF_GCLK_GEN_7_OOV +#define CONF_GCLK_GEN_7_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_7_idc +#ifndef CONF_GCLK_GEN_7_IDC +#define CONF_GCLK_GEN_7_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_7_enable +#ifndef CONF_GCLK_GEN_7_GENEN +#define CONF_GCLK_GEN_7_GENEN 0 +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 7 division <0x0000-0xFFFF> +// gclk_gen_7_div +#ifndef CONF_GCLK_GEN_7_DIV +#define CONF_GCLK_GEN_7_DIV 1 +#endif +// +// + +// Generic clock generator 8 configuration +// Indicates whether generic clock 8 configuration is enabled or not +// enable_gclk_gen_8 +#ifndef CONF_GCLK_GENERATOR_8_CONFIG +#define CONF_GCLK_GENERATOR_8_CONFIG 0 +#endif + +// Generic Clock Generator Control +// Generic clock generator 8 source// External Crystal Oscillator 8-48MHz (XOSC0) +// External Crystal Oscillator 8-48MHz (XOSC1) +// Generic clock generator input pad +// Generic clock generator 1 +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) +// 32kHz External Crystal Oscillator (XOSC32K) +// Digital Frequency Locked Loop (DFLL48M) +// Digital Phase Locked Loop (DPLL0) +// Digital Phase Locked Loop (DPLL1) +// This defines the clock source for generic clock generator 8 +// gclk_gen_8_oscillator +#ifndef CONF_GCLK_GEN_8_SOURCE +#define CONF_GCLK_GEN_8_SOURCE GCLK_GENCTRL_SRC_XOSC1 +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_8_runstdby +#ifndef CONF_GCLK_GEN_8_RUNSTDBY +#define CONF_GCLK_GEN_8_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_8_div_sel +#ifndef CONF_GCLK_GEN_8_DIVSEL +#define CONF_GCLK_GEN_8_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_8_oe +#ifndef CONF_GCLK_GEN_8_OE +#define CONF_GCLK_GEN_8_OE 0 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_8_oov +#ifndef CONF_GCLK_GEN_8_OOV +#define CONF_GCLK_GEN_8_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_8_idc +#ifndef CONF_GCLK_GEN_8_IDC +#define CONF_GCLK_GEN_8_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_8_enable +#ifndef CONF_GCLK_GEN_8_GENEN +#define CONF_GCLK_GEN_8_GENEN 0 +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 8 division <0x0000-0xFFFF> +// gclk_gen_8_div +#ifndef CONF_GCLK_GEN_8_DIV +#define CONF_GCLK_GEN_8_DIV 1 +#endif +// +// + +// Generic clock generator 9 configuration +// Indicates whether generic clock 9 configuration is enabled or not +// enable_gclk_gen_9 +#ifndef CONF_GCLK_GENERATOR_9_CONFIG +#define CONF_GCLK_GENERATOR_9_CONFIG 0 +#endif + +// Generic Clock Generator Control +// Generic clock generator 9 source// External Crystal Oscillator 8-48MHz (XOSC0) +// External Crystal Oscillator 8-48MHz (XOSC1) +// Generic clock generator input pad +// Generic clock generator 1 +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) +// 32kHz External Crystal Oscillator (XOSC32K) +// Digital Frequency Locked Loop (DFLL48M) +// Digital Phase Locked Loop (DPLL0) +// Digital Phase Locked Loop (DPLL1) +// This defines the clock source for generic clock generator 9 +// gclk_gen_9_oscillator +#ifndef CONF_GCLK_GEN_9_SOURCE +#define CONF_GCLK_GEN_9_SOURCE GCLK_GENCTRL_SRC_XOSC1 +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_9_runstdby +#ifndef CONF_GCLK_GEN_9_RUNSTDBY +#define CONF_GCLK_GEN_9_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_9_div_sel +#ifndef CONF_GCLK_GEN_9_DIVSEL +#define CONF_GCLK_GEN_9_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_9_oe +#ifndef CONF_GCLK_GEN_9_OE +#define CONF_GCLK_GEN_9_OE 0 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_9_oov +#ifndef CONF_GCLK_GEN_9_OOV +#define CONF_GCLK_GEN_9_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_9_idc +#ifndef CONF_GCLK_GEN_9_IDC +#define CONF_GCLK_GEN_9_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_9_enable +#ifndef CONF_GCLK_GEN_9_GENEN +#define CONF_GCLK_GEN_9_GENEN 0 +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 9 division <0x0000-0xFFFF> +// gclk_gen_9_div +#ifndef CONF_GCLK_GEN_9_DIV +#define CONF_GCLK_GEN_9_DIV 1 +#endif +// +// + +// Generic clock generator 10 configuration +// Indicates whether generic clock 10 configuration is enabled or not +// enable_gclk_gen_10 +#ifndef CONF_GCLK_GENERATOR_10_CONFIG +#define CONF_GCLK_GENERATOR_10_CONFIG 0 +#endif + +// Generic Clock Generator Control +// Generic clock generator 10 source// External Crystal Oscillator 8-48MHz (XOSC0) +// External Crystal Oscillator 8-48MHz (XOSC1) +// Generic clock generator input pad +// Generic clock generator 1 +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) +// 32kHz External Crystal Oscillator (XOSC32K) +// Digital Frequency Locked Loop (DFLL48M) +// Digital Phase Locked Loop (DPLL0) +// Digital Phase Locked Loop (DPLL1) +// This defines the clock source for generic clock generator 10 +// gclk_gen_10_oscillator +#ifndef CONF_GCLK_GEN_10_SOURCE +#define CONF_GCLK_GEN_10_SOURCE GCLK_GENCTRL_SRC_XOSC1 +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_10_runstdby +#ifndef CONF_GCLK_GEN_10_RUNSTDBY +#define CONF_GCLK_GEN_10_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_10_div_sel +#ifndef CONF_GCLK_GEN_10_DIVSEL +#define CONF_GCLK_GEN_10_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_10_oe +#ifndef CONF_GCLK_GEN_10_OE +#define CONF_GCLK_GEN_10_OE 0 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_10_oov +#ifndef CONF_GCLK_GEN_10_OOV +#define CONF_GCLK_GEN_10_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_10_idc +#ifndef CONF_GCLK_GEN_10_IDC +#define CONF_GCLK_GEN_10_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_10_enable +#ifndef CONF_GCLK_GEN_10_GENEN +#define CONF_GCLK_GEN_10_GENEN 0 +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 10 division <0x0000-0xFFFF> +// gclk_gen_10_div +#ifndef CONF_GCLK_GEN_10_DIV +#define CONF_GCLK_GEN_10_DIV 1 +#endif +// +// + +// Generic clock generator 11 configuration +// Indicates whether generic clock 11 configuration is enabled or not +// enable_gclk_gen_11 +#ifndef CONF_GCLK_GENERATOR_11_CONFIG +#define CONF_GCLK_GENERATOR_11_CONFIG 0 +#endif + +// Generic Clock Generator Control +// Generic clock generator 11 source// External Crystal Oscillator 8-48MHz (XOSC0) +// External Crystal Oscillator 8-48MHz (XOSC1) +// Generic clock generator input pad +// Generic clock generator 1 +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) +// 32kHz External Crystal Oscillator (XOSC32K) +// Digital Frequency Locked Loop (DFLL48M) +// Digital Phase Locked Loop (DPLL0) +// Digital Phase Locked Loop (DPLL1) +// This defines the clock source for generic clock generator 11 +// gclk_gen_11_oscillator +#ifndef CONF_GCLK_GEN_11_SOURCE +#define CONF_GCLK_GEN_11_SOURCE GCLK_GENCTRL_SRC_XOSC1 +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// gclk_arch_gen_11_runstdby +#ifndef CONF_GCLK_GEN_11_RUNSTDBY +#define CONF_GCLK_GEN_11_RUNSTDBY 0 +#endif + +// Divide Selection +// Indicates whether Divide Selection is enabled or not +// gclk_gen_11_div_sel +#ifndef CONF_GCLK_GEN_11_DIVSEL +#define CONF_GCLK_GEN_11_DIVSEL 0 +#endif + +// Output Enable +// Indicates whether Output Enable is enabled or not +// gclk_arch_gen_11_oe +#ifndef CONF_GCLK_GEN_11_OE +#define CONF_GCLK_GEN_11_OE 0 +#endif + +// Output Off Value +// Indicates whether Output Off Value is enabled or not +// gclk_arch_gen_11_oov +#ifndef CONF_GCLK_GEN_11_OOV +#define CONF_GCLK_GEN_11_OOV 0 +#endif + +// Improve Duty Cycle +// Indicates whether Improve Duty Cycle is enabled or not +// gclk_arch_gen_11_idc +#ifndef CONF_GCLK_GEN_11_IDC +#define CONF_GCLK_GEN_11_IDC 0 +#endif + +// Generic Clock Generator Enable +// Indicates whether Generic Clock Generator Enable is enabled or not +// gclk_arch_gen_11_enable +#ifndef CONF_GCLK_GEN_11_GENEN +#define CONF_GCLK_GEN_11_GENEN 0 +#endif +// + +// Generic Clock Generator Division +// Generic clock generator 11 division <0x0000-0xFFFF> +// gclk_gen_11_div +#ifndef CONF_GCLK_GEN_11_DIV +#define CONF_GCLK_GEN_11_DIV 1 +#endif +// +// + +// <<< end of configuration section >>> + +#endif // HPL_GCLK_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_mclk_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_mclk_config.h new file mode 100644 index 00000000000..a5a7de53c25 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_mclk_config.h @@ -0,0 +1,104 @@ +/* Auto-generated config file hpl_mclk_config.h */ +#ifndef HPL_MCLK_CONFIG_H +#define HPL_MCLK_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +#include + +// System Configuration +// Indicates whether configuration for system is enabled or not +// enable_cpu_clock +#ifndef CONF_SYSTEM_CONFIG +#define CONF_SYSTEM_CONFIG 1 +#endif + +// Basic settings +// CPU Clock source +// Generic clock generator 0 +// This defines the clock source for the CPU +// cpu_clock_source +#ifndef CONF_CPU_SRC +#define CONF_CPU_SRC GCLK_PCHCTRL_GEN_GCLK0_Val +#endif + +// CPU Clock Division Factor +// 1 +// 2 +// 4 +// 8 +// 16 +// 32 +// 64 +// 128 +// Prescalar for CPU clock +// cpu_div +#ifndef CONF_MCLK_CPUDIV +#define CONF_MCLK_CPUDIV MCLK_CPUDIV_DIV_DIV1_Val +#endif +// Low Power Clock Division +// Divide by 1 +// Divide by 2 +// Divide by 4 +// Divide by 8 +// Divide by 16 +// Divide by 32 +// Divide by 64 +// Divide by 128 +// mclk_arch_lpdiv +#ifndef CONF_MCLK_LPDIV +#define CONF_MCLK_LPDIV MCLK_LPDIV_LPDIV_DIV4_Val +#endif + +// Backup Clock Division +// Divide by 1 +// Divide by 2 +// Divide by 4 +// Divide by 8 +// Divide by 16 +// Divide by 32 +// Divide by 64 +// Divide by 128 +// mclk_arch_bupdiv +#ifndef CONF_MCLK_BUPDIV +#define CONF_MCLK_BUPDIV MCLK_BUPDIV_BUPDIV_DIV8_Val +#endif +// High-Speed Clock Division +// Divide by 1 +// mclk_arch_hsdiv +#ifndef CONF_MCLK_HSDIV +#define CONF_MCLK_HSDIV MCLK_HSDIV_DIV_DIV1_Val +#endif +// + +// NVM Settings +// NVM Wait States +// These bits select the number of wait states for a read operation. +// <0=> 0 +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 +// <8=> 8 +// <9=> 9 +// <10=> 10 +// <11=> 11 +// <12=> 12 +// <13=> 13 +// <14=> 14 +// <15=> 15 +// nvm_wait_states +#ifndef CONF_NVM_WAIT_STATE +#define CONF_NVM_WAIT_STATE 0 +#endif + +// + +// + +// <<< end of configuration section >>> + +#endif // HPL_MCLK_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_nvmctrl_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_nvmctrl_config.h new file mode 100644 index 00000000000..53fcb593abb --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_nvmctrl_config.h @@ -0,0 +1,36 @@ +/* Auto-generated config file hpl_nvmctrl_config.h */ +#ifndef HPL_NVMCTRL_CONFIG_H +#define HPL_NVMCTRL_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Basic Settings + +// Power Reduction Mode During Sleep +// <0x00=> Wake On Access +// <0x01=> Wake Up Instant +// <0x03=> Disabled +// nvm_arch_sleepprm +#ifndef CONF_NVM_SLEEPPRM +#define CONF_NVM_SLEEPPRM 0 +#endif + +// AHB0 Cache Disable +// Indicate whether AHB0 cache is disable or not +// nvm_arch_cache0 +#ifndef CONF_NVM_CACHE0 +#define CONF_NVM_CACHE0 1 +#endif + +// AHB1 Cache Disable +// Indicate whether AHB1 cache is disable or not +// nvm_arch_cache1 +#ifndef CONF_NVM_CACHE1 +#define CONF_NVM_CACHE1 1 +#endif + +// + +// <<< end of configuration section >>> + +#endif // HPL_NVMCTRL_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_osc32kctrl_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_osc32kctrl_config.h new file mode 100644 index 00000000000..d93cbf922e6 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_osc32kctrl_config.h @@ -0,0 +1,163 @@ +/* Auto-generated config file hpl_osc32kctrl_config.h */ +#ifndef HPL_OSC32KCTRL_CONFIG_H +#define HPL_OSC32KCTRL_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// RTC Source configuration +// enable_rtc_source +#ifndef CONF_RTCCTRL_CONFIG +#define CONF_RTCCTRL_CONFIG 0 +#endif + +// RTC source control +// RTC Clock Source Selection +// 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) +// 32kHz External Crystal Oscillator (XOSC32K) +// This defines the clock source for RTC +// rtc_source_oscillator +#ifndef CONF_RTCCTRL_SRC +#define CONF_RTCCTRL_SRC GCLK_GENCTRL_SRC_OSCULP32K +#endif + +// Use 1 kHz output +// rtc_1khz_selection +#ifndef CONF_RTCCTRL_1KHZ +#define CONF_RTCCTRL_1KHZ 1 +#endif + +#if CONF_RTCCTRL_SRC == GCLK_GENCTRL_SRC_OSCULP32K +#define CONF_RTCCTRL (CONF_RTCCTRL_1KHZ ? OSC32KCTRL_RTCCTRL_RTCSEL_ULP1K_Val : OSC32KCTRL_RTCCTRL_RTCSEL_ULP32K_Val) +#elif CONF_RTCCTRL_SRC == GCLK_GENCTRL_SRC_XOSC32K +#define CONF_RTCCTRL (CONF_RTCCTRL_1KHZ ? OSC32KCTRL_RTCCTRL_RTCSEL_XOSC1K_Val : OSC32KCTRL_RTCCTRL_RTCSEL_XOSC32K_Val) +#else +#error unexpected CONF_RTCCTRL_SRC +#endif + +// +// + +// 32kHz External Crystal Oscillator Configuration +// Indicates whether configuration for External 32K Osc is enabled or not +// enable_xosc32k +#ifndef CONF_XOSC32K_CONFIG +#define CONF_XOSC32K_CONFIG 1 +#endif + +// 32kHz External Crystal Oscillator Control +// Oscillator enable +// Indicates whether 32kHz External Crystal Oscillator is enabled or not +// xosc32k_arch_enable +#ifndef CONF_XOSC32K_ENABLE +#define CONF_XOSC32K_ENABLE 1 +#endif + +// Start-Up Time +// <0x0=>62592us +// <0x1=>125092us +// <0x2=>500092us +// <0x3=>1000092us +// <0x4=>2000092us +// <0x5=>4000092us +// <0x6=>8000092us +// xosc32k_arch_startup +#ifndef CONF_XOSC32K_STARTUP +#define CONF_XOSC32K_STARTUP 0x0 +#endif + +// On Demand Control +// Indicates whether On Demand Control is enabled or not +// xosc32k_arch_ondemand +#ifndef CONF_XOSC32K_ONDEMAND +#define CONF_XOSC32K_ONDEMAND 1 +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// xosc32k_arch_runstdby +#ifndef CONF_XOSC32K_RUNSTDBY +#define CONF_XOSC32K_RUNSTDBY 0 +#endif + +// 1kHz Output Enable +// Indicates whether 1kHz Output is enabled or not +// xosc32k_arch_en1k +#ifndef CONF_XOSC32K_EN1K +#define CONF_XOSC32K_EN1K 0 +#endif + +// 32kHz Output Enable +// Indicates whether 32kHz Output is enabled or not +// xosc32k_arch_en32k +#ifndef CONF_XOSC32K_EN32K +#define CONF_XOSC32K_EN32K 0 +#endif + +// Clock Switch Back +// Indicates whether Clock Switch Back is enabled or not +// xosc32k_arch_swben +#ifndef CONF_XOSC32K_SWBEN +#define CONF_XOSC32K_SWBEN 0 +#endif + +// Clock Failure Detector +// Indicates whether Clock Failure Detector is enabled or not +// xosc32k_arch_cfden +#ifndef CONF_XOSC32K_CFDEN +#define CONF_XOSC32K_CFDEN 0 +#endif + +// Clock Failure Detector Event Out +// Indicates whether Clock Failure Detector Event Out is enabled or not +// xosc32k_arch_cfdeo +#ifndef CONF_XOSC32K_CFDEO +#define CONF_XOSC32K_CFDEO 0 +#endif + +// Crystal connected to XIN32/XOUT32 Enable +// Indicates whether the connections between the I/O pads and the external clock or crystal oscillator is enabled or not +// xosc32k_arch_xtalen +#ifndef CONF_XOSC32K_XTALEN +#define CONF_XOSC32K_XTALEN 0 +#endif + +// Control Gain Mode +// <0x0=>Low Power mode +// <0x1=>Standard mode +// <0x2=>High Speed mode +// xosc32k_arch_cgm +#ifndef CONF_XOSC32K_CGM +#define CONF_XOSC32K_CGM 0x1 +#endif + +// +// + +// 32kHz Ultra Low Power Internal Oscillator Configuration +// Indicates whether configuration for OSCULP32K is enabled or not +// enable_osculp32k +#ifndef CONF_OSCULP32K_CONFIG +#define CONF_OSCULP32K_CONFIG 1 +#endif + +// 32kHz Ultra Low Power Internal Oscillator Control + +// Oscillator Calibration Control +// Indicates whether Oscillator Calibration is enabled or not +// osculp32k_calib_enable +#ifndef CONF_OSCULP32K_CALIB_ENABLE +#define CONF_OSCULP32K_CALIB_ENABLE 0 +#endif + +// Oscillator Calibration <0x0-0x3F> +// osculp32k_calib +#ifndef CONF_OSCULP32K_CALIB +#define CONF_OSCULP32K_CALIB 0x0 +#endif + +// +// + +// <<< end of configuration section >>> + +#endif // HPL_OSC32KCTRL_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_oscctrl_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_oscctrl_config.h new file mode 100644 index 00000000000..cd11866059b --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_oscctrl_config.h @@ -0,0 +1,634 @@ +/* Auto-generated config file hpl_oscctrl_config.h */ +#ifndef HPL_OSCCTRL_CONFIG_H +#define HPL_OSCCTRL_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// External Multipurpose Crystal Oscillator Configuration +// Indicates whether configuration for XOSC0 is enabled or not +// enable_xosc0 +#ifndef CONF_XOSC0_CONFIG +#define CONF_XOSC0_CONFIG 0 +#endif + +// Frequency <8000000-48000000> +// Oscillation frequency of the resonator connected to the External Multipurpose Crystal Oscillator. +// xosc0_frequency +#ifndef CONF_XOSC_FREQUENCY +#define CONF_XOSC0_FREQUENCY 12000000 +#endif + +// External Multipurpose Crystal Oscillator Control +// Oscillator enable +// Indicates whether External Multipurpose Crystal Oscillator is enabled or not +// xosc0_arch_enable +#ifndef CONF_XOSC0_ENABLE +#define CONF_XOSC0_ENABLE 0 +#endif + +// Start-Up Time +// <0x0=>31us +// <0x1=>61us +// <0x2=>122us +// <0x3=>244us +// <0x4=>488us +// <0x5=>977us +// <0x6=>1953us +// <0x7=>3906us +// <0x8=>7813us +// <0x9=>15625us +// <0xA=>31250us +// <0xB=>62500us +// <0xC=>125000us +// <0xD=>250000us +// <0xE=>500000us +// <0xF=>1000000us +// xosc0_arch_startup +#ifndef CONF_XOSC0_STARTUP +#define CONF_XOSC0_STARTUP 0 +#endif + +// Clock Switch Back +// Indicates whether Clock Switch Back is enabled or not +// xosc0_arch_swben +#ifndef CONF_XOSC0_SWBEN +#define CONF_XOSC0_SWBEN 0 +#endif + +// Clock Failure Detector +// Indicates whether Clock Failure Detector is enabled or not +// xosc0_arch_cfden +#ifndef CONF_XOSC0_CFDEN +#define CONF_XOSC0_CFDEN 0 +#endif + +// Automatic Loop Control Enable +// Indicates whether Automatic Loop Control is enabled or not +// xosc0_arch_enalc +#ifndef CONF_XOSC0_ENALC +#define CONF_XOSC0_ENALC 0 +#endif + +// Low Buffer Gain Enable +// Indicates whether Low Buffer Gain is enabled or not +// xosc0_arch_lowbufgain +#ifndef CONF_XOSC0_LOWBUFGAIN +#define CONF_XOSC0_LOWBUFGAIN 0 +#endif + +// On Demand Control +// Indicates whether On Demand Control is enabled or not +// xosc0_arch_ondemand +#ifndef CONF_XOSC0_ONDEMAND +#define CONF_XOSC0_ONDEMAND 0 +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// xosc0_arch_runstdby +#ifndef CONF_XOSC0_RUNSTDBY +#define CONF_XOSC0_RUNSTDBY 0 +#endif + +// Crystal connected to XIN/XOUT Enable +// Indicates whether the connections between the I/O pads and the external clock or crystal oscillator is enabled or not +// xosc0_arch_xtalen +#ifndef CONF_XOSC0_XTALEN +#define CONF_XOSC0_XTALEN 0 +#endif +// +// + +#if CONF_XOSC0_FREQUENCY >= 32000000 +#define CONF_XOSC0_CFDPRESC 0x0 +#define CONF_XOSC0_IMULT 0x7 +#define CONF_XOSC0_IPTAT 0x3 +#elif CONF_XOSC0_FREQUENCY >= 24000000 +#define CONF_XOSC0_CFDPRESC 0x1 +#define CONF_XOSC0_IMULT 0x6 +#define CONF_XOSC0_IPTAT 0x3 +#elif CONF_XOSC0_FREQUENCY >= 16000000 +#define CONF_XOSC0_CFDPRESC 0x2 +#define CONF_XOSC0_IMULT 0x5 +#define CONF_XOSC0_IPTAT 0x3 +#elif CONF_XOSC0_FREQUENCY >= 8000000 +#define CONF_XOSC0_CFDPRESC 0x3 +#define CONF_XOSC0_IMULT 0x4 +#define CONF_XOSC0_IPTAT 0x3 +#endif + +// External Multipurpose Crystal Oscillator Configuration +// Indicates whether configuration for XOSC1 is enabled or not +// enable_xosc1 +#ifndef CONF_XOSC1_CONFIG +#define CONF_XOSC1_CONFIG 0 +#endif + +// Frequency <8000000-48000000> +// Oscillation frequency of the resonator connected to the External Multipurpose Crystal Oscillator. +// xosc1_frequency +#ifndef CONF_XOSC_FREQUENCY +#define CONF_XOSC1_FREQUENCY 12000000 +#endif + +// External Multipurpose Crystal Oscillator Control +// Oscillator enable +// Indicates whether External Multipurpose Crystal Oscillator is enabled or not +// xosc1_arch_enable +#ifndef CONF_XOSC1_ENABLE +#define CONF_XOSC1_ENABLE 0 +#endif + +// Start-Up Time +// <0x0=>31us +// <0x1=>61us +// <0x2=>122us +// <0x3=>244us +// <0x4=>488us +// <0x5=>977us +// <0x6=>1953us +// <0x7=>3906us +// <0x8=>7813us +// <0x9=>15625us +// <0xA=>31250us +// <0xB=>62500us +// <0xC=>125000us +// <0xD=>250000us +// <0xE=>500000us +// <0xF=>1000000us +// xosc1_arch_startup +#ifndef CONF_XOSC1_STARTUP +#define CONF_XOSC1_STARTUP 0 +#endif + +// Clock Switch Back +// Indicates whether Clock Switch Back is enabled or not +// xosc1_arch_swben +#ifndef CONF_XOSC1_SWBEN +#define CONF_XOSC1_SWBEN 0 +#endif + +// Clock Failure Detector +// Indicates whether Clock Failure Detector is enabled or not +// xosc1_arch_cfden +#ifndef CONF_XOSC1_CFDEN +#define CONF_XOSC1_CFDEN 0 +#endif + +// Automatic Loop Control Enable +// Indicates whether Automatic Loop Control is enabled or not +// xosc1_arch_enalc +#ifndef CONF_XOSC1_ENALC +#define CONF_XOSC1_ENALC 0 +#endif + +// Low Buffer Gain Enable +// Indicates whether Low Buffer Gain is enabled or not +// xosc1_arch_lowbufgain +#ifndef CONF_XOSC1_LOWBUFGAIN +#define CONF_XOSC1_LOWBUFGAIN 0 +#endif + +// On Demand Control +// Indicates whether On Demand Control is enabled or not +// xosc1_arch_ondemand +#ifndef CONF_XOSC1_ONDEMAND +#define CONF_XOSC1_ONDEMAND 0 +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// xosc1_arch_runstdby +#ifndef CONF_XOSC1_RUNSTDBY +#define CONF_XOSC1_RUNSTDBY 0 +#endif + +// Crystal connected to XIN/XOUT Enable +// Indicates whether the connections between the I/O pads and the external clock or crystal oscillator is enabled or not +// xosc1_arch_xtalen +#ifndef CONF_XOSC1_XTALEN +#define CONF_XOSC1_XTALEN 0 +#endif +// +// + +#if CONF_XOSC1_FREQUENCY >= 32000000 +#define CONF_XOSC1_CFDPRESC 0x0 +#define CONF_XOSC1_IMULT 0x7 +#define CONF_XOSC1_IPTAT 0x3 +#elif CONF_XOSC1_FREQUENCY >= 24000000 +#define CONF_XOSC1_CFDPRESC 0x1 +#define CONF_XOSC1_IMULT 0x6 +#define CONF_XOSC1_IPTAT 0x3 +#elif CONF_XOSC1_FREQUENCY >= 16000000 +#define CONF_XOSC1_CFDPRESC 0x2 +#define CONF_XOSC1_IMULT 0x5 +#define CONF_XOSC1_IPTAT 0x3 +#elif CONF_XOSC1_FREQUENCY >= 8000000 +#define CONF_XOSC1_CFDPRESC 0x3 +#define CONF_XOSC1_IMULT 0x4 +#define CONF_XOSC1_IPTAT 0x3 +#endif + +// DFLL Configuration +// Indicates whether configuration for DFLL is enabled or not +// enable_dfll +#ifndef CONF_DFLL_CONFIG +#define CONF_DFLL_CONFIG 0 +#endif + +// Reference Clock Source +// Generic clock generator 0 +// Generic clock generator 1 +// Generic clock generator 2 +// Generic clock generator 3 +// Generic clock generator 4 +// Generic clock generator 5 +// Generic clock generator 6 +// Generic clock generator 7 +// Generic clock generator 8 +// Generic clock generator 9 +// Generic clock generator 10 +// Generic clock generator 11 +// Select the clock source +// dfll_ref_clock +#ifndef CONF_DFLL_GCLK +#define CONF_DFLL_GCLK GCLK_PCHCTRL_GEN_GCLK3_Val +#endif + +// Digital Frequency Locked Loop Control +// DFLL Enable +// Indicates whether DFLL is enabled or not +// dfll_arch_enable +#ifndef CONF_DFLL_ENABLE +#define CONF_DFLL_ENABLE 1 +#endif + +// On Demand Control +// Indicates whether On Demand Control is enabled or not +// dfll_arch_ondemand +#ifndef CONF_DFLL_ONDEMAND +#define CONF_DFLL_ONDEMAND 0 +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// dfll_arch_runstdby +#ifndef CONF_DFLL_RUNSTDBY +#define CONF_DFLL_RUNSTDBY 0 +#endif + +// USB Clock Recovery Mode +// Indicates whether USB Clock Recovery Mode is enabled or not +// dfll_arch_usbcrm +#ifndef CONF_DFLL_USBCRM +#define CONF_DFLL_USBCRM 1 +#endif + +// Wait Lock +// Indicates whether Wait Lock is enabled or not +// dfll_arch_waitlock +#ifndef CONF_DFLL_WAITLOCK +#define CONF_DFLL_WAITLOCK 1 +#endif + +// Bypass Coarse Lock +// Indicates whether Bypass Coarse Lock is enabled or not +// dfll_arch_bplckc +#ifndef CONF_DFLL_BPLCKC +#define CONF_DFLL_BPLCKC 0 +#endif + +// Quick Lock Disable +// Indicates whether Quick Lock Disable is enabled or not +// dfll_arch_qldis +#ifndef CONF_DFLL_QLDIS +#define CONF_DFLL_QLDIS 0 +#endif + +// Chill Cycle Disable +// Indicates whether Chill Cycle Disable is enabled or not +// dfll_arch_ccdis +#ifndef CONF_DFLL_CCDIS +#define CONF_DFLL_CCDIS 1 +#endif + +// Lose Lock After Wake +// Indicates whether Lose Lock After Wake is enabled or not +// dfll_arch_llaw +#ifndef CONF_DFLL_LLAW +#define CONF_DFLL_LLAW 0 +#endif + +// Stable DFLL Frequency +// Indicates whether Stable DFLL Frequency is enabled or not +// dfll_arch_stable +#ifndef CONF_DFLL_STABLE +#define CONF_DFLL_STABLE 0 +#endif + +// Operating Mode Selection +// <0=>Open Loop Mode +// <1=>Closed Loop Mode +// dfll_mode +#ifndef CONF_DFLL_MODE +#define CONF_DFLL_MODE 0x0 +#endif + +// Coarse Maximum Step <0x0-0x1F> +// dfll_arch_cstep +#ifndef CONF_DFLL_CSTEP +#define CONF_DFLL_CSTEP 0x1 +#endif + +// Fine Maximum Step <0x0-0xFF> +// dfll_arch_fstep +#ifndef CONF_DFLL_FSTEP +#define CONF_DFLL_FSTEP 0x1 +#endif + +// DFLL Multiply Factor <0x0-0xFFFF> +// dfll_mul +#ifndef CONF_DFLL_MUL +#define CONF_DFLL_MUL 0x0 +#endif + +// DFLL Calibration Overwrite +// Indicates whether Overwrite Calibration value of DFLL +// dfll_arch_calibration +#ifndef CONF_DFLL_OVERWRITE_CALIBRATION +#define CONF_DFLL_OVERWRITE_CALIBRATION 0 +#endif + +// Coarse Value <0x0-0x3F> +// dfll_arch_coarse +#ifndef CONF_DFLL_COARSE +#define CONF_DFLL_COARSE (0x1f / 4) +#endif + +// Fine Value <0x0-0xFF> +// dfll_arch_fine +#ifndef CONF_DFLL_FINE +#define CONF_DFLL_FINE (0x80) +#endif + +// + +// + +// + +// FDPLL0 Configuration +// Indicates whether configuration for FDPLL0 is enabled or not +// enable_fdpll0 +#ifndef CONF_FDPLL0_CONFIG +#define CONF_FDPLL0_CONFIG 1 +#endif + +// Reference Clock Source +// 32kHz External Crystal Oscillator (XOSC32K) +// External Crystal Oscillator 8-48MHz (XOSC0) +// External Crystal Oscillator 8-48MHz (XOSC1) +// Generic clock generator 0 +// Generic clock generator 1 +// Generic clock generator 2 +// Generic clock generator 3 +// Generic clock generator 4 +// Generic clock generator 5 +// Generic clock generator 6 +// Generic clock generator 7 +// Generic clock generator 8 +// Generic clock generator 9 +// Generic clock generator 10 +// Generic clock generator 11 +// Select the clock source. +// fdpll0_ref_clock +#ifndef CONF_FDPLL0_GCLK +#define CONF_FDPLL0_GCLK GCLK_PCHCTRL_GEN_GCLK5_Val +#endif + +// Digital Phase Locked Loop Control +// Enable +// Indicates whether Digital Phase Locked Loop is enabled or not +// fdpll0_arch_enable +#ifndef CONF_FDPLL0_ENABLE +#define CONF_FDPLL0_ENABLE 1 +#endif + +// On Demand Control +// Indicates whether On Demand Control is enabled or not +// fdpll0_arch_ondemand +#ifndef CONF_FDPLL0_ONDEMAND +#define CONF_FDPLL0_ONDEMAND 0 +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// fdpll0_arch_runstdby +#ifndef CONF_FDPLL0_RUNSTDBY +#define CONF_FDPLL0_RUNSTDBY 0 +#endif + +// Loop Divider Ratio Fractional Part <0x0-0x1F> +// fdpll0_ldrfrac +#ifndef CONF_FDPLL0_LDRFRAC +#define CONF_FDPLL0_LDRFRAC 0x0 +#endif + +// Loop Divider Ratio Integer Part <0x0-0x1FFF> +// fdpll0_ldr +#ifndef CONF_FDPLL0_LDR +#define CONF_FDPLL0_LDR 59 +#endif + +// Clock Divider <0x0-0x7FF> +// fdpll0_clock_div +#ifndef CONF_FDPLL0_DIV +#define CONF_FDPLL0_DIV 0x0 +#endif + +// DCO Filter Enable +// Indicates whether DCO Filter Enable is enabled or not +// fdpll0_arch_dcoen +#ifndef CONF_FDPLL0_DCOEN +#define CONF_FDPLL0_DCOEN 0 +#endif + +// Sigma-Delta DCO Filter Selection <0x0-0x7> +// fdpll0_clock_dcofilter +#ifndef CONF_FDPLL0_DCOFILTER +#define CONF_FDPLL0_DCOFILTER 0x0 +#endif + +// Lock Bypass +// Indicates whether Lock Bypass is enabled or not +// fdpll0_arch_lbypass +#ifndef CONF_FDPLL0_LBYPASS +#define CONF_FDPLL0_LBYPASS 0 +#endif + +// Lock Time +// <0x0=>No time-out, automatic lock +// <0x4=>The Time-out if no lock within 800 us +// <0x5=>The Time-out if no lock within 900 us +// <0x6=>The Time-out if no lock within 1 ms +// <0x7=>The Time-out if no lock within 11 ms +// fdpll0_arch_ltime +#ifndef CONF_FDPLL0_LTIME +#define CONF_FDPLL0_LTIME 0x0 +#endif + +// Reference Clock Selection +// <0x0=>GCLK clock reference +// <0x1=>XOSC32K clock reference +// <0x2=>XOSC0 clock reference +// <0x3=>XOSC1 clock reference +// fdpll0_arch_refclk +#ifndef CONF_FDPLL0_REFCLK +#define CONF_FDPLL0_REFCLK 0x0 +#endif + +// Wake Up Fast +// Indicates whether Wake Up Fast is enabled or not +// fdpll0_arch_wuf +#ifndef CONF_FDPLL0_WUF +#define CONF_FDPLL0_WUF 0 +#endif + +// Proportional Integral Filter Selection <0x0-0xF> +// fdpll0_arch_filter +#ifndef CONF_FDPLL0_FILTER +#define CONF_FDPLL0_FILTER 0x0 +#endif + +// +// +// FDPLL1 Configuration +// Indicates whether configuration for FDPLL1 is enabled or not +// enable_fdpll1 +#ifndef CONF_FDPLL1_CONFIG +#define CONF_FDPLL1_CONFIG 0 +#endif + +// Reference Clock Source +// 32kHz External Crystal Oscillator (XOSC32K) +// External Crystal Oscillator 8-48MHz (XOSC0) +// External Crystal Oscillator 8-48MHz (XOSC1) +// Generic clock generator 0 +// Generic clock generator 1 +// Generic clock generator 2 +// Generic clock generator 3 +// Generic clock generator 4 +// Generic clock generator 5 +// Generic clock generator 6 +// Generic clock generator 7 +// Generic clock generator 8 +// Generic clock generator 9 +// Generic clock generator 10 +// Generic clock generator 11 +// Select the clock source. +// fdpll1_ref_clock +#ifndef CONF_FDPLL1_GCLK +#define CONF_FDPLL1_GCLK GCLK_GENCTRL_SRC_XOSC32K +#endif + +// Digital Phase Locked Loop Control +// Enable +// Indicates whether Digital Phase Locked Loop is enabled or not +// fdpll1_arch_enable +#ifndef CONF_FDPLL1_ENABLE +#define CONF_FDPLL1_ENABLE 0 +#endif + +// On Demand Control +// Indicates whether On Demand Control is enabled or not +// fdpll1_arch_ondemand +#ifndef CONF_FDPLL1_ONDEMAND +#define CONF_FDPLL1_ONDEMAND 0 +#endif + +// Run in Standby +// Indicates whether Run in Standby is enabled or not +// fdpll1_arch_runstdby +#ifndef CONF_FDPLL1_RUNSTDBY +#define CONF_FDPLL1_RUNSTDBY 0 +#endif + +// Loop Divider Ratio Fractional Part <0x0-0x1F> +// fdpll1_ldrfrac +#ifndef CONF_FDPLL1_LDRFRAC +#define CONF_FDPLL1_LDRFRAC 0xd +#endif + +// Loop Divider Ratio Integer Part <0x0-0x1FFF> +// fdpll1_ldr +#ifndef CONF_FDPLL1_LDR +#define CONF_FDPLL1_LDR 0x5b7 +#endif + +// Clock Divider <0x0-0x7FF> +// fdpll1_clock_div +#ifndef CONF_FDPLL1_DIV +#define CONF_FDPLL1_DIV 0x0 +#endif + +// DCO Filter Enable +// Indicates whether DCO Filter Enable is enabled or not +// fdpll1_arch_dcoen +#ifndef CONF_FDPLL1_DCOEN +#define CONF_FDPLL1_DCOEN 0 +#endif + +// Sigma-Delta DCO Filter Selection <0x0-0x7> +// fdpll1_clock_dcofilter +#ifndef CONF_FDPLL1_DCOFILTER +#define CONF_FDPLL1_DCOFILTER 0x0 +#endif + +// Lock Bypass +// Indicates whether Lock Bypass is enabled or not +// fdpll1_arch_lbypass +#ifndef CONF_FDPLL1_LBYPASS +#define CONF_FDPLL1_LBYPASS 0 +#endif + +// Lock Time +// <0x0=>No time-out, automatic lock +// <0x4=>The Time-out if no lock within 800 us +// <0x5=>The Time-out if no lock within 900 us +// <0x6=>The Time-out if no lock within 1 ms +// <0x7=>The Time-out if no lock within 11 ms +// fdpll1_arch_ltime +#ifndef CONF_FDPLL1_LTIME +#define CONF_FDPLL1_LTIME 0x0 +#endif + +// Reference Clock Selection +// <0x0=>GCLK clock reference +// <0x1=>XOSC32K clock reference +// <0x2=>XOSC0 clock reference +// <0x3=>XOSC1 clock reference +// fdpll1_arch_refclk +#ifndef CONF_FDPLL1_REFCLK +#define CONF_FDPLL1_REFCLK 0x1 +#endif + +// Wake Up Fast +// Indicates whether Wake Up Fast is enabled or not +// fdpll1_arch_wuf +#ifndef CONF_FDPLL1_WUF +#define CONF_FDPLL1_WUF 0 +#endif + +// Proportional Integral Filter Selection <0x0-0xF> +// fdpll1_arch_filter +#ifndef CONF_FDPLL1_FILTER +#define CONF_FDPLL1_FILTER 0x0 +#endif + +// +// + +// <<< end of configuration section >>> + +#endif // HPL_OSCCTRL_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_rtc_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_rtc_config.h new file mode 100644 index 00000000000..2b0b6712e63 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_rtc_config.h @@ -0,0 +1,145 @@ +/* Auto-generated config file hpl_rtc_config.h */ +#ifndef HPL_RTC_CONFIG_H +#define HPL_RTC_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Basic settings + +#ifndef CONF_RTC_ENABLE +#define CONF_RTC_ENABLE 1 +#endif + +// Force reset RTC on initialization +// Force RTC to reset on initialization. +// Note that the previous power down data in RTC is lost if it's enabled. +// rtc_arch_init_reset +#ifndef CONF_RTC_INIT_RESET +#define CONF_RTC_INIT_RESET 0 +#endif + +// Prescaler configuration +// <0x0=>OFF(Peripheral clock divided by 1) +// <0x1=>Peripheral clock divided by 1 +// <0x2=>Peripheral clock divided by 2 +// <0x3=>Peripheral clock divided by 4 +// <0x4=>Peripheral clock divided by 8 +// <0x5=>Peripheral clock divided by 16 +// <0x6=>Peripheral clock divided by 32 +// <0x7=>Peripheral clock divided by 64 +// <0x8=>Peripheral clock divided by 128 +// <0x9=>Peripheral clock divided by 256 +// <0xA=>Peripheral clock divided by 512 +// <0xB=>Peripheral clock divided by 1024 +// These bits define the RTC clock relative to the peripheral clock +// rtc_arch_prescaler +#ifndef CONF_RTC_PRESCALER +#define CONF_RTC_PRESCALER 0xb + +#endif + +// Compare Value <1-4294967295> +// These bits define the RTC Compare value, the ticks period is equal to reciprocal of (rtc clock/prescaler/compare value), +// by default 1K clock input, 1 prescaler, 1 compare value, the ticks period equals to 1ms. +// rtc_arch_comp_val + +#ifndef CONF_RTC_COMP_VAL +#define CONF_RTC_COMP_VAL 1 + +#endif + +// Event control +// rtc_event_control +#ifndef CONF_RTC_EVENT_CONTROL_ENABLE +#define CONF_RTC_EVENT_CONTROL_ENABLE 0 +#endif + +// Periodic Interval 0 Event Output +// This bit indicates whether Periodic interval 0 event is enabled and will be generated +// rtc_pereo0 +#ifndef CONF_RTC_PEREO0 +#define CONF_RTC_PEREO0 0 +#endif +// Periodic Interval 1 Event Output +// This bit indicates whether Periodic interval 1 event is enabled and will be generated +// rtc_pereo1 +#ifndef CONF_RTC_PEREO1 +#define CONF_RTC_PEREO1 0 +#endif +// Periodic Interval 2 Event Output +// This bit indicates whether Periodic interval 2 event is enabled and will be generated +// rtc_pereo2 +#ifndef CONF_RTC_PEREO2 +#define CONF_RTC_PEREO2 0 +#endif +// Periodic Interval 3 Event Output +// This bit indicates whether Periodic interval 3 event is enabled and will be generated +// rtc_pereo3 +#ifndef CONF_RTC_PEREO3 +#define CONF_RTC_PEREO3 0 +#endif +// Periodic Interval 4 Event Output +// This bit indicates whether Periodic interval 4 event is enabled and will be generated +// rtc_pereo4 +#ifndef CONF_RTC_PEREO4 +#define CONF_RTC_PEREO4 0 +#endif +// Periodic Interval 5 Event Output +// This bit indicates whether Periodic interval 5 event is enabled and will be generated +// rtc_pereo5 +#ifndef CONF_RTC_PEREO5 +#define CONF_RTC_PEREO5 0 +#endif +// Periodic Interval 6 Event Output +// This bit indicates whether Periodic interval 6 event is enabled and will be generated +// rtc_pereo6 +#ifndef CONF_RTC_PEREO6 +#define CONF_RTC_PEREO6 0 +#endif +// Periodic Interval 7 Event Output +// This bit indicates whether Periodic interval 7 event is enabled and will be generated +// rtc_pereo7 +#ifndef CONF_RTC_PEREO7 +#define CONF_RTC_PEREO7 0 +#endif + +// Compare 0 Event Output +// This bit indicates whether Compare O event is enabled and will be generated +// rtc_cmpeo0 +#ifndef CONF_RTC_COMPE0 +#define CONF_RTC_COMPE0 0 +#endif + +// Compare 1 Event Output +// This bit indicates whether Compare 1 event is enabled and will be generated +// rtc_cmpeo1 +#ifndef CONF_RTC_COMPE1 +#define CONF_RTC_COMPE1 0 +#endif +// Overflow Event Output +// This bit indicates whether Overflow event is enabled and will be generated +// rtc_ovfeo +#ifndef CONF_RTC_OVFEO +#define CONF_RTC_OVFEO 0 +#endif + +// Tamper Event Output +// This bit indicates whether Tamper event output is enabled and will be generated +// rtc_tampereo +#ifndef CONF_RTC_TAMPEREO +#define CONF_RTC_TAMPEREO 0 +#endif + +// Tamper Event Input +// This bit indicates whether Tamper event input is enabled and will be generated +// rtc_tampevei +#ifndef CONF_RTC_TAMPEVEI +#define CONF_RTC_TAMPEVEI 0 +#endif +// + +// + +// <<< end of configuration section >>> + +#endif // HPL_RTC_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_sercom_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_sercom_config.h new file mode 100644 index 00000000000..cd411154c76 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_sercom_config.h @@ -0,0 +1,751 @@ +// For CircuitPython, use SERCOM settings as prototypes to set +// the default settings. This file defines these SERCOMs +// +// SERCOM0: SPI with hal_spi_m_sync.c driver: spi master synchronous +// SERCOM1: I2C with hal_i2c_m_sync.c driver: i2c master synchronous +// SERCOM2: USART with hal_usart_async.c driver: usart asynchronous +// SERCOM3: SPI with hal_spi_m_dma.c: spi master DMA + +#define PROTOTYPE_SERCOM_SPI_M_SYNC SERCOM0 +#define PROTOTYPE_SERCOM_SPI_M_SYNC_CLOCK_FREQUENCY CONF_GCLK_SERCOM0_CORE_FREQUENCY + +#define PROTOTYPE_SERCOM_I2CM_SYNC SERCOM1 + +#define PROTOTYPE_SERCOM_USART_ASYNC SERCOM2 +#define PROTOTYPE_SERCOM_USART_ASYNC_CLOCK_FREQUENCY CONF_GCLK_SERCOM2_CORE_FREQUENCY + +/* Auto-generated config file hpl_sercom_config.h */ +#ifndef HPL_SERCOM_CONFIG_H +#define HPL_SERCOM_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +#include + +// Enable configuration of module +#ifndef CONF_SERCOM_0_SPI_ENABLE +#define CONF_SERCOM_0_SPI_ENABLE 1 +#endif + +// Set module in SPI Master mode +#ifndef CONF_SERCOM_0_SPI_MODE +#define CONF_SERCOM_0_SPI_MODE 0x03 +#endif + +// Basic Configuration + +// Receive buffer enable +// Enable receive buffer to receive data from slave (RXEN) +// spi_master_rx_enable +#ifndef CONF_SERCOM_0_SPI_RXEN +#define CONF_SERCOM_0_SPI_RXEN 0x1 +#endif + +// Character Size +// Bit size for all characters sent over the SPI bus (CHSIZE) +// <0x0=>8 bits +// <0x1=>9 bits +// spi_master_character_size +#ifndef CONF_SERCOM_0_SPI_CHSIZE +#define CONF_SERCOM_0_SPI_CHSIZE 0x0 +#endif + +// Baud rate <1-12000000> +// The SPI data transfer rate +// spi_master_baud_rate +#ifndef CONF_SERCOM_0_SPI_BAUD +#define CONF_SERCOM_0_SPI_BAUD 50000 +#endif + +// + +// Advanced Configuration +// spi_master_advanced +#ifndef CONF_SERCOM_0_SPI_ADVANCED +#define CONF_SERCOM_0_SPI_ADVANCED 1 +#endif + +// Dummy byte <0x00-0x1ff> +// spi_master_dummybyte +// Dummy byte used when reading data from the slave without sending any data +#ifndef CONF_SERCOM_0_SPI_DUMMYBYTE +#define CONF_SERCOM_0_SPI_DUMMYBYTE 0x1ff +#endif + +// Data Order +// <0=>MSB first +// <1=>LSB first +// I least significant or most significant bit is shifted out first (DORD) +// spi_master_arch_dord +#ifndef CONF_SERCOM_0_SPI_DORD +#define CONF_SERCOM_0_SPI_DORD 0x0 +#endif + +// Clock Polarity +// <0=>SCK is low when idle +// <1=>SCK is high when idle +// Determines if the leading edge is rising or falling with a corresponding opposite edge at the trailing edge. (CPOL) +// spi_master_arch_cpol +#ifndef CONF_SERCOM_0_SPI_CPOL +#define CONF_SERCOM_0_SPI_CPOL 0x0 +#endif + +// Clock Phase +// <0x0=>Sample input on leading edge +// <0x1=>Sample input on trailing edge +// Determines if input data is sampled on leading or trailing SCK edge. (CPHA) +// spi_master_arch_cpha +#ifndef CONF_SERCOM_0_SPI_CPHA +#define CONF_SERCOM_0_SPI_CPHA 0x0 +#endif + +// Immediate Buffer Overflow Notification +// Controls when OVF is asserted (IBON) +// <0x0=>In data stream +// <0x1=>On buffer overflow +// spi_master_arch_ibon +#ifndef CONF_SERCOM_0_SPI_IBON +#define CONF_SERCOM_0_SPI_IBON 0x0 +#endif + +// Run in stand-by +// Module stays active in stand-by sleep mode. (RUNSTDBY) +// spi_master_arch_runstdby +#ifndef CONF_SERCOM_0_SPI_RUNSTDBY +#define CONF_SERCOM_0_SPI_RUNSTDBY 0x0 +#endif + +// Debug Stop Mode +// Behavior of the baud-rate generator when CPU is halted by external debugger. (DBGSTOP) +// <0=>Keep running +// <1=>Halt +// spi_master_arch_dbgstop +#ifndef CONF_SERCOM_0_SPI_DBGSTOP +#define CONF_SERCOM_0_SPI_DBGSTOP 0 +#endif + +// + +// Address mode disabled in master mode +#ifndef CONF_SERCOM_0_SPI_AMODE_EN +#define CONF_SERCOM_0_SPI_AMODE_EN 0 +#endif + +#ifndef CONF_SERCOM_0_SPI_AMODE +#define CONF_SERCOM_0_SPI_AMODE 0 +#endif + +#ifndef CONF_SERCOM_0_SPI_ADDR +#define CONF_SERCOM_0_SPI_ADDR 0 +#endif + +#ifndef CONF_SERCOM_0_SPI_ADDRMASK +#define CONF_SERCOM_0_SPI_ADDRMASK 0 +#endif + +#ifndef CONF_SERCOM_0_SPI_SSDE +#define CONF_SERCOM_0_SPI_SSDE 0 +#endif + +#ifndef CONF_SERCOM_0_SPI_MSSEN +#define CONF_SERCOM_0_SPI_MSSEN 0x0 +#endif + +#ifndef CONF_SERCOM_0_SPI_PLOADEN +#define CONF_SERCOM_0_SPI_PLOADEN 0 +#endif + +// Receive Data Pinout +// <0x0=>PAD[0] +// <0x1=>PAD[1] +// <0x2=>PAD[2] +// <0x3=>PAD[3] +// spi_master_rxpo +#ifndef CONF_SERCOM_0_SPI_RXPO +#define CONF_SERCOM_0_SPI_RXPO 2 +#endif + +// Transmit Data Pinout +// <0x0=>PAD[0,1]_DO_SCK +// <0x1=>PAD[2,3]_DO_SCK +// <0x2=>PAD[3,1]_DO_SCK +// <0x3=>PAD[0,3]_DO_SCK +// spi_master_txpo +#ifndef CONF_SERCOM_0_SPI_TXPO +#define CONF_SERCOM_0_SPI_TXPO 0 +#endif + +// Calculate baud register value from requested baudrate value +#ifndef CONF_SERCOM_0_SPI_BAUD_RATE +#define CONF_SERCOM_0_SPI_BAUD_RATE ((float)CONF_GCLK_SERCOM0_CORE_FREQUENCY / (float)(2 * CONF_SERCOM_0_SPI_BAUD)) - 1 +#endif + +#include + +#ifndef SERCOM_I2CM_CTRLA_MODE_I2C_MASTER +#define SERCOM_I2CM_CTRLA_MODE_I2C_MASTER (5 << 2) +#endif + +#ifndef CONF_SERCOM_1_I2CM_ENABLE +#define CONF_SERCOM_1_I2CM_ENABLE 1 +#endif + +// Basic + +// I2C Bus clock speed (Hz) <1-400000> +// I2C Bus clock (SCL) speed measured in Hz +// i2c_master_baud_rate +#ifndef CONF_SERCOM_1_I2CM_BAUD +#define CONF_SERCOM_1_I2CM_BAUD 100000 +#endif + +// + +// Advanced +// i2c_master_advanced +#ifndef CONF_SERCOM_1_I2CM_ADVANCED_CONFIG +#define CONF_SERCOM_1_I2CM_ADVANCED_CONFIG 1 +#endif + +// TRise (ns) <0-300> +// Determined by the bus impedance, check electric characteristics in the datasheet +// Standard Fast Mode: typical 215ns, max 300ns +// Fast Mode +: typical 60ns, max 100ns +// High Speed Mode: typical 20ns, max 40ns +// i2c_master_arch_trise + +#ifndef CONF_SERCOM_1_I2CM_TRISE +#define CONF_SERCOM_1_I2CM_TRISE 215 +#endif + +// Master SCL Low Extended Time-Out (MEXTTOEN) +// This enables the master SCL low extend time-out +// i2c_master_arch_mexttoen +#ifndef CONF_SERCOM_1_I2CM_MEXTTOEN +#define CONF_SERCOM_1_I2CM_MEXTTOEN 0 +#endif + +// Slave SCL Low Extend Time-Out (SEXTTOEN) +// Enables the slave SCL low extend time-out. If SCL is cumulatively held low for greater than 25ms from the initial START to a STOP, the slave will release its clock hold if enabled and reset the internal state machine +// i2c_master_arch_sexttoen +#ifndef CONF_SERCOM_1_I2CM_SEXTTOEN +#define CONF_SERCOM_1_I2CM_SEXTTOEN 0 +#endif + +// SCL Low Time-Out (LOWTOUT) +// Enables SCL low time-out. If SCL is held low for 25ms-35ms, the master will release it's clock hold +// i2c_master_arch_lowtout +#ifndef CONF_SERCOM_1_I2CM_LOWTOUT +#define CONF_SERCOM_1_I2CM_LOWTOUT 0 +#endif + +// Inactive Time-Out (INACTOUT) +// <0x0=>Disabled +// <0x1=>5-6 SCL cycle time-out(50-60us) +// <0x2=>10-11 SCL cycle time-out(100-110us) +// <0x3=>20-21 SCL cycle time-out(200-210us) +// Defines if inactivity time-out should be enabled, and how long the time-out should be +// i2c_master_arch_inactout +#ifndef CONF_SERCOM_1_I2CM_INACTOUT +#define CONF_SERCOM_1_I2CM_INACTOUT 0x0 +#endif + +// SDA Hold Time (SDAHOLD) +// <0=>Disabled +// <1=>50-100ns hold time +// <2=>300-600ns hold time +// <3=>400-800ns hold time +// Defines the SDA hold time with respect to the negative edge of SCL +// i2c_master_arch_sdahold +#ifndef CONF_SERCOM_1_I2CM_SDAHOLD +#define CONF_SERCOM_1_I2CM_SDAHOLD 0x2 +#endif + +// Run in stand-by +// Determine if the module shall run in standby sleep mode +// i2c_master_arch_runstdby +#ifndef CONF_SERCOM_1_I2CM_RUNSTDBY +#define CONF_SERCOM_1_I2CM_RUNSTDBY 0 +#endif + +// Debug Stop Mode +// Behavior of the baud-rate generator when CPU is halted by external debugger. +// <0=>Keep running +// <1=>Halt +// i2c_master_arch_dbgstop +#ifndef CONF_SERCOM_1_I2CM_DEBUG_STOP_MODE +#define CONF_SERCOM_1_I2CM_DEBUG_STOP_MODE 0 +#endif + +// + +#ifndef CONF_SERCOM_1_I2CM_SPEED +#define CONF_SERCOM_1_I2CM_SPEED 0x00 // Speed: Standard/Fast mode +#endif +#if CONF_SERCOM_1_I2CM_TRISE < 215 || CONF_SERCOM_1_I2CM_TRISE > 300 +#warning Bad I2C Rise time for Standard/Fast mode, reset to 215ns +#undef CONF_SERCOM_1_I2CM_TRISE +#define CONF_SERCOM_1_I2CM_TRISE 215 +#endif + +// gclk_freq - (i2c_scl_freq * 10) - (gclk_freq * i2c_scl_freq * Trise) +// BAUD + BAUDLOW = -------------------------------------------------------------------- +// i2c_scl_freq +// BAUD: register value low [7:0] +// BAUDLOW: register value high [15:8], only used for odd BAUD + BAUDLOW +#define CONF_SERCOM_1_I2CM_BAUD_BAUDLOW \ + (((CONF_GCLK_SERCOM1_CORE_FREQUENCY - (CONF_SERCOM_1_I2CM_BAUD * 10) \ + - (CONF_SERCOM_1_I2CM_TRISE * (CONF_SERCOM_1_I2CM_BAUD / 100) * (CONF_GCLK_SERCOM1_CORE_FREQUENCY / 10000) \ + / 1000)) \ + * 10 \ + + 5) \ + / (CONF_SERCOM_1_I2CM_BAUD * 10)) +#ifndef CONF_SERCOM_1_I2CM_BAUD_RATE +#if CONF_SERCOM_1_I2CM_BAUD_BAUDLOW > (0xFF * 2) +#warning Requested I2C baudrate too low, please check +#define CONF_SERCOM_1_I2CM_BAUD_RATE 0xFF +#elif CONF_SERCOM_1_I2CM_BAUD_BAUDLOW <= 1 +#warning Requested I2C baudrate too high, please check +#define CONF_SERCOM_1_I2CM_BAUD_RATE 1 +#else +#define CONF_SERCOM_1_I2CM_BAUD_RATE \ + ((CONF_SERCOM_1_I2CM_BAUD_BAUDLOW & 0x1) \ + ? (CONF_SERCOM_1_I2CM_BAUD_BAUDLOW / 2) + ((CONF_SERCOM_1_I2CM_BAUD_BAUDLOW / 2 + 1) << 8) \ + : (CONF_SERCOM_1_I2CM_BAUD_BAUDLOW / 2)) +#endif +#endif + +#include + +#ifndef CONF_SERCOM_2_USART_ENABLE +#define CONF_SERCOM_2_USART_ENABLE 1 +#endif + +// Basic Configuration + +// Receive buffer enable +// Enable input buffer in SERCOM module +// usart_rx_enable +#ifndef CONF_SERCOM_2_USART_RXEN +#define CONF_SERCOM_2_USART_RXEN 1 +#endif + +// Transmitt buffer enable +// Enable output buffer in SERCOM module +// usart_tx_enable +#ifndef CONF_SERCOM_2_USART_TXEN +#define CONF_SERCOM_2_USART_TXEN 1 +#endif + +// Frame parity +// <0x0=>No parity +// <0x1=>Even parity +// <0x2=>Odd parity +// Parity bit mode for USART frame +// usart_parity +#ifndef CONF_SERCOM_2_USART_PARITY +#define CONF_SERCOM_2_USART_PARITY 0x0 +#endif + +// Character Size +// <0x0=>8 bits +// <0x1=>9 bits +// <0x5=>5 bits +// <0x6=>6 bits +// <0x7=>7 bits +// Data character size in USART frame +// usart_character_size +#ifndef CONF_SERCOM_2_USART_CHSIZE +#define CONF_SERCOM_2_USART_CHSIZE 0x0 +#endif + +// Stop Bit +// <0=>One stop bit +// <1=>Two stop bits +// Number of stop bits in USART frame +// usart_stop_bit +#ifndef CONF_SERCOM_2_USART_SBMODE +#define CONF_SERCOM_2_USART_SBMODE 0 +#endif + +// Baud rate <1-3000000> +// USART baud rate setting +// usart_baud_rate +#ifndef CONF_SERCOM_2_USART_BAUD +#define CONF_SERCOM_2_USART_BAUD 9600 +#endif + +// + +// Advanced configuration +// usart_advanced +#ifndef CONF_SERCOM_2_USART_ADVANCED_CONFIG +#define CONF_SERCOM_2_USART_ADVANCED_CONFIG 1 +#endif + +// Run in stand-by +// Keep the module running in standby sleep mode +// usart_arch_runstdby +#ifndef CONF_SERCOM_2_USART_RUNSTDBY +#define CONF_SERCOM_2_USART_RUNSTDBY 0 +#endif + +// Immediate Buffer Overflow Notification +// Controls when the BUFOVF status bit is asserted +// usart_arch_ibon +#ifndef CONF_SERCOM_2_USART_IBON +#define CONF_SERCOM_2_USART_IBON 0 +#endif + +// Start of Frame Detection Enable +// Will wake the device from any sleep mode if usart_init and usart_enable was run priort to going to sleep. (receive buffer must be enabled) +// usart_arch_sfde +#ifndef CONF_SERCOM_2_USART_SFDE +#define CONF_SERCOM_2_USART_SFDE 0 +#endif + +// Collision Detection Enable +// Collision detection enable +// usart_arch_cloden +#ifndef CONF_SERCOM_2_USART_CLODEN +#define CONF_SERCOM_2_USART_CLODEN 0 +#endif + +// Operating Mode +// <0x0=>USART with external clock +// <0x1=>USART with internal clock +// Drive the shift register by an internal clock generated by the baud rate generator or an external clock supplied on the XCK pin. +// usart_arch_clock_mode +#ifndef CONF_SERCOM_2_USART_MODE +#define CONF_SERCOM_2_USART_MODE 0x1 +#endif + +// Sample Rate +// <0x0=>16x arithmetic +// <0x1=>16x fractional +// <0x2=>8x arithmetic +// <0x3=>8x fractional +// <0x3=>3x +// How many over-sampling bits used when samling data state +// usart_arch_sampr +#ifndef CONF_SERCOM_2_USART_SAMPR +#define CONF_SERCOM_2_USART_SAMPR 0x0 +#endif + +// Sample Adjustment +// <0x0=>7-8-9 (3-4-5 8-bit over-sampling) +// <0x1=>9-10-11 (4-5-6 8-bit over-sampling) +// <0x2=>11-12-13 (5-6-7 8-bit over-sampling) +// <0x3=>13-14-15 (6-7-8 8-bit over-sampling) +// Adjust which samples to use for data sampling in asynchronous mode +// usart_arch_sampa +#ifndef CONF_SERCOM_2_USART_SAMPA +#define CONF_SERCOM_2_USART_SAMPA 0x0 +#endif + +// Fractional Part <0-7> +// Fractional part of the baud rate if baud rate generator is in fractional mode +// usart_arch_fractional +#ifndef CONF_SERCOM_2_USART_FRACTIONAL +#define CONF_SERCOM_2_USART_FRACTIONAL 0x0 +#endif + +// Data Order +// <0=>MSB is transmitted first +// <1=>LSB is transmitted first +// Data order of the data bits in the frame +// usart_arch_dord +#ifndef CONF_SERCOM_2_USART_DORD +#define CONF_SERCOM_2_USART_DORD 1 +#endif + +// Does not do anything in UART mode +#define CONF_SERCOM_2_USART_CPOL 0 + +// Encoding Format +// <0=>No encoding +// <1=>IrDA encoded +// usart_arch_enc +#ifndef CONF_SERCOM_2_USART_ENC +#define CONF_SERCOM_2_USART_ENC 0 +#endif + +// Debug Stop Mode +// Behavior of the baud-rate generator when CPU is halted by external debugger. +// <0=>Keep running +// <1=>Halt +// usart_arch_dbgstop +#ifndef CONF_SERCOM_2_USART_DEBUG_STOP_MODE +#define CONF_SERCOM_2_USART_DEBUG_STOP_MODE 0 +#endif + +// + +#ifndef CONF_SERCOM_2_USART_INACK +#define CONF_SERCOM_2_USART_INACK 0x0 +#endif + +#ifndef CONF_SERCOM_2_USART_DSNACK +#define CONF_SERCOM_2_USART_DSNACK 0x0 +#endif + +#ifndef CONF_SERCOM_2_USART_MAXITER +#define CONF_SERCOM_2_USART_MAXITER 0x7 +#endif + +#ifndef CONF_SERCOM_2_USART_GTIME +#define CONF_SERCOM_2_USART_GTIME 0x2 +#endif + +#define CONF_SERCOM_2_USART_RXINV 0x0 +#define CONF_SERCOM_2_USART_TXINV 0x0 + +#ifndef CONF_SERCOM_2_USART_CMODE +#define CONF_SERCOM_2_USART_CMODE 0 +#endif + +#ifndef CONF_SERCOM_2_USART_RXPO +#define CONF_SERCOM_2_USART_RXPO 1 /* RX is on PIN_PA08 */ +#endif + +#ifndef CONF_SERCOM_2_USART_TXPO +#define CONF_SERCOM_2_USART_TXPO 0 /* TX is on PIN_PA09 */ +#endif + +/* Set correct parity settings in register interface based on PARITY setting */ +#if CONF_SERCOM_2_USART_PARITY == 0 +#define CONF_SERCOM_2_USART_PMODE 0 +#define CONF_SERCOM_2_USART_FORM 0 +#else +#define CONF_SERCOM_2_USART_PMODE CONF_SERCOM_2_USART_PARITY - 1 +#define CONF_SERCOM_2_USART_FORM 1 +#endif + +// Calculate BAUD register value in UART mode +#if CONF_SERCOM_2_USART_SAMPR == 0 +#ifndef CONF_SERCOM_2_USART_BAUD_RATE +#define CONF_SERCOM_2_USART_BAUD_RATE \ + 65536 - ((65536 * 16.0f * CONF_SERCOM_2_USART_BAUD) / CONF_GCLK_SERCOM2_CORE_FREQUENCY) +#endif +#ifndef CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH +#define CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH 0 +#endif +#elif CONF_SERCOM_2_USART_SAMPR == 1 +#ifndef CONF_SERCOM_2_USART_BAUD_RATE +#define CONF_SERCOM_2_USART_BAUD_RATE \ + ((CONF_GCLK_SERCOM2_CORE_FREQUENCY) / (CONF_SERCOM_2_USART_BAUD * 16)) - (CONF_SERCOM_2_USART_FRACTIONAL / 8) +#endif +#ifndef CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH +#define CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH 0 +#endif +#elif CONF_SERCOM_2_USART_SAMPR == 2 +#ifndef CONF_SERCOM_2_USART_BAUD_RATE +#define CONF_SERCOM_2_USART_BAUD_RATE \ + 65536 - ((65536 * 8.0f * CONF_SERCOM_2_USART_BAUD) / CONF_GCLK_SERCOM2_CORE_FREQUENCY) +#endif +#ifndef CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH +#define CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH 0 +#endif +#elif CONF_SERCOM_2_USART_SAMPR == 3 +#ifndef CONF_SERCOM_2_USART_BAUD_RATE +#define CONF_SERCOM_2_USART_BAUD_RATE \ + ((CONF_GCLK_SERCOM2_CORE_FREQUENCY) / (CONF_SERCOM_2_USART_BAUD * 8)) - (CONF_SERCOM_2_USART_FRACTIONAL / 8) +#endif +#ifndef CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH +#define CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH 0 +#endif +#elif CONF_SERCOM_2_USART_SAMPR == 4 +#ifndef CONF_SERCOM_2_USART_BAUD_RATE +#define CONF_SERCOM_2_USART_BAUD_RATE \ + 65536 - ((65536 * 3.0f * CONF_SERCOM_2_USART_BAUD) / CONF_GCLK_SERCOM2_CORE_FREQUENCY) +#endif +#ifndef CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH +#define CONF_SERCOM_2_USART_RECEIVE_PULSE_LENGTH 0 +#endif +#endif + +#include + +// Enable configuration of module +#ifndef CONF_SERCOM_3_SPI_ENABLE +#define CONF_SERCOM_3_SPI_ENABLE 1 +#endif + +// SPI DMA TX Channel <0-32> +// This defines DMA channel to be used +// spi_master_dma_tx_channel +#ifndef CONF_SERCOM_3_SPI_M_DMA_TX_CHANNEL +#define CONF_SERCOM_3_SPI_M_DMA_TX_CHANNEL 0 +#endif + +// SPI RX Channel Enable +// spi_master_rx_channel +#ifndef CONF_SERCOM_3_SPI_RX_CHANNEL +#define CONF_SERCOM_3_SPI_RX_CHANNEL 1 +#endif + +// DMA Channel <0-32> +// This defines DMA channel to be used +// spi_master_dma_rx_channel +#ifndef CONF_SERCOM_3_SPI_M_DMA_RX_CHANNEL +#define CONF_SERCOM_3_SPI_M_DMA_RX_CHANNEL 1 +#endif + +// + +// Set module in SPI Master mode +#ifndef CONF_SERCOM_3_SPI_MODE +#define CONF_SERCOM_3_SPI_MODE 0x03 +#endif + +// Basic Configuration + +// Receive buffer enable +// Enable receive buffer to receive data from slave (RXEN) +// spi_master_rx_enable +#ifndef CONF_SERCOM_3_SPI_RXEN +#define CONF_SERCOM_3_SPI_RXEN 0x1 +#endif + +// Character Size +// Bit size for all characters sent over the SPI bus (CHSIZE) +// <0x0=>8 bits +// <0x1=>9 bits +// spi_master_character_size +#ifndef CONF_SERCOM_3_SPI_CHSIZE +#define CONF_SERCOM_3_SPI_CHSIZE 0x0 +#endif + +// Baud rate <1-12000000> +// The SPI data transfer rate +// spi_master_baud_rate +#ifndef CONF_SERCOM_3_SPI_BAUD +#define CONF_SERCOM_3_SPI_BAUD 50000 +#endif + +// + +// Advanced Configuration +// spi_master_advanced +#ifndef CONF_SERCOM_3_SPI_ADVANCED +#define CONF_SERCOM_3_SPI_ADVANCED 0 +#endif + +// Dummy byte <0x00-0x1ff> +// spi_master_dummybyte +// Dummy byte used when reading data from the slave without sending any data +#ifndef CONF_SERCOM_3_SPI_DUMMYBYTE +#define CONF_SERCOM_3_SPI_DUMMYBYTE 0x1ff +#endif + +// Data Order +// <0=>MSB first +// <1=>LSB first +// I least significant or most significant bit is shifted out first (DORD) +// spi_master_arch_dord +#ifndef CONF_SERCOM_3_SPI_DORD +#define CONF_SERCOM_3_SPI_DORD 0x0 +#endif + +// Clock Polarity +// <0=>SCK is low when idle +// <1=>SCK is high when idle +// Determines if the leading edge is rising or falling with a corresponding opposite edge at the trailing edge. (CPOL) +// spi_master_arch_cpol +#ifndef CONF_SERCOM_3_SPI_CPOL +#define CONF_SERCOM_3_SPI_CPOL 0x0 +#endif + +// Clock Phase +// <0x0=>Sample input on leading edge +// <0x1=>Sample input on trailing edge +// Determines if input data is sampled on leading or trailing SCK edge. (CPHA) +// spi_master_arch_cpha +#ifndef CONF_SERCOM_3_SPI_CPHA +#define CONF_SERCOM_3_SPI_CPHA 0x0 +#endif + +// Immediate Buffer Overflow Notification +// Controls when OVF is asserted (IBON) +// <0x0=>In data stream +// <0x1=>On buffer overflow +// spi_master_arch_ibon +#ifndef CONF_SERCOM_3_SPI_IBON +#define CONF_SERCOM_3_SPI_IBON 0x0 +#endif + +// Run in stand-by +// Module stays active in stand-by sleep mode. (RUNSTDBY) +// spi_master_arch_runstdby +#ifndef CONF_SERCOM_3_SPI_RUNSTDBY +#define CONF_SERCOM_3_SPI_RUNSTDBY 0x0 +#endif + +// Debug Stop Mode +// Behavior of the baud-rate generator when CPU is halted by external debugger. (DBGSTOP) +// <0=>Keep running +// <1=>Halt +// spi_master_arch_dbgstop +#ifndef CONF_SERCOM_3_SPI_DBGSTOP +#define CONF_SERCOM_3_SPI_DBGSTOP 0 +#endif + +// + +// Address mode disabled in master mode +#ifndef CONF_SERCOM_3_SPI_AMODE_EN +#define CONF_SERCOM_3_SPI_AMODE_EN 0 +#endif + +#ifndef CONF_SERCOM_3_SPI_AMODE +#define CONF_SERCOM_3_SPI_AMODE 0 +#endif + +#ifndef CONF_SERCOM_3_SPI_ADDR +#define CONF_SERCOM_3_SPI_ADDR 0 +#endif + +#ifndef CONF_SERCOM_3_SPI_ADDRMASK +#define CONF_SERCOM_3_SPI_ADDRMASK 0 +#endif + +#ifndef CONF_SERCOM_3_SPI_SSDE +#define CONF_SERCOM_3_SPI_SSDE 0 +#endif + +#ifndef CONF_SERCOM_3_SPI_MSSEN +#define CONF_SERCOM_3_SPI_MSSEN 0x0 +#endif + +#ifndef CONF_SERCOM_3_SPI_PLOADEN +#define CONF_SERCOM_3_SPI_PLOADEN 0 +#endif + +// Receive Data Pinout +// <0x0=>PAD[0] +// <0x1=>PAD[1] +// <0x2=>PAD[2] +// <0x3=>PAD[3] +// spi_master_rxpo +#ifndef CONF_SERCOM_3_SPI_RXPO +#define CONF_SERCOM_3_SPI_RXPO 2 +#endif + +// Transmit Data Pinout +// <0x0=>PAD[0,1]_DO_SCK +// <0x1=>PAD[2,3]_DO_SCK +// <0x2=>PAD[3,1]_DO_SCK +// <0x3=>PAD[0,3]_DO_SCK +// spi_master_txpo +#ifndef CONF_SERCOM_3_SPI_TXPO +#define CONF_SERCOM_3_SPI_TXPO 0 +#endif + +// Calculate baud register value from requested baudrate value +#ifndef CONF_SERCOM_3_SPI_BAUD_RATE +#define CONF_SERCOM_3_SPI_BAUD_RATE ((float)CONF_GCLK_SERCOM3_CORE_FREQUENCY / (float)(2 * CONF_SERCOM_3_SPI_BAUD)) - 1 +#endif + +// <<< end of configuration section >>> + +#endif // HPL_SERCOM_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_systick_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_systick_config.h new file mode 100644 index 00000000000..a7f2f36208f --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_systick_config.h @@ -0,0 +1,18 @@ +/* Auto-generated config file hpl_systick_config.h */ +#ifndef HPL_SYSTICK_CONFIG_H +#define HPL_SYSTICK_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Advanced settings +// SysTick exception request +// Indicates whether the generation of SysTick exception is enabled or not +// systick_arch_tickint +#ifndef CONF_SYSTICK_TICKINT +#define CONF_SYSTICK_TICKINT 0 +#endif +// + +// <<< end of configuration section >>> + +#endif // HPL_SYSTICK_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_tc_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_tc_config.h new file mode 100644 index 00000000000..38d48e9b67c --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_tc_config.h @@ -0,0 +1,209 @@ +/* Auto-generated config file hpl_tc_config.h */ +#ifndef HPL_TC_CONFIG_H +#define HPL_TC_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +#include + +#ifndef CONF_TC0_ENABLE +#define CONF_TC0_ENABLE 1 +#endif + +// Basic settings +// Prescaler +// <0=> No division +// <1=> Divide by 2 +// <2=> Divide by 4 +// <3=> Divide by 8 +// <4=> Divide by 16 +// <5=> Divide by 64 +// <6=> Divide by 256 +// <7=> Divide by 1024 +// This defines the prescaler value +// tc_prescaler +#ifndef CONF_TC0_PRESCALER +#define CONF_TC0_PRESCALER 0 +#endif +// + +// PWM Waveform Output settings +// Waveform Period Value (uS) <0x00-0xFFFFFFFF> +// The unit of this value is us. +// tc_arch_wave_per_val +#ifndef CONF_TC0_WAVE_PER_VAL +#define CONF_TC0_WAVE_PER_VAL 0x3e8 +#endif + +// Waveform Duty Value (0.1%) <0x00-0x03E8> +// The unit of this value is 1/1000. +// tc_arch_wave_duty_val +#ifndef CONF_TC0_WAVE_DUTY_VAL +#define CONF_TC0_WAVE_DUTY_VAL 0x1f4 +#endif + +/* Caculate pwm ccx register value based on WAVE_PER_VAL and Waveform Duty Value */ +#if CONF_TC0_PRESCALER < TC_CTRLA_PRESCALER_DIV64_Val +#define CONF_TC0_CC0 \ + ((uint32_t)(((double)CONF_TC0_WAVE_PER_VAL * CONF_GCLK_TC0_FREQUENCY) / 1000000 / (1 << CONF_TC0_PRESCALER) - 1)) +#define CONF_TC0_CC1 ((CONF_TC0_CC0 * CONF_TC0_WAVE_DUTY_VAL) / 1000) + +#elif CONF_TC0_PRESCALER == TC_CTRLA_PRESCALER_DIV64_Val +#define CONF_TC0_CC0 ((uint32_t)(((double)CONF_TC0_WAVE_PER_VAL * CONF_GCLK_TC0_FREQUENCY) / 64000000 - 1)) +#define CONF_TC0_CC1 ((CONF_TC0_CC0 * CONF_TC0_WAVE_DUTY_VAL) / 1000) + +#elif CONF_TC0_PRESCALER == TC_CTRLA_PRESCALER_DIV256_Val +#define CONF_TC0_CC0 ((uint32_t)(((double)CONF_TC0_WAVE_PER_VAL * CONF_GCLK_TC0_FREQUENCY) / 256000000 - 1)) +#define CONF_TC0_CC1 ((CONF_TC0_CC0 * CONF_TC0_WAVE_DUTY_VAL) / 1000) + +#elif CONF_TC0_PRESCALER == TC_CTRLA_PRESCALER_DIV1024_Val +#define CONF_TC0_CC0 ((uint32_t)(((double)CONF_TC0_WAVE_PER_VAL * CONF_GCLK_TC0_FREQUENCY) / 1024000000 - 1)) +#define CONF_TC0_CC1 ((CONF_TC0_CC0 * CONF_TC0_WAVE_DUTY_VAL) / 1000) +#endif + +// + +// Advanced settings +// Mode +// Counter in 16-bit mode +// Counter in 32-bit mode +// These bits mode +// tc_mode +#ifndef CONF_TC0_MODE +#define CONF_TC0_MODE TC_CTRLA_MODE_COUNT16_Val +#endif + +// Period Value <0x00000000-0xFFFFFFFF> +// tc_per +#ifndef CONF_TC0_PER +#define CONF_TC0_PER 0x32 +#endif +// + +// Advanced settings +// Prescaler and Counter Synchronization Selection +// Reload or reset counter on next GCLK +// Reload or reset counter on next prescaler clock +// Reload or reset counter on next GCLK and reset prescaler counter +// These bits select if on retrigger event, the Counter should be cleared or reloaded on the next GCLK_TCx clock or on the next prescaled GCLK_TCx clock. +// tc_arch_presync +#ifndef CONF_TC0_PRESCSYNC +#define CONF_TC0_PRESCSYNC TC_CTRLA_PRESCSYNC_GCLK_Val +#endif + +// Run in standby +// Indicates whether the will continue running in standby sleep mode or not +// tc_arch_runstdby +#ifndef CONF_TC0_RUNSTDBY +#define CONF_TC0_RUNSTDBY 0 +#endif + +// On-Demand +// Indicates whether the TC0's on-demand mode is on or not +// tc_arch_ondemand +#ifndef CONF_TC0_ONDEMAND +#define CONF_TC0_ONDEMAND 0 +#endif + +// Auto Lock +// <0x0=>The Lock Update bit is not affected on overflow/underflow and re-trigger event +// <0x1=>The Lock Update bit is set on each overflow/underflow or re-trigger event +// tc_arch_alock +#ifndef CONF_TC0_ALOCK +#define CONF_TC0_ALOCK 0 +#endif + +/* Commented intentionally. Timer uses fixed value. May be used by other abstractions based on TC. */ +//#define CONF_TC0_CAPTEN0 0 +//#define CONF_TC0_CAPTEN1 0 +//#define CONF_TC0_COPEN0 0 +//#define CONF_TC0_COPEN1 0 + +/* Commented intentionally. Timer uses fixed value. May be used by other abstractions based on TC. */ +//#define CONF_TC0_DIR 0 +//#define CONF_TC0_ONESHOT 0 +//#define CONF_TC0_LUPD 0 + +// Debug Running Mode +// Indicates whether the Debug Running Mode is enabled or not +// tc_arch_dbgrun +#ifndef CONF_TC0_DBGRUN +#define CONF_TC0_DBGRUN 0 +#endif + +// Event control +// timer_event_control +#ifndef CONF_TC0_EVENT_CONTROL_ENABLE +#define CONF_TC0_EVENT_CONTROL_ENABLE 0 +#endif + +// Output Event On Match or Capture on Channel 0 +// Enable output of event on timer tick +// tc_arch_mceo0 +#ifndef CONF_TC0_MCEO0 +#define CONF_TC0_MCEO0 0 +#endif + +// Output Event On Match or Capture on Channel 1 +// Enable output of event on timer tick +// tc_arch_mceo1 +#ifndef CONF_TC0_MCEO1 +#define CONF_TC0_MCEO1 0 +#endif + +// Output Event On Timer Tick +// Enable output of event on timer tick +// tc_arch_ovfeo +#ifndef CONF_TC0_OVFEO +#define CONF_TC0_OVFEO 0 +#endif + +// Event Input +// Enable asynchronous input events +// tc_arch_tcei +#ifndef CONF_TC0_TCEI +#define CONF_TC0_TCEI 0 +#endif + +// Inverted Event Input +// Invert the asynchronous input events +// tc_arch_tcinv +#ifndef CONF_TC0_TCINV +#define CONF_TC0_TCINV 0 +#endif + +// Event action +// <0=> Event action disabled +// <1=> Start, restart or re-trigger TC on event +// <2=> Count on event +// <3=> Start on event +// <4=> Time stamp capture +// <5=> Period captured in CC0, pulse width in CC1 +// <6=> Period captured in CC1, pulse width in CC0 +// <7=> Pulse width capture +// Event which will be performed on an event +// tc_arch_evact +#ifndef CONF_TC0_EVACT +#define CONF_TC0_EVACT 0 +#endif +// + +/* Commented intentionally. Timer uses fixed value. May be used by other abstractions based on TC. */ +//#define CONF_TC0_WAVEGEN TC_CTRLA_WAVEGEN_MFRQ_Val + +/* Commented intentionally. Timer uses fixed value. May be used by other abstractions based on TC. */ +//#define CONF_TC0_INVEN0 0 +//#define CONF_TC0_INVEN1 0 + +/* Commented intentionally. Timer uses fixed value. May be used by other abstractions based on TC. */ +//#define CONF_TC0_PERBUF 0 + +/* Commented intentionally. Timer uses fixed value. May be used by other abstractions based on TC. */ +//#define CONF_TC0_CCBUF0 0 +//#define CONF_TC0_CCBUF1 0 + +// + +// <<< end of configuration section >>> + +#endif // HPL_TC_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_trng_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_trng_config.h new file mode 100644 index 00000000000..ba9014989a9 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_trng_config.h @@ -0,0 +1,27 @@ +/* Auto-generated config file hpl_trng_config.h */ +#ifndef HPL_TRNG_CONFIG_H +#define HPL_TRNG_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Advanced configurations + +// Run In Standby +// Indicates whether the TRNG works in standby mode +// trng_runstdby +#ifndef CONF_TRNG_RUNSTDBY +#define CONF_TRNG_RUNSTDBY 0 +#endif + +// Data Ready Event Output Enable +// Indicates whether the TRNG generates event on Data Ready +// trng_datardyeo +#ifndef CONF_TRNG_DATARDYEO +#define CONF_TRNG_DATARDYEO 0 +#endif + +// + +// <<< end of configuration section >>> + +#endif // HPL_TRNG_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_usb_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_usb_config.h new file mode 100644 index 00000000000..d1bb42fe451 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_usb_config.h @@ -0,0 +1,413 @@ +/* Auto-generated config file hpl_usb_config.h */ +#ifndef HPL_USB_CONFIG_H +#define HPL_USB_CONFIG_H + +// CIRCUITPY: + +// Use 64-byte USB buffers for endpoint directions that are in use. They're set to 0 below otherwise. + +#include "genhdr/autogen_usb_descriptor.h" + +#if defined(USB_ENDPOINT_1_OUT_USED) && USB_ENDPOINT_1_OUT_USED +#define CONF_USB_EP1_CACHE 64 +#endif +#if defined(USB_ENDPOINT_1_IN_USED) && USB_ENDPOINT_1_IN_USED +#define CONF_USB_EP1_I_CACHE 64 +#endif + +#if defined(USB_ENDPOINT_2_OUT_USED) && USB_ENDPOINT_2_OUT_USED +#define CONF_USB_EP2_CACHE 64 +#endif +#if defined(USB_ENDPOINT_2_IN_USED) && USB_ENDPOINT_2_IN_USED +#define CONF_USB_EP2_I_CACHE 64 +#endif + +#if defined(USB_ENDPOINT_3_OUT_USED) && USB_ENDPOINT_3_OUT_USED +#define CONF_USB_EP3_CACHE 64 +#endif +#if defined(USB_ENDPOINT_3_IN_USED) && USB_ENDPOINT_3_IN_USED +#define CONF_USB_EP3_I_CACHE 64 +#endif + +#if defined(USB_ENDPOINT_4_OUT_USED) && USB_ENDPOINT_4_OUT_USED +#define CONF_USB_EP4_CACHE 64 +#endif +#if defined(USB_ENDPOINT_4_IN_USED) && USB_ENDPOINT_4_IN_USED +#define CONF_USB_EP4_I_CACHE 64 +#endif + +#if defined(USB_ENDPOINT_5_OUT_USED) && USB_ENDPOINT_5_OUT_USED +#define CONF_USB_EP5_CACHE 64 +#endif +#if defined(USB_ENDPOINT_5_IN_USED) && USB_ENDPOINT_5_IN_USED +#define CONF_USB_EP5_I_CACHE 64 +#endif + +#if defined(USB_ENDPOINT_6_OUT_USED) && USB_ENDPOINT_6_OUT_USED +#define CONF_USB_EP6_CACHE 64 +#endif +#if defined(USB_ENDPOINT_6_IN_USED) && USB_ENDPOINT_6_IN_USED +#define CONF_USB_EP6_I_CACHE 64 +#endif + +#if defined(USB_ENDPOINT_7_OUT_USED) && USB_ENDPOINT_7_OUT_USED +#define CONF_USB_EP7_CACHE 64 +#endif +#if defined(USB_ENDPOINT_7_IN_USED) && USB_ENDPOINT_7_IN_USED +#define CONF_USB_EP7_I_CACHE 64 +#endif + + +// <<< Use Configuration Wizard in Context Menu >>> + +#define CONF_USB_N_0 0 +#define CONF_USB_N_1 1 +#define CONF_USB_N_2 2 +#define CONF_USB_N_3 3 +#define CONF_USB_N_4 4 +#define CONF_USB_N_5 5 +#define CONF_USB_N_6 6 +#define CONF_USB_N_7 7 +#define CONF_USB_N_8 8 +#define CONF_USB_N_9 9 +#define CONF_USB_N_10 10 +#define CONF_USB_N_11 11 +#define CONF_USB_N_12 12 +#define CONF_USB_N_13 13 +#define CONF_USB_N_14 14 +#define CONF_USB_N_15 15 + +#define CONF_USB_D_EP_N_MAX (USB_EPT_NUM - 1) +#define CONF_USB_D_N_EP_MAX (CONF_USB_D_EP_N_MAX * 2 - 1) + +// USB Device HAL Configuration + +// Max number of endpoints supported +// Limits the number of endpoints (described by EP address) can be used in app. +// NOTE(tannewt): This not only limits the number of endpoints but also the +// addresses. In other words, even if you use endpoint 6 you need to set this to 11. +// 1 (EP0 only) +// 2 (EP0 + 1 endpoint) +// 3 (EP0 + 2 endpoints) +// 4 (EP0 + 3 endpoints) +// 5 (EP0 + 4 endpoints) +// 6 (EP0 + 5 endpoints) +// 7 (EP0 + 6 endpoints) +// 8 (EP0 + 7 endpoints) +// Max possible (by "Max Endpoint Number" config) +// usbd_num_ep_sp +#ifndef CONF_USB_D_NUM_EP_SP +#define CONF_USB_D_NUM_EP_SP CONF_USB_D_N_EP_MAX +#endif + +// + +// Max Endpoint Number supported +// Limits the max endpoint number. +// USB endpoint address is constructed by direction and endpoint number. Bit 8 of address set indicates the direction is IN. E.g., EP0x81 and EP0x01 have the same endpoint number, 1. +// Reduce the value according to specific device design, to cut-off memory usage. +// 0 (only EP0) +// 1 (EP 0x81 or 0x01) +// 2 (EP 0x82 or 0x02) +// 3 (EP 0x83 or 0x03) +// 4 (EP 0x84 or 0x04) +// 5 (EP 0x85 or 0x05) +// 6 (EP 0x86 or 0x06) +// 7 (EP 0x87 or 0x07) +// Max possible (by HW) +// The number of physical endpoints - 1 +// usbd_arch_max_ep_n +#ifndef CONF_USB_D_MAX_EP_N +#define CONF_USB_D_MAX_EP_N CONF_USB_D_EP_N_MAX +#endif + +// USB Speed Limit +// Limits the working speed of the device. +// Full speed +// Low Speed +// usbd_arch_speed +#ifndef CONF_USB_D_SPEED +#define CONF_USB_D_SPEED USB_SPEED_FS +#endif + +// Cache buffer size for EP0 +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// EP0 is default control endpoint, so cache must be used to be able to receive SETUP packet at any time. +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// usb_arch_ep0_cache +#ifndef CONF_USB_EP0_CACHE +#define CONF_USB_EP0_CACHE 64 +#endif + +// Cache configuration EP1 +// Cache buffer size for EP1 OUT +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_arch_ep1_cache +#ifndef CONF_USB_EP1_CACHE +#define CONF_USB_EP1_CACHE 0 +#endif + +// Cache buffer size for EP1 IN +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must not be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_ep1_I_CACHE +#ifndef CONF_USB_EP1_I_CACHE +#define CONF_USB_EP1_I_CACHE 0 +#endif +// + +// Cache configuration EP2 +// Cache buffer size for EP2 OUT +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_arch_ep2_cache +#ifndef CONF_USB_EP2_CACHE +#define CONF_USB_EP2_CACHE 0 +#endif + +// Cache buffer size for EP2 IN +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must not be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_ep2_I_CACHE +#ifndef CONF_USB_EP2_I_CACHE +#define CONF_USB_EP2_I_CACHE 0 +#endif +// + +// Cache configuration EP3 +// Cache buffer size for EP3 OUT +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_arch_ep3_cache +#ifndef CONF_USB_EP3_CACHE +#define CONF_USB_EP3_CACHE 0 +#endif + +// Cache buffer size for EP3 IN +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must not be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_ep3_I_CACHE +#ifndef CONF_USB_EP3_I_CACHE +#define CONF_USB_EP3_I_CACHE 0 +#endif +// + +// Cache configuration EP4 +// Cache buffer size for EP4 OUT +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_arch_ep4_cache +#ifndef CONF_USB_EP4_CACHE +#define CONF_USB_EP4_CACHE 0 +#endif + +// Cache buffer size for EP4 IN +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must not be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_ep4_I_CACHE +#ifndef CONF_USB_EP4_I_CACHE +#define CONF_USB_EP4_I_CACHE 0 +#endif +// + +// Cache configuration EP5 +// Cache buffer size for EP5 OUT +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_arch_ep5_cache +#ifndef CONF_USB_EP5_CACHE +#define CONF_USB_EP5_CACHE 0 +#endif + +// Cache buffer size for EP5 IN +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must not be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_ep5_I_CACHE +#ifndef CONF_USB_EP5_I_CACHE +#define CONF_USB_EP5_I_CACHE 0 +#endif +// + +// Cache configuration EP6 +// Cache buffer size for EP6 OUT +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_arch_ep6_cache +#ifndef CONF_USB_EP6_CACHE +#define CONF_USB_EP6_CACHE 0 +#endif + +// Cache buffer size for EP6 IN +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must not be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_ep6_I_CACHE +#ifndef CONF_USB_EP6_I_CACHE +#define CONF_USB_EP6_I_CACHE 0 +#endif +// + +// Cache configuration EP7 +// Cache buffer size for EP7 OUT +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_arch_ep7_cache +#ifndef CONF_USB_EP7_CACHE +#define CONF_USB_EP7_CACHE 0 +#endif + +// Cache buffer size for EP7 IN +// Cache is used because the USB hardware always uses DMA which requires specific memory feature. +// This cache must not be allocated if you plan to use the endpoint as control endpoint. +// No cache means IN transaction not support data buffer outside of RAM, OUT transaction not support unaligned buffer and buffer size less than endpoint max packet size +// <0=> No cache +// <8=> Cached by 8 bytes buffer +// <16=> Cached by 16 bytes buffer +// <32=> Cached by 32 bytes buffer +// <64=> Cached by 64 bytes buffer +// <128=> Cached by 128 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <256=> Cached by 256 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <512=> Cached by 512 bytes buffer (HS Bulk or interrupt or isochronous EP) +// <1024=> Cached by 1024 bytes buffer (interrupt or isochronous EP) +// usb_ep7_I_CACHE +#ifndef CONF_USB_EP7_I_CACHE +#define CONF_USB_EP7_I_CACHE 0 +#endif +// + +// <<< end of configuration section >>> + +#endif // HPL_USB_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/peripheral_clk_config.h b/ports/atmel-samd/asf4_conf/samd51/peripheral_clk_config.h new file mode 100644 index 00000000000..41efca755e7 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/peripheral_clk_config.h @@ -0,0 +1,1006 @@ +/* Auto-generated config file peripheral_clk_config.h */ +#ifndef PERIPHERAL_CLK_CONFIG_H +#define PERIPHERAL_CLK_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// ADC Clock Source +// adc_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for ADC. +#ifndef CONF_GCLK_ADC0_SRC +#define CONF_GCLK_ADC0_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +/** + * \def CONF_GCLK_ADC0_FREQUENCY + * \brief ADC0's Clock frequency + */ +#ifndef CONF_GCLK_ADC0_FREQUENCY +#define CONF_GCLK_ADC0_FREQUENCY 48000000 +#endif + +// DAC Clock Source + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// dac_gclk_selection +// Select the clock source for DAC. +#ifndef CONF_GCLK_DAC_SRC +#define CONF_GCLK_DAC_SRC GCLK_PCHCTRL_GEN_GCLK5_Val +#endif + +/** + * \def CONF_GCLK_DAC_FREQUENCY + * \brief DAC's Clock frequency + */ +#ifndef CONF_GCLK_DAC_FREQUENCY +#define CONF_GCLK_DAC_FREQUENCY 2000000 +#endif + +// EVSYS Channel 0 Clock Source +// evsys_clk_selection_0 + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for channel 0. +#ifndef CONF_GCLK_EVSYS_CHANNEL_0_SRC +#define CONF_GCLK_EVSYS_CHANNEL_0_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +/** + * \def CONF_GCLK_EVSYS_CHANNEL_0_FREQUENCY + * \brief EVSYS's Clock frequency + */ + +#ifndef CONF_GCLK_EVSYS_CHANNEL_0_FREQUENCY +#define CONF_GCLK_EVSYS_CHANNEL_0_FREQUENCY 48000000.0 +#endif + +// EVSYS Channel 1 Clock Source +// evsys_clk_selection_1 + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for channel 1. +#ifndef CONF_GCLK_EVSYS_CHANNEL_1_SRC +#define CONF_GCLK_EVSYS_CHANNEL_1_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +/** + * \def CONF_GCLK_EVSYS_CHANNEL_1_FREQUENCY + * \brief EVSYS's Clock frequency + */ + +#ifndef CONF_GCLK_EVSYS_CHANNEL_1_FREQUENCY +#define CONF_GCLK_EVSYS_CHANNEL_1_FREQUENCY 48000000.0 +#endif + +// EVSYS Channel 2 Clock Source +// evsys_clk_selection_2 + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for channel 2. +#ifndef CONF_GCLK_EVSYS_CHANNEL_2_SRC +#define CONF_GCLK_EVSYS_CHANNEL_2_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +/** + * \def CONF_GCLK_EVSYS_CHANNEL_2_FREQUENCY + * \brief EVSYS's Clock frequency + */ + +#ifndef CONF_GCLK_EVSYS_CHANNEL_2_FREQUENCY +#define CONF_GCLK_EVSYS_CHANNEL_2_FREQUENCY 48000000.0 +#endif + +// EVSYS Channel 3 Clock Source +// evsys_clk_selection_3 + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for channel 3. +#ifndef CONF_GCLK_EVSYS_CHANNEL_3_SRC +#define CONF_GCLK_EVSYS_CHANNEL_3_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +/** + * \def CONF_GCLK_EVSYS_CHANNEL_3_FREQUENCY + * \brief EVSYS's Clock frequency + */ + +#ifndef CONF_GCLK_EVSYS_CHANNEL_3_FREQUENCY +#define CONF_GCLK_EVSYS_CHANNEL_3_FREQUENCY 48000000.0 +#endif + +// EVSYS Channel 4 Clock Source +// evsys_clk_selection_4 + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for channel 4. +#ifndef CONF_GCLK_EVSYS_CHANNEL_4_SRC +#define CONF_GCLK_EVSYS_CHANNEL_4_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +/** + * \def CONF_GCLK_EVSYS_CHANNEL_4_FREQUENCY + * \brief EVSYS's Clock frequency + */ + +#ifndef CONF_GCLK_EVSYS_CHANNEL_4_FREQUENCY +#define CONF_GCLK_EVSYS_CHANNEL_4_FREQUENCY 48000000.0 +#endif + +// EVSYS Channel 5 Clock Source +// evsys_clk_selection_5 + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for channel 5. +#ifndef CONF_GCLK_EVSYS_CHANNEL_5_SRC +#define CONF_GCLK_EVSYS_CHANNEL_5_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +/** + * \def CONF_GCLK_EVSYS_CHANNEL_5_FREQUENCY + * \brief EVSYS's Clock frequency + */ + +#ifndef CONF_GCLK_EVSYS_CHANNEL_5_FREQUENCY +#define CONF_GCLK_EVSYS_CHANNEL_5_FREQUENCY 48000000.0 +#endif + +// EVSYS Channel 6 Clock Source +// evsys_clk_selection_6 + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for channel 6. +#ifndef CONF_GCLK_EVSYS_CHANNEL_6_SRC +#define CONF_GCLK_EVSYS_CHANNEL_6_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +/** + * \def CONF_GCLK_EVSYS_CHANNEL_6_FREQUENCY + * \brief EVSYS's Clock frequency + */ + +#ifndef CONF_GCLK_EVSYS_CHANNEL_6_FREQUENCY +#define CONF_GCLK_EVSYS_CHANNEL_6_FREQUENCY 48000000.0 +#endif + +// EVSYS Channel 7 Clock Source +// evsys_clk_selection_7 + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for channel 7. +#ifndef CONF_GCLK_EVSYS_CHANNEL_7_SRC +#define CONF_GCLK_EVSYS_CHANNEL_7_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +/** + * \def CONF_GCLK_EVSYS_CHANNEL_7_FREQUENCY + * \brief EVSYS's Clock frequency + */ + +#ifndef CONF_GCLK_EVSYS_CHANNEL_7_FREQUENCY +#define CONF_GCLK_EVSYS_CHANNEL_7_FREQUENCY 48000000.0 +#endif + +// EVSYS Channel 8 Clock Source +// evsys_clk_selection_8 + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for channel 8. +#ifndef CONF_GCLK_EVSYS_CHANNEL_8_SRC +#define CONF_GCLK_EVSYS_CHANNEL_8_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +/** + * \def CONF_GCLK_EVSYS_CHANNEL_8_FREQUENCY + * \brief EVSYS's Clock frequency + */ + +#ifndef CONF_GCLK_EVSYS_CHANNEL_8_FREQUENCY +#define CONF_GCLK_EVSYS_CHANNEL_8_FREQUENCY 48000000.0 +#endif + +// EVSYS Channel 9 Clock Source +// evsys_clk_selection_9 + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for channel 9. +#ifndef CONF_GCLK_EVSYS_CHANNEL_9_SRC +#define CONF_GCLK_EVSYS_CHANNEL_9_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +/** + * \def CONF_GCLK_EVSYS_CHANNEL_9_FREQUENCY + * \brief EVSYS's Clock frequency + */ + +#ifndef CONF_GCLK_EVSYS_CHANNEL_9_FREQUENCY +#define CONF_GCLK_EVSYS_CHANNEL_9_FREQUENCY 48000000.0 +#endif + +// EVSYS Channel 10 Clock Source +// evsys_clk_selection_10 + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for channel 10. +#ifndef CONF_GCLK_EVSYS_CHANNEL_10_SRC +#define CONF_GCLK_EVSYS_CHANNEL_10_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +/** + * \def CONF_GCLK_EVSYS_CHANNEL_10_FREQUENCY + * \brief EVSYS's Clock frequency + */ + +#ifndef CONF_GCLK_EVSYS_CHANNEL_10_FREQUENCY +#define CONF_GCLK_EVSYS_CHANNEL_10_FREQUENCY 48000000.0 +#endif + +// EVSYS Channel 11 Clock Source +// evsys_clk_selection_11 + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for channel 11. +#ifndef CONF_GCLK_EVSYS_CHANNEL_11_SRC +#define CONF_GCLK_EVSYS_CHANNEL_11_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +/** + * \def CONF_GCLK_EVSYS_CHANNEL_11_FREQUENCY + * \brief EVSYS's Clock frequency + */ + +#ifndef CONF_GCLK_EVSYS_CHANNEL_11_FREQUENCY +#define CONF_GCLK_EVSYS_CHANNEL_11_FREQUENCY 48000000.0 +#endif + +/** + * \def CONF_CPU_FREQUENCY + * \brief CPU's Clock frequency + */ +#ifndef CONF_CPU_FREQUENCY +#define CONF_CPU_FREQUENCY 120000000 +#endif + +// RTC Clock Source +// rtc_clk_selection +// RTC source +// Select the clock source for RTC. +#ifndef CONF_GCLK_RTC_SRC +#define CONF_GCLK_RTC_SRC RTC_CLOCK_SOURCE +#endif + +/** + * \def CONF_GCLK_RTC_FREQUENCY + * \brief RTC's Clock frequency + */ +#ifndef CONF_GCLK_RTC_FREQUENCY +#define CONF_GCLK_RTC_FREQUENCY 1024 +#endif + +// Core Clock Source +// core_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for CORE. +#ifndef CONF_GCLK_SERCOM0_CORE_SRC +#define CONF_GCLK_SERCOM0_CORE_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +// Slow Clock Source +// slow_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the slow clock source. +#ifndef CONF_GCLK_SERCOM0_SLOW_SRC +#define CONF_GCLK_SERCOM0_SLOW_SRC GCLK_PCHCTRL_GEN_GCLK3_Val +#endif + +/** + * \def CONF_GCLK_SERCOM0_CORE_FREQUENCY + * \brief SERCOM0's Core Clock frequency + */ +#ifndef CONF_GCLK_SERCOM0_CORE_FREQUENCY +#define CONF_GCLK_SERCOM0_CORE_FREQUENCY 48000000 +#endif + +/** + * \def CONF_GCLK_SERCOM0_SLOW_FREQUENCY + * \brief SERCOM0's Slow Clock frequency + */ +#ifndef CONF_GCLK_SERCOM0_SLOW_FREQUENCY +#define CONF_GCLK_SERCOM0_SLOW_FREQUENCY 32768 +#endif + +// Core Clock Source +// core_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for CORE. +#ifndef CONF_GCLK_SERCOM1_CORE_SRC +#define CONF_GCLK_SERCOM1_CORE_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +// Slow Clock Source +// slow_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the slow clock source. +#ifndef CONF_GCLK_SERCOM1_SLOW_SRC +#define CONF_GCLK_SERCOM1_SLOW_SRC GCLK_PCHCTRL_GEN_GCLK3_Val +#endif + +/** + * \def CONF_GCLK_SERCOM1_CORE_FREQUENCY + * \brief SERCOM1's Core Clock frequency + */ +#ifndef CONF_GCLK_SERCOM1_CORE_FREQUENCY +#define CONF_GCLK_SERCOM1_CORE_FREQUENCY 48000000 +#endif + +/** + * \def CONF_GCLK_SERCOM1_SLOW_FREQUENCY + * \brief SERCOM1's Slow Clock frequency + */ +#ifndef CONF_GCLK_SERCOM1_SLOW_FREQUENCY +#define CONF_GCLK_SERCOM1_SLOW_FREQUENCY 32768 +#endif + +// Core Clock Source +// core_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for CORE. +#ifndef CONF_GCLK_SERCOM2_CORE_SRC +#define CONF_GCLK_SERCOM2_CORE_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +// Slow Clock Source +// slow_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the slow clock source. +#ifndef CONF_GCLK_SERCOM2_SLOW_SRC +#define CONF_GCLK_SERCOM2_SLOW_SRC GCLK_PCHCTRL_GEN_GCLK3_Val +#endif + +/** + * \def CONF_GCLK_SERCOM2_CORE_FREQUENCY + * \brief SERCOM2's Core Clock frequency + */ +#ifndef CONF_GCLK_SERCOM2_CORE_FREQUENCY +#define CONF_GCLK_SERCOM2_CORE_FREQUENCY 48000000 +#endif + +/** + * \def CONF_GCLK_SERCOM2_SLOW_FREQUENCY + * \brief SERCOM2's Slow Clock frequency + */ +#ifndef CONF_GCLK_SERCOM2_SLOW_FREQUENCY +#define CONF_GCLK_SERCOM2_SLOW_FREQUENCY 32768 +#endif + +// Core Clock Source +// core_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for CORE. +#ifndef CONF_GCLK_SERCOM3_CORE_SRC +#define CONF_GCLK_SERCOM3_CORE_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +// Slow Clock Source +// slow_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the slow clock source. +#ifndef CONF_GCLK_SERCOM3_SLOW_SRC +#define CONF_GCLK_SERCOM3_SLOW_SRC GCLK_PCHCTRL_GEN_GCLK3_Val +#endif + +/** + * \def CONF_GCLK_SERCOM3_CORE_FREQUENCY + * \brief SERCOM3's Core Clock frequency + */ +#ifndef CONF_GCLK_SERCOM3_CORE_FREQUENCY +#define CONF_GCLK_SERCOM3_CORE_FREQUENCY 48000000 +#endif + +/** + * \def CONF_GCLK_SERCOM3_SLOW_FREQUENCY + * \brief SERCOM3's Slow Clock frequency + */ +#ifndef CONF_GCLK_SERCOM3_SLOW_FREQUENCY +#define CONF_GCLK_SERCOM3_SLOW_FREQUENCY 32768 +#endif + +// TC Clock Source +// tc_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for TC. +#ifndef CONF_GCLK_TC0_SRC +#define CONF_GCLK_TC0_SRC GCLK_PCHCTRL_GEN_GCLK1_Val +#endif + +/** + * \def CONF_GCLK_TC0_FREQUENCY + * \brief TC0's Clock frequency + */ +#ifndef CONF_GCLK_TC0_FREQUENCY +#define CONF_GCLK_TC0_FREQUENCY 48000000 +#endif + +// USB Clock Source +// usb_gclk_selection + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for USB. +#ifndef CONF_GCLK_USB_SRC +#define CONF_GCLK_USB_SRC GCLK_PCHCTRL_GEN_GCLK1_Val + +#endif + +/** + * \def CONF_GCLK_USB_FREQUENCY + * \brief USB's Clock frequency + */ +#ifndef CONF_GCLK_USB_FREQUENCY +#define CONF_GCLK_USB_FREQUENCY 48000000 +#endif + +// <<< end of configuration section >>> + +#endif // PERIPHERAL_CLK_CONFIG_H diff --git a/ports/atmel-samd/asf4_conf/samd51/usbd_config.h b/ports/atmel-samd/asf4_conf/samd51/usbd_config.h new file mode 100644 index 00000000000..be1fa3c9e07 --- /dev/null +++ b/ports/atmel-samd/asf4_conf/samd51/usbd_config.h @@ -0,0 +1,850 @@ +/* Auto-generated config file usbd_config.h */ +#ifndef USBD_CONFIG_H +#define USBD_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// ---- USB Device Stack Core Options ---- + +// High Speed Support +// Enable high speed specific descriptors support, e.g., DeviceQualifierDescriptor and OtherSpeedConfiguration Descriptor. +// High speed support require descriptors description array on start, for LS/FS and HS support in first and second place. +// usbd_hs_sp +#ifndef CONF_USBD_HS_SP +#define CONF_USBD_HS_SP 0 +#endif + +// ---- USB Device Stack Composite Options ---- + +// Enable String Descriptors +// usb_composite_str_en +#ifndef CONF_USB_COMPOSITE_STR_EN +#define CONF_USB_COMPOSITE_STR_EN 0 +#endif +// Language IDs +// Language IDs in c format, split by comma (E.g., 0x0409 ...) +// usb_composite_langid +#ifndef CONF_USB_COMPOSITE_LANGID +#define CONF_USB_COMPOSITE_LANGID "0x0409" +#endif + +#ifndef CONF_USB_COMPOSITE_LANGID_DESC +#define CONF_USB_COMPOSITE_LANGID_DESC +#endif +// + +// Composite Device Descriptor + +// bcdUSB +// <0x0200=> USB 2.0 version +// <0x0210=> USB 2.1 version +// usb_composite_bcdusb +#ifndef CONF_USB_COMPOSITE_BCDUSB +#define CONF_USB_COMPOSITE_BCDUSB 0x200 +#endif + +// bMaxPackeSize0 +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes +// usb_composite_bmaxpksz0 +#ifndef CONF_USB_COMPOSITE_BMAXPKSZ0 +#define CONF_USB_COMPOSITE_BMAXPKSZ0 0x40 +#endif + +// idVender <0x0000-0xFFFF> +// usb_composite_idvender +#ifndef CONF_USB_COMPOSITE_IDVENDER +#define CONF_USB_COMPOSITE_IDVENDER 0x3eb +#endif + +// idProduct <0x0000-0xFFFF> +// usb_composite_idproduct +#ifndef CONF_USB_COMPOSITE_IDPRODUCT +#define CONF_USB_COMPOSITE_IDPRODUCT 0x2421 +#endif + +// bcdDevice <0x0000-0xFFFF> +// usb_composite_bcddevice +#ifndef CONF_USB_COMPOSITE_BCDDEVICE +#define CONF_USB_COMPOSITE_BCDDEVICE 0x100 +#endif + +// Enable string descriptor of iManufact +// usb_composite_imanufact_en +#ifndef CONF_USB_COMPOSITE_IMANUFACT_EN +#define CONF_USB_COMPOSITE_IMANUFACT_EN 0 +#endif + +#ifndef CONF_USB_COMPOSITE_IMANUFACT +#define CONF_USB_COMPOSITE_IMANUFACT (CONF_USB_COMPOSITE_IMANUFACT_EN * (CONF_USB_COMPOSITE_IMANUFACT_EN)) +#endif + +// Unicode string of iManufact +// usb_composite_imanufact_str +#ifndef CONF_USB_COMPOSITE_IMANUFACT_STR +#define CONF_USB_COMPOSITE_IMANUFACT_STR "Atmel" +#endif + +#ifndef CONF_USB_COMPOSITE_IMANUFACT_STR_DESC +#define CONF_USB_COMPOSITE_IMANUFACT_STR_DESC +#endif + +// + +// Enable string descriptor of iProduct +// usb_composite_iproduct_en +#ifndef CONF_USB_COMPOSITE_IPRODUCT_EN +#define CONF_USB_COMPOSITE_IPRODUCT_EN 0 +#endif + +#ifndef CONF_USB_COMPOSITE_IPRODUCT +#define CONF_USB_COMPOSITE_IPRODUCT \ + (CONF_USB_COMPOSITE_IPRODUCT_EN * (CONF_USB_COMPOSITE_IMANUFACT_EN + CONF_USB_COMPOSITE_IPRODUCT_EN)) +#endif + +// Unicode string of iProduct +// usb_composite_iproduct_str +#ifndef CONF_USB_COMPOSITE_IPRODUCT_STR +#define CONF_USB_COMPOSITE_IPRODUCT_STR "Composite Demo" +#endif + +#ifndef CONF_USB_COMPOSITE_IPRODUCT_STR_DESC +#define CONF_USB_COMPOSITE_IPRODUCT_STR_DESC +#endif + +// + +// Enable string descriptor of iSerialNum +// usb_composite_iserialnum_en +#ifndef CONF_USB_COMPOSITE_ISERIALNUM_EN +#define CONF_USB_COMPOSITE_ISERIALNUM_EN 0 +#endif + +#ifndef CONF_USB_COMPOSITE_ISERIALNUM +#define CONF_USB_COMPOSITE_ISERIALNUM \ + (CONF_USB_COMPOSITE_ISERIALNUM_EN \ + * (CONF_USB_COMPOSITE_IMANUFACT_EN + CONF_USB_COMPOSITE_IPRODUCT_EN + CONF_USB_COMPOSITE_ISERIALNUM_EN)) +#endif + +// Unicode string of iSerialNum +// usb_composite_iserialnum_str +#ifndef CONF_USB_COMPOSITE_ISERIALNUM_STR +#define CONF_USB_COMPOSITE_ISERIALNUM_STR "123456789ABCDEF" +#endif + +#ifndef CONF_USB_COMPOSITE_ISERIALNUM_STR_DESC +#define CONF_USB_COMPOSITE_ISERIALNUM_STR_DESC +#endif + +// + +// bNumConfigurations <0x01-0xFF> +// usb_composite_bnumconfig +#ifndef CONF_USB_COMPOSITE_BNUMCONFIG +#define CONF_USB_COMPOSITE_BNUMCONFIG 0x1 +#endif + +// + +// Composite Configuration Descriptor +// bConfigurationValue <0x01-0xFF> +// usb_composite_bconfigval +#ifndef CONF_USB_COMPOSITE_BCONFIGVAL +#define CONF_USB_COMPOSITE_BCONFIGVAL 0x1 +#endif +// Enable string descriptor of iConfig +// usb_composite_iconfig_en +#ifndef CONF_USB_COMPOSITE_ICONFIG_EN +#define CONF_USB_COMPOSITE_ICONFIG_EN 0 +#endif + +#ifndef CONF_USB_COMPOSITE_ICONFIG +#define CONF_USB_COMPOSITE_ICONFIG \ + (CONF_USB_COMPOSITE_ICONFIG_EN \ + * (CONF_USB_COMPOSITE_IMANUFACT_EN + CONF_USB_COMPOSITE_IPRODUCT_EN + CONF_USB_COMPOSITE_ISERIALNUM_EN \ + + CONF_USB_COMPOSITE_ICONFIG_EN)) +#endif + +// Unicode string of iConfig +// usb_composite_iconfig_str +#ifndef CONF_USB_COMPOSITE_ICONFIG_STR +#define CONF_USB_COMPOSITE_ICONFIG_STR "" +#endif + +#ifndef CONF_USB_COMPOSITE_ICONFIG_STR_DESC +#define CONF_USB_COMPOSITE_ICONFIG_STR_DESC +#endif + +// + +// bmAttributes +// <0x80=> Bus power supply, not support for remote wakeup +// <0xA0=> Bus power supply, support for remote wakeup +// <0xC0=> Self powered, not support for remote wakeup +// <0xE0=> Self powered, support for remote wakeup +// usb_composite_bmattri +#ifndef CONF_USB_COMPOSITE_BMATTRI +#define CONF_USB_COMPOSITE_BMATTRI 0x80 +#endif + +// bMaxPower <0x00-0xFF> +// usb_composite_bmaxpower +#ifndef CONF_USB_COMPOSITE_BMAXPOWER +#define CONF_USB_COMPOSITE_BMAXPOWER 0x32 +#endif +// + +// CDC ACM Support +// usb_composite_cdc_acm_support +#ifndef CONF_USB_COMPOSITE_CDC_ACM_EN +#define CONF_USB_COMPOSITE_CDC_ACM_EN 0 +#endif + +// CDC ACM Comm Interrupt IN Endpoint Address +// <0x81=> EndpointAddress = 0x81 +// <0x82=> EndpointAddress = 0x82 +// <0x83=> EndpointAddress = 0x83 +// <0x84=> EndpointAddress = 0x84 +// <0x85=> EndpointAddress = 0x85 +// <0x86=> EndpointAddress = 0x86 +// <0x87=> EndpointAddress = 0x87 +// <0x88=> EndpointAddress = 0x88 +// <0x89=> EndpointAddress = 0x89 + +// usb_composite_cdc_acm_epaddr +#ifndef CONF_USB_COMPOSITE_CDC_ACM_COMM_INT_EPADDR +#define CONF_USB_COMPOSITE_CDC_ACM_COMM_INT_EPADDR 0x82 +#endif + +// CDC ACM Comm Interrupt IN Endpoint wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes + +// usb_composite_cdc_acm_comm_int_maxpksz +#ifndef CONF_USB_COMPOSITE_CDC_ACM_COMM_INT_MAXPKSZ +#define CONF_USB_COMPOSITE_CDC_ACM_COMM_INT_MAXPKSZ 0x40 +#endif + +// CDC ACM Data BULK IN Endpoint Address +// <0x81=> EndpointAddress = 0x81 +// <0x82=> EndpointAddress = 0x82 +// <0x83=> EndpointAddress = 0x83 +// <0x84=> EndpointAddress = 0x84 +// <0x85=> EndpointAddress = 0x85 +// <0x86=> EndpointAddress = 0x86 +// <0x87=> EndpointAddress = 0x87 +// <0x88=> EndpointAddress = 0x88 +// <0x89=> EndpointAddress = 0x89 + +// usb_composite_cdc_acm_data_bulkin_epaddr +#ifndef CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKIN_EPADDR +#define CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKIN_EPADDR 0x81 +#endif + +// CDC ACM Data BULK IN Endpoint wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes + +// usb_composite_cdc_acm_data_builin_maxpksz +#ifndef CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKIN_MAXPKSZ +#define CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKIN_MAXPKSZ 0x40 +#endif + +// CDC ACM Data BULK IN Endpoint wMaxPacketSize for High Speed +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes +// <0x0080=> 128 bytes +// <0x0100=> 256 bytes +// <0x0200=> 512 bytes + +// usb_composite_cdc_acm_data_builin_maxpksz_hs +#ifndef CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKIN_MAXPKSZ_HS +#define CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKIN_MAXPKSZ_HS 0x200 +#endif + +// CDC ACM Data BULK OUT Endpoint Address +// <0x01=> EndpointAddress = 0x01 +// <0x02=> EndpointAddress = 0x02 +// <0x03=> EndpointAddress = 0x03 +// <0x04=> EndpointAddress = 0x04 +// <0x05=> EndpointAddress = 0x05 +// <0x06=> EndpointAddress = 0x06 +// <0x07=> EndpointAddress = 0x07 +// <0x08=> EndpointAddress = 0x08 +// <0x09=> EndpointAddress = 0x09 + +// usb_composite_cdc_acm_data_bulkout_epaddr +#ifndef CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKOUT_EPADDR +#define CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKOUT_EPADDR 0x1 +#endif + +// CDC ACM Data BULK OUT Endpoint wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes + +// usb_composite_cdc_acm_data_buckout_maxpksz +#ifndef CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKOUT_MAXPKSZ +#define CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKOUT_MAXPKSZ 0x40 +#endif + +// CDC ACM Data BULK OUT Endpoint wMaxPacketSize for High Speed +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes +// <0x0080=> 128 bytes +// <0x0100=> 256 bytes +// <0x0200=> 512 bytes + +// usb_composite_cdc_acm_data_buckout_maxpksz_hs +#ifndef CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKOUT_MAXPKSZ_HS +#define CONF_USB_COMPOSITE_CDC_ACM_DATA_BULKOUT_MAXPKSZ_HS 0x200 +#endif + +// CDC ACM Echo Demo generation +// conf_usb_composite_cdc_echo_demo +// Invoke cdcdf_acm_demo_init(buf[wMaxPacketSize]) to enable the echo demo. +// Buf is packet buffer for data receive and echo back. +// The buffer is 4 byte aligned to support DMA. +#ifndef CONF_USB_COMPOSITE_CDC_ECHO_DEMO +#define CONF_USB_COMPOSITE_CDC_ECHO_DEMO 0 +#endif + +// + +// HID Mouse Support +// usb_composite_hid_mouse_support +#ifndef CONF_USB_COMPOSITE_HID_MOUSE_EN +#define CONF_USB_COMPOSITE_HID_MOUSE_EN 0 +#endif + +// HID Mouse INTERRUPT IN Endpoint Address +// <0x81=> EndpointAddress = 0x81 +// <0x82=> EndpointAddress = 0x82 +// <0x83=> EndpointAddress = 0x83 +// <0x84=> EndpointAddress = 0x84 +// <0x85=> EndpointAddress = 0x85 +// <0x86=> EndpointAddress = 0x86 +// <0x87=> EndpointAddress = 0x87 +// <0x88=> EndpointAddress = 0x88 +// <0x89=> EndpointAddress = 0x89 + +// usb_composite_hid_mouse_intin_epaddr +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_MOUSE_INTIN_EPADDR +#define CONF_USB_COMPOSITE_HID_MOUSE_INTIN_EPADDR 0x83 +#endif + +// HID Mouse INTERRUPT IN Endpoint wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes + +// usb_composite_hid_mouse_intin_maxpksz +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_MOUSE_INTIN_MAXPKSZ +#define CONF_USB_COMPOSITE_HID_MOUSE_INTIN_MAXPKSZ 0x8 +#endif + +// HID Mouse Move Demo generation +// conf_usb_composite_hid_mouse_demo +// Invoke hiddf_demo_init(button1, button2, button3) to enabled the move demo. +// Button1 and button3 are the pins used for mouse moving left and right. +#ifndef CONF_USB_COMPOSITE_HID_MOUSE_DEMO +#define CONF_USB_COMPOSITE_HID_MOUSE_DEMO 0 +#endif + +// + +// HID Keyboard Support +// usb_composite_hid_keyboard_support +#ifndef CONF_USB_COMPOSITE_HID_KEYBOARD_EN +#define CONF_USB_COMPOSITE_HID_KEYBOARD_EN 0 +#endif + +// HID Keyboard INTERRUPT IN Endpoint Address +// <0x81=> EndpointAddress = 0x81 +// <0x82=> EndpointAddress = 0x82 +// <0x83=> EndpointAddress = 0x83 +// <0x84=> EndpointAddress = 0x84 +// <0x85=> EndpointAddress = 0x85 +// <0x86=> EndpointAddress = 0x86 +// <0x87=> EndpointAddress = 0x87 +// <0x88=> EndpointAddress = 0x88 +// <0x89=> EndpointAddress = 0x89 + +// usb_composite_hid_keyboard_intin_epaddr +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_KEYBOARD_INTIN_EPADDR +#define CONF_USB_COMPOSITE_HID_KEYBOARD_INTIN_EPADDR 0x84 +#endif + +// HID Keyboard INTERRUPT IN Endpoint wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes + +// usb_composite_hid_keyboard_intin_maxpksz +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_KEYBOARD_INTIN_MAXPKSZ +#define CONF_USB_COMPOSITE_HID_KEYBOARD_INTIN_MAXPKSZ 0x8 +#endif + +// HID Keyboard INTERRUPT OUT Endpoint Address +// <0x01=> EndpointAddress = 0x01 +// <0x02=> EndpointAddress = 0x02 +// <0x03=> EndpointAddress = 0x03 +// <0x04=> EndpointAddress = 0x04 +// <0x05=> EndpointAddress = 0x05 +// <0x06=> EndpointAddress = 0x06 +// <0x07=> EndpointAddress = 0x07 +// <0x08=> EndpointAddress = 0x08 +// <0x09=> EndpointAddress = 0x09 + +// usb_composite_hid_keyboard_intout_epaddr +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_KEYBOARD_INTOUT_EPADDR +#define CONF_USB_COMPOSITE_HID_KEYBOARD_INTOUT_EPADDR 0x2 +#endif + +// HID Keyboard INTERRUPT OUT Endpoint wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes + +// usb_composite_hid_keyboard_intout_maxpksz +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_KEYBOARD_INTOUT_MAXPKSZ +#define CONF_USB_COMPOSITE_HID_KEYBOARD_INTOUT_MAXPKSZ 0x8 +#endif + +// HID Keyboard Caps Lock Demo generation +// conf_usb_composite_hid_keyboard_demo +// Invoke hiddf_demo_init(button1, button2, button3) to enabled the move demo. +// Buffon2 is the pin used for keyboard CAPS LOCK simulation. +#ifndef CONF_USB_COMPOSITE_HID_KEYBOARD_DEMO +#define CONF_USB_COMPOSITE_HID_KEYBOARD_DEMO 0 +#endif + +// + +// HID Generic Support +// usb_composite_hid_generic_support +#ifndef CONF_USB_COMPOSITE_HID_GENERIC_EN +#define CONF_USB_COMPOSITE_HID_GENERIC_EN 0 +#endif + +#ifndef CONF_USB_COMPOSITE_HID_GENERIC_REPORT_LEN +#define CONF_USB_COMPOSITE_HID_GENERIC_REPORT_LEN 53 +#endif + +#ifndef CONF_USB_COMPOSITE_HID_GENERIC_REPORT +#define CONF_USB_COMPOSITE_HID_GENERIC_REPORT \ + 0x06, 0xFF, 0xFF, 0x09, 0x01, 0xA1, 0x01, 0x09, 0x02, 0x09, 0x03, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, \ + 0x40, 0x81, 0x02, 0x09, 0x04, 0x09, 0x05, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x40, 0x91, 0x02, \ + 0x09, 0x06, 0x09, 0x07, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x04, 0xB1, 0x02, 0xC0 +#endif + +// HID Generic INTERRUPT IN Endpoint Address +// <0x81=> EndpointAddress = 0x81 +// <0x82=> EndpointAddress = 0x82 +// <0x83=> EndpointAddress = 0x83 +// <0x84=> EndpointAddress = 0x84 +// <0x85=> EndpointAddress = 0x85 +// <0x86=> EndpointAddress = 0x86 +// <0x87=> EndpointAddress = 0x87 +// <0x88=> EndpointAddress = 0x88 +// <0x89=> EndpointAddress = 0x89 + +// usb_composite_hid_generic_intin_epaddr +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_GENERIC_INTIN_EPADDR +#define CONF_USB_COMPOSITE_HID_GENERIC_INTIN_EPADDR 0x85 +#endif + +// HID Generic INTERRUPT IN Endpoint wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes + +// usb_composite_hid_generic_intin_maxpksz +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_GENERIC_INTIN_MAXPKSZ +#define CONF_USB_COMPOSITE_HID_GENERIC_INTIN_MAXPKSZ 0x40 +#endif + +// HID Generic INTERRUPT OUT Endpoint Address +// <0x01=> EndpointAddress = 0x01 +// <0x02=> EndpointAddress = 0x02 +// <0x03=> EndpointAddress = 0x03 +// <0x04=> EndpointAddress = 0x04 +// <0x05=> EndpointAddress = 0x05 +// <0x06=> EndpointAddress = 0x06 +// <0x07=> EndpointAddress = 0x07 +// <0x08=> EndpointAddress = 0x08 +// <0x09=> EndpointAddress = 0x09 + +// usb_composite_hid_generic_intout_epaddr +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_GENERIC_INTOUT_EPADDR +#define CONF_USB_COMPOSITE_HID_GENERIC_INTOUT_EPADDR 0x3 +#endif + +// HID Generic INTERRUPT OUT Endpoint wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes +// usb_composite_hid_generic_intout_maxpksz +// Please make sure that the setting here is coincide with the endpoint setting in USB device driver. +#ifndef CONF_USB_COMPOSITE_HID_GENERIC_INTOUT_MAXPKSZ +#define CONF_USB_COMPOSITE_HID_GENERIC_INTOUT_MAXPKSZ 0x40 +#endif + +// + +// MSC Support +// usb_composite_msc_support +#ifndef CONF_USB_COMPOSITE_MSC_EN +#define CONF_USB_COMPOSITE_MSC_EN 0 +#endif + +// MSC BULK Endpoints wMaxPacketSize +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes + +// usb_composite_msc_bulk_maxpksz +#ifndef CONF_USB_COMPOSITE_MSC_BULK_MAXPKSZ +#define CONF_USB_COMPOSITE_MSC_BULK_MAXPKSZ 0x40 +#endif + +// MSC BULK Endpoints wMaxPacketSize for High Speed +// <0x0008=> 8 bytes +// <0x0010=> 16 bytes +// <0x0020=> 32 bytes +// <0x0040=> 64 bytes +// <0x0080=> 128 bytes +// <0x0100=> 256 bytes +// <0x0200=> 512 bytes + +// usb_composite_msc_bulk_maxpksz_hs +#ifndef CONF_USB_COMPOSITE_MSC_BULK_MAXPKSZ_HS +#define CONF_USB_COMPOSITE_MSC_BULK_MAXPKSZ_HS 0x200 +#endif + +// MSC BULK IN Endpoint Address +// <0x81=> EndpointAddress = 0x81 +// <0x82=> EndpointAddress = 0x82 +// <0x83=> EndpointAddress = 0x83 +// <0x84=> EndpointAddress = 0x84 +// <0x85=> EndpointAddress = 0x85 +// <0x86=> EndpointAddress = 0x86 +// <0x87=> EndpointAddress = 0x87 +// <0x88=> EndpointAddress = 0x88 +// <0x89=> EndpointAddress = 0x89 + +// usb_composite_msc_bulkin_epaddr +#ifndef CONF_USB_COMPOSITE_MSC_BULKIN_EPADDR +#define CONF_USB_COMPOSITE_MSC_BULKIN_EPADDR 0x86 +#endif + +// MSC BULK OUT Endpoint Address +// <0x01=> EndpointAddress = 0x01 +// <0x02=> EndpointAddress = 0x02 +// <0x03=> EndpointAddress = 0x03 +// <0x04=> EndpointAddress = 0x04 +// <0x05=> EndpointAddress = 0x05 +// <0x06=> EndpointAddress = 0x06 +// <0x07=> EndpointAddress = 0x07 +// <0x08=> EndpointAddress = 0x08 +// <0x09=> EndpointAddress = 0x09 + +// usb_composite_msc_bulkout_epaddr +#ifndef CONF_USB_COMPOSITE_MSC_BULKOUT_EPADDR +#define CONF_USB_COMPOSITE_MSC_BULKOUT_EPADDR 0x4 +#endif + +// Enable Demo code for Disk LUN handling +// usb_composite_msc_demo_en +#ifndef CONF_USB_COMPOSITE_MSC_LUN_DEMO +#define CONF_USB_COMPOSITE_MSC_LUN_DEMO 1 +#endif + +// Disk access cache/buffer of sectors if non-RAM disk (e.g., SD/MMC) enabled <1-64> +// conf_usb_msc_lun_buf_sectors +#ifndef CONF_USB_MSC_LUN_BUF_SECTORS +#define CONF_USB_MSC_LUN_BUF_SECTORS 4 +#endif + +// Enable Demo for RAM Disk +// conf_usb_msc_lun0_enable +#ifndef CONF_USB_MSC_LUN0_ENABLE +#define CONF_USB_MSC_LUN0_ENABLE 1 +#endif + +#ifndef CONF_USB_MSC_LUN0_TYPE +#define CONF_USB_MSC_LUN0_TYPE 0x00 +#endif + +// The disk is removable +// conf_usb_msc_lun0_rmb +#ifndef CONF_USB_MSC_LUN0_RMB +#define CONF_USB_MSC_LUN0_RMB 0x1 +#endif + +#ifndef CONF_USB_MSC_LUN0_ISO +#define CONF_USB_MSC_LUN0_ISO 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN0_ECMA +#define CONF_USB_MSC_LUN0_ECMA 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN0_ANSI +#define CONF_USB_MSC_LUN0_ANSI 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN0_REPO +#define CONF_USB_MSC_LUN0_REPO 0x01 +#endif + +#ifndef CONF_USB_MSC_LUN0_FACTORY +#define CONF_USB_MSC_LUN0_FACTORY 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN0_PRODUCT +#define CONF_USB_MSC_LUN0_PRODUCT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN0_PRODUCT_VERSION +#define CONF_USB_MSC_LUN0_PRODUCT_VERSION 0x00, 0x00, 0x00, 0x00 +#endif + +// Disk Size (in KB) <0x1-0xFFFFFFFF> +// Windows will not show disk less than 20K, so 22K is used to reserve more RAM for APP +// conf_usb_msc_lun0_capacity + +#ifndef CONF_USB_MSC_LUN0_CAPACITY +#define CONF_USB_MSC_LUN0_CAPACITY 22 +#endif + +#ifndef CONF_USB_MSC_LUN0_BLOCK_SIZE +#define CONF_USB_MSC_LUN0_BLOCK_SIZE 512 +#endif + +#ifndef CONF_USB_MSC_LUN0_LAST_BLOCK_ADDR +#define CONF_USB_MSC_LUN0_LAST_BLOCK_ADDR \ + ((uint32_t)CONF_USB_MSC_LUN0_CAPACITY * 1024 / CONF_USB_MSC_LUN0_BLOCK_SIZE - 1) +#endif + +// + +// Enable Demo for SD/MMC Disk +// SD/MMC stack must be added before enable SD/MMC demo +// SD/MMC insert/eject not supported by this simple demo +// conf_usb_msc_lun1_enable +#ifndef CONF_USB_MSC_LUN1_ENABLE +#define CONF_USB_MSC_LUN1_ENABLE 0 +#endif + +#ifndef CONF_USB_MSC_LUN1_TYPE +#define CONF_USB_MSC_LUN1_TYPE 0x00 +#endif + +// The disk is removable +// SD/MMC stack must be added before enable SD/MMC demo +// SD/MMC insert/eject not supported by this simple demo +// conf_usb_msc_lun1_rmb +#ifndef CONF_USB_MSC_LUN1_RMB +#define CONF_USB_MSC_LUN1_RMB 0x1 +#endif + +#ifndef CONF_USB_MSC_LUN1_ISO +#define CONF_USB_MSC_LUN1_ISO 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN1_ECMA +#define CONF_USB_MSC_LUN1_ECMA 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN1_ANSI +#define CONF_USB_MSC_LUN1_ANSI 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN1_REPO +#define CONF_USB_MSC_LUN1_REPO 0x01 +#endif + +#ifndef CONF_USB_MSC_LUN1_FACTORY +#define CONF_USB_MSC_LUN1_FACTORY 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN1_PRODUCT +#define CONF_USB_MSC_LUN1_PRODUCT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN1_PRODUCT_VERSION +#define CONF_USB_MSC_LUN1_PRODUCT_VERSION 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN1_CAPACITY +#define CONF_USB_MSC_LUN1_CAPACITY 22 +#endif + +#ifndef CONF_USB_MSC_LUN1_BLOCK_SIZE +#define CONF_USB_MSC_LUN1_BLOCK_SIZE 512 +#endif + +#ifndef CONF_USB_MSC_LUN1_LAST_BLOCK_ADDR +#define CONF_USB_MSC_LUN1_LAST_BLOCK_ADDR \ + ((uint32_t)CONF_USB_MSC_LUN1_CAPACITY * 1024 / CONF_USB_MSC_LUN1_BLOCK_SIZE - 1) +#endif + +// + +// Enable Demo for LUN 2 +// conf_usb_msc_lun2_enable +#ifndef CONF_USB_MSC_LUN2_ENABLE +#define CONF_USB_MSC_LUN2_ENABLE 0 +#endif + +#ifndef CONF_USB_MSC_LUN2_TYPE +#define CONF_USB_MSC_LUN2_TYPE 0x00 +#endif + +// The disk is removable +// conf_usb_msc_lun2_rmb +#ifndef CONF_USB_MSC_LUN2_RMB +#define CONF_USB_MSC_LUN2_RMB 0x1 +#endif + +#ifndef CONF_USB_MSC_LUN2_ISO +#define CONF_USB_MSC_LUN2_ISO 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN2_ECMA +#define CONF_USB_MSC_LUN2_ECMA 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN2_ANSI +#define CONF_USB_MSC_LUN2_ANSI 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN2_REPO +#define CONF_USB_MSC_LUN2_REPO 0x01 +#endif + +#ifndef CONF_USB_MSC_LUN2_FACTORY +#define CONF_USB_MSC_LUN2_FACTORY 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN2_PRODUCT +#define CONF_USB_MSC_LUN2_PRODUCT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN2_PRODUCT_VERSION +#define CONF_USB_MSC_LUN2_PRODUCT_VERSION 0x00, 0x00, 0x00, 0x00 +#endif + +// Disk Size (in KB) <0x1-0xFFFFFFFF> +// conf_usb_msc_lun2_capacity + +#ifndef CONF_USB_MSC_LUN2_CAPACITY +#define CONF_USB_MSC_LUN2_CAPACITY 22 +#endif + +#ifndef CONF_USB_MSC_LUN2_BLOCK_SIZE +#define CONF_USB_MSC_LUN2_BLOCK_SIZE 512 +#endif + +#ifndef CONF_USB_MSC_LUN2_LAST_BLOCK_ADDR +#define CONF_USB_MSC_LUN2_LAST_BLOCK_ADDR \ + ((uint32_t)CONF_USB_MSC_LUN2_CAPACITY * 1024 / CONF_USB_MSC_LUN2_BLOCK_SIZE - 1) +#endif + +// + +// Enable Demo for LUN 3 +// conf_usb_msc_lun3_enable +#ifndef CONF_USB_MSC_LUN3_ENABLE +#define CONF_USB_MSC_LUN3_ENABLE 0 +#endif + +#ifndef CONF_USB_MSC_LUN3_TYPE +#define CONF_USB_MSC_LUN3_TYPE 0x00 +#endif + +// The disk is removable +// conf_usb_msc_lun3_rmb +#ifndef CONF_USB_MSC_LUN3_RMB +#define CONF_USB_MSC_LUN3_RMB 0x1 +#endif + +#ifndef CONF_USB_MSC_LUN3_ISO +#define CONF_USB_MSC_LUN3_ISO 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN3_ECMA +#define CONF_USB_MSC_LUN3_ECMA 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN3_ANSI +#define CONF_USB_MSC_LUN3_ANSI 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN3_REPO +#define CONF_USB_MSC_LUN3_REPO 0x01 +#endif + +#ifndef CONF_USB_MSC_LUN3_FACTORY +#define CONF_USB_MSC_LUN3_FACTORY 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN3_PRODUCT +#define CONF_USB_MSC_LUN3_PRODUCT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#endif + +#ifndef CONF_USB_MSC_LUN3_PRODUCT_VERSION +#define CONF_USB_MSC_LUN3_PRODUCT_VERSION 0x00, 0x00, 0x00, 0x00 +#endif + +// Disk Size (in KB) <0x1-0xFFFFFFFF> +// conf_usb_msc_lun3_capacity + +#ifndef CONF_USB_MSC_LUN3_CAPACITY +#define CONF_USB_MSC_LUN3_CAPACITY 22 +#endif + +#ifndef CONF_USB_MSC_LUN3_BLOCK_SIZE +#define CONF_USB_MSC_LUN3_BLOCK_SIZE 512 +#endif + +#ifndef CONF_USB_MSC_LUN3_LAST_BLOCK_ADDR +#define CONF_USB_MSC_LUN3_LAST_BLOCK_ADDR \ + ((uint32_t)CONF_USB_MSC_LUN3_CAPACITY * 1024 / CONF_USB_MSC_LUN3_BLOCK_SIZE - 1) +#endif + +// + +// +// + +// <<< end of configuration section >>> + +#endif // USBD_CONFIG_H diff --git a/ports/atmel-samd/audio_dma.c b/ports/atmel-samd/audio_dma.c new file mode 100644 index 00000000000..481a420cbce --- /dev/null +++ b/ports/atmel-samd/audio_dma.c @@ -0,0 +1,353 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "audio_dma.h" +#include "samd/clocks.h" +#include "samd/events.h" +#include "samd/dma.h" + +#include "shared-bindings/audiocore/RawSample.h" +#include "shared-bindings/audiocore/WaveFile.h" + +#include "py/mpstate.h" +#include "py/runtime.h" + +#if CIRCUITPY_AUDIOIO || CIRCUITPY_AUDIOBUSIO + +static audio_dma_t* audio_dma_state[AUDIO_DMA_CHANNEL_COUNT]; + +// This cannot be in audio_dma_state because it's volatile. +static volatile bool audio_dma_pending[AUDIO_DMA_CHANNEL_COUNT]; + +uint8_t find_free_audio_dma_channel(void) { + uint8_t channel; + for (channel = 0; channel < AUDIO_DMA_CHANNEL_COUNT; channel++) { + if (!dma_channel_enabled(channel)) { + return channel; + } + } + return channel; +} + +void audio_dma_disable_channel(uint8_t channel) { + if (channel >= AUDIO_DMA_CHANNEL_COUNT) + return; + dma_disable_channel(channel); +} + +void audio_dma_enable_channel(uint8_t channel) { + if (channel >= AUDIO_DMA_CHANNEL_COUNT) + return; + dma_enable_channel(channel); +} + +void audio_dma_convert_signed(audio_dma_t* dma, uint8_t* buffer, uint32_t buffer_length, + uint8_t** output_buffer, uint32_t* output_buffer_length, + uint8_t* output_spacing) { + if (dma->first_buffer_free) { + *output_buffer = dma->first_buffer; + } else { + *output_buffer = dma->second_buffer; + } + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" + if (dma->signed_to_unsigned || dma->unsigned_to_signed) { + *output_buffer_length = buffer_length / dma->spacing; + *output_spacing = 1; + uint32_t out_i = 0; + if (dma->bytes_per_sample == 1) { + for (uint32_t i = 0; i < buffer_length; i += dma->spacing) { + if (dma->signed_to_unsigned) { + ((uint8_t*) *output_buffer)[out_i] = ((int8_t*) buffer)[i] + 0x80; + } else { + ((int8_t*) *output_buffer)[out_i] = ((uint8_t*) buffer)[i] - 0x80; + } + out_i += 1; + } + } else if (dma->bytes_per_sample == 2) { + for (uint32_t i = 0; i < buffer_length / 2; i += dma->spacing) { + if (dma->signed_to_unsigned) { + ((uint16_t*) *output_buffer)[out_i] = ((int16_t*) buffer)[i] + 0x8000; + } else { + ((int16_t*) *output_buffer)[out_i] = ((uint16_t*) buffer)[i] - 0x8000; + } + out_i += 1; + } + } + } else { + *output_buffer = buffer; + *output_buffer_length = buffer_length; + *output_spacing = dma->spacing; + } + #pragma GCC diagnostic pop + dma->first_buffer_free = !dma->first_buffer_free; +} + +void audio_dma_load_next_block(audio_dma_t* dma) { + uint8_t* buffer; + uint32_t buffer_length; + audioio_get_buffer_result_t get_buffer_result = + audiosample_get_buffer(dma->sample, dma->single_channel, dma->audio_channel, + &buffer, &buffer_length); + + DmacDescriptor* descriptor = dma->second_descriptor; + if (dma->first_descriptor_free) { + descriptor = dma_descriptor(dma->dma_channel); + } + dma->first_descriptor_free = !dma->first_descriptor_free; + + if (get_buffer_result == GET_BUFFER_ERROR) { + audio_dma_stop(dma); + return; + } + + uint8_t* output_buffer; + uint32_t output_buffer_length; + uint8_t output_spacing; + audio_dma_convert_signed(dma, buffer, buffer_length, &output_buffer, &output_buffer_length, + &output_spacing); + + descriptor->BTCNT.reg = output_buffer_length / dma->beat_size / output_spacing; + descriptor->SRCADDR.reg = ((uint32_t) output_buffer) + output_buffer_length; + if (get_buffer_result == GET_BUFFER_DONE) { + if (dma->loop) { + audiosample_reset_buffer(dma->sample, dma->single_channel, dma->audio_channel); + } else { + descriptor->DESCADDR.reg = 0; + } + } + descriptor->BTCTRL.bit.VALID = true; +} + +static void setup_audio_descriptor(DmacDescriptor* descriptor, uint8_t beat_size, + uint8_t spacing, uint32_t output_register_address) { + uint32_t beat_size_reg = DMAC_BTCTRL_BEATSIZE_BYTE; + if (beat_size == 2) { + beat_size_reg = DMAC_BTCTRL_BEATSIZE_HWORD; + } else if (beat_size == 4) { + beat_size_reg = DMAC_BTCTRL_BEATSIZE_WORD; + } + descriptor->BTCTRL.reg = beat_size_reg | + DMAC_BTCTRL_SRCINC | + DMAC_BTCTRL_EVOSEL_BLOCK | + DMAC_BTCTRL_STEPSIZE(spacing - 1) | + DMAC_BTCTRL_STEPSEL_SRC; + descriptor->DSTADDR.reg = output_register_address; +} + +// Playback should be shutdown before calling this. +audio_dma_result audio_dma_setup_playback(audio_dma_t* dma, + mp_obj_t sample, + bool loop, + bool single_channel, + uint8_t audio_channel, + bool output_signed, + uint32_t output_register_address, + uint8_t dma_trigger_source) { + uint8_t dma_channel = find_free_audio_dma_channel(); + if (dma_channel >= AUDIO_DMA_CHANNEL_COUNT) { + return AUDIO_DMA_DMA_BUSY; + } + + dma->sample = sample; + dma->loop = loop; + dma->single_channel = single_channel; + dma->audio_channel = audio_channel; + dma->dma_channel = dma_channel; + dma->signed_to_unsigned = false; + dma->unsigned_to_signed = false; + dma->second_descriptor = NULL; + dma->spacing = 1; + dma->first_descriptor_free = true; + audiosample_reset_buffer(sample, single_channel, audio_channel); + + bool single_buffer; + bool samples_signed; + uint32_t max_buffer_length; + audiosample_get_buffer_structure(sample, single_channel, &single_buffer, &samples_signed, + &max_buffer_length, &dma->spacing); + uint8_t output_spacing = dma->spacing; + if (output_signed != samples_signed) { + output_spacing = 1; + max_buffer_length /= dma->spacing; + dma->first_buffer = (uint8_t*) m_malloc(max_buffer_length, false); + if (dma->first_buffer == NULL) { + return AUDIO_DMA_MEMORY_ERROR; + } + dma->first_buffer_free = true; + if (!single_buffer) { + dma->second_buffer = (uint8_t*) m_malloc(max_buffer_length, false); + if (dma->second_buffer == NULL) { + return AUDIO_DMA_MEMORY_ERROR; + } + } + dma->signed_to_unsigned = !output_signed && samples_signed; + dma->unsigned_to_signed = output_signed && !samples_signed; + } + + dma->event_channel = 0xff; + if (!single_buffer) { + dma->second_descriptor = (DmacDescriptor*) m_malloc(sizeof(DmacDescriptor), false); + if (dma->second_descriptor == NULL) { + return AUDIO_DMA_MEMORY_ERROR; + } + + // We're likely double buffering so set up the block interrupts. + turn_on_event_system(); + dma->event_channel = find_sync_event_channel(); + + if (dma->event_channel >= EVSYS_SYNCH_NUM) { + mp_raise_RuntimeError(translate("All sync event channels in use")); + } + init_event_channel_interrupt(dma->event_channel, CORE_GCLK, EVSYS_ID_GEN_DMAC_CH_0 + dma_channel); + + // We keep the audio_dma_t for internal use and the sample as a root pointer because it + // contains the audiodma structure. + audio_dma_state[dma->dma_channel] = dma; + MP_STATE_PORT(playing_audio)[dma->dma_channel] = dma->sample; + } + + + if (audiosample_bits_per_sample(sample) == 16) { + dma->beat_size = 2; + dma->bytes_per_sample = 2; + } else { + dma->beat_size = 1; + dma->bytes_per_sample = 1; + if (single_channel) { + output_register_address += 1; + } + } + // Transfer both channels at once. + if (!single_channel && audiosample_channel_count(sample) == 2) { + dma->beat_size *= 2; + } + + DmacDescriptor* first_descriptor = dma_descriptor(dma_channel); + setup_audio_descriptor(first_descriptor, dma->beat_size, output_spacing, output_register_address); + if (single_buffer) { + first_descriptor->DESCADDR.reg = 0; + if (dma->loop) { + first_descriptor->DESCADDR.reg = (uint32_t) first_descriptor; + } + } else { + first_descriptor->DESCADDR.reg = (uint32_t) dma->second_descriptor; + setup_audio_descriptor(dma->second_descriptor, dma->beat_size, output_spacing, output_register_address); + dma->second_descriptor->DESCADDR.reg = (uint32_t) first_descriptor; + } + + // Load the first two blocks up front. + audio_dma_load_next_block(dma); + if (!single_buffer) { + audio_dma_load_next_block(dma); + } + + dma_configure(dma_channel, dma_trigger_source, true); + audio_dma_enable_channel(dma_channel); + + return AUDIO_DMA_OK; +} + +void audio_dma_stop(audio_dma_t* dma) { + uint8_t channel = dma->dma_channel; + if (channel < AUDIO_DMA_CHANNEL_COUNT) { + audio_dma_disable_channel(channel); + disable_event_channel(dma->event_channel); + MP_STATE_PORT(playing_audio)[channel] = NULL; + audio_dma_state[channel] = NULL; + } + dma->dma_channel = AUDIO_DMA_CHANNEL_COUNT; +} + +void audio_dma_pause(audio_dma_t* dma) { + dma_suspend_channel(dma->dma_channel); +} + +void audio_dma_resume(audio_dma_t* dma) { + dma_resume_channel(dma->dma_channel); +} + +bool audio_dma_get_paused(audio_dma_t* dma) { + if (dma->dma_channel >= AUDIO_DMA_CHANNEL_COUNT) { + return false; + } + uint32_t status = dma_transfer_status(dma->dma_channel); + + return (status & DMAC_CHINTFLAG_SUSP) != 0; +} + +void audio_dma_init(audio_dma_t* dma) { + dma->dma_channel = AUDIO_DMA_CHANNEL_COUNT; +} + +void audio_dma_reset(void) { + for (uint8_t i = 0; i < AUDIO_DMA_CHANNEL_COUNT; i++) { + audio_dma_state[i] = NULL; + audio_dma_pending[i] = false; + audio_dma_disable_channel(i); + dma_descriptor(i)->BTCTRL.bit.VALID = false; + MP_STATE_PORT(playing_audio)[i] = NULL; + } +} + +bool audio_dma_get_playing(audio_dma_t* dma) { + if (dma->dma_channel >= AUDIO_DMA_CHANNEL_COUNT) { + return false; + } + uint32_t status = dma_transfer_status(dma->dma_channel); + if ((status & DMAC_CHINTFLAG_TCMPL) != 0 || (status & DMAC_CHINTFLAG_TERR) != 0) { + audio_dma_stop(dma); + } + + return (status & DMAC_CHINTFLAG_TERR) == 0; +} + +// WARN(tannewt): DO NOT print from here. Printing calls background tasks such as this and causes a +// stack overflow. + +void audio_dma_background(void) { + for (uint8_t i = 0; i < AUDIO_DMA_CHANNEL_COUNT; i++) { + if (audio_dma_pending[i]) { + continue; + } + audio_dma_t* dma = audio_dma_state[i]; + if (dma == NULL) { + continue; + } + + bool block_done = event_interrupt_active(dma->event_channel); + if (!block_done) { + continue; + } + + // audio_dma_load_next_block() can call Python code, which can call audio_dma_background() + // recursively at the next background processing time. So disallow recursive calls to here. + audio_dma_pending[i] = true; + audio_dma_load_next_block(dma); + audio_dma_pending[i] = false; + } +} +#endif diff --git a/ports/atmel-samd/audio_dma.h b/ports/atmel-samd/audio_dma.h new file mode 100644 index 00000000000..9d923c5ce1d --- /dev/null +++ b/ports/atmel-samd/audio_dma.h @@ -0,0 +1,97 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_AUDIO_DMA_H +#define MICROPY_INCLUDED_ATMEL_SAMD_AUDIO_DMA_H + +#include "extmod/vfs_fat.h" +#include "py/obj.h" +#include "shared-module/audiocore/RawSample.h" +#include "shared-module/audiocore/WaveFile.h" + +typedef struct { + mp_obj_t sample; + uint8_t dma_channel; + uint8_t event_channel; + uint8_t audio_channel; + uint8_t bytes_per_sample; + uint8_t beat_size; + uint8_t spacing; + bool loop; + bool single_channel; + bool signed_to_unsigned; + bool unsigned_to_signed; + bool first_buffer_free; + uint8_t* first_buffer; + uint8_t* second_buffer; + bool first_descriptor_free; + DmacDescriptor* second_descriptor; +} audio_dma_t; + +typedef enum { + AUDIO_DMA_OK, + AUDIO_DMA_DMA_BUSY, + AUDIO_DMA_MEMORY_ERROR, +} audio_dma_result; + +uint32_t audiosample_sample_rate(mp_obj_t sample_obj); +uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj); +uint8_t audiosample_channel_count(mp_obj_t sample_obj); + +void audio_dma_init(audio_dma_t* dma); +void audio_dma_reset(void); + +uint8_t find_free_audio_dma_channel(void); + +// This sets everything up but doesn't start the timer. +// Sample is the python object for the sample to play. +// loop is true if we should loop the sample. +// single_channel is true if we only output a single channel. When false, all channels will be +// output. +// audio_channel is the index of the channel to dma. single_channel must be false in this case. +// output_signed is true if the dma'd data should be signed. False and it will be unsigned. +// output_register_address is the address to copy data to. +// dma_trigger_source is the DMA trigger source which cause another copy +audio_dma_result audio_dma_setup_playback(audio_dma_t* dma, + mp_obj_t sample, + bool loop, + bool single_channel, + uint8_t audio_channel, + bool output_signed, + uint32_t output_register_address, + uint8_t dma_trigger_source); + +void audio_dma_disable_channel(uint8_t channel); +void audio_dma_enable_channel(uint8_t channel); +void audio_dma_stop(audio_dma_t* dma); +bool audio_dma_get_playing(audio_dma_t* dma); +void audio_dma_pause(audio_dma_t* dma); +void audio_dma_resume(audio_dma_t* dma); +bool audio_dma_get_paused(audio_dma_t* dma); + +void audio_dma_background(void); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_AUDIO_DMA_H diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c new file mode 100644 index 00000000000..386ba07158a --- /dev/null +++ b/ports/atmel-samd/background.c @@ -0,0 +1,79 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "background.h" + +#include "audio_dma.h" +#include "tick.h" +#include "supervisor/filesystem.h" +#include "supervisor/usb.h" + +#include "py/runtime.h" +#include "shared-module/network/__init__.h" +#include "supervisor/shared/stack.h" + +#ifdef CIRCUITPY_DISPLAYIO +#include "shared-module/displayio/__init__.h" +#endif + +volatile uint64_t last_finished_tick = 0; + +bool stack_ok_so_far = true; + +static bool running_background_tasks = false; + +void background_tasks_reset(void) { + running_background_tasks = false; +} + +void run_background_tasks(void) { + // Don't call ourselves recursively. + if (running_background_tasks) { + return; + } + assert_heap_ok(); + running_background_tasks = true; + + #if CIRCUITPY_AUDIOIO || CIRCUITPY_AUDIOBUSIO + audio_dma_background(); + #endif + #if CIRCUITPY_DISPLAYIO + displayio_background(); + #endif + + #if CIRCUITPY_NETWORK + network_module_background(); + #endif + filesystem_background(); + usb_background(); + running_background_tasks = false; + assert_heap_ok(); + + last_finished_tick = ticks_ms; +} + +bool background_tasks_ok(void) { + return ticks_ms - last_finished_tick < 1000; +} diff --git a/ports/atmel-samd/background.h b/ports/atmel-samd/background.h new file mode 100644 index 00000000000..d9866a6abc6 --- /dev/null +++ b/ports/atmel-samd/background.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_BACKGROUND_H +#define MICROPY_INCLUDED_ATMEL_SAMD_BACKGROUND_H + +#include + +void background_tasks_reset(void); +void run_background_tasks(void); +void run_background_vm_tasks(void); +bool background_tasks_ok(void); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_BACKGROUND_H diff --git a/ports/atmel-samd/bindings/samd/Clock.c b/ports/atmel-samd/bindings/samd/Clock.c new file mode 100644 index 00000000000..be597c44409 --- /dev/null +++ b/ports/atmel-samd/bindings/samd/Clock.c @@ -0,0 +1,165 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * 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 "bindings/samd/Clock.h" +#include "samd/clocks.h" +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +//| .. currentmodule:: samd +//| +//| :class:`Clock` --- Clock reference +//| ------------------------------------------ +//| +//| Identifies a clock on the microcontroller. +//| +//| .. class:: Clock +//| +//| Identifies a clock on the microcontroller. They are fixed by the +//| hardware so they cannot be constructed on demand. Instead, use +//| `samd.clock` to reference the desired clock. +//| + +STATIC void samd_clock_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_printf(print, "%q.%q.%q", MP_QSTR_samd, MP_QSTR_clock, self->name); +} + +//| .. attribute:: enabled +//| +//| Is the clock enabled? (read-only) +//| +STATIC mp_obj_t samd_clock_get_enabled(mp_obj_t self_in) { + samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(clock_get_enabled(self->type, self->index)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(samd_clock_get_enabled_obj, samd_clock_get_enabled); + +const mp_obj_property_t samd_clock_enabled_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&samd_clock_get_enabled_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj, + }, +}; + +//| .. attribute:: parent +//| +//| Clock parent. (read-only) +//| +STATIC mp_obj_t samd_clock_get_parent(mp_obj_t self_in) { + samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint8_t p_type, p_index; + if (!clock_get_parent(self->type, self->index, &p_type, &p_index)) + return mp_const_none; + + const mp_map_t* samd_map = &samd_clock_globals.map; + for (uint8_t i = 0; i < samd_map->alloc; i++) { + samd_clock_obj_t *iter = samd_map->table[i].value; + if (iter->type == p_type && iter->index == p_index) + return iter; + } + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_1(samd_clock_get_parent_obj, samd_clock_get_parent); + +const mp_obj_property_t samd_clock_parent_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&samd_clock_get_parent_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj, + }, +}; + +//| .. attribute:: frequency +//| +//| Clock frequency. (read-only) +//| +STATIC mp_obj_t samd_clock_get_frequency(mp_obj_t self_in) { + samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int_from_uint(clock_get_frequency(self->type, self->index)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(samd_clock_get_frequency_obj, samd_clock_get_frequency); + +const mp_obj_property_t samd_clock_frequency_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&samd_clock_get_frequency_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj, + }, +}; + +//| .. attribute:: calibration +//| +//| Clock calibration. Not all clocks can be calibrated. +//| +STATIC mp_obj_t samd_clock_get_calibration(mp_obj_t self_in) { + samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int_from_uint(clock_get_calibration(self->type, self->index)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(samd_clock_get_calibration_obj, samd_clock_get_calibration); + +STATIC mp_obj_t samd_clock_set_calibration(mp_obj_t self_in, mp_obj_t calibration) { + samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in); + int ret = clock_set_calibration(self->type, self->index, mp_obj_get_int(calibration)); + if (ret == -2) + mp_raise_AttributeError(translate("calibration is read only")); + if (ret == -1) + mp_raise_ValueError(translate("calibration is out of range")); + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_2(samd_clock_set_calibration_obj, samd_clock_set_calibration); + +const mp_obj_property_t samd_clock_calibration_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&samd_clock_get_calibration_obj, + (mp_obj_t)&samd_clock_set_calibration_obj, + (mp_obj_t)&mp_const_none_obj, + }, +}; + +STATIC const mp_rom_map_elem_t samd_clock_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_enabled), MP_ROM_PTR(&samd_clock_enabled_obj) }, + { MP_ROM_QSTR(MP_QSTR_parent), MP_ROM_PTR(&samd_clock_parent_obj) }, + { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&samd_clock_frequency_obj) }, + { MP_ROM_QSTR(MP_QSTR_calibration), MP_ROM_PTR(&samd_clock_calibration_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(samd_clock_locals_dict, samd_clock_locals_dict_table); + +const mp_obj_type_t samd_clock_type = { + { &mp_type_type }, + .name = MP_QSTR_Clock, + .print = samd_clock_print, + .locals_dict = (mp_obj_t)&samd_clock_locals_dict, +}; diff --git a/ports/atmel-samd/bindings/samd/Clock.h b/ports/atmel-samd/bindings/samd/Clock.h new file mode 100644 index 00000000000..ccc8f10d101 --- /dev/null +++ b/ports/atmel-samd/bindings/samd/Clock.h @@ -0,0 +1,77 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_BINDINGS_SAMD_CLOCK_H +#define MICROPY_INCLUDED_ATMEL_SAMD_BINDINGS_SAMD_CLOCK_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + qstr name; + uint8_t type; + uint8_t index; +} samd_clock_obj_t; + +#define CLOCK(_name, _type, _index) \ +const samd_clock_obj_t clock_ ## _name = { \ + { &samd_clock_type }, \ + .name = MP_QSTR_ ## _name, \ + .type = _type, \ + .index = _index, \ +} + +#define CLOCK_SOURCE(_name) \ +const samd_clock_obj_t clock_ ## _name = { \ + { &samd_clock_type }, \ + .name = MP_QSTR_ ## _name, \ + .type = 0, \ + .index = GCLK_SOURCE_ ## _name, \ +} + +#define CLOCK_GCLK(_name) \ +const samd_clock_obj_t clock_ ## _name = { \ + { &samd_clock_type }, \ + .name = MP_QSTR_ ## _name, \ + .type = 1, \ + .index = _name ## _GCLK_ID, \ +} + +#define CLOCK_GCLK_(_name, _extra) \ +const samd_clock_obj_t clock_ ## _name ## _ ## _extra = { \ + { &samd_clock_type }, \ + .name = MP_QSTR_ ## _name ## _ ## _extra, \ + .type = 1, \ + .index = _name ## _GCLK_ID_ ## _extra, \ +} + +#define CLOCK_ENTRY(_name) { MP_ROM_QSTR(MP_QSTR_ ## _name), MP_ROM_PTR(&clock_ ## _name) } +#define CLOCK_ENTRY_(_name, _extra) { MP_ROM_QSTR(MP_QSTR_ ## _name ## _ ## _extra), MP_ROM_PTR(&clock_ ## _name ## _ ## _extra) } + +extern const mp_obj_type_t samd_clock_type; +extern const mp_obj_dict_t samd_clock_globals; + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_BINDINGS_SAMD_CLOCK_H diff --git a/ports/atmel-samd/bindings/samd/__init__.c b/ports/atmel-samd/bindings/samd/__init__.c new file mode 100644 index 00000000000..55a10001d26 --- /dev/null +++ b/ports/atmel-samd/bindings/samd/__init__.c @@ -0,0 +1,72 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "py/obj.h" +#include "py/runtime.h" + +#include "bindings/samd/Clock.h" + +//| :mod:`samd` --- SAMD implementation settings +//| ================================================= +//| +//| .. module:: samd +//| :synopsis: SAMD implementation settings +//| :platform: SAMD21 +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Clock +//| + +//| :mod:`samd.clock` --- samd clock names +//| -------------------------------------------------------- +//| +//| .. module:: samd.clock +//| :synopsis: samd clock names +//| :platform: SAMD21 +//| +//| References to clocks as named by the microcontroller +//| +const mp_obj_module_t samd_clock_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&samd_clock_globals, +}; + +STATIC const mp_rom_map_elem_t samd_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_samd) }, + { MP_ROM_QSTR(MP_QSTR_clock), MP_ROM_PTR(&samd_clock_module) }, +}; + +STATIC MP_DEFINE_CONST_DICT(samd_module_globals, samd_module_globals_table); + +const mp_obj_module_t samd_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&samd_module_globals, +}; diff --git a/ports/atmel-samd/boards/arduino_mkr1300/board.c b/ports/atmel-samd/boards/arduino_mkr1300/board.c new file mode 100644 index 00000000000..770bc825938 --- /dev/null +++ b/ports/atmel-samd/boards/arduino_mkr1300/board.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h new file mode 100644 index 00000000000..a508d91913f --- /dev/null +++ b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h @@ -0,0 +1,26 @@ +#define MICROPY_HW_BOARD_NAME "Arduino MKR1300" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define MICROPY_HW_LED_STATUS (&pin_PB23) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA09) +#define DEFAULT_I2C_BUS_SDA (&pin_PA08) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA13) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA12) +#define DEFAULT_SPI_BUS_MISO (&pin_PA15) + +#define DEFAULT_UART_BUS_RX (&pin_PB23) +#define DEFAULT_UART_BUS_TX (&pin_PB22) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk new file mode 100644 index 00000000000..a543468e522 --- /dev/null +++ b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk @@ -0,0 +1,13 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x2341 +USB_PID = 0x8053 +USB_PRODUCT = "Arduino MKR1300" +USB_MANUFACTURER = "Arduino" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/arduino_mkr1300/pins.c b/ports/atmel-samd/boards/arduino_mkr1300/pins.c new file mode 100644 index 00000000000..7a73e89bf9e --- /dev/null +++ b/ports/atmel-samd/boards/arduino_mkr1300/pins.c @@ -0,0 +1,42 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_PB09) }, // NOTE: LORA BOOT + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_RST), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_CS), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/arduino_mkrzero/board.c b/ports/atmel-samd/boards/arduino_mkrzero/board.c new file mode 100644 index 00000000000..0f60736a240 --- /dev/null +++ b/ports/atmel-samd/boards/arduino_mkrzero/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.h b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.h new file mode 100644 index 00000000000..02750e64698 --- /dev/null +++ b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.h @@ -0,0 +1,24 @@ +#define MICROPY_HW_BOARD_NAME "Arduino MKR Zero" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA09) +#define DEFAULT_I2C_BUS_SDA (&pin_PA08) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA17) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA16) +#define DEFAULT_SPI_BUS_MISO (&pin_PA19) + +#define DEFAULT_UART_BUS_RX (&pin_PB23) +#define DEFAULT_UART_BUS_TX (&pin_PB22) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk new file mode 100644 index 00000000000..5612eb88d73 --- /dev/null +++ b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x239A +USB_PID = 0x8050 +USB_PRODUCT = "Arduino MKRZero" +USB_MANUFACTURER = "Arduino" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/arduino_mkrzero/pins.c b/ports/atmel-samd/boards/arduino_mkrzero/pins.c new file mode 100644 index 00000000000..2494076ab1d --- /dev/null +++ b/ports/atmel-samd/boards/arduino_mkrzero/pins.c @@ -0,0 +1,45 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_SD_CD), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/arduino_zero/board.c b/ports/atmel-samd/boards/arduino_zero/board.c new file mode 100644 index 00000000000..770bc825938 --- /dev/null +++ b/ports/atmel-samd/boards/arduino_zero/board.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h new file mode 100644 index 00000000000..ec201e6ef5b --- /dev/null +++ b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h @@ -0,0 +1,29 @@ +#define MICROPY_HW_BOARD_NAME "Arduino Zero" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_HW_LED_STATUS (&pin_PA17) + +#define MICROPY_HW_LED_TX &pin_PA27 +#define MICROPY_HW_LED_RX &pin_PB03 + +#define MICROPY_PORT_A (PORT_PA27) +#define MICROPY_PORT_B (PORT_PB03) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk new file mode 100644 index 00000000000..cbbf15a3ef8 --- /dev/null +++ b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x2341 +USB_PID = 0x824D +USB_PRODUCT = "Arduino Zero" +USB_MANUFACTURER = "Arduino" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/arduino_zero/pins.c b/ports/atmel-samd/boards/arduino_zero/pins.c new file mode 100644 index 00000000000..7ebcc9a6e35 --- /dev/null +++ b/ports/atmel-samd/boards/arduino_zero/pins.c @@ -0,0 +1,35 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/bast_pro_mini_m0/board.c b/ports/atmel-samd/boards/bast_pro_mini_m0/board.c new file mode 100644 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/bast_pro_mini_m0/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/bast_pro_mini_m0/mpconfigboard.h b/ports/atmel-samd/boards/bast_pro_mini_m0/mpconfigboard.h new file mode 100644 index 00000000000..561240c69aa --- /dev/null +++ b/ports/atmel-samd/boards/bast_pro_mini_m0/mpconfigboard.h @@ -0,0 +1,53 @@ +#define MICROPY_HW_BOARD_NAME "Electronic Cats Bast Pro Mini M0" +#define MICROPY_HW_MCU_NAME "samd21e18" + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 0 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA08) +#define DEFAULT_I2C_BUS_SDA (&pin_PA09) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA17) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA16) +#define DEFAULT_SPI_BUS_MISO (&pin_PA19) + +#define DEFAULT_UART_BUS_RX (&pin_PA01) +#define DEFAULT_UART_BUS_TX (&pin_PA00) + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) + +#define IGNORE_PIN_PA03 1 +#define IGNORE_PIN_PA12 1 +#define IGNORE_PIN_PA13 1 +#define IGNORE_PIN_PA20 1 +#define IGNORE_PIN_PA21 1 +// USB is always used. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 +#define IGNORE_PIN_PA30 1 +#define IGNORE_PIN_PA31 1 +#define IGNORE_PIN_PB01 1 +#define IGNORE_PIN_PB02 1 +#define IGNORE_PIN_PB03 1 +#define IGNORE_PIN_PB04 1 +#define IGNORE_PIN_PB05 1 +#define IGNORE_PIN_PB06 1 +#define IGNORE_PIN_PB07 1 +#define IGNORE_PIN_PB08 1 +#define IGNORE_PIN_PB09 1 +#define IGNORE_PIN_PB10 1 +#define IGNORE_PIN_PB11 1 +#define IGNORE_PIN_PB12 1 +#define IGNORE_PIN_PB13 1 +#define IGNORE_PIN_PB14 1 +#define IGNORE_PIN_PB15 1 +#define IGNORE_PIN_PB16 1 +#define IGNORE_PIN_PB17 1 +#define IGNORE_PIN_PB22 1 +#define IGNORE_PIN_PB23 1 +#define IGNORE_PIN_PB30 1 +#define IGNORE_PIN_PB31 1 +#define IGNORE_PIN_PB00 1 diff --git a/ports/atmel-samd/boards/bast_pro_mini_m0/mpconfigboard.mk b/ports/atmel-samd/boards/bast_pro_mini_m0/mpconfigboard.mk new file mode 100644 index 00000000000..08e42aa4ef3 --- /dev/null +++ b/ports/atmel-samd/boards/bast_pro_mini_m0/mpconfigboard.mk @@ -0,0 +1,12 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x1209 +USB_PID = 0xBAB3 +USB_PRODUCT = "Bast Pro Mini M0" +USB_MANUFACTURER = "Electronic Cats" + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 diff --git a/ports/atmel-samd/boards/bast_pro_mini_m0/pins.c b/ports/atmel-samd/boards/bast_pro_mini_m0/pins.c new file mode 100644 index 00000000000..3ed940e362f --- /dev/null +++ b/ports/atmel-samd/boards/bast_pro_mini_m0/pins.c @@ -0,0 +1,36 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA28) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/board.h b/ports/atmel-samd/boards/board.h new file mode 100644 index 00000000000..4f0ae9d728e --- /dev/null +++ b/ports/atmel-samd/boards/board.h @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +// This file defines board specific functions. + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_BOARDS_BOARD_H +#define MICROPY_INCLUDED_ATMEL_SAMD_BOARDS_BOARD_H + +#include + +#include "py/mpconfig.h" + +// Initializes board related state once on start up. +void board_init(void); + +// Returns true if the user initiates safe mode in a board specific way. +// Also add BOARD_USER_SAFE_MODE in mpconfigboard.h to explain the board specific +// way. +bool board_requests_safe_mode(void); + +// Reset the state of off MCU components such as neopixels. +void reset_board(void); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_BOARDS_BOARD_H diff --git a/ports/atmel-samd/boards/capablerobot_usbhub/board.c b/ports/atmel-samd/boards/capablerobot_usbhub/board.c new file mode 100644 index 00000000000..9a19e02d13b --- /dev/null +++ b/ports/atmel-samd/boards/capablerobot_usbhub/board.c @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" +#include "common-hal/microcontroller/Pin.h" + +void board_init(void) { + // Don't reset: + // - USB Host Enable Pin + // - reset pin of the USB Hub + // + // If either are reset, USB devices will disconnect when the MCU restarts + never_reset_pin_number(PIN_PA07); + never_reset_pin_number(PIN_PB08); +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.h b/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.h new file mode 100644 index 00000000000..f4e40739b02 --- /dev/null +++ b/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.h @@ -0,0 +1,37 @@ +#define MICROPY_HW_BOARD_NAME "Capable Robot Programmable USB Hub" +#define MICROPY_HW_MCU_NAME "samd51g19" + +#define CIRCUITPY_MCU_FAMILY samd51 + + +#define MICROPY_HW_LED_STATUS (&pin_PA22) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// QSPI CS, and QSPI SCK +#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA01) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA00) +#define DEFAULT_SPI_BUS_MISO (&pin_PB23) + +#define DEFAULT_UART_BUS_RX (&pin_PA16) +#define DEFAULT_UART_BUS_TX (&pin_PA17) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk b/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk new file mode 100644 index 00000000000..f390a8681aa --- /dev/null +++ b/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk @@ -0,0 +1,16 @@ +LD_FILE = boards/samd51x19-bootloader-external-flash.ld +USB_VID = 0x04D8 +USB_PID = 0xEDB3 +USB_PRODUCT = "Programmable USB Hub" +USB_MANUFACTURER = "Capable Robot Components" + +CHIP_VARIANT = SAMD51G19A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = GD25Q16C +LONGINT_IMPL = MPZ + +# No I2S on SAMD51G +CIRCUITPY_AUDIOBUSIO = 0 diff --git a/ports/atmel-samd/boards/capablerobot_usbhub/pins.c b/ports/atmel-samd/boards/capablerobot_usbhub/pins.c new file mode 100644 index 00000000000..1fde6094096 --- /dev/null +++ b/ports/atmel-samd/boards/capablerobot_usbhub/pins.c @@ -0,0 +1,36 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_ANMB), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ANVLIM), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_AN5V), MP_ROM_PTR(&pin_PA05) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_MBPWM), MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MBINT), MP_ROM_PTR(&pin_PA15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MBCS), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MBRST), MP_ROM_PTR(&pin_PB09) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED3), MP_ROM_PTR(&pin_PA21) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA17) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_USBHEN), MP_ROM_PTR(&pin_PA07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_USBRST), MP_ROM_PTR(&pin_PB08) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA2), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL2), MP_ROM_PTR(&pin_PA13) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB23) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/catwan_usbstick/board.c b/ports/atmel-samd/boards/catwan_usbstick/board.c new file mode 100644 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/catwan_usbstick/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.h b/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.h new file mode 100644 index 00000000000..7a32bf023fa --- /dev/null +++ b/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.h @@ -0,0 +1,58 @@ +#define MICROPY_HW_BOARD_NAME "Electronic Cats CatWAN USBStick" +#define MICROPY_HW_MCU_NAME "samd21e18" + +#define MICROPY_HW_LED_RX &pin_PA14 + +#define MICROPY_PORT_A (PORT_PA14) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define DEFAULT_SPI_BUS_SCK (&pin_PA19) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA18) +#define DEFAULT_SPI_BUS_MISO (&pin_PA22) + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define IGNORE_PIN_PA00 1 +#define IGNORE_PIN_PA01 1 +#define IGNORE_PIN_PA02 1 +#define IGNORE_PIN_PA03 1 +#define IGNORE_PIN_PA05 1 +#define IGNORE_PIN_PA06 1 +#define IGNORE_PIN_PA07 1 +#define IGNORE_PIN_PA08 1 +#define IGNORE_PIN_PA09 1 +#define IGNORE_PIN_PA10 1 +#define IGNORE_PIN_PA11 1 +#define IGNORE_PIN_PA12 1 +#define IGNORE_PIN_PA13 1 +#define IGNORE_PIN_PA20 1 +#define IGNORE_PIN_PA21 1 +// USB is always used. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 +#define IGNORE_PIN_PA28 1 +#define IGNORE_PIN_PB01 1 +#define IGNORE_PIN_PB02 1 +#define IGNORE_PIN_PB03 1 +#define IGNORE_PIN_PB04 1 +#define IGNORE_PIN_PB05 1 +#define IGNORE_PIN_PB06 1 +#define IGNORE_PIN_PB07 1 +#define IGNORE_PIN_PB08 1 +#define IGNORE_PIN_PB09 1 +#define IGNORE_PIN_PB10 1 +#define IGNORE_PIN_PB11 1 +#define IGNORE_PIN_PB12 1 +#define IGNORE_PIN_PB13 1 +#define IGNORE_PIN_PB14 1 +#define IGNORE_PIN_PB15 1 +#define IGNORE_PIN_PB16 1 +#define IGNORE_PIN_PB17 1 +#define IGNORE_PIN_PB22 1 +#define IGNORE_PIN_PB23 1 +#define IGNORE_PIN_PB30 1 +#define IGNORE_PIN_PB31 1 +#define IGNORE_PIN_PB00 1 diff --git a/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.mk b/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.mk new file mode 100644 index 00000000000..2399aad5c5e --- /dev/null +++ b/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.mk @@ -0,0 +1,12 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x1209 +USB_PID = 0xBAB2 +USB_PRODUCT = "CatWAN USBStick" +USB_MANUFACTURER = "Electronic Cats" + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 diff --git a/ports/atmel-samd/boards/catwan_usbstick/pins.c b/ports/atmel-samd/boards/catwan_usbstick/pins.c new file mode 100644 index 00000000000..346bd9c10ca --- /dev/null +++ b/ports/atmel-samd/boards/catwan_usbstick/pins.c @@ -0,0 +1,17 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA30) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA31) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_D0), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_D1), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_D2), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_RST), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_CS), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/circuitplayground_express/board.c b/ports/atmel-samd/boards/circuitplayground_express/board.c new file mode 100644 index 00000000000..578963642dd --- /dev/null +++ b/ports/atmel-samd/boards/circuitplayground_express/board.c @@ -0,0 +1,65 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "boards/board.h" +#include "common-hal/microcontroller/Pin.h" +#include "hal/include/hal_gpio.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/neopixel_write/__init__.h" + +void board_init(void) +{ +} + +// Check the status of the two buttons on CircuitPlayground Express. If both are +// pressed, then boot into user safe mode. +bool board_requests_safe_mode(void) { + gpio_set_pin_function(PIN_PA14, GPIO_PIN_FUNCTION_OFF); + gpio_set_pin_direction(PIN_PA14, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(PIN_PA14, GPIO_PULL_DOWN); + + gpio_set_pin_function(PIN_PA28, GPIO_PIN_FUNCTION_OFF); + gpio_set_pin_direction(PIN_PA28, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(PIN_PA28, GPIO_PULL_DOWN); + bool safe_mode = gpio_get_pin_level(PIN_PA14) && + gpio_get_pin_level(PIN_PA28); + reset_pin_number(PIN_PA14); + reset_pin_number(PIN_PA28); + return safe_mode; +} + +void reset_board(void) { + uint8_t empty[30]; + memset(empty, 0, 30); + digitalio_digitalinout_obj_t neopixel_pin; + common_hal_digitalio_digitalinout_construct(&neopixel_pin, &pin_PB23); + common_hal_digitalio_digitalinout_switch_to_output(&neopixel_pin, false, + DRIVE_MODE_PUSH_PULL); + common_hal_neopixel_write(&neopixel_pin, empty, 30); + common_hal_digitalio_digitalinout_deinit(&neopixel_pin); +} diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h new file mode 100644 index 00000000000..e6a7e06769a --- /dev/null +++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h @@ -0,0 +1,48 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit CircuitPlayground Express" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_HW_LED_STATUS (&pin_PA17) + +// Don't allow touch on A0 (PA02), because it's connected to the speaker. +#define PA02_NO_TOUCH (true) + +// Salae reads 12mhz which is the limit even though we set it to the safer 8mhz. +#define SPI_FLASH_BAUDRATE (8000000) + +// On-board flash +#define SPI_FLASH_MOSI_PIN &pin_PA20 +#define SPI_FLASH_MISO_PIN &pin_PA16 +#define SPI_FLASH_SCK_PIN &pin_PA21 +#define SPI_FLASH_CS_PIN &pin_PB22 + +// These are pins not to reset. +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define SPEAKER_ENABLE_PIN (&pin_PA30) + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code. +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define CALIBRATE_CRYSTALLESS 1 + +// Explanation of how a user got into safe mode. +#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up" + +#define DEFAULT_I2C_BUS_SCL (&pin_PB03) +#define DEFAULT_I2C_BUS_SDA (&pin_PB02) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA05) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA07) +#define DEFAULT_SPI_BUS_MISO (&pin_PA06) + +#define DEFAULT_UART_BUS_RX (&pin_PB09) +#define DEFAULT_UART_BUS_TX (&pin_PB08) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk new file mode 100644 index 00000000000..3c43776f5bd --- /dev/null +++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk @@ -0,0 +1,29 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash-crystalless.ld +USB_VID = 0x239A +USB_PID = 0x8019 +USB_PRODUCT = "CircuitPlayground Express" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" +LONGINT_IMPL = MPZ + +# Make room for frozen libs. +CIRCUITPY_DISPLAYIO = 0 +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_I2CSLAVE = 0 + +SUPEROPT_GC = 0 +CFLAGS_INLINE_LIMIT = 55 + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Thermistor diff --git a/ports/atmel-samd/boards/circuitplayground_express/pins.c b/ports/atmel-samd/boards/circuitplayground_express/pins.c new file mode 100644 index 00000000000..6fc46bd216b --- /dev/null +++ b/ports/atmel-samd/boards/circuitplayground_express/pins.c @@ -0,0 +1,63 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_TEMPERATURE), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PA09) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON_A), MP_ROM_PTR(&pin_PA28) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA28) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_B), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_SLIDE_SWITCH), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB23) }, + + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + + { MP_ROM_QSTR(MP_QSTR_REMOTEIN), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_IR_RX), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_REMOTEOUT), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_IR_TX), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_IR_PROXIMITY), MP_ROM_PTR(&pin_PA04) }, + + { MP_ROM_QSTR(MP_QSTR_MICROPHONE_CLOCK), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_MICROPHONE_DATA), MP_ROM_PTR(&pin_PA08) }, + + { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_SDA), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_SCL), MP_ROM_PTR(&pin_PA01) }, + + { MP_ROM_QSTR(MP_QSTR_SPEAKER_ENABLE), MP_ROM_PTR(&pin_PA30) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/board.c b/ports/atmel-samd/boards/circuitplayground_express_crickit/board.c new file mode 100644 index 00000000000..578963642dd --- /dev/null +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/board.c @@ -0,0 +1,65 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "boards/board.h" +#include "common-hal/microcontroller/Pin.h" +#include "hal/include/hal_gpio.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/neopixel_write/__init__.h" + +void board_init(void) +{ +} + +// Check the status of the two buttons on CircuitPlayground Express. If both are +// pressed, then boot into user safe mode. +bool board_requests_safe_mode(void) { + gpio_set_pin_function(PIN_PA14, GPIO_PIN_FUNCTION_OFF); + gpio_set_pin_direction(PIN_PA14, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(PIN_PA14, GPIO_PULL_DOWN); + + gpio_set_pin_function(PIN_PA28, GPIO_PIN_FUNCTION_OFF); + gpio_set_pin_direction(PIN_PA28, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(PIN_PA28, GPIO_PULL_DOWN); + bool safe_mode = gpio_get_pin_level(PIN_PA14) && + gpio_get_pin_level(PIN_PA28); + reset_pin_number(PIN_PA14); + reset_pin_number(PIN_PA28); + return safe_mode; +} + +void reset_board(void) { + uint8_t empty[30]; + memset(empty, 0, 30); + digitalio_digitalinout_obj_t neopixel_pin; + common_hal_digitalio_digitalinout_construct(&neopixel_pin, &pin_PB23); + common_hal_digitalio_digitalinout_switch_to_output(&neopixel_pin, false, + DRIVE_MODE_PUSH_PULL); + common_hal_neopixel_write(&neopixel_pin, empty, 30); + common_hal_digitalio_digitalinout_deinit(&neopixel_pin); +} diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h new file mode 100644 index 00000000000..ca6f9b77346 --- /dev/null +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h @@ -0,0 +1,48 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit CircuitPlayground Express with Crickit libraries" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_HW_LED_STATUS (&pin_PA17) + +// Don't allow touch on A0 (PA02), because it's connected to the speaker. +#define PA02_NO_TOUCH (true) + +// Salae reads 12mhz which is the limit even though we set it to the safer 8mhz. +#define SPI_FLASH_BAUDRATE (8000000) + +// On-board flash +#define SPI_FLASH_MOSI_PIN &pin_PA20 +#define SPI_FLASH_MISO_PIN &pin_PA16 +#define SPI_FLASH_SCK_PIN &pin_PA21 +#define SPI_FLASH_CS_PIN &pin_PB22 + +// These are pins not to reset. +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define SPEAKER_ENABLE_PIN (&pin_PA30) + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code. +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define CALIBRATE_CRYSTALLESS 1 + +// Explanation of how a user got into safe mode. +#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up" + +#define DEFAULT_I2C_BUS_SCL (&pin_PB03) +#define DEFAULT_I2C_BUS_SDA (&pin_PB02) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA05) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA07) +#define DEFAULT_SPI_BUS_MISO (&pin_PA06) + +#define DEFAULT_UART_BUS_RX (&pin_PB09) +#define DEFAULT_UART_BUS_TX (&pin_PB08) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk new file mode 100644 index 00000000000..f456515f9a3 --- /dev/null +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk @@ -0,0 +1,33 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash-crystalless.ld +USB_VID = 0x239A +USB_PID = 0x8019 +USB_PRODUCT = "CircuitPlayground Express with Crickit libraries" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" + +# Turn off features and optimizations for Crickit build to make room for additional frozen libs. +LONGINT_IMPL = NONE +CIRCUITPY_DISPLAYIO = 0 +CIRCUITPY_PIXELBUF = 0 +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_I2CSLAVE = 0 + +SUPEROPT_GC = 0 +CFLAGS_INLINE_LIMIT = 55 + + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Crickit +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Motor +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_seesaw +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Thermistor diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/pins.c b/ports/atmel-samd/boards/circuitplayground_express_crickit/pins.c new file mode 100644 index 00000000000..6fc46bd216b --- /dev/null +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/pins.c @@ -0,0 +1,63 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_TEMPERATURE), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PA09) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON_A), MP_ROM_PTR(&pin_PA28) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA28) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_B), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_SLIDE_SWITCH), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB23) }, + + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + + { MP_ROM_QSTR(MP_QSTR_REMOTEIN), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_IR_RX), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_REMOTEOUT), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_IR_TX), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_IR_PROXIMITY), MP_ROM_PTR(&pin_PA04) }, + + { MP_ROM_QSTR(MP_QSTR_MICROPHONE_CLOCK), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_MICROPHONE_DATA), MP_ROM_PTR(&pin_PA08) }, + + { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_SDA), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_SCL), MP_ROM_PTR(&pin_PA01) }, + + { MP_ROM_QSTR(MP_QSTR_SPEAKER_ENABLE), MP_ROM_PTR(&pin_PA30) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/cp32-m4/board.c b/ports/atmel-samd/boards/cp32-m4/board.c new file mode 100644 index 00000000000..0f60736a240 --- /dev/null +++ b/ports/atmel-samd/boards/cp32-m4/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/cp32-m4/mpconfigboard.h b/ports/atmel-samd/boards/cp32-m4/mpconfigboard.h new file mode 100644 index 00000000000..9e329b3ed9d --- /dev/null +++ b/ports/atmel-samd/boards/cp32-m4/mpconfigboard.h @@ -0,0 +1,31 @@ +#define MICROPY_HW_BOARD_NAME "CP32-M4" +#define MICROPY_HW_MCU_NAME "samd51j20" + +#define MICROPY_HW_APA102_MOSI (&pin_PA12) +#define MICROPY_HW_APA102_SCK (&pin_PA13) + + +#define CIRCUITPY_MCU_FAMILY samd51 + +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11| PORT_PA12| PORT_PA13) +#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PB09) +#define DEFAULT_I2C_BUS_SDA (&pin_PB08) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA22) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA23) +#define DEFAULT_SPI_BUS_MISO (&pin_PA21) + +#define DEFAULT_UART_BUS_RX (&pin_PB17) +#define DEFAULT_UART_BUS_TX (&pin_PB16) diff --git a/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk b/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk new file mode 100644 index 00000000000..86a7719b849 --- /dev/null +++ b/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk @@ -0,0 +1,16 @@ +LD_FILE = boards/samd51x20-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8021 +USB_PRODUCT = "CP32-M4" +USB_MANUFACTURER = "Nadda-Reel Company LLC" + +CHIP_VARIANT = SAMD51J20A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "W25Q128JV_PM" + +CIRCUITPY_PS2IO = 1 +# No I2S on SAMD51G. +CIRCUITPY_AUDIOBUSIO = 0 diff --git a/ports/atmel-samd/boards/cp32-m4/pins.c b/ports/atmel-samd/boards/cp32-m4/pins.c new file mode 100644 index 00000000000..1946c9d3ab9 --- /dev/null +++ b/ports/atmel-samd/boards/cp32-m4/pins.c @@ -0,0 +1,51 @@ +#include "shared-bindings/board/__init__.h" + +// This mapping only includes functional names because pins broken +// out on connectors are labeled with their MCU name available from +// microcontroller.pin. +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER_P), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER_N), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_STATUS_LED), MP_ROM_PTR(&pin_PA15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BACKLIGHT_PWM), MP_ROM_PTR(&pin_PB09) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SW1_2), MP_ROM_PTR(&pin_PA06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SW3_4), MP_ROM_PTR(&pin_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SW5), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SW7), MP_ROM_PTR(&pin_PB06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SW8), MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SW9), MP_ROM_PTR(&pin_PB05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SW10), MP_ROM_PTR(&pin_PB04) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_EXT_HDR3), MP_ROM_PTR(&pin_PB07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_EXT_HDR4), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_EXT_HDR5), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_EXT_SW6), MP_ROM_PTR(&pin_PA21) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SD0), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD1), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD2), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD3), MP_ROM_PTR(&pin_PB14) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_CMD), MP_ROM_PTR(&pin_PB15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CLK), MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB17) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_VSPI_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_VSPI_MOSI), MP_ROM_PTR(&pin_PB23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_VSPI_MISO), MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_VSPI_CS0), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_VSPI_CS1), MP_ROM_PTR(&pin_PA27) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_PA23) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA12) }, + + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/datalore_ip_m4/board.c b/ports/atmel-samd/boards/datalore_ip_m4/board.c new file mode 100644 index 00000000000..0f60736a240 --- /dev/null +++ b/ports/atmel-samd/boards/datalore_ip_m4/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.h b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.h new file mode 100644 index 00000000000..99167d31bc6 --- /dev/null +++ b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.h @@ -0,0 +1,45 @@ +#define MICROPY_HW_BOARD_NAME "TG-Boards' Datalore IP M4" +#define MICROPY_HW_MCU_NAME "samd51j19" + +#define CIRCUITPY_MCU_FAMILY samd51 + +// This is for Rev F which is green + +#define MICROPY_HW_LED_TX (&pin_PA27) +#define MICROPY_HW_LED_RX (&pin_PB06) + +#define MICROPY_HW_LED_STATUS (&pin_PA16) + +#define MICROPY_HW_NEOPIXEL (&pin_PB22) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// QSPI CS, QSPI SCK and NeoPixel pin +#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11 | PORT_PB22) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PB03) +#define DEFAULT_I2C_BUS_SDA (&pin_PB02) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA13) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA12) +#define DEFAULT_SPI_BUS_MISO (&pin_PA14) + +#define DEFAULT_UART_BUS_RX (&pin_PA23) +#define DEFAULT_UART_BUS_TX (&pin_PA22) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk new file mode 100644 index 00000000000..aa5f47d4009 --- /dev/null +++ b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk @@ -0,0 +1,17 @@ +LD_FILE = boards/samd51x19-bootloader-external-flash.ld +USB_VID = 0x4097 +USB_PID = 0x0001 +USB_PRODUCT = "Datalore IP M4" +USB_MANUFACTURER = "TG-Boards" + +CHIP_VARIANT = SAMD51J19A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 3 +EXTERNAL_FLASH_DEVICES = "GD25Q16C, W25Q16JV_IQ, W25Q16JV_IM" +LONGINT_IMPL = MPZ + +CIRCUITPY_NETWORK = 1 +MICROPY_PY_WIZNET5K = 5500 +CIRCUITPY_PS2IO = 1 diff --git a/ports/atmel-samd/boards/datalore_ip_m4/pins.c b/ports/atmel-samd/boards/datalore_ip_m4/pins.c new file mode 100644 index 00000000000..4eb26dd21bb --- /dev/null +++ b/ports/atmel-samd/boards/datalore_ip_m4/pins.c @@ -0,0 +1,46 @@ +#include "shared-bindings/board/__init__.h" + +// This mapping only includes functional names because pins broken +// out on connectors are labeled with their MCU name available from +// microcontroller.pin. +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB09) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA16) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PB03) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_PB22) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA14) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX),MP_ROM_PTR(&pin_PB06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX),MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/datum_distance/board.c b/ports/atmel-samd/boards/datum_distance/board.c new file mode 100644 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/datum_distance/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/datum_distance/mpconfigboard.h b/ports/atmel-samd/boards/datum_distance/mpconfigboard.h new file mode 100644 index 00000000000..e02e4378057 --- /dev/null +++ b/ports/atmel-samd/boards/datum_distance/mpconfigboard.h @@ -0,0 +1,29 @@ +// LEDs +#define MICROPY_HW_LED_STATUS (&pin_PA17) +#define MICROPY_HW_LED_TX &pin_PA27 +#define MICROPY_HW_LED_RX &pin_PA17 + +#define MICROPY_HW_BOARD_NAME "J&J Studios datum-Distance" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/datum_distance/mpconfigboard.mk b/ports/atmel-samd/boards/datum_distance/mpconfigboard.mk new file mode 100644 index 00000000000..a7bb8293d45 --- /dev/null +++ b/ports/atmel-samd/boards/datum_distance/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x04D8 +USB_PID = 0xEE8C +USB_PRODUCT = "datum-Distance" +USB_MANUFACTURER = "J&J Studios LLC" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/datum_distance/pins.c b/ports/atmel-samd/boards/datum_distance/pins.c new file mode 100644 index 00000000000..b29a859b64c --- /dev/null +++ b/ports/atmel-samd/boards/datum_distance/pins.c @@ -0,0 +1,27 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/datum_imu/board.c b/ports/atmel-samd/boards/datum_imu/board.c new file mode 100644 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/datum_imu/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/datum_imu/mpconfigboard.h b/ports/atmel-samd/boards/datum_imu/mpconfigboard.h new file mode 100644 index 00000000000..b87739dd0e8 --- /dev/null +++ b/ports/atmel-samd/boards/datum_imu/mpconfigboard.h @@ -0,0 +1,29 @@ +// LEDs +#define MICROPY_HW_LED_STATUS (&pin_PA17) +#define MICROPY_HW_LED_TX &pin_PA27 +#define MICROPY_HW_LED_RX &pin_PA17 + +#define MICROPY_HW_BOARD_NAME "J&J Studios datum-IMU" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/datum_imu/mpconfigboard.mk b/ports/atmel-samd/boards/datum_imu/mpconfigboard.mk new file mode 100644 index 00000000000..507c83b0418 --- /dev/null +++ b/ports/atmel-samd/boards/datum_imu/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x04D8 +USB_PID = 0xEE8D +USB_PRODUCT = "datum-IMU" +USB_MANUFACTURER = "J&J Studios LLC" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/datum_imu/pins.c b/ports/atmel-samd/boards/datum_imu/pins.c new file mode 100644 index 00000000000..237b5774ec0 --- /dev/null +++ b/ports/atmel-samd/boards/datum_imu/pins.c @@ -0,0 +1,29 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/datum_light/board.c b/ports/atmel-samd/boards/datum_light/board.c new file mode 100644 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/datum_light/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/datum_light/mpconfigboard.h b/ports/atmel-samd/boards/datum_light/mpconfigboard.h new file mode 100644 index 00000000000..2a91c112dd5 --- /dev/null +++ b/ports/atmel-samd/boards/datum_light/mpconfigboard.h @@ -0,0 +1,29 @@ +// LEDs +#define MICROPY_HW_LED_STATUS (&pin_PA17) +#define MICROPY_HW_LED_TX &pin_PA27 +#define MICROPY_HW_LED_RX &pin_PA17 + +#define MICROPY_HW_BOARD_NAME "J&J Studios datum-Light" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/datum_light/mpconfigboard.mk b/ports/atmel-samd/boards/datum_light/mpconfigboard.mk new file mode 100644 index 00000000000..4bb227ba4e9 --- /dev/null +++ b/ports/atmel-samd/boards/datum_light/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x04D8 +USB_PID = 0xEE8E +USB_PRODUCT = "datum-Light" +USB_MANUFACTURER = "J&J Studios LLC" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/datum_light/pins.c b/ports/atmel-samd/boards/datum_light/pins.c new file mode 100644 index 00000000000..b29a859b64c --- /dev/null +++ b/ports/atmel-samd/boards/datum_light/pins.c @@ -0,0 +1,27 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/datum_weather/board.c b/ports/atmel-samd/boards/datum_weather/board.c new file mode 100644 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/datum_weather/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/datum_weather/mpconfigboard.h b/ports/atmel-samd/boards/datum_weather/mpconfigboard.h new file mode 100644 index 00000000000..45619197b9c --- /dev/null +++ b/ports/atmel-samd/boards/datum_weather/mpconfigboard.h @@ -0,0 +1,29 @@ +// LEDs +#define MICROPY_HW_LED_STATUS (&pin_PA17) +#define MICROPY_HW_LED_TX &pin_PA27 +#define MICROPY_HW_LED_RX &pin_PA17 + +#define MICROPY_HW_BOARD_NAME "J&J Studios datum-Weather" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/datum_weather/mpconfigboard.mk b/ports/atmel-samd/boards/datum_weather/mpconfigboard.mk new file mode 100644 index 00000000000..411aee62546 --- /dev/null +++ b/ports/atmel-samd/boards/datum_weather/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x04D8 +USB_PID = 0xEE8F +USB_PRODUCT = "datum-Weather" +USB_MANUFACTURER = "J&J Studios LLC" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/datum_weather/pins.c b/ports/atmel-samd/boards/datum_weather/pins.c new file mode 100644 index 00000000000..b29a859b64c --- /dev/null +++ b/ports/atmel-samd/boards/datum_weather/pins.c @@ -0,0 +1,27 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/escornabot_makech/board.c b/ports/atmel-samd/boards/escornabot_makech/board.c new file mode 100644 index 00000000000..881e15e0c5e --- /dev/null +++ b/ports/atmel-samd/boards/escornabot_makech/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Andrés Sabas for Electronic Cats + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h b/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h new file mode 100644 index 00000000000..f27cb533b26 --- /dev/null +++ b/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h @@ -0,0 +1,34 @@ +#define MICROPY_HW_BOARD_NAME "Escornabot Makech" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_HW_LED_STATUS (&pin_PA02) + +// These are pins not to reset. +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code. +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define CALIBRATE_CRYSTALLESS 1 + +// Explanation of how a user got into safe mode. +#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up" + +#define DEFAULT_I2C_BUS_SCL (&pin_PA08) +#define DEFAULT_I2C_BUS_SDA (&pin_PA09) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA14) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA19) +#define DEFAULT_SPI_BUS_MISO (&pin_PA20) + +#define DEFAULT_UART_BUS_RX (&pin_PA01) +#define DEFAULT_UART_BUS_TX (&pin_PA00) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.mk b/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.mk new file mode 100644 index 00000000000..a2c182e6837 --- /dev/null +++ b/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x1209 +USB_PID = 0xBAB6 +USB_PRODUCT = "Escornabot Makech" +USB_MANUFACTURER = "Electronic Cats" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/escornabot_makech/pins.c b/ports/atmel-samd/boards/escornabot_makech/pins.c new file mode 100644 index 00000000000..d43d254e713 --- /dev/null +++ b/ports/atmel-samd/boards/escornabot_makech/pins.c @@ -0,0 +1,58 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + //LEDs + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA10) }, + + // Buttons + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA03) }, + + + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA01) }, + + // Motors + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA28) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA17) }, + + // Buzzer + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA16) }, + + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA13) }, + + //UART + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA00) }, + + // I2C + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) }, + + // SPI + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA13) }, + + // ESP control + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_CS), MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_GPIO0), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_BUSY), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RESET), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RTS), MP_ROM_PTR(&pin_PA19) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/board.c b/ports/atmel-samd/boards/feather_m0_adalogger/board.c new file mode 100644 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_adalogger/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h new file mode 100644 index 00000000000..eb1b905851a --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h @@ -0,0 +1,27 @@ +// LEDs +#define MICROPY_HW_LED_STATUS (&pin_PA17) + +#define MICROPY_HW_BOARD_NAME "Adafruit Feather M0 Adalogger" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA22) +#define DEFAULT_I2C_BUS_SDA (&pin_PA23) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk new file mode 100644 index 00000000000..a88dbd563ec --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x239A +USB_PID = 0x8015 +USB_PRODUCT = "Feather M0 Adalogger" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/pins.c b/ports/atmel-samd/boards/feather_m0_adalogger/pins.c new file mode 100644 index 00000000000..63d134952bb --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_adalogger/pins.c @@ -0,0 +1,39 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_SD_CD), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_GREEN_LED), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/feather_m0_basic/board.c b/ports/atmel-samd/boards/feather_m0_basic/board.c new file mode 100644 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_basic/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h new file mode 100644 index 00000000000..a16cee0b4c2 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h @@ -0,0 +1,27 @@ +// LEDs +#define MICROPY_HW_LED_STATUS (&pin_PA17) + +#define MICROPY_HW_BOARD_NAME "Adafruit Feather M0 Basic" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk new file mode 100644 index 00000000000..076f1f8ff09 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x239A +USB_PID = 0x8015 +USB_PRODUCT = "Feather M0" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/feather_m0_basic/pins.c b/ports/atmel-samd/boards/feather_m0_basic/pins.c new file mode 100644 index 00000000000..f15ec2e9d65 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_basic/pins.c @@ -0,0 +1,32 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/feather_m0_express/board.c b/ports/atmel-samd/boards/feather_m0_express/board.c new file mode 100644 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_express/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h new file mode 100644 index 00000000000..e6cd1c729bd --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h @@ -0,0 +1,39 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Feather M0 Express" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_HW_LED_STATUS (&pin_PA17) + +#define MICROPY_HW_NEOPIXEL (&pin_PA06) + +#define SPI_FLASH_MOSI_PIN &pin_PA08 +#define SPI_FLASH_MISO_PIN &pin_PA14 +#define SPI_FLASH_SCK_PIN &pin_PA09 +#define SPI_FLASH_CS_PIN &pin_PA13 + +// These are pins not to reset. +#define MICROPY_PORT_A (PORT_PA06) +#define MICROPY_PORT_B ( 0 ) +#define MICROPY_PORT_C ( 0 ) + + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code. +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk new file mode 100644 index 00000000000..5b89f1be4f7 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk @@ -0,0 +1,20 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8023 +USB_PRODUCT = "Feather M0 Express" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" +LONGINT_IMPL = MPZ + +CIRCUITPY_BITBANGIO = 0 +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_I2CSLAVE = 0 + +CFLAGS_INLINE_LIMIT = 60 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/feather_m0_express/pins.c b/ports/atmel-samd/boards/feather_m0_express/pins.c new file mode 100644 index 00000000000..3c4effbe3b7 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_express/pins.c @@ -0,0 +1,33 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/board.c b/ports/atmel-samd/boards/feather_m0_express_crickit/board.c new file mode 100644 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h new file mode 100644 index 00000000000..77146889e5f --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h @@ -0,0 +1,42 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Feather M0 Express with Crickit libraries" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_HW_LED_STATUS (&pin_PA17) + +#define MICROPY_HW_NEOPIXEL (&pin_PA06) + +#define SPI_FLASH_MOSI_PIN &pin_PA08 +#define SPI_FLASH_MISO_PIN &pin_PA14 +#define SPI_FLASH_SCK_PIN &pin_PA09 +#define SPI_FLASH_CS_PIN &pin_PA13 + +// These are pins not to reset. +#define MICROPY_PORT_A (PORT_PA06) +#define MICROPY_PORT_B ( 0 ) +#define MICROPY_PORT_C ( 0 ) + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code. +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 + +// Not connected +#define IGNORE_PIN_PB22 1 +#define IGNORE_PIN_PB23 1 diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk new file mode 100644 index 00000000000..5793d82e559 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk @@ -0,0 +1,28 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8023 +USB_PRODUCT = "Feather M0 Express" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" +LONGINT_IMPL = MPZ + +# Make space for frozen libs +CIRCUITPY_BITBANGIO = 0 +CIRCUITPY_DISPLAYIO = 0 +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_I2CSLAVE = 0 +CIRCUITPY_GAMEPAD = 0 +CFLAGS_INLINE_LIMIT = 50 + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Crickit +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Motor +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_seesaw diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c b/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c new file mode 100644 index 00000000000..3c4effbe3b7 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c @@ -0,0 +1,33 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/board.c b/ports/atmel-samd/boards/feather_m0_rfm69/board.c new file mode 100644 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_rfm69/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h new file mode 100644 index 00000000000..19a51475876 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h @@ -0,0 +1,27 @@ +// LEDs +#define MICROPY_HW_LED_STATUS (&pin_PA17) + +#define MICROPY_HW_BOARD_NAME "Adafruit Feather M0 RFM69" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk new file mode 100644 index 00000000000..83d794d0477 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x239A +USB_PID = 0x8015 +USB_PRODUCT = "Feather M0 RFM69" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/pins.c b/ports/atmel-samd/boards/feather_m0_rfm69/pins.c new file mode 100644 index 00000000000..178f945ad45 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_rfm69/pins.c @@ -0,0 +1,35 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_RFM69_D0), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_RFM69_RST), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_RFM69_CS), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/board.c b/ports/atmel-samd/boards/feather_m0_rfm9x/board.c new file mode 100644 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_rfm9x/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h new file mode 100644 index 00000000000..d3db098e541 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h @@ -0,0 +1,27 @@ +// LEDs +#define MICROPY_HW_LED_STATUS (&pin_PA17) + +#define MICROPY_HW_BOARD_NAME "Adafruit Feather M0 RFM9x" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk new file mode 100644 index 00000000000..a84e14f55fd --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x239A +USB_PID = 0x8015 +USB_PRODUCT = "Feather M0 RFM9x" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c b/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c new file mode 100644 index 00000000000..977cb9fdfed --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c @@ -0,0 +1,35 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_D0), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_RST), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_RFM9X_CS), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/feather_m0_supersized/board.c b/ports/atmel-samd/boards/feather_m0_supersized/board.c new file mode 100644 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_supersized/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h new file mode 100644 index 00000000000..5ad265bf141 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h @@ -0,0 +1,38 @@ +/* Adafruit Feather M0 Express with an 8MB SPI flash instead of the usual 2MB */ + +#define MICROPY_HW_BOARD_NAME "Hacked Feather M0 Express with 8Mbyte SPI flash" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_HW_LED_STATUS (&pin_PA17) + +#define MICROPY_HW_NEOPIXEL (&pin_PA06) + +#define SPI_FLASH_MOSI_PIN &pin_PA08 +#define SPI_FLASH_MISO_PIN &pin_PA14 +#define SPI_FLASH_SCK_PIN &pin_PA09 +#define SPI_FLASH_CS_PIN &pin_PA13 + +// These are pins not to reset. +#define MICROPY_PORT_A (PORT_PA06) +#define MICROPY_PORT_B ( 0 ) +#define MICROPY_PORT_C ( 0 ) + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code. +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk new file mode 100644 index 00000000000..c5fef4373ce --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk @@ -0,0 +1,20 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8023 +USB_PRODUCT = "Feather M0 Supersized" +USB_MANUFACTURER = "Dave Astels" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "S25FL064L" +LONGINT_IMPL = MPZ + +CIRCUITPY_BITBANGIO = 0 +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_I2CSLAVE = 0 + +CFLAGS_INLINE_LIMIT = 60 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/feather_m0_supersized/pins.c b/ports/atmel-samd/boards/feather_m0_supersized/pins.c new file mode 100644 index 00000000000..3c4effbe3b7 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_supersized/pins.c @@ -0,0 +1,33 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/feather_m4_express/board.c b/ports/atmel-samd/boards/feather_m4_express/board.c new file mode 100644 index 00000000000..8096b9b8ea6 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m4_express/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h new file mode 100644 index 00000000000..f65ea8db785 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h @@ -0,0 +1,43 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Feather M4 Express" +#define MICROPY_HW_MCU_NAME "samd51j19" + +#define CIRCUITPY_MCU_FAMILY samd51 + +// Rev E + +#define MICROPY_HW_LED_STATUS (&pin_PA23) +#define MICROPY_HW_NEOPIXEL (&pin_PB03) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// QSPI CS, QSPI SCK and NeoPixel pin +#define MICROPY_PORT_B (PORT_PB03 | PORT_PB10 | PORT_PB11) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define EXTERNAL_FLASH_QSPI_DUAL + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA13) +#define DEFAULT_I2C_BUS_SDA (&pin_PA12) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA17) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB23) +#define DEFAULT_SPI_BUS_MISO (&pin_PB22) + +#define DEFAULT_UART_BUS_RX (&pin_PB17) +#define DEFAULT_UART_BUS_TX (&pin_PB16) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk new file mode 100644 index 00000000000..176ebac82c3 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk @@ -0,0 +1,17 @@ +LD_FILE = boards/samd51x19-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8026 +USB_PRODUCT = "Feather M4 Express" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD51J19A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = GD25Q16C +LONGINT_IMPL = MPZ + +CIRCUITPY_NETWORK = 1 +MICROPY_PY_WIZNET5K = 5500 +CIRCUITPY_PS2IO = 1 diff --git a/ports/atmel-samd/boards/feather_m4_express/pins.c b/ports/atmel-samd/boards/feather_m4_express/pins.c new file mode 100644 index 00000000000..d9496ecfc76 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m4_express/pins.c @@ -0,0 +1,34 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB17) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB17) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB16) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB16) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/feather_radiofruit_zigbee/board.c b/ports/atmel-samd/boards/feather_radiofruit_zigbee/board.c new file mode 100755 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/feather_radiofruit_zigbee/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.h b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.h new file mode 100755 index 00000000000..7df31f3a93e --- /dev/null +++ b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.h @@ -0,0 +1,37 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Feather RadioFruit Zigbee" +#define MICROPY_HW_MCU_NAME "samr21g18" + +#define MICROPY_HW_LED_STATUS (&pin_PA27) +#define MICROPY_HW_NEOPIXEL (&pin_PA22) + +#define SPI_FLASH_MOSI_PIN &pin_PA31 +#define SPI_FLASH_MISO_PIN &pin_PA30 +#define SPI_FLASH_SCK_PIN &pin_PA17 +#define SPI_FLASH_CS_PIN &pin_PA28 + +// These are pins not to reset. +#define MICROPY_PORT_A (PORT_PA22) +#define MICROPY_PORT_B ( 0 ) +#define MICROPY_PORT_C ( 0 ) + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code. +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA13) +#define DEFAULT_I2C_BUS_SDA (&pin_PA12) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB23) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB22) +#define DEFAULT_SPI_BUS_MISO (&pin_PA23) + +#define DEFAULT_UART_BUS_RX (&pin_PA09) +#define DEFAULT_UART_BUS_TX (&pin_PA08) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk new file mode 100755 index 00000000000..c4a3a5a19eb --- /dev/null +++ b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk @@ -0,0 +1,18 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8023 +USB_PRODUCT = "Feather RadioFruit Zigbee" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMR21G18A +CHIP_FAMILY = samd21 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" +LONGINT_IMPL = MPZ + +# No I2S on SAMR21G +CIRCUITPY_AUDIOBUSIO = 0 +# No DAC on SAMR21G +CIRCUITPY_AUDIOIO = 0 diff --git a/ports/atmel-samd/boards/feather_radiofruit_zigbee/pins.c b/ports/atmel-samd/boards/feather_radiofruit_zigbee/pins.c new file mode 100755 index 00000000000..7133978784c --- /dev/null +++ b/ports/atmel-samd/boards/feather_radiofruit_zigbee/pins.c @@ -0,0 +1,45 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + // Internally connected within the package + { MP_ROM_QSTR(MP_QSTR_DIG3), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_DIG4), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_SLP_TR), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_IRQ), MP_ROM_PTR(&pin_PB00) }, + { MP_ROM_QSTR(MP_QSTR_DIG1), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_DIG2), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_RF_MOSI), MP_ROM_PTR(&pin_PB30) }, + { MP_ROM_QSTR(MP_QSTR_SEL), MP_ROM_PTR(&pin_PB31) }, + { MP_ROM_QSTR(MP_QSTR_CLKM), MP_ROM_PTR(&pin_PC16) }, + { MP_ROM_QSTR(MP_QSTR_RF_SCK), MP_ROM_PTR(&pin_PC18) }, + { MP_ROM_QSTR(MP_QSTR_RF_MISO), MP_ROM_PTR(&pin_PC19) }, + { MP_ROM_QSTR(MP_QSTR_RESETN), MP_ROM_PTR(&pin_PB15) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/gemma_m0/board.c b/ports/atmel-samd/boards/gemma_m0/board.c new file mode 100644 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/gemma_m0/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h new file mode 100644 index 00000000000..5f09ab4d2fe --- /dev/null +++ b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h @@ -0,0 +1,69 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Gemma M0" +#define MICROPY_HW_MCU_NAME "samd21e18" + +#define MICROPY_HW_LED_STATUS (&pin_PA23) + +#define MICROPY_HW_APA102_MOSI (&pin_PA00) +#define MICROPY_HW_APA102_SCK (&pin_PA01) + +#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01 | PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA05) +#define DEFAULT_I2C_BUS_SDA (&pin_PA04) + +#define DEFAULT_UART_BUS_RX (&pin_PA05) +#define DEFAULT_UART_BUS_TX (&pin_PA04) + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define IGNORE_PIN_PA03 1 +#define IGNORE_PIN_PA06 1 +#define IGNORE_PIN_PA07 1 +#define IGNORE_PIN_PA08 1 +#define IGNORE_PIN_PA09 1 +#define IGNORE_PIN_PA10 1 +#define IGNORE_PIN_PA11 1 +#define IGNORE_PIN_PA12 1 +#define IGNORE_PIN_PA13 1 +#define IGNORE_PIN_PA14 1 +#define IGNORE_PIN_PA15 1 +#define IGNORE_PIN_PA16 1 +#define IGNORE_PIN_PA17 1 +#define IGNORE_PIN_PA18 1 +#define IGNORE_PIN_PA19 1 +#define IGNORE_PIN_PA20 1 +#define IGNORE_PIN_PA21 1 +#define IGNORE_PIN_PA22 1 +// USB is always used. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 +#define IGNORE_PIN_PA27 1 +#define IGNORE_PIN_PA28 1 +#define IGNORE_PIN_PA30 1 +#define IGNORE_PIN_PA31 1 +#define IGNORE_PIN_PB01 1 +#define IGNORE_PIN_PB02 1 +#define IGNORE_PIN_PB03 1 +#define IGNORE_PIN_PB04 1 +#define IGNORE_PIN_PB05 1 +#define IGNORE_PIN_PB06 1 +#define IGNORE_PIN_PB07 1 +#define IGNORE_PIN_PB08 1 +#define IGNORE_PIN_PB09 1 +#define IGNORE_PIN_PB10 1 +#define IGNORE_PIN_PB11 1 +#define IGNORE_PIN_PB12 1 +#define IGNORE_PIN_PB13 1 +#define IGNORE_PIN_PB14 1 +#define IGNORE_PIN_PB15 1 +#define IGNORE_PIN_PB16 1 +#define IGNORE_PIN_PB17 1 +#define IGNORE_PIN_PB22 1 +#define IGNORE_PIN_PB23 1 +#define IGNORE_PIN_PB30 1 +#define IGNORE_PIN_PB31 1 +#define IGNORE_PIN_PB00 1 diff --git a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk new file mode 100644 index 00000000000..6f44a22f842 --- /dev/null +++ b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x239A +USB_PID = 0x801D +USB_PRODUCT = "Gemma M0" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/gemma_m0/pins.c b/ports/atmel-samd/boards/gemma_m0/pins.c new file mode 100644 index 00000000000..9aecd5d84e3 --- /dev/null +++ b/ports/atmel-samd/boards/gemma_m0/pins.c @@ -0,0 +1,27 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, // pad 1 + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA05) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA04) }, // pad 0 + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA04) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA02) }, + + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23) }, + + { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA01) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/board.c b/ports/atmel-samd/boards/grandcentral_m4_express/board.c new file mode 100644 index 00000000000..7599f02b8ef --- /dev/null +++ b/ports/atmel-samd/boards/grandcentral_m4_express/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h new file mode 100644 index 00000000000..bc8f5a134a8 --- /dev/null +++ b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h @@ -0,0 +1,46 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Grand Central M4 Express" +#define MICROPY_HW_MCU_NAME "samd51p20" + +#define CIRCUITPY_MCU_FAMILY samd51 + +// This is for Rev B which is green and has the SD card slot at the edge of the board. + +#define MICROPY_HW_LED_STATUS (&pin_PB01) + +#define MICROPY_HW_LED_TX &(pin_PC30) +#define MICROPY_HW_LED_RX &(pin_PC31) + +#define MICROPY_HW_NEOPIXEL (&pin_PC24) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A ( PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11 ) +// QSPI CS, and QSPI SCK +#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11 ) +// NeoPixel pin, RX LED, TX LED +#define MICROPY_PORT_C ( PORT_PC24 | PORT_PC30 | PORT_PC31 ) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PB21) +#define DEFAULT_I2C_BUS_SDA (&pin_PB20) + +#define DEFAULT_SPI_BUS_SCK (&pin_PD09) +#define DEFAULT_SPI_BUS_MOSI (&pin_PD08) +#define DEFAULT_SPI_BUS_MISO (&pin_PD11) + +#define DEFAULT_UART_BUS_RX (&pin_PB25) +#define DEFAULT_UART_BUS_TX (&pin_PB24) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk new file mode 100644 index 00000000000..423761c3f7a --- /dev/null +++ b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk @@ -0,0 +1,15 @@ +LD_FILE = boards/samd51x20-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8032 +USB_PRODUCT = "Grand Central M4 Express" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD51P20A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C" +LONGINT_IMPL = MPZ + +CIRCUITPY_PS2IO = 1 diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/pins.c b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c new file mode 100644 index 00000000000..6b09c62bf38 --- /dev/null +++ b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c @@ -0,0 +1,133 @@ +#include "shared-bindings/board/__init__.h" + +// This mapping only includes functional names because pins broken +// out on connectors are labeled with their MCU name available from +// microcontroller.pin. +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_PA03) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PC00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PC01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PC02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PC03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB04) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PB05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PB06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_PB07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_PB09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A13), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A14), MP_ROM_PTR(&pin_PA06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A15), MP_ROM_PTR(&pin_PA07) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB25) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB25) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB24) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB24) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PC18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PC19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PC20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PC21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PD20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PD21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PB23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PB00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB01) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_TX3), MP_ROM_PTR(&pin_PB16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX3), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX2), MP_ROM_PTR(&pin_PC22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_PC22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX2), MP_ROM_PTR(&pin_PC23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_PC23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_PB20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_PB21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB21) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_PD12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_PA15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_PC17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_PC17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_PC16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_PC16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_DEN1), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_DEN2), MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D28), MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_CLK), MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D29), MP_ROM_PTR(&pin_PB19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_XCLK), MP_ROM_PTR(&pin_PB19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D30), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D7), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D31), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D6), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D5), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D4), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D34), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D3), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D2), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D1), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D0), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_PB15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D9), MP_ROM_PTR(&pin_PB15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D8), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D40), MP_ROM_PTR(&pin_PC13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D11), MP_ROM_PTR(&pin_PC13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D41), MP_ROM_PTR(&pin_PC12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D10), MP_ROM_PTR(&pin_PC12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D42), MP_ROM_PTR(&pin_PC15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D13), MP_ROM_PTR(&pin_PC15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_PC14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D12), MP_ROM_PTR(&pin_PC14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D44), MP_ROM_PTR(&pin_PC11) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D45), MP_ROM_PTR(&pin_PC10) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D46), MP_ROM_PTR(&pin_PC06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D47), MP_ROM_PTR(&pin_PC07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D48), MP_ROM_PTR(&pin_PC04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D49), MP_ROM_PTR(&pin_PC05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D50), MP_ROM_PTR(&pin_PD11) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PD11) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D51), MP_ROM_PTR(&pin_PD08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PD08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D52), MP_ROM_PTR(&pin_PD09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PD09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D53), MP_ROM_PTR(&pin_PD10) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_PD10) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_PB26) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_PB27) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PB28) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_PB29) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CARD_DETECT), MP_ROM_PTR(&pin_PB31) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PC24) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), MP_ROM_PTR(&pin_PC31) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), MP_ROM_PTR(&pin_PC30) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/hallowing_m0_express/board.c b/ports/atmel-samd/boards/hallowing_m0_express/board.c new file mode 100644 index 00000000000..b4c54062f62 --- /dev/null +++ b/ports/atmel-samd/boards/hallowing_m0_express/board.c @@ -0,0 +1,119 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/busio/SPI.h" + +#include "tick.h" + +displayio_fourwire_obj_t board_display_obj; + +#define DELAY 0x80 + +uint8_t display_init_sequence[] = { + 0x01, 0 | DELAY, 150, // SWRESET + 0x11, 0 | DELAY, 255, // SLPOUT + 0xb1, 3, 0x01, 0x2C, 0x2D, // _FRMCTR1 + 0xb2, 3, 0x01, 0x2C, 0x2D, // + 0xb3, 6, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, + 0xb4, 1, 0x07, // _INVCTR line inversion + 0xc0, 3, 0xa2, 0x02, 0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA + 0xc1, 1, 0xc5, // _PWCTR2 VGH=14.7V, VGL=-7.35V + 0xc2, 2, 0x0a, 0x00, // _PWCTR3 Opamp current small, Boost frequency + 0xc3, 2, 0x8a, 0x2a, + 0xc4, 2, 0x8a, 0xee, + 0xc5, 1, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V + 0x2a, 0, // _INVOFF + 0x36, 1, 0x18, // _MADCTL bottom to top refresh + // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie, + // fix on VTL + 0x3a, 1, 0x05, // COLMOD - 16bit color + 0xe0, 16, 0x02, 0x1c, 0x07, 0x12, // _GMCTRP1 Gamma + 0x37, 0x32, 0x29, 0x2d, + 0x29, 0x25, 0x2B, 0x39, + 0x00, 0x01, 0x03, 0x10, + 0xe1, 16, 0x03, 0x1d, 0x07, 0x06, // _GMCTRN1 + 0x2E, 0x2C, 0x29, 0x2D, + 0x2E, 0x2E, 0x37, 0x3F, + 0x00, 0x00, 0x02, 0x10, + 0x2a, 3, 0x02, 0x00, 0x81, // _CASET XSTART = 2, XEND = 129 + 0x2b, 3, 0x02, 0x00, 0x81, // _RASET XSTART = 2, XEND = 129 + 0x13, 0 | DELAY, 10, // _NORON + 0x29, 0 | DELAY, 100, // _DISPON +}; + +void board_init(void) { + displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + busio_spi_obj_t *spi = common_hal_board_create_spi(); + common_hal_displayio_fourwire_construct(bus, + spi, + &pin_PA28, // Command or data + &pin_PA01, // Chip select + &pin_PA27, // Reset + 12000000); + + displayio_display_obj_t* display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, + 128, // Width + 128, // Height + 2, // column start + 1, // row start + 0, // rotation + 16, // Color depth + false, // Grayscale + false, // Pixels in a byte share a row. Only used for depth < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + 0x37, // set vertical scroll command + display_init_sequence, + sizeof(display_init_sequence), + &pin_PA00, + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness (ignored) + true, // auto_brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60); // native_frames_per_second +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h new file mode 100644 index 00000000000..d5c2745009a --- /dev/null +++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.h @@ -0,0 +1,41 @@ +#define MICROPY_HW_BOARD_NAME "HalloWing M0 Express" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_HW_LED_STATUS (&pin_PA23) +#define MICROPY_HW_NEOPIXEL (&pin_PA12) + +#define SPI_FLASH_MOSI_PIN &pin_PB10 +#define SPI_FLASH_MISO_PIN &pin_PA13 +#define SPI_FLASH_SCK_PIN &pin_PB11 +#define SPI_FLASH_CS_PIN &pin_PA07 + +// These are pins not to reset. +// NeoPixel and for the display: Reset, Command or data, and Chip select +#define MICROPY_PORT_A ( PORT_PA01 | PORT_PA12 | PORT_PA27 | PORT_PA28) +// Data and Clock for the display +#define MICROPY_PORT_B ( PORT_PB22 | PORT_PB23 ) +#define MICROPY_PORT_C ( 0 ) + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code. +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA17) +#define DEFAULT_I2C_BUS_SDA (&pin_PA16) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB23) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB22) +#define DEFAULT_SPI_BUS_MISO (&pin_PB03) + +#define DEFAULT_UART_BUS_RX (&pin_PA09) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 + +// SWD is only available on the test pads so skip the pin objects. +#define IGNORE_PIN_PA30 1 +#define IGNORE_PIN_PA31 1 diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk new file mode 100644 index 00000000000..988d10d1cda --- /dev/null +++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk @@ -0,0 +1,30 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0xD1ED +USB_PRODUCT = "HalloWing M0 Express" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C" +LONGINT_IMPL = MPZ + +# To keep the build small +CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_BITBANGIO = 0 +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_GAMEPAD = 0 +CIRCUITPY_I2CSLAVE = 0 +CIRCUITPY_ROTARYIO = 0 +CIRCUITPY_RTC = 0 + +CFLAGS_INLINE_LIMIT = 60 +SUPEROPT_GC = 0 + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/atmel-samd/boards/hallowing_m0_express/pins.c b/ports/atmel-samd/boards/hallowing_m0_express/pins.c new file mode 100644 index 00000000000..3e670a676f2 --- /dev/null +++ b/ports/atmel-samd/boards/hallowing_m0_express/pins.c @@ -0,0 +1,67 @@ +#include "shared-bindings/board/__init__.h" + +#include "boards/board.h" +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_PB08) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH4), MP_ROM_PTR(&pin_PB09) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH3), MP_ROM_PTR(&pin_PA04) }, + + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH2), MP_ROM_PTR(&pin_PA05) }, + + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH1), MP_ROM_PTR(&pin_PA06) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB03) }, + + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA17) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23) }, + + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_EXTERNAL_NEOPIXEL), MP_ROM_PTR(&pin_PA08) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA12) }, + + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_SENSE), MP_ROM_PTR(&pin_PA11) }, + + { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_PA28) }, + { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_PA27) }, + + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_PA14) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/hallowing_m4_express/board.c b/ports/atmel-samd/boards/hallowing_m4_express/board.c new file mode 100644 index 00000000000..6bb2a591f0f --- /dev/null +++ b/ports/atmel-samd/boards/hallowing_m4_express/board.c @@ -0,0 +1,99 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "tick.h" + +displayio_fourwire_obj_t board_display_obj; + +#define DELAY 0x80 + +uint8_t display_init_sequence[] = { + 0x01, 0 | DELAY, 150, // SWRESET + 0x11, 0 | DELAY, 255, // SLPOUT + 0x36, 1, 0x00, // _MADCTL bottom to top refresh in vsync aligned order. + 0x3a, 1, 0x55, // COLMOD - 16bit color + 0x21, 0 | DELAY, 10, // _INVON + 0x13, 0 | DELAY, 10, // _NORON + 0x29, 0 | DELAY, 255, // _DISPON +}; + +void board_init(void) { + busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; + common_hal_busio_spi_construct(spi, &pin_PA01, &pin_PA00, NULL); + common_hal_busio_spi_never_reset(spi); + + displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + common_hal_displayio_fourwire_construct(bus, + spi, + &pin_PB31, // TFT_DC Command or data + &pin_PA27, // TFT_CS Chip select + &pin_PB30, // TFT_RST Reset + 60000000); + + displayio_display_obj_t* display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, + 240, // Width (after rotation) + 240, // Height (after rotation) + 0, // column start + 0, // row start + 180, // rotation + 16, // Color depth + false, // Grayscale + false, // Pixels in a byte share a row. Only used for depth < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + 0x37, // set vertical scroll command + display_init_sequence, + sizeof(display_init_sequence), + &pin_PB14, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness (ignored) + true, // auto_brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60); // native_frames_per_second +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.h new file mode 100644 index 00000000000..654632db5d7 --- /dev/null +++ b/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.h @@ -0,0 +1,39 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Hallowing M4 Express" +#define MICROPY_HW_MCU_NAME "samd51j19" + +#define CIRCUITPY_MCU_FAMILY samd51 + +// Rev C + +#define MICROPY_HW_LED_STATUS (&pin_PA23) +#define MICROPY_HW_NEOPIXEL (&pin_PB16) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// NeoPixel pin, QSPI CS, and QSPI SCK +#define MICROPY_PORT_B (PORT_PB16 | PORT_PB10 | PORT_PB11) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA13) +#define DEFAULT_I2C_BUS_SDA (&pin_PA12) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA22) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB23) +#define DEFAULT_SPI_BUS_MISO (&pin_PB22) + +#define DEFAULT_UART_BUS_RX (&pin_PB12) +#define DEFAULT_UART_BUS_TX (&pin_PB13) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk new file mode 100644 index 00000000000..0d891abc82a --- /dev/null +++ b/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk @@ -0,0 +1,17 @@ +LD_FILE = boards/samd51x19-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x804A +USB_PRODUCT = "Hallowing M4 Express" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD51J19A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = GD25Q64C +LONGINT_IMPL = MPZ + +CIRCUITPY_NETWORK = 1 +MICROPY_PY_WIZNET5K = 5500 +CIRCUITPY_PS2IO = 1 diff --git a/ports/atmel-samd/boards/hallowing_m4_express/pins.c b/ports/atmel-samd/boards/hallowing_m4_express/pins.c new file mode 100644 index 00000000000..915802d1d6a --- /dev/null +++ b/ports/atmel-samd/boards/hallowing_m4_express/pins.c @@ -0,0 +1,55 @@ +#include "shared-bindings/board/__init__.h" + +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_PB04) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB04) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB12) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB12) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB13) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB13) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_PB15) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB15) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB16) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB16) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PB01) }, + + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_EXTERNAL_NEOPIXEL), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_SENSE), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PB03) }, + + { MP_ROM_QSTR(MP_QSTR_SPEAKER_ENABLE), MP_ROM_PTR(&pin_PB05) }, + { MP_ROM_QSTR(MP_QSTR_CAP_PIN), MP_ROM_PTR(&pin_PA15) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/board.c b/ports/atmel-samd/boards/itsybitsy_m0_express/board.c new file mode 100644 index 00000000000..d7e856d6119 --- /dev/null +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/board.c @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h new file mode 100644 index 00000000000..6f9f661d944 --- /dev/null +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h @@ -0,0 +1,41 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit ItsyBitsy M0 Express" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_HW_LED_STATUS (&pin_PA17) + +#define MICROPY_HW_APA102_MOSI (&pin_PA01) +#define MICROPY_HW_APA102_SCK (&pin_PA00) + +#define SPI_FLASH_MOSI_PIN &pin_PB22 +#define SPI_FLASH_MISO_PIN &pin_PB03 +#define SPI_FLASH_SCK_PIN &pin_PB23 +#define SPI_FLASH_CS_PIN &pin_PA27 + +// These are pins not to reset. +#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code. +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 + +// Not connected +#define IGNORE_PIN_PA13 1 +#define IGNORE_PIN_PA28 1 diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk new file mode 100644 index 00000000000..2b64e902751 --- /dev/null +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk @@ -0,0 +1,24 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash-crystalless.ld +USB_VID = 0x239A +USB_PID = 0x8012 +USB_PRODUCT = "ItsyBitsy M0 Express" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "W25Q16FW, GD25Q16C" +LONGINT_IMPL = MPZ + +CIRCUITPY_BITBANG_APA102 = 1 + +CIRCUITPY_BITBANGIO = 0 +CIRCUITPY_GAMEPAD = 0 +CIRCUITPY_I2CSLAVE = 0 +CIRCUITPY_RTC = 0 + +CFLAGS_INLINE_LIMIT = 60 +SUPEROPT_GC = 0 + diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c b/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c new file mode 100644 index 00000000000..1b0e5d09ebe --- /dev/null +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c @@ -0,0 +1,45 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_PA17) }, // a.k.a D13 + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + + { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/board.c b/ports/atmel-samd/boards/itsybitsy_m4_express/board.c new file mode 100644 index 00000000000..0f60736a240 --- /dev/null +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h new file mode 100644 index 00000000000..9e4d4a10c96 --- /dev/null +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h @@ -0,0 +1,40 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit ItsyBitsy M4 Express" +#define MICROPY_HW_MCU_NAME "samd51g19" + +#define CIRCUITPY_MCU_FAMILY samd51 + +// This is for Rev B +#define MICROPY_HW_LED_STATUS (&pin_PA22) + +#define MICROPY_HW_APA102_MOSI (&pin_PB03) +#define MICROPY_HW_APA102_SCK (&pin_PB02) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// DotStar pins, QSPI CS, and QSPI SCK +#define MICROPY_PORT_B (PORT_PB02 | PORT_PB03 | PORT_PB10 | PORT_PB11) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA13) +#define DEFAULT_I2C_BUS_SDA (&pin_PA12) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA01) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA00) +#define DEFAULT_SPI_BUS_MISO (&pin_PB23) + +#define DEFAULT_UART_BUS_RX (&pin_PA16) +#define DEFAULT_UART_BUS_TX (&pin_PA17) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk new file mode 100644 index 00000000000..5cab5bf43ad --- /dev/null +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk @@ -0,0 +1,19 @@ +LD_FILE = boards/samd51x19-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x802C +USB_PRODUCT = "ItsyBitsy M4 Express" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD51G19A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = GD25Q16C +LONGINT_IMPL = MPZ + +CIRCUITPY_PS2IO = 1 +# No I2S on SAMD51G +CIRCUITPY_AUDIOBUSIO = 0 + +CIRCUITPY_BITBANG_APA102 = 1 diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c b/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c new file mode 100644 index 00000000000..8cd2f44f893 --- /dev/null +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c @@ -0,0 +1,42 @@ +#include "shared-bindings/board/__init__.h" + +// This mapping only includes functional names because pins broken +// out on connectors are labeled with their MCU name available from +// microcontroller.pin. +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA22) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA13) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB23) }, + + { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/kicksat-sprite/board.c b/ports/atmel-samd/boards/kicksat-sprite/board.c new file mode 100644 index 00000000000..fc53f396753 --- /dev/null +++ b/ports/atmel-samd/boards/kicksat-sprite/board.c @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "boards/board.h" +#include "py/mpconfig.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} \ No newline at end of file diff --git a/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.h b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.h new file mode 100644 index 00000000000..194542b0559 --- /dev/null +++ b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.h @@ -0,0 +1,30 @@ + +#define MICROPY_HW_BOARD_NAME "Sprite_v2b" +#define MICROPY_HW_MCU_NAME "samd51G19" +#define CIRCUITPY_MCU_FAMILY samd51 + +#define MICROPY_HW_LED_STATUS (&pin_PB03) + +#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define CALIBRATE_CRYSTALLESS 1 + +#define CIRCUITPY_INTERNAL_NVM_SIZE 0 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - 0x010000) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA17) +#define DEFAULT_I2C_BUS_SDA (&pin_PA16) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA05) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA07) +#define DEFAULT_SPI_BUS_MISO (&pin_PA04) + +#define DEFAULT_UART_BUS_TX (&pin_PB09) +#define DEFAULT_UART_BUS_RX (&pin_PB08) + +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk new file mode 100644 index 00000000000..706e551c5dd --- /dev/null +++ b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk @@ -0,0 +1,16 @@ +LD_FILE = boards/samd51x19-bootloader.ld +USB_VID = 0x04D8 +USB_PID = 0xED94 +USB_PRODUCT = "kicksat-sprite" +USB_MANUFACTURER = "maholli" + +CHIP_VARIANT = SAMD51G19A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 0 +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = MPZ + +# Not needed. +CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_DISPLAYIO = 0 diff --git a/ports/atmel-samd/boards/kicksat-sprite/pins.c b/ports/atmel-samd/boards/kicksat-sprite/pins.c new file mode 100644 index 00000000000..03af22ff26b --- /dev/null +++ b/ports/atmel-samd/boards/kicksat-sprite/pins.c @@ -0,0 +1,38 @@ +#include "shared-bindings/board/__init__.h" +#include "boards/board.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA04) }, + + { MP_ROM_QSTR(MP_QSTR_radioCS), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_WAKE), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_SHDWN), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_PWDWN), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_TST), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_FSYNC), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_VCLK), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_FSYNC), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_MD), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_MC), MP_ROM_PTR(&pin_PA19) }, + + { MP_ROM_QSTR(MP_QSTR_PA08), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_PA10), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_PA09), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_PA06), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_DAC0), MP_ROM_PTR(&pin_PA02) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA17) }, + + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB03) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); \ No newline at end of file diff --git a/ports/atmel-samd/boards/meowmeow/board.c b/ports/atmel-samd/boards/meowmeow/board.c new file mode 100644 index 00000000000..881e15e0c5e --- /dev/null +++ b/ports/atmel-samd/boards/meowmeow/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Andrés Sabas for Electronic Cats + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/meowmeow/mpconfigboard.h b/ports/atmel-samd/boards/meowmeow/mpconfigboard.h new file mode 100644 index 00000000000..1304b6dfbfe --- /dev/null +++ b/ports/atmel-samd/boards/meowmeow/mpconfigboard.h @@ -0,0 +1,34 @@ +#define MICROPY_HW_BOARD_NAME "Meow Meow" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_HW_LED_STATUS (&pin_PB23) + +// These are pins not to reset. +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code. +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define CALIBRATE_CRYSTALLESS 1 + +// Explanation of how a user got into safe mode. +#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up" + +#define DEFAULT_I2C_BUS_SCL (&pin_PA01) +#define DEFAULT_I2C_BUS_SDA (&pin_PA00) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA15) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA14) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/meowmeow/mpconfigboard.mk b/ports/atmel-samd/boards/meowmeow/mpconfigboard.mk new file mode 100644 index 00000000000..894e19a6bb6 --- /dev/null +++ b/ports/atmel-samd/boards/meowmeow/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x1209 +USB_PID = 0xBAB1 +USB_PRODUCT = "Meow Meow" +USB_MANUFACTURER = "Electronic Cats" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/meowmeow/pins.c b/ports/atmel-samd/boards/meowmeow/pins.c new file mode 100644 index 00000000000..41d122d8749 --- /dev/null +++ b/ports/atmel-samd/boards/meowmeow/pins.c @@ -0,0 +1,41 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA30) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA31) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/metro_m0_express/board.c b/ports/atmel-samd/boards/metro_m0_express/board.c new file mode 100644 index 00000000000..bd63baa6fd5 --- /dev/null +++ b/ports/atmel-samd/boards/metro_m0_express/board.c @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" + +void board_init(void) +{ + // struct port_config pin_conf; + // port_get_config_defaults(&pin_conf); + // + // pin_conf.direction = PORT_PIN_DIR_OUTPUT; + // port_pin_set_config(MICROPY_HW_LED_TX, &pin_conf); + // port_pin_set_output_level(MICROPY_HW_LED_TX, true); + // + // port_pin_set_config(MICROPY_HW_LED_RX, &pin_conf); + // port_pin_set_output_level(MICROPY_HW_LED_RX, true); +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h new file mode 100644 index 00000000000..bfa254b95e2 --- /dev/null +++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h @@ -0,0 +1,44 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Metro M0 Express" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_HW_LED_STATUS (&pin_PA17) +#define MICROPY_HW_LED_TX &pin_PA27 +// Comment this out if you have trouble connecting over SWD. It's one of the SWD pins. +#define MICROPY_HW_LED_RX &pin_PA31 + +#define MICROPY_HW_NEOPIXEL (&pin_PA30) + +// Clock rates are off: Salae reads 12MHz which is the limit even though we set it to the safer 8MHz. +#define SPI_FLASH_BAUDRATE (8000000) + +#define SPI_FLASH_MOSI_PIN &pin_PB22 +#define SPI_FLASH_MISO_PIN &pin_PB03 +#define SPI_FLASH_SCK_PIN &pin_PB23 +#define SPI_FLASH_CS_PIN &pin_PA13 + +// These are pins not to reset. +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code. +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk new file mode 100644 index 00000000000..d3f35ba8b06 --- /dev/null +++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk @@ -0,0 +1,19 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8014 +USB_PRODUCT = "Metro M0 Express" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" +LONGINT_IMPL = MPZ + +CIRCUITPY_BITBANGIO = 0 +CIRCUITPY_I2CSLAVE = 0 + +CFLAGS_INLINE_LIMIT = 60 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/metro_m0_express/pins.c b/ports/atmel-samd/boards/metro_m0_express/pins.c new file mode 100644 index 00000000000..c11fac5ce68 --- /dev/null +++ b/ports/atmel-samd/boards/metro_m0_express/pins.c @@ -0,0 +1,36 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA30) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/metro_m4_airlift_lite/board.c b/ports/atmel-samd/boards/metro_m4_airlift_lite/board.c new file mode 100644 index 00000000000..0f60736a240 --- /dev/null +++ b/ports/atmel-samd/boards/metro_m4_airlift_lite/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.h b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.h new file mode 100644 index 00000000000..e89b0322a12 --- /dev/null +++ b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.h @@ -0,0 +1,43 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Metro M4 Airlift Lite" +#define MICROPY_HW_MCU_NAME "samd51j19" + +#define CIRCUITPY_MCU_FAMILY samd51 + +#define MICROPY_HW_LED_TX (&pin_PB07) +#define MICROPY_HW_LED_RX (&pin_PB06) + +#define MICROPY_HW_LED_STATUS (&pin_PA16) + +#define MICROPY_HW_NEOPIXEL (&pin_PB22) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// QSPI CS, QSPI SCK and NeoPixel pin +#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11 | PORT_PB22) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PB03) +#define DEFAULT_I2C_BUS_SDA (&pin_PB02) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA13) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA12) +#define DEFAULT_SPI_BUS_MISO (&pin_PA14) + +#define DEFAULT_UART_BUS_RX (&pin_PA23) +#define DEFAULT_UART_BUS_TX (&pin_PA22) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk new file mode 100644 index 00000000000..98d85ba826f --- /dev/null +++ b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk @@ -0,0 +1,17 @@ +LD_FILE = boards/samd51x19-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8038 +USB_PRODUCT = "Metro M4 Airlift Lite" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD51J19A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 3 +EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C" +LONGINT_IMPL = MPZ + +CIRCUITPY_NETWORK = 1 +MICROPY_PY_WIZNET5K = 5500 +CIRCUITPY_PS2IO = 1 diff --git a/ports/atmel-samd/boards/metro_m4_airlift_lite/pins.c b/ports/atmel-samd/boards/metro_m4_airlift_lite/pins.c new file mode 100644 index 00000000000..4e90870c49e --- /dev/null +++ b/ports/atmel-samd/boards/metro_m4_airlift_lite/pins.c @@ -0,0 +1,55 @@ +#include "shared-bindings/board/__init__.h" + +// This mapping only includes functional names because pins broken +// out on connectors are labeled with their MCU name available from +// microcontroller.pin. +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB09) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA16) }, + + // ESP control + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_CS), MP_ROM_PTR(&pin_PA15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_GPIO0), MP_ROM_PTR(&pin_PB01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_BUSY), MP_ROM_PTR(&pin_PB04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RESET), MP_ROM_PTR(&pin_PB05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RTS), MP_ROM_PTR(&pin_PB23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_TX), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RX), MP_ROM_PTR(&pin_PA07) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PB03) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_PB22) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA14) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX),MP_ROM_PTR(&pin_PB06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX),MP_ROM_PTR(&pin_PB07) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/metro_m4_express/board.c b/ports/atmel-samd/boards/metro_m4_express/board.c new file mode 100644 index 00000000000..0f60736a240 --- /dev/null +++ b/ports/atmel-samd/boards/metro_m4_express/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h new file mode 100644 index 00000000000..2a8878874df --- /dev/null +++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h @@ -0,0 +1,45 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Metro M4 Express" +#define MICROPY_HW_MCU_NAME "samd51j19" + +#define CIRCUITPY_MCU_FAMILY samd51 + +// This is for Rev F which is green + +#define MICROPY_HW_LED_TX (&pin_PA27) +#define MICROPY_HW_LED_RX (&pin_PB06) + +#define MICROPY_HW_LED_STATUS (&pin_PA16) + +#define MICROPY_HW_NEOPIXEL (&pin_PB22) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// QSPI CS, QSPI SCK and NeoPixel pin +#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11 | PORT_PB22) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PB03) +#define DEFAULT_I2C_BUS_SDA (&pin_PB02) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA13) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA12) +#define DEFAULT_SPI_BUS_MISO (&pin_PA14) + +#define DEFAULT_UART_BUS_RX (&pin_PA23) +#define DEFAULT_UART_BUS_TX (&pin_PA22) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk new file mode 100644 index 00000000000..68b6f640651 --- /dev/null +++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk @@ -0,0 +1,17 @@ +LD_FILE = boards/samd51x19-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8021 +USB_PRODUCT = "Metro M4 Express" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD51J19A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 3 +EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C" +LONGINT_IMPL = MPZ + +CIRCUITPY_NETWORK = 1 +MICROPY_PY_WIZNET5K = 5500 +CIRCUITPY_PS2IO = 1 diff --git a/ports/atmel-samd/boards/metro_m4_express/pins.c b/ports/atmel-samd/boards/metro_m4_express/pins.c new file mode 100644 index 00000000000..4eb26dd21bb --- /dev/null +++ b/ports/atmel-samd/boards/metro_m4_express/pins.c @@ -0,0 +1,46 @@ +#include "shared-bindings/board/__init__.h" + +// This mapping only includes functional names because pins broken +// out on connectors are labeled with their MCU name available from +// microcontroller.pin. +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB09) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA16) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PB03) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_PB22) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA14) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX),MP_ROM_PTR(&pin_PB06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX),MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/mini_sam_m4/board.c b/ports/atmel-samd/boards/mini_sam_m4/board.c new file mode 100644 index 00000000000..0f60736a240 --- /dev/null +++ b/ports/atmel-samd/boards/mini_sam_m4/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.h b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.h new file mode 100644 index 00000000000..c4563964f82 --- /dev/null +++ b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.h @@ -0,0 +1,40 @@ +#define MICROPY_HW_BOARD_NAME "Mini SAM M4" +#define MICROPY_HW_MCU_NAME "samd51g19" + +#define CIRCUITPY_MCU_FAMILY samd51 + +#define MICROPY_HW_LED_STATUS (&pin_PA15) + +// RGB Status LED Pins +#define MICROPY_HW_APA102_MOSI (&pin_PB03) +#define MICROPY_HW_APA102_SCK (&pin_PB02) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// RGB Status LED pins, QSPI CS, and QSPI SCK +#define MICROPY_PORT_B (PORT_PB02 | PORT_PB03 | PORT_PB10 | PORT_PB11) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA13) +#define DEFAULT_I2C_BUS_SDA (&pin_PA12) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA01) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB22) +#define DEFAULT_SPI_BUS_MISO (&pin_PB23) + +#define DEFAULT_UART_BUS_RX (&pin_PA16) +#define DEFAULT_UART_BUS_TX (&pin_PA17) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk new file mode 100644 index 00000000000..4bd1d6e522f --- /dev/null +++ b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk @@ -0,0 +1,19 @@ +LD_FILE = boards/samd51x19-bootloader-external-flash.ld +USB_VID = 0x1209 +USB_PID = 0x2017 +USB_PRODUCT = "Mini SAM M4" +USB_MANUFACTURER = "Benjamin Shockley" + +CHIP_VARIANT = SAMD51G19A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "W25Q16JV_IM" +LONGINT_IMPL = MPZ + +CIRCUITPY_PS2IO = 1 +# No I2S on SAMD51G +CIRCUITPY_AUDIOBUSIO = 0 + +CIRCUITPY_BITBANG_APA102 = 1 diff --git a/ports/atmel-samd/boards/mini_sam_m4/pins.c b/ports/atmel-samd/boards/mini_sam_m4/pins.c new file mode 100644 index 00000000000..b1d8d5325cc --- /dev/null +++ b/ports/atmel-samd/boards/mini_sam_m4/pins.c @@ -0,0 +1,42 @@ +#include "shared-bindings/board/__init__.h" + +// This mapping only includes functional names because pins broken +// out on connectors are labeled with their MCU name available from +// microcontroller.pin. +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PA07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_PA03) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_PA00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA15) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA13) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB23) }, + + { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/monster_m4sk/board.c b/ports/atmel-samd/boards/monster_m4sk/board.c new file mode 100644 index 00000000000..2377f4a9da2 --- /dev/null +++ b/ports/atmel-samd/boards/monster_m4sk/board.c @@ -0,0 +1,100 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "tick.h" + +displayio_fourwire_obj_t board_display_obj; + +#define DELAY 0x80 + +uint8_t display_init_sequence[] = { + 0x01, 0 | DELAY, 150, // SWRESET + 0x11, 0 | DELAY, 255, // SLPOUT + 0x36, 1, 0x00, // _MADCTL bottom to top refresh in vsync aligned order. + 0x3a, 1, 0x55, // COLMOD - 16bit color + 0x38, 0, // Idle mode off + 0x21, 0, // _INVON + 0x13, 0, // _NORON + 0x29, 0 | DELAY, 255 // _DISPON +}; + +void board_init(void) { + busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; + common_hal_busio_spi_construct(spi, &pin_PA13, &pin_PA12, NULL); + common_hal_busio_spi_never_reset(spi); + + displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + common_hal_displayio_fourwire_construct(bus, + spi, + &pin_PA07, // TFT_DC Command or data + &pin_PA06, // TFT_CS Chip select + &pin_PA04, // TFT_RST Reset + 60000000); + + displayio_display_obj_t* display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, + 240, // Width (after rotation) + 240, // Height (after rotation) + 0, // column start + 0, // row start + 180, // rotation + 16, // Color depth + false, // Grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + 0x37, // set vertical scroll command + display_init_sequence, + sizeof(display_init_sequence), + &pin_PA23, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness (ignored) + true, // auto_brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60); // native_frames_per_second +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/monster_m4sk/mpconfigboard.h b/ports/atmel-samd/boards/monster_m4sk/mpconfigboard.h new file mode 100644 index 00000000000..fc77520f5f5 --- /dev/null +++ b/ports/atmel-samd/boards/monster_m4sk/mpconfigboard.h @@ -0,0 +1,29 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Monster M4SK" +#define MICROPY_HW_MCU_NAME "samd51j19" + +#define CIRCUITPY_MCU_FAMILY samd51 + +#define MICROPY_HW_LED_STATUS (&pin_PA27) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// DotStar pins, QSPI CS, and QSPI SCK +#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA01) +#define DEFAULT_I2C_BUS_SDA (&pin_PA00) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/monster_m4sk/mpconfigboard.mk b/ports/atmel-samd/boards/monster_m4sk/mpconfigboard.mk new file mode 100644 index 00000000000..534b7468f4b --- /dev/null +++ b/ports/atmel-samd/boards/monster_m4sk/mpconfigboard.mk @@ -0,0 +1,18 @@ +LD_FILE = boards/samd51x19-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8048 +USB_PRODUCT = "Monster M4SK" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD51J19A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = GD25Q64C +LONGINT_IMPL = MPZ + +CIRCUITPY_AUDIOIO = 1 +CIRCUITPY_DISPLAYIO = 1 +# No touch on SAMD51 yet +CIRCUITPY_TOUCHIO = 0 diff --git a/ports/atmel-samd/boards/monster_m4sk/pins.c b/ports/atmel-samd/boards/monster_m4sk/pins.c new file mode 100644 index 00000000000..11f9a063fc1 --- /dev/null +++ b/ports/atmel-samd/boards/monster_m4sk/pins.c @@ -0,0 +1,48 @@ +#include "shared-bindings/board/__init__.h" + +#include "boards/board.h" +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_HEADPHONE_LEFT), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_HEADPHONE_RIGHT), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_NOSE), MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA27) }, + + // I2C + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA01) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_PA22) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER_ENABLE), MP_ROM_PTR(&pin_PA14) }, + + { MP_ROM_QSTR(MP_QSTR_MICROPHONE_CLOCK), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_MICROPHONE_DATA), MP_ROM_PTR(&pin_PA17) }, + + // Right TFT control pins + { MP_OBJ_NEW_QSTR(MP_QSTR_RIGHT_TFT_LITE), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RIGHT_TFT_MOSI), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RIGHT_TFT_SCK), MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RIGHT_TFT_RST), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_RIGHT_TFT_CS), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_RIGHT_TFT_DC), MP_ROM_PTR(&pin_PA07) }, + + // Left TFT control pins. Some pins are attached through the SeeSaw chip. + { MP_OBJ_NEW_QSTR(MP_QSTR_LEFT_TFT_MOSI), MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LEFT_TFT_SCK), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_LEFT_TFT_CS), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_LEFT_TFT_DC), MP_ROM_PTR(&pin_PB22) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}, + { MP_ROM_QSTR(MP_QSTR_RIGHT_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/pewpew10/board.c b/ports/atmel-samd/boards/pewpew10/board.c new file mode 100644 index 00000000000..d7e856d6119 --- /dev/null +++ b/ports/atmel-samd/boards/pewpew10/board.c @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/pewpew10/mpconfigboard.h b/ports/atmel-samd/boards/pewpew10/mpconfigboard.h new file mode 100644 index 00000000000..445ccc4355c --- /dev/null +++ b/ports/atmel-samd/boards/pewpew10/mpconfigboard.h @@ -0,0 +1,50 @@ +#define MICROPY_HW_BOARD_NAME "PewPew 10.2" +#define MICROPY_HW_MCU_NAME "samd21e18" + +#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + + +#define IGNORE_PIN_PB00 1 +#define IGNORE_PIN_PB01 1 +#define IGNORE_PIN_PB02 1 +#define IGNORE_PIN_PB03 1 +#define IGNORE_PIN_PB04 1 +#define IGNORE_PIN_PB05 1 +#define IGNORE_PIN_PB06 1 +#define IGNORE_PIN_PB07 1 +#define IGNORE_PIN_PB08 1 +#define IGNORE_PIN_PB09 1 +#define IGNORE_PIN_PB10 1 +#define IGNORE_PIN_PB11 1 +#define IGNORE_PIN_PB12 1 +#define IGNORE_PIN_PB13 1 +#define IGNORE_PIN_PB14 1 +#define IGNORE_PIN_PB15 1 +#define IGNORE_PIN_PB16 1 +#define IGNORE_PIN_PB17 1 +#define IGNORE_PIN_PB22 1 +#define IGNORE_PIN_PB23 1 +#define IGNORE_PIN_PB30 1 +#define IGNORE_PIN_PB31 1 + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 + +// Default protocol pins. + +#define DEFAULT_I2C_BUS_SCL (&pin_PA01) +#define DEFAULT_I2C_BUS_SDA (&pin_PA00) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA31) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA30) +#define DEFAULT_SPI_BUS_MISO (&pin_PA04) + +#define DEFAULT_UART_BUS_RX (&pin_PA01) +#define DEFAULT_UART_BUS_TX (&pin_PA00) diff --git a/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk b/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk new file mode 100644 index 00000000000..e24a290519d --- /dev/null +++ b/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk @@ -0,0 +1,25 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x239A +USB_PID = 0x801D +USB_PRODUCT = "PewPew 10.2" +USB_MANUFACTURER = "Radomir Dopieralski" + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +CIRCUITPY_PEW = 1 +CIRCUITPY_ANALOGIO = 1 +CIRCUITPY_MATH = 1 +CIRCUITPY_NEOPIXEL_WRITE = 1 +CIRCUITPY_ROTARYIO = 0 +CIRCUITPY_RTC = 0 +CIRCUITPY_SAMD = 0 +CIRCUITPY_USB_MIDI = 0 + +SUPEROPT_GC = 0 + +FROZEN_MPY_DIRS += $(TOP)/frozen/pew-pewpew-standalone-10.x diff --git a/ports/atmel-samd/boards/pewpew10/pins.c b/ports/atmel-samd/boards/pewpew10/pins.c new file mode 100644 index 00000000000..9e5b9d98ecb --- /dev/null +++ b/ports/atmel-samd/boards/pewpew10/pins.c @@ -0,0 +1,51 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + // Pins for internal use. + { MP_ROM_QSTR(MP_QSTR__R1), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR__R2), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR__R3), MP_ROM_PTR(&pin_PA28) }, + { MP_ROM_QSTR(MP_QSTR__R4), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR__R5), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR__R6), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR__R7), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR__R8), MP_ROM_PTR(&pin_PA22) }, + + { MP_ROM_QSTR(MP_QSTR__C8), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR__C7), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR__C6), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR__C5), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR__C4), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR__C3), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR__C2), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR__C1), MP_ROM_PTR(&pin_PA15) }, + + { MP_ROM_QSTR(MP_QSTR__BUTTONS), MP_ROM_PTR(&pin_PA08) }, + + // User pins. + { MP_ROM_QSTR(MP_QSTR_P1), MP_ROM_PTR(&pin_PA30) }, + { MP_ROM_QSTR(MP_QSTR_P2), MP_ROM_PTR(&pin_PA31) }, + { MP_ROM_QSTR(MP_QSTR_P3), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_P4), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_P5), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_P6), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_P7), MP_ROM_PTR(&pin_PA04) }, + + // Protocol aliases. + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA01) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA01) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA30) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA31) }, + + { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&pin_PA02) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/pirkey_m0/board.c b/ports/atmel-samd/boards/pirkey_m0/board.c new file mode 100644 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/pirkey_m0/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.h b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.h new file mode 100644 index 00000000000..5a8eb9d1477 --- /dev/null +++ b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.h @@ -0,0 +1,62 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit pIRKey M0" +#define MICROPY_HW_MCU_NAME "samd21e18" + +#define MICROPY_HW_APA102_MOSI (&pin_PA00) +#define MICROPY_HW_APA102_SCK (&pin_PA01) + +#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01 | PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define IGNORE_PIN_PA02 1 +#define IGNORE_PIN_PA03 1 +#define IGNORE_PIN_PA04 1 +#define IGNORE_PIN_PA05 1 +#define IGNORE_PIN_PA06 1 +#define IGNORE_PIN_PA07 1 +#define IGNORE_PIN_PA08 1 +#define IGNORE_PIN_PA09 1 +#define IGNORE_PIN_PA10 1 +#define IGNORE_PIN_PA11 1 +#define IGNORE_PIN_PA12 1 +#define IGNORE_PIN_PA13 1 +#define IGNORE_PIN_PA14 1 +#define IGNORE_PIN_PA15 1 +#define IGNORE_PIN_PA16 1 +#define IGNORE_PIN_PA17 1 +#define IGNORE_PIN_PA18 1 +#define IGNORE_PIN_PA19 1 +#define IGNORE_PIN_PA20 1 +#define IGNORE_PIN_PA21 1 +#define IGNORE_PIN_PA22 1 +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 +#define IGNORE_PIN_PA27 1 +#define IGNORE_PIN_PA30 1 +#define IGNORE_PIN_PA31 1 +#define IGNORE_PIN_PB00 1 +#define IGNORE_PIN_PB01 1 +#define IGNORE_PIN_PB02 1 +#define IGNORE_PIN_PB03 1 +#define IGNORE_PIN_PB04 1 +#define IGNORE_PIN_PB05 1 +#define IGNORE_PIN_PB06 1 +#define IGNORE_PIN_PB07 1 +#define IGNORE_PIN_PB08 1 +#define IGNORE_PIN_PB09 1 +#define IGNORE_PIN_PB10 1 +#define IGNORE_PIN_PB11 1 +#define IGNORE_PIN_PB12 1 +#define IGNORE_PIN_PB13 1 +#define IGNORE_PIN_PB14 1 +#define IGNORE_PIN_PB15 1 +#define IGNORE_PIN_PB16 1 +#define IGNORE_PIN_PB17 1 +#define IGNORE_PIN_PB22 1 +#define IGNORE_PIN_PB23 1 +#define IGNORE_PIN_PB30 1 +#define IGNORE_PIN_PB31 1 diff --git a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk new file mode 100644 index 00000000000..686c9099fc9 --- /dev/null +++ b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk @@ -0,0 +1,31 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x239A +USB_PID = 0x8028 +USB_PRODUCT = "pIRKey M0" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE + +# A number of modules are removed for pIRKey to make room for frozen libraries. +# Many I/O functions are not available. +# math is very large and is also removed. +CIRCUITPY_ANALOGIO = 0 +CIRCUITPY_MATH = 0 +CIRCUITPY_NEOPIXEL_WRITE = 0 +CIRCUITPY_ROTARYIO = 0 +CIRCUITPY_RTC = 0 +CIRCUITPY_SAMD = 0 +CIRCUITPY_USB_MIDI = 1 +CIRCUITPY_TOUCHIO = 0 +CIRCUITPY_SMALL_BUILD = 1 +# Make more room. +SUPEROPT_GC = 0 + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_IRRemote diff --git a/ports/atmel-samd/boards/pirkey_m0/pins.c b/ports/atmel-samd/boards/pirkey_m0/pins.c new file mode 100644 index 00000000000..41d02e3291f --- /dev/null +++ b/ports/atmel-samd/boards/pirkey_m0/pins.c @@ -0,0 +1,9 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_REMOTEIN), MP_ROM_PTR(&pin_PA28) }, + + { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA01) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/pybadge/board.c b/ports/atmel-samd/boards/pybadge/board.c new file mode 100644 index 00000000000..37f7991d159 --- /dev/null +++ b/ports/atmel-samd/boards/pybadge/board.c @@ -0,0 +1,121 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "tick.h" + +displayio_fourwire_obj_t board_display_obj; + +#define DELAY 0x80 + +uint8_t display_init_sequence[] = { + 0x01, 0 | DELAY, 150, // SWRESET + 0x11, 0 | DELAY, 255, // SLPOUT + 0xb1, 3, 0x01, 0x2C, 0x2D, // _FRMCTR1 + 0xb2, 3, 0x01, 0x2C, 0x2D, // + 0xb3, 6, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, + 0xb4, 1, 0x07, // _INVCTR line inversion + 0xc0, 3, 0xa2, 0x02, 0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA + 0xc1, 1, 0xc5, // _PWCTR2 VGH=14.7V, VGL=-7.35V + 0xc2, 2, 0x0a, 0x00, // _PWCTR3 Opamp current small, Boost frequency + 0xc3, 2, 0x8a, 0x2a, + 0xc4, 2, 0x8a, 0xee, + 0xc5, 1, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V + 0x2a, 0, // _INVOFF + 0x36, 1, 0x00, // _MADCTL top to bottom refresh in vsync aligned order. + // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie, + // fix on VTL + 0x3a, 1, 0x05, // COLMOD - 16bit color + 0xe0, 16, 0x02, 0x1c, 0x07, 0x12, // _GMCTRP1 Gamma + 0x37, 0x32, 0x29, 0x2d, + 0x29, 0x25, 0x2B, 0x39, + 0x00, 0x01, 0x03, 0x10, + 0xe1, 16, 0x03, 0x1d, 0x07, 0x06, // _GMCTRN1 + 0x2E, 0x2C, 0x29, 0x2D, + 0x2E, 0x2E, 0x37, 0x3F, + 0x00, 0x00, 0x02, 0x10, + 0x2a, 3, 0x02, 0x00, 0x81, // _CASET XSTART = 2, XEND = 129 + 0x2b, 3, 0x02, 0x00, 0x81, // _RASET XSTART = 2, XEND = 129 + 0x13, 0 | DELAY, 10, // _NORON + 0x29, 0 | DELAY, 100, // _DISPON +}; + +void board_init(void) { + busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; + common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL); + common_hal_busio_spi_never_reset(spi); + + displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + common_hal_displayio_fourwire_construct(bus, + spi, + &pin_PB05, // TFT_DC Command or data + &pin_PB07, // TFT_CS Chip select + &pin_PA00, // TFT_RST Reset + 60000000); + + displayio_display_obj_t* display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, + 160, // Width (after rotation) + 128, // Height (after rotation) + 0, // column start + 0, // row start + 270, // rotation + 16, // Color depth + false, // grayscale + false, // pixels in byte share row. only used for depth < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + 0x37, // set vertical scroll command + display_init_sequence, + sizeof(display_init_sequence), + &pin_PA01, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness (ignored) + true, // auto_brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60); // native_frames_per_second +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/pybadge/mpconfigboard.h b/ports/atmel-samd/boards/pybadge/mpconfigboard.h new file mode 100644 index 00000000000..36115bc8733 --- /dev/null +++ b/ports/atmel-samd/boards/pybadge/mpconfigboard.h @@ -0,0 +1,37 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Pybadge" +#define MICROPY_HW_MCU_NAME "samd51j19" + +#define CIRCUITPY_MCU_FAMILY samd51 + +// This is for Rev B +#define MICROPY_HW_LED_STATUS (&pin_PA23) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// DotStar pins, QSPI CS, and QSPI SCK +#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA13) +#define DEFAULT_I2C_BUS_SDA (&pin_PA12) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA17) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB23) +#define DEFAULT_SPI_BUS_MISO (&pin_PB22) + +#define DEFAULT_UART_BUS_RX (&pin_PB17) +#define DEFAULT_UART_BUS_TX (&pin_PB16) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/pybadge/mpconfigboard.mk b/ports/atmel-samd/boards/pybadge/mpconfigboard.mk new file mode 100644 index 00000000000..7e2cb643988 --- /dev/null +++ b/ports/atmel-samd/boards/pybadge/mpconfigboard.mk @@ -0,0 +1,21 @@ +LD_FILE = boards/samd51x19-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8034 +USB_PRODUCT = "PyBadge" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD51J19A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = GD25Q16C +LONGINT_IMPL = MPZ + +CIRCUITPY_AUDIOIO = 1 +CIRCUITPY_DISPLAYIO = 1 +CIRCUITPY_GAMEPAD = 1 +CIRCUITPY_GAMEPADSHIFT = 1 +CIRCUITPY_STAGE = 1 + +FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pybadge diff --git a/ports/atmel-samd/boards/pybadge/pins.c b/ports/atmel-samd/boards/pybadge/pins.c new file mode 100644 index 00000000000..ca65d9df464 --- /dev/null +++ b/ports/atmel-samd/boards/pybadge/pins.c @@ -0,0 +1,70 @@ +#include "shared-bindings/board/__init__.h" + +#include "boards/board.h" +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PB01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PB02) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23) }, + + // UART + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB16) }, + + // I2C + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA13) }, + + // SPI + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB23) }, + + // Special named pins + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_PB04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER_ENABLE), MP_ROM_PTR(&pin_PA27) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_LATCH), MP_ROM_PTR(&pin_PB00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_OUT), MP_ROM_PTR(&pin_PB30) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_CLOCK), MP_ROM_PTR(&pin_PB31) }, + + // TFT control pins + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_LITE), MP_ROM_PTR(&pin_PA01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_MOSI), MP_ROM_PTR(&pin_PB15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_SCK), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RST), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_PB07) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_PB05) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/pybadge_airlift/board.c b/ports/atmel-samd/boards/pybadge_airlift/board.c new file mode 100644 index 00000000000..7622de6f086 --- /dev/null +++ b/ports/atmel-samd/boards/pybadge_airlift/board.c @@ -0,0 +1,99 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "tick.h" + +displayio_fourwire_obj_t board_display_obj; + +#define DELAY 0x80 + +uint8_t display_init_sequence[] = { + 0x01, 0 | DELAY, 150, // SWRESET + 0x11, 0 | DELAY, 255, // SLPOUT + 0x36, 1, 0x08, // _MADCTL bottom to top refresh in vsync aligned order. + 0x3a, 1, 0x55, // COLMOD - 16bit color + 0x21, 0 | DELAY, 10, // _INVON + 0x13, 0 | DELAY, 10, // _NORON + 0x29, 0 | DELAY, 255, // _DISPON +}; + +void board_init(void) { + busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; + common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL); + common_hal_busio_spi_never_reset(spi); + + displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + common_hal_displayio_fourwire_construct(bus, + spi, + &pin_PB05, // TFT_DC Command or data + &pin_PB06, // TFT_CS Chip select + &pin_PB07, // TFT_RST Reset + 60000000); + + displayio_display_obj_t* display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, + 320, // Width (after rotation) + 240, // Height (after rotation) + 0, // column start + 0, // row start + 90, // rotation + 16, // Color depth + false, // grayscale + false, // pixels in byte share row. Only used for depth < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + 0x37, // set vertical scroll command + display_init_sequence, + sizeof(display_init_sequence), + &pin_PA01, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness (ignored) + true, // auto_brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60); // native_frames_per_second +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.h b/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.h new file mode 100644 index 00000000000..ade74786d3c --- /dev/null +++ b/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.h @@ -0,0 +1,37 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Pybadge Airlift" +#define MICROPY_HW_MCU_NAME "samd51j20" + +#define CIRCUITPY_MCU_FAMILY samd51 + +// This is for Rev B +#define MICROPY_HW_LED_STATUS (&pin_PA23) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// DotStar pins, QSPI CS, and QSPI SCK +#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA13) +#define DEFAULT_I2C_BUS_SDA (&pin_PA12) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA17) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB23) +#define DEFAULT_SPI_BUS_MISO (&pin_PB22) + +#define DEFAULT_UART_BUS_RX (&pin_PB17) +#define DEFAULT_UART_BUS_TX (&pin_PB16) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.mk b/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.mk new file mode 100644 index 00000000000..7e77b0feaf2 --- /dev/null +++ b/ports/atmel-samd/boards/pybadge_airlift/mpconfigboard.mk @@ -0,0 +1,21 @@ +LD_FILE = boards/samd51x19-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8043 +USB_PRODUCT = "PyBadge AirLift" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD51J20A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = GD25Q16C +LONGINT_IMPL = MPZ + +CIRCUITPY_AUDIOIO = 1 +CIRCUITPY_DISPLAYIO = 1 +CIRCUITPY_GAMEPAD = 1 +CIRCUITPY_GAMEPADSHIFT = 1 +CIRCUITPY_STAGE = 1 + +FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pybadge diff --git a/ports/atmel-samd/boards/pybadge_airlift/pins.c b/ports/atmel-samd/boards/pybadge_airlift/pins.c new file mode 100644 index 00000000000..d3965024604 --- /dev/null +++ b/ports/atmel-samd/boards/pybadge_airlift/pins.c @@ -0,0 +1,75 @@ +#include "shared-bindings/board/__init__.h" + +#include "boards/board.h" +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + {MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB08)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB09)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA04)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PB01)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB04)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PB03)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PB02)}, + + {MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB17)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB16)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB03)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB02)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA14)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA16)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA18)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB14)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA15)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA19)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA20)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA21)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA22)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23)}, + + // UART + {MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB17)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB16)}, + + // I2C + {MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA12)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA13)}, + + // SPI + {MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB22)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB23)}, + + // Special named pins + {MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA15)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_PB04)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_PB14)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER_ENABLE), MP_ROM_PTR(&pin_PA27)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_LATCH), MP_ROM_PTR(&pin_PB00)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_OUT), MP_ROM_PTR(&pin_PB30)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_CLOCK), MP_ROM_PTR(&pin_PB31)}, + + // ESP control + {MP_OBJ_NEW_QSTR(MP_QSTR_ESP_CS), MP_ROM_PTR(&pin_PA14)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_ESP_GPIO0), MP_ROM_PTR(&pin_PA31)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_ESP_BUSY), MP_ROM_PTR(&pin_PA00)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RESET), MP_ROM_PTR(&pin_PB12)}, + + // TFT control pins + {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_LITE), MP_ROM_PTR(&pin_PA01)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_MOSI), MP_ROM_PTR(&pin_PB15)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_SCK), MP_ROM_PTR(&pin_PB13)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RST), MP_ROM_PTR(&pin_PB07)}, + {MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_PB06)}, + {MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_PB05)}, + + {MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj)}, + {MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj)}, + {MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj)}, + + {MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/pygamer/board.c b/ports/atmel-samd/boards/pygamer/board.c new file mode 100644 index 00000000000..b33ae4fb062 --- /dev/null +++ b/ports/atmel-samd/boards/pygamer/board.c @@ -0,0 +1,121 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "tick.h" + +displayio_fourwire_obj_t board_display_obj; + +#define DELAY 0x80 + +uint8_t display_init_sequence[] = { + 0x01, 0 | DELAY, 150, // SWRESET + 0x11, 0 | DELAY, 255, // SLPOUT + 0xb1, 3, 0x01, 0x2C, 0x2D, // _FRMCTR1 + 0xb2, 3, 0x01, 0x2C, 0x2D, // + 0xb3, 6, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, + 0xb4, 1, 0x07, // _INVCTR line inversion + 0xc0, 3, 0xa2, 0x02, 0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA + 0xc1, 1, 0xc5, // _PWCTR2 VGH=14.7V, VGL=-7.35V + 0xc2, 2, 0x0a, 0x00, // _PWCTR3 Opamp current small, Boost frequency + 0xc3, 2, 0x8a, 0x2a, + 0xc4, 2, 0x8a, 0xee, + 0xc5, 1, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V + 0x2a, 0, // _INVOFF + 0x36, 1, 0x00, // _MADCTL top to bottom refresh in vsync aligned order. + // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie, + // fix on VTL + 0x3a, 1, 0x05, // COLMOD - 16bit color + 0xe0, 16, 0x02, 0x1c, 0x07, 0x12, // _GMCTRP1 Gamma + 0x37, 0x32, 0x29, 0x2d, + 0x29, 0x25, 0x2B, 0x39, + 0x00, 0x01, 0x03, 0x10, + 0xe1, 16, 0x03, 0x1d, 0x07, 0x06, // _GMCTRN1 + 0x2E, 0x2C, 0x29, 0x2D, + 0x2E, 0x2E, 0x37, 0x3F, + 0x00, 0x00, 0x02, 0x10, + 0x2a, 3, 0x02, 0x00, 0x81, // _CASET XSTART = 2, XEND = 129 + 0x2b, 3, 0x02, 0x00, 0x81, // _RASET XSTART = 2, XEND = 129 + 0x13, 0 | DELAY, 10, // _NORON + 0x29, 0 | DELAY, 100, // _DISPON +}; + +void board_init(void) { + busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; + common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL); + common_hal_busio_spi_never_reset(spi); + + displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + common_hal_displayio_fourwire_construct(bus, + spi, + &pin_PB05, // TFT_DC Command or data + &pin_PB12, // TFT_CS Chip select + &pin_PA00, // TFT_RST Reset + 60000000); + + displayio_display_obj_t* display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, + 160, // Width + 128, // Height + 0, // column start + 0, // row start + 270, // rotation + 16, // Color depth + false, // Grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + 0x37, // set vertical scroll command + display_init_sequence, + sizeof(display_init_sequence), + &pin_PA01, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness (ignored) + true, // auto_brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60); // native_frames_per_second +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/pygamer/mpconfigboard.h b/ports/atmel-samd/boards/pygamer/mpconfigboard.h new file mode 100644 index 00000000000..4720b22eb1b --- /dev/null +++ b/ports/atmel-samd/boards/pygamer/mpconfigboard.h @@ -0,0 +1,36 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit PyGamer" +#define MICROPY_HW_MCU_NAME "samd51j19" + +#define CIRCUITPY_MCU_FAMILY samd51 + +#define MICROPY_HW_LED_STATUS (&pin_PA23) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// DotStar pins, QSPI CS, and QSPI SCK +#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA13) +#define DEFAULT_I2C_BUS_SDA (&pin_PA12) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA17) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB23) +#define DEFAULT_SPI_BUS_MISO (&pin_PB22) + +#define DEFAULT_UART_BUS_RX (&pin_PB17) +#define DEFAULT_UART_BUS_TX (&pin_PB16) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/pygamer/mpconfigboard.mk b/ports/atmel-samd/boards/pygamer/mpconfigboard.mk new file mode 100644 index 00000000000..0fce468d9fa --- /dev/null +++ b/ports/atmel-samd/boards/pygamer/mpconfigboard.mk @@ -0,0 +1,21 @@ +LD_FILE = boards/samd51x19-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x803E +USB_PRODUCT = "PyGamer" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD51J19A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = GD25Q64C +LONGINT_IMPL = MPZ + +CIRCUITPY_AUDIOIO = 1 +CIRCUITPY_DISPLAYIO = 1 +CIRCUITPY_GAMEPAD = 1 +CIRCUITPY_GAMEPADSHIFT = 1 +CIRCUITPY_STAGE = 1 + +FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pygamer diff --git a/ports/atmel-samd/boards/pygamer/pins.c b/ports/atmel-samd/boards/pygamer/pins.c new file mode 100644 index 00000000000..7e6eff43f97 --- /dev/null +++ b/ports/atmel-samd/boards/pygamer/pins.c @@ -0,0 +1,75 @@ +#include "shared-bindings/board/__init__.h" + +#include "boards/board.h" +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PB01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PB02) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23) }, + + // UART + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB16) }, + + // I2C + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA13) }, + + // SPI + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB23) }, + + // SDCS, dup of D4 + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PA14) }, + + // Special named pins + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_PB04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER_ENABLE), MP_ROM_PTR(&pin_PA27) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_LATCH), MP_ROM_PTR(&pin_PB00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_OUT), MP_ROM_PTR(&pin_PB30) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_CLOCK), MP_ROM_PTR(&pin_PB31) }, + + // TFT control pins + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_LITE), MP_ROM_PTR(&pin_PA01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_MOSI), MP_ROM_PTR(&pin_PB15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_SCK), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RST), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_PB12) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_PB05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_JOYSTICK_X), MP_ROM_PTR(&pin_PB07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_JOYSTICK_Y), MP_ROM_PTR(&pin_PB06) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/pygamer_advance/board.c b/ports/atmel-samd/boards/pygamer_advance/board.c new file mode 100644 index 00000000000..8eb501243f0 --- /dev/null +++ b/ports/atmel-samd/boards/pygamer_advance/board.c @@ -0,0 +1,99 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "tick.h" + +displayio_fourwire_obj_t board_display_obj; + +#define DELAY 0x80 + +uint8_t display_init_sequence[] = { + 0x01, 0 | DELAY, 150, // SWRESET + 0x11, 0 | DELAY, 255, // SLPOUT + 0x36, 1, 0x00, // _MADCTL bottom to top refresh in vsync aligned order. + 0x3a, 1, 0x55, // COLMOD - 16bit color + 0x21, 0 | DELAY, 10, // _INVON + 0x13, 0 | DELAY, 10, // _NORON + 0x29, 0 | DELAY, 255, // _DISPON +}; + +void board_init(void) { + busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; + common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB12, NULL); + common_hal_busio_spi_never_reset(spi); + + displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + common_hal_displayio_fourwire_construct(bus, + spi, + &pin_PA00, // TFT_DC Command or data + &pin_PB15, // TFT_CS Chip select + &pin_PB05, // TFT_RST Reset + 60000000); + + displayio_display_obj_t* display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, + 320, // Width (after rotation) + 240, // Height (after rotation) + 0, // column start + 0, // row start + 90, // rotation + 16, // Color depth + false, // Grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + 0x37, // set vertical scroll command + display_init_sequence, + sizeof(display_init_sequence), + &pin_PA01, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness (ignored) + true, // auto_brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60); // native_frames_per_second +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.h b/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.h new file mode 100644 index 00000000000..c05aa4f062e --- /dev/null +++ b/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.h @@ -0,0 +1,36 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit PyGamer" +#define MICROPY_HW_MCU_NAME "samd51j20" + +#define CIRCUITPY_MCU_FAMILY samd51 + +#define MICROPY_HW_LED_STATUS (&pin_PA23) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// DotStar pins, QSPI CS, and QSPI SCK +#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA13) +#define DEFAULT_I2C_BUS_SDA (&pin_PA12) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA17) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB23) +#define DEFAULT_SPI_BUS_MISO (&pin_PB22) + +#define DEFAULT_UART_BUS_RX (&pin_PB17) +#define DEFAULT_UART_BUS_TX (&pin_PB16) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.mk b/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.mk new file mode 100644 index 00000000000..8711738d4f2 --- /dev/null +++ b/ports/atmel-samd/boards/pygamer_advance/mpconfigboard.mk @@ -0,0 +1,21 @@ +LD_FILE = boards/samd51x19-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x803E +USB_PRODUCT = "PyGamer Advance" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD51J20A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = GD25Q64C +LONGINT_IMPL = MPZ + +CIRCUITPY_AUDIOIO = 1 +CIRCUITPY_DISPLAYIO = 1 +CIRCUITPY_GAMEPAD = 1 +CIRCUITPY_GAMEPADSHIFT = 1 +CIRCUITPY_STAGE = 1 + +FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pybadge diff --git a/ports/atmel-samd/boards/pygamer_advance/pins.c b/ports/atmel-samd/boards/pygamer_advance/pins.c new file mode 100644 index 00000000000..9c2284db1a2 --- /dev/null +++ b/ports/atmel-samd/boards/pygamer_advance/pins.c @@ -0,0 +1,75 @@ +#include "shared-bindings/board/__init__.h" + +#include "boards/board.h" +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PB01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PB02) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23) }, + + // UART + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB16) }, + + // I2C + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA13) }, + + // SPI + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB23) }, + + // SDCS, dup of D4 + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PA14) }, + + // Special named pins + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_PB04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER_ENABLE), MP_ROM_PTR(&pin_PA27) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_LATCH), MP_ROM_PTR(&pin_PB00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_OUT), MP_ROM_PTR(&pin_PB30) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_CLOCK), MP_ROM_PTR(&pin_PB31) }, + + // TFT control pins + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_LITE), MP_ROM_PTR(&pin_PA01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_MOSI), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_SCK), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RST), MP_ROM_PTR(&pin_PB05) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_PB15) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_PA00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_JOYSTICK_X), MP_ROM_PTR(&pin_PB07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_JOYSTICK_Y), MP_ROM_PTR(&pin_PB06) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/pyportal/board.c b/ports/atmel-samd/boards/pyportal/board.c new file mode 100644 index 00000000000..2a72897784c --- /dev/null +++ b/ports/atmel-samd/boards/pyportal/board.c @@ -0,0 +1,111 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" + +#include "tick.h" + +#define DELAY 0x80 + +uint8_t display_init_sequence[] = { + 0xEF, 3, 0x03, 0x80, 0x02, + 0xCF, 3, 0x00, 0xC1, 0x30, + 0xED, 4, 0x64, 0x03, 0x12, 0x81, + 0xE8, 3, 0x85, 0x00, 0x78, + 0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, + 0xF7, 1, 0x20, + 0xEA, 2, 0x00, 0x00, + 0xc0, 1, 0x23, // Power control VRH[5:0] + 0xc1, 1, 0x10, // Power control SAP[2:0];BT[3:0] + 0xc5, 2, 0x3e, 0x28, // VCM control + 0xc7, 1, 0x86, // VCM control2 + 0x36, 1, 0xa8, // Memory Access Control + 0x37, 1, 0x00, // Vertical scroll zero + 0x3a, 1, 0x55, // COLMOD: Pixel Format Set + 0xb1, 2, 0x00, 0x18, // Frame Rate Control (In Normal Mode/Full Colors) + 0xb6, 3, 0x08, 0xa2, 0x27, // Display Function Control + 0xF2, 1, 0x00, // 3Gamma Function Disable + 0x26, 1, 0x01, // Gamma curve selected + 0xe0, 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, // Set Gamma + 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00, + 0xe1, 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, // Set Gamma + 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, + 0x11, DELAY, 120, // Exit Sleep + 0x29, DELAY, 120, // Display on +}; + +void board_init(void) { + displayio_parallelbus_obj_t* bus = &displays[0].parallel_bus; + bus->base.type = &displayio_parallelbus_type; + common_hal_displayio_parallelbus_construct(bus, + &pin_PA16, // Data0 + &pin_PB05, // Command or data + &pin_PB06, // Chip select + &pin_PB09, // Write + &pin_PB04, // Read + &pin_PA00); // Reset + + displayio_display_obj_t* display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, + 320, // Width + 240, // Height + 0, // column start + 0, // row start + 0, // rotation + 16, // Color depth + false, // grayscale + false, // pixels_in_byte_share_row (unused for depths > 8) + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + 0x37, // Set vertical scroll command + display_init_sequence, + sizeof(display_init_sequence), + &pin_PB31, // Backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness (ignored) + true, // auto_brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60); // native_frames_per_second +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/pyportal/mpconfigboard.h b/ports/atmel-samd/boards/pyportal/mpconfigboard.h new file mode 100644 index 00000000000..43346488ba9 --- /dev/null +++ b/ports/atmel-samd/boards/pyportal/mpconfigboard.h @@ -0,0 +1,40 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit PyPortal" +#define MICROPY_HW_MCU_NAME "samd51j20" + +#define CIRCUITPY_MCU_FAMILY samd51 + +// This is for Rev B + +#define MICROPY_HW_LED_STATUS (&pin_PA27) + +#define MICROPY_HW_NEOPIXEL (&pin_PB22) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A ( PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11 ) +// QSPI CS, and QSPI SCK +#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11 | PORT_PB22 ) +#define MICROPY_PORT_C ( 0 ) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PB03) +#define DEFAULT_I2C_BUS_SDA (&pin_PB02) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA13) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA12) +#define DEFAULT_SPI_BUS_MISO (&pin_PA14) + +#define DEFAULT_UART_BUS_RX (&pin_PB13) +#define DEFAULT_UART_BUS_TX (&pin_PB12) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/pyportal/mpconfigboard.mk b/ports/atmel-samd/boards/pyportal/mpconfigboard.mk new file mode 100644 index 00000000000..f763c74fa45 --- /dev/null +++ b/ports/atmel-samd/boards/pyportal/mpconfigboard.mk @@ -0,0 +1,13 @@ +LD_FILE = boards/samd51x20-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8036 +USB_PRODUCT = "PyPortal" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD51J20A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C" +LONGINT_IMPL = MPZ diff --git a/ports/atmel-samd/boards/pyportal/pins.c b/ports/atmel-samd/boards/pyportal/pins.c new file mode 100644 index 00000000000..14699a209db --- /dev/null +++ b/ports/atmel-samd/boards/pyportal/pins.c @@ -0,0 +1,85 @@ +#include "shared-bindings/board/__init__.h" + +#include "boards/board.h" +#include "shared-module/displayio/__init__.h" + +// This mapping only includes functional names because pins broken +// out on connectors are labeled with their MCU name available from +// microcontroller.pin. +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_AUDIO_OUT), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, // analog out/in + { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER_ENABLE), MP_ROM_PTR(&pin_PA27) }, + + // Light sensor + { MP_OBJ_NEW_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_PA07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA07) }, + + // STEMMA connectors + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + + // Indicator LED + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_PB23) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_PB22) }, + + // LCD pins + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_PA00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RD), MP_ROM_PTR(&pin_PB04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RS), MP_ROM_PTR(&pin_PB05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_PB06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_TE), MP_ROM_PTR(&pin_PB07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_WR), MP_ROM_PTR(&pin_PB09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_PB09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_PB31) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA0), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA1), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA2), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA3), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA4), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA5), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA6), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA7), MP_ROM_PTR(&pin_PA23) }, + + // Touch pins + { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_YD), MP_ROM_PTR(&pin_PB00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_XL), MP_ROM_PTR(&pin_PB01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_YU), MP_ROM_PTR(&pin_PA06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_XR), MP_ROM_PTR(&pin_PB08) }, + + // ESP control + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_CS), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_GPIO0), MP_ROM_PTR(&pin_PB15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_BUSY), MP_ROM_PTR(&pin_PB16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RESET), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RTS), MP_ROM_PTR(&pin_PA15) }, + + // UART + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB13) }, + + // SPI + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA14) }, + + // I2C + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PB03) }, + + // SD Card + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS),MP_ROM_PTR(&pin_PB30) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CARD_DETECT),MP_ROM_PTR(&pin_PA01) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/pyportal_titano/board.c b/ports/atmel-samd/boards/pyportal_titano/board.c new file mode 100644 index 00000000000..a18bb380bbd --- /dev/null +++ b/ports/atmel-samd/boards/pyportal_titano/board.c @@ -0,0 +1,131 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" + +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" + +#include "tick.h" + +#define DELAY 0x80 + +uint8_t display_init_sequence[] = { + 0x01, DELAY, 100/5, // Soft reset, then delay 10 ms + 0xB9, 3, 0xFF, 0x83, 0x57, // Extension command set + 0xFF, DELAY, 500/5, + 0xB3, 4, 0x80, 0x00, 0x06, 0x06, // 0x80 enables SDO pin (0x00 disables) + 0xB6, 2, 0x01, 0x25, // -1.52V + 0xB0, 1, 0x68, // Normal mode 70Hz, Idle mode 55 Hz + 0xCC, 1, 0x05, + 0xB1, 6, + 0x00, // Not deep standby + 0x15, // BT + 0x1C, // VSPR + 0x1C, // VSNR + 0x83, // AP + 0xAA, // FS + 0xC0, 6, + 0x50, // OPON normal + 0x50, // OPON idle + 0x01, // STBA + 0x3C, // STBA + 0x1E, // STBA + 0x08, // GEN + 0xB4, 7, + 0x02, // NW 0x02 + 0x40, // RTN + 0x00, // DIV + 0x2A, // DUM + 0x2A, // DUM + 0x0D, // GDON + 0x78, // GDOFF + 0xE0, 34, + 0x02, 0x0A, 0x11, 0x1d, 0x23, 0x35, 0x41, 0x4b, 0x4b, + 0x42, 0x3A, 0x27, 0x1B, 0x08, 0x09, 0x03, 0x02, 0x0A, + 0x11, 0x1d, 0x23, 0x35, 0x41, 0x4b, 0x4b, 0x42, 0x3A, + 0x27, 0x1B, 0x08, 0x09, 0x03, 0x00, 0x01, + 0x3a, 1, 0x55, + 0x36, 1, 0x00, + 0x11, DELAY, 150/5, // Exit Sleep, then delay 150 ms + 0x29, DELAY, 50/5 +}; + +void board_init(void) { + busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; + common_hal_busio_spi_construct(spi, &pin_PA13, &pin_PA12, &pin_PA14); + common_hal_busio_spi_never_reset(spi); + + displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + common_hal_displayio_fourwire_construct(bus, + spi, + &pin_PB05, // TFT_DC Command or data + &pin_PB06, // TFT_CS Chip select + &pin_PA00, // TFT_RST Reset + 24000000); + + displayio_display_obj_t* display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, + 480, // Width + 320, // Height + 0, // column start + 0, // row start + 270, // rotation + 16, // Color depth + false, // grayscale + false, // pixels_in_byte_share_row (unused for depths > 8) + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + 0x37, // Set vertical scroll command + display_init_sequence, + sizeof(display_init_sequence), + &pin_PB31, // Backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness (ignored) + true, // auto_brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60); // native_frames_per_second +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/pyportal_titano/mpconfigboard.h b/ports/atmel-samd/boards/pyportal_titano/mpconfigboard.h new file mode 100644 index 00000000000..91c11881085 --- /dev/null +++ b/ports/atmel-samd/boards/pyportal_titano/mpconfigboard.h @@ -0,0 +1,39 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit PyPortal Titano" +#define MICROPY_HW_MCU_NAME "samd51j20" + +#define CIRCUITPY_MCU_FAMILY samd51 + + +#define MICROPY_HW_LED_STATUS (&pin_PA27) + +#define MICROPY_HW_NEOPIXEL (&pin_PB22) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A ( PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11 ) +// QSPI CS, and QSPI SCK +#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11 | PORT_PB22 ) +#define MICROPY_PORT_C ( 0 ) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PB03) +#define DEFAULT_I2C_BUS_SDA (&pin_PB02) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA13) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA12) +#define DEFAULT_SPI_BUS_MISO (&pin_PA14) + +#define DEFAULT_UART_BUS_RX (&pin_PB13) +#define DEFAULT_UART_BUS_TX (&pin_PB12) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/pyportal_titano/mpconfigboard.mk b/ports/atmel-samd/boards/pyportal_titano/mpconfigboard.mk new file mode 100644 index 00000000000..58b363779c0 --- /dev/null +++ b/ports/atmel-samd/boards/pyportal_titano/mpconfigboard.mk @@ -0,0 +1,13 @@ +LD_FILE = boards/samd51x20-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8054 +USB_PRODUCT = "PyPortal Titano" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD51J20A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C" +LONGINT_IMPL = MPZ diff --git a/ports/atmel-samd/boards/pyportal_titano/pins.c b/ports/atmel-samd/boards/pyportal_titano/pins.c new file mode 100644 index 00000000000..6bc0a504a4d --- /dev/null +++ b/ports/atmel-samd/boards/pyportal_titano/pins.c @@ -0,0 +1,94 @@ +#include "shared-bindings/board/__init__.h" + +#include "boards/board.h" +#include "shared-module/displayio/__init__.h" + +// This mapping only includes functional names because pins broken +// out on connectors are labeled with their MCU name available from +// microcontroller.pin. +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_AUDIO_OUT), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, // analog out/in + { MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER_ENABLE), MP_ROM_PTR(&pin_PA27) }, + + // Light sensor + { MP_OBJ_NEW_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_PA07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA07) }, + + // STEMMA connectors + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + + // Indicator LED + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_PB23) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_PB22) }, + + // LCD pins + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_PA00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RD), MP_ROM_PTR(&pin_PB04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RS), MP_ROM_PTR(&pin_PB05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_PB06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_TE), MP_ROM_PTR(&pin_PB07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_WR), MP_ROM_PTR(&pin_PB09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_PB09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_PB31) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA0), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA1), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA2), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA3), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA4), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA5), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA6), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LCD_DATA7), MP_ROM_PTR(&pin_PA23) }, + + // Touch pins + { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_YD), MP_ROM_PTR(&pin_PB00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_XL), MP_ROM_PTR(&pin_PB01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_YU), MP_ROM_PTR(&pin_PA06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TOUCH_XR), MP_ROM_PTR(&pin_PB08) }, + + // ESP control + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_CS), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_GPIO0), MP_ROM_PTR(&pin_PB15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_BUSY), MP_ROM_PTR(&pin_PB16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RESET), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RTS), MP_ROM_PTR(&pin_PA15) }, + + // UART + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB13) }, + + // SPI + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA14) }, + + // I2C + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PB03) }, + + // SD Card + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS),MP_ROM_PTR(&pin_PB30) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CARD_DETECT),MP_ROM_PTR(&pin_PA01) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + // TFT control pins + {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_LITE), MP_ROM_PTR(&pin_PB31)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_MOSI), MP_ROM_PTR(&pin_PA12)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_SCK), MP_ROM_PTR(&pin_PA13)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_MISO), MP_ROM_PTR(&pin_PA14)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RST), MP_ROM_PTR(&pin_PA00)}, + {MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_PB06)}, + {MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_PB05)}, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/pyruler/board.c b/ports/atmel-samd/boards/pyruler/board.c new file mode 100644 index 00000000000..d7e856d6119 --- /dev/null +++ b/ports/atmel-samd/boards/pyruler/board.c @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/pyruler/mpconfigboard.h b/ports/atmel-samd/boards/pyruler/mpconfigboard.h new file mode 100644 index 00000000000..171873b47c6 --- /dev/null +++ b/ports/atmel-samd/boards/pyruler/mpconfigboard.h @@ -0,0 +1,63 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit PyRuler" +#define MICROPY_HW_MCU_NAME "samd21e18" + +#define MICROPY_HW_LED_STATUS (&pin_PA10) + +#define MICROPY_HW_APA102_MOSI (&pin_PA00) +#define MICROPY_HW_APA102_SCK (&pin_PA01) + +#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define IGNORE_PIN_PA12 1 +#define IGNORE_PIN_PA13 1 +#define IGNORE_PIN_PA16 1 +#define IGNORE_PIN_PA17 1 +#define IGNORE_PIN_PA18 1 +#define IGNORE_PIN_PA19 1 +#define IGNORE_PIN_PA20 1 +#define IGNORE_PIN_PA21 1 +#define IGNORE_PIN_PA22 1 +#define IGNORE_PIN_PA23 1 +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 +#define IGNORE_PIN_PA30 1 +#define IGNORE_PIN_PA31 1 +#define IGNORE_PIN_PB01 1 +#define IGNORE_PIN_PB02 1 +#define IGNORE_PIN_PB03 1 +#define IGNORE_PIN_PB04 1 +#define IGNORE_PIN_PB05 1 +#define IGNORE_PIN_PB06 1 +#define IGNORE_PIN_PB07 1 +#define IGNORE_PIN_PB08 1 +#define IGNORE_PIN_PB09 1 +#define IGNORE_PIN_PB10 1 +#define IGNORE_PIN_PB11 1 +#define IGNORE_PIN_PB12 1 +#define IGNORE_PIN_PB13 1 +#define IGNORE_PIN_PB14 1 +#define IGNORE_PIN_PB15 1 +#define IGNORE_PIN_PB16 1 +#define IGNORE_PIN_PB17 1 +#define IGNORE_PIN_PB22 1 +#define IGNORE_PIN_PB23 1 +#define IGNORE_PIN_PB30 1 +#define IGNORE_PIN_PB31 1 +#define IGNORE_PIN_PB00 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA09) +#define DEFAULT_I2C_BUS_SDA (&pin_PA08) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA07) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA06) +#define DEFAULT_SPI_BUS_MISO (&pin_PA09) + +#define DEFAULT_UART_BUS_RX (&pin_PA07) +#define DEFAULT_UART_BUS_TX (&pin_PA06) diff --git a/ports/atmel-samd/boards/pyruler/mpconfigboard.mk b/ports/atmel-samd/boards/pyruler/mpconfigboard.mk new file mode 100644 index 00000000000..9663944a38c --- /dev/null +++ b/ports/atmel-samd/boards/pyruler/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x239A +USB_PID = 0x804C +USB_PRODUCT = "PyRuler" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/pyruler/pins.c b/ports/atmel-samd/boards/pyruler/pins.c new file mode 100644 index 00000000000..315dbe63039 --- /dev/null +++ b/ports/atmel-samd/boards/pyruler/pins.c @@ -0,0 +1,50 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + + { MP_ROM_QSTR(MP_QSTR_CAP0), MP_ROM_PTR(&pin_PA11) }, + + { MP_ROM_QSTR(MP_QSTR_CAP1), MP_ROM_PTR(&pin_PA05) }, + + { MP_ROM_QSTR(MP_QSTR_CAP2), MP_ROM_PTR(&pin_PA04) }, + + { MP_ROM_QSTR(MP_QSTR_CAP3), MP_ROM_PTR(&pin_PA03) }, + + { MP_ROM_QSTR(MP_QSTR_LED4), MP_ROM_PTR(&pin_PA15) }, + + { MP_ROM_QSTR(MP_QSTR_LED5), MP_ROM_PTR(&pin_PA14) }, + + { MP_ROM_QSTR(MP_QSTR_LED6), MP_ROM_PTR(&pin_PA28) }, + + { MP_ROM_QSTR(MP_QSTR_LED7), MP_ROM_PTR(&pin_PA27) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA09) }, + + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA06) }, + + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA07) }, + + { MP_ROM_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA10) }, + + { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/robohatmm1_m0/board.c b/ports/atmel-samd/boards/robohatmm1_m0/board.c new file mode 100644 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/robohatmm1_m0/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.h b/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.h new file mode 100644 index 00000000000..dc122b6fa5c --- /dev/null +++ b/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.h @@ -0,0 +1,42 @@ +#define MICROPY_HW_BOARD_NAME "Robo HAT MM1" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_HW_LED_STATUS (&pin_PB22) + +// Salae reads 12mhz which is the limit even though we set it to the safer 8mhz. +#define SPI_FLASH_BAUDRATE (8000000) + +// On-board flash +#define SPI_FLASH_MOSI_PIN &pin_PA12 +#define SPI_FLASH_MISO_PIN &pin_PA14 +#define SPI_FLASH_SCK_PIN &pin_PA13 +#define SPI_FLASH_CS_PIN &pin_PA15 + +// These are pins not to reset. +#define MICROPY_PORT_A ( 0 ) //PORT_PA06 +#define MICROPY_PORT_B ( 0 ) +#define MICROPY_PORT_C ( 0 ) + + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code. +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define CALIBRATE_CRYSTALLESS 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB10) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB08) +#define DEFAULT_SPI_BUS_MISO (&pin_PB11) + +#define DEFAULT_UART_BUS_RX (&pin_PB03) +#define DEFAULT_UART_BUS_TX (&pin_PB02) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 + diff --git a/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.mk b/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.mk new file mode 100644 index 00000000000..e4f688f1e23 --- /dev/null +++ b/ports/atmel-samd/boards/robohatmm1_m0/mpconfigboard.mk @@ -0,0 +1,29 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash-crystalless.ld +USB_VID = 0x1209 +USB_PID = 0x4D43 +USB_PRODUCT = "Robo HAT MM1" +USB_MANUFACTURER = "Robotics Masters" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ" +LONGINT_IMPL = MPZ + +# Non-Flash Edition +#INTERNAL_FLASH_FILESYSTEM = 1 +#LONGINT_IMPL = NONE + +CIRCUITPY_DISPLAYIO = 0 +CIRCUITPY_FREQUENCYIO = 0 + +CFLAGS_INLINE_LIMIT = 60 +SUPEROPT_GC = 0 + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +#FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_INA219 +#FROZEN_MPY_DIRS += $(TOP)/frozen/RoboticsMasters_CircuitPython_MPU9250 diff --git a/ports/atmel-samd/boards/robohatmm1_m0/pins.c b/ports/atmel-samd/boards/robohatmm1_m0/pins.c new file mode 100644 index 00000000000..f50e8d15a5a --- /dev/null +++ b/ports/atmel-samd/boards/robohatmm1_m0/pins.c @@ -0,0 +1,88 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + // SERVO Pins + { MP_ROM_QSTR(MP_QSTR_SERVO1), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_SERVO2), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_SERVO3), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_SERVO4), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_SERVO5), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_SERVO6), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_SERVO7), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_SERVO8), MP_ROM_PTR(&pin_PA08) }, + + // RCC Pins + { MP_ROM_QSTR(MP_QSTR_RCC1), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_RCC2), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_RCC3), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_RCC4), MP_ROM_PTR(&pin_PA04) }, + + // Special Function + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_POWER_OFF), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_POWER_DISABLE), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_POWER_ON), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_POWER_ENABLE), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_PA27) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB03) }, + + // GROVE on SERCOM0 + { MP_ROM_QSTR(MP_QSTR_GROVE_SCL), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_GROVE_SDA), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_GROVE_RX), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_GROVE_TX), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_GROVE_D1), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_GROVE_D0), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_GROVE_A1), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_GROVE_A0), MP_ROM_PTR(&pin_PA08) }, + + // UART on SERCOM0 + { MP_ROM_QSTR(MP_QSTR_UART_TX), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_UART_RX), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_UART_CTS), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_UART_RTS), MP_ROM_PTR(&pin_PA07) }, + + // SPI Flash on SERCOM2 + { MP_ROM_QSTR(MP_QSTR_FLASH_SCK), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_FLASH_MISO), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_FLASH_MOSI), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_FLASH_CS), MP_ROM_PTR(&pin_PA15) }, + + // I2C on SERCOM3 + { MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_PA01) }, + + // SPI on SERCOM4 + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB11) }, + + // GPS on SERCOM5 + { MP_ROM_QSTR(MP_QSTR_GPS_TX), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_GPS_RX), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_GPS_SDA), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_GPS_SCL), MP_ROM_PTR(&pin_PA01) }, + + // Raspberry Pi + { MP_ROM_QSTR(MP_QSTR_PI_GP25), MP_ROM_PTR(&pin_PA30) }, + { MP_ROM_QSTR(MP_QSTR_SWCLK), MP_ROM_PTR(&pin_PA30) }, + { MP_ROM_QSTR(MP_QSTR_PI_GP24), MP_ROM_PTR(&pin_PA31) }, + { MP_ROM_QSTR(MP_QSTR_SWDIO), MP_ROM_PTR(&pin_PA31) }, + { MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_PI_TX), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_PI_RX), MP_ROM_PTR(&pin_PA17) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/robohatmm1_m4/board.c b/ports/atmel-samd/boards/robohatmm1_m4/board.c new file mode 100644 index 00000000000..0f60736a240 --- /dev/null +++ b/ports/atmel-samd/boards/robohatmm1_m4/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.h b/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.h new file mode 100644 index 00000000000..ac3a3a0ddf5 --- /dev/null +++ b/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.h @@ -0,0 +1,44 @@ +#define MICROPY_HW_BOARD_NAME "Robo HAT MM1" +#define MICROPY_HW_MCU_NAME "samd51g19" + +#define CIRCUITPY_MCU_FAMILY samd51 + +#define MICROPY_HW_LED_STATUS (&pin_PB22) + +// Salae reads 12mhz which is the limit even though we set it to the safer 8mhz. +#define SPI_FLASH_BAUDRATE (8000000) + +// On-board flash +#define SPI_FLASH_MOSI_PIN &pin_PA12 +#define SPI_FLASH_MISO_PIN &pin_PA14 +#define SPI_FLASH_SCK_PIN &pin_PA13 +#define SPI_FLASH_CS_PIN &pin_PA15 + +// These are pins not to reset. +// SPI Data pins +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB10) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB08) +#define DEFAULT_SPI_BUS_MISO (&pin_PB11) + +#define DEFAULT_UART_BUS_RX (&pin_PB03) +#define DEFAULT_UART_BUS_TX (&pin_PB02) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk b/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk new file mode 100644 index 00000000000..f391bf625a3 --- /dev/null +++ b/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk @@ -0,0 +1,28 @@ +LD_FILE = boards/samd51x19-bootloader-external-flash.ld +USB_VID = 0x1209 +USB_PID = 0x4D43 +USB_PRODUCT = "Robo HAT MM1" +USB_MANUFACTURER = "Robotics Masters" + +CHIP_VARIANT = SAMD51G19A +CHIP_FAMILY = samd51 + +#QSPI_FLASH_FILESYSTEM = 0 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ" +LONGINT_IMPL = MPZ + +CIRCUITPY_PS2IO = 1 +# No I2S on SAMD51G +CIRCUITPY_AUDIOBUSIO = 0 +# Make room for more stuff +CIRCUITPY_DISPLAYIO = 0 +CIRCUITPY_FREQUENCYIO = 0 + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +#FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_INA219 +#FROZEN_MPY_DIRS += $(TOP)/frozen/RoboticsMasters_CircuitPython_MPU9250 diff --git a/ports/atmel-samd/boards/robohatmm1_m4/pins.c b/ports/atmel-samd/boards/robohatmm1_m4/pins.c new file mode 100644 index 00000000000..e1204e34378 --- /dev/null +++ b/ports/atmel-samd/boards/robohatmm1_m4/pins.c @@ -0,0 +1,89 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + // SERVO Pins + { MP_ROM_QSTR(MP_QSTR_SERVO1), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_SERVO2), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_SERVO3), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_SERVO4), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_SERVO5), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_SERVO6), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_SERVO7), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_SERVO8), MP_ROM_PTR(&pin_PA08) }, + + // RCC Pins + { MP_ROM_QSTR(MP_QSTR_RCC1), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_RCC2), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_RCC3), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_RCC4), MP_ROM_PTR(&pin_PA04) }, + + // Special Function + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_POWER_OFF), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_POWER_DISABLE), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_POWER_ON), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_POWER_ENABLE), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_PA27) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB03) }, + + // GROVE on SERCOM0 + { MP_ROM_QSTR(MP_QSTR_GROVE_SCL), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_GROVE_SDA), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_GROVE_RX), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_GROVE_TX), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_GROVE_D1), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_GROVE_D0), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_GROVE_A1), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_GROVE_A0), MP_ROM_PTR(&pin_PA08) }, + + // UART on SERCOM0 + { MP_ROM_QSTR(MP_QSTR_UART_TX), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_UART_RX), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_UART_CTS), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_UART_RTS), MP_ROM_PTR(&pin_PA07) }, + + // SPI Flash on SERCOM2 + { MP_ROM_QSTR(MP_QSTR_FLASH_SCK), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_FLASH_MISO), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_FLASH_MOSI), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_FLASH_CS), MP_ROM_PTR(&pin_PA15) }, + + // I2C on SERCOM3 + { MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_PA01) }, + + // SPI on SERCOM4 + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB11) }, + + // GPS on SERCOM5 + { MP_ROM_QSTR(MP_QSTR_GPS_TX), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_GPS_RX), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_GPS_SDA), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_GPS_SCL), MP_ROM_PTR(&pin_PA01) }, + + // Raspberry Pi + { MP_ROM_QSTR(MP_QSTR_PI_GP25), MP_ROM_PTR(&pin_PA30) }, + { MP_ROM_QSTR(MP_QSTR_SWCLK), MP_ROM_PTR(&pin_PA30) }, + { MP_ROM_QSTR(MP_QSTR_PI_GP24), MP_ROM_PTR(&pin_PA31) }, + { MP_ROM_QSTR(MP_QSTR_SWDIO), MP_ROM_PTR(&pin_PA31) }, + { MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_PI_TX), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_PI_RX), MP_ROM_PTR(&pin_PA17) }, + + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/sam32/board.c b/ports/atmel-samd/boards/sam32/board.c new file mode 100644 index 00000000000..7a23d300703 --- /dev/null +++ b/ports/atmel-samd/boards/sam32/board.c @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "boards/board.h" +#include "py/mpconfig.h" + +#include "common-hal/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/neopixel_write/__init__.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + uint8_t zeroes[96]; + memset(zeroes, 0, 96); + digitalio_digitalinout_obj_t neopixel; + common_hal_digitalio_digitalinout_construct(&neopixel, &pin_PA15); + common_hal_digitalio_digitalinout_switch_to_output(&neopixel, false, DRIVE_MODE_PUSH_PULL); + common_hal_neopixel_write(&neopixel, zeroes, 96); + common_hal_digitalio_digitalinout_deinit(&neopixel); +} \ No newline at end of file diff --git a/ports/atmel-samd/boards/sam32/mpconfigboard.h b/ports/atmel-samd/boards/sam32/mpconfigboard.h new file mode 100644 index 00000000000..f6d3fb6b462 --- /dev/null +++ b/ports/atmel-samd/boards/sam32/mpconfigboard.h @@ -0,0 +1,33 @@ + +#define MICROPY_HW_BOARD_NAME "SAM32v2a" +#define MICROPY_HW_MCU_NAME "samd51j20" +#define CIRCUITPY_MCU_FAMILY samd51 + +#define MICROPY_HW_LED_STATUS (&pin_PA27) +#define MICROPY_HW_NEOPIXEL (&pin_PA15) + +#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +#define CIRCUITPY_INTERNAL_NVM_SIZE 0 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - 0x010000) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA04) +#define DEFAULT_I2C_BUS_SDA (&pin_PA07) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB13) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB12) +#define DEFAULT_SPI_BUS_MISO (&pin_PB14) + +#define DEFAULT_UART_BUS_TX (&pin_PB16) +#define DEFAULT_UART_BUS_RX (&pin_PB17) + +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/sam32/mpconfigboard.mk b/ports/atmel-samd/boards/sam32/mpconfigboard.mk new file mode 100644 index 00000000000..12884a9cc8d --- /dev/null +++ b/ports/atmel-samd/boards/sam32/mpconfigboard.mk @@ -0,0 +1,11 @@ +LD_FILE = boards/samd51x20-bootloader.ld +USB_VID = 0x04D8 +USB_PID = 0xEDBE +USB_PRODUCT = "SAM32" +USB_MANUFACTURER = "maholli" + +CHIP_VARIANT = SAMD51J20A +CHIP_FAMILY = samd51 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = MPZ diff --git a/ports/atmel-samd/boards/sam32/pins.c b/ports/atmel-samd/boards/sam32/pins.c new file mode 100644 index 00000000000..f32057d754b --- /dev/null +++ b/ports/atmel-samd/boards/sam32/pins.c @@ -0,0 +1,57 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PB04) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PB05) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PB06) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PB07) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB13) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB12) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB14) }, + { MP_ROM_QSTR(MP_QSTR_xSDCS),MP_ROM_PTR(&pin_PB15) }, + + { MP_ROM_QSTR(MP_QSTR_DAC0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_PA05) }, + + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D29), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_D30), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_D31), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D41), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D42), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_D44), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D49), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_D50), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_D59), MP_ROM_PTR(&pin_PB30) }, + { MP_ROM_QSTR(MP_QSTR_D60), MP_ROM_PTR(&pin_PB31) }, + { MP_ROM_QSTR(MP_QSTR_D64), MP_ROM_PTR(&pin_PB03) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB16) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB17) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA04) }, + + { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_DTR), MP_ROM_PTR(&pin_PB10) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA15) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PA06) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); \ No newline at end of file diff --git a/ports/atmel-samd/boards/samd21x18-bootloader-crystalless.ld b/ports/atmel-samd/boards/samd21x18-bootloader-crystalless.ld new file mode 100644 index 00000000000..2adf4fa9098 --- /dev/null +++ b/ports/atmel-samd/boards/samd21x18-bootloader-crystalless.ld @@ -0,0 +1,84 @@ +/* + GNU linker script for SAMD21x18 (256K flash, 32K RAM) +*/ + +/* Specify the memory areas */ +MEMORY +{ + /* Leave 8KiB for the bootloader, 256b for persistent config (clock), 64k for the flash file system and 256b for the user config. */ + FLASH (rx) : ORIGIN = 0x00000000 + 8K, LENGTH = 256K - 8K - 256 - 64K - 256 + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K +} + +/* top end of the stack */ +/* stack must be double-word (8 byte) aligned */ +_estack = ORIGIN(RAM) + LENGTH(RAM) - 8; +_bootloader_dbl_tap = ORIGIN(RAM) + LENGTH(RAM) - 4; + +/* define output sections */ +SECTIONS +{ + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors)) /* isr vector table */ + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + . = ALIGN(4); + } >FLASH + + .ARM.exidx : + { + *(.ARM.exidx*) + *(.gnu.linkonce.armexidx.*) + _etext = .; /* define a global symbol at end of code */ + _sidata = .; /* start of .data section */ + } > 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); + _srelocate = .; /* create a global symbol at data start; used by startup code in order to initialize the .data section in RAM */ + *(.ramfunc) + *(.ramfunc*) + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _erelocate = .; /* define a global symbol at data end; used by startup code in order to initialize the .data section in RAM */ + } >RAM + + /* Uninitialized data section */ + .bss : + { + . = ALIGN(4); + _sbss = .; + _szero = .; /* define a global symbol at bss start; used by startup code */ + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ezero = .; /* define a global symbol at bss end; used by startup code */ + _ebss = .; + } >RAM + + /* this just checks there is enough RAM for a minimal stack */ + .stack : + { + . = ALIGN(4); + . = . + 2K; /* Reserve a minimum of 2K for the stack. */ + . = ALIGN(4); + } >RAM + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/ports/atmel-samd/boards/samd21x18-bootloader-external-flash-crystalless.ld b/ports/atmel-samd/boards/samd21x18-bootloader-external-flash-crystalless.ld new file mode 100644 index 00000000000..bddaae99daa --- /dev/null +++ b/ports/atmel-samd/boards/samd21x18-bootloader-external-flash-crystalless.ld @@ -0,0 +1,84 @@ +/* + GNU linker script for SAMD21x18 (256K flash, 32K RAM) +*/ + +/* Specify the memory areas */ +MEMORY +{ + /* Leave 8KiB for the bootloader, 256b for internal config and 256b for user config. */ + FLASH (rx) : ORIGIN = 0x00000000 + 8K, LENGTH = 256K - 8K - 256 - 256 + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K +} + +/* top end of the stack */ +/* stack must be double-word (8 byte) aligned */ +_estack = ORIGIN(RAM) + LENGTH(RAM) - 8; +_bootloader_dbl_tap = ORIGIN(RAM) + LENGTH(RAM) - 4; + +/* define output sections */ +SECTIONS +{ + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors)) /* isr vector table */ + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + . = ALIGN(4); + } >FLASH + + .ARM.exidx : + { + *(.ARM.exidx*) + *(.gnu.linkonce.armexidx.*) + _etext = .; /* define a global symbol at end of code */ + _sidata = .; /* start of .data section */ + } > 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); + _srelocate = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + *(.ramfunc) + *(.ramfunc*) + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _erelocate = .; /* 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 = .; + _szero = .; /* define a global symbol at bss start; used by startup code */ + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ezero = .; /* define a global symbol at bss end; used by startup code */ + _ebss = .; + } >RAM + + /* this just checks there is enough RAM for a minimal stack */ + .stack : + { + . = ALIGN(4); + . = . + 2K; /* Reserve a minimum of 2K for the stack. */ + . = ALIGN(4); + } >RAM + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/ports/atmel-samd/boards/samd21x18-bootloader-external-flash.ld b/ports/atmel-samd/boards/samd21x18-bootloader-external-flash.ld new file mode 100644 index 00000000000..4e677a079f4 --- /dev/null +++ b/ports/atmel-samd/boards/samd21x18-bootloader-external-flash.ld @@ -0,0 +1,84 @@ +/* + GNU linker script for SAMD21x18 (256K flash, 32K RAM) +*/ + +/* Specify the memory areas */ +MEMORY +{ + /* Leave 8KiB for the bootloader and 256b for user config. */ + FLASH (rx) : ORIGIN = 0x00000000 + 8K, LENGTH = 256K - 8K - 256 + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K /* 32 KiB RAM */ +} + +/* top end of the stack */ +/* stack must be double-word (8 byte) aligned */ +_estack = ORIGIN(RAM) + LENGTH(RAM) - 8; +_bootloader_dbl_tap = ORIGIN(RAM) + LENGTH(RAM) - 4; + +/* define output sections */ +SECTIONS +{ + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors)) /* isr vector table */ + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + . = ALIGN(4); + } >FLASH + + .ARM.exidx : + { + *(.ARM.exidx*) + *(.gnu.linkonce.armexidx.*) + _etext = .; /* define a global symbol at end of code */ + _sidata = .; /* start of .data section */ + } > 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 ( _etext ) + { + . = ALIGN(4); + _srelocate = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + *(.ramfunc) + *(.ramfunc*) + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _erelocate = .; /* 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 = .; + _szero = .; /* define a global symbol at bss start; used by startup code */ + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ezero = .; /* define a global symbol at bss end; used by startup code */ + _ebss = .; + } >RAM + + /* this just checks there is enough RAM for a minimal stack */ + .stack : + { + . = ALIGN(4); + . = . + 2K; /* Reserve a minimum of 2K for the stack. */ + . = ALIGN(4); + } >RAM + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/ports/atmel-samd/boards/samd21x18-bootloader.ld b/ports/atmel-samd/boards/samd21x18-bootloader.ld new file mode 100644 index 00000000000..2ef09ba9aff --- /dev/null +++ b/ports/atmel-samd/boards/samd21x18-bootloader.ld @@ -0,0 +1,85 @@ +/* + GNU linker script for SAMD21x18 (256K flash, 32K RAM) +*/ + +/* Specify the memory areas */ +MEMORY +{ + /* Leave 8KiB for the bootloader, 64k for the flash file system, and 256b + for user config. */ + FLASH (rx) : ORIGIN = 0x00000000 + 8K, LENGTH = 256K - 8K - 64K - 256 + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K +} + +/* top end of the stack */ +/* stack must be double-word (8 byte) aligned */ +_estack = ORIGIN(RAM) + LENGTH(RAM) - 8; +_bootloader_dbl_tap = ORIGIN(RAM) + LENGTH(RAM) - 4; + +/* define output sections */ +SECTIONS +{ + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors)) /* isr vector table */ + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + . = ALIGN(4); + } >FLASH + + .ARM.exidx : + { + *(.ARM.exidx*) + *(.gnu.linkonce.armexidx.*) + _etext = .; /* define a global symbol at end of code */ + _sidata = .; /* start of .data section */ + } > 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); + _srelocate = .; /* create a global symbol at data start; used by startup code in order to initialize the .data section in RAM */ + *(.ramfunc) + *(.ramfunc*) + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _erelocate = .; /* define a global symbol at data end; used by startup code in order to initialize the .data section in RAM */ + } >RAM + + /* Uninitialized data section */ + .bss : + { + . = ALIGN(4); + _sbss = .; + _szero = .; /* define a global symbol at bss start; used by startup code */ + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ezero = .; /* define a global symbol at bss end; used by startup code */ + _ebss = .; + } >RAM + + /* this just checks there is enough RAM for a minimal stack */ + .stack : + { + . = ALIGN(4); + . = . + 2K; /* Reserve a minimum of 2K for the stack. */ + . = ALIGN(4); + } >RAM + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/ports/atmel-samd/boards/samd21x18-external-flash.ld b/ports/atmel-samd/boards/samd21x18-external-flash.ld new file mode 100644 index 00000000000..a540bfde2af --- /dev/null +++ b/ports/atmel-samd/boards/samd21x18-external-flash.ld @@ -0,0 +1,83 @@ +/* + GNU linker script for SAMD21x18 (256K flash, 32K RAM) +*/ + +/* Specify the memory areas */ +MEMORY +{ + /* 256 KiB but leave 256b for internal config and 256b for user config (protected eeprom) */ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K - 256 - 256 + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K +} + +/* top end of the stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); +_bootloader_dbl_tap = 0; + +/* define output sections */ +SECTIONS +{ + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors)) /* isr vector table */ + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + . = ALIGN(4); + } >FLASH + + .ARM.exidx : + { + *(.ARM.exidx*) + *(.gnu.linkonce.armexidx.*) + _etext = .; /* define a global symbol at end of code */ + _sidata = .; /* start of .data section */ + } > 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); + _srelocate = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + *(.ramfunc) + *(.ramfunc*) + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _erelocate = .; /* 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 = .; + _szero = .; /* define a global symbol at bss start; used by startup code */ + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ezero = .; /* define a global symbol at bss end; used by startup code */ + _ebss = .; + } >RAM + + /* this just checks there is enough RAM for a minimal stack */ + .stack : + { + . = ALIGN(4); + . = . + 2K; /* Reserve a minimum of 2K for the stack. */ + . = ALIGN(4); + } >RAM + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/ports/atmel-samd/boards/samd21x18.ld b/ports/atmel-samd/boards/samd21x18.ld new file mode 100644 index 00000000000..139be86bb21 --- /dev/null +++ b/ports/atmel-samd/boards/samd21x18.ld @@ -0,0 +1,83 @@ +/* + GNU linker script for SAMD21x18 (256K flash, 32K RAM) +*/ + +/* Specify the memory areas */ +MEMORY +{ + /* Leave 256b for internal config, 64k for the flash file system and 256b for user config. */ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K - 256 - 64K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K +} + +/* top end of the stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); +_bootloader_dbl_tap = 0; + +/* define output sections */ +SECTIONS +{ + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors)) /* isr vector table */ + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + . = ALIGN(4); + } >FLASH + + .ARM.exidx : + { + *(.ARM.exidx*) + *(.gnu.linkonce.armexidx.*) + _etext = .; /* define a global symbol at end of code */ + _sidata = .; /* start of .data section */ + } > 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); + _srelocate = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + *(.ramfunc) + *(.ramfunc*) + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _erelocate = .; /* 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 = .; + _szero = .; /* define a global symbol at bss start; used by startup code */ + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ezero = .; /* define a global symbol at bss end; used by startup code */ + _ebss = .; + } >RAM + + /* this just checks there is enough RAM for a minimal stack */ + .stack : + { + . = ALIGN(4); + . = . + 2K; /* Reserve a minimum of 2K for the stack. */ + . = ALIGN(4); + } >RAM + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/ports/atmel-samd/boards/samd51x18-bootloader-external-flash.ld b/ports/atmel-samd/boards/samd51x18-bootloader-external-flash.ld new file mode 100644 index 00000000000..c0e812ce194 --- /dev/null +++ b/ports/atmel-samd/boards/samd51x18-bootloader-external-flash.ld @@ -0,0 +1,84 @@ +/* + GNU linker script for SAMD51x18 (256K flash, 128K RAM) +*/ + +/* Specify the memory areas */ +MEMORY +{ + /* Leave 16KiB for the bootloader. 8K for user data*/ + FLASH (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 256K - 16K - 8K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* top end of the stack */ +/* stack must be double-word (8 byte) aligned */ +_estack = ORIGIN(RAM) + LENGTH(RAM) - 8; +_bootloader_dbl_tap = ORIGIN(RAM) + LENGTH(RAM) - 4; + +/* define output sections */ +SECTIONS +{ + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors)) /* isr vector table */ + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + . = ALIGN(4); + } >FLASH + + .ARM.exidx : + { + *(.ARM.exidx*) + *(.gnu.linkonce.armexidx.*) + _etext = .; /* define a global symbol at end of code */ + _sidata = .; /* start of .data section */ + } > 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); + _srelocate = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + *(.ramfunc) + *(.ramfunc*) + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _erelocate = .; /* 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 = .; + _szero = .; /* define a global symbol at bss start; used by startup code */ + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ezero = .; /* define a global symbol at bss end; used by startup code */ + _ebss = .; + } >RAM + + /* this just checks there is enough RAM for a minimal stack */ + .stack : + { + . = ALIGN(4); + . = . + 10K; /* Reserve a minimum of 10K for the stack. nvm will temporarily store 8k on the stack when writing. */ + . = ALIGN(4); + } >RAM + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/ports/atmel-samd/boards/samd51x19-bootloader-external-flash.ld b/ports/atmel-samd/boards/samd51x19-bootloader-external-flash.ld new file mode 100644 index 00000000000..253a764c9b4 --- /dev/null +++ b/ports/atmel-samd/boards/samd51x19-bootloader-external-flash.ld @@ -0,0 +1,84 @@ +/* + GNU linker script for SAMD51x19 (512K flash, 192K RAM) +*/ + +/* Specify the memory areas */ +MEMORY +{ + /* Leave 16KiB for the bootloader. 8K for user data*/ + FLASH (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 512K - 16K - 8K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K +} + +/* top end of the stack */ +/* stack must be double-word (8 byte) aligned */ +_estack = ORIGIN(RAM) + LENGTH(RAM) - 8; +_bootloader_dbl_tap = ORIGIN(RAM) + LENGTH(RAM) - 4; + +/* define output sections */ +SECTIONS +{ + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors)) /* isr vector table */ + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + . = ALIGN(4); + } >FLASH + + .ARM.exidx : + { + *(.ARM.exidx*) + *(.gnu.linkonce.armexidx.*) + _etext = .; /* define a global symbol at end of code */ + _sidata = .; /* start of .data section */ + } > 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); + _srelocate = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + *(.ramfunc) + *(.ramfunc*) + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _erelocate = .; /* 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 = .; + _szero = .; /* define a global symbol at bss start; used by startup code */ + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ezero = .; /* define a global symbol at bss end; used by startup code */ + _ebss = .; + } >RAM + + /* this just checks there is enough RAM for a minimal stack */ + .stack : + { + . = ALIGN(4); + . = . + 10K; /* Reserve a minimum of 10K for the stack. nvm will temporarily store 8k on the stack when writing. */ + . = ALIGN(4); + } >RAM + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/ports/atmel-samd/boards/samd51x19-bootloader.ld b/ports/atmel-samd/boards/samd51x19-bootloader.ld new file mode 100644 index 00000000000..56786a37afb --- /dev/null +++ b/ports/atmel-samd/boards/samd51x19-bootloader.ld @@ -0,0 +1,84 @@ +/* + GNU linker script for SAMD51x19 (512K flash, 192K RAM) +*/ + +/* Specify the memory areas */ +MEMORY +{ + /* Leave 16KiB for the bootloader, 256KiB for the internal file system, and 8KiB for user binary data. */ + FLASH (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 512K - 16K - 256K - 8K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K +} + +/* top end of the stack */ +/* stack must be double-word (8 byte) aligned */ +_estack = ORIGIN(RAM) + LENGTH(RAM) - 8; +_bootloader_dbl_tap = ORIGIN(RAM) + LENGTH(RAM) - 4; + +/* define output sections */ +SECTIONS +{ + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors)) /* isr vector table */ + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + . = ALIGN(4); + } >FLASH + + .ARM.exidx : + { + *(.ARM.exidx*) + *(.gnu.linkonce.armexidx.*) + _etext = .; /* define a global symbol at end of code */ + _sidata = .; /* start of .data section */ + } > 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); + _srelocate = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + *(.ramfunc) + *(.ramfunc*) + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _erelocate = .; /* 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 = .; + _szero = .; /* define a global symbol at bss start; used by startup code */ + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ezero = .; /* define a global symbol at bss end; used by startup code */ + _ebss = .; + } >RAM + + /* this just checks there is enough RAM for a minimal stack */ + .stack : + { + . = ALIGN(4); + . = . + 10K; /* Reserve a minimum of 10K for the stack. nvm will temporarily store 8k on the stack when writing. */ + . = ALIGN(4); + } >RAM + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/ports/atmel-samd/boards/samd51x20-bootloader-external-flash.ld b/ports/atmel-samd/boards/samd51x20-bootloader-external-flash.ld new file mode 100644 index 00000000000..598915b1b7b --- /dev/null +++ b/ports/atmel-samd/boards/samd51x20-bootloader-external-flash.ld @@ -0,0 +1,84 @@ +/* + GNU linker script for SAMD51x20 (1MB flash, 256K RAM) +*/ + +/* Specify the memory areas */ +MEMORY +{ + /* Leave 16KiB for the bootloader. */ + FLASH (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 1M - 16K - 8K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K +} + +/* top end of the stack */ +/* stack must be double-word (8 byte) aligned */ +_estack = ORIGIN(RAM) + LENGTH(RAM) - 8; +_bootloader_dbl_tap = ORIGIN(RAM) + LENGTH(RAM) - 4; + +/* define output sections */ +SECTIONS +{ + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors)) /* isr vector table */ + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + . = ALIGN(4); + } >FLASH + + .ARM.exidx : + { + *(.ARM.exidx*) + *(.gnu.linkonce.armexidx.*) + _etext = .; /* define a global symbol at end of code */ + _sidata = .; /* start of .data section */ + } > 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); + _srelocate = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + *(.ramfunc) + *(.ramfunc*) + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _erelocate = .; /* 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 = .; + _szero = .; /* define a global symbol at bss start; used by startup code */ + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ezero = .; /* define a global symbol at bss end; used by startup code */ + _ebss = .; + } >RAM + + /* this just checks there is enough RAM for a minimal stack */ + .stack : + { + . = ALIGN(4); + . = . + 10K; /* Reserve a minimum of 10K for the stack. nvm will temporarily store 8k on the stack when writing. */ + . = ALIGN(4); + } >RAM + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/ports/atmel-samd/boards/samd51x20-bootloader.ld b/ports/atmel-samd/boards/samd51x20-bootloader.ld new file mode 100644 index 00000000000..49d4d879143 --- /dev/null +++ b/ports/atmel-samd/boards/samd51x20-bootloader.ld @@ -0,0 +1,84 @@ +/* + GNU linker script for SAMD51x20 (1MB flash, 256K RAM) +*/ + +/* Specify the memory areas */ +MEMORY +{ + /* Leave 16KiB for the bootloader, 512k for the filesystem and 8k for user config data. */ + FLASH (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 1M - 16K - 512K - 8K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K +} + +/* top end of the stack */ +/* stack must be double-word (8 byte) aligned */ +_estack = ORIGIN(RAM) + LENGTH(RAM) - 8; +_bootloader_dbl_tap = ORIGIN(RAM) + LENGTH(RAM) - 4; + +/* define output sections */ +SECTIONS +{ + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors)) /* isr vector table */ + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + . = ALIGN(4); + } >FLASH + + .ARM.exidx : + { + *(.ARM.exidx*) + *(.gnu.linkonce.armexidx.*) + _etext = .; /* define a global symbol at end of code */ + _sidata = .; /* start of .data section */ + } > 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); + _srelocate = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + *(.ramfunc) + *(.ramfunc*) + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _erelocate = .; /* 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 = .; + _szero = .; /* define a global symbol at bss start; used by startup code */ + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ezero = .; /* define a global symbol at bss end; used by startup code */ + _ebss = .; + } >RAM + + /* this just checks there is enough RAM for a minimal stack */ + .stack : + { + . = ALIGN(4); + . = . + 10K; /* Reserve a minimum of 10K for the stack. nvm will temporarily store 8k on the stack when writing. */ + . = ALIGN(4); + } >RAM + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/ports/atmel-samd/boards/samd51x20-external-flash.ld b/ports/atmel-samd/boards/samd51x20-external-flash.ld new file mode 100644 index 00000000000..d3ed90476e1 --- /dev/null +++ b/ports/atmel-samd/boards/samd51x20-external-flash.ld @@ -0,0 +1,82 @@ +/* + GNU linker script for SAMD51x20 (1MB flash, 256K RAM) +*/ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 1M - 8K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K +} + +/* top end of the stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); +_bootloader_dbl_tap = 0; + +/* define output sections */ +SECTIONS +{ + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors)) /* isr vector table */ + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + . = ALIGN(4); + } >FLASH + + .ARM.exidx : + { + *(.ARM.exidx*) + *(.gnu.linkonce.armexidx.*) + _etext = .; /* define a global symbol at end of code */ + _sidata = .; /* start of .data section */ + } > 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); + _srelocate = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + *(.ramfunc) + *(.ramfunc*) + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _erelocate = .; /* 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 = .; + _szero = .; /* define a global symbol at bss start; used by startup code */ + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ezero = .; /* define a global symbol at bss end; used by startup code */ + _ebss = .; + } >RAM + + /* this just checks there is enough RAM for a minimal stack */ + .stack : + { + . = ALIGN(4); + . = . + 10K; /* Reserve a minimum of 10K for the stack. nvm will temporarily store 8k on the stack when writing. */ + . = ALIGN(4); + } >RAM + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/ports/atmel-samd/boards/samd51x20.ld b/ports/atmel-samd/boards/samd51x20.ld new file mode 100644 index 00000000000..e203c5b7a99 --- /dev/null +++ b/ports/atmel-samd/boards/samd51x20.ld @@ -0,0 +1,83 @@ +/* + GNU linker script for SAMD51x20 (1MB flash, 256K RAM) +*/ + +/* Specify the memory areas */ +MEMORY +{ + /* 1024 KiB minus 512KiB for the internal file system and 8KiB for the user nvm. */ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 1M - 512K - 8K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K +} + +/* top end of the stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); +_bootloader_dbl_tap = 0; + +/* define output sections */ +SECTIONS +{ + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors)) /* isr vector table */ + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + . = ALIGN(4); + } >FLASH + + .ARM.exidx : + { + *(.ARM.exidx*) + *(.gnu.linkonce.armexidx.*) + _etext = .; /* define a global symbol at end of code */ + _sidata = .; /* start of .data section */ + } > 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); + _srelocate = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + *(.ramfunc) + *(.ramfunc*) + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _erelocate = .; /* 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 = .; + _szero = .; /* define a global symbol at bss start; used by startup code */ + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ezero = .; /* define a global symbol at bss end; used by startup code */ + _ebss = .; + } >RAM + + /* this just checks there is enough RAM for a minimal stack */ + .stack : + { + . = ALIGN(4); + . = . + 10K; /* Reserve a minimum of 10K for the stack. nvm will temporarily store 8k on the stack when writing. */ + . = ALIGN(4); + } >RAM + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/ports/atmel-samd/boards/snekboard/board.c b/ports/atmel-samd/boards/snekboard/board.c new file mode 100644 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/snekboard/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/snekboard/mpconfigboard.h b/ports/atmel-samd/boards/snekboard/mpconfigboard.h new file mode 100644 index 00000000000..a349143d91d --- /dev/null +++ b/ports/atmel-samd/boards/snekboard/mpconfigboard.h @@ -0,0 +1,35 @@ +#define MICROPY_HW_BOARD_NAME "keithp.com snekboard" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_HW_LED_STATUS (&pin_PA02) + +#define MICROPY_HW_NEOPIXEL (&pin_PB11) + +#define SPI_FLASH_MOSI_PIN &pin_PB22 +#define SPI_FLASH_MISO_PIN &pin_PB03 +#define SPI_FLASH_SCK_PIN &pin_PB23 +#define SPI_FLASH_CS_PIN &pin_PA27 + +// These are pins not to reset. +#define MICROPY_PORT_A (PORT_PB11) +#define MICROPY_PORT_B ( 0 ) +#define MICROPY_PORT_C ( 0 ) + + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code. +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 0 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA08) /* ANALOG 5 */ +#define DEFAULT_I2C_BUS_SDA (&pin_PA09) /* ANALOG 6 */ + +#define DEFAULT_UART_BUS_RX (&pin_PB08) /* ANALOG 1 */ +#define DEFAULT_UART_BUS_TX (&pin_PB09) /* ANALOG 2 */ + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/snekboard/mpconfigboard.mk b/ports/atmel-samd/boards/snekboard/mpconfigboard.mk new file mode 100644 index 00000000000..db2e511abfb --- /dev/null +++ b/ports/atmel-samd/boards/snekboard/mpconfigboard.mk @@ -0,0 +1,20 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x804E +USB_PRODUCT = "snekboard" +USB_MANUFACTURER = "keithp.com" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "W25Q16JV_IQ" +LONGINT_IMPL = MPZ + +CIRCUITPY_BITBANGIO = 0 +CIRCUITPY_GAMEPAD = 0 +CIRCUITPY_I2CSLAVE = 0 + +CFLAGS_INLINE_LIMIT = 60 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/snekboard/pins.c b/ports/atmel-samd/boards/snekboard/pins.c new file mode 100644 index 00000000000..48bdc672e08 --- /dev/null +++ b/ports/atmel-samd/boards/snekboard/pins.c @@ -0,0 +1,28 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_POWER1), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_DIR1), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_POWER2), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_DIR2), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_POWER3), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_DIR3), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_POWER4), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_DIR4), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/sparkfun_lumidrive/board.c b/ports/atmel-samd/boards/sparkfun_lumidrive/board.c new file mode 100755 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_lumidrive/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.h b/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.h new file mode 100755 index 00000000000..80cacfa9b07 --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.h @@ -0,0 +1,55 @@ +#define MICROPY_HW_BOARD_NAME "SparkFun LUMIDrive" +#define MICROPY_HW_MCU_NAME "samd21g18" + +// Clock rates are off: Salae reads 12MHz which is the limit even though we set it to the safer 8MHz. +#define SPI_FLASH_BAUDRATE (8000000) + +#define SPI_FLASH_MOSI_PIN &pin_PA08 +#define SPI_FLASH_MISO_PIN &pin_PA14 +#define SPI_FLASH_SCK_PIN &pin_PA09 +#define SPI_FLASH_CS_PIN &pin_PA13 + +#define MICROPY_PORT_A ( 0 ) +#define MICROPY_PORT_B ( 0 ) +#define MICROPY_PORT_C ( 0 ) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +//I2C +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +//SPI +#define DEFAULT_SPI_BUS_SCK (&pin_PA19) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA18) +#define DEFAULT_SPI_BUS_MISO (&pin_PA21) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 + +#define IGNORE_PIN_PA02 1 +#define IGNORE_PIN_PA03 1 +#define IGNORE_PIN_PA10 1 +#define IGNORE_PIN_PA11 1 +#define IGNORE_PIN_PA12 1 +#define IGNORE_PIN_PA15 1 +#define IGNORE_PIN_PA16 1 +#define IGNORE_PIN_PA21 1 +#define IGNORE_PIN_PA22 1 +#define IGNORE_PIN_PA23 1 +#define IGNORE_PIN_PA27 1 +#define IGNORE_PIN_PA28 1 + +#define IGNORE_PIN_PB02 1 +#define IGNORE_PIN_PB03 1 +#define IGNORE_PIN_PB08 1 +#define IGNORE_PIN_PB09 1 +#define IGNORE_PIN_PB10 1 +#define IGNORE_PIN_PB11 1 +#define IGNORE_PIN_PB22 1 +#define IGNORE_PIN_PB23 1 diff --git a/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk new file mode 100755 index 00000000000..9d0ef1c0409 --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk @@ -0,0 +1,18 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash.ld +USB_VID = 0x1B4F +USB_PID = 0x0017 +USB_PRODUCT = "LUMIDrive Board" +USB_MANUFACTURER = "SparkFun Electronics" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "W25Q32FV" +LONGINT_IMPL = MPZ + +CIRCUITPY_AUDIOIO = 0 +CIRCUITPY_AUDIOBUSIO = 0 + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar diff --git a/ports/atmel-samd/boards/sparkfun_lumidrive/pins.c b/ports/atmel-samd/boards/sparkfun_lumidrive/pins.c new file mode 100755 index 00000000000..52c0753d41e --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_lumidrive/pins.c @@ -0,0 +1,15 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA19) }, // + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA18) }, // + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, // + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, // + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, // + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/sparkfun_redboard_turbo/board.c b/ports/atmel-samd/boards/sparkfun_redboard_turbo/board.c new file mode 100755 index 00000000000..c8e20206a19 --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_redboard_turbo/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.h b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.h new file mode 100755 index 00000000000..cf7c3998bba --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.h @@ -0,0 +1,47 @@ +#define MICROPY_HW_BOARD_NAME "SparkFun RedBoard Turbo" +#define MICROPY_HW_MCU_NAME "samd21g18" + + +#define MICROPY_HW_LED_TX &pin_PA27 +#define MICROPY_HW_LED_RX &pin_PA31 + +#define MICROPY_HW_NEOPIXEL (&pin_PA30) + +// Clock rates are off: Salae reads 12MHz which is the limit even though we set it to the safer 8MHz. +#define SPI_FLASH_BAUDRATE (8000000) + +#define SPI_FLASH_MOSI_PIN &pin_PB22 +#define SPI_FLASH_MISO_PIN &pin_PB03 +#define SPI_FLASH_SCK_PIN &pin_PB23 +#define SPI_FLASH_CS_PIN &pin_PA13 + +#define MICROPY_PORT_A ( 0 ) +#define MICROPY_PORT_B ( 0 ) +#define MICROPY_PORT_C ( 0 ) + + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code. +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + + +// I2C - also QWIIC +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + + +#define DEFAULT_SPI_BUS_SCK (&pin_PB11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk new file mode 100755 index 00000000000..e80ef627717 --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk @@ -0,0 +1,19 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash.ld +USB_VID = 0x1B4F +USB_PID = 0x0015 +USB_PRODUCT = "RedBoard Turbo Board" +USB_MANUFACTURER = "SparkFun Electronics" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "W25Q32FV" +LONGINT_IMPL = MPZ + +CIRCUITPY_BITBANGIO = 0 +CIRCUITPY_I2CSLAVE = 0 + +CFLAGS_INLINE_LIMIT = 60 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/sparkfun_redboard_turbo/pins.c b/ports/atmel-samd/boards/sparkfun_redboard_turbo/pins.c new file mode 100755 index 00000000000..485589fcafa --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_redboard_turbo/pins.c @@ -0,0 +1,36 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_RGB_LED), MP_ROM_PTR(&pin_PA30) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/sparkfun_samd21_dev/board.c b/ports/atmel-samd/boards/sparkfun_samd21_dev/board.c new file mode 100644 index 00000000000..0f60736a240 --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_samd21_dev/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.h b/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.h new file mode 100644 index 00000000000..a50c61cf2da --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.h @@ -0,0 +1,24 @@ +#define MICROPY_HW_BOARD_NAME "SparkFun SAMD21 Dev Breakout" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk new file mode 100644 index 00000000000..c9d0baf11f7 --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x1B4F +USB_PID = 0x8D23 +USB_PRODUCT = "SparkFun SAMD21 Dev Breakout" +USB_MANUFACTURER = "SparkFun" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/sparkfun_samd21_dev/pins.c b/ports/atmel-samd/boards/sparkfun_samd21_dev/pins.c new file mode 100644 index 00000000000..039100956ef --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_samd21_dev/pins.c @@ -0,0 +1,58 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + + // Analog pins + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) }, + + // Digital pins + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_D30), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_D31), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_PA13) }, + + // UART pins + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_PB23) }, + + // SPI pins + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + + // I2C pins + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + + // LED pins + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_GREEN_LED), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_YELLOW_LED), MP_ROM_PTR(&pin_PB03) }, + + // Comm objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/sparkfun_samd21_mini/board.c b/ports/atmel-samd/boards/sparkfun_samd21_mini/board.c new file mode 100644 index 00000000000..0f60736a240 --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.h b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.h new file mode 100644 index 00000000000..6af7fa19181 --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.h @@ -0,0 +1,24 @@ +#define MICROPY_HW_BOARD_NAME "SparkFun SAMD21 Mini Breakout" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA17) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA16) +#define DEFAULT_SPI_BUS_MISO (&pin_PA19) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk new file mode 100644 index 00000000000..a6e216575e0 --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x1B4F +USB_PID = 0x8D22 +USB_PRODUCT = "SparkFun SAMD21 Mini Breakout" +USB_MANUFACTURER = "SparkFun" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c b/ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c new file mode 100644 index 00000000000..a90b0b5a30f --- /dev/null +++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c @@ -0,0 +1,51 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + + // Analog pins + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + + // Digital pins + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + + // UART pins + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + + // SPI pins + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA19) }, + + // I2C pins + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + + // LED pins + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_GREEN_LED), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_YELLOW_LED), MP_ROM_PTR(&pin_PB03) }, + + // Comm objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/trellis_m4_express/board.c b/ports/atmel-samd/boards/trellis_m4_express/board.c new file mode 100644 index 00000000000..a9b5f81631c --- /dev/null +++ b/ports/atmel-samd/boards/trellis_m4_express/board.c @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "boards/board.h" +#include "py/mpconfig.h" + +#include "common-hal/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/neopixel_write/__init__.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + uint8_t zeroes[96]; + memset(zeroes, 0, 96); + digitalio_digitalinout_obj_t neopixel; + common_hal_digitalio_digitalinout_construct(&neopixel, &pin_PA27); + common_hal_digitalio_digitalinout_switch_to_output(&neopixel, false, DRIVE_MODE_PUSH_PULL); + common_hal_neopixel_write(&neopixel, zeroes, 96); + common_hal_digitalio_digitalinout_deinit(&neopixel); +} diff --git a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h new file mode 100644 index 00000000000..8ca1df16217 --- /dev/null +++ b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.h @@ -0,0 +1,32 @@ + +#define MICROPY_HW_BOARD_NAME "Adafruit Trellis M4 Express" +#define MICROPY_HW_MCU_NAME "samd51g19" + +#define CIRCUITPY_MCU_FAMILY samd51 + +// This is for Rev D +#define MICROPY_HW_APA102_MOSI (&pin_PB03) +#define MICROPY_HW_APA102_SCK (&pin_PB02) + +// These are pins not to reset. +// QSPI Data pins +#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11) +// DotStar Pins, QSPI CS, and QSPI SCK +#define MICROPY_PORT_B (PORT_PB02 | PORT_PB03 | PORT_PB10 | PORT_PB11) +#define MICROPY_PORT_C (0) +#define MICROPY_PORT_D (0) + +#define AUTORESET_DELAY_MS 500 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code +#define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PB08) +#define DEFAULT_I2C_BUS_SDA (&pin_PB09) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk new file mode 100644 index 00000000000..ec37186c3af --- /dev/null +++ b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk @@ -0,0 +1,19 @@ +LD_FILE = boards/samd51x19-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8030 +USB_PRODUCT = "Trellis M4 Express" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD51G19A +CHIP_FAMILY = samd51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 2 +EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C" +LONGINT_IMPL = MPZ + +CIRCUITPY_PS2IO = 1 +# No I2S on SAMD51G +CIRCUITPY_AUDIOBUSIO = 0 + +CIRCUITPY_BITBANG_APA102 = 1 diff --git a/ports/atmel-samd/boards/trellis_m4_express/pins.c b/ports/atmel-samd/boards/trellis_m4_express/pins.c new file mode 100644 index 00000000000..4a0fa3ca211 --- /dev/null +++ b/ports/atmel-samd/boards/trellis_m4_express/pins.c @@ -0,0 +1,45 @@ +#include "shared-bindings/board/__init__.h" + +// This mapping only includes functional names because pins broken +// out on connectors are labeled with their MCU name available from +// microcontroller.pin. +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA04) }, // INT pin + { MP_OBJ_NEW_QSTR(MP_QSTR_MICOUT), MP_ROM_PTR(&pin_PA06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MICIN), MP_ROM_PTR(&pin_PA07) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB09) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_ACCELEROMETER_SDA), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ACCELEROMETER_SCL), MP_ROM_PTR(&pin_PA13) }, + + // Key Grid columns + { MP_OBJ_NEW_QSTR(MP_QSTR_COL0), MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_COL1), MP_ROM_PTR(&pin_PA15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_COL2), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_COL3), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_COL4), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_COL5), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_COL6), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_COL7), MP_ROM_PTR(&pin_PA23) }, + // Key Grid rows + { MP_OBJ_NEW_QSTR(MP_QSTR_ROW0), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ROW1), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ROW2), MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ROW3), MP_ROM_PTR(&pin_PB23) }, + + // IRQ/GPIO pin + { MP_OBJ_NEW_QSTR(MP_QSTR_INT), MP_ROM_PTR(&pin_PA04) }, + + // NeoPixels + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA27) }, + + { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PB02) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/trinket_m0/board.c b/ports/atmel-samd/boards/trinket_m0/board.c new file mode 100644 index 00000000000..d7e856d6119 --- /dev/null +++ b/ports/atmel-samd/boards/trinket_m0/board.c @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h new file mode 100644 index 00000000000..dd8bc03ccf3 --- /dev/null +++ b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h @@ -0,0 +1,71 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Trinket M0" +#define MICROPY_HW_MCU_NAME "samd21e18" + +// Rev B - Black +#define MICROPY_HW_LED_STATUS (&pin_PA10) + +#define MICROPY_HW_APA102_MOSI (&pin_PA00) +#define MICROPY_HW_APA102_SCK (&pin_PA01) + +#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define IGNORE_PIN_PA03 1 +#define IGNORE_PIN_PA04 1 +#define IGNORE_PIN_PA11 1 +#define IGNORE_PIN_PA12 1 +#define IGNORE_PIN_PA13 1 +#define IGNORE_PIN_PA14 1 +#define IGNORE_PIN_PA15 1 +#define IGNORE_PIN_PA16 1 +#define IGNORE_PIN_PA17 1 +#define IGNORE_PIN_PA18 1 +#define IGNORE_PIN_PA19 1 +#define IGNORE_PIN_PA20 1 +#define IGNORE_PIN_PA21 1 +#define IGNORE_PIN_PA22 1 +#define IGNORE_PIN_PA23 1 +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 +#define IGNORE_PIN_PA27 1 +#define IGNORE_PIN_PA28 1 +#define IGNORE_PIN_PA30 1 +#define IGNORE_PIN_PA31 1 +#define IGNORE_PIN_PB01 1 +#define IGNORE_PIN_PB02 1 +#define IGNORE_PIN_PB03 1 +#define IGNORE_PIN_PB04 1 +#define IGNORE_PIN_PB05 1 +#define IGNORE_PIN_PB06 1 +#define IGNORE_PIN_PB07 1 +#define IGNORE_PIN_PB08 1 +#define IGNORE_PIN_PB09 1 +#define IGNORE_PIN_PB10 1 +#define IGNORE_PIN_PB11 1 +#define IGNORE_PIN_PB12 1 +#define IGNORE_PIN_PB13 1 +#define IGNORE_PIN_PB14 1 +#define IGNORE_PIN_PB15 1 +#define IGNORE_PIN_PB16 1 +#define IGNORE_PIN_PB17 1 +#define IGNORE_PIN_PB22 1 +#define IGNORE_PIN_PB23 1 +#define IGNORE_PIN_PB30 1 +#define IGNORE_PIN_PB31 1 +#define IGNORE_PIN_PB00 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA09) +#define DEFAULT_I2C_BUS_SDA (&pin_PA08) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA07) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA06) +#define DEFAULT_SPI_BUS_MISO (&pin_PA09) + +#define DEFAULT_UART_BUS_RX (&pin_PA07) +#define DEFAULT_UART_BUS_TX (&pin_PA06) diff --git a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk new file mode 100644 index 00000000000..b4a00b654a6 --- /dev/null +++ b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk @@ -0,0 +1,14 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x239A +USB_PID = 0x801F +USB_PRODUCT = "Trinket M0" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/trinket_m0/pins.c b/ports/atmel-samd/boards/trinket_m0/pins.c new file mode 100644 index 00000000000..372601e6287 --- /dev/null +++ b/ports/atmel-samd/boards/trinket_m0/pins.c @@ -0,0 +1,34 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA09) }, + + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA06) }, + + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA07) }, + + { MP_ROM_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA10) }, + + { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/board.c b/ports/atmel-samd/boards/trinket_m0_haxpress/board.c new file mode 100644 index 00000000000..d7e856d6119 --- /dev/null +++ b/ports/atmel-samd/boards/trinket_m0_haxpress/board.c @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h new file mode 100644 index 00000000000..369d84b8b84 --- /dev/null +++ b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h @@ -0,0 +1,39 @@ +#define MICROPY_HW_BOARD_NAME "Trinket M0 Haxpress" +#define MICROPY_HW_MCU_NAME "samd21e18" + +// Rev B - Black +#define MICROPY_HW_LED_STATUS (&pin_PA10) +// #define MICROPY_HW_APA102_MOSI (&pin_PA00) +// #define MICROPY_HW_APA102_SCK (&pin_PA01) + +#define SPI_FLASH_MOSI_PIN &pin_PA16 +#define SPI_FLASH_MISO_PIN &pin_PA19 +#define SPI_FLASH_SCK_PIN &pin_PA17 +#define SPI_FLASH_CS_PIN &pin_PA11 + +// These are pins not to reset. +#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01 | PORT_PA18) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CALIBRATE_CRYSTALLESS 1 + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code. +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA09) +#define DEFAULT_I2C_BUS_SDA (&pin_PA08) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA07) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA06) +#define DEFAULT_SPI_BUS_MISO (&pin_PA09) + +#define DEFAULT_UART_BUS_RX (&pin_PA07) +#define DEFAULT_UART_BUS_TX (&pin_PA06) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk new file mode 100644 index 00000000000..c20358e19ff --- /dev/null +++ b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk @@ -0,0 +1,19 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash-crystalless.ld +USB_VID = 0x239A +USB_PID = 0x801F +USB_PRODUCT="Trinket M0 Haxpress" +USB_MANUFACTURER="Radomir Dopieralski" + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = W25Q32BV +LONGINT_IMPL = MPZ + +CIRCUITPY_BITBANGIO = 0 +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_I2CSLAVE = 0 + +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c b/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c new file mode 100644 index 00000000000..372601e6287 --- /dev/null +++ b/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c @@ -0,0 +1,34 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA09) }, + + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA06) }, + + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA07) }, + + { MP_ROM_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA10) }, + + { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/uchip/board.c b/ports/atmel-samd/boards/uchip/board.c new file mode 100644 index 00000000000..0f60736a240 --- /dev/null +++ b/ports/atmel-samd/boards/uchip/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/uchip/mpconfigboard.h b/ports/atmel-samd/boards/uchip/mpconfigboard.h new file mode 100644 index 00000000000..6dcaf2965c1 --- /dev/null +++ b/ports/atmel-samd/boards/uchip/mpconfigboard.h @@ -0,0 +1,55 @@ +#define MICROPY_HW_BOARD_NAME "uChip" +#define MICROPY_HW_MCU_NAME "samd21e18" + +#define MICROPY_HW_LED_STATUS (&pin_PA07) + +#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01 | PORT_PA14 | PORT_PA15 | PORT_PA28 | PORT_PA27 | PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define CIRCUITPY_INTERNAL_NVM_SIZE 0 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) + + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 + +#define IGNORE_PIN_PA27 1 +#define IGNORE_PIN_PA28 1 +#define IGNORE_PIN_PA30 1 +#define IGNORE_PIN_PA31 1 + +#define IGNORE_PIN_PB01 1 +#define IGNORE_PIN_PB02 1 +#define IGNORE_PIN_PB03 1 +#define IGNORE_PIN_PB04 1 +#define IGNORE_PIN_PB05 1 +#define IGNORE_PIN_PB06 1 +#define IGNORE_PIN_PB07 1 +#define IGNORE_PIN_PB08 1 +#define IGNORE_PIN_PB09 1 +#define IGNORE_PIN_PB10 1 +#define IGNORE_PIN_PB11 1 +#define IGNORE_PIN_PB12 1 +#define IGNORE_PIN_PB13 1 +#define IGNORE_PIN_PB14 1 +#define IGNORE_PIN_PB15 1 +#define IGNORE_PIN_PB16 1 +#define IGNORE_PIN_PB17 1 +#define IGNORE_PIN_PB22 1 +#define IGNORE_PIN_PB23 1 +#define IGNORE_PIN_PB30 1 +#define IGNORE_PIN_PB31 1 +#define IGNORE_PIN_PB00 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA17) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA16) +#define DEFAULT_SPI_BUS_MISO (&pin_PA19) + +#define DEFAULT_UART_BUS_RX (&pin_PA09) +#define DEFAULT_UART_BUS_TX (&pin_PA08) diff --git a/ports/atmel-samd/boards/uchip/mpconfigboard.mk b/ports/atmel-samd/boards/uchip/mpconfigboard.mk new file mode 100644 index 00000000000..109492b7647 --- /dev/null +++ b/ports/atmel-samd/boards/uchip/mpconfigboard.mk @@ -0,0 +1,12 @@ +LD_FILE = boards/samd21x18-bootloader.ld +USB_VID = 0x04D8 +USB_PID = 0xED5F +USB_PRODUCT = "uChip CircuitPython" +USB_MANUFACTURER = "Itaca Innovation" + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 diff --git a/ports/atmel-samd/boards/uchip/pins.c b/ports/atmel-samd/boards/uchip/pins.c new file mode 100644 index 00000000000..856a220742e --- /dev/null +++ b/ports/atmel-samd/boards/uchip/pins.c @@ -0,0 +1,35 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/ugame10/board.c b/ports/atmel-samd/boards/ugame10/board.c new file mode 100644 index 00000000000..ce389a2b1cc --- /dev/null +++ b/ports/atmel-samd/boards/ugame10/board.c @@ -0,0 +1,119 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/busio/SPI.h" + +#include "tick.h" + +displayio_fourwire_obj_t board_display_obj; + +#define DELAY 0x80 + +uint8_t display_init_sequence[] = { + 0x01, 0 | DELAY, 150, // SWRESET + 0x11, 0 | DELAY, 255, // SLPOUT + 0xb1, 3, 0x01, 0x2C, 0x2D, // _FRMCTR1 + 0xb2, 3, 0x01, 0x2C, 0x2D, // + 0xb3, 6, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, + 0xb4, 1, 0x07, // _INVCTR line inversion + 0xc0, 3, 0xa2, 0x02, 0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA + 0xc1, 1, 0xc5, // _PWCTR2 VGH=14.7V, VGL=-7.35V + 0xc2, 2, 0x0a, 0x00, // _PWCTR3 Opamp current small, Boost frequency + 0xc3, 2, 0x8a, 0x2a, + 0xc4, 2, 0x8a, 0xee, + 0xc5, 1, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V + 0x2a, 0, // _INVOFF + 0x36, 1, 0xa0, // _MADCTL bottom to top refresh + // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie, + // fix on VTL + 0x3a, 1, 0x05, // COLMOD - 16bit color + 0xe0, 16, 0x02, 0x1c, 0x07, 0x12, // _GMCTRP1 Gamma + 0x37, 0x32, 0x29, 0x2d, + 0x29, 0x25, 0x2B, 0x39, + 0x00, 0x01, 0x03, 0x10, + 0xe1, 16, 0x03, 0x1d, 0x07, 0x06, // _GMCTRN1 + 0x2E, 0x2C, 0x29, 0x2D, + 0x2E, 0x2E, 0x37, 0x3F, + 0x00, 0x00, 0x02, 0x10, + 0x2a, 3, 0x02, 0x00, 0x81, // _CASET XSTART = 2, XEND = 129 + 0x2b, 3, 0x02, 0x00, 0x81, // _RASET XSTART = 2, XEND = 129 + 0x13, 0 | DELAY, 10, // _NORON + 0x29, 0 | DELAY, 100, // _DISPON +}; + +void board_init(void) { + displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + busio_spi_obj_t *spi = common_hal_board_create_spi(); + common_hal_displayio_fourwire_construct(bus, + spi, + &pin_PA09, // Command or data + &pin_PA08, // Chip select + NULL, // Reset + 24000000); + + displayio_display_obj_t* display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, + 128, // Width + 128, // Height + 3, // column start + 2, // row start + 0, // rotation + 16, // Color depth + false, // grayscale + false, // pixels in byte share row. Only used with depth < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + 0x37, // set vertical scroll command + display_init_sequence, + sizeof(display_init_sequence), + NULL, + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // auto_brightness + false, // single_byte_bounds + false, // data as commands + true, // auto_refresh + 60); // native_frames_per_second +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/ugame10/brutalist-6.bdf b/ports/atmel-samd/boards/ugame10/brutalist-6.bdf new file mode 100644 index 00000000000..f9e21e76a9d --- /dev/null +++ b/ports/atmel-samd/boards/ugame10/brutalist-6.bdf @@ -0,0 +1,1147 @@ +STARTFONT 2.1 +FONT -FontForge-Brutalist-Regular-R-Normal--6-60-75-75-P-40-ISO8859-1 +SIZE 6 100 100 +FONTBOUNDINGBOX 4 6 0 0 +COMMENT "Generated by fontforge, http://fontforge.sourceforge.net" +STARTPROPERTIES 17 +FAMILY_NAME "brutalist" +WEIGHT_NAME "Regular" +SLANT "R" +SETWIDTH_NAME "Normal" +PIXEL_SIZE 6 +POINT_SIZE 60 +RESOLUTION_X 100 +RESOLUTION_Y 100 +SPACING "C" +AVERAGE_WIDTH 40 +CHARSET_REGISTRY "ISO8859" +CHARSET_ENCODING "1" +FONTNAME_REGISTRY "" +FONT_ASCENT 4 +FONT_DESCENT 2 +MIN_SPACE 6 +FIGURE_WIDTH 4 +ENDPROPERTIES +CHARS 96 +STARTCHAR space +ENCODING 32 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 1 1 3 -2 +BITMAP +00 +ENDCHAR +STARTCHAR exclam +ENCODING 33 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 1 6 0 -2 +BITMAP +80 +80 +80 +80 +00 +80 +ENDCHAR +STARTCHAR quotedbl +ENCODING 34 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 2 0 2 +BITMAP +A0 +A0 +ENDCHAR +STARTCHAR numbersign +ENCODING 35 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +A0 +E0 +A0 +A0 +E0 +A0 +ENDCHAR +STARTCHAR dollar +ENCODING 36 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +40 +E0 +C0 +60 +E0 +40 +ENDCHAR +STARTCHAR percent +ENCODING 37 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +A0 +20 +40 +40 +80 +A0 +ENDCHAR +STARTCHAR ampersand +ENCODING 38 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +40 +A0 +40 +A0 +A0 +60 +ENDCHAR +STARTCHAR quotesingle +ENCODING 39 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 1 2 0 2 +BITMAP +80 +80 +ENDCHAR +STARTCHAR parenleft +ENCODING 40 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +60 +80 +80 +80 +80 +60 +ENDCHAR +STARTCHAR parenright +ENCODING 41 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +C0 +20 +20 +20 +20 +C0 +ENDCHAR +STARTCHAR asterisk +ENCODING 42 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 3 0 0 +BITMAP +A0 +40 +A0 +ENDCHAR +STARTCHAR plus +ENCODING 43 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 3 0 0 +BITMAP +40 +E0 +40 +ENDCHAR +STARTCHAR comma +ENCODING 44 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 2 3 0 -2 +BITMAP +40 +40 +80 +ENDCHAR +STARTCHAR hyphen +ENCODING 45 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 1 0 1 +BITMAP +E0 +ENDCHAR +STARTCHAR period +ENCODING 46 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 1 1 0 -1 +BITMAP +80 +ENDCHAR +STARTCHAR slash +ENCODING 47 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +20 +20 +40 +40 +80 +80 +ENDCHAR +STARTCHAR zero +ENCODING 48 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +60 +A0 +A0 +A0 +C0 +ENDCHAR +STARTCHAR one +ENCODING 49 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 2 5 0 -1 +BITMAP +40 +C0 +40 +40 +40 +ENDCHAR +STARTCHAR two +ENCODING 50 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +20 +E0 +80 +E0 +ENDCHAR +STARTCHAR three +ENCODING 51 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +20 +E0 +20 +E0 +ENDCHAR +STARTCHAR four +ENCODING 52 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +A0 +A0 +E0 +20 +20 +ENDCHAR +STARTCHAR five +ENCODING 53 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +80 +E0 +20 +E0 +ENDCHAR +STARTCHAR six +ENCODING 54 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +80 +E0 +A0 +E0 +ENDCHAR +STARTCHAR seven +ENCODING 55 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +20 +20 +20 +20 +ENDCHAR +STARTCHAR eight +ENCODING 56 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +A0 +E0 +A0 +E0 +ENDCHAR +STARTCHAR nine +ENCODING 57 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +A0 +E0 +20 +E0 +ENDCHAR +STARTCHAR colon +ENCODING 58 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 1 3 1 0 +BITMAP +80 +00 +80 +ENDCHAR +STARTCHAR semicolon +ENCODING 59 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 2 5 0 -2 +BITMAP +40 +00 +40 +40 +80 +ENDCHAR +STARTCHAR less +ENCODING 60 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +20 +40 +80 +40 +20 +ENDCHAR +STARTCHAR equal +ENCODING 61 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 3 0 0 +BITMAP +E0 +00 +E0 +ENDCHAR +STARTCHAR greater +ENCODING 62 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +80 +40 +20 +40 +80 +ENDCHAR +STARTCHAR question +ENCODING 63 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +E0 +20 +60 +40 +00 +40 +ENDCHAR +STARTCHAR at +ENCODING 64 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +E0 +A0 +E0 +E0 +80 +E0 +ENDCHAR +STARTCHAR A +ENCODING 65 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +A0 +A0 +E0 +A0 +ENDCHAR +STARTCHAR B +ENCODING 66 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +C0 +A0 +C0 +A0 +E0 +ENDCHAR +STARTCHAR C +ENCODING 67 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +A0 +80 +A0 +E0 +ENDCHAR +STARTCHAR D +ENCODING 68 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +C0 +A0 +A0 +A0 +C0 +ENDCHAR +STARTCHAR E +ENCODING 69 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +80 +E0 +80 +E0 +ENDCHAR +STARTCHAR F +ENCODING 70 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +80 +80 +E0 +80 +ENDCHAR +STARTCHAR G +ENCODING 71 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +E0 +80 +A0 +A0 +E0 +20 +ENDCHAR +STARTCHAR H +ENCODING 72 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +A0 +A0 +E0 +A0 +A0 +ENDCHAR +STARTCHAR I +ENCODING 73 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +40 +40 +40 +E0 +ENDCHAR +STARTCHAR J +ENCODING 74 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +20 +20 +20 +A0 +E0 +ENDCHAR +STARTCHAR K +ENCODING 75 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +A0 +C0 +E0 +A0 +A0 +ENDCHAR +STARTCHAR L +ENCODING 76 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +80 +80 +80 +80 +E0 +ENDCHAR +STARTCHAR M +ENCODING 77 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +A0 +E0 +A0 +A0 +A0 +ENDCHAR +STARTCHAR N +ENCODING 78 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +A0 +E0 +E0 +E0 +A0 +ENDCHAR +STARTCHAR O +ENCODING 79 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +A0 +A0 +A0 +E0 +ENDCHAR +STARTCHAR P +ENCODING 80 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +A0 +A0 +E0 +80 +ENDCHAR +STARTCHAR Q +ENCODING 81 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +E0 +A0 +A0 +A0 +E0 +20 +ENDCHAR +STARTCHAR R +ENCODING 82 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +A0 +A0 +C0 +A0 +ENDCHAR +STARTCHAR S +ENCODING 83 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +80 +E0 +20 +E0 +ENDCHAR +STARTCHAR T +ENCODING 84 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +40 +40 +40 +40 +ENDCHAR +STARTCHAR U +ENCODING 85 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +A0 +A0 +A0 +A0 +E0 +ENDCHAR +STARTCHAR V +ENCODING 86 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +A0 +A0 +A0 +E0 +40 +ENDCHAR +STARTCHAR W +ENCODING 87 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +A0 +A0 +A0 +E0 +A0 +ENDCHAR +STARTCHAR X +ENCODING 88 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +A0 +A0 +40 +A0 +A0 +ENDCHAR +STARTCHAR Y +ENCODING 89 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +A0 +A0 +E0 +40 +40 +ENDCHAR +STARTCHAR Z +ENCODING 90 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +E0 +20 +40 +80 +E0 +ENDCHAR +STARTCHAR bracketleft +ENCODING 91 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +E0 +80 +80 +80 +80 +E0 +ENDCHAR +STARTCHAR backslash +ENCODING 92 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +80 +80 +40 +40 +20 +20 +ENDCHAR +STARTCHAR bracketright +ENCODING 93 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +E0 +20 +20 +20 +20 +E0 +ENDCHAR +STARTCHAR asciicircum +ENCODING 94 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 3 0 1 +BITMAP +40 +E0 +A0 +ENDCHAR +STARTCHAR underscore +ENCODING 95 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 1 0 -1 +BITMAP +E0 +ENDCHAR +STARTCHAR grave +ENCODING 96 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 2 2 1 2 +BITMAP +80 +40 +ENDCHAR +STARTCHAR a +ENCODING 97 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 4 0 -1 +BITMAP +E0 +60 +A0 +E0 +ENDCHAR +STARTCHAR b +ENCODING 98 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +80 +E0 +A0 +A0 +E0 +ENDCHAR +STARTCHAR c +ENCODING 99 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 4 0 -1 +BITMAP +E0 +A0 +80 +E0 +ENDCHAR +STARTCHAR d +ENCODING 100 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +20 +E0 +A0 +A0 +E0 +ENDCHAR +STARTCHAR e +ENCODING 101 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 4 0 -1 +BITMAP +E0 +A0 +C0 +E0 +ENDCHAR +STARTCHAR f +ENCODING 102 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +60 +40 +E0 +40 +40 +40 +ENDCHAR +STARTCHAR g +ENCODING 103 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -2 +BITMAP +E0 +A0 +E0 +20 +E0 +ENDCHAR +STARTCHAR h +ENCODING 104 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +80 +E0 +A0 +A0 +A0 +ENDCHAR +STARTCHAR i +ENCODING 105 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 2 5 1 -1 +BITMAP +80 +00 +80 +80 +C0 +ENDCHAR +STARTCHAR j +ENCODING 106 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +20 +00 +60 +20 +A0 +E0 +ENDCHAR +STARTCHAR k +ENCODING 107 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +80 +A0 +C0 +A0 +A0 +ENDCHAR +STARTCHAR l +ENCODING 108 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +C0 +40 +40 +40 +60 +ENDCHAR +STARTCHAR m +ENCODING 109 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 4 0 -1 +BITMAP +E0 +E0 +E0 +A0 +ENDCHAR +STARTCHAR n +ENCODING 110 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 4 0 -1 +BITMAP +E0 +A0 +A0 +A0 +ENDCHAR +STARTCHAR o +ENCODING 111 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 4 0 -1 +BITMAP +E0 +A0 +A0 +E0 +ENDCHAR +STARTCHAR p +ENCODING 112 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -2 +BITMAP +E0 +A0 +A0 +E0 +80 +ENDCHAR +STARTCHAR q +ENCODING 113 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -2 +BITMAP +E0 +A0 +A0 +E0 +20 +ENDCHAR +STARTCHAR r +ENCODING 114 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 4 0 -1 +BITMAP +E0 +A0 +80 +80 +ENDCHAR +STARTCHAR s +ENCODING 115 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 4 0 -1 +BITMAP +E0 +80 +60 +E0 +ENDCHAR +STARTCHAR t +ENCODING 116 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -1 +BITMAP +40 +E0 +40 +40 +60 +ENDCHAR +STARTCHAR u +ENCODING 117 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 4 0 -1 +BITMAP +A0 +A0 +A0 +E0 +ENDCHAR +STARTCHAR v +ENCODING 118 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 4 0 -1 +BITMAP +A0 +A0 +E0 +40 +ENDCHAR +STARTCHAR w +ENCODING 119 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 4 0 -1 +BITMAP +A0 +A0 +E0 +A0 +ENDCHAR +STARTCHAR x +ENCODING 120 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 4 0 -1 +BITMAP +A0 +40 +A0 +A0 +ENDCHAR +STARTCHAR y +ENCODING 121 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 5 0 -2 +BITMAP +A0 +A0 +E0 +20 +E0 +ENDCHAR +STARTCHAR z +ENCODING 122 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 4 0 -1 +BITMAP +E0 +40 +80 +E0 +ENDCHAR +STARTCHAR braceleft +ENCODING 123 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +60 +40 +C0 +40 +40 +60 +ENDCHAR +STARTCHAR bar +ENCODING 124 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 1 6 1 -2 +BITMAP +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR braceright +ENCODING 125 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +C0 +40 +60 +40 +40 +C0 +ENDCHAR +STARTCHAR asciitilde +ENCODING 126 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 4 3 0 1 +BITMAP +50 +F0 +A0 +ENDCHAR +STARTCHAR uni007F +ENCODING 127 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 3 6 0 -2 +BITMAP +E0 +A0 +A0 +A0 +A0 +E0 +ENDCHAR +ENDFONT diff --git a/ports/atmel-samd/boards/ugame10/brutalist.sfd b/ports/atmel-samd/boards/ugame10/brutalist.sfd new file mode 100644 index 00000000000..2a48515aa5c --- /dev/null +++ b/ports/atmel-samd/boards/ugame10/brutalist.sfd @@ -0,0 +1,1034 @@ +SplineFontDB: 3.0 +FontName: brutalistRegular +FullName: brutalist Regular +FamilyName: brutalist +Weight: Regular +Copyright: Copyright (c) 2019, sheep,,, +UComments: "2019-6-28: Created with FontForge (http://fontforge.org)" +Version: 001.000 +ItalicAngle: 0 +UnderlinePosition: -100 +UnderlineWidth: 50 +Ascent: 666 +Descent: 334 +InvalidEm: 0 +LayerCount: 2 +Layer: 0 0 "Back" 1 +Layer: 1 0 "Fore" 0 +XUID: [1021 455 -922482232 13638063] +OS2Version: 0 +OS2_WeightWidthSlopeOnly: 0 +OS2_UseTypoMetrics: 1 +CreationTime: 1561742286 +ModificationTime: 1561742286 +OS2TypoAscent: 0 +OS2TypoAOffset: 1 +OS2TypoDescent: 0 +OS2TypoDOffset: 1 +OS2TypoLinegap: 0 +OS2WinAscent: 0 +OS2WinAOffset: 1 +OS2WinDescent: 0 +OS2WinDOffset: 1 +HheadAscent: 0 +HheadAOffset: 1 +HheadDescent: 0 +HheadDOffset: 1 +OS2Vendor: 'PfEd' +DEI: 91125 +Encoding: ISO8859-1 +UnicodeInterp: none +NameList: AGL For New Fonts +DisplaySize: 6 +AntiAlias: 1 +FitToEm: 0 +WinInfo: 0 32 23 +OnlyBitmaps: 1 +BeginChars: 256 96 + +StartChar: space +Encoding: 32 32 0 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: exclam +Encoding: 33 33 1 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: quotedbl +Encoding: 34 34 2 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: numbersign +Encoding: 35 35 3 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: dollar +Encoding: 36 36 4 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: percent +Encoding: 37 37 5 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: ampersand +Encoding: 38 38 6 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: quotesingle +Encoding: 39 39 7 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: parenleft +Encoding: 40 40 8 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: parenright +Encoding: 41 41 9 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: asterisk +Encoding: 42 42 10 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: plus +Encoding: 43 43 11 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: comma +Encoding: 44 44 12 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: hyphen +Encoding: 45 45 13 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: period +Encoding: 46 46 14 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: slash +Encoding: 47 47 15 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: zero +Encoding: 48 48 16 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: one +Encoding: 49 49 17 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: two +Encoding: 50 50 18 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: three +Encoding: 51 51 19 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: four +Encoding: 52 52 20 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: five +Encoding: 53 53 21 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: six +Encoding: 54 54 22 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: seven +Encoding: 55 55 23 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: eight +Encoding: 56 56 24 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: nine +Encoding: 57 57 25 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: colon +Encoding: 58 58 26 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: semicolon +Encoding: 59 59 27 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: less +Encoding: 60 60 28 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: equal +Encoding: 61 61 29 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: greater +Encoding: 62 62 30 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: question +Encoding: 63 63 31 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: at +Encoding: 64 64 32 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: A +Encoding: 65 65 33 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: B +Encoding: 66 66 34 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: C +Encoding: 67 67 35 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: D +Encoding: 68 68 36 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: E +Encoding: 69 69 37 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: F +Encoding: 70 70 38 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: G +Encoding: 71 71 39 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: H +Encoding: 72 72 40 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: I +Encoding: 73 73 41 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: J +Encoding: 74 74 42 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: K +Encoding: 75 75 43 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: L +Encoding: 76 76 44 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: M +Encoding: 77 77 45 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: N +Encoding: 78 78 46 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: O +Encoding: 79 79 47 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: P +Encoding: 80 80 48 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: Q +Encoding: 81 81 49 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: R +Encoding: 82 82 50 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: S +Encoding: 83 83 51 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: T +Encoding: 84 84 52 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: U +Encoding: 85 85 53 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: V +Encoding: 86 86 54 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: W +Encoding: 87 87 55 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: X +Encoding: 88 88 56 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: Y +Encoding: 89 89 57 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: Z +Encoding: 90 90 58 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: bracketleft +Encoding: 91 91 59 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: backslash +Encoding: 92 92 60 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: bracketright +Encoding: 93 93 61 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: asciicircum +Encoding: 94 94 62 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: underscore +Encoding: 95 95 63 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: grave +Encoding: 96 96 64 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: a +Encoding: 97 97 65 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: b +Encoding: 98 98 66 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: c +Encoding: 99 99 67 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: d +Encoding: 100 100 68 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: e +Encoding: 101 101 69 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: f +Encoding: 102 102 70 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: g +Encoding: 103 103 71 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: h +Encoding: 104 104 72 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: i +Encoding: 105 105 73 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: j +Encoding: 106 106 74 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: k +Encoding: 107 107 75 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: l +Encoding: 108 108 76 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: m +Encoding: 109 109 77 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: n +Encoding: 110 110 78 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: o +Encoding: 111 111 79 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: p +Encoding: 112 112 80 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: q +Encoding: 113 113 81 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: r +Encoding: 114 114 82 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: s +Encoding: 115 115 83 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: t +Encoding: 116 116 84 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: u +Encoding: 117 117 85 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: v +Encoding: 118 118 86 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: w +Encoding: 119 119 87 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: x +Encoding: 120 120 88 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: y +Encoding: 121 121 89 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: z +Encoding: 122 122 90 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: braceleft +Encoding: 123 123 91 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: bar +Encoding: 124 124 92 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: braceright +Encoding: 125 125 93 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: asciitilde +Encoding: 126 126 94 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: uni007F +Encoding: 127 127 95 +Width: 666 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar +EndChars +BitmapFont: 6 96 4 2 1 +BDFStartProperties: 20 +FONT 1 "-FontForge-Brutalist-Regular-R-Normal--6-60-75-75-P-40-ISO8859-1" +SIZE 1 "6 100 100" +FONTBOUNDINGBOX 1 "4 6 0 -1" +FAMILY_NAME 16 "brutalist" +WEIGHT_NAME 16 "Regular" +SLANT 16 "R" +SETWIDTH_NAME 16 "Normal" +PIXEL_SIZE 18 6 +POINT_SIZE 18 60 +RESOLUTION_X 19 100 +RESOLUTION_Y 19 100 +SPACING 16 "C" +AVERAGE_WIDTH 18 40 +CHARSET_REGISTRY 16 "ISO8859" +CHARSET_ENCODING 16 "1" +FONTNAME_REGISTRY 16 "" +FONT_ASCENT 18 4 +FONT_DESCENT 18 2 +MIN_SPACE 18 6 +FIGURE_WIDTH 18 4 +BDFEndProperties +Resolution: 100 +BDFChar: 0 32 5 3 3 -2 -2 +z +BDFChar: 1 33 5 0 0 -2 3 +J:N0#!.Y%L +BDFChar: 2 34 5 0 2 2 3 +TV)8b +BDFChar: 3 35 5 0 2 -2 3 +T\uK9i1L&M +BDFChar: 4 36 5 0 2 -2 3 +5iBFci'78B +BDFChar: 5 37 5 0 2 -2 3 +THHKbJ=llB +BDFChar: 6 38 5 0 2 -2 3 +5bLB8TO7a" +BDFChar: 7 39 5 0 0 2 3 +J:IV" +BDFChar: 8 40 5 0 2 -2 3 +@" + +#include "py/gc.h" +#include "py/nlr.h" +#include "py/runtime.h" +#include "py/binary.h" +#include "py/mphal.h" + +#include "samd/adc.h" +#include "shared-bindings/analogio/AnalogIn.h" +#include "supervisor/shared/translate.h" + +#include "atmel_start_pins.h" +#include "hal/include/hal_adc_sync.h" +#include "hpl/gclk/hpl_gclk_base.h" + +#ifdef SAMD21 +#include "hpl/pm/hpl_pm_base.h" +#endif + +void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, + const mcu_pin_obj_t *pin) { + uint8_t adc_index; + uint8_t adc_channel = 0xff; + for (adc_index = 0; adc_index < NUM_ADC_PER_PIN; adc_index++) { + // TODO(tannewt): Only use ADC0 on the SAMD51 when touch isn't being + // used. + if (pin->adc_input[adc_index] != 0xff) { + adc_channel = pin->adc_input[adc_index]; + break; + } + } + if (adc_channel == 0xff) { + // No ADC function on that pin + mp_raise_ValueError(translate("Pin does not have ADC capabilities")); + } + claim_pin(pin); + + gpio_set_pin_function(pin->number, GPIO_PIN_FUNCTION_B); + + static Adc* adc_insts[] = ADC_INSTS; + self->instance = adc_insts[adc_index]; + self->channel = adc_channel; + self->pin = pin; +} + +bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t *self) { + return self->pin == mp_const_none; +} + +void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { + if (common_hal_analogio_analogin_deinited(self)) { + return; + } + reset_pin_number(self->pin->number); + self->pin = mp_const_none; +} + +void analogin_reset() { +} + +uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { + // Something else might have used the ADC in a different way, + // so we completely re-initialize it. + + struct adc_sync_descriptor adc; + + samd_peripherals_adc_setup(&adc, self->instance); + + // Full scale is 3.3V (VDDANA) = 65535. + + // On SAMD21, INTVCC1 is 0.5*VDDANA. On SAMD51, INTVCC1 is 1*VDDANA. + // So on SAMD21 only, divide the input by 2, so full scale will match 0.5*VDDANA. + adc_sync_set_reference(&adc, ADC_REFCTRL_REFSEL_INTVCC1_Val); + #ifdef SAMD21 + adc_sync_set_channel_gain(&adc, self->channel, ADC_INPUTCTRL_GAIN_DIV2_Val); + #endif + + adc_sync_set_resolution(&adc, ADC_CTRLB_RESSEL_12BIT_Val); + + adc_sync_enable_channel(&adc, self->channel); + + // We need to set the inputs because the above channel enable only enables the ADC. + adc_sync_set_inputs(&adc, self->channel, ADC_INPUTCTRL_MUXNEG_GND_Val, self->channel); + + // Read twice and discard first result, as recommended in section 14 of + // http://www.atmel.com/images/Atmel-42645-ADC-Configurations-with-Examples_ApplicationNote_AT11481.pdf + // "Discard the first conversion result whenever there is a change in ADC configuration + // like voltage reference / ADC channel change" + // Empirical observation shows the first reading is quite different than subsequent ones. + + uint16_t value; + adc_sync_read_channel(&adc, self->channel, ((uint8_t*) &value), 2); + adc_sync_read_channel(&adc, self->channel, ((uint8_t*) &value), 2); + + adc_sync_deinit(&adc); + // Shift the value to be 16 bit. + return value << 4; +} + +float common_hal_analogio_analogin_get_reference_voltage(analogio_analogin_obj_t *self) { + return 3.3f; +} diff --git a/ports/atmel-samd/common-hal/analogio/AnalogIn.h b/ports/atmel-samd/common-hal/analogio/AnalogIn.h new file mode 100644 index 00000000000..0b13ba7e14d --- /dev/null +++ b/ports/atmel-samd/common-hal/analogio/AnalogIn.h @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ANALOGIO_ANALOGIN_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ANALOGIO_ANALOGIN_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t * pin; + Adc* instance; + uint8_t channel; +} analogio_analogin_obj_t; + +void analogin_reset(void); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ANALOGIO_ANALOGIN_H diff --git a/ports/atmel-samd/common-hal/analogio/AnalogOut.c b/ports/atmel-samd/common-hal/analogio/AnalogOut.c new file mode 100644 index 00000000000..9ac1f7bd15c --- /dev/null +++ b/ports/atmel-samd/common-hal/analogio/AnalogOut.c @@ -0,0 +1,155 @@ +/* + * This file is part of the MicroPython 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 +#include + +#include "py/mperrno.h" +#include "py/runtime.h" + +#include "shared-bindings/analogio/AnalogOut.h" +#include "shared-bindings/audioio/AudioOut.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "supervisor/shared/translate.h" + +#include "atmel_start_pins.h" +#include "hal/include/hal_dac_sync.h" +#include "hpl/gclk/hpl_gclk_base.h" +#include "peripheral_clk_config.h" + +#ifdef SAMD21 +#include "hpl/pm/hpl_pm_base.h" +#endif + +void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self, + const mcu_pin_obj_t *pin) { + #if defined(SAMD21) && !defined(PIN_PA02) + mp_raise_NotImplementedError(translate("No DAC on chip")); + #else + if (pin->number != PIN_PA02 + #ifdef SAMD51 + && pin->number != PIN_PA05 + #endif + ) { + mp_raise_ValueError(translate("AnalogOut not supported on given pin")); + return; + } + + self->channel = 0; + #ifdef SAMD51 + if (pin->number == PIN_PA05) { + self->channel = 1; + } + #endif + + #ifdef SAMD51 + hri_mclk_set_APBDMASK_DAC_bit(MCLK); + #endif + + #ifdef SAMD21 + _pm_enable_bus_clock(PM_BUS_APBC, DAC); + #endif + + // SAMD21: This clock should be <= 12 MHz, per datasheet section 47.6.3. + // SAMD51: This clock should be <= 350kHz, per datasheet table 37-6. + _gclk_enable_channel(DAC_GCLK_ID, CONF_GCLK_DAC_SRC); + + // Don't double init the DAC on the SAMD51 when both outputs are in use. We use the free state + // of each output pin to determine DAC state. + int32_t result = ERR_NONE; + #ifdef SAMD51 + if (!common_hal_mcu_pin_is_free(&pin_PA02) || !common_hal_mcu_pin_is_free(&pin_PA05)) { + #endif + // Fake the descriptor if the DAC is already initialized. + self->descriptor.device.hw = DAC; + #ifdef SAMD51 + } else { + #endif + result = dac_sync_init(&self->descriptor, DAC); + #ifdef SAMD51 + } + #endif + if (result != ERR_NONE) { + mp_raise_OSError(MP_EIO); + return; + } + claim_pin(pin); + + gpio_set_pin_function(pin->number, GPIO_PIN_FUNCTION_B); + + dac_sync_enable_channel(&self->descriptor, self->channel); + #endif +} + +bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self) { + return self->deinited; +} + +void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self) { + #if (defined(SAMD21) && defined(PIN_PA02)) || defined(SAMD51) + if (common_hal_analogio_analogout_deinited(self)) { + return; + } + dac_sync_disable_channel(&self->descriptor, self->channel); + reset_pin_number(PIN_PA02); + // Only deinit the DAC on the SAMD51 if both outputs are free. + #ifdef SAMD51 + if (common_hal_mcu_pin_is_free(&pin_PA02) && common_hal_mcu_pin_is_free(&pin_PA05)) { + #endif + dac_sync_deinit(&self->descriptor); + #ifdef SAMD51 + } + #endif + self->deinited = true; + // TODO(tannewt): Turn off the DAC clocks to save power. + #endif +} + +void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, + uint16_t value) { + #if defined(SAMD21) && !defined(PIN_PA02) + return; + #endif + // Input is 16 bit so make sure and set LEFTADJ to 1 so it takes the top + // bits. This is currently done in asf4_conf/*/hpl_dac_config.h. + dac_sync_write(&self->descriptor, self->channel, &value, 1); +} + +void analogout_reset(void) { + // audioout_reset also resets the DAC, and does a smooth ramp down to avoid clicks + // if it was enabled, so do that instead if AudioOut is enabled. +#if CIRCUITPY_AUDIOIO + audioout_reset(); +#else + #ifdef SAMD21 + while (DAC->STATUS.reg & DAC_STATUS_SYNCBUSY) {} + #endif + #ifdef SAMD51 + while (DAC->SYNCBUSY.reg & DAC_SYNCBUSY_SWRST) {} + #endif + DAC->CTRLA.reg |= DAC_CTRLA_SWRST; +#endif +} diff --git a/ports/atmel-samd/common-hal/analogio/AnalogOut.h b/ports/atmel-samd/common-hal/analogio/AnalogOut.h new file mode 100644 index 00000000000..3710a7211ac --- /dev/null +++ b/ports/atmel-samd/common-hal/analogio/AnalogOut.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ANALOGIO_ANALOGOUT_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ANALOGIO_ANALOGOUT_H + +#include "common-hal/microcontroller/Pin.h" + +#include "hal/include/hal_dac_sync.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + struct dac_sync_descriptor descriptor; + uint8_t channel; + bool deinited; +} analogio_analogout_obj_t; + +void analogout_reset(void); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ANALOGIO_ANALOGOUT_H diff --git a/ports/atmel-samd/common-hal/analogio/__init__.c b/ports/atmel-samd/common-hal/analogio/__init__.c new file mode 100644 index 00000000000..eea58c77d63 --- /dev/null +++ b/ports/atmel-samd/common-hal/analogio/__init__.c @@ -0,0 +1 @@ +// No analogio module functions. diff --git a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c new file mode 100644 index 00000000000..05a6aaf7b03 --- /dev/null +++ b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c @@ -0,0 +1,386 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 +#include + +#include "extmod/vfs_fat.h" +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "common-hal/audiobusio/I2SOut.h" +#include "shared-bindings/audiobusio/I2SOut.h" +#include "shared-bindings/audiocore/RawSample.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "supervisor/shared/translate.h" + +#include "atmel_start_pins.h" +#include "hal/include/hal_gpio.h" +#include "hpl/gclk/hpl_gclk_base.h" +#include "peripheral_clk_config.h" + +#ifdef SAMD21 +#include "hpl/pm/hpl_pm_base.h" +#endif + +#include "samd/clocks.h" +#include "samd/dma.h" +#include "samd/events.h" +#include "samd/i2s.h" +#include "samd/pins.h" +#include "samd/timers.h" + +#include "audio_dma.h" + +#ifdef SAMD21 +#define SERCTRL(name) I2S_SERCTRL_ ## name +#endif + +#ifdef SAMD51 +#define SERCTRL(name) I2S_TXCTRL_ ## name +#endif + +void i2sout_reset(void) { + // Make sure the I2S peripheral is running so we can see if the resources we need are free. + #ifdef SAMD51 + // Connect the clock units to the 2mhz clock. It can't disable without it. + connect_gclk_to_peripheral(5, I2S_GCLK_ID_0); + connect_gclk_to_peripheral(5, I2S_GCLK_ID_1); + #endif + if (I2S->CTRLA.bit.ENABLE == 1) { + I2S->CTRLA.bit.ENABLE = 0; + while (I2S->SYNCBUSY.bit.ENABLE == 1) {} + } + + // Make sure the I2S peripheral is running so we can see if the resources we need are free. + #ifdef SAMD51 + // Connect the clock units to the 2mhz clock by default. They can't reset without it. + disconnect_gclk_from_peripheral(5, I2S_GCLK_ID_0); + disconnect_gclk_from_peripheral(5, I2S_GCLK_ID_1); + + hri_mclk_clear_APBDMASK_I2S_bit(MCLK); + #endif + + #ifdef SAMD21 + _pm_disable_bus_clock(PM_BUS_APBC, I2S); + #endif +} + +void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t* self, + const mcu_pin_obj_t* bit_clock, const mcu_pin_obj_t* word_select, + const mcu_pin_obj_t* data, bool left_justified) { + uint8_t serializer = 0xff; + uint8_t bc_clock_unit = 0xff; + uint8_t ws_clock_unit = 0xff; + #ifdef SAMD21 + if (bit_clock == &pin_PA10 + #ifdef PIN_PA20 + || bit_clock == &pin_PA20 + #endif + ) { // I2S SCK[0] + bc_clock_unit = 0; + } + #ifdef PIN_PB11 + else if (bit_clock == &pin_PB11) { // I2S SCK[1] + bc_clock_unit = 1; + } + #endif + if (word_select == &pin_PA11 + #ifdef PIN_PA21 + || word_select == &pin_PA21 + #endif + ) { // I2S FS[0] + ws_clock_unit = 0; + } + #ifdef PIN_PB12 + else if (word_select == &pin_PB12) { // I2S FS[1] + ws_clock_unit = 1; + } + #endif + + if (data == &pin_PA07 || data == &pin_PA19) { // I2S SD[0] + serializer = 0; + } else if (data == &pin_PA08 + #ifdef PIN_PB16 + || data == &pin_PB16 + #endif + ) { // I2S SD[1] + serializer = 1; + } + #endif + #ifdef SAMD51 + // Only clock unit 0 can be used for transmission. + if (bit_clock == &pin_PA10 || bit_clock == &pin_PB16) { // I2S SCK[0] + bc_clock_unit = 0; + } + if (word_select == &pin_PA09 || word_select == &pin_PA20) { // I2S FS[0] + ws_clock_unit = 0; + } + if (data == &pin_PA11 || data == &pin_PA21) { // I2S SDO + serializer = 0; + } + #endif + if (bc_clock_unit == 0xff) { + mp_raise_ValueError_varg(translate("Invalid %q pin"), MP_QSTR_bit_clock); + } + if (ws_clock_unit == 0xff) { + mp_raise_ValueError_varg(translate("Invalid %q pin"), MP_QSTR_word_select); + } + if (bc_clock_unit != ws_clock_unit) { + mp_raise_ValueError(translate("Bit clock and word select must share a clock unit")); + } + if (serializer == 0xff) { + mp_raise_ValueError_varg(translate("Invalid %q pin"), MP_QSTR_data); + } + self->clock_unit = ws_clock_unit; + self->serializer = serializer; + + turn_on_i2s(); + + if (I2S->CTRLA.bit.ENABLE == 0) { + I2S->CTRLA.bit.SWRST = 1; + while (I2S->CTRLA.bit.SWRST == 1) {} + } else { + #ifdef SAMD21 + if ((I2S->CTRLA.vec.SEREN & (1 << serializer)) != 0) { + mp_raise_RuntimeError(translate("Serializer in use")); + } + #endif + #ifdef SAMD51 + if (I2S->CTRLA.bit.TXEN == 1) { + mp_raise_RuntimeError(translate("Serializer in use")); + } + #endif + } + + #ifdef SAMD51 + #define GPIO_I2S_FUNCTION GPIO_PIN_FUNCTION_J + #endif + #ifdef SAMD21 + #define GPIO_I2S_FUNCTION GPIO_PIN_FUNCTION_G + #endif + assert_pin_free(bit_clock); + assert_pin_free(word_select); + assert_pin_free(data); + + self->bit_clock = bit_clock; + self->word_select = word_select; + self->data = data; + + claim_pin(bit_clock); + claim_pin(word_select); + claim_pin(data); + + gpio_set_pin_function(self->bit_clock->number, GPIO_I2S_FUNCTION); + gpio_set_pin_function(self->word_select->number, GPIO_I2S_FUNCTION); + gpio_set_pin_function(self->data->number, GPIO_I2S_FUNCTION); + + self->left_justified = left_justified; + self->playing = false; + audio_dma_init(&self->dma); +} + +bool common_hal_audiobusio_i2sout_deinited(audiobusio_i2sout_obj_t* self) { + return self->bit_clock == mp_const_none; +} + +void common_hal_audiobusio_i2sout_deinit(audiobusio_i2sout_obj_t* self) { + if (common_hal_audiobusio_i2sout_deinited(self)) { + return; + } + + reset_pin_number(self->bit_clock->number); + self->bit_clock = mp_const_none; + reset_pin_number(self->word_select->number); + self->word_select = mp_const_none; + reset_pin_number(self->data->number); + self->data = mp_const_none; +} + +void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t* self, + mp_obj_t sample, bool loop) { + if (common_hal_audiobusio_i2sout_get_playing(self)) { + common_hal_audiobusio_i2sout_stop(self); + } + #ifdef SAMD21 + if ((I2S->CTRLA.vec.CKEN & (1 << self->clock_unit)) == 1) { + mp_raise_RuntimeError(translate("Clock unit in use")); + } + #endif + uint8_t bits_per_sample = audiosample_bits_per_sample(sample); + // We always output stereo so output twice as many bits. + uint16_t bits_per_sample_output = bits_per_sample * 2; + uint16_t divisor = 48000000 / (bits_per_sample_output * audiosample_sample_rate(sample)); + // Find a free GCLK to generate the MCLK signal. + uint8_t gclk = find_free_gclk(divisor); + if (gclk > GCLK_GEN_NUM) { + mp_raise_RuntimeError(translate("Unable to find free GCLK")); + } + self->gclk = gclk; + + uint32_t clkctrl = I2S_CLKCTRL_MCKSEL_GCLK | + I2S_CLKCTRL_NBSLOTS(1) | + I2S_CLKCTRL_FSWIDTH_HALF; + if (self->left_justified) { + clkctrl |= I2S_CLKCTRL_BITDELAY_LJ; + } else { + clkctrl |= I2S_CLKCTRL_FSOUTINV | I2S_CLKCTRL_BITDELAY_I2S; + } + uint8_t channel_count = audiosample_channel_count(sample); + if (channel_count > 2) { + mp_raise_ValueError(translate("Too many channels in sample.")); + } + #ifdef SAMD21 + uint32_t serctrl = (self->clock_unit << I2S_SERCTRL_CLKSEL_Pos) | SERCTRL(SERMODE_TX) | I2S_SERCTRL_TXSAME_SAME | I2S_SERCTRL_EXTEND_MSBIT | I2S_SERCTRL_TXDEFAULT_ONE | I2S_SERCTRL_SLOTADJ_LEFT; + #endif + #ifdef SAMD51 + uint32_t serctrl = (self->clock_unit << I2S_RXCTRL_CLKSEL_Pos) | I2S_TXCTRL_TXSAME_SAME; + #endif + if (audiosample_channel_count(sample) == 1) { + serctrl |= SERCTRL(MONO_MONO); + } else { + serctrl |= SERCTRL(MONO_STEREO); + } + if (bits_per_sample == 8) { + serctrl |= SERCTRL(DATASIZE_8C); + clkctrl |= I2S_CLKCTRL_SLOTSIZE_8; + } else if (bits_per_sample == 16) { + serctrl |= SERCTRL(DATASIZE_16C); + clkctrl |= I2S_CLKCTRL_SLOTSIZE_16; + } + + // Configure the I2S peripheral + i2s_set_enable(false); + + I2S->CLKCTRL[self->clock_unit].reg = clkctrl; + #ifdef SAMD21 + I2S->SERCTRL[self->serializer].reg = serctrl; + #endif + #ifdef SAMD51 + I2S->TXCTRL.reg = serctrl; + #endif + + // The DFLL is always a 48mhz clock + enable_clock_generator(self->gclk, CLOCK_48MHZ, divisor); + connect_gclk_to_peripheral(self->gclk, I2S_GCLK_ID_0 + self->clock_unit); + + i2s_set_enable(true); + + #ifdef SAMD21 + uint32_t tx_register = (uint32_t) &I2S->DATA[self->serializer].reg; + uint8_t dmac_id = I2S_DMAC_ID_TX_0 + self->serializer; + #endif + #ifdef SAMD51 + uint32_t tx_register = (uint32_t) &I2S->TXDATA.reg; + uint8_t dmac_id = I2S_DMAC_ID_TX_0; + #endif + audio_dma_result result = audio_dma_setup_playback(&self->dma, sample, loop, false, 0, + true /* output signed */, tx_register, dmac_id); + + if (result == AUDIO_DMA_DMA_BUSY) { + common_hal_audiobusio_i2sout_stop(self); + mp_raise_RuntimeError(translate("No DMA channel found")); + } else if (result == AUDIO_DMA_MEMORY_ERROR) { + common_hal_audiobusio_i2sout_stop(self); + mp_raise_RuntimeError(translate("Unable to allocate buffers for signed conversion")); + } + + I2S->INTFLAG.reg = I2S_INTFLAG_TXUR0 | I2S_INTFLAG_TXUR1; + + I2S->CTRLA.vec.CKEN = 1 << self->clock_unit; + while ((I2S->SYNCBUSY.vec.CKEN & (1 << self->clock_unit)) != 0) {} + + // Init the serializer after the clock. Otherwise, it will never enable because its unclocked. + #ifdef SAMD21 + I2S->CTRLA.vec.SEREN = 1 << self->serializer; + while ((I2S->SYNCBUSY.vec.SEREN & (1 << self->serializer)) != 0) {} + #endif + #ifdef SAMD51 + I2S->CTRLA.bit.TXEN = 1; + while (I2S->SYNCBUSY.bit.TXEN == 1) {} + #endif + + self->playing = true; +} + +void common_hal_audiobusio_i2sout_pause(audiobusio_i2sout_obj_t* self) { + audio_dma_pause(&self->dma); +} + +void common_hal_audiobusio_i2sout_resume(audiobusio_i2sout_obj_t* self) { + // Clear any overrun/underrun errors + #ifdef SAMD21 + I2S->INTFLAG.reg = I2S_INTFLAG_TXUR0 << self->serializer; + #endif + #ifdef SAMD51 + I2S->INTFLAG.reg = I2S_INTFLAG_TXUR0 | I2S_INTFLAG_TXUR1; + #endif + + audio_dma_resume(&self->dma); +} + +bool common_hal_audiobusio_i2sout_get_paused(audiobusio_i2sout_obj_t* self) { + return audio_dma_get_paused(&self->dma); +} + +void common_hal_audiobusio_i2sout_stop(audiobusio_i2sout_obj_t* self) { + audio_dma_stop(&self->dma); + + #ifdef SAMD21 + I2S->CTRLA.vec.SEREN &= ~(1 << self->serializer); + while ((I2S->SYNCBUSY.vec.SEREN & (1 << self->serializer)) != 0) {} + #endif + #ifdef SAMD51 + I2S->CTRLA.bit.TXEN = 0; + while (I2S->SYNCBUSY.bit.TXEN == 1) {} + #endif + + #ifdef SAMD21 + if (self->clock_unit == 0) { + I2S->CTRLA.bit.CKEN0 = 0; + while (I2S->SYNCBUSY.bit.CKEN0 == 1) {} + } else { + I2S->CTRLA.bit.CKEN1 = 0; + while (I2S->SYNCBUSY.bit.CKEN1 == 1) {} + } + #endif + disconnect_gclk_from_peripheral(self->gclk, I2S_GCLK_ID_0 + self->clock_unit); + disable_clock_generator(self->gclk); + + #ifdef SAMD51 + connect_gclk_to_peripheral(5, I2S_GCLK_ID_0 + self->clock_unit); + #endif + + self->playing = false; +} + +bool common_hal_audiobusio_i2sout_get_playing(audiobusio_i2sout_obj_t* self) { + bool still_playing = audio_dma_get_playing(&self->dma); + if (self->playing && !still_playing) { + common_hal_audiobusio_i2sout_stop(self); + } + return still_playing; +} diff --git a/ports/atmel-samd/common-hal/audiobusio/I2SOut.h b/ports/atmel-samd/common-hal/audiobusio/I2SOut.h new file mode 100644 index 00000000000..ce88f4de697 --- /dev/null +++ b/ports/atmel-samd/common-hal/audiobusio/I2SOut.h @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_AUDIOBUSIO_I2SOUT_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_AUDIOBUSIO_I2SOUT_H + +#include "common-hal/microcontroller/Pin.h" + +#include "audio_dma.h" +#include "py/obj.h" + +// We don't bit pack because we'll only have two at most. Its better to save code size instead. +typedef struct { + mp_obj_base_t base; + bool left_justified; + const mcu_pin_obj_t *bit_clock; + const mcu_pin_obj_t *word_select; + const mcu_pin_obj_t *data; + uint8_t clock_unit; + uint8_t serializer; + uint8_t gclk; + bool playing; + audio_dma_t dma; +} audiobusio_i2sout_obj_t; + +void i2sout_reset(void); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_AUDIOBUSIO_I2SOUT_H diff --git a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c new file mode 100644 index 00000000000..76010a68434 --- /dev/null +++ b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -0,0 +1,476 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 +#include +#include + +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "common-hal/analogio/AnalogOut.h" +#include "common-hal/audiobusio/PDMIn.h" +#include "shared-bindings/analogio/AnalogOut.h" +#include "shared-bindings/audiobusio/PDMIn.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "supervisor/shared/translate.h" + +#include "atmel_start_pins.h" +#include "hal/include/hal_gpio.h" +#include "hal/utils/include/utils.h" + +#include "samd/clocks.h" +#include "samd/events.h" +#include "samd/i2s.h" +#include "samd/pins.h" +#include "samd/dma.h" + +#include "audio_dma.h" +#include "tick.h" + +#define OVERSAMPLING 64 +#define SAMPLES_PER_BUFFER 32 + +// MEMS microphones must be clocked at at least 1MHz. +#define MIN_MIC_CLOCK 1000000 + +#ifdef SAMD21 +#define SERCTRL(name) I2S_SERCTRL_ ## name +#endif + +#ifdef SAMD51 +#define SERCTRL(name) I2S_RXCTRL_ ## name +#endif + +void pdmin_reset(void) { + while (I2S->SYNCBUSY.reg & I2S_SYNCBUSY_ENABLE) {} + I2S->INTENCLR.reg = I2S_INTENCLR_MASK; + I2S->INTFLAG.reg = I2S_INTFLAG_MASK; + I2S->CTRLA.reg &= ~I2S_SYNCBUSY_ENABLE; + while (I2S->SYNCBUSY.reg & I2S_SYNCBUSY_ENABLE) {} + I2S->CTRLA.reg = I2S_CTRLA_SWRST; +} + +void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t* self, + const mcu_pin_obj_t* clock_pin, + const mcu_pin_obj_t* data_pin, + uint32_t sample_rate, + uint8_t bit_depth, + bool mono, + uint8_t oversample) { + self->clock_pin = clock_pin; // PA10, PA20 -> SCK0, PB11 -> SCK1 + #ifdef SAMD21 + if (clock_pin == &pin_PA10 + #ifdef PIN_PA20 + || clock_pin == &pin_PA20 + #endif + ) { + self->clock_unit = 0; + #ifdef PIN_PB11 + } else if (clock_pin == &pin_PB11) { + self->clock_unit = 1; + #endif + #endif + #ifdef SAMD51 + if (clock_pin == &pin_PA10 || clock_pin == &pin_PB16) { + self->clock_unit = 0; + } else if (clock_pin == &pin_PB12 + #ifdef PIN_PB28 + || data_pin == &pin_PB28) { + #else + ) { + #endif + self->clock_unit = 1; + #endif + } else { + mp_raise_ValueError_varg(translate("Invalid %q pin"), MP_QSTR_clock); + } + + self->data_pin = data_pin; // PA07, PA19 -> SD0, PA08, PB16 -> SD1 + + #ifdef SAMD21 + if (data_pin == &pin_PA07 || data_pin == &pin_PA19) { + self->serializer = 0; + } else if (data_pin == &pin_PA08 + #ifdef PIN_PB16 + || data_pin == &pin_PB16) { + #else + ) { + #endif + self->serializer = 1; + #endif + #ifdef SAMD51 + if (data_pin == &pin_PB10 || data_pin == &pin_PA22) { + self->serializer = 1; + #endif + } else { + mp_raise_ValueError_varg(translate("Invalid %q pin"), MP_QSTR_data); + } + + if (!(bit_depth == 16 || bit_depth == 8) || !mono || oversample != OVERSAMPLING) { + mp_raise_NotImplementedError(translate("Only 8 or 16 bit mono with " MP_STRINGIFY(OVERSAMPLING) "x oversampling is supported.")); + } + + turn_on_i2s(); + + if (I2S->CTRLA.bit.ENABLE == 0) { + I2S->CTRLA.bit.SWRST = 1; + while (I2S->CTRLA.bit.SWRST == 1) {} + } else { + #ifdef SAMD21 + if ((I2S->CTRLA.vec.SEREN & (1 << self->serializer)) != 0) { + mp_raise_RuntimeError(translate("Serializer in use")); + } + #endif + #ifdef SAMD51 + if (I2S->CTRLA.bit.RXEN == 1) { + mp_raise_RuntimeError(translate("Serializer in use")); + } + #endif + } + #ifdef SAMD51 + #define GPIO_I2S_FUNCTION GPIO_PIN_FUNCTION_J + #endif + #ifdef SAMD21 + #define GPIO_I2S_FUNCTION GPIO_PIN_FUNCTION_G + #endif + assert_pin_free(clock_pin); + assert_pin_free(data_pin); + + uint32_t clock_divisor = (uint32_t) roundf( 48000000.0f / sample_rate / oversample); + float mic_clock_freq = 48000000.0f / clock_divisor; + self->sample_rate = mic_clock_freq / oversample; + if (mic_clock_freq < MIN_MIC_CLOCK || clock_divisor == 0) { + mp_raise_ValueError(translate("sampling rate out of range")); + } + // Find a free GCLK to generate the MCLK signal. + uint8_t gclk = find_free_gclk(clock_divisor); + if (gclk > GCLK_GEN_NUM) { + mp_raise_RuntimeError(translate("Unable to find free GCLK")); + } + self->gclk = gclk; + + enable_clock_generator(self->gclk, CLOCK_48MHZ, clock_divisor); + connect_gclk_to_peripheral(self->gclk, I2S_GCLK_ID_0 + self->clock_unit); + + // Clock unit configuration + + uint32_t clkctrl = I2S_CLKCTRL_MCKSEL_GCLK | + I2S_CLKCTRL_NBSLOTS(2) | + I2S_CLKCTRL_FSWIDTH_SLOT | + I2S_CLKCTRL_SLOTSIZE_16; + + // Serializer configuration + #ifdef SAMD21 + uint32_t serctrl = (self->clock_unit << I2S_SERCTRL_CLKSEL_Pos) | SERCTRL(SERMODE_PDM2) | SERCTRL(DATASIZE_32); + #endif + #ifdef SAMD51 + uint32_t serctrl = (self->clock_unit << I2S_RXCTRL_CLKSEL_Pos) | SERCTRL(SERMODE_PDM2) | SERCTRL(DATASIZE_32); + #endif + + // Configure the I2S peripheral + i2s_set_enable(false); + + I2S->CLKCTRL[self->clock_unit].reg = clkctrl; + #ifdef SAMD21 + I2S->SERCTRL[self->serializer].reg = serctrl; + #endif + #ifdef SAMD51 + I2S->RXCTRL.reg = serctrl; + #endif + + i2s_set_enable(true); + + // Run the clock all the time. This eliminates startup delay for the microphone, + // which can be 10-100ms. Turn serializer on as needed. + i2s_set_clock_unit_enable(self->clock_unit, true); + + claim_pin(clock_pin); + claim_pin(data_pin); + + gpio_set_pin_function(self->clock_pin->number, GPIO_I2S_FUNCTION); + gpio_set_pin_function(self->data_pin->number, GPIO_I2S_FUNCTION); + + self->bytes_per_sample = oversample >> 3; + self->bit_depth = bit_depth; +} + +bool common_hal_audiobusio_pdmin_deinited(audiobusio_pdmin_obj_t* self) { + return self->clock_pin == mp_const_none; +} + +void common_hal_audiobusio_pdmin_deinit(audiobusio_pdmin_obj_t* self) { + if (common_hal_audiobusio_pdmin_deinited(self)) { + return; + } + + i2s_set_serializer_enable(self->serializer, false); + i2s_set_clock_unit_enable(self->clock_unit, false); + + i2s_set_enable(false); + + disconnect_gclk_from_peripheral(self->gclk, I2S_GCLK_ID_0 + self->clock_unit); + disable_clock_generator(self->gclk); + + reset_pin_number(self->clock_pin->number); + reset_pin_number(self->data_pin->number); + self->clock_pin = mp_const_none; + self->data_pin = mp_const_none; +} + +uint8_t common_hal_audiobusio_pdmin_get_bit_depth(audiobusio_pdmin_obj_t* self) { + return self->bit_depth; +} + +uint32_t common_hal_audiobusio_pdmin_get_sample_rate(audiobusio_pdmin_obj_t* self) { + return self->sample_rate; +} + +static void setup_dma(audiobusio_pdmin_obj_t* self, uint32_t length, + DmacDescriptor* descriptor, + DmacDescriptor* second_descriptor, + uint32_t words_per_buffer, uint8_t words_per_sample, + uint32_t* first_buffer, uint32_t* second_buffer) { + descriptor->BTCTRL.reg = DMAC_BTCTRL_VALID | + DMAC_BTCTRL_BLOCKACT_NOACT | + DMAC_BTCTRL_EVOSEL_BLOCK | + DMAC_BTCTRL_DSTINC | + DMAC_BTCTRL_BEATSIZE_WORD; + + // Block transfer count is the number of beats per block (aka descriptor). + // In this case there are two bytes per beat so divide the length by two. + uint16_t block_transfer_count = words_per_buffer; + if (length * words_per_sample < words_per_buffer) { + block_transfer_count = length * words_per_sample; + } + + descriptor->BTCNT.reg = block_transfer_count; + descriptor->DSTADDR.reg = ((uint32_t) first_buffer + sizeof(uint32_t) * block_transfer_count); + descriptor->DESCADDR.reg = 0; + if (length * words_per_sample > words_per_buffer) { + descriptor->DESCADDR.reg = ((uint32_t)second_descriptor); + } + #ifdef SAMD21 + descriptor->SRCADDR.reg = (uint32_t)&I2S->DATA[self->serializer]; + #endif + #ifdef SAMD51 + descriptor->SRCADDR.reg = (uint32_t)&I2S->RXDATA; + #endif + + // Do we need more values than will fit in the first buffer? + // If so, set up a second buffer chained to be filled after the first buffer. + if (length * words_per_sample > words_per_buffer) { + block_transfer_count = words_per_buffer; + second_descriptor->DESCADDR.reg = ((uint32_t)descriptor); + if (length * words_per_sample < 2 * words_per_buffer) { + // Length needed is more than one buffer but less than two. + // Subtract off the size of the first buffer, and what remains is the count we need. + block_transfer_count = length * words_per_sample - words_per_buffer; + second_descriptor->DESCADDR.reg = 0; + } + second_descriptor->DSTADDR.reg = ((uint32_t) second_buffer + sizeof(uint32_t) * block_transfer_count); + + second_descriptor->BTCNT.reg = block_transfer_count; + #ifdef SAMD21 + second_descriptor->SRCADDR.reg = (uint32_t)&I2S->DATA[self->serializer]; + #endif + #ifdef SAMD51 + second_descriptor->SRCADDR.reg = (uint32_t)&I2S->RXDATA; + #endif + second_descriptor->BTCTRL.reg = DMAC_BTCTRL_VALID | + DMAC_BTCTRL_BLOCKACT_NOACT | + DMAC_BTCTRL_EVOSEL_BLOCK | + DMAC_BTCTRL_DSTINC | + DMAC_BTCTRL_BEATSIZE_WORD; + } +} + +// a windowed sinc filter for 44 khz, 64 samples +// +// This filter is good enough to use for lower sample rates as +// well. It does not increase the noise enough to be a problem. +// +// In the long run we could use a fast filter like this to do the +// decimation and initial filtering in real time, filtering to a +// higher sample rate than specified. Then after the audio is +// recorded, a more expensive filter non-real-time filter could be +// used to down-sample and low-pass. +uint16_t sinc_filter [OVERSAMPLING] = { + 0, 2, 9, 21, 39, 63, 94, 132, + 179, 236, 302, 379, 467, 565, 674, 792, + 920, 1055, 1196, 1341, 1487, 1633, 1776, 1913, + 2042, 2159, 2263, 2352, 2422, 2474, 2506, 2516, + 2506, 2474, 2422, 2352, 2263, 2159, 2042, 1913, + 1776, 1633, 1487, 1341, 1196, 1055, 920, 792, + 674, 565, 467, 379, 302, 236, 179, 132, + 94, 63, 39, 21, 9, 2, 0, 0 +}; + +#define REPEAT_16_TIMES(X) X X X X X X X X X X X X X X X X + +static uint16_t filter_sample(uint32_t pdm_samples[4]) { + uint16_t running_sum = 0; + const uint16_t *filter_ptr = sinc_filter; + for (uint8_t i = 0; i < OVERSAMPLING/16; i++) { + // The sample is 16-bits right channel in the upper two bytes and 16-bits left channel + // in the lower two bytes. + // We just ignore the upper bits + uint32_t pdm_sample = pdm_samples[i]; + REPEAT_16_TIMES( { + if (pdm_sample & 0x8000) { + running_sum += *filter_ptr; + } + filter_ptr++; + pdm_sample <<= 1; + } + ) + } + return running_sum; +} + +// output_buffer may be a byte buffer or a halfword buffer. +// output_buffer_length is the number of slots, not the number of bytes. +uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* self, + uint16_t* output_buffer, uint32_t output_buffer_length) { + uint8_t dma_channel = find_free_audio_dma_channel(); + uint8_t event_channel = find_sync_event_channel(); + if (event_channel >= EVSYS_SYNCH_NUM) { + mp_raise_RuntimeError(translate("All sync event channels in use")); + } + + // We allocate two buffers on the stack to use for double buffering. + const uint8_t samples_per_buffer = SAMPLES_PER_BUFFER; + // For every word we record, we throw away 2 bytes of a phantom second channel. + uint8_t words_per_sample = self->bytes_per_sample / 2; + uint32_t words_per_buffer = samples_per_buffer * words_per_sample; + uint32_t first_buffer[words_per_buffer]; + uint32_t second_buffer[words_per_buffer]; + + turn_on_event_system(); + + COMPILER_ALIGNED(16) DmacDescriptor second_descriptor; + + setup_dma(self, output_buffer_length, dma_descriptor(dma_channel), &second_descriptor, + words_per_buffer, words_per_sample, first_buffer, second_buffer); + + uint8_t trigger_source = I2S_DMAC_ID_RX_0; + #ifdef SAMD21 + trigger_source += self->serializer; + #endif + + dma_configure(dma_channel, trigger_source, true); + init_event_channel_interrupt(event_channel, CORE_GCLK, EVSYS_ID_GEN_DMAC_CH_0 + dma_channel); + // Turn on serializer now to get it in sync with DMA. + i2s_set_serializer_enable(self->serializer, true); + audio_dma_enable_channel(dma_channel); + + // Record + uint32_t buffers_processed = 0; + uint32_t values_output = 0; + + uint32_t remaining_samples_needed = output_buffer_length; + while (values_output < output_buffer_length) { + if (event_interrupt_overflow(event_channel)) { + // Looks like we aren't keeping up. We shouldn't skip a buffer so stop early. + break; + } + // Wait for the next buffer to fill + uint32_t wait_counts = 0; + #ifdef SAMD21 + #define MAX_WAIT_COUNTS 1000 + #endif + #ifdef SAMD51 + #define MAX_WAIT_COUNTS 6000 + #endif + // If wait_counts exceeds the max count, buffer has probably stopped filling; + // DMA may have missed an I2S trigger event. + while (!event_interrupt_active(event_channel) && ++wait_counts < MAX_WAIT_COUNTS) { + RUN_BACKGROUND_TASKS; + } + + // The mic is running all the time, so we don't need to wait the usual 10msec or 100msec + // for it to start up. + + // Flip back and forth between processing the first and second buffers. + uint32_t *buffer = first_buffer; + DmacDescriptor* descriptor = dma_descriptor(dma_channel); + if (buffers_processed % 2 == 1) { + buffer = second_buffer; + descriptor = &second_descriptor; + } + // Decimate and filter the buffer that was just filled. + uint32_t samples_gathered = descriptor->BTCNT.reg / words_per_sample; + // Don't run off the end of output buffer. Process only as many as needed. + uint32_t samples_to_process = min(remaining_samples_needed, samples_gathered); + for (uint32_t i = 0; i < samples_to_process; i++) { + // Call filter_sample just one place so it can be inlined. + uint16_t value = filter_sample(buffer + i * words_per_sample); + if (self->bit_depth == 8) { + // Truncate to 8 bits. + ((uint8_t*) output_buffer)[values_output] = value >> 8; + } else { + output_buffer[values_output] = value; + } + values_output++; + } + + buffers_processed++; + + // Compute how many more samples we need, and if the last buffer is the last + // set of samples needed, adjust the DMA count to only fetch as necessary. + remaining_samples_needed = output_buffer_length - values_output; + if (remaining_samples_needed <= samples_per_buffer*2 && + remaining_samples_needed > samples_per_buffer) { + // Adjust the DMA settings for the current buffer, which will be processed + // after the other buffer, which is now receiving samples via DMA. + // We don't adjust the DMA in progress, but the one after that. + // Timeline: + // 1. current buffer (already processed) + // 2. alternate buffer (DMA in progress) + // 3. current buffer (last set of samples needed) + + // Set up to receive the last set of samples (don't include the alternate buffer, now in use). + uint32_t samples_needed_for_last_buffer = remaining_samples_needed - samples_per_buffer; + descriptor->BTCNT.reg = samples_needed_for_last_buffer * words_per_sample; + descriptor->DSTADDR.reg = ((uint32_t) buffer) + + samples_needed_for_last_buffer * words_per_sample * sizeof(buffer[0]); + + // Break chain to alternate buffer. + descriptor->DESCADDR.reg = 0; + } + } + + disable_event_channel(event_channel); + audio_dma_disable_channel(dma_channel); + // Turn off serializer, but leave clock on, to avoid mic startup delay. + i2s_set_serializer_enable(self->serializer, false); + + return values_output; +} + +void common_hal_audiobusio_pdmin_record_to_file(audiobusio_pdmin_obj_t* self, uint8_t* buffer, uint32_t length) { + +} diff --git a/ports/atmel-samd/common-hal/audiobusio/PDMIn.h b/ports/atmel-samd/common-hal/audiobusio/PDMIn.h new file mode 100644 index 00000000000..5c4d4feea06 --- /dev/null +++ b/ports/atmel-samd/common-hal/audiobusio/PDMIn.h @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_AUDIOBUSIO_AUDIOOUT_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_AUDIOBUSIO_AUDIOOUT_H + +#include "common-hal/microcontroller/Pin.h" + +#include "extmod/vfs_fat.h" +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t *clock_pin; + const mcu_pin_obj_t *data_pin; + uint32_t sample_rate; + uint8_t serializer; + uint8_t clock_unit; + uint8_t bytes_per_sample; + uint8_t bit_depth; + uint8_t gclk; +} audiobusio_pdmin_obj_t; + +void pdmin_reset(void); + +void pdmin_background(void); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_AUDIOBUSIO_AUDIOOUT_H diff --git a/ports/atmel-samd/common-hal/audiobusio/__init__.c b/ports/atmel-samd/common-hal/audiobusio/__init__.c new file mode 100644 index 00000000000..87db404966a --- /dev/null +++ b/ports/atmel-samd/common-hal/audiobusio/__init__.c @@ -0,0 +1 @@ +// No audiobusio module functions. diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.c b/ports/atmel-samd/common-hal/audioio/AudioOut.c new file mode 100644 index 00000000000..90f1aa41f68 --- /dev/null +++ b/ports/atmel-samd/common-hal/audioio/AudioOut.c @@ -0,0 +1,471 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 +#include + +#include "extmod/vfs_fat.h" +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "common-hal/audioio/AudioOut.h" +#include "shared-bindings/audioio/AudioOut.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "supervisor/shared/translate.h" + +#include "atmel_start_pins.h" +#include "hal/include/hal_gpio.h" +#include "hpl/gclk/hpl_gclk_base.h" +#include "peripheral_clk_config.h" + +#ifdef SAMD21 +#include "hpl/pm/hpl_pm_base.h" +#endif + +#include "audio_dma.h" +#include "timer_handler.h" + +#include "samd/dma.h" +#include "samd/events.h" +#include "samd/pins.h" +#include "samd/timers.h" + +#ifdef SAMD21 +static void ramp_value(uint16_t start, uint16_t end) { + start = DAC->DATA.reg; + int32_t diff = (int32_t) end - start; + int32_t step = 49; + int32_t steps = diff / step; + if (diff < 0) { + steps = -steps; + step = -step; + } + for (int32_t i = 0; i < steps; i++) { + uint32_t value = start + step * i; + DAC->DATA.reg = value; + DAC->DATABUF.reg = value; + common_hal_mcu_delay_us(50); + RUN_BACKGROUND_TASKS; + } +} +#endif + +#ifdef SAMD51 +static void ramp_value(uint16_t start, uint16_t end) { + int32_t diff = (int32_t) end - start; + int32_t step = 49; + int32_t steps = diff / step; + if (diff < 0) { + steps = -steps; + step = -step; + } + + for (int32_t i = 0; i < steps; i++) { + uint16_t value = start + step * i; + DAC->DATA[0].reg = value; + DAC->DATABUF[0].reg = value; + DAC->DATA[1].reg = value; + DAC->DATABUF[1].reg = value; + + common_hal_mcu_delay_us(50); + RUN_BACKGROUND_TASKS; + } +} +#endif + +void audioout_reset(void) { + #if defined(SAMD21) && !defined(PIN_PA02) + return; + #endif + #ifdef SAMD21 + while (DAC->STATUS.reg & DAC_STATUS_SYNCBUSY) {} + #endif + #ifdef SAMD51 + while (DAC->SYNCBUSY.reg & DAC_SYNCBUSY_SWRST) {} + #endif + if (DAC->CTRLA.bit.ENABLE) { + ramp_value(0x8000, 0); + } + DAC->CTRLA.reg |= DAC_CTRLA_SWRST; + + // TODO(tannewt): Turn off the DAC clocks to save power. +} + +void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self, + const mcu_pin_obj_t* left_channel, const mcu_pin_obj_t* right_channel, uint16_t quiescent_value) { + #ifdef SAMD51 + bool dac_clock_enabled = hri_mclk_get_APBDMASK_DAC_bit(MCLK); + #endif + + #ifdef SAMD21 + bool dac_clock_enabled = PM->APBCMASK.bit.DAC_; + #endif + // Only support exclusive use of the DAC. + if (dac_clock_enabled && DAC->CTRLA.bit.ENABLE == 1) { + mp_raise_RuntimeError(translate("DAC already in use")); + } + #ifdef SAMD21 + if (right_channel != NULL) { + mp_raise_ValueError(translate("Right channel unsupported")); + } + if (left_channel != &pin_PA02) { + mp_raise_ValueError(translate("Invalid pin")); + } + assert_pin_free(left_channel); + claim_pin(left_channel); + #endif + #ifdef SAMD51 + self->right_channel = NULL; + if (left_channel != &pin_PA02 && left_channel != &pin_PA05) { + mp_raise_ValueError(translate("Invalid pin for left channel")); + } + assert_pin_free(left_channel); + if (right_channel != NULL && right_channel != &pin_PA02 && right_channel != &pin_PA05) { + mp_raise_ValueError(translate("Invalid pin for right channel")); + } + if (right_channel == left_channel) { + mp_raise_ValueError(translate("Cannot output both channels on the same pin")); + } + claim_pin(left_channel); + if (right_channel != NULL) { + claim_pin(right_channel); + self->right_channel = right_channel; + audio_dma_init(&self->right_dma); + } + #endif + self->left_channel = left_channel; + audio_dma_init(&self->left_dma); + + #ifdef SAMD51 + hri_mclk_set_APBDMASK_DAC_bit(MCLK); + #endif + + #ifdef SAMD21 + _pm_enable_bus_clock(PM_BUS_APBC, DAC); + #endif + + // SAMD51: This clock should be <= 12 MHz, per datasheet section 47.6.3. + // SAMD21: This clock is 48mhz despite the datasheet saying it must only be <= 350kHz, per + // datasheet table 37-6. It's incorrect because the max output rate is 350ksps and is only + // achieved when the GCLK is more than 8mhz. + _gclk_enable_channel(DAC_GCLK_ID, CONF_GCLK_DAC_SRC); + + DAC->CTRLA.bit.SWRST = 1; + while (DAC->CTRLA.bit.SWRST == 1) {} + // Make sure there are no outstanding access errors. (Reading DATA can cause this.) + #ifdef SAMD51 + PAC->INTFLAGD.reg = PAC_INTFLAGD_DAC; + #endif + + bool channel0_enabled = true; + #ifdef SAMD51 + channel0_enabled = self->left_channel == &pin_PA02 || self->right_channel == &pin_PA02; + bool channel1_enabled = self->left_channel == &pin_PA05 || self->right_channel == &pin_PA05; + #endif + + if (channel0_enabled) { + #ifdef SAMD21 + DAC->EVCTRL.reg |= DAC_EVCTRL_STARTEI; + // We disable the voltage pump because we always run at 3.3v. + DAC->CTRLB.reg = DAC_CTRLB_REFSEL_AVCC | + DAC_CTRLB_LEFTADJ | + DAC_CTRLB_EOEN | + DAC_CTRLB_VPD; + #endif + #ifdef SAMD51 + DAC->EVCTRL.reg |= DAC_EVCTRL_STARTEI0; + DAC->DACCTRL[0].reg = DAC_DACCTRL_CCTRL_CC1M | + DAC_DACCTRL_ENABLE | + DAC_DACCTRL_LEFTADJ; + DAC->CTRLB.reg = DAC_CTRLB_REFSEL_VREFPU; + #endif + } + #ifdef SAMD51 + if (channel1_enabled) { + DAC->EVCTRL.reg |= DAC_EVCTRL_STARTEI1; + DAC->DACCTRL[1].reg = DAC_DACCTRL_CCTRL_CC1M | + DAC_DACCTRL_ENABLE | + DAC_DACCTRL_LEFTADJ; + DAC->CTRLB.reg = DAC_CTRLB_REFSEL_VREFPU; + } + #endif + + // Re-enable the DAC + DAC->CTRLA.bit.ENABLE = 1; + #ifdef SAMD21 + while (DAC->STATUS.bit.SYNCBUSY == 1) {} + #endif + #ifdef SAMD51 + while (DAC->SYNCBUSY.bit.ENABLE == 1) {} + while (channel0_enabled && DAC->STATUS.bit.READY0 == 0) {} + while (channel1_enabled && DAC->STATUS.bit.READY1 == 0) {} + #endif + + // Use a timer to coordinate when DAC conversions occur. + Tc *t = NULL; + uint8_t tc_index = TC_INST_NUM; + for (uint8_t i = TC_INST_NUM; i > 0; i--) { + if (tc_insts[i - 1]->COUNT16.CTRLA.bit.ENABLE == 0) { + t = tc_insts[i - 1]; + tc_index = i - 1; + break; + } + } + if (t == NULL) { + common_hal_audioio_audioout_deinit(self); + mp_raise_RuntimeError(translate("All timers in use")); + return; + } + self->tc_index = tc_index; + + // Use the 48mhz clocks on both the SAMD21 and 51 because we will be going much slower. + uint8_t tc_gclk = 0; + #ifdef SAMD51 + tc_gclk = 1; + #endif + + set_timer_handler(true, tc_index, TC_HANDLER_NO_INTERRUPT); + turn_on_clocks(true, tc_index, tc_gclk); + + // Don't bother setting the period. We set it before you playback anything. + tc_set_enable(t, false); + tc_reset(t); + #ifdef SAMD51 + t->COUNT16.WAVE.reg = TC_WAVE_WAVEGEN_MFRQ; + #endif + #ifdef SAMD21 + t->COUNT16.CTRLA.bit.WAVEGEN = TC_CTRLA_WAVEGEN_MFRQ_Val; + #endif + t->COUNT16.EVCTRL.reg = TC_EVCTRL_OVFEO; + tc_set_enable(t, true); + t->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_STOP; + + // Connect the timer overflow event, which happens at the target frequency, + // to the DAC conversion trigger(s). + #ifdef SAMD21 + #define FIRST_TC_GEN_ID EVSYS_ID_GEN_TC3_OVF + #endif + #ifdef SAMD51 + #define FIRST_TC_GEN_ID EVSYS_ID_GEN_TC0_OVF + #endif + uint8_t tc_gen_id = FIRST_TC_GEN_ID + 3 * tc_index; + + turn_on_event_system(); + + // Find a free event channel. We start at the highest channels because we only need and async + // path. + uint8_t channel = find_async_event_channel(); + if (channel >= EVSYS_CHANNELS) { + mp_raise_RuntimeError(translate("All event channels in use")); + } + + #ifdef SAMD51 + connect_event_user_to_channel(EVSYS_ID_USER_DAC_START_1, channel); + if (right_channel != NULL) { + gpio_set_pin_function(self->right_channel->number, GPIO_PIN_FUNCTION_B); + } + #define EVSYS_ID_USER_DAC_START EVSYS_ID_USER_DAC_START_0 + #endif + connect_event_user_to_channel(EVSYS_ID_USER_DAC_START, channel); + gpio_set_pin_function(self->left_channel->number, GPIO_PIN_FUNCTION_B); + init_async_event_channel(channel, tc_gen_id); + + self->tc_to_dac_event_channel = channel; + + // Ramp the DAC up. + self->quiescent_value = quiescent_value; + ramp_value(0, quiescent_value); + + // Leave the DMA setup to playback. +} + +bool common_hal_audioio_audioout_deinited(audioio_audioout_obj_t* self) { + return self->left_channel == mp_const_none; +} + +void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t* self) { + if (common_hal_audioio_audioout_deinited(self)) { + return; + } + + // Ramp the DAC down. + ramp_value(self->quiescent_value, 0); + + DAC->CTRLA.bit.ENABLE = 0; + #ifdef SAMD21 + while (DAC->STATUS.bit.SYNCBUSY == 1) {} + #endif + #ifdef SAMD51 + while (DAC->SYNCBUSY.bit.ENABLE == 1) {} + #endif + + disable_event_channel(self->tc_to_dac_event_channel); + + tc_set_enable(tc_insts[self->tc_index], false); + + reset_pin_number(self->left_channel->number); + self->left_channel = mp_const_none; + #ifdef SAMD51 + reset_pin_number(self->right_channel->number); + self->right_channel = mp_const_none; + #endif +} + +static void set_timer_frequency(Tc* timer, uint32_t frequency) { + uint32_t system_clock = 48000000; + uint32_t new_top; + uint8_t new_divisor; + for (new_divisor = 0; new_divisor < 8; new_divisor++) { + new_top = (system_clock / prescaler[new_divisor] / frequency) - 1; + if (new_top < (1u << 16)) { + break; + } + } + uint8_t old_divisor = timer->COUNT16.CTRLA.bit.PRESCALER; + if (new_divisor != old_divisor) { + tc_set_enable(timer, false); + timer->COUNT16.CTRLA.bit.PRESCALER = new_divisor; + tc_set_enable(timer, true); + } + tc_wait_for_sync(timer); + timer->COUNT16.CC[0].reg = new_top; + tc_wait_for_sync(timer); +} + +void common_hal_audioio_audioout_play(audioio_audioout_obj_t* self, + mp_obj_t sample, bool loop) { + if (common_hal_audioio_audioout_get_playing(self)) { + common_hal_audioio_audioout_stop(self); + } + audio_dma_result result = AUDIO_DMA_OK; + uint32_t sample_rate = audiosample_sample_rate(sample); + #ifdef SAMD21 + uint32_t max_sample_rate = 350000; + #endif + #ifdef SAMD51 + uint32_t max_sample_rate = 1000000; + #endif + if (sample_rate > max_sample_rate) { + mp_raise_ValueError_varg(translate("Sample rate too high. It must be less than %d"), max_sample_rate); + } + #ifdef SAMD21 + result = audio_dma_setup_playback(&self->left_dma, sample, loop, true, 0, + false /* output unsigned */, + (uint32_t) &DAC->DATABUF.reg, + DAC_DMAC_ID_EMPTY); + #endif + + #ifdef SAMD51 + uint32_t left_channel_reg = (uint32_t) &DAC->DATABUF[0].reg; + uint8_t left_channel_trigger = DAC_DMAC_ID_EMPTY_0; + uint32_t right_channel_reg = 0; + uint8_t right_channel_trigger = 0; + if (self->left_channel == &pin_PA05) { + left_channel_reg = (uint32_t) &DAC->DATABUF[1].reg; + left_channel_trigger = DAC_DMAC_ID_EMPTY_1; + } else if (self->right_channel == &pin_PA05) { + right_channel_reg = (uint32_t) &DAC->DATABUF[1].reg; + right_channel_trigger = DAC_DMAC_ID_EMPTY_1; + } + if (self->right_channel == &pin_PA02) { + right_channel_reg = (uint32_t) &DAC->DATABUF[0].reg; + right_channel_trigger = DAC_DMAC_ID_EMPTY_0; + } + result = audio_dma_setup_playback(&self->left_dma, sample, loop, true, 0, + false /* output unsigned */, + left_channel_reg, + left_channel_trigger); + if (right_channel_reg != 0 && result == AUDIO_DMA_OK) { + result = audio_dma_setup_playback(&self->right_dma, sample, loop, true, 1, + false /* output unsigned */, + right_channel_reg, + right_channel_trigger); + } + #endif + if (result != AUDIO_DMA_OK) { + audio_dma_stop(&self->left_dma); + #ifdef SAMD51 + audio_dma_stop(&self->right_dma); + #endif + if (result == AUDIO_DMA_DMA_BUSY) { + mp_raise_RuntimeError(translate("No DMA channel found")); + } else if (result == AUDIO_DMA_MEMORY_ERROR) { + mp_raise_RuntimeError(translate("Unable to allocate buffers for signed conversion")); + } + } + Tc* timer = tc_insts[self->tc_index]; + set_timer_frequency(timer, audiosample_sample_rate(sample)); + timer->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_RETRIGGER; + while (timer->COUNT16.STATUS.bit.STOP == 1) {} + self->playing = true; +} + +void common_hal_audioio_audioout_pause(audioio_audioout_obj_t* self) { + audio_dma_pause(&self->left_dma); + #ifdef SAMD51 + audio_dma_pause(&self->right_dma); + #endif +} + +void common_hal_audioio_audioout_resume(audioio_audioout_obj_t* self) { + // Clear any overrun/underrun errors + #ifdef SAMD21 + DAC->INTFLAG.reg = DAC_INTFLAG_UNDERRUN; + #endif + #ifdef SAMD51 + DAC->INTFLAG.reg = DAC_INTFLAG_UNDERRUN0 | DAC_INTFLAG_UNDERRUN1; + #endif + + audio_dma_resume(&self->left_dma); + #ifdef SAMD51 + audio_dma_resume(&self->right_dma); + #endif +} + +bool common_hal_audioio_audioout_get_paused(audioio_audioout_obj_t* self) { + return audio_dma_get_paused(&self->left_dma); +} + +void common_hal_audioio_audioout_stop(audioio_audioout_obj_t* self) { + Tc* timer = tc_insts[self->tc_index]; + timer->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_STOP; + audio_dma_stop(&self->left_dma); + #ifdef SAMD51 + audio_dma_stop(&self->right_dma); + #endif + // Ramp the DAC to default. The start is ignored when the current value can be readback. + // Otherwise, we just set it immediately. + ramp_value(self->quiescent_value, self->quiescent_value); +} + +bool common_hal_audioio_audioout_get_playing(audioio_audioout_obj_t* self) { + bool now_playing = audio_dma_get_playing(&self->left_dma); + if (self->playing && !now_playing) { + common_hal_audioio_audioout_stop(self); + } + return now_playing; +} diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.h b/ports/atmel-samd/common-hal/audioio/AudioOut.h new file mode 100644 index 00000000000..56b6b75c893 --- /dev/null +++ b/ports/atmel-samd/common-hal/audioio/AudioOut.h @@ -0,0 +1,54 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_AUDIOIO_AUDIOOUT_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_AUDIOIO_AUDIOOUT_H + +#include "common-hal/microcontroller/Pin.h" + +#include "audio_dma.h" +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t *left_channel; + audio_dma_t left_dma; + #ifdef SAMD51 + const mcu_pin_obj_t *right_channel; + audio_dma_t right_dma; + #endif + uint8_t tc_index; + + uint8_t tc_to_dac_event_channel; + bool playing; + uint16_t quiescent_value; +} audioio_audioout_obj_t; + +void audioout_reset(void); + +void audioout_background(void); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_AUDIOIO_AUDIOOUT_H diff --git a/ports/atmel-samd/common-hal/audioio/__init__.c b/ports/atmel-samd/common-hal/audioio/__init__.c new file mode 100644 index 00000000000..404f021a117 --- /dev/null +++ b/ports/atmel-samd/common-hal/audioio/__init__.c @@ -0,0 +1 @@ +// No audioio module functions. diff --git a/ports/atmel-samd/common-hal/board/__init__.c b/ports/atmel-samd/common-hal/board/__init__.c new file mode 100644 index 00000000000..634760335e4 --- /dev/null +++ b/ports/atmel-samd/common-hal/board/__init__.c @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython 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 + +#include "py/runtime.h" +#include "py/mphal.h" +#include "common-hal/microcontroller/Pin.h" + +// Pins aren't actually defined here. They are in the board specific directory +// such as boards/arduino_zero/pins.c. diff --git a/ports/atmel-samd/common-hal/busio/I2C.c b/ports/atmel-samd/common-hal/busio/I2C.c new file mode 100644 index 00000000000..cdc616bbc8e --- /dev/null +++ b/ports/atmel-samd/common-hal/busio/I2C.c @@ -0,0 +1,236 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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 "shared-bindings/busio/I2C.h" +#include "py/mperrno.h" +#include "py/runtime.h" + +#include "hal/include/hal_gpio.h" +#include "hal/include/hal_i2c_m_sync.h" +#include "hal/include/hpl_i2c_m_sync.h" + +#include "samd/sercom.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "supervisor/shared/translate.h" + +#include "common-hal/busio/SPI.h" // for never_reset_sercom + +// Number of times to try to send packet if failed. +#define ATTEMPTS 2 + +Sercom *samd_i2c_get_sercom(const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, + uint8_t *sercom_index, uint32_t *sda_pinmux, uint32_t *scl_pinmux) { + *sda_pinmux = 0; + *scl_pinmux = 0; + for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) { + *sercom_index = sda->sercom[i].index; + if (*sercom_index >= SERCOM_INST_NUM) { + continue; + } + Sercom* potential_sercom = sercom_insts[*sercom_index]; + if (potential_sercom->I2CM.CTRLA.bit.ENABLE != 0 || + sda->sercom[i].pad != 0) { + continue; + } + *sda_pinmux = PINMUX(sda->number, (i == 0) ? MUX_C : MUX_D); + for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { + if (*sercom_index == scl->sercom[j].index && + scl->sercom[j].pad == 1) { + *scl_pinmux = PINMUX(scl->number, (j == 0) ? MUX_C : MUX_D); + return potential_sercom; + } + } + } + return NULL; +} + +void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, + const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t frequency, uint32_t timeout) { + uint8_t sercom_index; + uint32_t sda_pinmux, scl_pinmux; + Sercom* sercom = samd_i2c_get_sercom(scl, sda, &sercom_index, &sda_pinmux, &scl_pinmux); + if (sercom == NULL) { + mp_raise_ValueError(translate("Invalid pins")); + } + + // Test that the pins are in a high state. (Hopefully indicating they are pulled up.) + gpio_set_pin_function(sda->number, GPIO_PIN_FUNCTION_OFF); + gpio_set_pin_function(scl->number, GPIO_PIN_FUNCTION_OFF); + gpio_set_pin_direction(sda->number, GPIO_DIRECTION_IN); + gpio_set_pin_direction(scl->number, GPIO_DIRECTION_IN); + + gpio_set_pin_pull_mode(sda->number, GPIO_PULL_DOWN); + gpio_set_pin_pull_mode(scl->number, GPIO_PULL_DOWN); + + common_hal_mcu_delay_us(10); + + gpio_set_pin_pull_mode(sda->number, GPIO_PULL_OFF); + gpio_set_pin_pull_mode(scl->number, GPIO_PULL_OFF); + + // We must pull up within 3us to achieve 400khz. + common_hal_mcu_delay_us(3); + + if (!gpio_get_pin_level(sda->number) || !gpio_get_pin_level(scl->number)) { + reset_pin_number(sda->number); + reset_pin_number(scl->number); + mp_raise_RuntimeError(translate("SDA or SCL needs a pull up")); + } + gpio_set_pin_function(sda->number, sda_pinmux); + gpio_set_pin_function(scl->number, scl_pinmux); + + // Set up I2C clocks on sercom. + samd_peripherals_sercom_clock_init(sercom, sercom_index); + + if (i2c_m_sync_init(&self->i2c_desc, sercom) != ERR_NONE) { + reset_pin_number(sda->number); + reset_pin_number(scl->number); + mp_raise_OSError(MP_EIO); + } + + // clkrate is always 0. baud_rate is in kHz. + + // Frequency must be set before the I2C device is enabled. + if (i2c_m_sync_set_baudrate(&self->i2c_desc, 0, frequency / 1000) != ERR_NONE) { + reset_pin_number(sda->number); + reset_pin_number(scl->number); + mp_raise_ValueError(translate("Unsupported baudrate")); + } + + self->sda_pin = sda->number; + self->scl_pin = scl->number; + claim_pin(sda); + claim_pin(scl); + + if (i2c_m_sync_enable(&self->i2c_desc) != ERR_NONE) { + common_hal_busio_i2c_deinit(self); + mp_raise_OSError(MP_EIO); + } +} + +bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { + return self->sda_pin == NO_PIN; +} + +void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { + if (common_hal_busio_i2c_deinited(self)) { + return; + } + + i2c_m_sync_disable(&self->i2c_desc); + i2c_m_sync_deinit(&self->i2c_desc); + + reset_pin_number(self->sda_pin); + reset_pin_number(self->scl_pin); + self->sda_pin = NO_PIN; + self->scl_pin = NO_PIN; +} + +bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { + struct io_descriptor *i2c_io; + i2c_m_sync_get_io_descriptor(&self->i2c_desc, &i2c_io); + i2c_m_sync_set_slaveaddr(&self->i2c_desc, addr, I2C_M_SEVEN); + + // Write no data when just probing + return io_write(i2c_io, NULL, 0) == ERR_NONE; +} + +bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) { + bool grabbed_lock = false; + CRITICAL_SECTION_ENTER() + if (!self->has_lock) { + grabbed_lock = true; + self->has_lock = true; + } + CRITICAL_SECTION_LEAVE(); + return grabbed_lock; +} + +bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self) { + return self->has_lock; +} + +void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { + self->has_lock = false; +} + +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, + const uint8_t *data, size_t len, bool transmit_stop_bit) { + + uint16_t attempts = ATTEMPTS; + int32_t status; + do { + struct _i2c_m_msg msg; + msg.addr = addr; + msg.len = len; + msg.flags = transmit_stop_bit ? I2C_M_STOP : 0; + msg.buffer = (uint8_t *) data; + status = _i2c_m_sync_transfer(&self->i2c_desc.device, &msg); + + // Give up after ATTEMPTS tries. + if (--attempts == 0) { + break; + } + } while (status != I2C_OK); + if (status == I2C_OK) { + return 0; + } else if (status == I2C_ERR_BAD_ADDRESS) { + return MP_ENODEV; + } + return MP_EIO; +} + +uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *data, size_t len) { + + uint16_t attempts = ATTEMPTS; + int32_t status; + do { + struct _i2c_m_msg msg; + msg.addr = addr; + msg.len = len; + msg.flags = I2C_M_STOP | I2C_M_RD; + msg.buffer = data; + status = _i2c_m_sync_transfer(&self->i2c_desc.device, &msg); + + // Give up after ATTEMPTS tries. + if (--attempts == 0) { + break; + } + } while (status != I2C_OK); + if (status == ERR_NONE) { + return 0; + } else if (status == I2C_ERR_BAD_ADDRESS) { + return MP_ENODEV; + } + return MP_EIO; +} + +void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { + never_reset_sercom(self->i2c_desc.device.hw); + + never_reset_pin_number(self->scl_pin); + never_reset_pin_number(self->sda_pin); +} diff --git a/ports/atmel-samd/common-hal/busio/I2C.h b/ports/atmel-samd/common-hal/busio/I2C.h new file mode 100644 index 00000000000..6bec6e8047a --- /dev/null +++ b/ports/atmel-samd/common-hal/busio/I2C.h @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_H + +#include "common-hal/microcontroller/Pin.h" + +#include "hal/include/hal_i2c_m_sync.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + struct i2c_m_sync_desc i2c_desc; + bool has_lock; + uint8_t scl_pin; + uint8_t sda_pin; +} busio_i2c_obj_t; + +extern Sercom *samd_i2c_get_sercom(const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, + uint8_t *sercom_index, uint32_t *sda_pinmux, uint32_t *scl_pinmux); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_H diff --git a/ports/atmel-samd/common-hal/busio/OneWire.h b/ports/atmel-samd/common-hal/busio/OneWire.h new file mode 100644 index 00000000000..a09a44c2627 --- /dev/null +++ b/ports/atmel-samd/common-hal/busio/OneWire.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_ONEWIRE_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_ONEWIRE_H + +// Use bitbangio. +#include "shared-module/busio/OneWire.h" + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_ONEWIRE_H diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c new file mode 100644 index 00000000000..7a1426bedc8 --- /dev/null +++ b/ports/atmel-samd/common-hal/busio/SPI.c @@ -0,0 +1,373 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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 "shared-bindings/busio/SPI.h" +#include "py/mperrno.h" +#include "py/runtime.h" + +#include "hpl_sercom_config.h" +#include "peripheral_clk_config.h" + +#include "boards/board.h" +#include "common-hal/microcontroller/Pin.h" +#include "hal/include/hal_gpio.h" +#include "hal/include/hal_spi_m_sync.h" +#include "hal/include/hpl_spi_m_sync.h" +#include "supervisor/shared/rgb_led_status.h" + +#include "samd/dma.h" +#include "samd/sercom.h" + +bool never_reset_sercoms[SERCOM_INST_NUM]; + +void never_reset_sercom(Sercom* sercom) { + // Reset all SERCOMs except the ones being used by on-board devices. + Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS; + for (int i = 0; i < SERCOM_INST_NUM; i++) { + if (sercom_instances[i] == sercom) { + never_reset_sercoms[i] = true; + break; + } + } +} + +void allow_reset_sercom(Sercom* sercom) { + // Reset all SERCOMs except the ones being used by on-board devices. + Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS; + for (int i = 0; i < SERCOM_INST_NUM; i++) { + if (sercom_instances[i] == sercom) { + never_reset_sercoms[i] = false; + break; + } + } +} + +void reset_sercoms(void) { + // Reset all SERCOMs except the ones being used by on-board devices. + Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS; + for (int i = 0; i < SERCOM_INST_NUM; i++) { + if (never_reset_sercoms[i]) { + continue; + } + #ifdef MICROPY_HW_APA102_SERCOM + if (sercom_instances[i] == MICROPY_HW_APA102_SERCOM) { + continue; + } + #endif + // SWRST is same for all modes of SERCOMs. + sercom_instances[i]->SPI.CTRLA.bit.SWRST = 1; + } +} + + +void common_hal_busio_spi_construct(busio_spi_obj_t *self, + const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, + const mcu_pin_obj_t * miso) { + Sercom* sercom = NULL; + uint8_t sercom_index; + uint32_t clock_pinmux = 0; + bool mosi_none = mosi == mp_const_none || mosi == NULL; + bool miso_none = miso == mp_const_none || miso == NULL; + uint32_t mosi_pinmux = 0; + uint32_t miso_pinmux = 0; + uint8_t clock_pad = 0; + uint8_t mosi_pad = 0; + uint8_t miso_pad = 0; + uint8_t dopo = 255; + + // Special case for SAMR boards. + #ifdef PIN_PC19 + if (miso == &pin_PC19) { + if (mosi == &pin_PB30 && clock == &pin_PC18) { + sercom = SERCOM4; + sercom_index = 4; + clock_pinmux = MUX_F; + mosi_pinmux = MUX_F; + miso_pinmux = MUX_F; + clock_pad = 3; + mosi_pad = 2; + miso_pad = 0; + dopo = samd_peripherals_get_spi_dopo(clock_pad, mosi_pad); + } + // Error, leave SERCOM unset to throw an exception later. + } else { + #endif + for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) { + sercom_index = clock->sercom[i].index; // 2 for SERCOM2, etc. + if (sercom_index >= SERCOM_INST_NUM) { + continue; + } + Sercom* potential_sercom = sercom_insts[sercom_index]; + if ( + #if defined(MICROPY_HW_APA102_SCK) && defined(MICROPY_HW_APA102_MOSI) && !CIRCUITPY_BITBANG_APA102 + (potential_sercom->SPI.CTRLA.bit.ENABLE != 0 && + potential_sercom != status_apa102.spi_desc.dev.prvt && + !apa102_sck_in_use)) { + #else + potential_sercom->SPI.CTRLA.bit.ENABLE != 0) { + #endif + continue; + } + clock_pinmux = PINMUX(clock->number, (i == 0) ? MUX_C : MUX_D); + clock_pad = clock->sercom[i].pad; + if (!samd_peripherals_valid_spi_clock_pad(clock_pad)) { + continue; + } + for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { + if (!mosi_none) { + if (sercom_index == mosi->sercom[j].index) { + mosi_pinmux = PINMUX(mosi->number, (j == 0) ? MUX_C : MUX_D); + mosi_pad = mosi->sercom[j].pad; + dopo = samd_peripherals_get_spi_dopo(clock_pad, mosi_pad); + if (dopo > 0x3) { + continue; // pad combination not possible + } + if (miso_none) { + sercom = potential_sercom; + break; + } + } else { + continue; + } + } + if (!miso_none) { + for (int k = 0; k < NUM_SERCOMS_PER_PIN; k++) { + if (sercom_index == miso->sercom[k].index) { + miso_pinmux = PINMUX(miso->number, (k == 0) ? MUX_C : MUX_D); + miso_pad = miso->sercom[k].pad; + sercom = potential_sercom; + break; + } + } + } + if (sercom != NULL) { + break; + } + } + if (sercom != NULL) { + break; + } + } + #ifdef PIN_PC19 + } + #endif + if (sercom == NULL) { + mp_raise_ValueError(translate("Invalid pins")); + } + + // Set up SPI clocks on SERCOM. + samd_peripherals_sercom_clock_init(sercom, sercom_index); + + #if defined(MICROPY_HW_APA102_SCK) && defined(MICROPY_HW_APA102_MOSI) && !CIRCUITPY_BITBANG_APA102 + // if we're re-using the dotstar sercom, make sure it is disabled or the init will fail out + hri_sercomspi_clear_CTRLA_ENABLE_bit(sercom); + #endif + if (spi_m_sync_init(&self->spi_desc, sercom) != ERR_NONE) { + mp_raise_OSError(MP_EIO); + } + + // Pads must be set after spi_m_sync_init(), which uses default values from + // the prototypical SERCOM. + hri_sercomspi_write_CTRLA_DOPO_bf(sercom, dopo); + hri_sercomspi_write_CTRLA_DIPO_bf(sercom, miso_pad); + + // Always start at 250khz which is what SD cards need. They are sensitive to + // SPI bus noise before they are put into SPI mode. + uint8_t baud_value = samd_peripherals_spi_baudrate_to_baud_reg_value(250000); + if (spi_m_sync_set_baudrate(&self->spi_desc, baud_value) != ERR_NONE) { + // spi_m_sync_set_baudrate does not check for validity, just whether the device is + // busy or not + mp_raise_OSError(MP_EIO); + } + + gpio_set_pin_direction(clock->number, GPIO_DIRECTION_OUT); + gpio_set_pin_pull_mode(clock->number, GPIO_PULL_OFF); + gpio_set_pin_function(clock->number, clock_pinmux); + claim_pin(clock); + self->clock_pin = clock->number; + + if (mosi_none) { + self->MOSI_pin = NO_PIN; + } else { + gpio_set_pin_direction(mosi->number, GPIO_DIRECTION_OUT); + gpio_set_pin_pull_mode(mosi->number, GPIO_PULL_OFF); + gpio_set_pin_function(mosi->number, mosi_pinmux); + self->MOSI_pin = mosi->number; + claim_pin(mosi); + } + + if (miso_none) { + self->MISO_pin = NO_PIN; + } else { + gpio_set_pin_direction(miso->number, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(miso->number, GPIO_PULL_OFF); + gpio_set_pin_function(miso->number, miso_pinmux); + self->MISO_pin = miso->number; + claim_pin(miso); + } + + spi_m_sync_enable(&self->spi_desc); +} + +void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { + never_reset_sercom(self->spi_desc.dev.prvt); + + never_reset_pin_number(self->clock_pin); + never_reset_pin_number(self->MOSI_pin); + never_reset_pin_number(self->MISO_pin); +} + +bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { + return self->clock_pin == NO_PIN; +} + +void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { + if (common_hal_busio_spi_deinited(self)) { + return; + } + allow_reset_sercom(self->spi_desc.dev.prvt); + + spi_m_sync_disable(&self->spi_desc); + spi_m_sync_deinit(&self->spi_desc); + reset_pin_number(self->clock_pin); + reset_pin_number(self->MOSI_pin); + reset_pin_number(self->MISO_pin); + self->clock_pin = NO_PIN; +} + +bool common_hal_busio_spi_configure(busio_spi_obj_t *self, + uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { + uint8_t baud_reg_value = samd_peripherals_spi_baudrate_to_baud_reg_value(baudrate); + + void * hw = self->spi_desc.dev.prvt; + // If the settings are already what we want then don't reset them. + if (hri_sercomspi_get_CTRLA_CPHA_bit(hw) == phase && + hri_sercomspi_get_CTRLA_CPOL_bit(hw) == polarity && + hri_sercomspi_read_CTRLB_CHSIZE_bf(hw) == ((uint32_t)bits - 8) && + hri_sercomspi_read_BAUD_BAUD_bf(hw) == baud_reg_value) { + return true; + } + + // Disable, set values (most or all are enable-protected), and re-enable. + spi_m_sync_disable(&self->spi_desc); + hri_sercomspi_wait_for_sync(hw, SERCOM_SPI_SYNCBUSY_MASK); + + hri_sercomspi_write_CTRLA_CPHA_bit(hw, phase); + hri_sercomspi_write_CTRLA_CPOL_bit(hw, polarity); + hri_sercomspi_write_CTRLB_CHSIZE_bf(hw, bits - 8); + hri_sercomspi_write_BAUD_BAUD_bf(hw, baud_reg_value); + hri_sercomspi_wait_for_sync(hw, SERCOM_SPI_SYNCBUSY_MASK); + + spi_m_sync_enable(&self->spi_desc); + hri_sercomspi_wait_for_sync(hw, SERCOM_SPI_SYNCBUSY_MASK); + + return true; +} + +bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { + bool grabbed_lock = false; + CRITICAL_SECTION_ENTER() + if (!self->has_lock) { + grabbed_lock = true; + self->has_lock = true; + } + CRITICAL_SECTION_LEAVE(); + return grabbed_lock; +} + +bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self) { + return self->has_lock; +} + +void common_hal_busio_spi_unlock(busio_spi_obj_t *self) { + self->has_lock = false; +} + +bool common_hal_busio_spi_write(busio_spi_obj_t *self, + const uint8_t *data, size_t len) { + if (len == 0) { + return true; + } + int32_t status; + if (len >= 16) { + status = sercom_dma_write(self->spi_desc.dev.prvt, data, len); + } else { + struct io_descriptor *spi_io; + spi_m_sync_get_io_descriptor(&self->spi_desc, &spi_io); + status = spi_io->write(spi_io, data, len); + } + return status >= 0; // Status is number of chars read or an error code < 0. +} + +bool common_hal_busio_spi_read(busio_spi_obj_t *self, + uint8_t *data, size_t len, uint8_t write_value) { + if (len == 0) { + return true; + } + int32_t status; + if (len >= 16) { + status = sercom_dma_read(self->spi_desc.dev.prvt, data, len, write_value); + } else { + self->spi_desc.dev.dummy_byte = write_value; + + struct io_descriptor *spi_io; + spi_m_sync_get_io_descriptor(&self->spi_desc, &spi_io); + + status = spi_io->read(spi_io, data, len); + } + return status >= 0; // Status is number of chars read or an error code < 0. +} + +bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_out, uint8_t *data_in, size_t len) { + if (len == 0) { + return true; + } + int32_t status; + if (len >= 16) { + status = sercom_dma_transfer(self->spi_desc.dev.prvt, data_out, data_in, len); + } else { + struct spi_xfer xfer; + xfer.txbuf = data_out; + xfer.rxbuf = data_in; + xfer.size = len; + status = spi_m_sync_transfer(&self->spi_desc, &xfer); + } + return status >= 0; // Status is number of chars read or an error code < 0. +} + +uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t* self) { + return samd_peripherals_spi_baud_reg_value_to_baudrate(hri_sercomspi_read_BAUD_reg(self->spi_desc.dev.prvt)); +} + +uint8_t common_hal_busio_spi_get_phase(busio_spi_obj_t* self) { + void * hw = self->spi_desc.dev.prvt; + return hri_sercomspi_get_CTRLA_CPHA_bit(hw); +} + +uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t* self) { + void * hw = self->spi_desc.dev.prvt; + return hri_sercomspi_get_CTRLA_CPOL_bit(hw); +} diff --git a/ports/atmel-samd/common-hal/busio/SPI.h b/ports/atmel-samd/common-hal/busio/SPI.h new file mode 100644 index 00000000000..a1c0e151797 --- /dev/null +++ b/ports/atmel-samd/common-hal/busio/SPI.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_SPI_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_SPI_H + +#include "common-hal/microcontroller/Pin.h" + +#include "hal/include/hal_spi_m_sync.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + struct spi_m_sync_descriptor spi_desc; + bool has_lock; + uint8_t clock_pin; + uint8_t MOSI_pin; + uint8_t MISO_pin; +} busio_spi_obj_t; + +void reset_sercoms(void); +void never_reset_sercom(Sercom* sercom); + + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_SPI_H diff --git a/ports/atmel-samd/common-hal/busio/UART.c b/ports/atmel-samd/common-hal/busio/UART.c new file mode 100644 index 00000000000..2505e894afc --- /dev/null +++ b/ports/atmel-samd/common-hal/busio/UART.c @@ -0,0 +1,394 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 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 "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/busio/UART.h" + +#include "mpconfigport.h" +#include "lib/utils/interrupt_char.h" +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "supervisor/shared/translate.h" + +#include "tick.h" + +#include "hpl_sercom_config.h" +#include "peripheral_clk_config.h" + +#include "hal/include/hal_gpio.h" +#include "hal/include/hal_usart_async.h" +#include "hal/include/hpl_usart_async.h" + +#include "samd/sercom.h" + +// Do-nothing callback needed so that usart_async code will enable rx interrupts. +// See comment below re usart_async_register_callback() +static void usart_async_rxc_callback(const struct usart_async_descriptor *const descr) { + // Nothing needs to be done by us. +} + +void common_hal_busio_uart_construct(busio_uart_obj_t *self, + const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, + uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout, + uint16_t receiver_buffer_size) { + Sercom* sercom = NULL; + uint8_t sercom_index = 255; // Unset index + uint32_t rx_pinmux = 0; + uint8_t rx_pad = 255; // Unset pad + uint32_t tx_pinmux = 0; + uint8_t tx_pad = 255; // Unset pad + + if (bits > 8) { + mp_raise_NotImplementedError(translate("bytes > 8 bits not supported")); + } + + bool have_tx = tx != mp_const_none; + bool have_rx = rx != mp_const_none; + if (!have_tx && !have_rx) { + mp_raise_ValueError(translate("tx and rx cannot both be None")); + } + + self->baudrate = baudrate; + self->character_bits = bits; + self->timeout_ms = timeout * 1000; + + // This assignment is only here because the usart_async routines take a *const argument. + struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc; + + for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) { + Sercom* potential_sercom = NULL; + if (have_tx) { + sercom_index = tx->sercom[i].index; + if (sercom_index >= SERCOM_INST_NUM) { + continue; + } + potential_sercom = sercom_insts[sercom_index]; +#ifdef SAMD21 + if (potential_sercom->USART.CTRLA.bit.ENABLE != 0 || + !(tx->sercom[i].pad == 0 || + tx->sercom[i].pad == 2)) { + continue; + } +#endif +#ifdef SAMD51 + if (potential_sercom->USART.CTRLA.bit.ENABLE != 0 || + !(tx->sercom[i].pad == 0)) { + continue; + } +#endif + tx_pinmux = PINMUX(tx->number, (i == 0) ? MUX_C : MUX_D); + tx_pad = tx->sercom[i].pad; + if (rx == mp_const_none) { + sercom = potential_sercom; + break; + } + } + for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { + if (((!have_tx && rx->sercom[j].index < SERCOM_INST_NUM && + sercom_insts[rx->sercom[j].index]->USART.CTRLA.bit.ENABLE == 0) || + sercom_index == rx->sercom[j].index) && + rx->sercom[j].pad != tx_pad) { + rx_pinmux = PINMUX(rx->number, (j == 0) ? MUX_C : MUX_D); + rx_pad = rx->sercom[j].pad; + sercom = sercom_insts[rx->sercom[j].index]; + sercom_index = rx->sercom[j].index; + break; + } + } + if (sercom != NULL) { + break; + } + } + if (sercom == NULL) { + mp_raise_ValueError(translate("Invalid pins")); + } + if (!have_tx) { + tx_pad = 0; + if (rx_pad == 0) { + tx_pad = 2; + } + } + if (!have_rx) { + rx_pad = (tx_pad + 1) % 4; + } + + // Set up clocks on SERCOM. + samd_peripherals_sercom_clock_init(sercom, sercom_index); + + if (rx && receiver_buffer_size > 0) { + self->buffer_length = receiver_buffer_size; + // Initially allocate the UART's buffer in the long-lived part of the + // heap. UARTs are generally long-lived objects, but the "make long- + // lived" machinery is incapable of moving internal pointers like + // self->buffer, so do it manually. (However, as long as internal + // pointers like this are NOT moved, allocating the buffer + // in the long-lived pool is not strictly necessary) + self->buffer = (uint8_t *) gc_alloc(self->buffer_length * sizeof(uint8_t), false, true); + if (self->buffer == NULL) { + common_hal_busio_uart_deinit(self); + mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer")); + } + } else { + self->buffer_length = 0; + self->buffer = NULL; + } + + if (usart_async_init(usart_desc_p, sercom, self->buffer, self->buffer_length, NULL) != ERR_NONE) { + mp_raise_ValueError(translate("Could not initialize UART")); + } + + // usart_async_init() sets a number of defaults based on a prototypical SERCOM + // which don't necessarily match what we need. After calling it, set the values + // specific to this instantiation of UART. + + // Set pads computed for this SERCOM. + // TXPO: + // 0x0: TX pad 0; no RTS/CTS + // 0x1: TX pad 2; no RTS/CTS + // 0x2: TX pad 0; RTS: pad 2, CTS: pad 3 (not used by us right now) + // So divide by 2 to map pad to value. + // RXPO: + // 0x0: RX pad 0 + // 0x1: RX pad 1 + // 0x2: RX pad 2 + // 0x3: RX pad 3 + + // Doing a group mask and set of the registers saves 60 bytes over setting the bitfields individually. + + sercom->USART.CTRLA.reg &= ~(SERCOM_USART_CTRLA_TXPO_Msk | + SERCOM_USART_CTRLA_RXPO_Msk | + SERCOM_USART_CTRLA_FORM_Msk); + sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_TXPO(tx_pad / 2) | + SERCOM_USART_CTRLA_RXPO(rx_pad) | + (parity == PARITY_NONE ? 0 : SERCOM_USART_CTRLA_FORM(1)); + + // Enable tx and/or rx based on whether the pins were specified. + // CHSIZE is 0 for 8 bits, 5, 6, 7 for 5, 6, 7 bits. 1 for 9 bits, but we don't support that. + sercom->USART.CTRLB.reg &= ~(SERCOM_USART_CTRLB_TXEN | + SERCOM_USART_CTRLB_RXEN | + SERCOM_USART_CTRLB_PMODE | + SERCOM_USART_CTRLB_SBMODE | + SERCOM_USART_CTRLB_CHSIZE_Msk); + sercom->USART.CTRLB.reg |= (have_tx ? SERCOM_USART_CTRLB_TXEN : 0) | + (have_rx ? SERCOM_USART_CTRLB_RXEN : 0) | + (parity == PARITY_ODD ? SERCOM_USART_CTRLB_PMODE : 0) | + (stop > 1 ? SERCOM_USART_CTRLB_SBMODE : 0) | + SERCOM_USART_CTRLB_CHSIZE(bits % 8); + + // Set baud rate + common_hal_busio_uart_set_baudrate(self, baudrate); + + // Turn on rx interrupt handling. The UART async driver has its own set of internal callbacks, + // which are set up by uart_async_init(). These in turn can call user-specified callbacks. + // In fact, the actual interrupts are not enabled unless we set up a user-specified callback. + // This is confusing. It's explained in the Atmel START User Guide -> Implementation Description -> + // Different read function behavior in some asynchronous drivers. As of this writing: + // http://start.atmel.com/static/help/index.html?GUID-79201A5A-226F-4FBB-B0B8-AB0BE0554836 + // Look at the ASFv4 code example for async USART. + usart_async_register_callback(usart_desc_p, USART_ASYNC_RXC_CB, usart_async_rxc_callback); + + + if (have_tx) { + gpio_set_pin_direction(tx->number, GPIO_DIRECTION_OUT); + gpio_set_pin_pull_mode(tx->number, GPIO_PULL_OFF); + gpio_set_pin_function(tx->number, tx_pinmux); + self->tx_pin = tx->number; + claim_pin(tx); + } else { + self->tx_pin = NO_PIN; + } + + if (have_rx) { + gpio_set_pin_direction(rx->number, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(rx->number, GPIO_PULL_OFF); + gpio_set_pin_function(rx->number, rx_pinmux); + self->rx_pin = rx->number; + claim_pin(rx); + } else { + self->rx_pin = NO_PIN; + } + + usart_async_enable(usart_desc_p); +} + +bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { + return self->rx_pin == NO_PIN && self->tx_pin == NO_PIN; +} + +void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { + if (common_hal_busio_uart_deinited(self)) { + return; + } + // This assignment is only here because the usart_async routines take a *const argument. + struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc; + usart_async_disable(usart_desc_p); + usart_async_deinit(usart_desc_p); + reset_pin_number(self->rx_pin); + reset_pin_number(self->tx_pin); + self->rx_pin = NO_PIN; + self->tx_pin = NO_PIN; +} + +// Read characters. +size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { + if (self->rx_pin == NO_PIN) { + mp_raise_ValueError(translate("No RX pin")); + } + + // This assignment is only here because the usart_async routines take a *const argument. + struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc; + + if (len == 0) { + // Nothing to read. + return 0; + } + + struct io_descriptor *io; + usart_async_get_io_descriptor(usart_desc_p, &io); + + size_t total_read = 0; + uint64_t start_ticks = ticks_ms; + + // Busy-wait until timeout or until we've read enough chars. + while (ticks_ms - start_ticks <= self->timeout_ms) { + // Read as many chars as we can right now, up to len. + size_t num_read = io_read(io, data, len); + + // Advance pointer in data buffer, and decrease how many chars left to read. + data += num_read; + len -= num_read; + total_read += num_read; + if (len == 0) { + // Don't need to read any more: data buf is full. + break; + } + if (num_read > 0) { + // Reset the timeout on every character read. + start_ticks = ticks_ms; + } + RUN_BACKGROUND_TASKS; + // Allow user to break out of a timeout with a KeyboardInterrupt. + if (mp_hal_is_interrupted()) { + break; + } + // If we are zero timeout, make sure we don't loop again (in the event + // we read in under 1ms) + if (self->timeout_ms == 0) { + break; + } + } + + if (total_read == 0) { + *errcode = EAGAIN; + return MP_STREAM_ERROR; + } + + return total_read; +} + +// Write characters. +size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { + if (self->tx_pin == NO_PIN) { + mp_raise_ValueError(translate("No TX pin")); + } + + // This assignment is only here because the usart_async routines take a *const argument. + struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc; + + struct io_descriptor *io; + usart_async_get_io_descriptor(usart_desc_p, &io); + + if (io_write(io, data, len) < 0) { + *errcode = MP_EAGAIN; + return MP_STREAM_ERROR; + } + + // Wait until write is complete or timeout. + bool done = false; + uint64_t start_ticks = ticks_ms; + // Busy-wait for timeout. + while (ticks_ms - start_ticks < self->timeout_ms) { + if (usart_async_is_tx_empty(usart_desc_p)) { + done = true; + break; + } + RUN_BACKGROUND_TASKS; + } + + if (!done) { + *errcode = MP_EAGAIN; + return MP_STREAM_ERROR; + } + + // All the characters got written. + return len; +} + +uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) { + return self->baudrate; +} + +void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) { + // This assignment is only here because the usart_async routines take a *const argument. + struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc; + usart_async_set_baud_rate(usart_desc_p, + // Samples and ARITHMETIC vs FRACTIONAL must correspond to USART_SAMPR in + // hpl_sercom_config.h. + _usart_async_calculate_baud_rate(baudrate, // e.g. 9600 baud + PROTOTYPE_SERCOM_USART_ASYNC_CLOCK_FREQUENCY, + 16, // samples + USART_BAUDRATE_ASYNCH_ARITHMETIC, + 0 // fraction - not used for ARITHMETIC + )); + self->baudrate = baudrate; +} + +uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { + // This assignment is only here because the usart_async routines take a *const argument. + struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc; + struct usart_async_status async_status; + usart_async_get_status(usart_desc_p, &async_status); + return async_status.rxcnt; +} + +void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) { + // This assignment is only here because the usart_async routines take a *const argument. + struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc; + usart_async_flush_rx_buffer(usart_desc_p); + +} + +bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { + if (self->tx_pin == NO_PIN) { + return false; + } + // This assignment is only here because the usart_async routines take a *const argument. + const struct _usart_async_device * const usart_device_p = + (struct _usart_async_device * const) &self->usart_desc.device; + return _usart_async_is_byte_sent(usart_device_p); +} diff --git a/ports/atmel-samd/common-hal/busio/UART.h b/ports/atmel-samd/common-hal/busio/UART.h new file mode 100644 index 00000000000..f94df040f8c --- /dev/null +++ b/ports/atmel-samd/common-hal/busio/UART.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_UART_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_UART_H + +#include "common-hal/microcontroller/Pin.h" + +#include "hal/include/hal_usart_async.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + struct usart_async_descriptor usart_desc; + uint8_t rx_pin; + uint8_t tx_pin; + uint8_t character_bits; + bool rx_error; + uint32_t baudrate; + uint32_t timeout_ms; + uint32_t buffer_length; + uint8_t* buffer; +} busio_uart_obj_t; + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_UART_H diff --git a/ports/atmel-samd/common-hal/busio/__init__.c b/ports/atmel-samd/common-hal/busio/__init__.c new file mode 100644 index 00000000000..41761b6743a --- /dev/null +++ b/ports/atmel-samd/common-hal/busio/__init__.c @@ -0,0 +1 @@ +// No busio module functions. diff --git a/ports/atmel-samd/common-hal/digitalio/DigitalInOut.c b/ports/atmel-samd/common-hal/digitalio/DigitalInOut.c new file mode 100644 index 00000000000..e167cbb694c --- /dev/null +++ b/ports/atmel-samd/common-hal/digitalio/DigitalInOut.c @@ -0,0 +1,186 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 +#include + +#include "py/runtime.h" +#include "py/mphal.h" + +#include "hal/include/hal_gpio.h" + +#include "common-hal/microcontroller/Pin.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "supervisor/shared/translate.h" + +digitalinout_result_t common_hal_digitalio_digitalinout_construct( + digitalio_digitalinout_obj_t* self, const mcu_pin_obj_t* pin) { + claim_pin(pin); + self->pin = pin; + self->output = false; + self->open_drain = false; + + // Must set pull after setting direction. + gpio_set_pin_direction(pin->number, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(pin->number, GPIO_PULL_OFF); + return DIGITALINOUT_OK; +} + +void common_hal_digitalio_digitalinout_never_reset( + digitalio_digitalinout_obj_t *self) { + never_reset_pin_number(self->pin->number); +} + +bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t* self) { + return self->pin == mp_const_none; +} + +void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self) { + if (common_hal_digitalio_digitalinout_deinited(self)) { + return; + } + reset_pin_number(self->pin->number); + self->pin = mp_const_none; +} + +void common_hal_digitalio_digitalinout_switch_to_input( + digitalio_digitalinout_obj_t* self, digitalio_pull_t pull) { + self->output = false; + // This also sets direction to input. + common_hal_digitalio_digitalinout_set_pull(self, pull); +} + +void common_hal_digitalio_digitalinout_switch_to_output( + digitalio_digitalinout_obj_t* self, bool value, + digitalio_drive_mode_t drive_mode) { + const uint8_t pin = self->pin->number; + gpio_set_pin_pull_mode(pin, GPIO_PULL_OFF); + // Turn on "strong" pin driving (more current available). See DRVSTR doc in datasheet. + hri_port_set_PINCFG_DRVSTR_bit(PORT, (enum gpio_port)GPIO_PORT(pin), GPIO_PIN(pin)); + + self->output = true; + self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN; + + // Direction is set in set_value. We don't need to do it here. + common_hal_digitalio_digitalinout_set_value(self, value); +} + +digitalio_direction_t common_hal_digitalio_digitalinout_get_direction( + digitalio_digitalinout_obj_t* self) { + return self->output ? DIRECTION_OUTPUT : DIRECTION_INPUT; +} + +void common_hal_digitalio_digitalinout_set_value( + digitalio_digitalinout_obj_t* self, bool value) { + const uint8_t pin = self->pin->number; + const uint8_t port = GPIO_PORT(pin); + const uint32_t pin_mask = 1U << GPIO_PIN(pin); + if (value) { + if (self->open_drain) { + // Assertion: pull is off, so the pin is floating in this case. + // We do open-drain high output (no sinking of current) + // by changing the direction to input with no pulls. + hri_port_clear_DIR_DIR_bf(PORT, port, pin_mask); + } else { + hri_port_set_DIR_DIR_bf(PORT, port, pin_mask); + hri_port_set_OUT_OUT_bf(PORT, port, pin_mask); + } + } else { + hri_port_set_DIR_DIR_bf(PORT, port, pin_mask); + hri_port_clear_OUT_OUT_bf(PORT,port, pin_mask); + } +} + +bool common_hal_digitalio_digitalinout_get_value( + digitalio_digitalinout_obj_t* self) { + const uint8_t pin = self->pin->number; + if (!self->output) { + return gpio_get_pin_level(pin); + } else { + if (self->open_drain && hri_port_get_DIR_reg(PORT, GPIO_PORT(pin), 1U << GPIO_PIN(pin)) == 0) { + return true; + } else { + return hri_port_get_OUT_reg(PORT, GPIO_PORT(pin), 1U << GPIO_PIN(pin)); + } + } +} + +void common_hal_digitalio_digitalinout_set_drive_mode( + digitalio_digitalinout_obj_t* self, + digitalio_drive_mode_t drive_mode) { + bool value = common_hal_digitalio_digitalinout_get_value(self); + self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN; + // True is implemented differently between modes so reset the value to make + // sure it's correct for the new mode. + if (value) { + common_hal_digitalio_digitalinout_set_value(self, value); + } +} + +digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( + digitalio_digitalinout_obj_t* self) { + if (self->open_drain) { + return DRIVE_MODE_OPEN_DRAIN; + } else { + return DRIVE_MODE_PUSH_PULL; + } +} + +void common_hal_digitalio_digitalinout_set_pull( + digitalio_digitalinout_obj_t* self, digitalio_pull_t pull) { + enum gpio_pull_mode asf_pull = GPIO_PULL_OFF; + switch (pull) { + case PULL_UP: + asf_pull = GPIO_PULL_UP; + break; + case PULL_DOWN: + asf_pull = GPIO_PULL_DOWN; + break; + case PULL_NONE: + default: + break; + } + // Must set pull after setting direction. + gpio_set_pin_direction(self->pin->number, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(self->pin->number, asf_pull); +} + +digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( + digitalio_digitalinout_obj_t* self) { + uint32_t pin = self->pin->number; + if (self->output) { + mp_raise_AttributeError(translate("Cannot get pull while in output mode")); + return PULL_NONE; + } else { + if (hri_port_get_PINCFG_PULLEN_bit(PORT, GPIO_PORT(pin), GPIO_PIN(pin)) == 0) { + return PULL_NONE; + } if (hri_port_get_OUT_reg(PORT, GPIO_PORT(pin), 1U << GPIO_PIN(pin)) > 0) { + return PULL_UP; + } else { + return PULL_DOWN; + } + } +} diff --git a/ports/atmel-samd/common-hal/digitalio/DigitalInOut.h b/ports/atmel-samd/common-hal/digitalio/DigitalInOut.h new file mode 100644 index 00000000000..4b443d9bcee --- /dev/null +++ b/ports/atmel-samd/common-hal/digitalio/DigitalInOut.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DIGITALIO_DIGITALINOUT_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DIGITALIO_DIGITALINOUT_H + +#include "common-hal/microcontroller/Pin.h" +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t * pin; + bool output; + bool open_drain; +} digitalio_digitalinout_obj_t; + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DIGITALIO_DIGITALINOUT_H diff --git a/ports/atmel-samd/common-hal/digitalio/__init__.c b/ports/atmel-samd/common-hal/digitalio/__init__.c new file mode 100644 index 00000000000..20fad459593 --- /dev/null +++ b/ports/atmel-samd/common-hal/digitalio/__init__.c @@ -0,0 +1 @@ +// No digitalio module functions. diff --git a/ports/atmel-samd/common-hal/displayio/ParallelBus.c b/ports/atmel-samd/common-hal/displayio/ParallelBus.c new file mode 100644 index 00000000000..2479e3b40e9 --- /dev/null +++ b/ports/atmel-samd/common-hal/displayio/ParallelBus.c @@ -0,0 +1,150 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/ParallelBus.h" + +#include + +#include "common-hal/microcontroller/Pin.h" +#include "py/runtime.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/microcontroller/__init__.h" + +#include "tick.h" + +void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self, + const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select, + const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset) { + + uint8_t data_pin = data0->number; + if (data_pin % 8 != 0) { + mp_raise_ValueError(translate("Data 0 pin must be byte aligned")); + } + for (uint8_t i = 0; i < 8; i++) { + if (!pin_number_is_free(data_pin + i)) { + mp_raise_ValueError_varg(translate("Bus pin %d is already in use"), i); + } + } + PortGroup *const g = &PORT->Group[data0->number / 32]; + g->DIRSET.reg = 0xff << (data_pin % 32); + uint32_t wrconfig = PORT_WRCONFIG_WRPINCFG | PORT_WRCONFIG_DRVSTR; + if (data_pin % 32 > 15) { + wrconfig |= PORT_WRCONFIG_HWSEL | (0xff << ((data_pin % 32) - 16)); + } else { + wrconfig |= 0xff << (data_pin % 32); + } + g->WRCONFIG.reg = wrconfig; + self->bus = ((uint8_t*) &g->OUT.reg) + (data0->number % 32 / 8); + + self->command.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->command, command); + common_hal_digitalio_digitalinout_switch_to_output(&self->command, true, DRIVE_MODE_PUSH_PULL); + + self->chip_select.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); + common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL); + + self->write.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->write, write); + common_hal_digitalio_digitalinout_switch_to_output(&self->write, true, DRIVE_MODE_PUSH_PULL); + + self->read.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->read, read); + common_hal_digitalio_digitalinout_switch_to_output(&self->read, true, DRIVE_MODE_PUSH_PULL); + + self->data0_pin = data_pin; + self->write_group = &PORT->Group[write->number / 32]; + self->write_mask = 1 << (write->number % 32); + + self->reset.base.type = &mp_type_NoneType; + if (reset != NULL) { + self->reset.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->reset, reset); + common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); + never_reset_pin_number(reset->number); + common_hal_displayio_parallelbus_reset(self); + } + + never_reset_pin_number(command->number); + never_reset_pin_number(chip_select->number); + never_reset_pin_number(write->number); + never_reset_pin_number(read->number); + for (uint8_t i = 0; i < 8; i++) { + never_reset_pin_number(data_pin + i); + } +} + +void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self) { + for (uint8_t i = 0; i < 8; i++) { + reset_pin_number(self->data0_pin + i); + } + + reset_pin_number(self->command.pin->number); + reset_pin_number(self->chip_select.pin->number); + reset_pin_number(self->write.pin->number); + reset_pin_number(self->read.pin->number); + reset_pin_number(self->reset.pin->number); +} + +bool common_hal_displayio_parallelbus_reset(mp_obj_t obj) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + if (self->reset.base.type == &mp_type_NoneType) { + return false; + } + + common_hal_digitalio_digitalinout_set_value(&self->reset, false); + common_hal_mcu_delay_us(4); + common_hal_digitalio_digitalinout_set_value(&self->reset, true); + return true; +} + +bool common_hal_displayio_parallelbus_bus_free(mp_obj_t obj) { + return true; +} + +bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); + return true; +} + +void common_hal_displayio_parallelbus_send(mp_obj_t obj, display_byte_type_t byte_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->command, byte_type == DISPLAY_DATA); + uint32_t* clear_write = (uint32_t*) &self->write_group->OUTCLR.reg; + uint32_t* set_write = (uint32_t*) &self->write_group->OUTSET.reg; + uint32_t mask = self->write_mask; + for (uint32_t i = 0; i < data_length; i++) { + *clear_write = mask; + *self->bus = data[i]; + *set_write = mask; + } +} + +void common_hal_displayio_parallelbus_end_transaction(mp_obj_t obj) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); +} diff --git a/ports/atmel-samd/common-hal/displayio/ParallelBus.h b/ports/atmel-samd/common-hal/displayio/ParallelBus.h new file mode 100644 index 00000000000..630bec351b6 --- /dev/null +++ b/ports/atmel-samd/common-hal/displayio/ParallelBus.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_PARALLELBUS_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_PARALLELBUS_H + +#include "common-hal/digitalio/DigitalInOut.h" + +typedef struct { + mp_obj_base_t base; + uint8_t* bus; + digitalio_digitalinout_obj_t command; + digitalio_digitalinout_obj_t chip_select; + digitalio_digitalinout_obj_t reset; + digitalio_digitalinout_obj_t write; + digitalio_digitalinout_obj_t read; + uint8_t data0_pin; + PortGroup* write_group; + uint32_t write_mask; +} displayio_parallelbus_obj_t; + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_PARALLELBUS_H diff --git a/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c b/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c new file mode 100644 index 00000000000..d34049946b0 --- /dev/null +++ b/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c @@ -0,0 +1,550 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Michael Schroeder + * + * 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 + +#include "hal/include/hal_gpio.h" +#include "atmel_start_pins.h" +#include "supervisor/shared/translate.h" + +#include "mpconfigport.h" +#include "py/runtime.h" +#include "timer_handler.h" +#include "background.h" + +#include "samd/clocks.h" +#include "samd/timers.h" +#include "samd/events.h" +#include "samd/pins.h" +#include "samd/external_interrupts.h" + +#include "shared-bindings/frequencyio/FrequencyIn.h" +#include "peripheral_clk_config.h" +#include "hpl_gclk_config.h" + +#include "tick.h" + +#ifdef SAMD21 +#include "hpl/gclk/hpl_gclk_base.h" +#endif + +static frequencyio_frequencyin_obj_t *active_frequencyins[TC_INST_NUM]; +volatile uint8_t reference_tc = 0xff; +#ifdef SAMD51 +static uint8_t dpll_gclk; +#endif + +void frequencyin_emergency_cancel_capture(uint8_t index) { + frequencyio_frequencyin_obj_t* self = active_frequencyins[index]; + + NVIC_DisableIRQ(self->TC_IRQ); + NVIC_ClearPendingIRQ(self->TC_IRQ); + #ifdef SAMD21 + NVIC_DisableIRQ(EIC_IRQn); + NVIC_ClearPendingIRQ(EIC_IRQn); + #endif + #ifdef SAMD51 + NVIC_DisableIRQ(EIC_0_IRQn + self->channel); + NVIC_ClearPendingIRQ(EIC_0_IRQn + self->channel); + #endif + + common_hal_frequencyio_frequencyin_pause(self); // pause any further captures + + NVIC_EnableIRQ(self->TC_IRQ); + #ifdef SAMD21 + NVIC_EnableIRQ(EIC_IRQn); + #endif + #ifdef SAMD51 + NVIC_EnableIRQ(EIC_0_IRQn + self->channel); + #endif + mp_raise_RuntimeError(translate("Frequency captured is above capability. Capture Paused.")); +} + +void frequencyin_interrupt_handler(uint8_t index) { + Tc* ref_tc = tc_insts[reference_tc]; + + if (!ref_tc->COUNT16.INTFLAG.bit.OVF) return; // false trigger + + uint32_t current_us; + uint64_t current_ms; + current_tick(¤t_ms, ¤t_us); + + for (uint8_t i = 0; i <= (TC_INST_NUM - 1); i++) { + if (active_frequencyins[i] != NULL) { + frequencyio_frequencyin_obj_t* self = active_frequencyins[i]; + Tc* tc = tc_insts[self->tc_index]; + + uint32_t mask = 1 << self->channel; + if ((EIC->INTFLAG.reg & mask) == mask) { + // Make sure capture_period has elapsed before we + // record a new event count. + if (current_ms - self->last_ms >= self->capture_period) { + float new_factor = self->last_us + (1000 - current_us); + // ms difference will not need 64 bits. If we use 64 bits, + // double-precision float routines are required, and we don't + // want to include them because they're very large. + self->factor = (uint32_t) (current_ms - self->last_ms) + (new_factor / 1000); + self->last_ms = current_ms; + self->last_us = current_us; + + #ifdef SAMD51 + tc->COUNT16.CTRLBSET.bit.CMD = TC_CTRLBSET_CMD_READSYNC_Val; + while ((tc->COUNT16.SYNCBUSY.bit.COUNT == 1) || + (tc->COUNT16.CTRLBSET.bit.CMD == TC_CTRLBSET_CMD_READSYNC_Val)) { + } + #endif + + uint16_t new_freq = tc->COUNT16.COUNT.reg; + if ((tc->COUNT16.INTFLAG.reg & TC_INTFLAG_OVF) == 1) { + new_freq += 65535; + tc->COUNT16.INTFLAG.reg |= TC_INTFLAG_OVF; + } + self->frequency = new_freq; + + #ifdef SAMD51 + tc->COUNT16.CTRLBSET.bit.CMD = TC_CTRLBSET_CMD_RETRIGGER_Val; + while ((tc->COUNT16.SYNCBUSY.bit.COUNT == 1) || + (tc->COUNT16.CTRLBSET.bit.CMD == TC_CTRLBSET_CMD_RETRIGGER_Val)) { + } + #endif + } + EIC->INTFLAG.reg |= mask; + } + + // Check if we've reached the upper limit of detection + if (!background_tasks_ok() || self->errored_too_fast) { + self->errored_too_fast = true; + frequencyin_emergency_cancel_capture(i); + } + } + } + ref_tc->COUNT16.INTFLAG.reg |= TC_INTFLAG_OVF; +} + +void frequencyin_reference_tc_init() { + if (reference_tc == 0xff) { + return; + } + #ifdef SAMD21 + set_timer_handler(true, reference_tc, TC_HANDLER_FREQUENCYIN); + turn_on_clocks(true, reference_tc, 0); + #endif + // use the DPLL we setup so that the reference_tc and freqin_tc(s) + // are using the same clock frequency. + #ifdef SAMD51 + if (dpll_gclk == 0xff) { + frequencyin_samd51_start_dpll(); + } + set_timer_handler(true, reference_tc, TC_HANDLER_FREQUENCYIN); + turn_on_clocks(true, reference_tc, dpll_gclk); + #endif + + Tc *tc = tc_insts[reference_tc]; + tc_set_enable(tc, false); + tc_reset(tc); + + #ifdef SAMD21 + tc->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 | TC_CTRLA_PRESCALER_DIV1; + tc->COUNT16.INTENSET.bit.OVF = 1; + NVIC_EnableIRQ(TC3_IRQn + reference_tc); + #endif + #ifdef SAMD51 + tc->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 | + TC_CTRLA_PRESCALER_DIV1; + tc->COUNT16.INTENSET.bit.OVF = 1; + NVIC_EnableIRQ(TC0_IRQn + reference_tc); + #endif +} + +bool frequencyin_reference_tc_enabled() { + if (reference_tc == 0xff) { + return false; + } + Tc *tc = tc_insts[reference_tc]; + return tc->COUNT16.CTRLA.bit.ENABLE; +} + +void frequencyin_reference_tc_enable(bool enable) { + if (reference_tc == 0xff) { + return; + } + Tc *tc = tc_insts[reference_tc]; + tc_set_enable(tc, enable); +} + +#ifdef SAMD51 +void frequencyin_samd51_start_dpll() { + if (clock_get_enabled(0, GCLK_SOURCE_DPLL1)) { + return; + } + + uint8_t free_gclk = find_free_gclk(1); + if (free_gclk == 0xff) { + dpll_gclk = 0xff; + return; + } + + GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL1].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(free_gclk); + // TC4-7 can only have a max of 100MHz source + // DPLL1 frequency equation with [X]OSC32K as source: 98.304MHz = 32768(2999 + 1 + 0/32) + // Will also enable the Lock Bypass due to low-frequency sources causing DPLL unlocks + // as outlined in the Errata (1.12.1) + OSCCTRL->Dpll[1].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0) | OSCCTRL_DPLLRATIO_LDR(2999); + if (board_has_crystal()) { // we can use XOSC32K directly as the source + OSC32KCTRL->XOSC32K.bit.EN32K = 1; + OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK(1) | + OSCCTRL_DPLLCTRLB_LBYPASS; + } else { + // can't use OSCULP32K directly; need to setup a GCLK as a reference, + // which must be done in samd/clocks.c to avoid waiting for sync + return; + //OSC32KCTRL->OSCULP32K.bit.EN32K = 1; + //OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK(0); + } + OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE; + + while (!(OSCCTRL->Dpll[1].DPLLSTATUS.bit.LOCK || OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY)) {} + enable_clock_generator(free_gclk, GCLK_GENCTRL_SRC_DPLL1_Val, 1); + dpll_gclk = free_gclk; +} + +void frequencyin_samd51_stop_dpll() { + if (!clock_get_enabled(0, GCLK_SOURCE_DPLL1)) { + return; + } + + disable_clock_generator(dpll_gclk); + + GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL1].reg = 0; + OSCCTRL->Dpll[1].DPLLCTRLA.reg = 0; + OSCCTRL->Dpll[1].DPLLRATIO.reg = 0; + OSCCTRL->Dpll[1].DPLLCTRLB.reg = 0; + + while (OSCCTRL->Dpll[1].DPLLSYNCBUSY.bit.ENABLE) { + } + dpll_gclk = 0xff; +} +#endif + +void common_hal_frequencyio_frequencyin_construct(frequencyio_frequencyin_obj_t* self, const mcu_pin_obj_t* pin, const uint16_t capture_period) { + + if (!pin->has_extint) { + mp_raise_RuntimeError(translate("No hardware support on pin")); + } + if ((capture_period == 0) || (capture_period > 500)) { + mp_raise_ValueError(translate("Invalid capture period. Valid range: 1 - 500")); + } + uint32_t mask = 1 << pin->extint_channel; + if (eic_get_enable() == 1 && + #ifdef SAMD21 + ((EIC->INTENSET.vec.EXTINT & mask) != 0 || (EIC->EVCTRL.vec.EXTINTEO & mask) != 0)) { + #endif + #ifdef SAMD51 + ((EIC->INTENSET.bit.EXTINT & mask) != 0 || (EIC->EVCTRL.bit.EXTINTEO & mask) != 0)) { + #endif + mp_raise_RuntimeError(translate("EXTINT channel already in use")); + } + + uint8_t timer_index = find_free_timer(); + if (timer_index == 0xff) { + mp_raise_RuntimeError(translate("All timers in use")); + } + Tc *tc = tc_insts[timer_index]; + + self->tc_index = timer_index; + self->pin = pin->number; + self->channel = pin->extint_channel; + self->errored_too_fast = false; + self->last_ms = 0; + self->last_us = 1000; + self->capture_period = capture_period; + #ifdef SAMD21 + self->TC_IRQ = TC3_IRQn + timer_index; + #endif + #ifdef SAMD51 + self->TC_IRQ = TC0_IRQn + timer_index; + #endif + + active_frequencyins[timer_index] = self; + + // SAMD21: We use GCLK0 generated from DFLL running at 48mhz + // SAMD51: We use a GCLK generated from DPLL1 running at <100mhz + #ifdef SAMD21 + set_timer_handler(timer_index, 0, TC_HANDLER_NO_INTERRUPT); + turn_on_clocks(true, timer_index, 0); + #endif + #ifdef SAMD51 + frequencyin_samd51_start_dpll(); + if (dpll_gclk == 0xff && !clock_get_enabled(0, GCLK_SOURCE_DPLL1)) { + common_hal_frequencyio_frequencyin_deinit(self); + mp_raise_RuntimeError(translate("No available clocks")); + } + set_timer_handler(timer_index, dpll_gclk, TC_HANDLER_NO_INTERRUPT); + turn_on_clocks(true, timer_index, dpll_gclk); + #endif + + // Ensure EIC is on + if (eic_get_enable() == 0) { + turn_on_external_interrupt_controller(); // enables EIC, so disable it after + } + eic_set_enable(false); + + uint8_t sense_setting = EIC_CONFIG_SENSE0_HIGH_Val; + uint8_t config_index = self->channel / 8; + uint8_t position = (self->channel % 8) * 4; + uint32_t masked_value = EIC->CONFIG[config_index].reg & ~(0xf << position); + EIC->CONFIG[config_index].reg = masked_value | (sense_setting << position); + + #ifdef SAMD21 + masked_value = EIC->EVCTRL.vec.EXTINTEO; + EIC->EVCTRL.vec.EXTINTEO = masked_value | (1 << self->channel); + #endif + #ifdef SAMD51 + masked_value = EIC->EVCTRL.bit.EXTINTEO; + EIC->EVCTRL.bit.EXTINTEO = masked_value | (1 << self->channel); + EIC->ASYNCH.bit.ASYNCH = 1; + #endif + + turn_on_cpu_interrupt(self->channel); + + eic_set_enable(true); + + // Turn on EVSYS + turn_on_event_system(); + uint8_t evsys_channel = find_async_event_channel(); + #ifdef SAMD21 + connect_event_user_to_channel((EVSYS_ID_USER_TC3_EVU + timer_index), evsys_channel); + #endif + #ifdef SAMD51 + connect_event_user_to_channel((EVSYS_ID_USER_TC0_EVU + timer_index), evsys_channel); + #endif + init_async_event_channel(evsys_channel, (EVSYS_ID_GEN_EIC_EXTINT_0 + self->channel)); + self->event_channel = evsys_channel; + + tc_set_enable(tc, false); + tc_reset(tc); + #ifdef SAMD21 + tc->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 | + TC_CTRLA_PRESCALER_DIV1; + tc->COUNT16.EVCTRL.bit.TCEI = 1; + tc->COUNT16.EVCTRL.bit.EVACT = TC_EVCTRL_EVACT_COUNT_Val; + #endif + + #ifdef SAMD51 + tc->COUNT16.EVCTRL.reg = TC_EVCTRL_EVACT(TC_EVCTRL_EVACT_COUNT_Val) | TC_EVCTRL_TCEI; + tc->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 | + TC_CTRLA_PRESCALER_DIV1; + #endif + + NVIC_EnableIRQ(self->TC_IRQ); + + gpio_set_pin_function(pin->number, GPIO_PIN_FUNCTION_A); + + tc_set_enable(tc, true); + + // setup reference TC if not already + if (reference_tc == 0xff) { + reference_tc = find_free_timer(); + if (reference_tc == 0xff) { + common_hal_frequencyio_frequencyin_deinit(self); + mp_raise_RuntimeError(translate("All timers in use")); + } + frequencyin_reference_tc_init(); + } + if (!frequencyin_reference_tc_enabled()) { + frequencyin_reference_tc_enable(true); + } +} + +bool common_hal_frequencyio_frequencyin_deinited(frequencyio_frequencyin_obj_t* self) { + return self->pin == NO_PIN; +} + +void common_hal_frequencyio_frequencyin_deinit(frequencyio_frequencyin_obj_t* self) { + if (common_hal_frequencyio_frequencyin_deinited(self)) { + return; + } + reset_pin_number(self->pin); + + // turn off EIC & EVSYS utilized by this TC + disable_event_channel(self->event_channel); + eic_set_enable(false); + #ifdef SAMD21 + disable_event_user(EVSYS_ID_USER_TC3_EVU + self->tc_index); + uint32_t masked_value = EIC->EVCTRL.vec.EXTINTEO; + EIC->EVCTRL.vec.EXTINTEO = masked_value ^ (1 << self->channel); + #endif + #ifdef SAMD51 + disable_event_user(EVSYS_ID_USER_TC0_EVU + self->tc_index); + uint32_t masked_value = EIC->EVCTRL.bit.EXTINTEO; + EIC->EVCTRL.bit.EXTINTEO = masked_value ^ (1 << self->channel); + NVIC_DisableIRQ(EIC_0_IRQn + self->channel); + NVIC_ClearPendingIRQ(EIC_0_IRQn + self->channel); + #endif + eic_set_enable(true); + // check if any other objects are using the EIC; if not, turn it off + if (EIC->EVCTRL.reg == 0 && EIC->INTENSET.reg == 0) { + eic_reset(); + turn_off_external_interrupt_controller(); + } + + // turn off the TC we were using + Tc *tc = tc_insts[self->tc_index]; + tc_set_enable(tc, false); + tc_reset(tc); + NVIC_DisableIRQ(self->TC_IRQ); + NVIC_ClearPendingIRQ(self->TC_IRQ); + + active_frequencyins[self->tc_index] = NULL; + self->tc_index = 0xff; + self->pin = NO_PIN; + + bool check_active = false; + for (uint8_t i = 0; i <= (TC_INST_NUM - 1); i++) { + if (active_frequencyins[i] != NULL) { + check_active = true; + } + } + if (!check_active) { + frequencyin_reference_tc_enable(false); + reference_tc = 0xff; + #ifdef SAMD51 + frequencyin_samd51_stop_dpll(); + #endif + } +} + +uint32_t common_hal_frequencyio_frequencyin_get_item(frequencyio_frequencyin_obj_t* self) { + NVIC_DisableIRQ(self->TC_IRQ); + #ifdef SAMD21 + NVIC_DisableIRQ(EIC_IRQn); + #endif + #ifdef SAMD51 + NVIC_DisableIRQ(EIC_0_IRQn + self->channel); + #endif + + // adjust for actual capture period vs base `capture_period` + float frequency_adjustment = 0.0; + if (self->factor > self->capture_period) { + float time_each_event = self->factor / self->frequency; // get the time for each event during actual period + float capture_diff = self->factor - self->capture_period; // get the difference of actual and base periods + // we only need to adjust if the capture_diff can contain 1 or more events + // if so, we add how many events could have occured during the diff time + if (time_each_event > capture_diff) { + frequency_adjustment = capture_diff / time_each_event; + } + } + + float value = 1000 / (self->capture_period / (self->frequency + frequency_adjustment)); + + NVIC_ClearPendingIRQ(self->TC_IRQ); + NVIC_EnableIRQ(self->TC_IRQ); + #ifdef SAMD21 + NVIC_ClearPendingIRQ(EIC_IRQn); + NVIC_EnableIRQ(EIC_IRQn); + #endif + #ifdef SAMD51 + NVIC_ClearPendingIRQ(EIC_0_IRQn + self->channel); + NVIC_EnableIRQ(EIC_0_IRQn + self->channel); + #endif + + return value; +} + +void common_hal_frequencyio_frequencyin_pause(frequencyio_frequencyin_obj_t* self) { + Tc *tc = tc_insts[self->tc_index]; + if (!tc->COUNT16.EVCTRL.bit.TCEI) { + return; + } + tc->COUNT16.EVCTRL.bit.TCEI = 0; + + #ifdef SAMD21 + uint32_t masked_value = EIC->EVCTRL.vec.EXTINTEO; + EIC->EVCTRL.vec.EXTINTEO = masked_value ^ (1 << self->channel); + #endif + #ifdef SAMD51 + uint32_t masked_value = EIC->EVCTRL.bit.EXTINTEO; + EIC->EVCTRL.bit.EXTINTEO = masked_value ^ (1 << self->channel); + #endif + return; +} + +void common_hal_frequencyio_frequencyin_resume(frequencyio_frequencyin_obj_t* self) { + Tc *tc = tc_insts[self->tc_index]; + if (tc->COUNT16.EVCTRL.bit.TCEI) { + return; + } + tc->COUNT16.EVCTRL.bit.TCEI = 1; + + #ifdef SAMD21 + uint32_t masked_value = EIC->EVCTRL.vec.EXTINTEO; + EIC->EVCTRL.vec.EXTINTEO = masked_value | (1 << self->channel); + #endif + #ifdef SAMD51 + uint32_t masked_value = EIC->EVCTRL.bit.EXTINTEO; + EIC->EVCTRL.bit.EXTINTEO = masked_value | (1 << self->channel); + #endif + self->errored_too_fast = false; + return; +} + +void common_hal_frequencyio_frequencyin_clear(frequencyio_frequencyin_obj_t* self) { + NVIC_DisableIRQ(self->TC_IRQ); + #ifdef SAMD21 + NVIC_DisableIRQ(EIC_IRQn); + #endif + #ifdef SAMD51 + NVIC_DisableIRQ(EIC_0_IRQn + self->channel); + #endif + + self->frequency = 0; + + NVIC_ClearPendingIRQ(self->TC_IRQ); + NVIC_EnableIRQ(self->TC_IRQ); + #ifdef SAMD21 + NVIC_ClearPendingIRQ(EIC_IRQn); + NVIC_EnableIRQ(EIC_IRQn); + #endif + #ifdef SAMD51 + NVIC_ClearPendingIRQ(EIC_0_IRQn + self->channel); + NVIC_EnableIRQ(EIC_0_IRQn + self->channel); + #endif + return; +} + +uint16_t common_hal_frequencyio_frequencyin_get_capture_period(frequencyio_frequencyin_obj_t *self) { + return self->capture_period; +} + +void common_hal_frequencyio_frequencyin_set_capture_period(frequencyio_frequencyin_obj_t *self, uint16_t capture_period) { + if ((capture_period == 0) || (capture_period > 500)) { + mp_raise_ValueError(translate("Invalid capture period. Valid range: 1 - 500")); + } + + self->capture_period = capture_period; + + common_hal_frequencyio_frequencyin_clear(self); +} diff --git a/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.h b/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.h new file mode 100644 index 00000000000..abd63cc86d4 --- /dev/null +++ b/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.h @@ -0,0 +1,60 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Michael Schroeder + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_FREQUENCYIO_FREQUENCYIN_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_FREQUENCYIO_FREQUENCYIN_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint8_t tc_index; + uint8_t pin; + uint8_t channel; + uint8_t event_channel; + uint32_t frequency; + volatile uint64_t last_ms; + volatile uint32_t last_us; + float factor; + uint32_t capture_period; + uint8_t TC_IRQ; + volatile bool errored_too_fast; +} frequencyio_frequencyin_obj_t; + +void frequencyin_interrupt_handler(uint8_t index); +void frequencyin_emergency_cancel_capture(uint8_t index); +void frequencyin_reference_tc_init(void); +void frequencyin_reference_tc_enable(bool enable); +bool frequencyin_reference_tc_enabled(void); +#ifdef SAMD51 +void frequencyin_samd51_start_dpll(void); +void frequencyin_samd51_stop_dpll(void); +#endif + + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_FREQUENCYIO_FREQUENCYIN_H diff --git a/ports/atmel-samd/common-hal/frequencyio/__init__.c b/ports/atmel-samd/common-hal/frequencyio/__init__.c new file mode 100644 index 00000000000..487814bd076 --- /dev/null +++ b/ports/atmel-samd/common-hal/frequencyio/__init__.c @@ -0,0 +1 @@ +// No ferquencyio module functions. diff --git a/ports/atmel-samd/common-hal/i2cslave/I2CSlave.c b/ports/atmel-samd/common-hal/i2cslave/I2CSlave.c new file mode 100644 index 00000000000..79c1449e2f6 --- /dev/null +++ b/ports/atmel-samd/common-hal/i2cslave/I2CSlave.c @@ -0,0 +1,252 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * 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 "shared-bindings/i2cslave/I2CSlave.h" +#include "common-hal/busio/I2C.h" + +#include "lib/utils/interrupt_char.h" +#include "py/mperrno.h" +#include "py/mphal.h" +#include "py/runtime.h" + +#include "hal/include/hal_gpio.h" +#include "peripherals/samd/sercom.h" + +void common_hal_i2cslave_i2c_slave_construct(i2cslave_i2c_slave_obj_t *self, + const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, + uint8_t *addresses, unsigned int num_addresses, bool smbus) { + uint8_t sercom_index; + uint32_t sda_pinmux, scl_pinmux; + Sercom *sercom = samd_i2c_get_sercom(scl, sda, &sercom_index, &sda_pinmux, &scl_pinmux); + if (sercom == NULL) { + mp_raise_ValueError(translate("Invalid pins")); + } + self->sercom = sercom; + + gpio_set_pin_function(sda->number, GPIO_PIN_FUNCTION_OFF); + gpio_set_pin_function(scl->number, GPIO_PIN_FUNCTION_OFF); + gpio_set_pin_function(sda->number, sda_pinmux); + gpio_set_pin_function(scl->number, scl_pinmux); + + self->sda_pin = sda->number; + self->scl_pin = scl->number; + claim_pin(sda); + claim_pin(scl); + + samd_peripherals_sercom_clock_init(sercom, sercom_index); + + sercom->I2CS.CTRLA.bit.SWRST = 1; + while (sercom->I2CS.CTRLA.bit.SWRST || sercom->I2CS.SYNCBUSY.bit.SWRST) {} + + sercom->I2CS.CTRLB.bit.AACKEN = 0; // Automatic acknowledge is disabled. + + if (num_addresses == 1) { + sercom->I2CS.CTRLB.bit.AMODE = 0x0; // MASK + sercom->I2CS.ADDR.bit.ADDR = addresses[0]; + sercom->I2CS.ADDR.bit.ADDRMASK = 0x00; // Match exact address + } else if (num_addresses == 2) { + sercom->I2CS.CTRLB.bit.AMODE = 0x1; // 2_ADDRS + sercom->I2CS.ADDR.bit.ADDR = addresses[0]; + sercom->I2CS.ADDR.bit.ADDRMASK = addresses[1]; + } else { + uint32_t combined = 0; // all addresses OR'ed + uint32_t differ = 0; // bits that differ between addresses + for (unsigned int i = 0; i < num_addresses; i++) { + combined |= addresses[i]; + differ |= addresses[0] ^ addresses[i]; + } + sercom->I2CS.CTRLB.bit.AMODE = 0x0; // MASK + sercom->I2CS.ADDR.bit.ADDR = combined; + sercom->I2CS.ADDR.bit.ADDRMASK = differ; + } + self->addresses = addresses; + self->num_addresses = num_addresses; + + if (smbus) { + sercom->I2CS.CTRLA.bit.LOWTOUTEN = 1; // Errata 12003 + sercom->I2CS.CTRLA.bit.SEXTTOEN = 1; // Slave SCL Low Extend/Cumulative Time-Out 25ms + } + sercom->I2CS.CTRLA.bit.SCLSM = 0; // Clock stretch before ack + sercom->I2CS.CTRLA.bit.MODE = 0x04; // Slave mode + sercom->I2CS.CTRLA.bit.ENABLE = 1; +} + +bool common_hal_i2cslave_i2c_slave_deinited(i2cslave_i2c_slave_obj_t *self) { + return self->sda_pin == NO_PIN; +} + +void common_hal_i2cslave_i2c_slave_deinit(i2cslave_i2c_slave_obj_t *self) { + if (common_hal_i2cslave_i2c_slave_deinited(self)) { + return; + } + + self->sercom->I2CS.CTRLA.bit.ENABLE = 0; + + reset_pin_number(self->sda_pin); + reset_pin_number(self->scl_pin); + self->sda_pin = NO_PIN; + self->scl_pin = NO_PIN; +} + +static int i2c_slave_check_error(i2cslave_i2c_slave_obj_t *self, bool raise) { + if (!self->sercom->I2CS.INTFLAG.bit.ERROR) { + return 0; + } + + int err = MP_EIO; + + if (self->sercom->I2CS.STATUS.bit.LOWTOUT || self->sercom->I2CS.STATUS.bit.SEXTTOUT) { + err = MP_ETIMEDOUT; + } + + self->sercom->I2CS.INTFLAG.reg = SERCOM_I2CS_INTFLAG_ERROR; // Clear flag + + if (raise) { + mp_raise_OSError(err); + } + return -err; +} + +int common_hal_i2cslave_i2c_slave_is_addressed(i2cslave_i2c_slave_obj_t *self, uint8_t *address, bool *is_read, bool *is_restart) +{ + int err = i2c_slave_check_error(self, false); + if (err) { + return err; + } + + if (!self->sercom->I2CS.INTFLAG.bit.AMATCH) { + return 0; + } + + self->writing = false; + + *address = self->sercom->I2CS.DATA.reg >> 1; + *is_read = self->sercom->I2CS.STATUS.bit.DIR; + *is_restart = self->sercom->I2CS.STATUS.bit.SR; + + for (unsigned int i = 0; i < self->num_addresses; i++) { + if (*address == self->addresses[i]) { + common_hal_i2cslave_i2c_slave_ack(self, true); + return 1; + } + } + + // This should clear AMATCH, but it doesn't... + common_hal_i2cslave_i2c_slave_ack(self, false); + return 0; +} + +int common_hal_i2cslave_i2c_slave_read_byte(i2cslave_i2c_slave_obj_t *self, uint8_t *data) { + for (int t = 0; t < 100 && !self->sercom->I2CS.INTFLAG.reg; t++) { + mp_hal_delay_us(10); + } + + i2c_slave_check_error(self, true); + + if (!self->sercom->I2CS.INTFLAG.bit.DRDY || + self->sercom->I2CS.INTFLAG.bit.PREC || + self->sercom->I2CS.INTFLAG.bit.AMATCH) { + return 0; + } + + *data = self->sercom->I2CS.DATA.reg; + return 1; +} + +int common_hal_i2cslave_i2c_slave_write_byte(i2cslave_i2c_slave_obj_t *self, uint8_t data) { + for (int t = 0; !self->sercom->I2CS.INTFLAG.reg && t < 100; t++) { + mp_hal_delay_us(10); + } + + i2c_slave_check_error(self, true); + + if (self->sercom->I2CS.INTFLAG.bit.PREC) { + return 0; + } + + // RXNACK can carry over from the previous transfer + if (self->writing && self->sercom->I2CS.STATUS.bit.RXNACK) { + return 0; + } + + self->writing = true; + + if (!self->sercom->I2CS.INTFLAG.bit.DRDY) { + return 0; + } + + self->sercom->I2CS.DATA.bit.DATA = data; // Send data + + return 1; +} + +void common_hal_i2cslave_i2c_slave_ack(i2cslave_i2c_slave_obj_t *self, bool ack) { + self->sercom->I2CS.CTRLB.bit.ACKACT = !ack; + self->sercom->I2CS.CTRLB.bit.CMD = 0x03; +} + +void common_hal_i2cslave_i2c_slave_close(i2cslave_i2c_slave_obj_t *self) { + for (int t = 0; !self->sercom->I2CS.INTFLAG.reg && t < 100; t++) { + mp_hal_delay_us(10); + } + + if (self->sercom->I2CS.INTFLAG.bit.AMATCH || !self->sercom->I2CS.STATUS.bit.CLKHOLD) { + return; + } + + if (!self->sercom->I2CS.STATUS.bit.DIR) { + common_hal_i2cslave_i2c_slave_ack(self, false); + } else { + int i = 0; + while (self->sercom->I2CS.INTFLAG.reg == SERCOM_I2CS_INTFLAG_DRDY) { + if (mp_hal_is_interrupted()) { + return; + } + + self->sercom->I2CS.DATA.bit.DATA = 0xff; // Send dummy byte + + // Wait for a result (if any). + // test_byte_word.py::TestWord::test_write_seq leaves us with no INTFLAGs set in some of the tests + for (int t = 0; !self->sercom->I2CS.INTFLAG.reg && t < 100; t++) { + mp_hal_delay_us(10); + } + + if (++i > 1000) { // Avoid getting stuck "forever" + mp_raise_OSError(MP_EIO); + } + } + } + + if (self->sercom->I2CS.INTFLAG.bit.AMATCH) { + return; + } + + if (self->sercom->I2CS.STATUS.bit.CLKHOLD) { + // Unable to release the clock. + // The slave might have to be re-initialized to get unstuck. + mp_raise_OSError(MP_EIO); + } +} diff --git a/ports/atmel-samd/common-hal/i2cslave/I2CSlave.h b/ports/atmel-samd/common-hal/i2cslave/I2CSlave.h new file mode 100644 index 00000000000..bf4f877bd46 --- /dev/null +++ b/ports/atmel-samd/common-hal/i2cslave/I2CSlave.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_SLAVE_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_SLAVE_H + +#include "common-hal/microcontroller/Pin.h" +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + + uint8_t *addresses; + unsigned int num_addresses; + + Sercom *sercom; + uint8_t scl_pin; + uint8_t sda_pin; + bool writing; +} i2cslave_i2c_slave_obj_t; + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_SLAVE_H diff --git a/ports/atmel-samd/common-hal/i2cslave/__init__.c b/ports/atmel-samd/common-hal/i2cslave/__init__.c new file mode 100644 index 00000000000..f289bbc0e43 --- /dev/null +++ b/ports/atmel-samd/common-hal/i2cslave/__init__.c @@ -0,0 +1 @@ +// No i2cslave module functions. diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c new file mode 100644 index 00000000000..6f3cbc75986 --- /dev/null +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c @@ -0,0 +1,234 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/microcontroller/Pin.h" + +#include "atmel_start_pins.h" +#include "hal/include/hal_gpio.h" + +#include "samd/pins.h" +#include "supervisor/shared/rgb_led_status.h" + +#ifdef MICROPY_HW_NEOPIXEL +bool neopixel_in_use; +#endif +#ifdef MICROPY_HW_APA102_MOSI +bool apa102_sck_in_use; +bool apa102_mosi_in_use; +#endif +#ifdef SPEAKER_ENABLE_PIN +bool speaker_enable_in_use; +#endif + +#define PORT_COUNT (PORT_BITS / 32 + 1) + +#ifdef SAMD51 +#define SWD_MUX GPIO_PIN_FUNCTION_H +#endif +#ifdef SAMD21 +#define SWD_MUX GPIO_PIN_FUNCTION_G +#endif + +STATIC uint32_t never_reset_pins[PORT_COUNT]; + +void reset_all_pins(void) { + uint32_t pin_mask[PORT_COUNT] = PORT_OUT_IMPLEMENTED; + + // Do not full reset USB lines. + pin_mask[0] &= ~(PORT_PA24 | PORT_PA25); + + // Do not reset SWD when a debugger is present. + if (DSU->STATUSB.bit.DBGPRES == 1) { + pin_mask[0] &= ~(PORT_PA30 | PORT_PA31); + } + + for (uint32_t i = 0; i < PORT_COUNT; i++) { + pin_mask[i] &= ~never_reset_pins[i]; + } + + gpio_set_port_direction(GPIO_PORTA, pin_mask[0] & ~MICROPY_PORT_A, GPIO_DIRECTION_OFF); + gpio_set_port_direction(GPIO_PORTB, pin_mask[1] & ~MICROPY_PORT_B, GPIO_DIRECTION_OFF); + #if PORT_BITS > 64 + gpio_set_port_direction(GPIO_PORTC, pin_mask[2] & ~MICROPY_PORT_C, GPIO_DIRECTION_OFF); + #endif + #if PORT_BITS > 96 + gpio_set_port_direction(GPIO_PORTD, pin_mask[3] & ~MICROPY_PORT_D, GPIO_DIRECTION_OFF); + #endif + + // Configure SWD. SWDIO will be automatically switched on PA31 when a signal is input on + // SWCLK. + #ifdef SAMD51 + gpio_set_pin_function(PIN_PA30, MUX_PA30H_CM4_SWCLK); + #endif + #ifdef SAMD21 + gpio_set_pin_function(PIN_PA30, GPIO_PIN_FUNCTION_G); + gpio_set_pin_function(PIN_PA31, GPIO_PIN_FUNCTION_G); + #endif + + #ifdef MICROPY_HW_NEOPIXEL + neopixel_in_use = false; + #endif + #ifdef MICROPY_HW_APA102_MOSI + apa102_sck_in_use = false; + apa102_mosi_in_use = false; + #endif + + // After configuring SWD because it may be shared. + #ifdef SPEAKER_ENABLE_PIN + speaker_enable_in_use = false; + gpio_set_pin_function(SPEAKER_ENABLE_PIN->number, GPIO_PIN_FUNCTION_OFF); + gpio_set_pin_direction(SPEAKER_ENABLE_PIN->number, GPIO_DIRECTION_OUT); + gpio_set_pin_level(SPEAKER_ENABLE_PIN->number, false); + #endif +} + +void never_reset_pin_number(uint8_t pin_number) { + never_reset_pins[GPIO_PORT(pin_number)] |= 1 << GPIO_PIN(pin_number); +} + +void reset_pin_number(uint8_t pin_number) { + never_reset_pins[GPIO_PORT(pin_number)] &= ~(1 << GPIO_PIN(pin_number)); + + if (pin_number >= PORT_BITS) { + return; + } + + #ifdef MICROPY_HW_NEOPIXEL + if (pin_number == MICROPY_HW_NEOPIXEL->number) { + neopixel_in_use = false; + rgb_led_status_init(); + return; + } + #endif + #ifdef MICROPY_HW_APA102_MOSI + if (pin_number == MICROPY_HW_APA102_MOSI->number || + pin_number == MICROPY_HW_APA102_SCK->number) { + apa102_mosi_in_use = apa102_mosi_in_use && pin_number != MICROPY_HW_APA102_MOSI->number; + apa102_sck_in_use = apa102_sck_in_use && pin_number != MICROPY_HW_APA102_SCK->number; + if (!apa102_sck_in_use && !apa102_mosi_in_use) { + rgb_led_status_init(); + } + return; + } + #endif + + if (pin_number == PIN_PA30 + #ifdef SAMD51 + ) { + #endif + #ifdef SAMD21 + || pin_number == PIN_PA31) { + #endif + gpio_set_pin_function(pin_number, SWD_MUX); + } else { + gpio_set_pin_direction(pin_number, GPIO_DIRECTION_OFF); + gpio_set_pin_function(pin_number, GPIO_PIN_FUNCTION_OFF); + } + + #ifdef SPEAKER_ENABLE_PIN + if (pin_number == SPEAKER_ENABLE_PIN->number) { + speaker_enable_in_use = false; + gpio_set_pin_function(pin_number, GPIO_PIN_FUNCTION_OFF); + gpio_set_pin_direction(SPEAKER_ENABLE_PIN->number, GPIO_DIRECTION_OUT); + gpio_set_pin_level(SPEAKER_ENABLE_PIN->number, false); + } + #endif +} + +void claim_pin(const mcu_pin_obj_t* pin) { + #ifdef MICROPY_HW_NEOPIXEL + if (pin == MICROPY_HW_NEOPIXEL) { + neopixel_in_use = true; + } + #endif + #ifdef MICROPY_HW_APA102_MOSI + if (pin == MICROPY_HW_APA102_MOSI) { + apa102_mosi_in_use = true; + } + if (pin == MICROPY_HW_APA102_SCK) { + apa102_sck_in_use = true; + } + #endif + + #ifdef SPEAKER_ENABLE_PIN + if (pin == SPEAKER_ENABLE_PIN) { + speaker_enable_in_use = true; + } + #endif +} + +bool pin_number_is_free(uint8_t pin_number) { + PortGroup *const port = &PORT->Group[(enum gpio_port)GPIO_PORT(pin_number)]; + uint8_t pin_index = GPIO_PIN(pin_number); + volatile PORT_PINCFG_Type *state = &port->PINCFG[pin_index]; + volatile PORT_PMUX_Type *pmux = &port->PMUX[pin_index / 2]; + + if (pin_number == PIN_PA30 || pin_number == PIN_PA31) { + if (DSU->STATUSB.bit.DBGPRES == 1) { + return false; + } + if (pin_number == PIN_PA30 + #ifdef SAMD51 + ) { + #endif + #ifdef SAMD21 + || pin_number == PIN_PA31) { + #endif) { + return state->bit.PMUXEN == 1 && ((pmux->reg >> (4 * pin_index % 2)) & 0xf) == SWD_MUX; + } + } + + return state->bit.PMUXEN == 0 && state->bit.INEN == 0 && + state->bit.PULLEN == 0 && (port->DIR.reg & (1 << pin_index)) == 0; +} + +bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) { + #ifdef MICROPY_HW_NEOPIXEL + if (pin == MICROPY_HW_NEOPIXEL) { + // Special case for Metro M0 where the NeoPixel is also SWCLK + if (MICROPY_HW_NEOPIXEL == &pin_PA30 && DSU->STATUSB.bit.DBGPRES == 1) { + return false; + } + return !neopixel_in_use; + } + #endif + #ifdef MICROPY_HW_APA102_MOSI + if (pin == MICROPY_HW_APA102_MOSI) { + return !apa102_mosi_in_use; + } + if (pin == MICROPY_HW_APA102_SCK) { + return !apa102_sck_in_use; + } + #endif + + #ifdef SPEAKER_ENABLE_PIN + if (pin == SPEAKER_ENABLE_PIN) { + return !speaker_enable_in_use; + } + #endif + + return pin_number_is_free(pin->number); +} diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.h b/ports/atmel-samd/common-hal/microcontroller/Pin.h new file mode 100644 index 00000000000..14887207aa1 --- /dev/null +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.h @@ -0,0 +1,50 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_MICROCONTROLLER_PIN_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_MICROCONTROLLER_PIN_H + +#include + +#include "peripherals/samd/pins.h" + +#ifdef MICROPY_HW_NEOPIXEL +extern bool neopixel_in_use; +#endif +#ifdef MICROPY_HW_APA102_MOSI +extern bool apa102_sck_in_use; +extern bool apa102_mosi_in_use; +#endif + +void reset_all_pins(void); +// reset_pin_number takes the pin number instead of the pointer so that objects don't +// need to store a full pointer. +void reset_pin_number(uint8_t pin_number); +void never_reset_pin_number(uint8_t pin_number); +void claim_pin(const mcu_pin_obj_t* pin); +bool pin_number_is_free(uint8_t pin_number); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_MICROCONTROLLER_PIN_H diff --git a/ports/atmel-samd/common-hal/microcontroller/Processor.c b/ports/atmel-samd/common-hal/microcontroller/Processor.c new file mode 100644 index 00000000000..e85a7bc4598 --- /dev/null +++ b/ports/atmel-samd/common-hal/microcontroller/Processor.c @@ -0,0 +1,302 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert for Adafruit Industries + * + * 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. + */ + +/* + * Includes code from ASF sample code adc_temp.h and adc_temp.c, + * and so includes this license: + * + * Copyright (C) 2015 Atmel Corporation. All rights reserved. + * + * License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "common-hal/microcontroller/Processor.h" + +#include "samd/adc.h" + +#include "peripheral_clk_config.h" + +#define ADC_TEMP_SAMPLE_LENGTH 4 +#define INT1V_VALUE_FLOAT 1.0 +#define INT1V_DIVIDER_1000 1000.0 +#define ADC_12BIT_FULL_SCALE_VALUE_FLOAT 4095.0 + + +// Decimal to fraction conversion. (adapted from ASF sample). +STATIC float convert_dec_to_frac(uint8_t val) { + float float_val = (float)val; + if (val < 10) { + return (float_val/10.0); + } else if (val < 100) { + return (float_val/100.0); + } else { + return (float_val/1000.0); + } +} + +// Extract the production calibration data information from NVM (adapted from ASF sample), +// then calculate the temperature +#ifdef SAMD21 +STATIC float calculate_temperature(uint16_t raw_value) { + volatile uint32_t val1; /* Temperature Log Row Content first 32 bits */ + volatile uint32_t val2; /* Temperature Log Row Content another 32 bits */ + uint8_t room_temp_val_int; /* Integer part of room temperature in °C */ + uint8_t room_temp_val_dec; /* Decimal part of room temperature in °C */ + uint8_t hot_temp_val_int; /* Integer part of hot temperature in °C */ + uint8_t hot_temp_val_dec; /* Decimal part of hot temperature in °C */ + int8_t room_int1v_val; /* internal 1V reference drift at room temperature */ + int8_t hot_int1v_val; /* internal 1V reference drift at hot temperature*/ + + float tempR; // Production Room temperature + float tempH; // Production Hot temperature + float INT1VR; // Room temp 2's complement of the internal 1V reference value + float INT1VH; // Hot temp 2's complement of the internal 1V reference value + uint16_t ADCR; // Production Room temperature ADC value + uint16_t ADCH; // Production Hot temperature ADC value + float VADCR; // Room temperature ADC voltage + float VADCH; // Hot temperature ADC voltage + + uint32_t *temp_log_row_ptr = (uint32_t *)NVMCTRL_TEMP_LOG; + + val1 = *temp_log_row_ptr; + temp_log_row_ptr++; + val2 = *temp_log_row_ptr; + + room_temp_val_int = (uint8_t)((val1 & FUSES_ROOM_TEMP_VAL_INT_Msk) >> FUSES_ROOM_TEMP_VAL_INT_Pos); + room_temp_val_dec = (uint8_t)((val1 & FUSES_ROOM_TEMP_VAL_DEC_Msk) >> FUSES_ROOM_TEMP_VAL_DEC_Pos); + + hot_temp_val_int = (uint8_t)((val1 & FUSES_HOT_TEMP_VAL_INT_Msk) >> FUSES_HOT_TEMP_VAL_INT_Pos); + hot_temp_val_dec = (uint8_t)((val1 & FUSES_HOT_TEMP_VAL_DEC_Msk) >> FUSES_HOT_TEMP_VAL_DEC_Pos); + + room_int1v_val = (int8_t)((val1 & FUSES_ROOM_INT1V_VAL_Msk) >> FUSES_ROOM_INT1V_VAL_Pos); + hot_int1v_val = (int8_t)((val2 & FUSES_HOT_INT1V_VAL_Msk) >> FUSES_HOT_INT1V_VAL_Pos); + + ADCR = (uint16_t)((val2 & FUSES_ROOM_ADC_VAL_Msk) >> FUSES_ROOM_ADC_VAL_Pos); + ADCH = (uint16_t)((val2 & FUSES_HOT_ADC_VAL_Msk) >> FUSES_HOT_ADC_VAL_Pos); + + tempR = room_temp_val_int + convert_dec_to_frac(room_temp_val_dec); + tempH = hot_temp_val_int + convert_dec_to_frac(hot_temp_val_dec); + + INT1VR = 1 - ((float)room_int1v_val/INT1V_DIVIDER_1000); + INT1VH = 1 - ((float)hot_int1v_val/INT1V_DIVIDER_1000); + + VADCR = ((float)ADCR * INT1VR)/ADC_12BIT_FULL_SCALE_VALUE_FLOAT; + VADCH = ((float)ADCH * INT1VH)/ADC_12BIT_FULL_SCALE_VALUE_FLOAT; + + float VADC; /* Voltage calculation using ADC result for Coarse Temp calculation */ + float VADCM; /* Voltage calculation using ADC result for Fine Temp calculation. */ + float INT1VM; /* Voltage calculation for reality INT1V value during the ADC conversion */ + + VADC = ((float)raw_value * INT1V_VALUE_FLOAT)/ADC_12BIT_FULL_SCALE_VALUE_FLOAT; + + // Hopefully compiler will remove common subepxressions here. + + // calculate fine temperature using Equation1 and Equation + // 1b as mentioned in data sheet section "Temperature Sensor Characteristics" + // of Electrical Characteristics. (adapted from ASF sample code). + // Coarse Temp Calculation by assume INT1V=1V for this ADC conversion + float coarse_temp = tempR + (((tempH - tempR)/(VADCH - VADCR)) * (VADC - VADCR)); + + // Calculation to find the real INT1V value during the ADC conversion + INT1VM = INT1VR + (((INT1VH - INT1VR) * (coarse_temp - tempR))/(tempH - tempR)); + + VADCM = ((float)raw_value * INT1VM)/ADC_12BIT_FULL_SCALE_VALUE_FLOAT; + + // Fine Temp Calculation by replace INT1V=1V by INT1V = INT1Vm for ADC conversion + float fine_temp = tempR + (((tempH - tempR)/(VADCH - VADCR)) * (VADCM - VADCR)); + + return fine_temp; +} +#endif // SAMD21 + +#ifdef SAMD51 +STATIC float calculate_temperature(uint16_t TP, uint16_t TC) { + uint32_t TLI = (*(uint32_t *)FUSES_ROOM_TEMP_VAL_INT_ADDR & FUSES_ROOM_TEMP_VAL_INT_Msk) >> FUSES_ROOM_TEMP_VAL_INT_Pos; + uint32_t TLD = (*(uint32_t *)FUSES_ROOM_TEMP_VAL_DEC_ADDR & FUSES_ROOM_TEMP_VAL_DEC_Msk) >> FUSES_ROOM_TEMP_VAL_DEC_Pos; + float TL = TLI + convert_dec_to_frac(TLD); + + uint32_t THI = (*(uint32_t *)FUSES_HOT_TEMP_VAL_INT_ADDR & FUSES_HOT_TEMP_VAL_INT_Msk) >> FUSES_HOT_TEMP_VAL_INT_Pos; + uint32_t THD = (*(uint32_t *)FUSES_HOT_TEMP_VAL_DEC_ADDR & FUSES_HOT_TEMP_VAL_DEC_Msk) >> FUSES_HOT_TEMP_VAL_DEC_Pos; + float TH = THI + convert_dec_to_frac(THD); + + uint16_t VPL = (*(uint32_t *)FUSES_ROOM_ADC_VAL_PTAT_ADDR & FUSES_ROOM_ADC_VAL_PTAT_Msk) >> FUSES_ROOM_ADC_VAL_PTAT_Pos; + uint16_t VPH = (*(uint32_t *)FUSES_HOT_ADC_VAL_PTAT_ADDR & FUSES_HOT_ADC_VAL_PTAT_Msk) >> FUSES_HOT_ADC_VAL_PTAT_Pos; + + uint16_t VCL = (*(uint32_t *)FUSES_ROOM_ADC_VAL_CTAT_ADDR & FUSES_ROOM_ADC_VAL_CTAT_Msk) >> FUSES_ROOM_ADC_VAL_CTAT_Pos; + uint16_t VCH = (*(uint32_t *)FUSES_HOT_ADC_VAL_CTAT_ADDR & FUSES_HOT_ADC_VAL_CTAT_Msk) >> FUSES_HOT_ADC_VAL_CTAT_Pos; + + // From SAMD51 datasheet: section 45.6.3.1 (page 1327). + return (TL*VPH*TC - VPL*TH*TC - TL*VCH*TP + TH*VCL*TP) / (VCL*TP - VCH*TP - VPL*TC + VPH*TC); +} +#endif // SAMD51 + +float common_hal_mcu_processor_get_temperature(void) { + struct adc_sync_descriptor adc; + + static Adc* adc_insts[] = ADC_INSTS; + samd_peripherals_adc_setup(&adc, adc_insts[0]); + +#ifdef SAMD21 + // The parameters chosen here are from the temperature example in: + // http://www.atmel.com/images/Atmel-42645-ADC-Configurations-with-Examples_ApplicationNote_AT11481.pdf + // That note also recommends in general: + // "Discard the first conversion result whenever there is a change + // in ADC configuration like voltage reference / ADC channel change." + + adc_sync_set_resolution(&adc, ADC_CTRLB_RESSEL_12BIT_Val); + adc_sync_set_reference(&adc, ADC_REFCTRL_REFSEL_INT1V_Val); + // Channel passed in adc_sync_enable_channel is actually ignored (!). + adc_sync_enable_channel(&adc, ADC_INPUTCTRL_MUXPOS_TEMP_Val); + adc_sync_set_inputs(&adc, + ADC_INPUTCTRL_MUXPOS_TEMP_Val, // pos_input + ADC_INPUTCTRL_MUXNEG_GND_Val, // neg_input + ADC_INPUTCTRL_MUXPOS_TEMP_Val); // channel channel (this arg is ignored (!)) + + adc_sync_set_resolution(&adc, ADC_CTRLB_RESSEL_12BIT_Val); + + hri_adc_write_CTRLB_PRESCALER_bf(adc.device.hw, ADC_CTRLB_PRESCALER_DIV32_Val); + hri_adc_write_SAMPCTRL_SAMPLEN_bf(adc.device.hw, ADC_TEMP_SAMPLE_LENGTH); + + hri_sysctrl_set_VREF_TSEN_bit(SYSCTRL); + + // Oversample and decimate. A higher samplenum produces a more stable result. + hri_adc_write_AVGCTRL_SAMPLENUM_bf(adc.device.hw, ADC_AVGCTRL_SAMPLENUM_4_Val); + hri_adc_write_AVGCTRL_ADJRES_bf(adc.device.hw, 2); + + volatile uint16_t value; + + // Read twice and discard first result, as recommended in section 14 of + // http://www.atmel.com/images/Atmel-42645-ADC-Configurations-with-Examples_ApplicationNote_AT11481.pdf + // "Discard the first conversion result whenever there is a change in ADC configuration + // like voltage reference / ADC channel change" + // Empirical observation shows the first reading is quite different than subsequent ones. + + // The channel listed in adc_sync_read_channel is actually ignored(!). + // Must be set as above with adc_sync_set_inputs. + adc_sync_read_channel(&adc, ADC_INPUTCTRL_MUXPOS_TEMP_Val, ((uint8_t*) &value), 2); + adc_sync_read_channel(&adc, ADC_INPUTCTRL_MUXPOS_TEMP_Val, ((uint8_t*) &value), 2); + + adc_sync_deinit(&adc); + return calculate_temperature(value); +#endif // SAMD21 + +#ifdef SAMD51 + adc_sync_set_resolution(&adc, ADC_CTRLB_RESSEL_12BIT_Val); + // Reference voltage choice is a guess. It's not specified in the datasheet that I can see. + // INTVCC1 seems to read a little high. + // INTREF doesn't work: ADC hangs BUSY. + adc_sync_set_reference(&adc, ADC_REFCTRL_REFSEL_INTVCC0_Val); + + // If ONDEMAND=1, we don't need to use the VREF.TSSEL bit to choose PTAT and CTAT. + hri_supc_set_VREF_ONDEMAND_bit(SUPC); + hri_supc_set_VREF_TSEN_bit(SUPC); + + // Channel passed in adc_sync_enable_channel is actually ignored (!). + adc_sync_enable_channel(&adc, ADC_INPUTCTRL_MUXPOS_PTAT_Val); + adc_sync_set_inputs(&adc, + ADC_INPUTCTRL_MUXPOS_PTAT_Val, // pos_input + ADC_INPUTCTRL_MUXNEG_GND_Val, // neg_input + ADC_INPUTCTRL_MUXPOS_PTAT_Val); // channel (this arg is ignored (!)) + + // Read both temperature sensors. + volatile uint16_t ptat; + volatile uint16_t ctat; + + // The channel listed in adc_sync_read_channel is actually ignored(!). + // Must be set as above with adc_sync_set_inputs. + // Read twice for stability (necessary?) + adc_sync_read_channel(&adc, ADC_INPUTCTRL_MUXPOS_PTAT_Val, ((uint8_t*) &ptat), 2); + adc_sync_read_channel(&adc, ADC_INPUTCTRL_MUXPOS_PTAT_Val, ((uint8_t*) &ptat), 2); + + adc_sync_set_inputs(&adc, + ADC_INPUTCTRL_MUXPOS_CTAT_Val, // pos_input + ADC_INPUTCTRL_MUXNEG_GND_Val, // neg_input + ADC_INPUTCTRL_MUXPOS_CTAT_Val); // channel (this arg is ignored (!)) + + // Channel passed in adc_sync_enable_channel is actually ignored (!). + adc_sync_enable_channel(&adc, ADC_INPUTCTRL_MUXPOS_CTAT_Val); + // The channel listed in adc_sync_read_channel is actually ignored(!). + // Must be set as above with adc_sync_set_inputs. + // Read twice for stability (necessary?) + adc_sync_read_channel(&adc, ADC_INPUTCTRL_MUXPOS_CTAT_Val, ((uint8_t*) &ctat), 2); + adc_sync_read_channel(&adc, ADC_INPUTCTRL_MUXPOS_CTAT_Val, ((uint8_t*) &ctat), 2); + hri_supc_set_VREF_ONDEMAND_bit(SUPC); + + adc_sync_deinit(&adc); + return calculate_temperature(ptat, ctat); +#endif // SAMD51 +} + + +uint32_t common_hal_mcu_processor_get_frequency(void) { + // TODO(tannewt): Determine this dynamically. + return CONF_CPU_FREQUENCY; +} + +void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { + #ifdef SAMD21 + uint32_t* id_addresses[4] = {(uint32_t *) 0x0080A00C, (uint32_t *) 0x0080A040, + (uint32_t *) 0x0080A044, (uint32_t *) 0x0080A048}; + #endif + #ifdef SAMD51 + uint32_t* id_addresses[4] = {(uint32_t *) 0x008061FC, (uint32_t *) 0x00806010, + (uint32_t *) 0x00806014, (uint32_t *) 0x00806018}; + #endif + + for (int i=0; i<4; i++) { + for (int k=0; k<4; k++) { + raw_id[4 * i + k] = (*(id_addresses[i]) >> k * 8) & 0xff; + } + } +} diff --git a/ports/atmel-samd/common-hal/microcontroller/Processor.h b/ports/atmel-samd/common-hal/microcontroller/Processor.h new file mode 100644 index 00000000000..1e1d201eb75 --- /dev/null +++ b/ports/atmel-samd/common-hal/microcontroller/Processor.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H + +#define COMMON_HAL_MCU_PROCESSOR_UID_LENGTH 16 + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + // Stores no state currently. +} mcu_processor_obj_t; + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H diff --git a/ports/atmel-samd/common-hal/microcontroller/__init__.c b/ports/atmel-samd/common-hal/microcontroller/__init__.c new file mode 100644 index 00000000000..cb0751acefc --- /dev/null +++ b/ports/atmel-samd/common-hal/microcontroller/__init__.c @@ -0,0 +1,396 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "py/mphal.h" +#include "py/obj.h" +#include "hal/include/hal_atomic.h" +#include "py/runtime.h" + +#include "reset.h" + +#include "shared-bindings/nvm/ByteArray.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/Processor.h" +#include "supervisor/shared/safe_mode.h" +#include "supervisor/shared/translate.h" + +void common_hal_mcu_delay_us(uint32_t delay) { + mp_hal_delay_us(delay); +} + +volatile uint32_t nesting_count = 0; +void common_hal_mcu_disable_interrupts(void) { + __disable_irq(); + __DMB(); + nesting_count++; +} + +void common_hal_mcu_enable_interrupts(void) { + if (nesting_count == 0) { + // This is very very bad because it means there was mismatched disable/enables so we + // "HardFault". + HardFault_Handler(); + } + nesting_count--; + if (nesting_count > 0) { + return; + } + __DMB(); + __enable_irq(); +} + +void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { + if (runmode == RUNMODE_BOOTLOADER) { + if (!bootloader_available()) { + mp_raise_ValueError(translate("Cannot reset into bootloader because no bootloader is present.")); + } + // Pretend to be the first of the two reset presses needed to enter the + // bootloader. That way one reset will end in the bootloader. + _bootloader_dbl_tap = DBL_TAP_MAGIC; + } else { + // Set up the default. + _bootloader_dbl_tap = DBL_TAP_MAGIC_QUICK_BOOT; + } + if (runmode == RUNMODE_SAFE_MODE) { + safe_mode_on_next_reset(PROGRAMMATIC_SAFE_MODE); + } +} + +void common_hal_mcu_reset(void) { + reset(); +} + +// The singleton microcontroller.Processor object, bound to microcontroller.cpu +// It currently only has properties, and no state. +const mcu_processor_obj_t common_hal_mcu_processor_obj = { + .base = { + .type = &mcu_processor_type, + }, +}; + +// NVM is only available on Express boards for now. +#if CIRCUITPY_INTERNAL_NVM_SIZE > 0 +// The singleton nvm.ByteArray object. +const nvm_bytearray_obj_t common_hal_mcu_nvm_obj = { + .base = { + .type = &nvm_bytearray_type, + }, + .len = CIRCUITPY_INTERNAL_NVM_SIZE, + .start_address = (uint8_t*) (FLASH_SIZE - CIRCUITPY_INTERNAL_NVM_SIZE) +}; +#endif + +// This maps MCU pin names to pin objects. +STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = { +#if defined(PIN_PA00) && !defined(IGNORE_PIN_PA00) + { MP_ROM_QSTR(MP_QSTR_PA00), MP_ROM_PTR(&pin_PA00) }, +#endif +#if defined(PIN_PA01) && !defined(IGNORE_PIN_PA01) + { MP_ROM_QSTR(MP_QSTR_PA01), MP_ROM_PTR(&pin_PA01) }, +#endif +#if defined(PIN_PA02) && !defined(IGNORE_PIN_PA02) + { MP_ROM_QSTR(MP_QSTR_PA02), MP_ROM_PTR(&pin_PA02) }, +#endif +#if defined(PIN_PA03) && !defined(IGNORE_PIN_PA03) + { MP_ROM_QSTR(MP_QSTR_PA03), MP_ROM_PTR(&pin_PA03) }, +#endif +#if defined(PIN_PA04) && !defined(IGNORE_PIN_PA04) + { MP_ROM_QSTR(MP_QSTR_PA04), MP_ROM_PTR(&pin_PA04) }, +#endif +#if defined(PIN_PA05) && !defined(IGNORE_PIN_PA05) + { MP_ROM_QSTR(MP_QSTR_PA05), MP_ROM_PTR(&pin_PA05) }, +#endif +#if defined(PIN_PA06) && !defined(IGNORE_PIN_PA06) + { MP_ROM_QSTR(MP_QSTR_PA06), MP_ROM_PTR(&pin_PA06) }, +#endif +#if defined(PIN_PA07) && !defined(IGNORE_PIN_PA07) + { MP_ROM_QSTR(MP_QSTR_PA07), MP_ROM_PTR(&pin_PA07) }, +#endif +#if defined(PIN_PA08) && !defined(IGNORE_PIN_PA08) + { MP_ROM_QSTR(MP_QSTR_PA08), MP_ROM_PTR(&pin_PA08) }, +#endif +#if defined(PIN_PA09) && !defined(IGNORE_PIN_PA09) + { MP_ROM_QSTR(MP_QSTR_PA09), MP_ROM_PTR(&pin_PA09) }, +#endif +#if defined(PIN_PA10) && !defined(IGNORE_PIN_PA10) + { MP_ROM_QSTR(MP_QSTR_PA10), MP_ROM_PTR(&pin_PA10) }, +#endif +#if defined(PIN_PA11) && !defined(IGNORE_PIN_PA11) + { MP_ROM_QSTR(MP_QSTR_PA11), MP_ROM_PTR(&pin_PA11) }, +#endif +#if defined(PIN_PA12) && !defined(IGNORE_PIN_PA12) + { MP_ROM_QSTR(MP_QSTR_PA12), MP_ROM_PTR(&pin_PA12) }, +#endif +#if defined(PIN_PA13) && !defined(IGNORE_PIN_PA13) + { MP_ROM_QSTR(MP_QSTR_PA13), MP_ROM_PTR(&pin_PA13) }, +#endif +#if defined(PIN_PA14) && !defined(IGNORE_PIN_PA14) + { MP_ROM_QSTR(MP_QSTR_PA14), MP_ROM_PTR(&pin_PA14) }, +#endif +#if defined(PIN_PA15) && !defined(IGNORE_PIN_PA15) + { MP_ROM_QSTR(MP_QSTR_PA15), MP_ROM_PTR(&pin_PA15) }, +#endif +#if defined(PIN_PA16) && !defined(IGNORE_PIN_PA16) + { MP_ROM_QSTR(MP_QSTR_PA16), MP_ROM_PTR(&pin_PA16) }, +#endif +#if defined(PIN_PA17) && !defined(IGNORE_PIN_PA17) + { MP_ROM_QSTR(MP_QSTR_PA17), MP_ROM_PTR(&pin_PA17) }, +#endif +#if defined(PIN_PA18) && !defined(IGNORE_PIN_PA18) + { MP_ROM_QSTR(MP_QSTR_PA18), MP_ROM_PTR(&pin_PA18) }, +#endif +#if defined(PIN_PA19) && !defined(IGNORE_PIN_PA19) + { MP_ROM_QSTR(MP_QSTR_PA19), MP_ROM_PTR(&pin_PA19) }, +#endif +#if defined(PIN_PA20) && !defined(IGNORE_PIN_PA20) + { MP_ROM_QSTR(MP_QSTR_PA20), MP_ROM_PTR(&pin_PA20) }, +#endif +#if defined(PIN_PA21) && !defined(IGNORE_PIN_PA21) + { MP_ROM_QSTR(MP_QSTR_PA21), MP_ROM_PTR(&pin_PA21) }, +#endif +#if defined(PIN_PA22) && !defined(IGNORE_PIN_PA22) + { MP_ROM_QSTR(MP_QSTR_PA22), MP_ROM_PTR(&pin_PA22) }, +#endif +#if defined(PIN_PA23) && !defined(IGNORE_PIN_PA23) + { MP_ROM_QSTR(MP_QSTR_PA23), MP_ROM_PTR(&pin_PA23) }, +#endif +#if defined(PIN_PA24) && !defined(IGNORE_PIN_PA24) + { MP_ROM_QSTR(MP_QSTR_PA24), MP_ROM_PTR(&pin_PA24) }, +#endif +#if defined(PIN_PA25) && !defined(IGNORE_PIN_PA25) + { MP_ROM_QSTR(MP_QSTR_PA25), MP_ROM_PTR(&pin_PA25) }, +#endif +#if defined(PIN_PA27) && !defined(IGNORE_PIN_PA27) + { MP_ROM_QSTR(MP_QSTR_PA27), MP_ROM_PTR(&pin_PA27) }, +#endif +#if defined(PIN_PA28) && !defined(IGNORE_PIN_PA28) + { MP_ROM_QSTR(MP_QSTR_PA28), MP_ROM_PTR(&pin_PA28) }, +#endif +#if defined(PIN_PA30) && !defined(IGNORE_PIN_PA30) + { MP_ROM_QSTR(MP_QSTR_PA30), MP_ROM_PTR(&pin_PA30) }, +#endif +#if defined(PIN_PA31) && !defined(IGNORE_PIN_PA31) + { MP_ROM_QSTR(MP_QSTR_PA31), MP_ROM_PTR(&pin_PA31) }, +#endif + +#if defined(PIN_PB00) && !defined(IGNORE_PIN_PB00) + { MP_ROM_QSTR(MP_QSTR_PB00), MP_ROM_PTR(&pin_PB00) }, +#endif +#if defined(PIN_PB01) && !defined(IGNORE_PIN_PB01) + { MP_ROM_QSTR(MP_QSTR_PB01), MP_ROM_PTR(&pin_PB01) }, +#endif +#if defined(PIN_PB02) && !defined(IGNORE_PIN_PB02) + { MP_ROM_QSTR(MP_QSTR_PB02), MP_ROM_PTR(&pin_PB02) }, +#endif +#if defined(PIN_PB03) && !defined(IGNORE_PIN_PB03) + { MP_ROM_QSTR(MP_QSTR_PB03), MP_ROM_PTR(&pin_PB03) }, +#endif +#if defined(PIN_PB04) && !defined(IGNORE_PIN_PB04) + { MP_ROM_QSTR(MP_QSTR_PB04), MP_ROM_PTR(&pin_PB04) }, +#endif +#if defined(PIN_PB05) && !defined(IGNORE_PIN_PB05) + { MP_ROM_QSTR(MP_QSTR_PB05), MP_ROM_PTR(&pin_PB05) }, +#endif +#if defined(PIN_PB06) && !defined(IGNORE_PIN_PB06) + { MP_ROM_QSTR(MP_QSTR_PB06), MP_ROM_PTR(&pin_PB06) }, +#endif +#if defined(PIN_PB07) && !defined(IGNORE_PIN_PB07) + { MP_ROM_QSTR(MP_QSTR_PB07), MP_ROM_PTR(&pin_PB07) }, +#endif +#if defined(PIN_PB08) && !defined(IGNORE_PIN_PB08) + { MP_ROM_QSTR(MP_QSTR_PB08), MP_ROM_PTR(&pin_PB08) }, +#endif +#if defined(PIN_PB09) && !defined(IGNORE_PIN_PB09) + { MP_ROM_QSTR(MP_QSTR_PB09), MP_ROM_PTR(&pin_PB09) }, +#endif +#if defined(PIN_PB10) && !defined(IGNORE_PIN_PB10) + { MP_ROM_QSTR(MP_QSTR_PB10), MP_ROM_PTR(&pin_PB10) }, +#endif +#if defined(PIN_PB11) && !defined(IGNORE_PIN_PB11) + { MP_ROM_QSTR(MP_QSTR_PB11), MP_ROM_PTR(&pin_PB11) }, +#endif +#if defined(PIN_PB12) && !defined(IGNORE_PIN_PB12) + { MP_ROM_QSTR(MP_QSTR_PB12), MP_ROM_PTR(&pin_PB12) }, +#endif +#if defined(PIN_PB13) && !defined(IGNORE_PIN_PB13) + { MP_ROM_QSTR(MP_QSTR_PB13), MP_ROM_PTR(&pin_PB13) }, +#endif +#if defined(PIN_PB14) && !defined(IGNORE_PIN_PB14) + { MP_ROM_QSTR(MP_QSTR_PB14), MP_ROM_PTR(&pin_PB14) }, +#endif +#if defined(PIN_PB15) && !defined(IGNORE_PIN_PB15) + { MP_ROM_QSTR(MP_QSTR_PB15), MP_ROM_PTR(&pin_PB15) }, +#endif +#if defined(PIN_PB16) && !defined(IGNORE_PIN_PB16) + { MP_ROM_QSTR(MP_QSTR_PB16), MP_ROM_PTR(&pin_PB16) }, +#endif +#if defined(PIN_PB17) && !defined(IGNORE_PIN_PB17) + { MP_ROM_QSTR(MP_QSTR_PB17), MP_ROM_PTR(&pin_PB17) }, +#endif +#if defined(PIN_PB18) && !defined(IGNORE_PIN_PB18) + { MP_ROM_QSTR(MP_QSTR_PB18), MP_ROM_PTR(&pin_PB18) }, +#endif +#if defined(PIN_PB19) && !defined(IGNORE_PIN_PB19) + { MP_ROM_QSTR(MP_QSTR_PB19), MP_ROM_PTR(&pin_PB19) }, +#endif +#if defined(PIN_PB20) && !defined(IGNORE_PIN_PB20) + { MP_ROM_QSTR(MP_QSTR_PB20), MP_ROM_PTR(&pin_PB20) }, +#endif +#if defined(PIN_PB21) && !defined(IGNORE_PIN_PB21) + { MP_ROM_QSTR(MP_QSTR_PB21), MP_ROM_PTR(&pin_PB21) }, +#endif +#if defined(PIN_PB22) && !defined(IGNORE_PIN_PB22) + { MP_ROM_QSTR(MP_QSTR_PB22), MP_ROM_PTR(&pin_PB22) }, +#endif +#if defined(PIN_PB23) && !defined(IGNORE_PIN_PB23) + { MP_ROM_QSTR(MP_QSTR_PB23), MP_ROM_PTR(&pin_PB23) }, +#endif +#if defined(PIN_PB30) && !defined(IGNORE_PIN_PB30) + { MP_ROM_QSTR(MP_QSTR_PB30), MP_ROM_PTR(&pin_PB30) }, +#endif +#if defined(PIN_PB31) && !defined(IGNORE_PIN_PB31) + { MP_ROM_QSTR(MP_QSTR_PB31), MP_ROM_PTR(&pin_PB31) }, +#endif + +// These are SAMD51 specific so we assume we want them in RAM +#if defined(PIN_PC00) + { MP_ROM_QSTR(MP_QSTR_PC00), MP_ROM_PTR(&pin_PC00) }, +#endif +#if defined(PIN_PC01) + { MP_ROM_QSTR(MP_QSTR_PC01), MP_ROM_PTR(&pin_PC01) }, +#endif +#if defined(PIN_PC02) + { MP_ROM_QSTR(MP_QSTR_PC02), MP_ROM_PTR(&pin_PC02) }, +#endif +#if defined(PIN_PC03) + { MP_ROM_QSTR(MP_QSTR_PC03), MP_ROM_PTR(&pin_PC03) }, +#endif +#if defined(PIN_PC04) + { MP_ROM_QSTR(MP_QSTR_PC04), MP_ROM_PTR(&pin_PC04) }, +#endif +#if defined(PIN_PC05) + { MP_ROM_QSTR(MP_QSTR_PC05), MP_ROM_PTR(&pin_PC05) }, +#endif +#if defined(PIN_PC06) + { MP_ROM_QSTR(MP_QSTR_PC06), MP_ROM_PTR(&pin_PC06) }, +#endif +#if defined(PIN_PC07) + { MP_ROM_QSTR(MP_QSTR_PC07), MP_ROM_PTR(&pin_PC07) }, +#endif +#if defined(PIN_PC10) + { MP_ROM_QSTR(MP_QSTR_PC10), MP_ROM_PTR(&pin_PC10) }, +#endif +#if defined(PIN_PC11) + { MP_ROM_QSTR(MP_QSTR_PC11), MP_ROM_PTR(&pin_PC11) }, +#endif +#if defined(PIN_PC12) + { MP_ROM_QSTR(MP_QSTR_PC12), MP_ROM_PTR(&pin_PC12) }, +#endif +#if defined(PIN_PC13) + { MP_ROM_QSTR(MP_QSTR_PC13), MP_ROM_PTR(&pin_PC13) }, +#endif +#if defined(PIN_PC14) + { MP_ROM_QSTR(MP_QSTR_PC14), MP_ROM_PTR(&pin_PC14) }, +#endif +#if defined(PIN_PC15) + { MP_ROM_QSTR(MP_QSTR_PC15), MP_ROM_PTR(&pin_PC15) }, +#endif +#if defined(PIN_PC16) + { MP_ROM_QSTR(MP_QSTR_PC16), MP_ROM_PTR(&pin_PC16) }, +#endif +#if defined(PIN_PC17) + { MP_ROM_QSTR(MP_QSTR_PC17), MP_ROM_PTR(&pin_PC17) }, +#endif +#if defined(PIN_PC18) + { MP_ROM_QSTR(MP_QSTR_PC18), MP_ROM_PTR(&pin_PC18) }, +#endif +#if defined(PIN_PC19) + { MP_ROM_QSTR(MP_QSTR_PC19), MP_ROM_PTR(&pin_PC19) }, +#endif +#if defined(PIN_PC20) + { MP_ROM_QSTR(MP_QSTR_PC20), MP_ROM_PTR(&pin_PC20) }, +#endif +#if defined(PIN_PC21) + { MP_ROM_QSTR(MP_QSTR_PC21), MP_ROM_PTR(&pin_PC21) }, +#endif +#if defined(PIN_PC22) + { MP_ROM_QSTR(MP_QSTR_PC22), MP_ROM_PTR(&pin_PC22) }, +#endif +#if defined(PIN_PC23) + { MP_ROM_QSTR(MP_QSTR_PC23), MP_ROM_PTR(&pin_PC23) }, +#endif +#if defined(PIN_PC24) + { MP_ROM_QSTR(MP_QSTR_PC24), MP_ROM_PTR(&pin_PC24) }, +#endif +#if defined(PIN_PC25) + { MP_ROM_QSTR(MP_QSTR_PC25), MP_ROM_PTR(&pin_PC25) }, +#endif +#if defined(PIN_PC26) + { MP_ROM_QSTR(MP_QSTR_PC26), MP_ROM_PTR(&pin_PC26) }, +#endif +#if defined(PIN_PC27) + { MP_ROM_QSTR(MP_QSTR_PC27), MP_ROM_PTR(&pin_PC27) }, +#endif +#if defined(PIN_PC28) + { MP_ROM_QSTR(MP_QSTR_PC28), MP_ROM_PTR(&pin_PC28) }, +#endif +#if defined(PIN_PC30) + { MP_ROM_QSTR(MP_QSTR_PC30), MP_ROM_PTR(&pin_PC30) }, +#endif +#if defined(PIN_PC31) + { MP_ROM_QSTR(MP_QSTR_PC31), MP_ROM_PTR(&pin_PC31) }, +#endif + +#if defined(PIN_PD00) + { MP_ROM_QSTR(MP_QSTR_PD00), MP_ROM_PTR(&pin_PD00) }, +#endif +#if defined(PIN_PD01) + { MP_ROM_QSTR(MP_QSTR_PD01), MP_ROM_PTR(&pin_PD01) }, +#endif +#if defined(PIN_PD08) + { MP_ROM_QSTR(MP_QSTR_PD08), MP_ROM_PTR(&pin_PD08) }, +#endif +#if defined(PIN_PD09) + { MP_ROM_QSTR(MP_QSTR_PD09), MP_ROM_PTR(&pin_PD09) }, +#endif +#if defined(PIN_PD10) + { MP_ROM_QSTR(MP_QSTR_PD10), MP_ROM_PTR(&pin_PD10) }, +#endif +#if defined(PIN_PD11) + { MP_ROM_QSTR(MP_QSTR_PD11), MP_ROM_PTR(&pin_PD11) }, +#endif +#if defined(PIN_PD12) + { MP_ROM_QSTR(MP_QSTR_PD12), MP_ROM_PTR(&pin_PD12) }, +#endif +#if defined(PIN_PD20) + { MP_ROM_QSTR(MP_QSTR_PD20), MP_ROM_PTR(&pin_PD20) }, +#endif +#if defined(PIN_PD21) + { MP_ROM_QSTR(MP_QSTR_PD21), MP_ROM_PTR(&pin_PD21) }, +#endif +}; +MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_global_dict_table); diff --git a/ports/atmel-samd/common-hal/neopixel_write/__init__.c b/ports/atmel-samd/common-hal/neopixel_write/__init__.c new file mode 100644 index 00000000000..57e963c918d --- /dev/null +++ b/ports/atmel-samd/common-hal/neopixel_write/__init__.c @@ -0,0 +1,192 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "hpl_gpio.h" + +#include "py/mphal.h" + +#include "shared-bindings/neopixel_write/__init__.h" + +#include "tick.h" + +#ifdef SAMD51 +#include "hri/hri_cmcc_d51.h" +#include "hri/hri_nvmctrl_d51.h" + +// This magical macro makes sure the delay isn't optimized out and is the +// minimal three instructions. +#define delay_cycles(cycles) \ +{ \ + uint32_t t; \ + asm volatile ( \ + "movs %[t], %[c]\n\t" \ + "loop%=:\n\t" \ + "subs %[t], #1\n\t" \ + "bne.n loop%=" : [t] "=r"(t) : [c] "I" (cycles)); \ + } +#endif + +// Ensure this code is compiled with -Os. Any other optimization level may change the timing of it +// and break neopixels. +#pragma GCC push_options +#pragma GCC optimize ("Os") + +uint64_t next_start_tick_ms = 0; +uint32_t next_start_tick_us = 1000; + +void common_hal_neopixel_write(const digitalio_digitalinout_obj_t* digitalinout, uint8_t *pixels, uint32_t numBytes) { + // This is adapted directly from the Adafruit NeoPixel library SAMD21G18A code: + // https://github.com/adafruit/Adafruit_NeoPixel/blob/master/Adafruit_NeoPixel.cpp + uint8_t *ptr, *end, p, bitMask; + uint32_t pinMask; + PortGroup* port; + + // This must be called while interrupts are on in case we're waiting for a + // future ms tick. + wait_until(next_start_tick_ms, next_start_tick_us); + + // Turn off interrupts of any kind during timing-sensitive code. + mp_hal_disable_all_interrupts(); + + + #ifdef SAMD21 + // Make sure the NVM cache is consistently timed. + NVMCTRL->CTRLB.bit.READMODE = NVMCTRL_CTRLB_READMODE_DETERMINISTIC_Val; + #endif + + #ifdef SAMD51 + // When this routine is positioned at certain addresses, the timing logic + // below can be too fast by about 2.5x. This is some kind of (un)fortunate code + // positiong with respect to a cache line. + // Theoretically we should turn on off the CMCC caches and the + // NVM caches to ensure consistent timing. Testing shows the the NVMCTRL + // cache disabling seems to make the difference. But turn both off to make sure. + // It's difficult to test because additions to the code before the timing loop + // below change instruction placement. Testing was done by adding cache changes + // below the loop (so only the first time through is wrong). + // + // Turn off instruction, data, and NVM caches to force consistent timing. + // Invalidate existing cache entries. + hri_cmcc_set_CFG_reg(CMCC, CMCC_CFG_DCDIS | CMCC_CFG_ICDIS); + hri_cmcc_write_MAINT0_reg(CMCC, CMCC_MAINT0_INVALL); + hri_nvmctrl_set_CTRLA_CACHEDIS0_bit(NVMCTRL); + hri_nvmctrl_set_CTRLA_CACHEDIS1_bit(NVMCTRL); + #endif + + uint32_t pin = digitalinout->pin->number; + port = &PORT->Group[GPIO_PORT(pin)]; // Convert GPIO # to port register + pinMask = (1UL << (pin % 32)); // From port_pin_set_output_level ASF code. + ptr = pixels; + end = ptr + numBytes; + p = *ptr++; + bitMask = 0x80; + + volatile uint32_t *set = &(port->OUTSET.reg), + *clr = &(port->OUTCLR.reg); + + for(;;) { + *set = pinMask; + // This is the time where the line is always high regardless of the bit. + // For the SK6812 its 0.3us +- 0.15us + #ifdef SAMD21 + asm("nop; nop;"); + #endif + #ifdef SAMD51 + delay_cycles(2); + #endif + if((p & bitMask) != 0) { + // This is the high delay unique to a one bit. + // For the SK6812 its 0.3us + #ifdef SAMD21 + asm("nop; nop; nop; nop; nop; nop; nop;"); + #endif + #ifdef SAMD51 + delay_cycles(3); + #endif + *clr = pinMask; + } else { + *clr = pinMask; + // This is the low delay unique to a zero bit. + // For the SK6812 its 0.3us + #ifdef SAMD21 + asm("nop; nop;"); + #endif + #ifdef SAMD51 + delay_cycles(2); + #endif + } + if((bitMask >>= 1) != 0) { + // This is the delay between bits in a byte and is the 1 code low + // level time from the datasheet. + // For the SK6812 its 0.6us +- 0.15us + #ifdef SAMD21 + asm("nop; nop; nop; nop; nop;"); + #endif + #ifdef SAMD51 + delay_cycles(4); + #endif + } else { + if(ptr >= end) break; + p = *ptr++; + bitMask = 0x80; + // This is the delay between bytes. It's similar to the other branch + // in the if statement except its tuned to account for the time the + // above operations take. + // For the SK6812 its 0.6us +- 0.15us + #ifdef SAMD51 + delay_cycles(3); + #endif + } + } + + #ifdef SAMD21 + // Speed up! (But inconsistent timing.) + NVMCTRL->CTRLB.bit.READMODE = NVMCTRL_CTRLB_READMODE_NO_MISS_PENALTY_Val; + #endif + + #ifdef SAMD51 + // Turn instruction, data, and NVM caches back on. + hri_cmcc_clear_CFG_reg(CMCC, CMCC_CFG_DCDIS | CMCC_CFG_ICDIS); + hri_nvmctrl_clear_CTRLA_CACHEDIS0_bit(NVMCTRL); + hri_nvmctrl_clear_CTRLA_CACHEDIS1_bit(NVMCTRL); + + #endif + + // ticks_ms may be out of date at this point because we stopped the + // interrupt. We'll risk it anyway. + current_tick(&next_start_tick_ms, &next_start_tick_us); + if (next_start_tick_us < 100) { + next_start_tick_ms += 1; + next_start_tick_us = 100 - next_start_tick_us; + } else { + next_start_tick_us -= 100; + } + + // Turn on interrupts after timing-sensitive code. + mp_hal_enable_all_interrupts(); + +} + +#pragma GCC pop_options diff --git a/ports/atmel-samd/common-hal/nvm/ByteArray.c b/ports/atmel-samd/common-hal/nvm/ByteArray.c new file mode 100644 index 00000000000..12a127f53a3 --- /dev/null +++ b/ports/atmel-samd/common-hal/nvm/ByteArray.c @@ -0,0 +1,55 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "common-hal/nvm/ByteArray.h" + +#include "hal_flash.h" + +#include "supervisor/shared/stack.h" + +#include +#include + +uint32_t common_hal_nvm_bytearray_get_length(nvm_bytearray_obj_t *self) { + return self->len; +} + +bool common_hal_nvm_bytearray_set_bytes(nvm_bytearray_obj_t *self, + uint32_t start_index, uint8_t* values, uint32_t len) { + // We don't use features that use any advanced NVMCTRL features so we can fake the descriptor + // whenever we need it instead of storing it long term. + struct flash_descriptor desc; + desc.dev.hw = NVMCTRL; + flash_write(&desc, (uint32_t) self->start_address + start_index, values, len); + assert_heap_ok(); + return true; +} + +// NVM memory is memory mapped so reading it is easy. +void common_hal_nvm_bytearray_get_bytes(nvm_bytearray_obj_t *self, + uint32_t start_index, uint32_t len, uint8_t* values) { + memcpy(values, self->start_address + start_index, len); +} diff --git a/ports/atmel-samd/common-hal/nvm/ByteArray.h b/ports/atmel-samd/common-hal/nvm/ByteArray.h new file mode 100644 index 00000000000..f6a816cb9d7 --- /dev/null +++ b/ports/atmel-samd/common-hal/nvm/ByteArray.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NVM_BYTEARRAY_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NVM_BYTEARRAY_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint8_t* start_address; + uint32_t len; +} nvm_bytearray_obj_t; + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NVM_BYTEARRAY_H diff --git a/ports/atmel-samd/common-hal/nvm/__init__.c b/ports/atmel-samd/common-hal/nvm/__init__.c new file mode 100644 index 00000000000..f0792430f01 --- /dev/null +++ b/ports/atmel-samd/common-hal/nvm/__init__.c @@ -0,0 +1,27 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +// No nvm module functions. diff --git a/ports/atmel-samd/common-hal/os/__init__.c b/ports/atmel-samd/common-hal/os/__init__.c new file mode 100644 index 00000000000..eeba29dfafe --- /dev/null +++ b/ports/atmel-samd/common-hal/os/__init__.c @@ -0,0 +1,85 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "genhdr/mpversion.h" +#include "py/mpconfig.h" +#include "py/objstr.h" +#include "py/objtuple.h" +#include "py/qstr.h" + +#ifdef SAMD51 +#include "hal/include/hal_rand_sync.h" +#endif + +STATIC const qstr os_uname_info_fields[] = { + MP_QSTR_sysname, MP_QSTR_nodename, + MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine +}; +#ifdef SAMD21 +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, "samd21"); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, "samd21"); +#endif +#ifdef SAMD51 +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, "samd51"); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, "samd51"); +#endif +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); + + +STATIC MP_DEFINE_ATTRTUPLE( + os_uname_info_obj, + os_uname_info_fields, + 5, + (mp_obj_t)&os_uname_info_sysname_obj, + (mp_obj_t)&os_uname_info_nodename_obj, + (mp_obj_t)&os_uname_info_release_obj, + (mp_obj_t)&os_uname_info_version_obj, + (mp_obj_t)&os_uname_info_machine_obj +); + +mp_obj_t common_hal_os_uname(void) { + return (mp_obj_t)&os_uname_info_obj; +} + +bool common_hal_os_urandom(uint8_t* buffer, uint32_t length) { + #ifdef SAMD51 + hri_mclk_set_APBCMASK_TRNG_bit(MCLK); + struct rand_sync_desc random; + rand_sync_init(&random, TRNG); + rand_sync_enable(&random); + + rand_sync_read_buf8(&random, buffer, length); + + rand_sync_disable(&random); + rand_sync_deinit(&random); + hri_mclk_clear_APBCMASK_TRNG_bit(MCLK); + return true; + #else + return false; + #endif +} diff --git a/ports/atmel-samd/common-hal/ps2io/Ps2.c b/ports/atmel-samd/common-hal/ps2io/Ps2.c new file mode 100644 index 00000000000..6a06864f217 --- /dev/null +++ b/ports/atmel-samd/common-hal/ps2io/Ps2.c @@ -0,0 +1,441 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017-2018 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Elvis Pfutzenreuter + * + * 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 "common-hal/ps2io/Ps2.h" + +#include + +#include "atmel_start_pins.h" +#include "hal/include/hal_gpio.h" + +#include "background.h" +#include "eic_handler.h" +#include "mpconfigport.h" +#include "py/gc.h" +#include "py/runtime.h" +#include "samd/external_interrupts.h" +#include "samd/pins.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/ps2io/Ps2.h" +#include "supervisor/shared/translate.h" + +#include "tick.h" + +#define STATE_IDLE 0 +#define STATE_RECV 1 +#define STATE_RECV_PARITY 2 +#define STATE_RECV_STOP 3 +#define STATE_RECV_ERR 10 + +#define ERROR_STARTBIT 0x01 +#define ERROR_TIMEOUT 0x02 +#define ERROR_PARITY 0x04 +#define ERROR_STOPBIT 0x08 +#define ERROR_BUFFER 0x10 + +#define ERROR_TX_CLKLO 0x100 +#define ERROR_TX_CLKHI 0x200 +#define ERROR_TX_ACKDATA 0x400 +#define ERROR_TX_ACKCLK 0x800 +#define ERROR_TX_RTS 0x1000 +#define ERROR_TX_NORESP 0x2000 + +static void ps2_set_config(ps2io_ps2_obj_t* self) { + uint32_t sense_setting = EIC_CONFIG_SENSE0_FALL_Val; + set_eic_handler(self->channel, EIC_HANDLER_PS2); + turn_on_eic_channel(self->channel, sense_setting); +} + +static void disable_interrupt(ps2io_ps2_obj_t* self) { + uint32_t mask = 1 << self->channel; + EIC->INTENCLR.reg = mask << EIC_INTENSET_EXTINT_Pos; +} + +static void resume_interrupt(ps2io_ps2_obj_t* self) { + disable_interrupt(self); + + self->state = STATE_IDLE; + gpio_set_pin_function(self->clk_pin, GPIO_PIN_FUNCTION_A); + uint32_t mask = 1 << self->channel; + EIC->INTFLAG.reg = mask << EIC_INTFLAG_EXTINT_Pos; + EIC->INTENSET.reg = mask << EIC_INTENSET_EXTINT_Pos; + + ps2_set_config(self); +} + +static void clk_hi(ps2io_ps2_obj_t* self) { + // External pull-up + // Must set pull after setting direction. + gpio_set_pin_direction(self->clk_pin, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(self->clk_pin, GPIO_PULL_OFF); +} + +static bool wait_clk_lo(ps2io_ps2_obj_t* self, uint32_t us) { + clk_hi(self); + common_hal_mcu_delay_us(1); + while (gpio_get_pin_level(self->clk_pin) && us) { + --us; + common_hal_mcu_delay_us(1); + } + return us; +} + +static bool wait_clk_hi(ps2io_ps2_obj_t* self, uint32_t us) { + clk_hi(self); + common_hal_mcu_delay_us(1); + while (!gpio_get_pin_level(self->clk_pin) && us) { + --us; + common_hal_mcu_delay_us(1); + } + return us; +} + +static void clk_lo(ps2io_ps2_obj_t* self) { + gpio_set_pin_pull_mode(self->clk_pin, GPIO_PULL_OFF); + gpio_set_pin_direction(self->clk_pin, GPIO_DIRECTION_OUT); + gpio_set_pin_level(self->clk_pin, 0); +} + +static void data_hi(ps2io_ps2_obj_t* self) { + // External pull-up + gpio_set_pin_direction(self->data_pin, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(self->data_pin, GPIO_PULL_OFF); +} + +static bool wait_data_lo(ps2io_ps2_obj_t* self, uint32_t us) { + data_hi(self); + common_hal_mcu_delay_us(1); + while (gpio_get_pin_level(self->data_pin) && us) { + --us; + common_hal_mcu_delay_us(1); + } + return us; +} + +static bool wait_data_hi(ps2io_ps2_obj_t* self, uint32_t us) { + data_hi(self); + common_hal_mcu_delay_us(1); + while (!gpio_get_pin_level(self->data_pin) && us) { + --us; + common_hal_mcu_delay_us(1); + } + return us; +} + +static void data_lo(ps2io_ps2_obj_t* self) { + gpio_set_pin_pull_mode(self->data_pin, GPIO_PULL_OFF); + gpio_set_pin_direction(self->data_pin, GPIO_DIRECTION_OUT); + gpio_set_pin_level(self->data_pin, 0); +} + +static void idle(ps2io_ps2_obj_t* self) { + clk_hi(self); + data_hi(self); +} + +static void inhibit(ps2io_ps2_obj_t* self) { + clk_lo(self); + data_hi(self); +} + +static void delay_us(uint32_t t) { + common_hal_mcu_delay_us(t); +} + +void ps2_interrupt_handler(uint8_t channel) { + // Grab the current time first. + uint32_t current_us; + uint64_t current_ms; + current_tick(¤t_ms, ¤t_us); + + ps2io_ps2_obj_t* self = get_eic_channel_data(channel); + int data_bit = gpio_get_pin_level(self->data_pin) ? 1 : 0; + + // test for timeout + if (self->state != STATE_IDLE) { + int64_t diff_ms = current_ms - self->last_int_ms; + if (diff_ms >= 2) { // a.k.a. > 1.001ms + self->last_errors |= ERROR_TIMEOUT; + self->state = STATE_IDLE; + } + } + + self->last_int_us = current_us; + self->last_int_ms = current_ms; + + if (self->state == STATE_IDLE) { + self->bits = 0; + self->parity = false; + self->bitcount = 0; + self->state = STATE_RECV; + if (data_bit) { + // start bit should be 0 + self->last_errors |= ERROR_STARTBIT; + self->state = STATE_RECV_ERR; + } else { + self->state = STATE_RECV; + } + + } else if (self->state == STATE_RECV) { + if (data_bit) { + self->bits |= data_bit << self->bitcount; + self->parity = !self->parity; + } + ++self->bitcount; + if (self->bitcount >= 8) { + self->state = STATE_RECV_PARITY; + } + + } else if (self->state == STATE_RECV_PARITY) { + ++self->bitcount; + if (data_bit) { + self->parity = !self->parity; + } + if (!self->parity) { + self->last_errors |= ERROR_PARITY; + self->state = STATE_RECV_ERR; + } else { + self->state = STATE_RECV_STOP; + } + + } else if (self->state == STATE_RECV_STOP) { + ++self->bitcount; + if (! data_bit) { + self->last_errors |= ERROR_STOPBIT; + } else if (self->waiting_cmd_response) { + self->cmd_response = self->bits; + self->waiting_cmd_response = false; + } else if (self->bufcount >= sizeof(self->buffer)) { + self->last_errors |= ERROR_BUFFER; + } else { + self->buffer[self->bufposw] = self->bits; + self->bufposw = (self->bufposw + 1) % sizeof(self->buffer); + self->bufcount++; + } + self->state = STATE_IDLE; + + } else if (self->state == STATE_RECV_ERR) { + // just count the bits until idle + if (++self->bitcount >= 10) { + self->state = STATE_IDLE; + } + } +} + +void common_hal_ps2io_ps2_construct(ps2io_ps2_obj_t* self, + const mcu_pin_obj_t* data_pin, const mcu_pin_obj_t* clk_pin) { + if (!clk_pin->has_extint) { + mp_raise_RuntimeError(translate("No hardware support on clk pin")); + } + if (eic_get_enable() && !eic_channel_free(clk_pin->extint_channel)) { + mp_raise_RuntimeError(translate("EXTINT channel already in use")); + } + + clk_hi(self); + data_hi(self); + + self->channel = clk_pin->extint_channel; + self->clk_pin = clk_pin->number; + self->data_pin = data_pin->number; + self->state = STATE_IDLE; + self->bufcount = 0; + self->bufposr = 0; + self->bufposw = 0; + self->waiting_cmd_response = false; + + set_eic_channel_data(clk_pin->extint_channel, (void*) self); + + // Check to see if the EIC is enabled and start it up if its not.' + if (eic_get_enable() == 0) { + turn_on_external_interrupt_controller(); + } + + gpio_set_pin_function(clk_pin->number, GPIO_PIN_FUNCTION_A); + gpio_set_pin_function(data_pin->number, GPIO_PIN_FUNCTION_A); + + turn_on_cpu_interrupt(self->channel); + + claim_pin(clk_pin); + claim_pin(data_pin); + + // Set config will enable the EIC. + ps2_set_config(self); +} + +bool common_hal_ps2io_ps2_deinited(ps2io_ps2_obj_t* self) { + return self->clk_pin == NO_PIN; +} + +void common_hal_ps2io_ps2_deinit(ps2io_ps2_obj_t* self) { + if (common_hal_ps2io_ps2_deinited(self)) { + return; + } + set_eic_handler(self->channel, EIC_HANDLER_NO_INTERRUPT); + turn_off_eic_channel(self->channel); + reset_pin_number(self->clk_pin); + reset_pin_number(self->data_pin); + self->clk_pin = NO_PIN; + self->data_pin = NO_PIN; +} + +uint16_t common_hal_ps2io_ps2_get_len(ps2io_ps2_obj_t* self) { + return self->bufcount; +} + +bool common_hal_ps2io_ps2_get_paused(ps2io_ps2_obj_t* self) { + uint32_t mask = 1 << self->channel; + return (EIC->INTENSET.reg & (mask << EIC_INTENSET_EXTINT_Pos)) == 0; +} + +int16_t common_hal_ps2io_ps2_popleft(ps2io_ps2_obj_t* self) +{ + common_hal_mcu_disable_interrupts(); + if (self->bufcount <= 0) { + common_hal_mcu_enable_interrupts(); + return -1; + } + uint8_t b = self->buffer[self->bufposr]; + self->bufposr = (self->bufposr + 1) % sizeof(self->buffer); + self->bufcount -= 1; + common_hal_mcu_enable_interrupts(); + return b; +} + +uint16_t common_hal_ps2io_ps2_clear_errors(ps2io_ps2_obj_t* self) +{ + common_hal_mcu_disable_interrupts(); + uint16_t errors = self->last_errors; + self->last_errors = 0; + common_hal_mcu_enable_interrupts(); + return errors; +} + +// Based upon TMK implementation of PS/2 protocol +// https://github.com/tmk/tmk_keyboard/blob/master/tmk_core/protocol/ps2_interrupt.c + +int16_t common_hal_ps2io_ps2_sendcmd(ps2io_ps2_obj_t* self, uint8_t b) +{ + disable_interrupt(self); + inhibit(self); + delay_us(100); + + /* RTS and start bit */ + data_lo(self); + clk_hi(self); + if (!wait_clk_lo(self, 10000)) { + self->last_errors |= ERROR_TX_RTS; + goto ERROR; + } + + bool parity = true; + for (uint8_t i = 0; i < 8; i++) { + delay_us(15); + if (b & (1 << i)) { + parity = !parity; + data_hi(self); + } else { + data_lo(self); + } + if (!wait_clk_hi(self, 50)) { + self->last_errors |= ERROR_TX_CLKHI; + goto ERROR; + } + if (!wait_clk_lo(self, 50)) { + self->last_errors |= ERROR_TX_CLKLO; + goto ERROR; + } + } + + delay_us(15); + if (parity) { + data_hi(self); + } else { + data_lo(self); + } + if (!wait_clk_hi(self, 50)) { + self->last_errors |= ERROR_TX_CLKHI; + goto ERROR; + } + if (!wait_clk_lo(self, 50)) { + self->last_errors |= ERROR_TX_CLKLO; + goto ERROR; + } + + /* Stop bit */ + delay_us(15); + data_hi(self); + + /* Ack */ + if (!wait_data_lo(self, 50)) { + self->last_errors |= ERROR_TX_ACKDATA; + goto ERROR; + } + if (!wait_clk_lo(self, 50)) { + self->last_errors |= ERROR_TX_ACKCLK; + goto ERROR; + } + + /* wait for idle state */ + if (!wait_clk_hi(self, 50)) { + self->last_errors |= ERROR_TX_ACKCLK; + goto ERROR; + } + if (!wait_data_hi(self, 50)) { + self->last_errors |= ERROR_TX_ACKDATA; + goto ERROR; + } + + /* Wait for response byte */ + self->waiting_cmd_response = true; + idle(self); + resume_interrupt(self); + + for (int i = 0; i < 25; ++i) { + delay_us(1000); + common_hal_mcu_disable_interrupts(); + bool has_response = !self->waiting_cmd_response; + uint8_t response = self->cmd_response; + common_hal_mcu_enable_interrupts(); + + if (has_response) { + return response; + } + } + + /* No response */ + common_hal_mcu_disable_interrupts(); + self->waiting_cmd_response = false; + self->last_errors |= ERROR_TX_NORESP; + common_hal_mcu_enable_interrupts(); + return -1; + + /* Other errors */ +ERROR: + idle(self); + resume_interrupt(self); + return -1; +} diff --git a/ports/atmel-samd/common-hal/ps2io/Ps2.h b/ports/atmel-samd/common-hal/ps2io/Ps2.h new file mode 100644 index 00000000000..cce6ae4746a --- /dev/null +++ b/ports/atmel-samd/common-hal/ps2io/Ps2.h @@ -0,0 +1,62 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Elvis Pfutzenreuter + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PS2IO_PS2_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PS2IO_PS2_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint8_t channel; + uint8_t clk_pin; + uint8_t data_pin; + + uint8_t state; + uint64_t last_int_ms; + uint32_t last_int_us; + + uint16_t bits; + bool parity; + uint8_t bitcount; + + uint8_t buffer[16]; + uint8_t bufcount; + uint8_t bufposr; + uint8_t bufposw; + + uint16_t last_errors; + + bool waiting_cmd_response; + uint8_t cmd_response; +} ps2io_ps2_obj_t; + +void ps2_interrupt_handler(uint8_t channel); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PS2IO_PS2_H diff --git a/ports/atmel-samd/common-hal/ps2io/__init__.c b/ports/atmel-samd/common-hal/ps2io/__init__.c new file mode 100644 index 00000000000..ba4b4249f73 --- /dev/null +++ b/ports/atmel-samd/common-hal/ps2io/__init__.c @@ -0,0 +1 @@ +// No ps2io module functions. diff --git a/ports/atmel-samd/common-hal/pulseio/PWMOut.c b/ports/atmel-samd/common-hal/pulseio/PWMOut.c new file mode 100644 index 00000000000..6dcace21fdd --- /dev/null +++ b/ports/atmel-samd/common-hal/pulseio/PWMOut.c @@ -0,0 +1,473 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2016 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 + +#include "py/runtime.h" +#include "common-hal/pulseio/PWMOut.h" +#include "shared-bindings/pulseio/PWMOut.h" +#include "shared-bindings/microcontroller/Processor.h" +#include "timer_handler.h" + +#include "atmel_start_pins.h" +#include "hal/utils/include/utils_repeat_macro.h" +#include "samd/timers.h" +#include "supervisor/shared/translate.h" + +#include "samd/pins.h" + +#undef ENABLE + +# define _TCC_SIZE(unused, n) TCC ## n ## _SIZE, +# define TCC_SIZES { REPEAT_MACRO(_TCC_SIZE, 0, TCC_INST_NUM) } + +static uint32_t tcc_periods[TCC_INST_NUM]; +static uint32_t tc_periods[TC_INST_NUM]; + +uint32_t target_tcc_frequencies[TCC_INST_NUM]; +uint8_t tcc_refcount[TCC_INST_NUM]; + +// This bitmask keeps track of which channels of a TCC are currently claimed. +#ifdef SAMD21 +uint8_t tcc_channels[3]; // Set by pwmout_reset() to {0xf0, 0xfc, 0xfc} initially. +#endif +#ifdef SAMD51 +uint8_t tcc_channels[5]; // Set by pwmout_reset() to {0xc0, 0xf0, 0xf8, 0xfc, 0xfc} initially. +#endif + +static uint8_t never_reset_tc_or_tcc[TC_INST_NUM + TCC_INST_NUM]; + +void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) { + if (self->timer->is_tc) { + never_reset_tc_or_tcc[self->timer->index] += 1; + } else { + never_reset_tc_or_tcc[TC_INST_NUM + self->timer->index] += 1; + } + + never_reset_pin_number(self->pin->number); +} + +void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self) { + if (self->timer->is_tc) { + never_reset_tc_or_tcc[self->timer->index] -= 1; + } else { + never_reset_tc_or_tcc[TC_INST_NUM + self->timer->index] -= 1; + } +} + +void pwmout_reset(void) { + // Reset all timers + for (int i = 0; i < TCC_INST_NUM; i++) { + target_tcc_frequencies[i] = 0; + tcc_refcount[i] = 0; + } + Tcc *tccs[TCC_INST_NUM] = TCC_INSTS; + for (int i = 0; i < TCC_INST_NUM; i++) { + if (never_reset_tc_or_tcc[TC_INST_NUM + i] > 0) { + continue; + } + // Disable the module before resetting it. + if (tccs[i]->CTRLA.bit.ENABLE == 1) { + tccs[i]->CTRLA.bit.ENABLE = 0; + while (tccs[i]->SYNCBUSY.bit.ENABLE == 1) { + } + } + uint8_t mask = 0xff; + for (uint8_t j = 0; j < tcc_cc_num[i]; j++) { + mask <<= 1; + } + tcc_channels[i] = mask; + tccs[i]->CTRLA.bit.SWRST = 1; + while (tccs[i]->CTRLA.bit.SWRST == 1) { + } + } + Tc *tcs[TC_INST_NUM] = TC_INSTS; + for (int i = 0; i < TC_INST_NUM; i++) { + if (never_reset_tc_or_tcc[i] > 0) { + continue; + } + tcs[i]->COUNT16.CTRLA.bit.SWRST = 1; + while (tcs[i]->COUNT16.CTRLA.bit.SWRST == 1) { + } + } +} + +static uint8_t tcc_channel(const pin_timer_t* t) { + // For the SAMD51 this hardcodes the use of OTMX == 0x0, the output matrix mapping, which uses + // SAMD21-style modulo mapping. + return t->wave_output % tcc_cc_num[t->index]; +} + +bool channel_ok(const pin_timer_t* t) { + uint8_t channel_bit = 1 << tcc_channel(t); + return (!t->is_tc && ((tcc_channels[t->index] & channel_bit) == 0)) || + t->is_tc; +} + +pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, + const mcu_pin_obj_t* pin, + uint16_t duty, + uint32_t frequency, + bool variable_frequency) { + self->pin = pin; + self->variable_frequency = variable_frequency; + + if (pin->timer[0].index >= TC_INST_NUM && + pin->timer[1].index >= TCC_INST_NUM +#ifdef SAMD51 + && pin->timer[2].index >= TCC_INST_NUM +#endif + ) { + return PWMOUT_INVALID_PIN; + } + + if (frequency == 0 || frequency > 6000000) { + return PWMOUT_INVALID_FREQUENCY; + } + + // Figure out which timer we are using. + + // First see if a tcc is already going with the frequency we want and our + // channel is unused. tc's don't have enough channels to share. + const pin_timer_t* timer = NULL; + uint8_t mux_position = 0; + if (!variable_frequency) { + for (uint8_t i = 0; i < TCC_INST_NUM && timer == NULL; i++) { + if (target_tcc_frequencies[i] != frequency) { + continue; + } + for (uint8_t j = 0; j < NUM_TIMERS_PER_PIN && timer == NULL; j++) { + const pin_timer_t* t = &pin->timer[j]; + if (t->index != i || t->is_tc || t->index >= TCC_INST_NUM) { + continue; + } + Tcc* tcc = tcc_insts[t->index]; + if (tcc->CTRLA.bit.ENABLE == 1 && channel_ok(t)) { + timer = t; + mux_position = j; + // Claim channel. + tcc_channels[timer->index] |= (1 << tcc_channel(timer)); + + } + } + } + } + + // No existing timer has been found, so find a new one to use and set it up. + if (timer == NULL) { + // By default, with fixed frequency we want to share a TCC because its likely we'll have + // other outputs at the same frequency. If the frequency is variable then we'll only have + // one output so we start with the TCs to see if they work. + int8_t direction = -1; + uint8_t start = NUM_TIMERS_PER_PIN - 1; + bool found = false; + if (variable_frequency) { + direction = 1; + start = 0; + } + for (int8_t i = start; i >= 0 && i < NUM_TIMERS_PER_PIN && timer == NULL; i += direction) { + const pin_timer_t* t = &pin->timer[i]; + if ((!t->is_tc && t->index >= TCC_INST_NUM) || + (t->is_tc && t->index >= TC_INST_NUM)) { + continue; + } + if (t->is_tc) { + found = true; + Tc* tc = tc_insts[t->index]; + if (tc->COUNT16.CTRLA.bit.ENABLE == 0 && t->wave_output == 1) { + timer = t; + mux_position = i; + } + } else { + Tcc* tcc = tcc_insts[t->index]; + if (tcc->CTRLA.bit.ENABLE == 0 && channel_ok(t)) { + timer = t; + mux_position = i; + } + } + } + + if (timer == NULL) { + if (found) { + return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE; + } + return PWMOUT_ALL_TIMERS_IN_USE; + } + + uint8_t resolution = 0; + if (timer->is_tc) { + resolution = 16; + } else { + // TCC resolution varies so look it up. + const uint8_t _tcc_sizes[TCC_INST_NUM] = TCC_SIZES; + resolution = _tcc_sizes[timer->index]; + } + // First determine the divisor that gets us the highest resolution. + uint32_t system_clock = common_hal_mcu_processor_get_frequency(); + uint32_t top; + uint8_t divisor; + for (divisor = 0; divisor < 8; divisor++) { + top = (system_clock / prescaler[divisor] / frequency) - 1; + if (top < (1u << resolution)) { + break; + } + } + + set_timer_handler(timer->is_tc, timer->index, TC_HANDLER_NO_INTERRUPT); + // We use the zeroeth clock on either port to go full speed. + turn_on_clocks(timer->is_tc, timer->index, 0); + + if (timer->is_tc) { + tc_periods[timer->index] = top; + Tc* tc = tc_insts[timer->index]; + #ifdef SAMD21 + tc->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 | + TC_CTRLA_PRESCALER(divisor) | + TC_CTRLA_WAVEGEN_MPWM; + tc->COUNT16.CC[0].reg = top; + #endif + #ifdef SAMD51 + + tc->COUNT16.CTRLA.bit.SWRST = 1; + while (tc->COUNT16.CTRLA.bit.SWRST == 1) { + } + tc_set_enable(tc, false); + tc->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 | TC_CTRLA_PRESCALER(divisor); + tc->COUNT16.WAVE.reg = TC_WAVE_WAVEGEN_MPWM; + tc->COUNT16.CCBUF[0].reg = top; + tc->COUNT16.CCBUF[1].reg = 0; + #endif + + tc_set_enable(tc, true); + } else { + tcc_periods[timer->index] = top; + Tcc* tcc = tcc_insts[timer->index]; + tcc_set_enable(tcc, false); + tcc->CTRLA.bit.PRESCALER = divisor; + tcc->PER.bit.PER = top; + tcc->WAVE.bit.WAVEGEN = TCC_WAVE_WAVEGEN_NPWM_Val; + tcc_set_enable(tcc, true); + target_tcc_frequencies[timer->index] = frequency; + tcc_refcount[timer->index]++; + if (variable_frequency) { + // We're changing frequency so claim all of the channels. + tcc_channels[timer->index] = 0xff; + } else { + tcc_channels[timer->index] |= (1 << tcc_channel(timer)); + } + } + } + + self->timer = timer; + + gpio_set_pin_function(pin->number, GPIO_PIN_FUNCTION_E + mux_position); + + common_hal_pulseio_pwmout_set_duty_cycle(self, duty); + return PWMOUT_OK; +} + +bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) { + return self->pin == mp_const_none; +} + +void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { + if (common_hal_pulseio_pwmout_deinited(self)) { + return; + } + const pin_timer_t* t = self->timer; + if (t->is_tc) { + Tc* tc = tc_insts[t->index]; + tc_set_enable(tc, false); + tc->COUNT16.CTRLA.bit.SWRST = true; + tc_wait_for_sync(tc); + } else { + tcc_refcount[t->index]--; + tcc_channels[t->index] &= ~(1 << tcc_channel(t)); + if (tcc_refcount[t->index] == 0) { + target_tcc_frequencies[t->index] = 0; + Tcc* tcc = tcc_insts[t->index]; + tcc_set_enable(tcc, false); + tcc->CTRLA.bit.SWRST = true; + while (tcc->SYNCBUSY.bit.SWRST != 0) { + /* Wait for sync */ + } + } + } + reset_pin_number(self->pin->number); + self->pin = mp_const_none; +} + +extern void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty) { + const pin_timer_t* t = self->timer; + if (t->is_tc) { + uint16_t adjusted_duty = tc_periods[t->index] * duty / 0xffff; + #ifdef SAMD21 + tc_insts[t->index]->COUNT16.CC[t->wave_output].reg = adjusted_duty; + #endif + #ifdef SAMD51 + Tc* tc = tc_insts[t->index]; + while (tc->COUNT16.SYNCBUSY.bit.CC1 != 0) {} + tc->COUNT16.CCBUF[1].reg = adjusted_duty; + #endif + } else { + uint32_t adjusted_duty = ((uint64_t) tcc_periods[t->index]) * duty / 0xffff; + uint8_t channel = tcc_channel(t); + Tcc* tcc = tcc_insts[t->index]; + + // Write into the CC buffer register, which will be transferred to the + // CC register on an UPDATE (when period is finished). + // Do clock domain syncing as necessary. + + while (tcc->SYNCBUSY.reg != 0) {} + + // Lock out double-buffering while updating the CCB value. + tcc->CTRLBSET.bit.LUPD = 1; + #ifdef SAMD21 + tcc->CCB[channel].reg = adjusted_duty; + #endif + #ifdef SAMD51 + tcc->CCBUF[channel].reg = adjusted_duty; + #endif + tcc->CTRLBCLR.bit.LUPD = 1; + } +} + +uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) { + const pin_timer_t* t = self->timer; + if (t->is_tc) { + Tc* tc = tc_insts[t->index]; + tc_wait_for_sync(tc); + uint16_t cv = tc->COUNT16.CC[t->wave_output].reg; + return cv * 0xffff / tc_periods[t->index]; + } else { + Tcc* tcc = tcc_insts[t->index]; + uint8_t channel = tcc_channel(t); + uint32_t cv = 0; + + while (tcc->SYNCBUSY.bit.CTRLB) {} + + #ifdef SAMD21 + // If CCBV (CCB valid) is set, the CCB value hasn't yet been copied + // to the CC value. + if ((tcc->STATUS.vec.CCBV & (1 << channel)) != 0) { + cv = tcc->CCB[channel].reg; + } else { + cv = tcc->CC[channel].reg; + } + #endif + #ifdef SAMD51 + if ((tcc->STATUS.vec.CCBUFV & (1 << channel)) != 0) { + cv = tcc->CCBUF[channel].reg; + } else { + cv = tcc->CC[channel].reg; + } + #endif + + uint32_t duty_cycle = ((uint64_t) cv) * 0xffff / tcc_periods[t->index]; + + return duty_cycle; + } +} + + +void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, + uint32_t frequency) { + if (frequency == 0 || frequency > 6000000) { + mp_raise_ValueError(translate("Invalid PWM frequency")); + } + const pin_timer_t* t = self->timer; + uint8_t resolution; + if (t->is_tc) { + resolution = 16; + } else { + resolution = 24; + } + uint32_t system_clock = common_hal_mcu_processor_get_frequency(); + uint32_t new_top; + uint8_t new_divisor; + for (new_divisor = 0; new_divisor < 8; new_divisor++) { + new_top = (system_clock / prescaler[new_divisor] / frequency) - 1; + if (new_top < (1u << resolution)) { + break; + } + } + uint16_t old_duty = common_hal_pulseio_pwmout_get_duty_cycle(self); + if (t->is_tc) { + Tc* tc = tc_insts[t->index]; + uint8_t old_divisor = tc->COUNT16.CTRLA.bit.PRESCALER; + if (new_divisor != old_divisor) { + tc_set_enable(tc, false); + tc->COUNT16.CTRLA.bit.PRESCALER = new_divisor; + tc_set_enable(tc, true); + } + tc_periods[t->index] = new_top; + #ifdef SAMD21 + tc->COUNT16.CC[0].reg = new_top; + #endif + #ifdef SAMD51 + while (tc->COUNT16.SYNCBUSY.reg != 0) {} + tc->COUNT16.CCBUF[0].reg = new_top; + #endif + } else { + Tcc* tcc = tcc_insts[t->index]; + uint8_t old_divisor = tcc->CTRLA.bit.PRESCALER; + if (new_divisor != old_divisor) { + tcc_set_enable(tcc, false); + tcc->CTRLA.bit.PRESCALER = new_divisor; + tcc_set_enable(tcc, true); + } + while (tcc->SYNCBUSY.reg != 0) {} + tcc_periods[t->index] = new_top; + #ifdef SAMD21 + tcc->PERB.bit.PERB = new_top; + #endif + #ifdef SAMD51 + tcc->PERBUF.bit.PERBUF = new_top; + #endif + } + + common_hal_pulseio_pwmout_set_duty_cycle(self, old_duty); +} + +uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self) { + uint32_t system_clock = common_hal_mcu_processor_get_frequency(); + const pin_timer_t* t = self->timer; + uint8_t divisor; + uint32_t top; + if (t->is_tc) { + divisor = tc_insts[t->index]->COUNT16.CTRLA.bit.PRESCALER; + top = tc_periods[t->index]; + } else { + divisor = tcc_insts[t->index]->CTRLA.bit.PRESCALER; + top = tcc_periods[t->index]; + } + return (system_clock / prescaler[divisor]) / (top + 1); +} + +bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self) { + return self->variable_frequency; +} diff --git a/ports/atmel-samd/common-hal/pulseio/PWMOut.h b/ports/atmel-samd/common-hal/pulseio/PWMOut.h new file mode 100644 index 00000000000..eef653bcb2d --- /dev/null +++ b/ports/atmel-samd/common-hal/pulseio/PWMOut.h @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PWMOUT_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PWMOUT_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t *pin; + const pin_timer_t* timer; + bool variable_frequency; +} pulseio_pwmout_obj_t; + +void pwmout_reset(void); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PWMOUT_H diff --git a/ports/atmel-samd/common-hal/pulseio/PulseIn.c b/ports/atmel-samd/common-hal/pulseio/PulseIn.c new file mode 100644 index 00000000000..a2494f102f4 --- /dev/null +++ b/ports/atmel-samd/common-hal/pulseio/PulseIn.c @@ -0,0 +1,245 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017-2018 Scott Shawcroft for Adafruit Industries + * + * 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 "common-hal/pulseio/PulseIn.h" + +#include + +#include "atmel_start_pins.h" +#include "hal/include/hal_gpio.h" + +#include "background.h" +#include "eic_handler.h" +#include "mpconfigport.h" +#include "py/gc.h" +#include "py/runtime.h" +#include "samd/external_interrupts.h" +#include "samd/pins.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/pulseio/PulseIn.h" +#include "supervisor/shared/translate.h" + +#include "tick.h" + +static void pulsein_set_config(pulseio_pulsein_obj_t* self, bool first_edge) { + uint32_t sense_setting; + if (!first_edge) { + sense_setting = EIC_CONFIG_SENSE0_BOTH_Val; + configure_eic_channel(self->channel, sense_setting); + return; + } else if (self->idle_state) { + sense_setting = EIC_CONFIG_SENSE0_FALL_Val; + } else { + sense_setting = EIC_CONFIG_SENSE0_RISE_Val; + } + set_eic_handler(self->channel, EIC_HANDLER_PULSEIN); + turn_on_eic_channel(self->channel, sense_setting); +} + +void pulsein_interrupt_handler(uint8_t channel) { + // Grab the current time first. + uint32_t current_us; + uint64_t current_ms; + current_tick(¤t_ms, ¤t_us); + + // current_tick gives us the remaining us until the next tick but we want the number since the + // last ms. + current_us = 1000 - current_us; + pulseio_pulsein_obj_t* self = get_eic_channel_data(channel); + if (!background_tasks_ok() || self->errored_too_fast) { + self->errored_too_fast = true; + common_hal_pulseio_pulsein_pause(self); + return; + } + if (self->first_edge) { + self->first_edge = false; + pulsein_set_config(self, false); + } else { + uint32_t ms_diff = current_ms - self->last_ms; + uint16_t us_diff = current_us - self->last_us; + uint32_t total_diff = us_diff; + if (self->last_us > current_us) { + total_diff = 1000 + current_us - self->last_us; + if (ms_diff > 1) { + total_diff += (ms_diff - 1) * 1000; + } + } else { + total_diff += ms_diff * 1000; + } + uint16_t duration = 0xffff; + if (total_diff < duration) { + duration = total_diff; + } + + uint16_t i = (self->start + self->len) % self->maxlen; + self->buffer[i] = duration; + if (self->len < self->maxlen) { + self->len++; + } else { + self->start++; + } + } + self->last_ms = current_ms; + self->last_us = current_us; +} + +void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, + const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) { + if (!pin->has_extint) { + mp_raise_RuntimeError(translate("No hardware support on pin")); + } + if (eic_get_enable() && !eic_channel_free(pin->extint_channel)) { + mp_raise_RuntimeError(translate("EXTINT channel already in use")); + } + + self->buffer = (uint16_t *) m_malloc(maxlen * sizeof(uint16_t), false); + if (self->buffer == NULL) { + mp_raise_msg_varg(&mp_type_MemoryError, translate("Failed to allocate RX buffer of %d bytes"), maxlen * sizeof(uint16_t)); + } + self->channel = pin->extint_channel; + self->pin = pin->number; + self->maxlen = maxlen; + self->idle_state = idle_state; + self->start = 0; + self->len = 0; + self->first_edge = true; + self->last_us = 0; + self->last_ms = 0; + self->errored_too_fast = false; + + set_eic_channel_data(pin->extint_channel, (void*) self); + + // Check to see if the EIC is enabled and start it up if its not.' + if (eic_get_enable() == 0) { + turn_on_external_interrupt_controller(); + } + + gpio_set_pin_function(pin->number, GPIO_PIN_FUNCTION_A); + + turn_on_cpu_interrupt(self->channel); + + claim_pin(pin); + + // Set config will enable the EIC. + pulsein_set_config(self, true); +} + +bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self) { + return self->pin == NO_PIN; +} + +void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) { + if (common_hal_pulseio_pulsein_deinited(self)) { + return; + } + set_eic_handler(self->channel, EIC_HANDLER_NO_INTERRUPT); + turn_off_eic_channel(self->channel); + reset_pin_number(self->pin); + self->pin = NO_PIN; +} + +void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) { + uint32_t mask = 1 << self->channel; + EIC->INTENCLR.reg = mask << EIC_INTENSET_EXTINT_Pos; +} + +void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, + uint16_t trigger_duration) { + // Make sure we're paused. + common_hal_pulseio_pulsein_pause(self); + + // Reset erroring + self->errored_too_fast = false; + + // Send the trigger pulse. + if (trigger_duration > 0) { + gpio_set_pin_pull_mode(self->pin, GPIO_PULL_OFF); + gpio_set_pin_direction(self->pin, GPIO_DIRECTION_OUT); + gpio_set_pin_level(self->pin, !self->idle_state); + common_hal_mcu_delay_us((uint32_t)trigger_duration); + gpio_set_pin_level(self->pin, self->idle_state); + } + + // Reconfigure the pin and make sure its set to detect the first edge. + self->first_edge = true; + self->last_ms = 0; + self->last_us = 0; + gpio_set_pin_function(self->pin, GPIO_PIN_FUNCTION_A); + uint32_t mask = 1 << self->channel; + // Clear previous interrupt state and re-enable it. + EIC->INTFLAG.reg = mask << EIC_INTFLAG_EXTINT_Pos; + EIC->INTENSET.reg = mask << EIC_INTENSET_EXTINT_Pos; + + pulsein_set_config(self, true); +} + +void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self) { + common_hal_mcu_disable_interrupts(); + self->start = 0; + self->len = 0; + common_hal_mcu_enable_interrupts(); +} + +uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) { + if (self->len == 0) { + mp_raise_IndexError(translate("pop from an empty PulseIn")); + } + common_hal_mcu_disable_interrupts(); + uint16_t value = self->buffer[self->start]; + self->start = (self->start + 1) % self->maxlen; + self->len--; + common_hal_mcu_enable_interrupts(); + + return value; +} + +uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self) { + return self->maxlen; +} + +uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) { + return self->len; +} + +bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self) { + uint32_t mask = 1 << self->channel; + return (EIC->INTENSET.reg & (mask << EIC_INTENSET_EXTINT_Pos)) == 0; +} + +uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, + int16_t index) { + common_hal_mcu_disable_interrupts(); + if (index < 0) { + index += self->len; + } + if (index < 0 || index >= self->len) { + common_hal_mcu_enable_interrupts(); + mp_raise_IndexError(translate("index out of range")); + } + uint16_t value = self->buffer[(self->start + index) % self->maxlen]; + common_hal_mcu_enable_interrupts(); + return value; +} diff --git a/ports/atmel-samd/common-hal/pulseio/PulseIn.h b/ports/atmel-samd/common-hal/pulseio/PulseIn.h new file mode 100644 index 00000000000..f5326d9e517 --- /dev/null +++ b/ports/atmel-samd/common-hal/pulseio/PulseIn.h @@ -0,0 +1,53 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEIN_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEIN_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint8_t channel; + uint8_t pin; + uint16_t* buffer; + uint16_t maxlen; + bool idle_state; + volatile uint16_t start; + volatile uint16_t len; + volatile bool first_edge; + volatile uint64_t last_ms; + volatile uint16_t last_us; + volatile bool errored_too_fast; +} pulseio_pulsein_obj_t; + +void pulsein_reset(void); + +void pulsein_interrupt_handler(uint8_t channel); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEIN_H diff --git a/ports/atmel-samd/common-hal/pulseio/PulseOut.c b/ports/atmel-samd/common-hal/pulseio/PulseOut.c new file mode 100644 index 00000000000..8b8bc6dc684 --- /dev/null +++ b/ports/atmel-samd/common-hal/pulseio/PulseOut.c @@ -0,0 +1,208 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 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 "common-hal/pulseio/PulseOut.h" + +#include + +#include "hal/include/hal_gpio.h" + +#include "mpconfigport.h" +#include "samd/pins.h" +#include "samd/timers.h" +#include "py/gc.h" +#include "py/runtime.h" +#include "shared-bindings/pulseio/PulseOut.h" +#include "supervisor/shared/translate.h" +#include "timer_handler.h" + +// This timer is shared amongst all PulseOut objects under the assumption that +// the code is single threaded. +static uint8_t refcount = 0; + +static uint8_t pulseout_tc_index = 0xff; + +static __IO PORT_PINCFG_Type *active_pincfg = NULL; +static uint16_t *pulse_buffer = NULL; +static volatile uint16_t pulse_index = 0; +static uint16_t pulse_length; +static volatile uint32_t current_compare = 0; + +static void turn_on(__IO PORT_PINCFG_Type * pincfg) { + pincfg->reg = PORT_PINCFG_PMUXEN; +} + +static void turn_off(__IO PORT_PINCFG_Type * pincfg) { + pincfg->reg = PORT_PINCFG_RESETVALUE; +} + +void pulse_finish(void) { + pulse_index++; + + if (active_pincfg == NULL) { + return; + } + // Always turn it off. + turn_off(active_pincfg); + if (pulse_index >= pulse_length) { + return; + } + current_compare = (current_compare + pulse_buffer[pulse_index] * 3 / 4) & 0xffff; + Tc* tc = tc_insts[pulseout_tc_index]; + tc->COUNT16.CC[0].reg = current_compare; + if (pulse_index % 2 == 0) { + turn_on(active_pincfg); + } +} + +void pulseout_interrupt_handler(uint8_t index) { + if (index != pulseout_tc_index) return; + Tc* tc = tc_insts[index]; + if (!tc->COUNT16.INTFLAG.bit.MC0) return; + + pulse_finish(); + + // Clear the interrupt bit. + tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC0; +} + +void pulseout_reset() { + refcount = 0; + pulseout_tc_index = 0xff; + active_pincfg = NULL; +} + +void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self, + const pulseio_pwmout_obj_t* carrier) { + if (refcount == 0) { + // Find a spare timer. + Tc *tc = NULL; + int8_t index = TC_INST_NUM - 1; + for (; index >= 0; index--) { + if (tc_insts[index]->COUNT16.CTRLA.bit.ENABLE == 0) { + tc = tc_insts[index]; + break; + } + } + if (tc == NULL) { + mp_raise_RuntimeError(translate("All timers in use")); + } + + pulseout_tc_index = index; + + set_timer_handler(true, index, TC_HANDLER_PULSEOUT); + // We use GCLK0 for SAMD21 and GCLK1 for SAMD51 because they both run at 48mhz making our + // math the same across the boards. + #ifdef SAMD21 + turn_on_clocks(true, index, 0); + #endif + #ifdef SAMD51 + turn_on_clocks(true, index, 1); + #endif + + + #ifdef SAMD21 + tc->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 | + TC_CTRLA_PRESCALER_DIV64 | + TC_CTRLA_WAVEGEN_NFRQ; + #endif + #ifdef SAMD51 + tc_reset(tc); + tc_set_enable(tc, false); + tc->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 | TC_CTRLA_PRESCALER_DIV64; + tc->COUNT16.WAVE.reg = TC_WAVE_WAVEGEN_NFRQ; + #endif + + tc_set_enable(tc, true); + tc->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_STOP; + } + refcount++; + + self->pin = carrier->pin->number; + + PortGroup *const port_base = &PORT->Group[GPIO_PORT(self->pin)]; + self->pincfg = &port_base->PINCFG[self->pin % 32]; + + // Set the port to output a zero. + port_base->OUTCLR.reg = 1 << (self->pin % 32); + port_base->DIRSET.reg = 1 << (self->pin % 32); + + // Turn off the pinmux which should connect the port output. + turn_off(self->pincfg); +} + +bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self) { + return self->pin == NO_PIN; +} + +void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) { + if (common_hal_pulseio_pulseout_deinited(self)) { + return; + } + PortGroup *const port_base = &PORT->Group[GPIO_PORT(self->pin)]; + port_base->DIRCLR.reg = 1 << (self->pin % 32); + + turn_on(self->pincfg); + + refcount--; + if (refcount == 0) { + tc_reset(tc_insts[pulseout_tc_index]); + pulseout_tc_index = 0xff; + } + self->pin = NO_PIN; +} + +void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pulses, uint16_t length) { + if (active_pincfg != NULL) { + mp_raise_RuntimeError(translate("Another send is already active")); + } + active_pincfg = self->pincfg; + pulse_buffer = pulses; + pulse_index = 0; + pulse_length = length; + + current_compare = pulses[0] * 3 / 4; + Tc* tc = tc_insts[pulseout_tc_index]; + tc->COUNT16.CC[0].reg = current_compare; + + // Clear our interrupt in case it was set earlier + tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC0; + tc->COUNT16.INTENSET.reg = TC_INTENSET_MC0; + tc_enable_interrupts(pulseout_tc_index); + turn_on(active_pincfg); + tc->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_RETRIGGER; + + while(pulse_index < length) { + // Do other things while we wait. The interrupts will handle sending the + // signal. + RUN_BACKGROUND_TASKS; + } + + tc->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_STOP; + tc->COUNT16.INTENCLR.reg = TC_INTENCLR_MC0; + tc_disable_interrupts(pulseout_tc_index); + active_pincfg = NULL; +} diff --git a/ports/atmel-samd/common-hal/pulseio/PulseOut.h b/ports/atmel-samd/common-hal/pulseio/PulseOut.h new file mode 100644 index 00000000000..634088128fb --- /dev/null +++ b/ports/atmel-samd/common-hal/pulseio/PulseOut.h @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEOUT_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEOUT_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + __IO PORT_PINCFG_Type *pincfg; + uint8_t pin; +} pulseio_pulseout_obj_t; + +void pulseout_reset(void); +void pulseout_interrupt_handler(uint8_t index); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEOUT_H diff --git a/ports/atmel-samd/common-hal/pulseio/__init__.c b/ports/atmel-samd/common-hal/pulseio/__init__.c new file mode 100644 index 00000000000..2bee925bc77 --- /dev/null +++ b/ports/atmel-samd/common-hal/pulseio/__init__.c @@ -0,0 +1 @@ +// No pulseio module functions. diff --git a/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c b/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c new file mode 100644 index 00000000000..0922718f962 --- /dev/null +++ b/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c @@ -0,0 +1,171 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "common-hal/rotaryio/IncrementalEncoder.h" + +#include "atmel_start_pins.h" + +#include "eic_handler.h" +#include "samd/external_interrupts.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t* self, + const mcu_pin_obj_t* pin_a, const mcu_pin_obj_t* pin_b) { + if (!pin_a->has_extint || !pin_b->has_extint) { + mp_raise_RuntimeError(translate("Both pins must support hardware interrupts")); + } + + // TODO: The SAMD51 has a peripheral dedicated to quadrature encoder debugging. Use it instead + // of the external interrupt. + + if (eic_get_enable()) { + if (!eic_channel_free(pin_a->extint_channel) || !eic_channel_free(pin_b->extint_channel)) { + mp_raise_RuntimeError(translate("A hardware interrupt channel is already in use")); + } + } else { + turn_on_external_interrupt_controller(); + } + + // These default settings apply when the EIC isn't yet enabled. + self->eic_channel_a = pin_a->extint_channel; + self->eic_channel_b = pin_b->extint_channel; + self->pin_a = pin_a->number; + self->pin_b = pin_b->number; + + gpio_set_pin_function(self->pin_a, GPIO_PIN_FUNCTION_A); + gpio_set_pin_pull_mode(self->pin_a, GPIO_PULL_UP); + + gpio_set_pin_function(self->pin_b, GPIO_PIN_FUNCTION_A); + gpio_set_pin_pull_mode(self->pin_b, GPIO_PULL_UP); + + set_eic_channel_data(self->eic_channel_a, (void*) self); + set_eic_channel_data(self->eic_channel_b, (void*) self); + + self->position = 0; + self->quarter_count = 0; + + // Top two bits of self->last_state don't matter, because they'll be gone as soon as + // interrupt handler is called. + self->last_state = + ((uint8_t) gpio_get_pin_level(self->pin_a) << 1) | + (uint8_t) gpio_get_pin_level(self->pin_b); + + claim_pin(pin_a); + claim_pin(pin_b); + + set_eic_handler(self->eic_channel_a, EIC_HANDLER_INCREMENTAL_ENCODER); + turn_on_eic_channel(self->eic_channel_a, EIC_CONFIG_SENSE0_BOTH_Val); + + set_eic_handler(self->eic_channel_b, EIC_HANDLER_INCREMENTAL_ENCODER); + turn_on_eic_channel(self->eic_channel_b, EIC_CONFIG_SENSE0_BOTH_Val); +} + +bool common_hal_rotaryio_incrementalencoder_deinited(rotaryio_incrementalencoder_obj_t* self) { + return self->pin_a == NO_PIN; +} + +void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_obj_t* self) { + if (common_hal_rotaryio_incrementalencoder_deinited(self)) { + return; + } + + set_eic_handler(self->eic_channel_a, EIC_HANDLER_NO_INTERRUPT); + turn_off_eic_channel(self->eic_channel_a); + + set_eic_handler(self->eic_channel_b, EIC_HANDLER_NO_INTERRUPT); + turn_off_eic_channel(self->eic_channel_b); + + reset_pin_number(self->pin_a); + self->pin_a = NO_PIN; + + reset_pin_number(self->pin_b); + self->pin_b = NO_PIN; +} + +mp_int_t common_hal_rotaryio_incrementalencoder_get_position(rotaryio_incrementalencoder_obj_t* self) { + return self->position; +} + +void common_hal_rotaryio_incrementalencoder_set_position(rotaryio_incrementalencoder_obj_t* self, + mp_int_t new_position) { + self->position = new_position; +} + +void incrementalencoder_interrupt_handler(uint8_t channel) { + rotaryio_incrementalencoder_obj_t* self = get_eic_channel_data(channel); + + // This table also works for detent both at 11 and 00 + // For 11 at detent: + // Turning cw: 11->01->00->10->11 + // Turning ccw: 11->10->00->01->11 + // For 00 at detent: + // Turning cw: 00->10->11->10->00 + // Turning ccw: 00->01->11->10->00 + + // index table by state + #define BAD 7 + static const int8_t transitions[16] = { + 0, // 00 -> 00 no movement + -1, // 00 -> 01 3/4 ccw (11 detent) or 1/4 ccw (00 at detent) + +1, // 00 -> 10 3/4 cw or 1/4 cw + BAD, // 00 -> 11 non-Gray-code transition + +1, // 01 -> 00 2/4 or 4/4 cw + 0, // 01 -> 01 no movement + BAD, // 01 -> 10 non-Gray-code transition + -1, // 01 -> 11 4/4 or 2/4 ccw + -1, // 10 -> 00 2/4 or 4/4 ccw + BAD, // 10 -> 01 non-Gray-code transition + 0, // 10 -> 10 no movement + +1, // 10 -> 11 4/4 or 2/4 cw + BAD, // 11 -> 00 non-Gray-code transition + +1, // 11 -> 01 1/4 or 3/4 cw + -1, // 11 -> 10 1/4 or 3/4 ccw + 0, // 11 -> 11 no movement + }; + + // Shift the old AB bits to the "old" position, and set the new AB bits. + // TODO(tannewt): If we need more speed then read the pin directly. gpio_get_pin_level has + // smarts to compensate for pin direction we don't need. + self->last_state = (self->last_state & 0x3) << 2 | + ((uint8_t) gpio_get_pin_level(self->pin_a) << 1) | + (uint8_t) gpio_get_pin_level(self->pin_b); + + int8_t quarter_incr = transitions[self->last_state]; + if (quarter_incr == BAD) { + // Missed a transition. We don't know which way we're going, so do nothing. + return; + } + + self->quarter_count += quarter_incr; + if (self->quarter_count >= 4) { + self->position += 1; + self->quarter_count = 0; + } else if (self->quarter_count <= -4) { + self->position -= 1; + self->quarter_count = 0; + } +} diff --git a/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.h b/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.h new file mode 100644 index 00000000000..e07cc84d5da --- /dev/null +++ b/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.h @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ROTARYIO_INCREMENTALENCODER_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ROTARYIO_INCREMENTALENCODER_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint8_t pin_a; + uint8_t pin_b; + uint8_t eic_channel_a:4; + uint8_t eic_channel_b:4; + uint8_t last_state:4; // + int8_t quarter_count:4; // count intermediate transitions between detents + mp_int_t position; +} rotaryio_incrementalencoder_obj_t; + + +void incrementalencoder_interrupt_handler(uint8_t channel); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ROTARYIO_INCREMENTALENCODER_H diff --git a/ports/atmel-samd/common-hal/rotaryio/__init__.c b/ports/atmel-samd/common-hal/rotaryio/__init__.c new file mode 100644 index 00000000000..0aae79c26a1 --- /dev/null +++ b/ports/atmel-samd/common-hal/rotaryio/__init__.c @@ -0,0 +1 @@ +// No rotaryio module functions. diff --git a/ports/atmel-samd/common-hal/rtc/RTC.c b/ports/atmel-samd/common-hal/rtc/RTC.c new file mode 100644 index 00000000000..4c888418b6a --- /dev/null +++ b/ports/atmel-samd/common-hal/rtc/RTC.c @@ -0,0 +1,105 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * 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 + +#include +#include +#include +#include +#include + +#include "py/obj.h" +#include "py/runtime.h" +#include "lib/timeutils/timeutils.h" +#include "shared-bindings/rtc/__init__.h" +#include "supervisor/shared/translate.h" + +static struct calendar_descriptor calendar; + +void rtc_init(void) { +#ifdef SAMD21 + _gclk_enable_channel(RTC_GCLK_ID, CONF_GCLK_RTC_SRC); +#endif +#ifdef SAMD51 + hri_mclk_set_APBAMASK_RTC_bit(MCLK); +#endif + calendar_init(&calendar, RTC); + calendar_set_baseyear(&calendar, 2000); + calendar_enable(&calendar); +} + +void common_hal_rtc_get_time(timeutils_struct_time_t *tm) { + struct calendar_date_time datetime; + calendar_get_date_time(&calendar, &datetime); + + tm->tm_year = datetime.date.year; + tm->tm_mon = datetime.date.month; + tm->tm_mday = datetime.date.day; + tm->tm_hour = datetime.time.hour; + tm->tm_min = datetime.time.min; + tm->tm_sec = datetime.time.sec; +} + +void common_hal_rtc_set_time(timeutils_struct_time_t *tm) { + // Reset prescaler to increase initial precision. Otherwise we can be up to 1 second off already. + uint32_t freqcorr = hri_rtcmode0_read_FREQCORR_reg(calendar.device.hw); + calendar_deinit(&calendar); + rtc_init(); + hri_rtcmode0_write_FREQCORR_reg(calendar.device.hw, freqcorr); + + struct calendar_date date = { + .year = tm->tm_year, + .month = tm->tm_mon, + .day = tm->tm_mday, + }; + calendar_set_date(&calendar, &date); + + struct calendar_time time = { + .hour = tm->tm_hour, + .min = tm->tm_min, + .sec = tm->tm_sec, + }; + calendar_set_time(&calendar, &time); +} + +// A positive value speeds up the clock by removing clock cycles. +int common_hal_rtc_get_calibration(void) { + int calibration = hri_rtcmode0_read_FREQCORR_VALUE_bf(calendar.device.hw); + + if (!hri_rtcmode0_get_FREQCORR_SIGN_bit(calendar.device.hw)) + calibration = -calibration; + + return calibration; +} + +void common_hal_rtc_set_calibration(int calibration) { + if (calibration > 127 || calibration < -127) + mp_raise_ValueError(translate("calibration value out of range +/-127")); + + hri_rtcmode0_write_FREQCORR_SIGN_bit(calendar.device.hw, calibration < 0 ? 0 : 1); + hri_rtcmode0_write_FREQCORR_VALUE_bf(calendar.device.hw, abs(calibration)); +} diff --git a/ports/atmel-samd/common-hal/rtc/RTC.h b/ports/atmel-samd/common-hal/rtc/RTC.h new file mode 100644 index 00000000000..1d63b2deac2 --- /dev/null +++ b/ports/atmel-samd/common-hal/rtc/RTC.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RTC_RTC_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RTC_RTC_H + +extern void rtc_init(void); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RTC_RTC_H diff --git a/docs/sphinx_selective_exclude/__init__.py b/ports/atmel-samd/common-hal/rtc/__init__.c similarity index 100% rename from docs/sphinx_selective_exclude/__init__.py rename to ports/atmel-samd/common-hal/rtc/__init__.c diff --git a/ports/atmel-samd/common-hal/supervisor/Runtime.c b/ports/atmel-samd/common-hal/supervisor/Runtime.c new file mode 100755 index 00000000000..6be38f216ac --- /dev/null +++ b/ports/atmel-samd/common-hal/supervisor/Runtime.c @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Michael Schroeder + * + * 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 +#include "shared-bindings/supervisor/Runtime.h" +#include "supervisor/serial.h" + +bool common_hal_get_serial_connected(void) { + return (bool) serial_connected(); +} + +bool common_hal_get_serial_bytes_available(void) { + return (bool) serial_bytes_available(); +} diff --git a/ports/atmel-samd/common-hal/supervisor/Runtime.h b/ports/atmel-samd/common-hal/supervisor/Runtime.h new file mode 100755 index 00000000000..f3d76d1b680 --- /dev/null +++ b/ports/atmel-samd/common-hal/supervisor/Runtime.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Michael Schroeder + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_SUPERVISOR_RUNTIME_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_SUPERVISOR_RUNTIME_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + // Stores no state currently. +} super_runtime_obj_t; + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_SUPERVISOR_RUNTIME_H diff --git a/ports/atmel-samd/common-hal/supervisor/__init__.c b/ports/atmel-samd/common-hal/supervisor/__init__.c new file mode 100755 index 00000000000..ac88556b45d --- /dev/null +++ b/ports/atmel-samd/common-hal/supervisor/__init__.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Michael Schroeder + * + * 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 "py/obj.h" + +#include "shared-bindings/supervisor/__init__.h" +#include "shared-bindings/supervisor/Runtime.h" + + +// The singleton supervisor.Runtime object, bound to supervisor.runtime +// It currently only has properties, and no state. +const super_runtime_obj_t common_hal_supervisor_runtime_obj = { + .base = { + .type = &supervisor_runtime_type, + }, +}; \ No newline at end of file diff --git a/ports/atmel-samd/common-hal/time/__init__.c b/ports/atmel-samd/common-hal/time/__init__.c new file mode 100644 index 00000000000..0d60adef20c --- /dev/null +++ b/ports/atmel-samd/common-hal/time/__init__.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "py/mphal.h" + +#include "shared-bindings/time/__init__.h" + +#include "tick.h" + +inline uint64_t common_hal_time_monotonic() { + return ticks_ms; +} + +void common_hal_time_delay_ms(uint32_t delay) { + mp_hal_delay_ms(delay); +} diff --git a/ports/atmel-samd/common-hal/touchio/TouchIn.c b/ports/atmel-samd/common-hal/touchio/TouchIn.c new file mode 100644 index 00000000000..908d8d72285 --- /dev/null +++ b/ports/atmel-samd/common-hal/touchio/TouchIn.c @@ -0,0 +1,142 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "py/nlr.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "py/binary.h" +#include "py/mphal.h" +#include "shared-bindings/touchio/TouchIn.h" +#include "supervisor/shared/translate.h" + +// Native touchio only exists for SAMD21 +#ifdef SAMD21 + +#include "hpl/pm/hpl_pm_base.h" + +#include "samd/clocks.h" +#include "samd/pins.h" + +#include "tick.h" +#include "adafruit_ptc.h" + +bool touch_enabled = false; + +static uint16_t get_raw_reading(touchio_touchin_obj_t *self) { + adafruit_ptc_start_conversion(PTC, &self->config); + + while (!adafruit_ptc_is_conversion_finished(PTC)) { + // wait + RUN_BACKGROUND_TASKS; + } + + return adafruit_ptc_get_conversion_result(PTC); +} + +void common_hal_touchio_touchin_construct(touchio_touchin_obj_t* self, + const mcu_pin_obj_t *pin) { + if (!pin->has_touch) { + mp_raise_ValueError(translate("Invalid pin")); + } + claim_pin(pin); + + // Turn on the PTC if its not in use. We won't turn it off until reset. + if ((( Ptc *) PTC)->CTRLA.bit.ENABLE == 0) { + // We run the PTC at 8mhz so divide the 48mhz clock by 6. + uint8_t gclk = find_free_gclk(6); + if (gclk > GCLK_GEN_NUM) { + mp_raise_RuntimeError(translate("No free GCLKs")); + } + enable_clock_generator(gclk, CLOCK_48MHZ, 6); + + /* Setup and enable generic clock source for PTC module. */ + connect_gclk_to_peripheral(gclk, PTC_GCLK_ID); + + _pm_enable_bus_clock(PM_BUS_APBC, PTC); + } + + adafruit_ptc_get_config_default(&self->config); + self->config.pin = pin->number; + self->config.yline = pin->touch_y_line; + + adafruit_ptc_init(PTC, &self->config); + + // Initial values for pins will vary, depending on what peripherals the pins + // share on-chip. + // + // Set a "touched" threshold not too far above the initial value. + // For simple finger touch, the values may vary as much as a factor of two, + // but for touches using fruit or other objects, the difference is much less. + + self->threshold = get_raw_reading(self) + 100; +} + +bool common_hal_touchio_touchin_deinited(touchio_touchin_obj_t* self) { + return self->config.pin == NO_PIN; +} + +void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t* self) { + // TODO(tannewt): Reset the PTC. + if (common_hal_touchio_touchin_deinited(self)) { + return; + } + // We leave the clocks running because they may be in use by others. + + reset_pin_number(self->config.pin); + self->config.pin = NO_PIN; +} + +void touchin_reset() { + Ptc* ptc = ((Ptc *) PTC); + if (ptc->CTRLA.bit.ENABLE == 1) { + ptc->CTRLA.bit.ENABLE = 0; + while (ptc->CTRLA.bit.ENABLE == 1) {} + + ptc->CTRLA.bit.SWRESET = 1; + while (ptc->CTRLA.bit.SWRESET == 1) {} + } +} + +bool common_hal_touchio_touchin_get_value(touchio_touchin_obj_t *self) { + uint16_t reading = get_raw_reading(self); + return reading > self->threshold; +} + +uint16_t common_hal_touchio_touchin_get_raw_value(touchio_touchin_obj_t *self) { + return get_raw_reading(self); +} + +uint16_t common_hal_touchio_touchin_get_threshold(touchio_touchin_obj_t *self) { + return self->threshold; +} + +void common_hal_touchio_touchin_set_threshold(touchio_touchin_obj_t *self, uint16_t new_threshold) { + self->threshold = new_threshold; +} + +#endif // SAMD21 diff --git a/ports/atmel-samd/common-hal/touchio/TouchIn.h b/ports/atmel-samd/common-hal/touchio/TouchIn.h new file mode 100644 index 00000000000..85550b8a3a2 --- /dev/null +++ b/ports/atmel-samd/common-hal/touchio/TouchIn.h @@ -0,0 +1,50 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_TOUCHIO_TOUCHIN_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_TOUCHIO_TOUCHIN_H + +// Native touchio only exists for SAMD21 +#ifdef SAMD21 + +#include "common-hal/microcontroller/Pin.h" + +#include "samd21_ptc_component.h" +#include "adafruit_ptc.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + struct adafruit_ptc_config config; + uint16_t threshold; +} touchio_touchin_obj_t; + +void touchin_reset(void); + +#endif // SAMD21 + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_TOUCHIO_TOUCHIN_H diff --git a/ports/atmel-samd/common-hal/touchio/__init__.c b/ports/atmel-samd/common-hal/touchio/__init__.c new file mode 100644 index 00000000000..d2290447c95 --- /dev/null +++ b/ports/atmel-samd/common-hal/touchio/__init__.c @@ -0,0 +1 @@ +// No touchio module functions. diff --git a/ports/atmel-samd/eic_handler.c b/ports/atmel-samd/eic_handler.c new file mode 100644 index 00000000000..30ecaa7cae2 --- /dev/null +++ b/ports/atmel-samd/eic_handler.c @@ -0,0 +1,65 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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 "common-hal/pulseio/PulseIn.h" +#include "common-hal/ps2io/Ps2.h" +#include "common-hal/rotaryio/IncrementalEncoder.h" +#include "shared-bindings/microcontroller/__init__.h" +//#include "samd/external_interrupts.h" +#include "eic_handler.h" + +// Which handler should be called for a particular channel? +static uint8_t eic_channel_handler[EIC_EXTINT_NUM]; + +void set_eic_handler(uint8_t channel, uint8_t eic_handler) { + eic_channel_handler[channel] = eic_handler; +} + +void shared_eic_handler(uint8_t channel) { + uint8_t handler = eic_channel_handler[channel]; + switch (handler) { +#if CIRCUITPY_PULSEIO + case EIC_HANDLER_PULSEIN: + pulsein_interrupt_handler(channel); + break; +#endif + +#if CIRCUITPY_PS2IO + case EIC_HANDLER_PS2: + ps2_interrupt_handler(channel); + break; +#endif + +#if CIRCUITPY_ROTARYIO + case EIC_HANDLER_INCREMENTAL_ENCODER: + incrementalencoder_interrupt_handler(channel); + break; +#endif + + default: + break; + } +} diff --git a/ports/atmel-samd/eic_handler.h b/ports/atmel-samd/eic_handler.h new file mode 100644 index 00000000000..71b0fce678b --- /dev/null +++ b/ports/atmel-samd/eic_handler.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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. + */ +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_EIC_HANDLER_H +#define MICROPY_INCLUDED_ATMEL_SAMD_EIC_HANDLER_H + +#define EIC_HANDLER_NO_INTERRUPT 0x0 +#define EIC_HANDLER_PULSEIN 0x1 +#define EIC_HANDLER_INCREMENTAL_ENCODER 0x2 +#define EIC_HANDLER_PS2 0x3 + +void set_eic_handler(uint8_t channel, uint8_t eic_handler); +void shared_eic_handler(uint8_t channel); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_EIC_HANDLER_H diff --git a/ports/atmel-samd/fatfs_port.c b/ports/atmel-samd/fatfs_port.c new file mode 100644 index 00000000000..c4ce18c2a7f --- /dev/null +++ b/ports/atmel-samd/fatfs_port.c @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython 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 "py/mphal.h" +#include "py/runtime.h" +#include "lib/oofatfs/ff.h" /* FatFs lower layer API */ +#include "lib/oofatfs/diskio.h" /* FatFs lower layer API */ +#include "lib/timeutils/timeutils.h" + +#if CIRCUITPY_RTC +#include "shared-bindings/rtc/RTC.h" +#endif + +DWORD get_fattime(void) { +#if CIRCUITPY_RTC + timeutils_struct_time_t tm; + common_hal_rtc_get_time(&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); +#else + return ((2016 - 1980) << 25) | ((9) << 21) | ((1) << 16) | ((16) << 11) | ((43) << 5) | (35 / 2); +#endif + + +} diff --git a/ports/atmel-samd/freetouch b/ports/atmel-samd/freetouch new file mode 160000 index 00000000000..b6859a349ef --- /dev/null +++ b/ports/atmel-samd/freetouch @@ -0,0 +1 @@ +Subproject commit b6859a349efb79e2008d6f6a34e406e93a8e19c0 diff --git a/ports/atmel-samd/modules/frozentest.py b/ports/atmel-samd/modules/frozentest.py new file mode 100644 index 00000000000..0f99b74297f --- /dev/null +++ b/ports/atmel-samd/modules/frozentest.py @@ -0,0 +1,7 @@ +print('uPy') +print('a long string that is not interned') +print('a string that has unicode αβγ chars') +print(b'bytes 1234\x01') +print(123456789) +for i in range(4): + print(i) diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h new file mode 100644 index 00000000000..4e15a6c308c --- /dev/null +++ b/ports/atmel-samd/mpconfigport.h @@ -0,0 +1,85 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef __INCLUDED_MPCONFIGPORT_H +#define __INCLUDED_MPCONFIGPORT_H + +// Definitions for which SAMD chip we're using. +#include "include/sam.h" + +#ifdef SAMD21 +#define CIRCUITPY_MCU_FAMILY samd21 +#define MICROPY_PY_SYS_PLATFORM "Atmel SAMD21" +#define SPI_FLASH_MAX_BAUDRATE 8000000 +#define CIRCUITPY_DEFAULT_STACK_SIZE 4096 +#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0) +#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (0) +#define MICROPY_PY_FUNCTION_ATTRS (0) +// MICROPY_PY_UJSON depends on MICROPY_PY_IO +#define MICROPY_PY_IO (0) +#define MICROPY_PY_UJSON (0) +#define MICROPY_PY_REVERSE_SPECIAL_METHODS (0) +#define MICROPY_PY_UERRNO_LIST \ + X(EPERM) \ + X(ENOENT) \ + X(EIO) \ + X(EAGAIN) \ + X(ENOMEM) \ + X(EACCES) \ + X(EEXIST) \ + X(ENODEV) \ + X(EISDIR) \ + X(EINVAL) \ + +#endif + +#ifdef SAMD51 +#define CIRCUITPY_MCU_FAMILY samd51 +#define MICROPY_PY_SYS_PLATFORM "MicroChip SAMD51" +#define SPI_FLASH_MAX_BAUDRATE 24000000 +// 24kiB stack +#define CIRCUITPY_DEFAULT_STACK_SIZE 0x6000 +#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) +#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1) +#define MICROPY_PY_FUNCTION_ATTRS (1) +#define MICROPY_PY_IO (1) +#define MICROPY_PY_UJSON (1) +#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) +// MICROPY_PY_UERRNO_LIST - Use the default +#endif + +// Turning off audioio, audiobusio, and touchio as necessary +// due to limitations of chips is handled in mpconfigboard.mk + +#include "peripherals/samd/dma.h" + +#include "py/circuitpy_mpconfig.h" + +#define MICROPY_PORT_ROOT_POINTERS \ + CIRCUITPY_COMMON_ROOT_POINTERS \ + mp_obj_t playing_audio[AUDIO_DMA_CHANNEL_COUNT]; + +#endif // __INCLUDED_MPCONFIGPORT_H diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk new file mode 100644 index 00000000000..af33edb0eba --- /dev/null +++ b/ports/atmel-samd/mpconfigport.mk @@ -0,0 +1,32 @@ +# Define an equivalent for MICROPY_LONGINT_IMPL, to pass to $(MPY-TOOL) in py/mkrules.mk +# $(MPY-TOOL) needs to know what kind of longint to use (if any) to freeze long integers. +# This should correspond to the MICROPY_LONGINT_IMPL definition in mpconfigport.h. + +ifeq ($(LONGINT_IMPL),NONE) +MPY_TOOL_LONGINT_IMPL = -mlongint-impl=none +endif + +ifeq ($(LONGINT_IMPL),MPZ) +MPY_TOOL_LONGINT_IMPL = -mlongint-impl=mpz +endif + +ifeq ($(LONGINT_IMPL),LONGLONG) +MPY_TOOL_LONGINT_IMPL = -mlongint-impl=longlong +endif + +# Put samd21-only choices here. +ifeq ($(CHIP_FAMILY),samd21) +# frequencyio not yet verified as working on SAMD21. +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_TOUCHIO_USE_NATIVE = 1 +endif + +# Put samd51-only choices here. +ifeq ($(CHIP_FAMILY),samd51) +CIRCUITPY_SAMD = 1 +CIRCUITPY_TOUCHIO_USE_NATIVE = 0 +endif + +INTERNAL_LIBM = 1 + +USB_SERIAL_NUMBER_LENGTH = 32 diff --git a/ports/atmel-samd/mphalport.c b/ports/atmel-samd/mphalport.c new file mode 100644 index 00000000000..957bf6073e0 --- /dev/null +++ b/ports/atmel-samd/mphalport.c @@ -0,0 +1,92 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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 + +#include "lib/mp-readline/readline.h" +#include "lib/utils/interrupt_char.h" +#include "py/mphal.h" +#include "py/mpstate.h" +#include "py/runtime.h" +#include "py/smallint.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/time/__init__.h" +#include "supervisor/shared/autoreload.h" + +#include "hal/include/hal_atomic.h" +#include "hal/include/hal_delay.h" +#include "hal/include/hal_gpio.h" +#include "hal/include/hal_sleep.h" +#include "sam.h" + +#include "mpconfigboard.h" +#include "mphalport.h" +#include "reset.h" +#include "tick.h" + +extern uint32_t common_hal_mcu_processor_get_frequency(void); + +void mp_hal_delay_ms(mp_uint_t delay) { + uint64_t start_tick = ticks_ms; + uint64_t duration = 0; + while (duration < delay) { + RUN_BACKGROUND_TASKS; + // Check to see if we've been CTRL-Ced by autoreload or the user. + if(MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) || + MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { + break; + } + duration = (ticks_ms - start_tick); + // TODO(tannewt): Go to sleep for a little while while we wait. + } +} + +// Use mp_hal_delay_us() for timing of less than 1ms. +// Do a simple timing loop to wait for a certain number of microseconds. +// Can be used when interrupts are disabled, which makes tick_delay() unreliable. +// +// Testing done at 48 MHz on SAMD21 and 120 MHz on SAMD51, multiplication and division cancel out. +// But get the frequency just in case. +#ifdef SAMD21 +#define DELAY_LOOP_ITERATIONS_PER_US ( (10U*48000000U) / common_hal_mcu_processor_get_frequency()) +#endif +#ifdef SAMD51 +#define DELAY_LOOP_ITERATIONS_PER_US ( (30U*120000000U) / common_hal_mcu_processor_get_frequency()) +#endif + +void mp_hal_delay_us(mp_uint_t delay) { + for (uint32_t i = delay*DELAY_LOOP_ITERATIONS_PER_US; i > 0; i--) { + asm volatile("nop"); + } +} + +void mp_hal_disable_all_interrupts(void) { + common_hal_mcu_disable_interrupts(); +} + +void mp_hal_enable_all_interrupts(void) { + common_hal_mcu_enable_interrupts(); +} diff --git a/ports/atmel-samd/mphalport.h b/ports/atmel-samd/mphalport.h new file mode 100644 index 00000000000..64269b201f4 --- /dev/null +++ b/ports/atmel-samd/mphalport.h @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_MPHALPORT_H +#define MICROPY_INCLUDED_ATMEL_SAMD_MPHALPORT_H + +#include "py/obj.h" + +#include "lib/oofatfs/ff.h" + +// Global millisecond tick count (driven by SysTick interrupt). +extern volatile uint64_t ticks_ms; + +static inline mp_uint_t mp_hal_ticks_ms(void) { + return ticks_ms; +} +// Number of bytes in receive buffer +volatile uint8_t usb_rx_count; +volatile bool mp_cdc_enabled; + +int receive_usb(void); + +void mp_hal_set_interrupt_char(int c); + +void mp_hal_disable_all_interrupts(void); +void mp_hal_enable_all_interrupts(void); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_MPHALPORT_H diff --git a/ports/atmel-samd/peripherals b/ports/atmel-samd/peripherals new file mode 160000 index 00000000000..83a4759d186 --- /dev/null +++ b/ports/atmel-samd/peripherals @@ -0,0 +1 @@ +Subproject commit 83a4759d186574d8034435cd2303def85e4ed793 diff --git a/ports/atmel-samd/qstrdefsport.h b/ports/atmel-samd/qstrdefsport.h new file mode 100644 index 00000000000..3ba897069bf --- /dev/null +++ b/ports/atmel-samd/qstrdefsport.h @@ -0,0 +1 @@ +// qstrs specific to this port diff --git a/ports/atmel-samd/reset.c b/ports/atmel-samd/reset.c new file mode 100644 index 00000000000..735639cc4d7 --- /dev/null +++ b/ports/atmel-samd/reset.c @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "include/sam.h" + +#include "reset.h" +#include "supervisor/filesystem.h" + +void reset(void) { + filesystem_flush(); + NVIC_SystemReset(); +} + + +extern uint32_t _srelocate; +bool bootloader_available(void) { + return &_bootloader_dbl_tap >= &_srelocate; +} diff --git a/ports/atmel-samd/reset.h b/ports/atmel-samd/reset.h new file mode 100644 index 00000000000..b589d261115 --- /dev/null +++ b/ports/atmel-samd/reset.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_RESET_H +#define MICROPY_INCLUDED_ATMEL_SAMD_RESET_H + +#include +#include + +// Copied from inc/uf2.h in https://github.com/Microsoft/uf2-samd21 +#define DBL_TAP_MAGIC 0xf01669ef // Randomly selected, adjusted to have first and last bit set +#define DBL_TAP_MAGIC_QUICK_BOOT 0xf02669ef + +extern uint32_t _bootloader_dbl_tap; + +void reset_to_bootloader(void); +void reset(void); +bool bootloader_available(void); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_RESET_H diff --git a/ports/atmel-samd/samd_peripherals_config.h b/ports/atmel-samd/samd_peripherals_config.h new file mode 100644 index 00000000000..37df7b19a84 --- /dev/null +++ b/ports/atmel-samd/samd_peripherals_config.h @@ -0,0 +1,38 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SAMD_PERIPHERALS_CONFIG_H +#define MICROPY_INCLUDED_ATMEL_SAMD_SAMD_PERIPHERALS_CONFIG_H + +#include "py/obj.h" + +extern const mp_obj_type_t mcu_pin_type; + +#define PIN_PREFIX_VALUES { &mcu_pin_type }, +#define PIN_PREFIX_FIELDS mp_obj_base_t base; + + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_SAMD_PERIPHERALS_CONFIG_H diff --git a/ports/atmel-samd/supervisor/internal_flash.c b/ports/atmel-samd/supervisor/internal_flash.c new file mode 100644 index 00000000000..6dd5ac0a70c --- /dev/null +++ b/ports/atmel-samd/supervisor/internal_flash.c @@ -0,0 +1,152 @@ +/* + * This file is part of the MicroPython 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 "supervisor/internal_flash.h" + +#include +#include + +#include "extmod/vfs.h" +#include "extmod/vfs_fat.h" +#include "py/mphal.h" +#include "py/obj.h" +#include "py/runtime.h" +#include "lib/oofatfs/ff.h" + +#ifdef SAMD21 +#include "hpl/pm/hpl_pm_base.h" +#endif +#include "hal/include/hal_flash.h" + +#include "supervisor/shared/rgb_led_status.h" + +static struct flash_descriptor supervisor_flash_desc; + +void supervisor_flash_init(void) { + // Activity LED for flash writes. + #ifdef MICROPY_HW_LED_MSC + struct port_config pin_conf; + port_get_config_defaults(&pin_conf); + + pin_conf.direction = PORT_PIN_DIR_OUTPUT; + port_pin_set_config(MICROPY_HW_LED_MSC, &pin_conf); + port_pin_set_output_level(MICROPY_HW_LED_MSC, false); + #endif + + #ifdef SAMD51 + hri_mclk_set_AHBMASK_NVMCTRL_bit(MCLK); + #endif + #ifdef SAMD21 + _pm_enable_bus_clock(PM_BUS_APBB, NVMCTRL); + #endif + flash_init(&supervisor_flash_desc, NVMCTRL); +} + +uint32_t supervisor_flash_get_block_size(void) { + return FILESYSTEM_BLOCK_SIZE; +} + +uint32_t supervisor_flash_get_block_count(void) { + return INTERNAL_FLASH_PART1_NUM_BLOCKS; +} + +void supervisor_flash_flush(void) { +} + +void supervisor_flash_release_cache(void) { +} + +void flash_flush(void) { + supervisor_flash_flush(); +} + +static int32_t convert_block_to_flash_addr(uint32_t block) { + if (0 <= block && block < INTERNAL_FLASH_PART1_NUM_BLOCKS) { + // a block in partition 1 + return INTERNAL_FLASH_MEM_SEG1_START_ADDR + block * FILESYSTEM_BLOCK_SIZE; + } + // bad block + return -1; +} + +bool supervisor_flash_read_block(uint8_t *dest, uint32_t block) { + // non-MBR block, get data from flash memory + int32_t src = convert_block_to_flash_addr(block); + if (src == -1) { + // bad block number + return false; + } + int32_t error_code = flash_read(&supervisor_flash_desc, src, dest, FILESYSTEM_BLOCK_SIZE); + return error_code == ERR_NONE; +} + +bool supervisor_flash_write_block(const uint8_t *src, uint32_t block) { + #ifdef MICROPY_HW_LED_MSC + port_pin_set_output_level(MICROPY_HW_LED_MSC, true); + #endif + temp_status_color(ACTIVE_WRITE); + // non-MBR block, copy to cache + int32_t dest = convert_block_to_flash_addr(block); + if (dest == -1) { + // bad block number + return false; + } + int32_t error_code; + error_code = flash_erase(&supervisor_flash_desc, + dest, + FILESYSTEM_BLOCK_SIZE / flash_get_page_size(&supervisor_flash_desc)); + if (error_code != ERR_NONE) { + return false; + } + + error_code = flash_append(&supervisor_flash_desc, dest, src, FILESYSTEM_BLOCK_SIZE); + if (error_code != ERR_NONE) { + return false; + } + clear_temp_status(); + #ifdef MICROPY_HW_LED_MSC + port_pin_set_output_level(MICROPY_HW_LED_MSC, false); + #endif + return true; +} + +mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) { + for (size_t i = 0; i < num_blocks; i++) { + if (!supervisor_flash_read_block(dest + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) { + return 1; // error + } + } + return 0; // success +} + +mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) { + for (size_t i = 0; i < num_blocks; i++) { + if (!supervisor_flash_write_block(src + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) { + return 1; // error + } + } + return 0; // success +} diff --git a/ports/atmel-samd/supervisor/internal_flash.h b/ports/atmel-samd/supervisor/internal_flash.h new file mode 100644 index 00000000000..0939a345480 --- /dev/null +++ b/ports/atmel-samd/supervisor/internal_flash.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython 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. + */ +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_H +#define MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_H + +#include + +#include "mpconfigport.h" + +#include "sam.h" + +#ifdef SAMD51 +#define TOTAL_INTERNAL_FLASH_SIZE (FLASH_SIZE / 2) +#endif + +#ifdef SAMD21 +#define TOTAL_INTERNAL_FLASH_SIZE 0x010000 +#endif + +#define INTERNAL_FLASH_MEM_SEG1_START_ADDR (FLASH_SIZE - TOTAL_INTERNAL_FLASH_SIZE - CIRCUITPY_INTERNAL_NVM_SIZE) +#define INTERNAL_FLASH_PART1_NUM_BLOCKS (TOTAL_INTERNAL_FLASH_SIZE / FILESYSTEM_BLOCK_SIZE) + +#define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms +#define INTERNAL_FLASH_IDLE_TICK(tick) (((tick) & INTERNAL_FLASH_SYSTICK_MASK) == 2) + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_H diff --git a/ports/atmel-samd/supervisor/internal_flash_root_pointers.h b/ports/atmel-samd/supervisor/internal_flash_root_pointers.h new file mode 100644 index 00000000000..3e9148ce0aa --- /dev/null +++ b/ports/atmel-samd/supervisor/internal_flash_root_pointers.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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. + */ +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_ROOT_POINTERS_H +#define MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_ROOT_POINTERS_H + +#define FLASH_ROOT_POINTERS + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_ROOT_POINTERS_H diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c new file mode 100644 index 00000000000..512fd8eb8d6 --- /dev/null +++ b/ports/atmel-samd/supervisor/port.c @@ -0,0 +1,305 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "supervisor/port.h" + +// ASF 4 +#include "atmel_start_pins.h" +#include "hal/include/hal_delay.h" +#include "hal/include/hal_gpio.h" +#include "hal/include/hal_init.h" +#include "hpl/gclk/hpl_gclk_base.h" +#include "hpl/pm/hpl_pm_base.h" + +#ifdef SAMD21 +#include "hri/hri_pm_d21.h" +#endif +#ifdef SAMD51 +#include "hri/hri_rstc_d51.h" +#endif + +#include "common-hal/analogio/AnalogIn.h" +#include "common-hal/analogio/AnalogOut.h" +#include "common-hal/audiobusio/PDMIn.h" +#include "common-hal/audiobusio/I2SOut.h" +#include "common-hal/audioio/AudioOut.h" +#include "common-hal/busio/SPI.h" +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/pulseio/PulseIn.h" +#include "common-hal/pulseio/PulseOut.h" +#include "common-hal/pulseio/PWMOut.h" +#include "common-hal/ps2io/Ps2.h" +#include "common-hal/rtc/RTC.h" + +#if CIRCUITPY_TOUCHIO_USE_NATIVE +#include "common-hal/touchio/TouchIn.h" +#endif + +#include "samd/cache.h" +#include "samd/clocks.h" +#include "samd/events.h" +#include "samd/external_interrupts.h" +#include "samd/dma.h" +#include "shared-bindings/rtc/__init__.h" +#include "reset.h" +#include "tick.h" + +#include "supervisor/shared/safe_mode.h" +#include "supervisor/shared/stack.h" + +#include "tusb.h" + +#if CIRCUITPY_GAMEPAD +#include "shared-module/gamepad/__init__.h" +#endif +#if CIRCUITPY_GAMEPADSHIFT +#include "shared-module/gamepadshift/__init__.h" +#endif +#include "shared-module/_pew/PewPew.h" + +extern volatile bool mp_msc_enabled; + +#if defined(SAMD21) && defined(ENABLE_MICRO_TRACE_BUFFER) +// Stores 2 ^ TRACE_BUFFER_MAGNITUDE_PACKETS packets. +// 7 -> 128 packets +#define TRACE_BUFFER_MAGNITUDE_PACKETS 7 +// Size in uint32_t. Two per packet. +#define TRACE_BUFFER_SIZE (1 << (TRACE_BUFFER_MAGNITUDE_PACKETS + 1)) +// Size in bytes. 4 bytes per uint32_t. +#define TRACE_BUFFER_SIZE_BYTES (TRACE_BUFFER_SIZE << 2) +__attribute__((__aligned__(TRACE_BUFFER_SIZE_BYTES))) uint32_t mtb[TRACE_BUFFER_SIZE] = {0}; +#endif + +safe_mode_t port_init(void) { +#if defined(SAMD21) + + // Set brownout detection to ~2.7V. Default from factory is 1.7V, + // which is too low for proper operation of external SPI flash chips (they are 2.7-3.6V). + // Disable while changing level. + SYSCTRL->BOD33.bit.ENABLE = 0; + SYSCTRL->BOD33.bit.LEVEL = 39; // 2.77V with hysteresis off. Table 37.20 in datasheet. + SYSCTRL->BOD33.bit.ENABLE = 1; + + #ifdef ENABLE_MICRO_TRACE_BUFFER + REG_MTB_POSITION = ((uint32_t) (mtb - REG_MTB_BASE)) & 0xFFFFFFF8; + REG_MTB_FLOW = (((uint32_t) mtb - REG_MTB_BASE) + TRACE_BUFFER_SIZE_BYTES) & 0xFFFFFFF8; + REG_MTB_MASTER = 0x80000000 + (TRACE_BUFFER_MAGNITUDE_PACKETS - 1); + #else + // Triple check that the MTB is off. Switching between debug and non-debug + // builds can leave it set over reset and wreak havok as a result. + REG_MTB_MASTER = 0x00000000 + 6; + #endif +#endif + +#if defined(SAMD51) + // Set brownout detection to ~2.7V. Default from factory is 1.7V, + // which is too low for proper operation of external SPI flash chips (they are 2.7-3.6V). + // Disable while changing level. + SUPC->BOD33.bit.ENABLE = 0; + SUPC->BOD33.bit.LEVEL = 200; // 2.7V: 1.5V + LEVEL * 6mV. + SUPC->BOD33.bit.ENABLE = 1; + + // MPU (Memory Protection Unit) setup. + // We hoped we could make the QSPI region be non-cachable with the MPU, + // but the CMCC doesn't seem to pay attention to the MPU settings. + // Leaving this code here disabled, + // because it was hard enough to figure out, and maybe there's + // a mistake that could make it work in the future. +#if 0 + // Designate QSPI memory mapped region as not cachable. + + // Turn off MPU in case it is on. + MPU->CTRL = 0; + // Configure region 0. + MPU->RNR = 0; + // Region base: start of QSPI mapping area. + // QSPI region runs from 0x04000000 up to and not including 0x05000000: 16 megabytes + MPU->RBAR = QSPI_AHB; + MPU->RASR = + 0b011 << MPU_RASR_AP_Pos | // full read/write access for privileged and user mode + 0b000 << MPU_RASR_TEX_Pos | // caching not allowed, strongly ordered + 1 << MPU_RASR_S_Pos | // sharable + 0 << MPU_RASR_C_Pos | // not cachable + 0 << MPU_RASR_B_Pos | // not bufferable + 0b10111 << MPU_RASR_SIZE_Pos | // 16MB region size + 1 << MPU_RASR_ENABLE_Pos // enable this region + ; + // Turn off regions 1-7. + for (uint32_t i = 1; i < 8; i ++) { + MPU->RNR = i; + MPU->RBAR = 0; + MPU->RASR = 0; + } + + // Turn on MPU. Turn on PRIVDEFENA, which defines a default memory + // map for all privileged access, so we don't have to set up other regions + // besides QSPI. + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_ENABLE_Msk; +#endif + + samd_peripherals_enable_cache(); +#endif + +#ifdef SAMD21 + hri_nvmctrl_set_CTRLB_RWS_bf(NVMCTRL, 2); + _pm_init(); +#endif + clock_init(); + + // Configure millisecond timer initialization. + tick_init(); + +#if CIRCUITPY_RTC + rtc_init(); +#endif + + init_shared_dma(); + + // Reset everything into a known state before board_init. + reset_port(); + + // Init the board last so everything else is ready + board_init(); + + #ifdef SAMD21 + if (PM->RCAUSE.bit.BOD33 == 1 || PM->RCAUSE.bit.BOD12 == 1) { + return BROWNOUT; + } + #endif + #ifdef SAMD51 + if (RSTC->RCAUSE.bit.BODVDD == 1 || RSTC->RCAUSE.bit.BODCORE == 1) { + return BROWNOUT; + } + #endif + + if (board_requests_safe_mode()) { + return USER_SAFE_MODE; + } + + return NO_SAFE_MODE; +} + +void reset_port(void) { + reset_sercoms(); + +#if CIRCUITPY_AUDIOIO + audio_dma_reset(); + audioout_reset(); +#endif +#if CIRCUITPY_AUDIOBUSIO + i2sout_reset(); + //pdmin_reset(); +#endif + +#if CIRCUITPY_TOUCHIO && CIRCUITPY_TOUCHIO_USE_NATIVE + touchin_reset(); +#endif + eic_reset(); +#if CIRCUITPY_PULSEIO + pulseout_reset(); + pwmout_reset(); +#endif + +#if CIRCUITPY_ANALOGIO + analogin_reset(); + analogout_reset(); +#endif +#if CIRCUITPY_RTC + rtc_reset(); +#endif + + reset_gclks(); + +#if CIRCUITPY_GAMEPAD + gamepad_reset(); +#endif +#if CIRCUITPY_GAMEPADSHIFT + gamepadshift_reset(); +#endif +#if CIRCUITPY_PEW + pew_reset(); +#endif + + reset_event_system(); + + reset_all_pins(); + + // Output clocks for debugging. + // not supported by SAMD51G; uncomment for SAMD51J or update for 51G + // #ifdef SAMD51 + // gpio_set_pin_function(PIN_PA10, GPIO_PIN_FUNCTION_M); // GCLK4, D3 + // gpio_set_pin_function(PIN_PA11, GPIO_PIN_FUNCTION_M); // GCLK5, A4 + // gpio_set_pin_function(PIN_PB14, GPIO_PIN_FUNCTION_M); // GCLK0, D5 + // gpio_set_pin_function(PIN_PB15, GPIO_PIN_FUNCTION_M); // GCLK1, D6 + // #endif + + if (tud_cdc_connected()) { + save_usb_clock_calibration(); + } +} + +void reset_to_bootloader(void) { + _bootloader_dbl_tap = DBL_TAP_MAGIC; + reset(); +} + +void reset_cpu(void) { + reset(); +} + +// Place the word to save 8k from the end of RAM so we and the bootloader don't clobber it. +#ifdef SAMD21 +uint32_t* safe_word = (uint32_t*) (HMCRAMC0_ADDR + HMCRAMC0_SIZE - 0x2000); +#endif +#ifdef SAMD51 +uint32_t* safe_word = (uint32_t*) (HSRAM_ADDR + HSRAM_SIZE - 0x2000); +#endif + +void port_set_saved_word(uint32_t value) { + *safe_word = value; +} + +uint32_t port_get_saved_word(void) { + return *safe_word; +} + +/** + * \brief Default interrupt handler for unused IRQs. + */ +__attribute__((used)) void HardFault_Handler(void) +{ +#ifdef ENABLE_MICRO_TRACE_BUFFER + // Turn off the micro trace buffer so we don't fill it up in the infinite + // loop below. + REG_MTB_MASTER = 0x00000000 + 6; +#endif + + reset_into_safe_mode(HARD_CRASH); + while (true) { + asm("nop;"); + } +} diff --git a/ports/atmel-samd/supervisor/qspi_flash.c b/ports/atmel-samd/supervisor/qspi_flash.c new file mode 100644 index 00000000000..eca47b16484 --- /dev/null +++ b/ports/atmel-samd/supervisor/qspi_flash.c @@ -0,0 +1,232 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016, 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/spi_flash_api.h" + +#include +#include + +#include "mpconfigboard.h" // for EXTERNAL_FLASH_QSPI_DUAL + +#include "supervisor/shared/external_flash/common_commands.h" +#include "supervisor/shared/external_flash/qspi_flash.h" +#include "samd/cache.h" +#include "samd/dma.h" + +#include "atmel_start_pins.h" +#include "hal_gpio.h" + +bool spi_flash_command(uint8_t command) { + QSPI->INSTRCTRL.bit.INSTR = command; + + QSPI->INSTRFRAME.reg = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI | + QSPI_INSTRFRAME_ADDRLEN_24BITS | + QSPI_INSTRFRAME_TFRTYPE_READ | + QSPI_INSTRFRAME_INSTREN; + + QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; + + while( !QSPI->INTFLAG.bit.INSTREND ); + + QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; + + return true; +} + +bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length) { + samd_peripherals_disable_and_clear_cache(); + + QSPI->INSTRCTRL.bit.INSTR = command; + + QSPI->INSTRFRAME.reg = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI | + QSPI_INSTRFRAME_ADDRLEN_24BITS | + QSPI_INSTRFRAME_TFRTYPE_READ | + QSPI_INSTRFRAME_INSTREN | + QSPI_INSTRFRAME_DATAEN; + + // Dummy read of INSTRFRAME needed to synchronize. + // See Instruction Transmission Flow Diagram, figure 37.9, page 995 + // and Example 4, page 998, section 37.6.8.5. + (volatile uint32_t) QSPI->INSTRFRAME.reg; + + memcpy(response, (uint8_t *) QSPI_AHB, length); + + QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; + + while( !QSPI->INTFLAG.bit.INSTREND ); + + QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; + + samd_peripherals_enable_cache(); + + return true; +} + +bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) { + samd_peripherals_disable_and_clear_cache(); + + QSPI->INSTRCTRL.bit.INSTR = command; + + QSPI->INSTRFRAME.reg = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI | + QSPI_INSTRFRAME_ADDRLEN_24BITS | + QSPI_INSTRFRAME_TFRTYPE_WRITE | + QSPI_INSTRFRAME_INSTREN | + (data != NULL ? QSPI_INSTRFRAME_DATAEN : 0); + + // Dummy read of INSTRFRAME needed to synchronize. + // See Instruction Transmission Flow Diagram, figure 37.9, page 995 + // and Example 4, page 998, section 37.6.8.5. + (volatile uint32_t) QSPI->INSTRFRAME.reg; + + if (data != NULL) { + memcpy((uint8_t *) QSPI_AHB, data, length); + } + + QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; + + while( !QSPI->INTFLAG.bit.INSTREND ); + + QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; + + samd_peripherals_enable_cache(); + + return true; +} + +bool spi_flash_sector_command(uint8_t command, uint32_t address) { + QSPI->INSTRCTRL.bit.INSTR = command; + QSPI->INSTRADDR.bit.ADDR = address; + + QSPI->INSTRFRAME.reg = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI | + QSPI_INSTRFRAME_ADDRLEN_24BITS | + QSPI_INSTRFRAME_TFRTYPE_WRITE | + QSPI_INSTRFRAME_INSTREN | + QSPI_INSTRFRAME_ADDREN; + + QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; + + while( !QSPI->INTFLAG.bit.INSTREND ); + + QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; + + return true; +} + +bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) { + samd_peripherals_disable_and_clear_cache(); + + QSPI->INSTRCTRL.bit.INSTR = CMD_PAGE_PROGRAM; + uint32_t mode = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI; + + QSPI->INSTRFRAME.reg = mode | + QSPI_INSTRFRAME_ADDRLEN_24BITS | + QSPI_INSTRFRAME_TFRTYPE_WRITEMEMORY | + QSPI_INSTRFRAME_INSTREN | + QSPI_INSTRFRAME_ADDREN | + QSPI_INSTRFRAME_DATAEN; + + memcpy(((uint8_t *) QSPI_AHB) + address, data, length); + // TODO(tannewt): Fix DMA and enable it. + // qspi_dma_write(address, data, length); + + QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; + + while( !QSPI->INTFLAG.bit.INSTREND ); + + QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; + + samd_peripherals_enable_cache(); + + return true; +} + +bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t length) { + samd_peripherals_disable_and_clear_cache(); + + #ifdef EXTERNAL_FLASH_QSPI_DUAL + QSPI->INSTRCTRL.bit.INSTR = CMD_DUAL_READ; + uint32_t mode = QSPI_INSTRFRAME_WIDTH_DUAL_OUTPUT; + #else + QSPI->INSTRCTRL.bit.INSTR = CMD_QUAD_READ; + uint32_t mode = QSPI_INSTRFRAME_WIDTH_QUAD_OUTPUT; + #endif + + QSPI->INSTRFRAME.reg = mode | + QSPI_INSTRFRAME_ADDRLEN_24BITS | + QSPI_INSTRFRAME_TFRTYPE_READMEMORY | + QSPI_INSTRFRAME_INSTREN | + QSPI_INSTRFRAME_ADDREN | + QSPI_INSTRFRAME_DATAEN | + QSPI_INSTRFRAME_DUMMYLEN(8); + + memcpy(data, ((uint8_t *) QSPI_AHB) + address, length); + // TODO(tannewt): Fix DMA and enable it. + // qspi_dma_read(address, data, length); + + QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER; + + while( !QSPI->INTFLAG.bit.INSTREND ); + + QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND; + + samd_peripherals_enable_cache(); + + return true; +} + + +void spi_flash_init(void) { + MCLK->APBCMASK.bit.QSPI_ = true; + MCLK->AHBMASK.bit.QSPI_ = true; + MCLK->AHBMASK.bit.QSPI_2X_ = false; // Only true if we are doing DDR. + + QSPI->CTRLA.reg = QSPI_CTRLA_SWRST; + // We don't need to wait because we're running as fast as the CPU. + + // Slow, good for debugging with Saleae + // QSPI->BAUD.bit.BAUD = 32; + // Super fast, may be unreliable when Saleae is connected to high speed lines. + QSPI->BAUD.bit.BAUD = 2; + QSPI->CTRLB.reg = QSPI_CTRLB_MODE_MEMORY | // Serial memory mode (map to QSPI_AHB) + QSPI_CTRLB_DATALEN_8BITS | + QSPI_CTRLB_CSMODE_LASTXFER; + + QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE; + + // The QSPI is only connected to one set of pins in the SAMD51 so we can hard code it. + uint32_t pins[6] = {PIN_PA08, PIN_PA09, PIN_PA10, PIN_PA11, PIN_PB10, PIN_PB11}; + for (uint8_t i = 0; i < 6; i++) { + gpio_set_pin_direction(pins[i], GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(pins[i], GPIO_PULL_OFF); + gpio_set_pin_function(pins[i], GPIO_PIN_FUNCTION_H); + } +} + +void spi_flash_init_device(const external_flash_device* device) { + check_quad_enable(device); + + // TODO(tannewt): Adjust the speed for the found device. +} diff --git a/ports/atmel-samd/supervisor/samd21_cpu.s b/ports/atmel-samd/supervisor/samd21_cpu.s new file mode 100755 index 00000000000..741bb21358a --- /dev/null +++ b/ports/atmel-samd/supervisor/samd21_cpu.s @@ -0,0 +1,35 @@ +.syntax unified +.cpu cortex-m0 +.thumb +.text +.align 2 + +@ uint cpu_get_regs_and_sp(r0=uint regs[10]) +.global cpu_get_regs_and_sp +.thumb +.thumb_func +.type cpu_get_regs_and_sp, %function +cpu_get_regs_and_sp: +@ store registers into given array +str r4, [r0, #0] +str r5, [r0, #4] +str r6, [r0, #8] +str r7, [r0, #12] +push {r1} +mov r1, r8 +str r1, [r0, #16] +mov r1, r9 +str r1, [r0, #20] +mov r1, r10 +str r1, [r0, #24] +mov r1, r11 +str r1, [r0, #28] +mov r1, r12 +str r1, [r0, #32] +mov r1, r13 +str r1, [r0, #36] +pop {r1} + +@ return the sp +mov r0, sp +bx lr diff --git a/ports/atmel-samd/supervisor/samd51_cpu.s b/ports/atmel-samd/supervisor/samd51_cpu.s new file mode 100755 index 00000000000..9e6807a5e2e --- /dev/null +++ b/ports/atmel-samd/supervisor/samd51_cpu.s @@ -0,0 +1,27 @@ +.syntax unified +.cpu cortex-m4 +.thumb +.text +.align 2 + +@ uint cpu_get_regs_and_sp(r0=uint regs[10]) +.global cpu_get_regs_and_sp +.thumb +.thumb_func +.type cpu_get_regs_and_sp, %function +cpu_get_regs_and_sp: +@ store registers into given array +str r4, [r0], #4 +str r5, [r0], #4 +str r6, [r0], #4 +str r7, [r0], #4 +str r8, [r0], #4 +str r9, [r0], #4 +str r10, [r0], #4 +str r11, [r0], #4 +str r12, [r0], #4 +str r13, [r0], #4 + +@ return the sp +mov r0, sp +bx lr diff --git a/ports/atmel-samd/supervisor/usb.c b/ports/atmel-samd/supervisor/usb.c new file mode 100644 index 00000000000..d13ca0ef13b --- /dev/null +++ b/ports/atmel-samd/supervisor/usb.c @@ -0,0 +1,59 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "atmel_start_pins.h" +#include "hpl/pm/hpl_pm_base.h" +#include "hpl/gclk/hpl_gclk_base.h" +#include "hal_gpio.h" + +void init_usb_hardware(void) { + #ifdef SAMD21 + _pm_enable_bus_clock(PM_BUS_APBB, USB); + _pm_enable_bus_clock(PM_BUS_AHB, USB); + _gclk_enable_channel(USB_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val); + #endif + + #ifdef SAMD51 + hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | GCLK_PCHCTRL_CHEN); + hri_mclk_set_AHBMASK_USB_bit(MCLK); + hri_mclk_set_APBBMASK_USB_bit(MCLK); + #endif + + gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT); + gpio_set_pin_level(PIN_PA24, false); + gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF); + gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT); + gpio_set_pin_level(PIN_PA25, false); + gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF); + #ifdef SAMD21 + gpio_set_pin_function(PIN_PA24, PINMUX_PA24G_USB_DM); + gpio_set_pin_function(PIN_PA25, PINMUX_PA25G_USB_DP); + #endif + #ifdef SAMD51 + gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM); + gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP); + #endif +} diff --git a/ports/atmel-samd/tick.c b/ports/atmel-samd/tick.c new file mode 100644 index 00000000000..dde473375e4 --- /dev/null +++ b/ports/atmel-samd/tick.c @@ -0,0 +1,129 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "tick.h" + +#include "peripheral_clk_config.h" + +#include "supervisor/shared/autoreload.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Processor.h" + +#if CIRCUITPY_GAMEPAD +#include "shared-module/gamepad/__init__.h" +#endif + +#if CIRCUITPY_GAMEPADSHIFT +#include "shared-module/gamepadshift/__init__.h" +#endif +// Global millisecond tick count +volatile uint64_t ticks_ms = 0; + +void SysTick_Handler(void) { + // SysTick interrupt handler called when the SysTick timer reaches zero + // (every millisecond). + common_hal_mcu_disable_interrupts(); + ticks_ms += 1; + + // Read the control register to reset the COUNTFLAG. + (void) SysTick->CTRL; + common_hal_mcu_enable_interrupts(); + + #ifdef CIRCUITPY_AUTORELOAD_DELAY_MS + autoreload_tick(); + #endif + #ifdef CIRCUITPY_GAMEPAD_TICKS + if (!(ticks_ms & CIRCUITPY_GAMEPAD_TICKS)) { + #if CIRCUITPY_GAMEPAD + gamepad_tick(); + #endif + #if CIRCUITPY_GAMEPADSHIFT + gamepadshift_tick(); + #endif + } + #endif +} + +void tick_init() { + uint32_t ticks_per_ms = common_hal_mcu_processor_get_frequency() / 1000; + SysTick_Config(ticks_per_ms-1); + NVIC_EnableIRQ(SysTick_IRQn); + // Set all peripheral interrupt priorities to the lowest priority by default. + for (uint16_t i = 0; i < PERIPH_COUNT_IRQn; i++) { + NVIC_SetPriority(i, (1UL << __NVIC_PRIO_BITS) - 1UL); + } + // Bump up the systick interrupt so nothing else interferes with timekeeping. + NVIC_SetPriority(SysTick_IRQn, 0); + #ifdef SAMD21 + NVIC_SetPriority(USB_IRQn, 1); + #endif + + #ifdef SAMD51 + NVIC_SetPriority(USB_0_IRQn, 1); + NVIC_SetPriority(USB_1_IRQn, 1); + NVIC_SetPriority(USB_2_IRQn, 1); + NVIC_SetPriority(USB_3_IRQn, 1); + #endif +} + +void tick_delay(uint32_t us) { + uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000; + uint32_t us_until_next_tick = SysTick->VAL / ticks_per_us; + uint32_t start_tick; + while (us >= us_until_next_tick) { + start_tick = SysTick->VAL; // wait for SysTick->VAL to RESET + while (SysTick->VAL < start_tick) {} + us -= us_until_next_tick; + us_until_next_tick = 1000; + } + while (SysTick->VAL > ((us_until_next_tick - us) * ticks_per_us)) {} +} + +// us counts down! +void current_tick(uint64_t* ms, uint32_t* us_until_ms) { + uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000; + + // We disable interrupts to prevent ticks_ms from changing while we grab it. + common_hal_mcu_disable_interrupts(); + uint32_t tick_status = SysTick->CTRL; + uint32_t current_us = SysTick->VAL; + uint32_t tick_status2 = SysTick->CTRL; + uint64_t current_ms = ticks_ms; + // The second clause ensures our value actually rolled over. Its possible it hit zero between + // the VAL read and CTRL read. + if ((tick_status & SysTick_CTRL_COUNTFLAG_Msk) != 0 || + ((tick_status2 & SysTick_CTRL_COUNTFLAG_Msk) != 0 && current_us > ticks_per_us)) { + current_ms++; + } + common_hal_mcu_enable_interrupts(); + *ms = current_ms; + *us_until_ms = current_us / ticks_per_us; +} + +void wait_until(uint64_t ms, uint32_t us_until_ms) { + uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000; + while (ticks_ms <= ms && SysTick->VAL / ticks_per_us >= us_until_ms) {} +} diff --git a/ports/atmel-samd/tick.h b/ports/atmel-samd/tick.h new file mode 100644 index 00000000000..c8c8d739aba --- /dev/null +++ b/ports/atmel-samd/tick.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_TICK_H +#define MICROPY_INCLUDED_ATMEL_SAMD_TICK_H + +#include "py/mpconfig.h" + +extern volatile uint64_t ticks_ms; + +extern struct timer_descriptor ms_timer; + +void tick_init(void); + +void tick_delay(uint32_t us); + +void current_tick(uint64_t* ms, uint32_t* us_until_ms); +// Do not call this with interrupts disabled because it may be waiting for +// ticks_ms to increment. +void wait_until(uint64_t ms, uint32_t us_until_ms); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_TICK_H diff --git a/ports/atmel-samd/timer_handler.c b/ports/atmel-samd/timer_handler.c new file mode 100644 index 00000000000..5d6de3093fc --- /dev/null +++ b/ports/atmel-samd/timer_handler.c @@ -0,0 +1,69 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 +#include + +#include "timer_handler.h" + +#include "common-hal/pulseio/PulseOut.h" +#include "shared-module/_pew/PewPew.h" +#include "common-hal/frequencyio/FrequencyIn.h" + +static uint8_t tc_handler[TC_INST_NUM]; + +void set_timer_handler(bool is_tc, uint8_t index, uint8_t timer_handler) { + if (is_tc) { + tc_handler[index] = timer_handler; + } +} + +void shared_timer_handler(bool is_tc, uint8_t index) { + // Add calls to interrupt handlers for specific functionality here. + // Make sure to add the handler #define to timer_handler.h + if (is_tc) { + uint8_t handler = tc_handler[index]; + switch(handler) { + case TC_HANDLER_PULSEOUT: + #if CIRCUITPY_PULSEIO + pulseout_interrupt_handler(index); + #endif + break; + case TC_HANDLER_PEW: + #if CIRCUITPY_PEW + pewpew_interrupt_handler(index); + #endif + break; + case TC_HANDLER_FREQUENCYIN: + #if CIRCUITPY_FREQUENCYIO + frequencyin_interrupt_handler(index); + #endif + break; + default: + break; + } + } +} diff --git a/ports/atmel-samd/timer_handler.h b/ports/atmel-samd/timer_handler.h new file mode 100644 index 00000000000..4a7adb58c3e --- /dev/null +++ b/ports/atmel-samd/timer_handler.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_TIMER_HANDLER_H +#define MICROPY_INCLUDED_ATMEL_SAMD_TIMER_HANDLER_H + +#define TC_HANDLER_NO_INTERRUPT 0x0 +#define TC_HANDLER_PULSEOUT 0x1 +#define TC_HANDLER_PEW 0x2 +#define TC_HANDLER_FREQUENCYIN 0x3 + +void set_timer_handler(bool is_tc, uint8_t index, uint8_t timer_handler); +void shared_timer_handler(bool is_tc, uint8_t index); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_TIMER_HANDLER_H diff --git a/ports/atmel-samd/tools/bossac_linux b/ports/atmel-samd/tools/bossac_linux new file mode 100755 index 00000000000..f08c74635da Binary files /dev/null and b/ports/atmel-samd/tools/bossac_linux differ diff --git a/ports/atmel-samd/tools/bossac_osx b/ports/atmel-samd/tools/bossac_osx new file mode 100755 index 00000000000..c9f2b53e452 Binary files /dev/null and b/ports/atmel-samd/tools/bossac_osx differ diff --git a/ports/atmel-samd/tools/gen_pin_name_table.py b/ports/atmel-samd/tools/gen_pin_name_table.py new file mode 100644 index 00000000000..ded64e5f69c --- /dev/null +++ b/ports/atmel-samd/tools/gen_pin_name_table.py @@ -0,0 +1,227 @@ +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +# +# 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. + +# This helper generates the pinout tables in ../README.rst. + +import os +import os.path + +pins = ["PA00", "PA01", "PA02", "PA03", "PB08", "PB09", "PA04", "PA05", "PA06", + "PA07", "PA08", "PA09", "PA10", "PA11", "PB10", "PB11", "PA12", "PA13", + "PA14", "PA15", "PA16", "PA17", "PA18", "PA19", "PA20", "PA21", "PA22", + "PA23", "PA24", "PA25", "PB22", "PB23", "PA27", "PA28", "PA29", "PA30", + "PA31", "PB02", "PB03"] + +# Dictionary keys: [board][pin] = list of pin names +mapping = {} + +QSTR = " { MP_OBJ_NEW_QSTR(MP_QSTR_" + +for board in os.listdir("boards"): + if not os.path.isdir("boards/" + board): + continue + mapping[board] = {} + with open("boards/" + board + "/pins.c", "r") as f: + for line in f: + if line.startswith(QSTR): + board_name, _, pin = line.split(")") + board_name = board_name[len(QSTR):] + pin = pin[-8:-4] + if pin not in mapping[board]: + mapping[board][pin] = [] + mapping[board][pin].append(board_name) + +column_width = {} +for board in mapping: + column_width[board] = len(board) + for pin in mapping[board]: + l = len(" / ".join("``" + x + "``" for x in mapping[board][pin])) + column_width[board] = max(l, column_width[board]) + +first_column_width = len("`microcontroller.pin`") +print("=" * first_column_width, end="") +total_board_width = -2 +for board in column_width: + column = " " + "=" * column_width[board] + total_board_width += len(column) + print(column, end="") + +print() +print("`microcontroller.pin` `board`") +print("-" * first_column_width + " " + "-" * total_board_width) + +print("Datasheet".ljust(first_column_width), end="") +for board in column_width: + print(" " + board.ljust(column_width[board]), end="") +print() + +print("=" * first_column_width, end="") +for board in column_width: + column = " " + "=" * column_width[board] + print(column, end="") +print() + +for pin in pins: + print(pin.ljust(first_column_width), end="") + for board in column_width: + if pin in mapping[board]: + names = " / ".join("``" + x + "``" for x in mapping[board][pin]) + print(" " + names.ljust(column_width[board]), end="") + else: + print(" " * (column_width[board] + 2), end="") + print() + +print("=" * first_column_width, end="") +for board in column_width: + column = " " + "=" * column_width[board] + print(column, end="") +print() + +print() +print() +# Generate pin capabilities too. + +ALL_BUT_USB = list(pins) +ALL_BUT_USB.remove("PA24") +ALL_BUT_USB.remove("PA25") + +# dictionary is [module][class] = [pins] +capabilities = { + "analogio" : { + "AnalogIn" : ["PA02", "PA03", "PB08", "PB09", "PA04", "PA05", "PA06", + "PA07", "PA08", "PA09", "PA10", "PA11", "PB02", "PB03"], + "AnalogOut": ["PA02"] + }, + "audioio" : { + "AudioOut": ["PA02"] + }, + "bitbangio": { + "I2C": ALL_BUT_USB, + "OneWire": ALL_BUT_USB, + "SPI": ALL_BUT_USB + }, + "busio": { + "I2C - SDA": ["PA00", "PB08", "PA08", "PA12", "PA16", "PA22", "PB02"], # SERCOM pad 0 + "I2C - SCL": ["PA01", "PB09", "PA09", "PA13", "PA17", "PA23", "PB03"], # SERCOM pad 1 + "OneWire": ALL_BUT_USB, + "SPI - MISO": ["PA00", "PA01", "PB08", "PB09", "PA04", "PA05", "PA06", + "PA07", "PA08", "PA09", "PA10", "PA11", "PB10", "PB11", + "PA12", "PA13", "PA14", "PA15", "PA16", "PA17", "PA18", + "PA19", "PA20", "PA21", "PA22", "PA23", "PB22", "PB23", + "PA30", "PA31", "PB02", "PB03"], # any SERCOM pad + "SPI - MOSI": ["PA00", "PB08", "PA04", "PA06", "PA08", "PA10", "PA11", + "PB10", "PB11", "PA14", "PA15", "PA16", "PA18", "PA19", + "PA20", "PA21", "PA22", "PB22", "PB23", "PA30", "PA31", + "PB02"], # any pad but 1 + "SPI - SCK": ["PA01", "PB09", "PA05", "PA07", "PA09", "PA11", "PB11", + "PA13", "PA15", "PA17", "PA19", "PA21", "PA23", "PB23", + "PA31", "PB03"], # 1 or 3 + "UART - RX": ["PA00", "PA01", "PB08", "PB09", "PA04", "PA05", "PA06", + "PA07", "PA08", "PA09", "PA10", "PA11", "PB10", "PB11", + "PA12", "PA13", "PA14", "PA15", "PA16", "PA17", "PA18", + "PA19", "PA20", "PA21", "PA22", "PA23", "PB22", "PB23", + "PA30", "PA31", "PB02", "PB03"], # any pad + "UART - TX": ["PA00", "PB08", "PA04", "PA06", "PA08", "PA10", "PB10", + "PA12", "PA14", "PA16", "PA18", "PA20", "PA22", "PB22", + "PA30", "PB02"] # pad 0 or 2 + }, + "digitalio": { + "DigitalInOut": ALL_BUT_USB + }, + "pulseio": { + "PulseIn": ALL_BUT_USB, + "PWMOut": ["PA01", "PB09", "PA04", "PA05", "PA06", "PA07", "PA08", + "PA09", "PA10", "PA11", "PB10", "PB11", "PA12", "PA13", + "PA14", "PA15", "PA16", "PA17", "PA18", "PA19", "PA20", + "PA21", "PA22", "PA23", "PA30", "PA31"] + }, + "ps2io": { + "Ps2": ALL_BUT_USB, + }, + "touchio": { + "TouchIn": ["PA02", "PA03", "PB08", "PB09", "PA04", "PA05", "PA06", + "PA07", "PB02", "PB03"] + } +} + +column_width = {} +for module in capabilities: + for c in capabilities[module]: + column_width[module + c] = max(len("**Yes**"), len(c)) + +module_width = {} +for module in capabilities: + module_width[module] = 0 + for c in capabilities[module]: + module_width[module] += column_width[module + c] + 2 + module_width[module] -= 2 + + if module_width[module] < (len(module) + 2): + column_width[module + c] += (len(module) + 2 - module_width[module]) + module_width[module] = len(module) + 2 + +first_column_width = len("`microcontroller.pin`") +print("=" * first_column_width, end="") +for module in capabilities: + for c in capabilities[module]: + print(" " + "=" * column_width[module + c], end="") +print() + +print("`microcontroller.pin`", end="") +for module in capabilities: + print(" " + ("`" + module + "`").ljust(module_width[module]), end="") +print() + +print("-" * first_column_width, end="") +for module in capabilities: + print(" " + "-" * module_width[module], end="") +print() + +print("Datasheet".ljust(first_column_width), end="") +for module in capabilities: + for c in capabilities[module]: + print(" " + c.ljust(column_width[module + c]), end="") +print() + +print("=" * first_column_width, end="") +for module in capabilities: + for c in capabilities[module]: + print(" " + "=" * column_width[module + c], end="") +print() + +for pin in pins: + print(pin.ljust(first_column_width), end="") + for module in capabilities: + for c in capabilities[module]: + if pin in capabilities[module][c]: + print(" " + "**Yes**".ljust(column_width[module + c]), end="") + else: + print(" " * (column_width[module + c] + 2), end="") + print() + +print("=" * first_column_width, end="") +for module in capabilities: + for c in capabilities[module]: + print(" " + "=" * column_width[module + c], end="") +print() diff --git a/ports/atmel-samd/tools/samd21.json b/ports/atmel-samd/tools/samd21.json new file mode 100644 index 00000000000..8a2b098a133 --- /dev/null +++ b/ports/atmel-samd/tools/samd21.json @@ -0,0 +1 @@ +{"jsonForm":"=1","formatVersion":2,"board":{"identifier":"CustomBoard","device":"SAMD21G18A-MF"},"identifier":"","name":"My Project","details":null,"application":null,"middlewares":[{"functionality":"USB_Chapter_9","identifier":"USB_CHAPTER_9","user_label":"USB_CHAPTER_9","api":"USB:Protocol:Core","configuration":{},"dependencies":{},"definition":"Atmel:USB:0.0.1::USB_Chapter_9"},{"functionality":"USB_Class_HUB","identifier":"USB_CLASS_HUB","user_label":"USB_CLASS_HUB","api":"USB:Protocol:HUB","configuration":{},"dependencies":{"USB Chapter 9":"USB_CHAPTER_9"},"definition":"Atmel:USB:0.0.1::USB_Class_HUB"},{"functionality":"USB_Class_HID","identifier":"USB_CLASS_HID","user_label":"USB_CLASS_HID","api":"USB:Protocol:HID","configuration":{},"dependencies":{"USB Chapter 9":"USB_CHAPTER_9"},"definition":"Atmel:USB:0.0.1::USB_Class_HID"},{"functionality":"USB_Class_CDC","identifier":"USB_CLASS_CDC","user_label":"USB_CLASS_CDC","api":"USB:Protocol:CDC","configuration":{},"dependencies":{"USB Chapter 9":"USB_CHAPTER_9"},"definition":"Atmel:USB:0.0.1::USB_Class_CDC"},{"functionality":"USB_Class_Mass_Storage_(MSC)","identifier":"USB_CLASS_MSC","user_label":"USB_CLASS_MSC","api":"USB:Protocol:MSC","configuration":{},"dependencies":{"USB Chapter 9":"USB_CHAPTER_9"},"definition":"Atmel:USB:0.0.1::USB_Class_MSC"},{"functionality":"USB_Class_VENDOR","identifier":"USB_CLASS_VENDOR","user_label":"USB_CLASS_VENDOR","api":"USB:Protocol:VENDOR","configuration":{},"dependencies":{"USB Chapter 9":"USB_CHAPTER_9"},"definition":"Atmel:USB:0.0.1::USB_Class_VENDOR"},{"functionality":"USB_Device_Core","identifier":"USB_DEVICE_STACK_CORE_INSTANCE","user_label":"USB_DEVICE_STACK_CORE_INSTANCE","api":"USB:Device:Core","configuration":{},"dependencies":{"USB Chapter 9":"USB_CHAPTER_9","USB Device instance":"USB_0"},"definition":"Atmel:USB:0.0.1::USB_Device_Core"},{"functionality":"USB_Device_COMPOSITE","identifier":"USB_DEVICE_COMPOSITE_0","user_label":"USB_DEVICE_COMPOSITE_0","api":"USB:Device:COMPOSITE","configuration":{"usb_composite_bcdusb":"USB 2.0 version","usb_composite_bmaxpksz0":"64 bytes","usb_composite_idvender":1003,"usb_composite_idproduct":9249,"usb_composite_bcddevice":256,"usb_composite_imanufact":0,"usb_composite_iproduct":0,"usb_composite_iserialnum":0,"usb_composite_bnumconfig":1,"usb_composite_bconfigval":1,"usb_composite_iconfig":0,"usb_composite_bmattri":"Bus power supply, not support for remote wakeup","usb_composite_bmaxpower":50,"usb_composite_cdc_acm_support":true,"usb_composite_cdc_acm_epaddr":"EndpointAddress = 0x82","usb_composite_cdc_acm_comm_int_maxpksz":"64 bytes","usb_composite_cdc_acm_data_bulkin_epaddr":"EndpointAddress = 0x81","usb_composite_cdc_acm_data_builin_maxpksz":"64 bytes","usb_composite_cdc_acm_data_bulkout_epaddr":"EndpointAddress = 0x01","usb_composite_cdc_acm_data_buckout_maxpksz":"64 bytes","usb_composite_hid_mouse_support":false,"usb_composite_hid_mouse_intin_epaddr":"EndpointAddress = 0x83","usb_composite_hid_mouse_intin_maxpksz":"8 bytes","usb_composite_hid_keyboard_support":false,"usb_composite_hid_keyboard_intin_epaddr":"EndpointAddress = 0x84","usb_composite_hid_keyboard_intin_maxpksz":"8 bytes","usb_composite_hid_keyboard_intout_epaddr":"EndpointAddress = 0x02","usb_composite_hid_keyboard_intout_maxpksz":"8 bytes","usb_composite_hid_generic_support":false,"usb_composite_hid_generic_intin_epaddr":"EndpointAddress = 0x85","usb_composite_hid_generic_intin_maxpksz":"64 bytes","usb_composite_hid_generic_intout_epaddr":"EndpointAddress = 0x03","usb_composite_hid_generic_intout_maxpksz":"64 bytes"},"dependencies":{"USB Class MSC":"USB_CLASS_MSC","USB Class CDC":"USB_CLASS_CDC","USB Device Stack Core Instance":"USB_DEVICE_STACK_CORE_INSTANCE","USB Class VENDOR":"USB_CLASS_VENDOR","USB Class HID":"USB_CLASS_HID","USB Class HUB":"USB_CLASS_HUB"},"definition":"Atmel:USB:0.0.1::USB_Device_Composite"}],"drivers":[{"functionality":null,"identifier":"GCLK","user_label":"GCLK","api":"HAL:HPL:GCLK","configuration":{"enable_gclk_gen_0":true,"gclk_arch_gen_0_RUNSTDBY":false,"gclk_gen_0_div_sel":false,"gclk_arch_gen_0_oe":false,"gclk_arch_gen_0_oov":false,"gclk_arch_gen_0_idc":false,"gclk_arch_gen_0_enable":true,"gclk_gen_0_oscillator":"8MHz Internal Oscillator (OSC8M)","gclk_gen_0_div":1,"enable_gclk_gen_1":false,"gclk_arch_gen_1_RUNSTDBY":false,"gclk_gen_1_div_sel":false,"gclk_arch_gen_1_oe":false,"gclk_arch_gen_1_oov":false,"gclk_arch_gen_1_idc":false,"gclk_arch_gen_1_enable":false,"gclk_gen_1_oscillator":"External Crystal Oscillator 0.4-32MHz (XOSC)","gclk_gen_1_div":1,"enable_gclk_gen_2":false,"gclk_arch_gen_2_RUNSTDBY":false,"gclk_gen_2_div_sel":false,"gclk_arch_gen_2_oe":false,"gclk_arch_gen_2_oov":false,"gclk_arch_gen_2_idc":false,"gclk_arch_gen_2_enable":false,"gclk_gen_2_oscillator":"External Crystal Oscillator 0.4-32MHz (XOSC)","gclk_gen_2_div":1,"enable_gclk_gen_3":false,"gclk_arch_gen_3_RUNSTDBY":false,"gclk_gen_3_div_sel":false,"gclk_arch_gen_3_oe":false,"gclk_arch_gen_3_oov":false,"gclk_arch_gen_3_idc":false,"gclk_arch_gen_3_enable":false,"gclk_gen_3_oscillator":"External Crystal Oscillator 0.4-32MHz (XOSC)","gclk_gen_3_div":1,"enable_gclk_gen_4":false,"gclk_arch_gen_4_RUNSTDBY":false,"gclk_gen_4_div_sel":false,"gclk_arch_gen_4_oe":false,"gclk_arch_gen_4_oov":false,"gclk_arch_gen_4_idc":false,"gclk_arch_gen_4_enable":false,"gclk_gen_4_oscillator":"External Crystal Oscillator 0.4-32MHz (XOSC)","gclk_gen_4_div":1,"enable_gclk_gen_5":false,"gclk_arch_gen_5_RUNSTDBY":false,"gclk_gen_5_div_sel":false,"gclk_arch_gen_5_oe":false,"gclk_arch_gen_5_oov":false,"gclk_arch_gen_5_idc":false,"gclk_arch_gen_5_enable":false,"gclk_gen_5_oscillator":"External Crystal Oscillator 0.4-32MHz (XOSC)","gclk_gen_5_div":1,"enable_gclk_gen_6":false,"gclk_arch_gen_6_RUNSTDBY":false,"gclk_gen_6_div_sel":false,"gclk_arch_gen_6_oe":false,"gclk_arch_gen_6_oov":false,"gclk_arch_gen_6_idc":false,"gclk_arch_gen_6_enable":false,"gclk_gen_6_oscillator":"External Crystal Oscillator 0.4-32MHz (XOSC)","gclk_gen_6_div":1,"enable_gclk_gen_7":false,"gclk_arch_gen_7_RUNSTDBY":false,"gclk_gen_7_div_sel":false,"gclk_arch_gen_7_oe":false,"gclk_arch_gen_7_oov":false,"gclk_arch_gen_7_idc":false,"gclk_arch_gen_7_enable":false,"gclk_gen_7_oscillator":"External Crystal Oscillator 0.4-32MHz (XOSC)","gclk_gen_7_div":1},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD21_Drivers:0.0.1::GCLK::driver_definition::GCLK::HAL:HPL:GCLK","identifier":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::GCLK::driver_config_definition::GCLK::HAL:HPL:GCLK","module":"GCLK"}},{"functionality":null,"identifier":"PM","user_label":"PM","api":"HAL:HPL:PM","configuration":{"enable_cpu_clock":true,"cpu_clock_source":"Generic clock generator 0","cpu_div":"1","nvm_wait_states":"0","apba_div":"1","apbb_div":"1","apbc_div":"1"},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD21_Drivers:0.0.1::PM::driver_definition::PM::HAL:HPL:PM","identifier":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::PM::driver_config_definition::PM::HAL:HPL:PM","module":"PM"},"clocks":{"domain_group":{"nodes":[{"name":"CPU","input":"CPU"}],"configuration":{}}}},{"functionality":null,"identifier":"DMAC","user_label":"DMAC","api":"HAL:HPL:DMAC","configuration":{"dmac_enable":false,"dmac_lvlen0":false,"dmac_rrlvlen0":"Static arbitration scheme for channel with priority 0","dmac_lvlpri0":0,"dmac_lvlen1":false,"dmac_rrlvlen1":"Static arbitration scheme for channel with priority 1","dmac_lvlpri1":0,"dmac_lvlen2":false,"dmac_rrlvlen2":"Static arbitration scheme for channel with priority 2","dmac_lvlpri2":0,"dmac_lvlen3":false,"dmac_rrlvlen3":"Static arbitration scheme for channel with priority 3","dmac_lvlpri3":0,"dmac_dbgrun":false,"dmac_channel_0_settings":false,"dmac_enable_0":false,"dmac_trigact_0":"One trigger required for each block transfer","dmac_trifsrc_0":"Only software/event triggers","dmac_lvl_0":"Channel priority 0","dmac_evoe_0":false,"dmac_evie_0":false,"dmac_evact_0":"No action","dmac_stepsize_0":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_0":"Step size settings apply to the destination address","dmac_srcinc_0":false,"dmac_dstinc_0":false,"dmac_beatsize_0":"8-bit bus transfer","dmac_blockact_0":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_0":"Event generation disabled","dmac_channel_1_settings":false,"dmac_enable_1":false,"dmac_trigact_1":"One trigger required for each block transfer","dmac_trifsrc_1":"Only software/event triggers","dmac_lvl_1":"Channel priority 0","dmac_evoe_1":false,"dmac_evie_1":false,"dmac_evact_1":"No action","dmac_stepsize_1":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_1":"Step size settings apply to the destination address","dmac_srcinc_1":false,"dmac_dstinc_1":false,"dmac_beatsize_1":"8-bit bus transfer","dmac_blockact_1":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_1":"Event generation disabled","dmac_channel_2_settings":false,"dmac_enable_2":false,"dmac_trigact_2":"One trigger required for each block transfer","dmac_trifsrc_2":"Only software/event triggers","dmac_lvl_2":"Channel priority 0","dmac_evoe_2":false,"dmac_evie_2":false,"dmac_evact_2":"No action","dmac_stepsize_2":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_2":"Step size settings apply to the destination address","dmac_srcinc_2":false,"dmac_dstinc_2":false,"dmac_beatsize_2":"8-bit bus transfer","dmac_blockact_2":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_2":"Event generation disabled","dmac_channel_3_settings":false,"dmac_enable_3":false,"dmac_trigact_3":"One trigger required for each block transfer","dmac_trifsrc_3":"Only software/event triggers","dmac_lvl_3":"Channel priority 0","dmac_evoe_3":false,"dmac_evie_3":false,"dmac_evact_3":"No action","dmac_stepsize_3":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_3":"Step size settings apply to the destination address","dmac_srcinc_3":false,"dmac_dstinc_3":false,"dmac_beatsize_3":"8-bit bus transfer","dmac_blockact_3":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_3":"Event generation disabled","dmac_channel_4_settings":false,"dmac_enable_4":false,"dmac_trigact_4":"One trigger required for each block transfer","dmac_trifsrc_4":"Only software/event triggers","dmac_lvl_4":"Channel priority 0","dmac_evoe_4":false,"dmac_evie_4":false,"dmac_evact_4":"No action","dmac_stepsize_4":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_4":"Step size settings apply to the destination address","dmac_srcinc_4":false,"dmac_dstinc_4":false,"dmac_beatsize_4":"8-bit bus transfer","dmac_blockact_4":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_4":"Event generation disabled","dmac_channel_5_settings":false,"dmac_enable_5":false,"dmac_trigact_5":"One trigger required for each block transfer","dmac_trifsrc_5":"Only software/event triggers","dmac_lvl_5":"Channel priority 0","dmac_evoe_5":false,"dmac_evie_5":false,"dmac_evact_5":"No action","dmac_stepsize_5":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_5":"Step size settings apply to the destination address","dmac_srcinc_5":false,"dmac_dstinc_5":false,"dmac_beatsize_5":"8-bit bus transfer","dmac_blockact_5":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_5":"Event generation disabled","dmac_channel_6_settings":false,"dmac_enable_6":false,"dmac_trigact_6":"One trigger required for each block transfer","dmac_trifsrc_6":"Only software/event triggers","dmac_lvl_6":"Channel priority 0","dmac_evoe_6":false,"dmac_evie_6":false,"dmac_evact_6":"No action","dmac_stepsize_6":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_6":"Step size settings apply to the destination address","dmac_srcinc_6":false,"dmac_dstinc_6":false,"dmac_beatsize_6":"8-bit bus transfer","dmac_blockact_6":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_6":"Event generation disabled","dmac_channel_7_settings":false,"dmac_enable_7":false,"dmac_trigact_7":"One trigger required for each block transfer","dmac_trifsrc_7":"Only software/event triggers","dmac_lvl_7":"Channel priority 0","dmac_evoe_7":false,"dmac_evie_7":false,"dmac_evact_7":"No action","dmac_stepsize_7":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_7":"Step size settings apply to the destination address","dmac_srcinc_7":false,"dmac_dstinc_7":false,"dmac_beatsize_7":"8-bit bus transfer","dmac_blockact_7":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_7":"Event generation disabled","dmac_channel_8_settings":false,"dmac_enable_8":false,"dmac_trigact_8":"One trigger required for each block transfer","dmac_trifsrc_8":"Only software/event triggers","dmac_lvl_8":"Channel priority 0","dmac_evoe_8":false,"dmac_evie_8":false,"dmac_evact_8":"No action","dmac_stepsize_8":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_8":"Step size settings apply to the destination address","dmac_srcinc_8":false,"dmac_dstinc_8":false,"dmac_beatsize_8":"8-bit bus transfer","dmac_blockact_8":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_8":"Event generation disabled","dmac_channel_9_settings":false,"dmac_enable_9":false,"dmac_trigact_9":"One trigger required for each block transfer","dmac_trifsrc_9":"Only software/event triggers","dmac_lvl_9":"Channel priority 0","dmac_evoe_9":false,"dmac_evie_9":false,"dmac_evact_9":"No action","dmac_stepsize_9":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_9":"Step size settings apply to the destination address","dmac_srcinc_9":false,"dmac_dstinc_9":false,"dmac_beatsize_9":"8-bit bus transfer","dmac_blockact_9":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_9":"Event generation disabled","dmac_channel_10_settings":false,"dmac_enable_10":false,"dmac_trigact_10":"One trigger required for each block transfer","dmac_trifsrc_10":"Only software/event triggers","dmac_lvl_10":"Channel priority 0","dmac_evoe_10":false,"dmac_evie_10":false,"dmac_evact_10":"No action","dmac_stepsize_10":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_10":"Step size settings apply to the destination address","dmac_srcinc_10":false,"dmac_dstinc_10":false,"dmac_beatsize_10":"8-bit bus transfer","dmac_blockact_10":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_10":"Event generation disabled","dmac_channel_11_settings":false,"dmac_enable_11":false,"dmac_trigact_11":"One trigger required for each block transfer","dmac_trifsrc_11":"Only software/event triggers","dmac_lvl_11":"Channel priority 0","dmac_evoe_11":false,"dmac_evie_11":false,"dmac_evact_11":"No action","dmac_stepsize_11":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_11":"Step size settings apply to the destination address","dmac_srcinc_11":false,"dmac_dstinc_11":false,"dmac_beatsize_11":"8-bit bus transfer","dmac_blockact_11":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_11":"Event generation disabled","dmac_channel_12_settings":false,"dmac_enable_12":false,"dmac_trigact_12":"One trigger required for each block transfer","dmac_trifsrc_12":"Only software/event triggers","dmac_lvl_12":"Channel priority 0","dmac_evoe_12":false,"dmac_evie_12":false,"dmac_evact_12":"No action","dmac_stepsize_12":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_12":"Step size settings apply to the destination address","dmac_srcinc_12":false,"dmac_dstinc_12":false,"dmac_beatsize_12":"8-bit bus transfer","dmac_blockact_12":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_12":"Event generation disabled","dmac_channel_13_settings":false,"dmac_enable_13":false,"dmac_trigact_13":"One trigger required for each block transfer","dmac_trifsrc_13":"Only software/event triggers","dmac_lvl_13":"Channel priority 0","dmac_evoe_13":false,"dmac_evie_13":false,"dmac_evact_13":"No action","dmac_stepsize_13":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_13":"Step size settings apply to the destination address","dmac_srcinc_13":false,"dmac_dstinc_13":false,"dmac_beatsize_13":"8-bit bus transfer","dmac_blockact_13":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_13":"Event generation disabled","dmac_channel_14_settings":false,"dmac_enable_14":false,"dmac_trigact_14":"One trigger required for each block transfer","dmac_trifsrc_14":"Only software/event triggers","dmac_lvl_14":"Channel priority 0","dmac_evoe_14":false,"dmac_evie_14":false,"dmac_evact_14":"No action","dmac_stepsize_14":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_14":"Step size settings apply to the destination address","dmac_srcinc_14":false,"dmac_dstinc_14":false,"dmac_beatsize_14":"8-bit bus transfer","dmac_blockact_14":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_14":"Event generation disabled","dmac_channel_15_settings":false,"dmac_enable_15":false,"dmac_trigact_15":"One trigger required for each block transfer","dmac_trifsrc_15":"Only software/event triggers","dmac_lvl_15":"Channel priority 0","dmac_evoe_15":false,"dmac_evie_15":false,"dmac_evact_15":"No action","dmac_stepsize_15":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_15":"Step size settings apply to the destination address","dmac_srcinc_15":false,"dmac_dstinc_15":false,"dmac_beatsize_15":"8-bit bus transfer","dmac_blockact_15":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_15":"Event generation disabled"},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD21_Drivers:0.0.1::DMAC::driver_definition::DMAC::HAL:HPL:DMAC","identifier":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::DMAC::driver_config_definition::DMAC::HAL:HPL:DMAC","module":"DMAC"}},{"functionality":null,"identifier":"SYSCTRL","user_label":"SYSCTRL","api":"HAL:HPL:SYSCTRL","configuration":{"enable_osc8m":true,"osc8m_arch_enable":true,"osc8m_arch_ondemand":true,"osc8m_arch_runstdby":false,"osc8m_presc":"8","osc8m_arch_overwrite_calibration":false,"osc8m_arch_calib":0,"enable_osc32k":false,"osc32k_arch_enable":false,"osc32k_arch_ondemand":true,"osc32k_arch_runstdby":false,"osc32k_arch_en32k":false,"osc32k_arch_en1k":false,"osc32k_arch_wrtlock":false,"osc32k_arch_startup":"3 Clock Cycles (92us)","osc32k_arch_overwrite_calibration":false,"osc32k_arch_calib":0,"enable_xosc32k":false,"xosc32k_arch_enable":false,"xosc32k_arch_ondemand":true,"xosc32k_arch_runstdby":false,"xosc32k_arch_en1k":false,"xosc32k_arch_en32k":false,"xosc32k_arch_xtalen":false,"xosc32k_arch_wrtlock":false,"xosc32k_arch_aampen":false,"xosc32k_arch_startup":"122 us","enable_xosc":false,"xosc_frequency":400000,"xosc_arch_enable":false,"xosc_arch_ondemand":true,"xosc_arch_runstdby":false,"xosc_arch_xtalen":false,"xosc_arch_ampgc":false,"xosc_arch_gain":"2Mhz","xosc_arch_startup":"31 us","enable_osculp32k":true,"osculp32k_arch_wrtlock":false,"osculp32k_arch_overwrite_calibration":false,"osculp32k_arch_calib":0,"enable_dfll48m":false,"dfll48m_ref_clock":"Generic clock generator 4","dfll48m_arch_enable":false,"dfll48m_arch_waitlock":false,"dfll48m_arch_bplckc":false,"dfll48m_arch_qldis":false,"dfll48m_arch_ccdis":false,"dfll48m_arch_ondemand":true,"dfll48m_arch_runstdby":false,"dfll48m_arch_usbcrm":true,"dfll48m_arch_llaw":false,"dfll48m_arch_stable":false,"dfll48m_mode":"Closed Loop Mode","dfll_arch_cstep":1,"dfll_arch_fstep":1,"dfll48m_mul":0,"dfll48m_arch_calibration":true,"dfll48m_arch_coarse":10,"dfll48m_arch_fine":512,"enable_fdpll96m":false,"fdpll96m_ref_clock":"Generic clock generator 3","fdpll96m_arch_ondemand":true,"fdpll96m_arch_runstdby":false,"fdpll96m_arch_enable":false,"fdpll96m_arch_lbypass":false,"fdpll96m_clock_div":0,"fdpll96m_ldrfrac":13,"fdpll96m_ldr":1463},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD21_Drivers:0.0.1::SYSCTRL::driver_definition::SYSCTRL::HAL:HPL:SYSCTRL","identifier":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::SYSCTRL::driver_config_definition::SYSCTRL::HAL:HPL:SYSCTRL","module":"SYSCTRL"}},{"functionality":"ADC","identifier":"ADC_0","user_label":"ADC_0","api":"HAL:Driver:ADC_Sync","configuration":{"adc_resolution":"12-bit","adc_reference":"1.0V voltage reference","adc_prescaler":"Peripheral clock divided by 4","adc_freerunning_mode":false,"adc_differential_mode":false,"adc_pinmux_positive":"ADC AIN0 pin","adc_pinmux_negative":"ADC AIN0 pin","adc_advanced_settings":false,"adc_arch_runstdby":false,"adc_arch_dbgrun":false,"adc_arch_leftadj":false,"adc_arch_refcomp":false,"adc_arch_corren":false,"adc_arch_offsetcorr":0,"adc_arch_gaincorr":0,"adc_arch_gain":"1x","adc_arch_adjres":0,"adc_arch_samplenum":"1 sample","adc_arch_samplen":0,"adc_arch_winmode":"No window mode","adc_arch_winlt":0,"adc_arch_winut":0,"adc_arch_inputscan":0,"adc_arch_inputoffset":0,"adc_arch_event_settings":false,"adc_arch_winmoneo":false,"adc_arch_resrdyeo":false,"adc_arch_syncei":false,"adc_arch_startei":false},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD21_Drivers:0.0.1::ADC::driver_definition::ADC::HAL:Driver:ADC.Sync","identifier":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::ADC::driver_config_definition::ADC::HAL:Driver:ADC.Sync","module":"ADC"},"clocks":{"domain_group":{"nodes":[{"name":"ADC","input":"Generic clock generator 0"}],"configuration":{"adc_gclk_selection":"Generic clock generator 0"}}}},{"functionality":"Flash","identifier":"FLASH_0","user_label":"FLASH_0","api":"HAL:Driver:FLASH","configuration":{"nvm_arch_read_mode":"No Miss Penalty","nvm_arch_sleepprm":"Wake On Access","nvm_arch_cache":false},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD21_Drivers:0.0.1::NVMCTRL::driver_definition::Flash::HAL:Driver:FLASH","identifier":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::NVMCTRL::driver_config_definition::Flash::HAL:Driver:FLASH","module":"NVMCTRL"}},{"functionality":"SPI","identifier":"SPI_0","user_label":"SPI_0","api":"HAL:Driver:SPI_Master_Sync","configuration":{"spi_master_rx_enable":true,"spi_master_character_size":"8 bits","spi_master_baud_rate":50000,"spi_master_advanced":false,"spi_master_dummybyte":511,"spi_master_arch_dord":"MSB first","spi_master_arch_cpol":"SCK is low when idle","spi_master_arch_cpha":"Sample input on leading edge","spi_master_arch_ibon":"In data stream","spi_master_arch_runstdby":false,"spi_master_arch_dbgstop":"Keep running"},"dependencies":{},"optional_signals":[],"variant":{"specification":"TXPO=0, RXPO=2","required_signals":[{"label":"MOSI","identifier":"SPI_0:MOSI","name":"SERCOM0/PAD/0","pad":"PA04","configuration":null,"definition":"","mode":"Enabled"},{"label":"MISO","identifier":"SPI_0:MISO","name":"SERCOM0/PAD/2","pad":"PA06","configuration":null,"definition":"","mode":"Enabled"},{"label":"SCK","identifier":"SPI_0:SCK","name":"SERCOM0/PAD/1","pad":"PA05","configuration":null,"definition":"","mode":"Enabled"}]},"definition":{"base":"Atmel:SAMD21_Drivers:0.0.1::SERCOM::driver_definition::SPI.Master::HAL:Driver:SPI.Master.Sync","identifier":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::SERCOM0::driver_config_definition::SPI.Master::HAL:Driver:SPI.Master.Sync","module":"SERCOM0"},"clocks":{"domain_group":{"nodes":[{"name":"Slow","input":"Generic clock generator 3"},{"name":"Core","input":"Generic clock generator 0"}],"configuration":{"core_gclk_selection":"Generic clock generator 0","slow_gclk_selection":"Generic clock generator 3"}}}},{"functionality":"I2C","identifier":"I2C_0","user_label":"I2C_0","api":"HAL:Driver:I2C_Master_Sync","configuration":{"i2c_master_baud_rate":100000,"i2c_master_advanced":false,"i2c_master_arch_trise":215,"i2c_master_arch_mexttoen":false,"i2c_master_arch_sexttoen":false,"i2c_master_arch_lowtout":false,"i2c_master_arch_inactout":"Disabled","i2c_master_arch_sdahold":"300-600ns hold time","i2c_master_arch_runstdby":false,"i2c_master_arch_dbgstop":"Keep running"},"dependencies":{},"optional_signals":[],"variant":{"specification":"SDA=0, SCL=1","required_signals":[{"label":"SDA","identifier":"I2C_0:SDA","name":"SERCOM1/PAD/0","pad":"PA16","configuration":null,"definition":"","mode":"Enabled"},{"label":"SCL","identifier":"I2C_0:SCL","name":"SERCOM1/PAD/1","pad":"PA17","configuration":null,"definition":"","mode":"Enabled"}]},"definition":{"base":"Atmel:SAMD21_Drivers:0.0.1::SERCOM::driver_definition::I2C.Master.Standard~2FFast-mode::HAL:Driver:I2C.Master.Sync","identifier":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::SERCOM1::driver_config_definition::I2C.Master.Standard~2FFast-mode::HAL:Driver:I2C.Master.Sync","module":"SERCOM1"},"clocks":{"domain_group":{"nodes":[{"name":"Slow","input":"Generic clock generator 3"},{"name":"Core","input":"Generic clock generator 0"}],"configuration":{"core_gclk_selection":"Generic clock generator 0","slow_gclk_selection":"Generic clock generator 3"}}}},{"functionality":"USART","identifier":"USART_0","user_label":"USART_0","api":"HAL:Driver:USART_Sync","configuration":{"usart_rx_enable":true,"usart_tx_enable":true,"usart_parity":"No parity","usart_character_size":"8 bits","usart_stop_bit":"One stop bit","usart_baud_rate":9600,"usart_advanced":false,"usart_arch_runstdby":false,"usart_arch_ibon":false,"usart_arch_sfde":false,"usart_arch_cloden":false,"usart_arch_clock_mode":"USART with internal clock","usart_arch_sampr":"16x arithmetic","usart_arch_sampa":"7-8-9 (3-4-5 8-bit over-sampling)","usart_arch_fractional":0,"usart_arch_dord":"LSB is transmitted first","usart_arch_enc":"No encoding","usart_arch_dbgstop":"Keep running"},"dependencies":{},"optional_signals":[],"variant":{"specification":"TXPO=0, RXPO=1, CMODE=0","required_signals":[{"label":"TX","identifier":"USART_0:TX","name":"SERCOM2/PAD/0","pad":"PA08","configuration":null,"definition":"","mode":"Enabled"},{"label":"RX","identifier":"USART_0:RX","name":"SERCOM2/PAD/1","pad":"PA09","configuration":null,"definition":"","mode":"Enabled"}]},"definition":{"base":"Atmel:SAMD21_Drivers:0.0.1::SERCOM::driver_definition::UART::HAL:Driver:USART.Sync","identifier":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::SERCOM2::driver_config_definition::UART::HAL:Driver:USART.Sync","module":"SERCOM2"},"clocks":{"domain_group":{"nodes":[{"name":"Slow","input":"Generic clock generator 3"},{"name":"Core","input":"Generic clock generator 0"}],"configuration":{"core_gclk_selection":"Generic clock generator 0","slow_gclk_selection":"Generic clock generator 3"}}}},{"functionality":"Delay","identifier":"DELAY_0","user_label":"DELAY_0","api":"HAL:Driver:Delay","configuration":{"systick_arch_tickint":false},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD21_Drivers:0.0.1::SysTick::driver_definition::Delay::HAL:Driver:Delay","identifier":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::SysTick::driver_config_definition::Delay::HAL:Driver:Delay","module":"SysTick"}},{"functionality":"Timer","identifier":"TIMER_0","user_label":"TIMER_0","api":"HAL:Driver:Timer","configuration":{"rtc_arch_prescaler":"Peripheral clock divided by 1","rtc_arch_comp_val":1024,"rtc_event_control":false,"rtc_pereo0":false,"rtc_pereo1":false,"rtc_pereo2":false,"rtc_pereo3":false,"rtc_pereo4":false,"rtc_pereo5":false,"rtc_pereo6":false,"rtc_pereo7":false,"rtc_cmpeo0":false,"rtc_ovfeo":false},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD21_Drivers:0.0.1::RTC::driver_definition::Timer::HAL:Driver:Timer","identifier":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::RTC::driver_config_definition::Timer::HAL:Driver:Timer","module":"RTC"},"clocks":{"domain_group":{"nodes":[{"name":"RTC","input":"Generic clock generator 0"}],"configuration":{"rtc_clk_selection":"Generic clock generator 0"}}}},{"functionality":"PWM","identifier":"PWM_0","user_label":"PWM_0","api":"HAL:Driver:PWM","configuration":{"tc_prescaler":"Divide by 8","tc_per":50,"tc_arch_wave_per_val":1000,"tc_arch_wave_duty_val":500,"tc_arch_mode":"Counter in 16-bit mode","tc_arch_runstdby":false,"tc_arch_presync":"Reload or reset counter on next GCLK","tc_arch_dbgrun":false,"timer_event_control":false,"tc_arch_ovfeo":false,"tc_arch_tcei":false,"tc_arch_tceinv":false,"tc_arch_evact":"Event action disabled","tc_arch_mceo0":false,"tc_arch_mceo1":false},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD21_Drivers:0.0.1::TC::driver_definition::PWM::HAL:Driver:PWM","identifier":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::TC3::driver_config_definition::PWM::HAL:Driver:PWM","module":"TC3"},"clocks":{"domain_group":{"nodes":[{"name":"TC","input":"Generic clock generator 0"}],"configuration":{"tc_gclk_selection":"Generic clock generator 0"}}}},{"functionality":"DAC","identifier":"DAC_0","user_label":"DAC_0","api":"HAL:Driver:DAC_Sync","configuration":{"dac_arch_refsel":"Internal 1.0v reference","dac_advanced_settings":false,"dac_arch_runstdby":false,"dac_arch_bdwp":false,"dac_arch_vpd":false,"dac_arch_leftadj":false,"dac_arch_ioen":false,"dac_arch_eoen":true,"dac_arch_emptyeo":false,"dac_arch_startei":false},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD21_Drivers:0.0.1::DAC::driver_definition::DAC::HAL:Driver:DAC.Sync","identifier":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::DAC::driver_config_definition::DAC::HAL:Driver:DAC.Sync","module":"DAC"},"clocks":{"domain_group":{"nodes":[{"name":"DAC","input":"Generic clock generator 0"}],"configuration":{"dac_gclk_selection":"Generic clock generator 0"}}}},{"functionality":"USB","identifier":"USB_0","user_label":"USB_0","api":"HAL:Driver:USB_Device","configuration":{"usbd_num_ep_sp":"4 (EP0 + 3 endpoints)","usbd_arch_max_ep_n":"2 (EP 0x82 or 0x02)","usbd_arch_speed":"Full speed","usb_arch_ep0_cache":"Cached by 64 bytes buffer","usb_arch_ep1_cache":"Cached by 64 bytes buffer","usb_ep1_I_CACHE":"No cache","usb_arch_ep2_cache":"Cached by 64 bytes buffer","usb_ep2_I_CACHE":"No cache","usb_arch_ep3_cache":"Cached by 64 bytes buffer","usb_ep3_I_CACHE":"No cache","usb_arch_ep4_cache":"Cached by 64 bytes buffer","usb_ep4_I_CACHE":"No cache","usb_arch_ep5_cache":"Cached by 64 bytes buffer","usb_ep5_I_CACHE":"No cache","usb_arch_ep6_cache":"Cached by 64 bytes buffer","usb_ep6_I_CACHE":"No cache","usb_arch_ep7_cache":"Cached by 64 bytes buffer","usb_ep7_I_CACHE":"No cache"},"dependencies":{},"optional_signals":[],"variant":{"specification":"default","required_signals":[{"label":"Data-","identifier":"USB_0:Data-","name":"USB/DM","pad":"PA24","configuration":null,"definition":"","mode":"Enabled"},{"label":"Data+","identifier":"USB_0:Data+","name":"USB/DP","pad":"PA25","configuration":null,"definition":"","mode":"Enabled"}]},"definition":{"base":"Atmel:SAMD21_Drivers:0.0.1::USB::driver_definition::USB.Device::HAL:Driver:USB.Device","identifier":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::USB::driver_config_definition::USB.Device::HAL:Driver:USB.Device","module":"USB"},"clocks":{"domain_group":{"nodes":[{"name":"USB","input":"Generic clock generator 0"}],"configuration":{"usb_gclk_selection":"Generic clock generator 0"}}}}],"pads":[{"name":"PA00","user_label":"PA00","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA00","mode":"Digital input","configuration":null},{"name":"PA01","user_label":"PA01","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA01","mode":"Digital input","configuration":null},{"name":"PA02","user_label":"PA02","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA02","mode":"Digital input","configuration":null},{"name":"PA03","user_label":"PA03","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA03","mode":"Digital input","configuration":null},{"name":"PB08","user_label":"PB08","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PB08","mode":"Digital input","configuration":null},{"name":"PB09","user_label":"PB09","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PB09","mode":"Digital input","configuration":null},{"name":"PA04","user_label":"PA04","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA04","mode":"Digital output","configuration":null},{"name":"PA05","user_label":"PA05","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA05","mode":"Digital output","configuration":null},{"name":"PA06","user_label":"PA06","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA06","mode":"Digital input","configuration":null},{"name":"PA07","user_label":"PA07","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA07","mode":"Digital input","configuration":null},{"name":"PA08","user_label":"PA08","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA08","mode":"Peripheral IO","configuration":null},{"name":"PA09","user_label":"PA09","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA09","mode":"Peripheral IO","configuration":null},{"name":"PA10","user_label":"PA10","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA10","mode":"Digital input","configuration":null},{"name":"PA11","user_label":"PA11","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA11","mode":"Digital input","configuration":null},{"name":"PB10","user_label":"PB10","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PB10","mode":"Digital input","configuration":null},{"name":"PB11","user_label":"PB11","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PB11","mode":"Digital input","configuration":null},{"name":"PA12","user_label":"PA12","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA12","mode":"Digital input","configuration":null},{"name":"PA13","user_label":"PA13","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA13","mode":"Digital input","configuration":null},{"name":"PA14","user_label":"PA14","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA14","mode":"Digital input","configuration":null},{"name":"PA15","user_label":"PA15","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA15","mode":"Digital input","configuration":null},{"name":"PA16","user_label":"PA16","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA16","mode":"I2C","configuration":null},{"name":"PA17","user_label":"PA17","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA17","mode":"I2C","configuration":null},{"name":"PA18","user_label":"PA18","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA18","mode":"Digital input","configuration":null},{"name":"PA19","user_label":"PA19","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA19","mode":"Digital input","configuration":null},{"name":"PA20","user_label":"PA20","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA20","mode":"Digital input","configuration":null},{"name":"PA21","user_label":"PA21","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA21","mode":"Digital input","configuration":null},{"name":"PA22","user_label":"PA22","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA22","mode":"Digital input","configuration":null},{"name":"PA23","user_label":"PA23","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA23","mode":"Digital input","configuration":null},{"name":"PA24","user_label":"PA24","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA24","mode":"Advanced","configuration":null},{"name":"PA25","user_label":"PA25","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA25","mode":"Advanced","configuration":null},{"name":"PB22","user_label":"PB22","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PB22","mode":"Digital input","configuration":null},{"name":"PB23","user_label":"PB23","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PB23","mode":"Digital input","configuration":null},{"name":"PA27","user_label":"PA27","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA27","mode":"Digital input","configuration":null},{"name":"PA28","user_label":"PA28","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA28","mode":"Digital input","configuration":null},{"name":"PA30","user_label":"PA30","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA30","mode":"Digital input","configuration":null},{"name":"PA31","user_label":"PA31","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PA31","mode":"Digital input","configuration":null},{"name":"PB02","user_label":"PB02","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PB02","mode":"Digital input","configuration":null},{"name":"PB03","user_label":"PB03","definition":"Atmel:SAMD21_Drivers:0.0.1::SAMD21G18A-MF::pad::PB03","mode":"Digital input","configuration":null}]} diff --git a/ports/atmel-samd/tools/samd51.json b/ports/atmel-samd/tools/samd51.json new file mode 100644 index 00000000000..dee06850218 --- /dev/null +++ b/ports/atmel-samd/tools/samd51.json @@ -0,0 +1 @@ +{"jsonForm":"=1","formatVersion":2,"board":{"identifier":"CustomBoard","device":"SAMD51G19A-MF"},"identifier":"","name":"My Project","details":null,"application":null,"middlewares":[{"functionality":"USB_Chapter_9","identifier":"USB_CHAPTER_9","user_label":"USB_CHAPTER_9","api":"USB:Protocol:Core","configuration":{},"dependencies":{},"definition":"Atmel:USB:0.0.1::USB_Chapter_9"},{"functionality":"USB_Class_HUB","identifier":"USB_CLASS_HUB","user_label":"USB_CLASS_HUB","api":"USB:Protocol:HUB","configuration":{},"dependencies":{"USB Chapter 9":"USB_CHAPTER_9"},"definition":"Atmel:USB:0.0.1::USB_Class_HUB"},{"functionality":"USB_Class_HID","identifier":"USB_CLASS_HID","user_label":"USB_CLASS_HID","api":"USB:Protocol:HID","configuration":{},"dependencies":{"USB Chapter 9":"USB_CHAPTER_9"},"definition":"Atmel:USB:0.0.1::USB_Class_HID"},{"functionality":"USB_Class_CDC","identifier":"USB_CLASS_CDC","user_label":"USB_CLASS_CDC","api":"USB:Protocol:CDC","configuration":{},"dependencies":{"USB Chapter 9":"USB_CHAPTER_9"},"definition":"Atmel:USB:0.0.1::USB_Class_CDC"},{"functionality":"USB_Class_Mass_Storage_(MSC)","identifier":"USB_CLASS_MSC","user_label":"USB_CLASS_MSC","api":"USB:Protocol:MSC","configuration":{},"dependencies":{"USB Chapter 9":"USB_CHAPTER_9"},"definition":"Atmel:USB:0.0.1::USB_Class_MSC"},{"functionality":"USB_Class_VENDOR","identifier":"USB_CLASS_VENDOR","user_label":"USB_CLASS_VENDOR","api":"USB:Protocol:VENDOR","configuration":{},"dependencies":{"USB Chapter 9":"USB_CHAPTER_9"},"definition":"Atmel:USB:0.0.1::USB_Class_VENDOR"},{"functionality":"USB_Device_Core","identifier":"USB_DEVICE_STACK_CORE_INSTANCE","user_label":"USB_DEVICE_STACK_CORE_INSTANCE","api":"USB:Device:Core","configuration":{},"dependencies":{"USB Chapter 9":"USB_CHAPTER_9","USB Device instance":"USB_DEVICE_INSTANCE"},"definition":"Atmel:USB:0.0.1::USB_Device_Core"},{"functionality":"USB_Device_COMPOSITE","identifier":"USB_DEVICE_COMPOSITE_0","user_label":"USB_DEVICE_COMPOSITE_0","api":"USB:Device:COMPOSITE","configuration":{"usb_composite_bcdusb":"USB 2.0 version","usb_composite_bmaxpksz0":"64 bytes","usb_composite_idvender":1003,"usb_composite_idproduct":9249,"usb_composite_bcddevice":256,"usb_composite_imanufact":0,"usb_composite_iproduct":0,"usb_composite_iserialnum":0,"usb_composite_bnumconfig":1,"usb_composite_bconfigval":1,"usb_composite_iconfig":0,"usb_composite_bmattri":"Bus power supply, not support for remote wakeup","usb_composite_bmaxpower":50,"usb_composite_cdc_acm_support":false,"usb_composite_cdc_acm_epaddr":"EndpointAddress = 0x82","usb_composite_cdc_acm_comm_int_maxpksz":"64 bytes","usb_composite_cdc_acm_data_bulkin_epaddr":"EndpointAddress = 0x81","usb_composite_cdc_acm_data_builin_maxpksz":"64 bytes","usb_composite_cdc_acm_data_bulkout_epaddr":"EndpointAddress = 0x01","usb_composite_cdc_acm_data_buckout_maxpksz":"64 bytes","usb_composite_hid_mouse_support":false,"usb_composite_hid_mouse_intin_epaddr":"EndpointAddress = 0x83","usb_composite_hid_mouse_intin_maxpksz":"8 bytes","usb_composite_hid_keyboard_support":false,"usb_composite_hid_keyboard_intin_epaddr":"EndpointAddress = 0x84","usb_composite_hid_keyboard_intin_maxpksz":"8 bytes","usb_composite_hid_keyboard_intout_epaddr":"EndpointAddress = 0x02","usb_composite_hid_keyboard_intout_maxpksz":"8 bytes","usb_composite_hid_generic_support":false,"usb_composite_hid_generic_intin_epaddr":"EndpointAddress = 0x85","usb_composite_hid_generic_intin_maxpksz":"64 bytes","usb_composite_hid_generic_intout_epaddr":"EndpointAddress = 0x03","usb_composite_hid_generic_intout_maxpksz":"64 bytes","conf_usb_composite_cdc_echo_demo":false,"conf_usb_composite_hid_mouse_demo":false,"conf_usb_composite_hid_keyboard_demo":false,"usb_composite_msc_support":false,"usb_composite_msc_bulk_maxpksz":"64 bytes","usb_composite_msc_bulkin_epaddr":"EndpointAddress = 0x86","usb_composite_msc_bulkout_epaddr":"EndpointAddress = 0x04","usb_composite_msc_demo_en":true,"conf_usb_msc_lun_buf_sectors":4,"conf_usb_msc_lun0_enable":true,"conf_usb_msc_lun0_rmb":true,"conf_usb_msc_lun0_capacity":22,"conf_usb_msc_lun1_enable":false,"conf_usb_msc_lun1_rmb":true},"dependencies":{"USB Class MSC":"USB_CLASS_MSC","USB Class CDC":"USB_CLASS_CDC","USB Device Stack Core Instance":"USB_DEVICE_STACK_CORE_INSTANCE","USB Class VENDOR":"USB_CLASS_VENDOR","USB Class HID":"USB_CLASS_HID","USB Class HUB":"USB_CLASS_HUB"},"definition":"Atmel:USB:0.0.1::USB_Device_Composite"}],"drivers":[{"functionality":null,"identifier":"GCLK","user_label":"GCLK","api":"HAL:HPL:GCLK","configuration":{"enable_gclk_gen_0":true,"gclk_gen_0_oscillator":"External Crystal Oscillator 8-48MHz (XOSC1)","gclk_arch_gen_0_runstdby":false,"gclk_gen_0_div_sel":false,"gclk_arch_gen_0_oe":false,"gclk_arch_gen_0_oov":false,"gclk_arch_gen_0_idc":false,"gclk_arch_gen_0_enable":true,"gclk_gen_0_div":1,"enable_gclk_gen_1":false,"gclk_gen_1_oscillator":"Digital Frequency Locked Loop (DFLL48M)","gclk_arch_gen_1_runstdby":false,"gclk_gen_1_div_sel":false,"gclk_arch_gen_1_oe":false,"gclk_arch_gen_1_oov":false,"gclk_arch_gen_1_idc":false,"gclk_arch_gen_1_enable":false,"gclk_gen_1_div":1,"enable_gclk_gen_2":false,"gclk_gen_2_oscillator":"External Crystal Oscillator 8-48MHz (XOSC1)","gclk_arch_gen_2_runstdby":false,"gclk_gen_2_div_sel":true,"gclk_arch_gen_2_oe":false,"gclk_arch_gen_2_oov":false,"gclk_arch_gen_2_idc":false,"gclk_arch_gen_2_enable":false,"gclk_gen_2_div":1,"enable_gclk_gen_3":false,"gclk_gen_3_oscillator":"32kHz External Crystal Oscillator (XOSC32K)","gclk_arch_gen_3_runstdby":false,"gclk_gen_3_div_sel":false,"gclk_arch_gen_3_oe":false,"gclk_arch_gen_3_oov":false,"gclk_arch_gen_3_idc":false,"gclk_arch_gen_3_enable":false,"gclk_gen_3_div":1,"enable_gclk_gen_4":false,"gclk_gen_4_oscillator":"External Crystal Oscillator 8-48MHz (XOSC1)","gclk_arch_gen_4_runstdby":false,"gclk_gen_4_div_sel":false,"gclk_arch_gen_4_oe":false,"gclk_arch_gen_4_oov":false,"gclk_arch_gen_4_idc":false,"gclk_arch_gen_4_enable":false,"gclk_gen_4_div":1,"enable_gclk_gen_5":false,"gclk_gen_5_oscillator":"External Crystal Oscillator 8-48MHz (XOSC1)","gclk_arch_gen_5_runstdby":false,"gclk_gen_5_div_sel":false,"gclk_arch_gen_5_oe":false,"gclk_arch_gen_5_oov":false,"gclk_arch_gen_5_idc":false,"gclk_arch_gen_5_enable":false,"gclk_gen_5_div":1,"enable_gclk_gen_6":false,"gclk_gen_6_oscillator":"External Crystal Oscillator 8-48MHz (XOSC1)","gclk_arch_gen_6_runstdby":false,"gclk_gen_6_div_sel":false,"gclk_arch_gen_6_oe":false,"gclk_arch_gen_6_oov":false,"gclk_arch_gen_6_idc":false,"gclk_arch_gen_6_enable":false,"gclk_gen_6_div":1,"enable_gclk_gen_7":false,"gclk_gen_7_oscillator":"External Crystal Oscillator 8-48MHz (XOSC1)","gclk_arch_gen_7_runstdby":false,"gclk_gen_7_div_sel":false,"gclk_arch_gen_7_oe":false,"gclk_arch_gen_7_oov":false,"gclk_arch_gen_7_idc":false,"gclk_arch_gen_7_enable":false,"gclk_gen_7_div":1,"enable_gclk_gen_8":false,"gclk_gen_8_oscillator":"External Crystal Oscillator 8-48MHz (XOSC1)","gclk_arch_gen_8_runstdby":false,"gclk_gen_8_div_sel":false,"gclk_arch_gen_8_oe":false,"gclk_arch_gen_8_oov":false,"gclk_arch_gen_8_idc":false,"gclk_arch_gen_8_enable":false,"gclk_gen_8_div":1,"enable_gclk_gen_9":false,"gclk_gen_9_oscillator":"External Crystal Oscillator 8-48MHz (XOSC1)","gclk_arch_gen_9_runstdby":false,"gclk_gen_9_div_sel":false,"gclk_arch_gen_9_oe":false,"gclk_arch_gen_9_oov":false,"gclk_arch_gen_9_idc":false,"gclk_arch_gen_9_enable":false,"gclk_gen_9_div":1,"enable_gclk_gen_10":false,"gclk_gen_10_oscillator":"External Crystal Oscillator 8-48MHz (XOSC1)","gclk_arch_gen_10_runstdby":false,"gclk_gen_10_div_sel":false,"gclk_arch_gen_10_oe":false,"gclk_arch_gen_10_oov":false,"gclk_arch_gen_10_idc":false,"gclk_arch_gen_10_enable":false,"gclk_gen_10_div":1,"enable_gclk_gen_11":false,"gclk_gen_11_oscillator":"External Crystal Oscillator 8-48MHz (XOSC1)","gclk_arch_gen_11_runstdby":false,"gclk_gen_11_div_sel":false,"gclk_arch_gen_11_oe":false,"gclk_arch_gen_11_oov":false,"gclk_arch_gen_11_idc":false,"gclk_arch_gen_11_enable":false,"gclk_gen_11_div":1},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::GCLK::driver_definition::GCLK::HAL:HPL:GCLK","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::GCLK::driver_config_definition::GCLK::HAL:HPL:GCLK","module":"GCLK"}},{"functionality":null,"identifier":"OSC32KCTRL","user_label":"OSC32KCTRL","api":"HAL:HPL:OSC32KCTRL","configuration":{"enable_rtc_source":false,"rtc_source_oscillator":"32kHz Ultra Low Power Internal Oscillator (OSCULP32K)","rtc_1khz_selection":true,"enable_xosc32k":false,"xosc32k_arch_enable":false,"xosc32k_arch_startup":"62592us","xosc32k_arch_ondemand":true,"xosc32k_arch_runstdby":false,"xosc32k_arch_en1k":false,"xosc32k_arch_en32k":false,"xosc32k_arch_swben":false,"xosc32k_arch_cfden":false,"xosc32k_arch_cfdeo":false,"xosc32k_arch_xtalen":false,"xosc32k_arch_cgm":"Standard mode","enable_osculp32k":true,"osculp32k_calib_enable":false,"osculp32k_calib":0},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::OSC32KCTRL::driver_definition::OSC32KCTRL::HAL:HPL:OSC32KCTRL","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::OSC32KCTRL::driver_config_definition::OSC32KCTRL::HAL:HPL:OSC32KCTRL","module":"OSC32KCTRL"}},{"functionality":null,"identifier":"MCLK","user_label":"MCLK","api":"HAL:HPL:MCLK","configuration":{"enable_cpu_clock":true,"cpu_clock_source":"Generic clock generator 0","cpu_div":"1","mclk_arch_lpdiv":"Divide by 4","mclk_arch_bupdiv":"Divide by 8","mclk_arch_hsdiv":"Divide by 1","nvm_wait_states":"0"},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::MCLK::driver_definition::MCLK::HAL:HPL:MCLK","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::MCLK::driver_config_definition::MCLK::HAL:HPL:MCLK","module":"MCLK"},"clocks":{"domain_group":{"configuration":null,"nodes":[{"name":"CPU","input":"CPU"}]}}},{"functionality":null,"identifier":"RAMECC","user_label":"RAMECC","api":"HAL:HPL:RAMECC","configuration":{},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::RAMECC::driver_definition::RAMECC::HAL:HPL:RAMECC","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::RAMECC::driver_config_definition::RAMECC::HAL:HPL:RAMECC","module":"RAMECC"}},{"functionality":null,"identifier":"OSCCTRL","user_label":"OSCCTRL","api":"HAL:HPL:OSCCTRL","configuration":{"enable_xosc0":false,"xosc0_frequency":12000000,"xosc0_arch_enable":false,"xosc0_arch_startup":"31us","xosc0_arch_swben":false,"xosc0_arch_cfden":false,"xosc0_arch_enalc":false,"xosc0_arch_lowbufgain":false,"xosc0_arch_ondemand":false,"xosc0_arch_runstdby":false,"xosc0_arch_xtalen":false,"enable_xosc1":true,"xosc1_frequency":12000000,"xosc1_arch_enable":true,"xosc1_arch_startup":"31us","xosc1_arch_swben":false,"xosc1_arch_cfden":false,"xosc1_arch_enalc":false,"xosc1_arch_lowbufgain":false,"xosc1_arch_ondemand":false,"xosc1_arch_runstdby":false,"xosc1_arch_xtalen":true,"enable_dfll":false,"dfll_ref_clock":"Generic clock generator 3","dfll_arch_enable":false,"dfll_arch_ondemand":false,"dfll_arch_runstdby":false,"dfll_arch_usbcrm":false,"dfll_arch_waitlock":true,"dfll_arch_bplckc":false,"dfll_arch_qldis":false,"dfll_arch_ccdis":false,"dfll_arch_llaw":false,"dfll_arch_stable":false,"dfll_mode":"Open Loop Mode","dfll_arch_cstep":1,"dfll_arch_fstep":1,"dfll_mul":0,"dfll_arch_calibration":false,"dfll_arch_coarse":31,"dfll_arch_fine":128,"enable_fdpll0":false,"fdpll0_ref_clock":"32kHz External Crystal Oscillator (XOSC32K)","fdpll0_arch_enable":false,"fdpll0_arch_ondemand":false,"fdpll0_arch_runstdby":false,"fdpll0_ldrfrac":13,"fdpll0_ldr":1463,"fdpll0_clock_div":0,"fdpll0_arch_dcoen":false,"fdpll0_clock_dcofilter":0,"fdpll0_arch_lbypass":false,"fdpll0_arch_ltime":"No time-out, automatic lock","fdpll0_arch_refclk":"XOSC32K clock reference","fdpll0_arch_wuf":false,"fdpll0_arch_filter":0,"enable_fdpll1":false,"fdpll1_ref_clock":"32kHz External Crystal Oscillator (XOSC32K)","fdpll1_arch_enable":false,"fdpll1_arch_ondemand":false,"fdpll1_arch_runstdby":false,"fdpll1_ldrfrac":13,"fdpll1_ldr":1463,"fdpll1_clock_div":0,"fdpll1_arch_dcoen":false,"fdpll1_clock_dcofilter":0,"fdpll1_arch_lbypass":false,"fdpll1_arch_ltime":"No time-out, automatic lock","fdpll1_arch_refclk":"XOSC32K clock reference","fdpll1_arch_wuf":false,"fdpll1_arch_filter":0},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::OSCCTRL::driver_definition::OSCCTRL::HAL:HPL:OSCCTRL","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::OSCCTRL::driver_config_definition::OSCCTRL::HAL:HPL:OSCCTRL","module":"OSCCTRL"}},{"functionality":null,"identifier":"DMAC","user_label":"DMAC","api":"HAL:HPL:DMAC","configuration":{"dmac_enable":false,"dmac_lvlen0":true,"dmac_rrlvlen0":"Static arbitration scheme for channel with priority 0","dmac_lvlpri0":0,"dmac_lvlen1":true,"dmac_rrlvlen1":"Static arbitration scheme for channel with priority 1","dmac_lvlpri1":0,"dmac_lvlen2":true,"dmac_rrlvlen2":"Static arbitration scheme for channel with priority 2","dmac_lvlpri2":0,"dmac_lvlen3":true,"dmac_rrlvlen3":"Static arbitration scheme for channel with priority 3","dmac_lvlpri3":0,"dmac_dbgrun":false,"dmac_channel_0_settings":false,"dmac_runstdby_0":false,"dmac_trigact_0":"One trigger required for each block transfer","dmac_trifsrc_0":"Only software/event triggers","dmac_lvl_0":"Channel priority 0","dmac_evoe_0":false,"dmac_evie_0":false,"dmac_evact_0":"No action","dmac_stepsize_0":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_0":"Step size settings apply to the destination address","dmac_srcinc_0":false,"dmac_dstinc_0":false,"dmac_beatsize_0":"8-bit bus transfer","dmac_blockact_0":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_0":"Event generation disabled","dmac_channel_1_settings":false,"dmac_runstdby_1":false,"dmac_trigact_1":"One trigger required for each block transfer","dmac_trifsrc_1":"Only software/event triggers","dmac_lvl_1":"Channel priority 0","dmac_evoe_1":false,"dmac_evie_1":false,"dmac_evact_1":"No action","dmac_stepsize_1":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_1":"Step size settings apply to the destination address","dmac_srcinc_1":false,"dmac_dstinc_1":false,"dmac_beatsize_1":"8-bit bus transfer","dmac_blockact_1":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_1":"Event generation disabled","dmac_channel_2_settings":false,"dmac_runstdby_2":false,"dmac_trigact_2":"One trigger required for each block transfer","dmac_trifsrc_2":"Only software/event triggers","dmac_lvl_2":"Channel priority 0","dmac_evoe_2":false,"dmac_evie_2":false,"dmac_evact_2":"No action","dmac_stepsize_2":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_2":"Step size settings apply to the destination address","dmac_srcinc_2":false,"dmac_dstinc_2":false,"dmac_beatsize_2":"8-bit bus transfer","dmac_blockact_2":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_2":"Event generation disabled","dmac_channel_3_settings":false,"dmac_runstdby_3":false,"dmac_trigact_3":"One trigger required for each block transfer","dmac_trifsrc_3":"Only software/event triggers","dmac_lvl_3":"Channel priority 0","dmac_evoe_3":false,"dmac_evie_3":false,"dmac_evact_3":"No action","dmac_stepsize_3":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_3":"Step size settings apply to the destination address","dmac_srcinc_3":false,"dmac_dstinc_3":false,"dmac_beatsize_3":"8-bit bus transfer","dmac_blockact_3":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_3":"Event generation disabled","dmac_channel_4_settings":false,"dmac_runstdby_4":false,"dmac_trigact_4":"One trigger required for each block transfer","dmac_trifsrc_4":"Only software/event triggers","dmac_lvl_4":"Channel priority 0","dmac_evoe_4":false,"dmac_evie_4":false,"dmac_evact_4":"No action","dmac_stepsize_4":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_4":"Step size settings apply to the destination address","dmac_srcinc_4":false,"dmac_dstinc_4":false,"dmac_beatsize_4":"8-bit bus transfer","dmac_blockact_4":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_4":"Event generation disabled","dmac_channel_5_settings":false,"dmac_runstdby_5":false,"dmac_trigact_5":"One trigger required for each block transfer","dmac_trifsrc_5":"Only software/event triggers","dmac_lvl_5":"Channel priority 0","dmac_evoe_5":false,"dmac_evie_5":false,"dmac_evact_5":"No action","dmac_stepsize_5":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_5":"Step size settings apply to the destination address","dmac_srcinc_5":false,"dmac_dstinc_5":false,"dmac_beatsize_5":"8-bit bus transfer","dmac_blockact_5":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_5":"Event generation disabled","dmac_channel_6_settings":false,"dmac_runstdby_6":false,"dmac_trigact_6":"One trigger required for each block transfer","dmac_trifsrc_6":"Only software/event triggers","dmac_lvl_6":"Channel priority 0","dmac_evoe_6":false,"dmac_evie_6":false,"dmac_evact_6":"No action","dmac_stepsize_6":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_6":"Step size settings apply to the destination address","dmac_srcinc_6":false,"dmac_dstinc_6":false,"dmac_beatsize_6":"8-bit bus transfer","dmac_blockact_6":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_6":"Event generation disabled","dmac_channel_7_settings":false,"dmac_runstdby_7":false,"dmac_trigact_7":"One trigger required for each block transfer","dmac_trifsrc_7":"Only software/event triggers","dmac_lvl_7":"Channel priority 0","dmac_evoe_7":false,"dmac_evie_7":false,"dmac_evact_7":"No action","dmac_stepsize_7":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_7":"Step size settings apply to the destination address","dmac_srcinc_7":false,"dmac_dstinc_7":false,"dmac_beatsize_7":"8-bit bus transfer","dmac_blockact_7":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_7":"Event generation disabled","dmac_channel_8_settings":false,"dmac_runstdby_8":false,"dmac_trigact_8":"One trigger required for each block transfer","dmac_trifsrc_8":"Only software/event triggers","dmac_lvl_8":"Channel priority 0","dmac_evoe_8":false,"dmac_evie_8":false,"dmac_evact_8":"No action","dmac_stepsize_8":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_8":"Step size settings apply to the destination address","dmac_srcinc_8":false,"dmac_dstinc_8":false,"dmac_beatsize_8":"8-bit bus transfer","dmac_blockact_8":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_8":"Event generation disabled","dmac_channel_9_settings":false,"dmac_runstdby_9":false,"dmac_trigact_9":"One trigger required for each block transfer","dmac_trifsrc_9":"Only software/event triggers","dmac_lvl_9":"Channel priority 0","dmac_evoe_9":false,"dmac_evie_9":false,"dmac_evact_9":"No action","dmac_stepsize_9":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_9":"Step size settings apply to the destination address","dmac_srcinc_9":false,"dmac_dstinc_9":false,"dmac_beatsize_9":"8-bit bus transfer","dmac_blockact_9":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_9":"Event generation disabled","dmac_channel_10_settings":false,"dmac_runstdby_10":false,"dmac_trigact_10":"One trigger required for each block transfer","dmac_trifsrc_10":"Only software/event triggers","dmac_lvl_10":"Channel priority 0","dmac_evoe_10":false,"dmac_evie_10":false,"dmac_evact_10":"No action","dmac_stepsize_10":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_10":"Step size settings apply to the destination address","dmac_srcinc_10":false,"dmac_dstinc_10":false,"dmac_beatsize_10":"8-bit bus transfer","dmac_blockact_10":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_10":"Event generation disabled","dmac_channel_11_settings":false,"dmac_runstdby_11":false,"dmac_trigact_11":"One trigger required for each block transfer","dmac_trifsrc_11":"Only software/event triggers","dmac_lvl_11":"Channel priority 0","dmac_evoe_11":false,"dmac_evie_11":false,"dmac_evact_11":"No action","dmac_stepsize_11":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_11":"Step size settings apply to the destination address","dmac_srcinc_11":false,"dmac_dstinc_11":false,"dmac_beatsize_11":"8-bit bus transfer","dmac_blockact_11":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_11":"Event generation disabled","dmac_channel_12_settings":false,"dmac_runstdby_12":false,"dmac_trigact_12":"One trigger required for each block transfer","dmac_trifsrc_12":"Only software/event triggers","dmac_lvl_12":"Channel priority 0","dmac_evoe_12":false,"dmac_evie_12":false,"dmac_evact_12":"No action","dmac_stepsize_12":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_12":"Step size settings apply to the destination address","dmac_srcinc_12":false,"dmac_dstinc_12":false,"dmac_beatsize_12":"8-bit bus transfer","dmac_blockact_12":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_12":"Event generation disabled","dmac_channel_13_settings":false,"dmac_runstdby_13":false,"dmac_trigact_13":"One trigger required for each block transfer","dmac_trifsrc_13":"Only software/event triggers","dmac_lvl_13":"Channel priority 0","dmac_evoe_13":false,"dmac_evie_13":false,"dmac_evact_13":"No action","dmac_stepsize_13":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_13":"Step size settings apply to the destination address","dmac_srcinc_13":false,"dmac_dstinc_13":false,"dmac_beatsize_13":"8-bit bus transfer","dmac_blockact_13":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_13":"Event generation disabled","dmac_channel_14_settings":false,"dmac_runstdby_14":false,"dmac_trigact_14":"One trigger required for each block transfer","dmac_trifsrc_14":"Only software/event triggers","dmac_lvl_14":"Channel priority 0","dmac_evoe_14":false,"dmac_evie_14":false,"dmac_evact_14":"No action","dmac_stepsize_14":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_14":"Step size settings apply to the destination address","dmac_srcinc_14":false,"dmac_dstinc_14":false,"dmac_beatsize_14":"8-bit bus transfer","dmac_blockact_14":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_14":"Event generation disabled","dmac_channel_15_settings":false,"dmac_runstdby_15":false,"dmac_trigact_15":"One trigger required for each block transfer","dmac_trifsrc_15":"Only software/event triggers","dmac_lvl_15":"Channel priority 0","dmac_evoe_15":false,"dmac_evie_15":false,"dmac_evact_15":"No action","dmac_stepsize_15":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_15":"Step size settings apply to the destination address","dmac_srcinc_15":false,"dmac_dstinc_15":false,"dmac_beatsize_15":"8-bit bus transfer","dmac_blockact_15":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_15":"Event generation disabled","dmac_channel_16_settings":false,"dmac_runstdby_16":false,"dmac_trigact_16":"One trigger required for each block transfer","dmac_trifsrc_16":"Only software/event triggers","dmac_lvl_16":"Channel priority 0","dmac_evoe_16":false,"dmac_evie_16":false,"dmac_evact_16":"No action","dmac_stepsize_16":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_16":"Step size settings apply to the destination address","dmac_srcinc_16":false,"dmac_dstinc_16":false,"dmac_beatsize_16":"8-bit bus transfer","dmac_blockact_16":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_16":"Event generation disabled","dmac_channel_17_settings":false,"dmac_runstdby_17":false,"dmac_trigact_17":"One trigger required for each block transfer","dmac_trifsrc_17":"Only software/event triggers","dmac_lvl_17":"Channel priority 0","dmac_evoe_17":false,"dmac_evie_17":false,"dmac_evact_17":"No action","dmac_stepsize_17":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_17":"Step size settings apply to the destination address","dmac_srcinc_17":false,"dmac_dstinc_17":false,"dmac_beatsize_17":"8-bit bus transfer","dmac_blockact_17":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_17":"Event generation disabled","dmac_channel_18_settings":false,"dmac_runstdby_18":false,"dmac_trigact_18":"One trigger required for each block transfer","dmac_trifsrc_18":"Only software/event triggers","dmac_lvl_18":"Channel priority 0","dmac_evoe_18":false,"dmac_evie_18":false,"dmac_evact_18":"No action","dmac_stepsize_18":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_18":"Step size settings apply to the destination address","dmac_srcinc_18":false,"dmac_dstinc_18":false,"dmac_beatsize_18":"8-bit bus transfer","dmac_blockact_18":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_18":"Event generation disabled","dmac_channel_19_settings":false,"dmac_runstdby_19":false,"dmac_trigact_19":"One trigger required for each block transfer","dmac_trifsrc_19":"Only software/event triggers","dmac_lvl_19":"Channel priority 0","dmac_evoe_19":false,"dmac_evie_19":false,"dmac_evact_19":"No action","dmac_stepsize_19":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_19":"Step size settings apply to the destination address","dmac_srcinc_19":false,"dmac_dstinc_19":false,"dmac_beatsize_19":"8-bit bus transfer","dmac_blockact_19":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_19":"Event generation disabled","dmac_channel_20_settings":false,"dmac_runstdby_20":false,"dmac_trigact_20":"One trigger required for each block transfer","dmac_trifsrc_20":"Only software/event triggers","dmac_lvl_20":"Channel priority 0","dmac_evoe_20":false,"dmac_evie_20":false,"dmac_evact_20":"No action","dmac_stepsize_20":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_20":"Step size settings apply to the destination address","dmac_srcinc_20":false,"dmac_dstinc_20":false,"dmac_beatsize_20":"8-bit bus transfer","dmac_blockact_20":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_20":"Event generation disabled","dmac_channel_21_settings":false,"dmac_runstdby_21":false,"dmac_trigact_21":"One trigger required for each block transfer","dmac_trifsrc_21":"Only software/event triggers","dmac_lvl_21":"Channel priority 0","dmac_evoe_21":false,"dmac_evie_21":false,"dmac_evact_21":"No action","dmac_stepsize_21":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_21":"Step size settings apply to the destination address","dmac_srcinc_21":false,"dmac_dstinc_21":false,"dmac_beatsize_21":"8-bit bus transfer","dmac_blockact_21":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_21":"Event generation disabled","dmac_channel_22_settings":false,"dmac_runstdby_22":false,"dmac_trigact_22":"One trigger required for each block transfer","dmac_trifsrc_22":"Only software/event triggers","dmac_lvl_22":"Channel priority 0","dmac_evoe_22":false,"dmac_evie_22":false,"dmac_evact_22":"No action","dmac_stepsize_22":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_22":"Step size settings apply to the destination address","dmac_srcinc_22":false,"dmac_dstinc_22":false,"dmac_beatsize_22":"8-bit bus transfer","dmac_blockact_22":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_22":"Event generation disabled","dmac_channel_23_settings":false,"dmac_runstdby_23":false,"dmac_trigact_23":"One trigger required for each block transfer","dmac_trifsrc_23":"Only software/event triggers","dmac_lvl_23":"Channel priority 0","dmac_evoe_23":false,"dmac_evie_23":false,"dmac_evact_23":"No action","dmac_stepsize_23":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_23":"Step size settings apply to the destination address","dmac_srcinc_23":false,"dmac_dstinc_23":false,"dmac_beatsize_23":"8-bit bus transfer","dmac_blockact_23":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_23":"Event generation disabled","dmac_channel_24_settings":false,"dmac_runstdby_24":false,"dmac_trigact_24":"One trigger required for each block transfer","dmac_trifsrc_24":"Only software/event triggers","dmac_lvl_24":"Channel priority 0","dmac_evoe_24":false,"dmac_evie_24":false,"dmac_evact_24":"No action","dmac_stepsize_24":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_24":"Step size settings apply to the destination address","dmac_srcinc_24":false,"dmac_dstinc_24":false,"dmac_beatsize_24":"8-bit bus transfer","dmac_blockact_24":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_24":"Event generation disabled","dmac_channel_25_settings":false,"dmac_runstdby_25":false,"dmac_trigact_25":"One trigger required for each block transfer","dmac_trifsrc_25":"Only software/event triggers","dmac_lvl_25":"Channel priority 0","dmac_evoe_25":false,"dmac_evie_25":false,"dmac_evact_25":"No action","dmac_stepsize_25":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_25":"Step size settings apply to the destination address","dmac_srcinc_25":false,"dmac_dstinc_25":false,"dmac_beatsize_25":"8-bit bus transfer","dmac_blockact_25":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_25":"Event generation disabled","dmac_channel_26_settings":false,"dmac_runstdby_26":false,"dmac_trigact_26":"One trigger required for each block transfer","dmac_trifsrc_26":"Only software/event triggers","dmac_lvl_26":"Channel priority 0","dmac_evoe_26":false,"dmac_evie_26":false,"dmac_evact_26":"No action","dmac_stepsize_26":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_26":"Step size settings apply to the destination address","dmac_srcinc_26":false,"dmac_dstinc_26":false,"dmac_beatsize_26":"8-bit bus transfer","dmac_blockact_26":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_26":"Event generation disabled","dmac_channel_27_settings":false,"dmac_runstdby_27":false,"dmac_trigact_27":"One trigger required for each block transfer","dmac_trifsrc_27":"Only software/event triggers","dmac_lvl_27":"Channel priority 0","dmac_evoe_27":false,"dmac_evie_27":false,"dmac_evact_27":"No action","dmac_stepsize_27":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_27":"Step size settings apply to the destination address","dmac_srcinc_27":false,"dmac_dstinc_27":false,"dmac_beatsize_27":"8-bit bus transfer","dmac_blockact_27":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_27":"Event generation disabled","dmac_channel_28_settings":false,"dmac_runstdby_28":false,"dmac_trigact_28":"One trigger required for each block transfer","dmac_trifsrc_28":"Only software/event triggers","dmac_lvl_28":"Channel priority 0","dmac_evoe_28":false,"dmac_evie_28":false,"dmac_evact_28":"No action","dmac_stepsize_28":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_28":"Step size settings apply to the destination address","dmac_srcinc_28":false,"dmac_dstinc_28":false,"dmac_beatsize_28":"8-bit bus transfer","dmac_blockact_28":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_28":"Event generation disabled","dmac_channel_29_settings":false,"dmac_runstdby_29":false,"dmac_trigact_29":"One trigger required for each block transfer","dmac_trifsrc_29":"Only software/event triggers","dmac_lvl_29":"Channel priority 0","dmac_evoe_29":false,"dmac_evie_29":false,"dmac_evact_29":"No action","dmac_stepsize_29":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_29":"Step size settings apply to the destination address","dmac_srcinc_29":false,"dmac_dstinc_29":false,"dmac_beatsize_29":"8-bit bus transfer","dmac_blockact_29":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_29":"Event generation disabled","dmac_channel_30_settings":false,"dmac_runstdby_30":false,"dmac_trigact_30":"One trigger required for each block transfer","dmac_trifsrc_30":"Only software/event triggers","dmac_lvl_30":"Channel priority 0","dmac_evoe_30":false,"dmac_evie_30":false,"dmac_evact_30":"No action","dmac_stepsize_30":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_30":"Step size settings apply to the destination address","dmac_srcinc_30":false,"dmac_dstinc_30":false,"dmac_beatsize_30":"8-bit bus transfer","dmac_blockact_30":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_30":"Event generation disabled","dmac_channel_31_settings":false,"dmac_runstdby_31":false,"dmac_trigact_31":"One trigger required for each block transfer","dmac_trifsrc_31":"Only software/event triggers","dmac_lvl_31":"Channel priority 0","dmac_evoe_31":false,"dmac_evie_31":false,"dmac_evact_31":"No action","dmac_stepsize_31":"Next ADDR = ADDR + (BEATSIZE + 1) * 1","dmac_stepsel_31":"Step size settings apply to the destination address","dmac_srcinc_31":false,"dmac_dstinc_31":false,"dmac_beatsize_31":"8-bit bus transfer","dmac_blockact_31":"Channel will be disabled if it is the last block transfer in the transaction","dmac_evosel_31":"Event generation disabled"},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::DMAC::driver_definition::DMAC::HAL:HPL:DMAC","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::DMAC::driver_config_definition::DMAC::HAL:HPL:DMAC","module":"DMAC"}},{"functionality":"ADC","identifier":"ADC_0","user_label":"ADC_0","api":"HAL:Driver:ADC_Sync","configuration":{"adc_arch_startinv":false,"adc_reference":"Internal bandgap reference","adc_arch_flushinv":false,"adc_arch_flushei":false,"adc_arch_winmoneo":false,"adc_arch_adjres":0,"adc_resolution":"12-bit","adc_arch_refcomp":false,"adc_arch_gaincorr":0,"adc_arch_samplen":0,"adc_arch_offsetcorr":0,"adc_arch_leftadj":false,"adc_arch_dbgrun":false,"adc_advanced_settings":false,"adc_arch_corren":false,"adc_pinmux_negative":"ADC AIN0 pin","adc_arch_winmode":"No window mode","adc_prescaler":"Peripheral clock divided by 2","adc_arch_samplenum":"1 sample","adc_pinmux_positive":"ADC AIN0 pin","adc_arch_seqen":0,"adc_arch_runstdby":false,"adc_arch_winlt":0,"adc_arch_offcomp":false,"adc_arch_event_settings":false,"adc_arch_resrdyeo":false,"adc_differential_mode":false,"adc_arch_ondemand":false,"adc_freerunning_mode":false,"adc_arch_winut":0,"adc_arch_startei":false},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::ADC::driver_definition::ADC::HAL:Driver:ADC.Sync","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::ADC0::driver_config_definition::ADC::HAL:Driver:ADC.Sync","module":"ADC0"},"clocks":{"domain_group":{"configuration":null,"nodes":[{"name":"ADC","input":"Generic clock generator 0"}]}}},{"functionality":"DAC","identifier":"DAC_0","user_label":"DAC_0","api":"HAL:Driver:DAC_Sync","configuration":{"dac0_arch_runstdby":false,"dac0_arch_cctrl":"GCLK_DAC <= 1.2MHz (100kSPS)","dac1_arch_runstdby":false,"dac_advanced_settings":false,"adc_arch_dbgrun":true,"dac0_arch_leftadj":false,"dac1_arch_leftadj":false,"dac_arch_refsel":"Unbuffered external voltage reference","dac_arch_startei_0":false,"dac1_arch_cctrl":"GCLK_DAC <= 1.2MHz (100kSPS)","dac_arch_emptyeo_0":false,"dac_arch_emptyeo_1":false,"dac1_arch_refresh":0,"dac0_arch_refresh":0,"dac1_arch_ditrher":false,"dac_arch_invei0":"Detection on rising edge pf the input event","dac_arch_invei1":"Detection on rising edge pf the input event","dac_arch_startei_1":false,"dac0_arch_ditrher":false,"dac_arch_diff":false},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::DAC::driver_definition::DAC::HAL:Driver:DAC.Sync","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::DAC::driver_config_definition::DAC::HAL:Driver:DAC.Sync","module":"DAC"},"clocks":{"domain_group":{"configuration":null,"nodes":[{"name":"DAC","input":"Generic clock generator 0"}]}}},{"functionality":"Event_System","identifier":"EVENT_SYSTEM_0","user_label":"EVENT_SYSTEM_0","api":"HAL:Driver:Event_system","configuration":{"evsys_runstdby_17":false,"evsys_runstdby_16":false,"evsys_runstdby_15":false,"evsys_runstdby_14":false,"evsys_runstdby_13":false,"evsys_runstdby_12":false,"evsys_runstdby_11":false,"evsys_runstdby_10":false,"evsys_runstdby_19":false,"evsys_runstdby_18":false,"evsys_channel_6":"No channel output selected","evsys_channel_7":"No channel output selected","evsys_channel_4":"No channel output selected","evsys_channel_5":"No channel output selected","evsys_channel_2":"No channel output selected","evsys_channel_3":"No channel output selected","evsys_channel_0":"No channel output selected","evsys_channel_1":"No channel output selected","evsys_path_31":"Synchronous path","evsys_path_30":"Synchronous path","evsys_channel_8":"No channel output selected","evsys_channel_9":"No channel output selected","evsys_evgen_8":"No event generator","evsys_channel_setting_6":false,"evsys_ondemand_14":false,"evsys_ondemand_15":false,"evsys_channel_setting_3":false,"evsys_channel_setting_2":false,"evsys_channel_setting_1":false,"evsys_channel_setting_0":false,"evsys_evgen_0":"No event generator","evsys_evgen_1":"No event generator","evsys_evgen_2":"No event generator","evsys_evgen_3":"No event generator","evsys_evgen_4":"No event generator","evsys_evgen_5":"No event generator","evsys_channel_setting_9":false,"evsys_channel_setting_8":false,"evsys_evd_16":false,"evsys_evd_17":false,"evsys_evd_14":false,"evsys_evgen_29":"No event generator","evsys_evgen_28":"No event generator","evsys_evgen_23":"No event generator","evsys_evgen_22":"No event generator","evsys_evgen_21":"No event generator","evsys_evgen_20":"No event generator","evsys_evgen_27":"No event generator","evsys_evgen_26":"No event generator","evsys_evgen_25":"No event generator","evsys_evgen_24":"No event generator","evsys_evd_10":false,"evsys_evd_11":false,"evsys_edgsel_30":"No event output when using the resynchronized or synchronous path","evsys_edgsel_31":"No event output when using the resynchronized or synchronous path","evsys_ondemand_17":false,"evsys_path_19":"Synchronous path","evsys_path_18":"Synchronous path","evsys_evd_18":false,"evsys_path_13":"Synchronous path","evsys_path_12":"Synchronous path","evsys_path_11":"Synchronous path","evsys_evd_19":false,"evsys_path_17":"Synchronous path","evsys_path_16":"Synchronous path","evsys_path_15":"Synchronous path","evsys_path_14":"Synchronous path","evsys_ondemand_30":false,"evsys_ondemand_31":false,"evsys_channel_setting_28":false,"evsys_channel_setting_29":false,"evsys_channel_setting_26":false,"evsys_channel_setting_27":false,"evsys_channel_setting_24":false,"evsys_channel_setting_25":false,"evsys_channel_setting_22":false,"evsys_channel_setting_23":false,"evsys_channel_setting_20":false,"evsys_channel_setting_21":false,"evsys_ovr_12":false,"evsys_evgen_13":"No event generator","evsys_ovr_0":false,"evsys_ovr_1":false,"evsys_ovr_2":false,"evsys_ovr_3":false,"evsys_ovr_4":false,"evsys_ovr_5":false,"evsys_ovr_6":false,"evsys_ovr_7":false,"evsys_ovr_8":false,"evsys_ovr_9":false,"evsys_ondemand_16":false,"evsys_channel_setting_7":false,"evsys_evd_29":false,"evsys_evd_28":false,"evsys_ovr_30":false,"evsys_ovr_31":false,"evsys_evgen_9":"No event generator","evsys_evd_23":false,"evsys_evd_22":false,"evsys_evd_21":false,"evsys_evd_20":false,"evsys_evd_27":false,"evsys_channel_setting_5":false,"evsys_evd_25":false,"evsys_evd_24":false,"evsys_channel_21":"No channel output selected","evsys_channel_20":"No channel output selected","evsys_channel_23":"No channel output selected","evsys_channel_setting_4":false,"evsys_channel_25":"No channel output selected","evsys_channel_24":"No channel output selected","evsys_channel_27":"No channel output selected","evsys_channel_26":"No channel output selected","evsys_channel_29":"No channel output selected","evsys_channel_28":"No channel output selected","evsys_ondemand_13":false,"evsys_ondemand_10":false,"evsys_ondemand_11":false,"evsys_edgsel_29":"No event output when using the resynchronized or synchronous path","evsys_edgsel_28":"No event output when using the resynchronized or synchronous path","evsys_ondemand_12":false,"evsys_path_9":"Synchronous path","evsys_path_8":"Synchronous path","evsys_path_7":"Synchronous path","evsys_path_6":"Synchronous path","evsys_path_5":"Synchronous path","evsys_path_4":"Synchronous path","evsys_path_3":"Synchronous path","evsys_path_2":"Synchronous path","evsys_path_1":"Synchronous path","evsys_path_0":"Synchronous path","evsys_channel_36":"No channel output selected","evsys_ondemand_18":false,"evsys_channel_37":"No channel output selected","evsys_ondemand_19":false,"evsys_evgen_6":"No event generator","evsys_evgen_12":"No event generator","evsys_ovr_13":false,"evsys_evgen_10":"No event generator","evsys_ovr_11":false,"evsys_evgen_16":"No event generator","evsys_evgen_17":"No event generator","evsys_ovr_14":false,"evsys_evgen_15":"No event generator","evsys_ovr_18":false,"evsys_ovr_19":false,"evsys_channel_47":"No channel output selected","evsys_channel_46":"No channel output selected","evsys_channel_45":"No channel output selected","evsys_channel_44":"No channel output selected","evsys_channel_43":"No channel output selected","evsys_channel_42":"No channel output selected","evsys_channel_41":"No channel output selected","evsys_channel_40":"No channel output selected","evsys_channel_49":"No channel output selected","evsys_channel_48":"No channel output selected","evsys_runstdby_22":false,"evsys_runstdby_23":false,"evsys_runstdby_20":false,"evsys_runstdby_21":false,"evsys_runstdby_26":false,"evsys_runstdby_27":false,"evsys_runstdby_24":false,"evsys_runstdby_25":false,"evsys_runstdby_28":false,"evsys_runstdby_29":false,"evsys_ovr_10":false,"evsys_evgen_11":"No event generator","evsys_evd_12":false,"evsys_ovr_17":false,"evsys_evgen_14":"No event generator","evsys_evgen_7":"No event generator","evsys_ovr_15":false,"evsys_evd_13":false,"evsys_evgen_18":"No event generator","evsys_evgen_19":"No event generator","evsys_evgen_30":"No event generator","evsys_evgen_31":"No event generator","evsys_edgsel_21":"No event output when using the resynchronized or synchronous path","evsys_edgsel_20":"No event output when using the resynchronized or synchronous path","evsys_edgsel_23":"No event output when using the resynchronized or synchronous path","evsys_edgsel_22":"No event output when using the resynchronized or synchronous path","evsys_edgsel_25":"No event output when using the resynchronized or synchronous path","evsys_edgsel_24":"No event output when using the resynchronized or synchronous path","evsys_edgsel_27":"No event output when using the resynchronized or synchronous path","evsys_edgsel_26":"No event output when using the resynchronized or synchronous path","evsys_channel_65":"No channel output selected","evsys_channel_64":"No channel output selected","evsys_channel_66":"No channel output selected","evsys_channel_61":"No channel output selected","evsys_channel_60":"No channel output selected","evsys_channel_63":"No channel output selected","evsys_channel_62":"No channel output selected","evsys_path_28":"Synchronous path","evsys_path_29":"Synchronous path","evsys_path_26":"Synchronous path","evsys_path_27":"Synchronous path","evsys_path_24":"Synchronous path","evsys_path_25":"Synchronous path","evsys_path_22":"Synchronous path","evsys_path_23":"Synchronous path","evsys_path_20":"Synchronous path","evsys_path_21":"Synchronous path","evsys_channel_18":"No channel output selected","evsys_channel_19":"No channel output selected","evsys_channel_10":"No channel output selected","evsys_channel_11":"No channel output selected","evsys_channel_12":"No channel output selected","evsys_channel_17":"No channel output selected","evsys_ondemand_29":false,"evsys_ondemand_28":false,"evsys_ondemand_23":false,"evsys_ondemand_22":false,"evsys_ondemand_21":false,"evsys_ondemand_20":false,"evsys_ondemand_27":false,"evsys_ondemand_26":false,"evsys_ondemand_25":false,"evsys_ondemand_24":false,"evsys_channel_setting_19":false,"evsys_channel_setting_18":false,"evsys_channel_setting_13":false,"evsys_channel_setting_12":false,"evsys_channel_setting_11":false,"evsys_channel_setting_10":false,"evsys_channel_setting_17":false,"evsys_channel_setting_16":false,"evsys_channel_setting_15":false,"evsys_channel_setting_14":false,"evsys_evd_4":false,"evsys_evd_5":false,"evsys_evd_6":false,"evsys_evd_7":false,"evsys_evd_0":false,"evsys_evd_1":false,"evsys_evd_2":false,"evsys_evd_3":false,"evsys_evd_8":false,"evsys_evd_9":false,"evsys_channel_38":"No channel output selected","evsys_channel_39":"No channel output selected","evsys_evd_30":false,"evsys_evd_31":false,"evsys_channel_34":"No channel output selected","evsys_channel_35":"No channel output selected","evsys_channel_32":"No channel output selected","evsys_channel_33":"No channel output selected","evsys_channel_30":"No channel output selected","evsys_channel_31":"No channel output selected","evsys_channel_setting_31":false,"evsys_channel_setting_30":false,"evsys_evd_26":false,"evsys_channel_22":"No channel output selected","evsys_ovr_16":false,"evsys_ovr_27":false,"evsys_ovr_26":false,"evsys_ovr_25":false,"evsys_evd_15":false,"evsys_ovr_23":false,"evsys_ovr_22":false,"evsys_ovr_21":false,"evsys_ovr_20":false,"evsys_ovr_29":false,"evsys_ovr_28":false,"evsys_channel_54":"No channel output selected","evsys_channel_55":"No channel output selected","evsys_channel_56":"No channel output selected","evsys_channel_57":"No channel output selected","evsys_channel_50":"No channel output selected","evsys_channel_51":"No channel output selected","evsys_channel_52":"No channel output selected","evsys_channel_53":"No channel output selected","evsys_channel_58":"No channel output selected","evsys_channel_59":"No channel output selected","evsys_runstdby_31":false,"evsys_runstdby_30":false,"evsys_ondemand_8":false,"evsys_ondemand_9":false,"evsys_ondemand_4":false,"evsys_ondemand_5":false,"evsys_ondemand_6":false,"evsys_ondemand_7":false,"evsys_ondemand_0":false,"evsys_ondemand_1":false,"evsys_ondemand_2":false,"evsys_ondemand_3":false,"evsys_edgsel_14":"No event output when using the resynchronized or synchronous path","evsys_path_10":"Synchronous path","evsys_edgsel_15":"No event output when using the resynchronized or synchronous path","evsys_edgsel_16":"No event output when using the resynchronized or synchronous path","evsys_edgsel_17":"No event output when using the resynchronized or synchronous path","evsys_edgsel_10":"No event output when using the resynchronized or synchronous path","evsys_ovr_24":false,"evsys_edgsel_11":"No event output when using the resynchronized or synchronous path","evsys_edgsel_12":"No event output when using the resynchronized or synchronous path","evsys_edgsel_13":"No event output when using the resynchronized or synchronous path","evsys_edgsel_6":"No event output when using the resynchronized or synchronous path","evsys_edgsel_7":"No event output when using the resynchronized or synchronous path","evsys_edgsel_4":"No event output when using the resynchronized or synchronous path","evsys_edgsel_5":"No event output when using the resynchronized or synchronous path","evsys_edgsel_2":"No event output when using the resynchronized or synchronous path","evsys_edgsel_3":"No event output when using the resynchronized or synchronous path","evsys_edgsel_0":"No event output when using the resynchronized or synchronous path","evsys_edgsel_1":"No event output when using the resynchronized or synchronous path","evsys_edgsel_8":"No event output when using the resynchronized or synchronous path","evsys_edgsel_9":"No event output when using the resynchronized or synchronous path","evsys_runstdby_3":false,"evsys_runstdby_2":false,"evsys_runstdby_1":false,"evsys_runstdby_0":false,"evsys_runstdby_7":false,"evsys_runstdby_6":false,"evsys_runstdby_5":false,"evsys_runstdby_4":false,"evsys_runstdby_9":false,"evsys_runstdby_8":false,"evsys_edgsel_18":"No event output when using the resynchronized or synchronous path","evsys_edgsel_19":"No event output when using the resynchronized or synchronous path"},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::EVSYS::driver_definition::Event.System::HAL:Driver:Event.system","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::EVSYS::driver_config_definition::Event.System::HAL:Driver:Event.system","module":"EVSYS"},"clocks":{"domain_group":{"configuration":null,"nodes":[{"name":"Channel 0","input":"Generic clock generator 0"},{"name":"Channel 1","input":"Generic clock generator 0"},{"name":"Channel 10","input":"Generic clock generator 0"},{"name":"Channel 11","input":"Generic clock generator 0"},{"name":"Channel 2","input":"Generic clock generator 0"},{"name":"Channel 3","input":"Generic clock generator 0"},{"name":"Channel 4","input":"Generic clock generator 0"},{"name":"Channel 5","input":"Generic clock generator 0"},{"name":"Channel 6","input":"Generic clock generator 0"},{"name":"Channel 7","input":"Generic clock generator 0"},{"name":"Channel 8","input":"Generic clock generator 0"},{"name":"Channel 9","input":"Generic clock generator 0"}]}}},{"functionality":"Timer","identifier":"TIMER_0","user_label":"TIMER_0","api":"HAL:Driver:Timer","configuration":{"rtc_event_control":false,"rtc_arch_prescaler":"OFF(Peripheral clock divided by 1)","rtc_ovfeo":false,"rtc_tampereo":false,"rtc_pereo1":false,"rtc_pereo0":false,"rtc_pereo3":false,"rtc_arch_comp_val":1,"rtc_pereo5":false,"rtc_pereo4":false,"rtc_pereo7":false,"rtc_pereo6":false,"rtc_pereo2":false,"rtc_tampevei":false,"rtc_cmpeo0":false,"rtc_cmpeo1":false},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::RTC::driver_definition::Timer::HAL:Driver:Timer","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::RTC::driver_config_definition::Timer::HAL:Driver:Timer","module":"RTC"},"clocks":{"domain_group":{"configuration":null,"nodes":[{"name":"RTC","input":"RTC source"}]}}},{"functionality":"I2C","identifier":"I2C_0","user_label":"I2C_0","api":"HAL:Driver:I2C_Master_Sync","configuration":{"i2c_master_arch_mexttoen":false,"i2c_master_arch_inactout":"Disabled","i2c_master_arch_dbgstop":"Keep running","i2c_master_arch_sexttoen":false,"i2c_master_arch_lowtout":false,"i2c_master_baud_rate":100000,"i2c_master_arch_trise":215,"i2c_master_arch_runstdby":false,"i2c_master_arch_sdahold":"300-600ns hold time","i2c_master_advanced":false},"dependencies":{},"optional_signals":[],"variant":{"specification":"SDA=0, SCL=1","required_signals":[{"label":"SDA","identifier":"I2C_0:SDA","name":"SERCOM2/PAD/0","pad":"PA09","configuration":null,"definition":"","mode":"Enabled"},{"label":"SCL","identifier":"I2C_0:SCL","name":"SERCOM2/PAD/1","pad":"PA08","configuration":null,"definition":"","mode":"Enabled"}]},"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::SERCOM::driver_definition::I2C.Master.Standard~2FFast-mode::HAL:Driver:I2C.Master.Sync","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::SERCOM2::driver_config_definition::I2C.Master.Standard~2FFast-mode::HAL:Driver:I2C.Master.Sync","module":"SERCOM2"},"clocks":{"domain_group":{"configuration":null,"nodes":[{"name":"Core","input":"Generic clock generator 0"},{"name":"Slow","input":"Generic clock generator 3"}]}}},{"functionality":"SPI","identifier":"SPI_0","user_label":"SPI_0","api":"HAL:Driver:SPI_Master_Sync","configuration":{"spi_master_arch_dbgstop":"Keep running","spi_master_advanced":false,"spi_master_arch_cpol":"SCK is low when idle","spi_master_arch_runstdby":false,"spi_master_baud_rate":50000,"spi_master_character_size":"8 bits","spi_master_arch_dord":"MSB first","spi_master_arch_ibon":"In data stream","spi_master_arch_cpha":"Sample input on leading edge","spi_master_dummybyte":511,"spi_master_rx_enable":true},"dependencies":{},"optional_signals":[],"variant":{"specification":"TXPO=0, RXPO=2","required_signals":[{"label":"MOSI","identifier":"SPI_0:MOSI","name":"SERCOM0/PAD/0","pad":"PA04","configuration":null,"definition":"","mode":"Enabled"},{"label":"MISO","identifier":"SPI_0:MISO","name":"SERCOM0/PAD/2","pad":"PA06","configuration":null,"definition":"","mode":"Enabled"},{"label":"SCK","identifier":"SPI_0:SCK","name":"SERCOM0/PAD/1","pad":"PA05","configuration":null,"definition":"","mode":"Enabled"}]},"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::SERCOM::driver_definition::SPI.Master::HAL:Driver:SPI.Master.Sync","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::SERCOM0::driver_config_definition::SPI.Master::HAL:Driver:SPI.Master.Sync","module":"SERCOM0"},"clocks":{"domain_group":{"configuration":null,"nodes":[{"name":"Core","input":"Generic clock generator 0"},{"name":"Slow","input":"Generic clock generator 3"}]}}},{"functionality":"USART","identifier":"USART_0","user_label":"USART_0","api":"HAL:Driver:USART_Sync","configuration":{"usart_baud_rate":9600,"usart_arch_dord":"LSB is transmitted first","usart_parity":"No parity","usart_character_size":"8 bits","usart_arch_dbgstop":"Keep running","usart_arch_sfde":false,"usart_arch_enc":"No encoding","usart_arch_clock_mode":"USART with internal clock","usart_stop_bit":"One stop bit","usart_arch_sampa":"7-8-9 (3-4-5 8-bit over-sampling)","usart_advanced":false,"usart_arch_fractional":0,"usart_tx_enable":true,"usart_arch_cloden":false,"usart_arch_sampr":"16x arithmetic","usart_arch_runstdby":false,"usart_rx_enable":true,"usart_arch_ibon":false},"dependencies":{},"optional_signals":[],"variant":{"specification":"TXPO=0, RXPO=1, CMODE=0","required_signals":[{"label":"TX","identifier":"USART_0:TX","name":"SERCOM1/PAD/0","pad":"PA00","configuration":null,"definition":"","mode":"Enabled"},{"label":"RX","identifier":"USART_0:RX","name":"SERCOM1/PAD/1","pad":"PA01","configuration":null,"definition":"","mode":"Enabled"}]},"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::SERCOM::driver_definition::UART::HAL:Driver:USART.Sync","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::SERCOM1::driver_config_definition::UART::HAL:Driver:USART.Sync","module":"SERCOM1"},"clocks":{"domain_group":{"configuration":null,"nodes":[{"name":"Core","input":"Generic clock generator 0"},{"name":"Slow","input":"Generic clock generator 3"}]}}},{"functionality":"Delay","identifier":"DELAY_0","user_label":"DELAY_0","api":"HAL:Driver:Delay","configuration":{"systick_arch_tickint":false},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::SysTick::driver_definition::Delay::HAL:Driver:Delay","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::SysTick::driver_config_definition::Delay::HAL:Driver:Delay","module":"SysTick"}},{"functionality":"PWM","identifier":"PWM_0","user_label":"PWM_0","api":"HAL:Driver:PWM","configuration":{"tc_per":50,"tc_arch_mceo0":false,"tc_arch_mceo1":false,"tc_arch_tcinv":false,"tc_prescaler":"No division","tc_mode":"Counter in 16-bit mode","tc_arch_presync":"Reload or reset counter on next GCLK","tc_arch_ondemand":false,"tc_arch_runstdby":false,"tc_arch_alock":"The Lock Update bit is not affected on overflow/underflow and re-trigger event","timer_event_control":false,"tc_arch_dbgrun":false,"tc_arch_ovfeo":false,"tc_arch_tcei":false,"tc_arch_wave_duty_val":500,"tc_arch_wave_per_val":1000,"tc_arch_evact":"Event action disabled"},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::TC::driver_definition::PWM::HAL:Driver:PWM","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::TC0::driver_config_definition::PWM::HAL:Driver:PWM","module":"TC0"},"clocks":{"domain_group":{"configuration":null,"nodes":[{"name":"TC","input":"Generic clock generator 0"}]}}},{"functionality":"RAND","identifier":"RAND_0","user_label":"RAND_0","api":"HAL:Driver:RAND_Sync","configuration":{"trng_runstdby":false,"trng_datardyeo":false},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::TRNG::driver_definition::RAND::HAL:Driver:RAND.Sync","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::TRNG::driver_config_definition::RAND::HAL:Driver:RAND.Sync","module":"TRNG"}},{"functionality":"USB","identifier":"USB_DEVICE_INSTANCE","user_label":"USB_DEVICE_INSTANCE","api":"HAL:Driver:USB_Device","configuration":{"usb_arch_ep4_cache":"Cached by 64 bytes buffer","usb_arch_ep1_cache":"Cached by 64 bytes buffer","usb_arch_ep5_cache":"Cached by 64 bytes buffer","usb_ep5_I_CACHE":"No cache","usb_ep2_I_CACHE":"No cache","usb_ep4_I_CACHE":"No cache","usb_arch_ep7_cache":"Cached by 64 bytes buffer","usb_arch_ep2_cache":"Cached by 64 bytes buffer","usbd_num_ep_sp":"4 (EP0 + 3 endpoints)","usb_ep7_I_CACHE":"No cache","usb_arch_ep0_cache":"Cached by 64 bytes buffer","usbd_arch_max_ep_n":"2 (EP 0x82 or 0x02)","usb_ep1_I_CACHE":"No cache","usb_ep3_I_CACHE":"No cache","usbd_arch_speed":"Full speed","usb_arch_ep6_cache":"Cached by 64 bytes buffer","usb_ep6_I_CACHE":"No cache","usb_arch_ep3_cache":"Cached by 64 bytes buffer"},"dependencies":{},"optional_signals":[],"variant":{"specification":"default","required_signals":[{"label":"Data-","identifier":"USB_DEVICE_INSTANCE:Data-","name":"USB/DM","pad":"PA24","configuration":null,"definition":"","mode":"Enabled"},{"label":"Data+","identifier":"USB_DEVICE_INSTANCE:Data+","name":"USB/DP","pad":"PA25","configuration":null,"definition":"","mode":"Enabled"}]},"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::USB::driver_definition::USB.Device::HAL:Driver:USB.Device","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::USB::driver_config_definition::USB.Device::HAL:Driver:USB.Device","module":"USB"},"clocks":{"domain_group":{"configuration":null,"nodes":[{"name":"USB","input":"Generic clock generator 0"}]}}},{"functionality":"Flash","identifier":"FLASH_0","user_label":"FLASH_0","api":"HAL:Driver:FLASH","configuration":{"nvm_arch_sleepprm":"Wake On Access","nvm_arch_cache0":false,"nvm_arch_cache1":false},"dependencies":{},"optional_signals":[],"variant":null,"definition":{"base":"Atmel:SAMD51_Drivers:0.0.1::NVMCTRL::driver_definition::Flash::HAL:Driver:FLASH","identifier":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::NVMCTRL::driver_config_definition::Flash::HAL:Driver:FLASH","module":"NVMCTRL"}}],"pads":[{"name":"PA00","user_label":"PA00","definition":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::pad::PA00","mode":"Peripheral IO","configuration":null},{"name":"PA01","user_label":"PA01","definition":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::pad::PA01","mode":"Peripheral IO","configuration":null},{"name":"PA04","user_label":"PA04","definition":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::pad::PA04","mode":"Digital output","configuration":null},{"name":"PA05","user_label":"PA05","definition":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::pad::PA05","mode":"Digital output","configuration":null},{"name":"PA06","user_label":"PA06","definition":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::pad::PA06","mode":"Digital input","configuration":null},{"name":"PA08","user_label":"PA08","definition":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::pad::PA08","mode":"I2C","configuration":null},{"name":"PA09","user_label":"PA09","definition":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::pad::PA09","mode":"I2C","configuration":null},{"name":"PA24","user_label":"PA24","definition":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::pad::PA24","mode":"Advanced","configuration":null},{"name":"PA25","user_label":"PA25","definition":"Atmel:SAMD51_Drivers:0.0.1::SAMD51G19A-MF::pad::PA25","mode":"Advanced","configuration":null}]} diff --git a/ports/atmel-samd/tools/update_asf.py b/ports/atmel-samd/tools/update_asf.py new file mode 100644 index 00000000000..7b7bac10fe6 --- /dev/null +++ b/ports/atmel-samd/tools/update_asf.py @@ -0,0 +1,54 @@ +import requests +import zipfile +import os.path +import shutil +import sys +import subprocess + +for chip in ["samd21", "samd51"]: + r = None + filename = chip + ".zip" + if not os.path.isfile(filename): + with open("tools/" + chip + ".json", "r") as project_json: + headers = {"content-type": "text/plain"} + r = requests.post("http://start.atmel.com/api/v1/generate/?format=atzip&compilers=[make]&file_name_base=My%20Project", headers=headers, data=project_json) + if not r.ok: + # Double check that the JSON is minified. If its not, you'll get a 404. + print(r.text) + sys.exit(1) + with open(filename, "wb") as out: + out.write(r.content) + + # Extract to a temporary location and patch it before replacing the existing location. + z = zipfile.ZipFile(filename) + tmp_dir = "asf4/" + chip + "_vanilla" + z.extractall(tmp_dir) + + # Remove all carriage returns. + for dirpath, dirnames, filenames in os.walk(tmp_dir): + for fn in filenames: + fn = os.path.join(dirpath, fn) + subprocess.run(["sed", "-i", "s/\r//g", fn]) + + # Move files to match SAMD51 structure. + if chip == "samd21": + shutil.move("asf4/samd21_vanilla/samd21a/include", "asf4/samd21_vanilla") + shutil.move("asf4/samd21_vanilla/samd21a/gcc/gcc", "asf4/samd21_vanilla/gcc") + shutil.move("asf4/samd21_vanilla/samd21a/gcc/system_samd21.c", "asf4/samd21_vanilla/gcc") + + ok = True + for patch in os.listdir("asf4/patches/" + chip): + patch = "patches/" + chip + "/" + patch + print(patch) + result = subprocess.run(["patch", "-l", "-F", "10", "-u", "-p", "1", "-d", tmp_dir, "-i", "../" + patch]) + ok = ok and result.returncode == 0 + print() + + if ok: + real_dir = "asf4/" + chip + shutil.rmtree(real_dir) + shutil.move(tmp_dir, real_dir) + # delete the zip on success + os.remove(filename) + else: + print("A patch failed!") diff --git a/ports/cc3200/mods/modwlan.c b/ports/cc3200/mods/modwlan.c index 8acc89da38b..c27e993bc01 100644 --- a/ports/cc3200/mods/modwlan.c +++ b/ports/cc3200/mods/modwlan.c @@ -29,6 +29,7 @@ #include #include "simplelink.h" +#include "py/ioctl.h" #include "py/mpconfig.h" #include "py/obj.h" #include "py/objstr.h" diff --git a/ports/cc3200/mptask.c b/ports/cc3200/mptask.c index 6143f72a7a6..81048d1e7ef 100644 --- a/ports/cc3200/mptask.c +++ b/ports/cc3200/mptask.c @@ -180,7 +180,7 @@ void TASK_MicroPython (void *pvParameters) { if (!safeboot) { // run boot.py - int ret = pyexec_file("boot.py"); + int ret = pyexec_file("boot.py", NULL); if (ret & PYEXEC_FORCED_EXIT) { goto soft_reset_exit; } @@ -205,7 +205,7 @@ void TASK_MicroPython (void *pvParameters) { } else { main_py = mp_obj_str_get_str(MP_STATE_PORT(machine_config_main)); } - int ret = pyexec_file(main_py); + int ret = pyexec_file(main_py, NULL); if (ret & PYEXEC_FORCED_EXIT) { goto soft_reset_exit; } diff --git a/ports/esp8266/.gitignore b/ports/esp8266/.gitignore new file mode 100644 index 00000000000..414487d53eb --- /dev/null +++ b/ports/esp8266/.gitignore @@ -0,0 +1 @@ +build-*/ diff --git a/ports/esp8266/Makefile b/ports/esp8266/Makefile index 716f18d6a1b..4f23dfff1ef 100644 --- a/ports/esp8266/Makefile +++ b/ports/esp8266/Makefile @@ -1,3 +1,13 @@ +# Select the board to build for: if not given on the command line, +# then default to PYBV10. +BOARD ?= feather_huzzah +ifeq ($(wildcard boards/$(BOARD)/.),) +$(error Invalid BOARD specified) +endif + +# If the build directory is not given, make it reflect the board name. +BUILD ?= build-$(BOARD) + include ../../py/mkenv.mk # qstr definitions (must come before including py.mk) @@ -15,13 +25,14 @@ FROZEN_MPY_DIR ?= modules # include py core make definitions include $(TOP)/py/py.mk -FWBIN = $(BUILD)/firmware-combined.bin +FWBIN = $(BUILD)/firmware.bin PORT ?= /dev/ttyACM0 BAUD ?= 115200 FLASH_MODE ?= qio FLASH_SIZE ?= detect CROSS_COMPILE = xtensa-lx106-elf- ESP_SDK = $(shell $(CC) -print-sysroot)/usr +ESPTOOL = esptool.py INC += -I. INC += -I$(TOP) @@ -38,7 +49,7 @@ CFLAGS_XTENSA = -fsingle-precision-constant -Wdouble-promotion \ -Wl,-EL -mlongcalls -mtext-section-literals -mforce-l32 \ -DLWIP_OPEN_SRC -CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -std=gnu99 -nostdlib -DUART_OS=$(UART_OS) \ +CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -Wno-strict-aliasing -std=gnu99 -nostdlib -DUART_OS=$(UART_OS) \ $(CFLAGS_XTENSA) $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA) LDSCRIPT = esp8266.ld @@ -69,7 +80,6 @@ SRC_C = \ uart.c \ esppwm.c \ espneopixel.c \ - espapa102.c \ intr.c \ modpyb.c \ modmachine.c \ @@ -82,14 +92,66 @@ SRC_C = \ machine_hspi.c \ modesp.c \ modnetwork.c \ - modutime.c \ - moduos.c \ ets_alt_task.c \ fatfs_port.c \ posix_helpers.c \ hspi.c \ + boards/$(BOARD)/pins.c \ + supervisor/stub/stack.c \ + supervisor/shared/translate.c \ $(SRC_MOD) +SRC_COMMON_HAL = \ + microcontroller/__init__.c \ + microcontroller/Pin.c \ + microcontroller/Processor.c \ + analogio/__init__.c \ + analogio/AnalogIn.c \ + analogio/AnalogOut.c \ + digitalio/__init__.c \ + digitalio/DigitalInOut.c \ + pulseio/__init__.c \ + pulseio/PulseIn.c \ + pulseio/PulseOut.c \ + pulseio/PWMOut.c \ + busio/__init__.c \ + busio/SPI.c \ + busio/UART.c \ + multiterminal/__init__.c \ + neopixel_write/__init__.c \ + os/__init__.c \ + time/__init__.c \ + board/__init__.c + + +# These don't have corresponding files in each port but are still located in +# shared-bindings to make it clear what the contents of the modules are. +SRC_BINDINGS_ENUMS = \ + digitalio/Direction.c \ + digitalio/DriveMode.c \ + digitalio/Pull.c \ + math/__init__.c \ + microcontroller/RunMode.c \ + util.c + +SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ + $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ + $(addprefix common-hal/, $(SRC_COMMON_HAL)) +SRC_SHARED_MODULE = \ + bitbangio/__init__.c \ + bitbangio/I2C.c \ + bitbangio/OneWire.c \ + bitbangio/SPI.c \ + busio/I2C.c \ + busio/OneWire.c \ + multiterminal/__init__.c \ + os/__init__.c \ + random/__init__.c \ + struct/__init__.c + +SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ + $(addprefix shared-module/, $(SRC_SHARED_MODULE)) + EXTMOD_SRC_C = $(addprefix extmod/,\ modlwip.c \ modonewire.c \ @@ -118,6 +180,8 @@ LIB_SRC_C = $(addprefix lib/,\ mp-readline/readline.c \ netutils/netutils.c \ timeutils/timeutils.c \ + utils/buffer_helper.c \ + utils/context_manager_helpers.c \ utils/pyexec.c \ utils/interrupt_char.c \ utils/sys_stdio_mphal.c \ @@ -131,8 +195,7 @@ endif DRIVERS_SRC_C = $(addprefix drivers/,\ bus/softspi.c \ - dht/dht.c \ - ) + ) SRC_S = \ gchelper.s \ @@ -141,16 +204,20 @@ OBJ = OBJ += $(PY_O) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_EXPANDED:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(STM_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(EXTMOD_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o)) # List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(EXTMOD_SRC_C) $(LIB_SRC_C) $(DRIVERS_SRC_C) +SRC_QSTR += $(SRC_C) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) $(STM_SRC_C) $(EXTMOD_SRC_C) $(DRIVERS_SRC_C) # Append any auto-generated sources that are needed by sources listed in SRC_QSTR SRC_QSTR_AUTO_DEPS += -all: $(BUILD)/libaxtls.a $(FWBIN) +all: + @echo "CircuitPython 4.0.0 and later do not support esp8266 boards." CONFVARS_FILE = $(BUILD)/confvars @@ -167,24 +234,25 @@ FROZEN_EXTRA_DEPS = $(CONFVARS_FILE) .PHONY: deploy -deploy: $(BUILD)/firmware-combined.bin +deploy: $(FWBIN) $(ECHO) "Writing $< to the board" - $(Q)esptool.py --port $(PORT) --baud $(BAUD) write_flash --verify --flash_size=$(FLASH_SIZE) --flash_mode=$(FLASH_MODE) 0 $< + $(Q)$(ESPTOOL) --port $(PORT) --baud $(BAUD) write_flash --verify --flash_size=$(FLASH_SIZE) --flash_mode=$(FLASH_MODE) 0 $< erase: $(ECHO) "Erase flash" - $(Q)esptool.py --port $(PORT) --baud $(BAUD) erase_flash + $(Q)$(ESPTOOL) --port $(PORT) --baud $(BAUD) erase_flash reset: echo -e "\r\nimport machine; machine.reset()\r\n" >$(PORT) $(FWBIN): $(BUILD)/firmware.elf $(ECHO) "Create $@" - $(Q)esptool.py elf2image $^ + $(Q)$(ESPTOOL) elf2image $^ $(Q)$(PYTHON) makeimg.py $(BUILD)/firmware.elf-0x00000.bin $(BUILD)/firmware.elf-0x[0-5][1-f]000.bin $@ + $(BUILD)/firmware.elf: $(OBJ) - $(ECHO) "LINK $@" + $(STEPECHO) "LINK $@" $(Q)$(LD) $(LDFLAGS) -o $@ $^ $(LIBS) $(Q)$(SIZE) $@ @@ -201,6 +269,7 @@ axtls: $(BUILD)/libaxtls.a $(BUILD)/libaxtls.a: cd $(TOP)/lib/axtls; cp config/upyconfig config/.config + cd $(TOP)/lib/axtls; $(MAKE) ssl/version.h cd $(TOP)/lib/axtls; $(MAKE) oldconfig -B cd $(TOP)/lib/axtls; $(MAKE) clean cd $(TOP)/lib/axtls; $(MAKE) all CC="$(CC)" LD="$(LD)" AR="$(AR)" CFLAGS_EXTRA="$(CFLAGS_XTENSA) -Dabort=abort_ -DRT_MAX_PLAIN_LENGTH=1024 -DRT_EXTRA=4096" @@ -208,4 +277,4 @@ $(BUILD)/libaxtls.a: clean-modules: git clean -f -d modules - rm -f build/frozen*.c + rm -f $(BUILD)/frozen*.c diff --git a/ports/esp8266/README.md b/ports/esp8266/README.md index f4dddd1ca16..5f0ad8073e5 100644 --- a/ports/esp8266/README.md +++ b/ports/esp8266/README.md @@ -34,6 +34,14 @@ run `make` in its directory to build and install the SDK locally. Make sure to add toolchain bin directory to your PATH. Read esp-open-sdk's README for additional important information on toolchain setup. +Travis builds, including releases are actually built using a specific +esp-open-sdk binary. The location of the binary can be seen in the +`.travis.yml` in the top-level directory of CircuitPython. This may be ahead +of or behind the pfalcon repository, depending on the specific needs of +CircuitPython. If your local system is binary-compatible with Travis +(most Ubuntu and Debian based systems are), you can download the binary and +skip building it locally. + Add the external dependencies to the MicroPython repository checkout: ```bash $ git submodule update --init diff --git a/ports/esp8266/boards/feather_huzzah/pins.c b/ports/esp8266/boards/feather_huzzah/pins.c new file mode 100644 index 00000000000..d9f03c266c4 --- /dev/null +++ b/ports/esp8266/boards/feather_huzzah/pins.c @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "common-hal/microcontroller/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pin_TOUT) }, + { MP_ROM_QSTR(MP_QSTR_GPIO16), MP_ROM_PTR(&pin_XPD_DCDC) }, + { MP_ROM_QSTR(MP_QSTR_GPIO14), MP_ROM_PTR(&pin_MTMS) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_MTMS) }, + { MP_ROM_QSTR(MP_QSTR_GPIO12), MP_ROM_PTR(&pin_MTDI) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_MTDI) }, + { MP_ROM_QSTR(MP_QSTR_GPIO13), MP_ROM_PTR(&pin_MTCK) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_MTCK) }, + { MP_ROM_QSTR(MP_QSTR_GPIO15), MP_ROM_PTR(&pin_MTDO) }, + { MP_ROM_QSTR(MP_QSTR_GPIO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GPIO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GPIO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_U0RXD) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_U0TXD) }, + { MP_ROM_QSTR(MP_QSTR_GPIO5), MP_ROM_PTR(&pin_DVDD) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_DVDD) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/esp8266/common-hal/analogio/AnalogIn.c b/ports/esp8266/common-hal/analogio/AnalogIn.c new file mode 100644 index 00000000000..63580c07cbd --- /dev/null +++ b/ports/esp8266/common-hal/analogio/AnalogIn.c @@ -0,0 +1,67 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 +#include + +#include "py/nlr.h" +#include "py/runtime.h" +#include "py/binary.h" +#include "py/mphal.h" +#include "common-hal/microcontroller/__init__.h" +#include "shared-bindings/analogio/AnalogIn.h" +#include "supervisor/shared/translate.h" + +#include "user_interface.h" + +void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, + const mcu_pin_obj_t *pin) { + if (pin != &pin_TOUT) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, translate("Pin %q does not have ADC capabilities"), pin->name)); + } + claim_pin(pin); +} + +bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t* self) { + return self->deinited; +} + +void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t* self) { + if (common_hal_analogio_analogin_deinited(self)) { + return; + } + reset_pin(&pin_TOUT); + self->deinited = true; +} + +uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { + // ADC is 10 bit so shift by 6 to make it 16-bit. + return system_adc_read() << 6; +} + +float common_hal_analogio_analogin_get_reference_voltage(analogio_analogin_obj_t *self) { + return 1.0f; +} diff --git a/ports/esp8266/common-hal/analogio/AnalogIn.h b/ports/esp8266/common-hal/analogio/AnalogIn.h new file mode 100644 index 00000000000..b20b8cc61e2 --- /dev/null +++ b/ports/esp8266/common-hal/analogio/AnalogIn.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ESP8266_COMMON_HAL_ANALOGIO_ANALOGIN_H +#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_ANALOGIO_ANALOGIN_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + bool deinited; +} analogio_analogin_obj_t; + +#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_ANALOGIO_ANALOGIN_H diff --git a/ports/esp8266/common-hal/analogio/AnalogOut.c b/ports/esp8266/common-hal/analogio/AnalogOut.c new file mode 100644 index 00000000000..b01d8edb8a7 --- /dev/null +++ b/ports/esp8266/common-hal/analogio/AnalogOut.c @@ -0,0 +1,51 @@ +/* + * 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 "shared-bindings/analogio/AnalogOut.h" + +#include +#include +#include + +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self, + const mcu_pin_obj_t *pin) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, + translate("No hardware support for analog out."))); +} + +bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self) { + return true; +} + +void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self) { +} + +void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, + uint16_t value) { +} diff --git a/ports/esp8266/common-hal/analogio/AnalogOut.h b/ports/esp8266/common-hal/analogio/AnalogOut.h new file mode 100644 index 00000000000..79343a78fe2 --- /dev/null +++ b/ports/esp8266/common-hal/analogio/AnalogOut.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ESP8266_COMMON_HAL_ANALOGIO_ANALOGOUT_H +#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_ANALOGIO_ANALOGOUT_H + +#include "py/obj.h" + +// Not supported, throws error on construction. +typedef struct { + mp_obj_base_t base; +} analogio_analogout_obj_t; + +#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_ANALOGIO_ANALOGOUT_H diff --git a/ports/esp8266/common-hal/analogio/__init__.c b/ports/esp8266/common-hal/analogio/__init__.c new file mode 100644 index 00000000000..eea58c77d63 --- /dev/null +++ b/ports/esp8266/common-hal/analogio/__init__.c @@ -0,0 +1 @@ +// No analogio module functions. diff --git a/ports/esp8266/common-hal/board/__init__.c b/ports/esp8266/common-hal/board/__init__.c new file mode 100644 index 00000000000..9365f0fd960 --- /dev/null +++ b/ports/esp8266/common-hal/board/__init__.c @@ -0,0 +1,34 @@ +/* + * 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 + +#include "py/runtime.h" +#include "py/mphal.h" +#include "common-hal/microcontroller/Pin.h" + +// Pins aren't actually defined here. They are in the board specific directory +// such as boards/feather_huzzah/pins.c. diff --git a/ports/esp8266/common-hal/busio/I2C.h b/ports/esp8266/common-hal/busio/I2C.h new file mode 100644 index 00000000000..f0e8ff4af8e --- /dev/null +++ b/ports/esp8266/common-hal/busio/I2C.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_I2C_H +#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_I2C_H + +// Use the bitbang wrapper for I2C +#include "shared-module/busio/I2C.h" + +#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_I2C_H diff --git a/ports/esp8266/common-hal/busio/OneWire.h b/ports/esp8266/common-hal/busio/OneWire.h new file mode 100644 index 00000000000..230474067bd --- /dev/null +++ b/ports/esp8266/common-hal/busio/OneWire.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_ONEWIRE_H +#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_ONEWIRE_H + +// Use the bitbang wrapper for OneWire +#include "shared-module/busio/OneWire.h" + +#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_ONEWIRE_H diff --git a/ports/esp8266/common-hal/busio/SPI.c b/ports/esp8266/common-hal/busio/SPI.c new file mode 100644 index 00000000000..d00997820e8 --- /dev/null +++ b/ports/esp8266/common-hal/busio/SPI.c @@ -0,0 +1,225 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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 "shared-bindings/microcontroller/__init__.h" +#include "common-hal/busio/SPI.h" +#include "py/nlr.h" +#include "supervisor/shared/translate.h" + +#include "eagle_soc.h" +#include "ets_alt_task.h" +#include "c_types.h" +#include "gpio.h" +#include "hspi.h" + +extern const mcu_pin_obj_t pin_MTMS; +extern const mcu_pin_obj_t pin_MTCK; +extern const mcu_pin_obj_t pin_MTDI; + +void busio_spi_init_gpio(uint8_t sysclk_as_spiclk, const mcu_pin_obj_t * clock, + const mcu_pin_obj_t * mosi, const mcu_pin_obj_t * miso) { + + uint32_t clock_div_flag = 0; + if (sysclk_as_spiclk) { + clock_div_flag = 0x0001; + } + + // Set bit 9 if 80MHz sysclock required + WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105 | (clock_div_flag<<9)); + // GPIO12 is HSPI MISO pin (Master Data In) + if (miso == &pin_MTDI) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2); + } + // GPIO13 is HSPI MOSI pin (Master Data Out) + if (mosi == &pin_MTCK) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2); + } + // GPIO14 is HSPI CLK pin (Clock) + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2); +} + + +void common_hal_busio_spi_construct(busio_spi_obj_t *self, + const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, + const mcu_pin_obj_t * miso) { + if (clock != &pin_MTMS || !((mosi == &pin_MTCK && miso == MP_OBJ_TO_PTR(mp_const_none)) || + (mosi == MP_OBJ_TO_PTR(mp_const_none) && miso == &pin_MTDI) || + (mosi == &pin_MTCK && miso == &pin_MTDI))) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Pins not valid for SPI"))); + } + + busio_spi_init_gpio(SPI_CLK_USE_DIV, clock, mosi, miso); + self->clock = clock; + self->mosi = mosi; + self->miso = miso; + + spi_clock(HSPI, SPI_CLK_PREDIV, SPI_CLK_CNTDIV); + self->frequency = SPI_CLK_FREQ; + spi_tx_byte_order(HSPI, SPI_BYTE_ORDER_HIGH_TO_LOW); + spi_rx_byte_order(HSPI, SPI_BYTE_ORDER_HIGH_TO_LOW); + + SET_PERI_REG_MASK(SPI_USER(HSPI), SPI_CS_SETUP|SPI_CS_HOLD); + CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_FLASH_MODE); +} + +bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { + return self->deinited; +} + +void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { + if (common_hal_busio_spi_deinited(self)) { + return; + } + + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 0); + PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTDI_U); + + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 0); + PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTCK_U); + + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 0); + PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTMS_U); + + // Turn off outputs 12 - 14. + gpio_output_set(0x0, 0x0, 0x0, 0x7 << 12); + + self->deinited = true; +} + +bool common_hal_busio_spi_configure(busio_spi_obj_t *self, + uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { + if (bits != 8) { + return false; + } + if (baudrate == 80000000L) { + // Special case for full speed. + busio_spi_init_gpio(SPI_CLK_80MHZ_NODIV, self->clock, self->mosi, self->miso); + spi_clock(HSPI, 0, 0); + self->frequency = 80000000L; + } else if (baudrate > 40000000L) { + return false; + } else { + uint32_t divider = 40000000L / baudrate; + uint16_t prediv = MIN(divider, SPI_CLKDIV_PRE + 1); + uint16_t cntdiv = (divider / prediv) * 2; // cntdiv has to be even + if (cntdiv > SPI_CLKCNT_N + 1 || cntdiv == 0 || prediv == 0) { + return false; + } + busio_spi_init_gpio(SPI_CLK_USE_DIV, self->clock, self->mosi, self->miso); + spi_clock(HSPI, prediv, cntdiv); + self->frequency = 80000000L / (prediv * cntdiv); + } + spi_mode(HSPI, phase, polarity); + return true; +} + +bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { + bool success = false; + common_hal_mcu_disable_interrupts(); + if (!self->locked) { + self->locked = true; + success = true; + } + common_hal_mcu_enable_interrupts(); + return success; +} + +bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self) { + return self->locked; +} + +void common_hal_busio_spi_unlock(busio_spi_obj_t *self) { + self->locked = false; +} + +bool common_hal_busio_spi_write(busio_spi_obj_t *self, + const uint8_t * data, size_t len) { + size_t chunk_size = 1024; + size_t count = len / chunk_size; + size_t i = 0; + for (size_t j = 0; j < count; ++j) { + for (size_t k = 0; k < chunk_size; ++k) { + spi_tx8fast(HSPI, data[i]); + ++i; + } + ets_loop_iter(); + } + while (i < len) { + spi_tx8fast(HSPI, data[i]); + ++i; + } + while (spi_busy(HSPI)) {}; // Wait for SPI to finish the last byte. + return true; +} + +bool common_hal_busio_spi_read(busio_spi_obj_t *self, + uint8_t * data, size_t len, uint8_t write_value) { + // Process data in chunks, let the pending tasks run in between + size_t chunk_size = 1024; // TODO this should depend on baudrate + size_t count = len / chunk_size; + size_t i = 0; + uint32_t long_write_value = ((uint32_t) write_value) << 24 | + write_value << 16 | + write_value << 8 | + write_value; + for (size_t j = 0; j < count; ++j) { + for (size_t k = 0; k < chunk_size; ++k) { + data[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, long_write_value, 8, 0); + ++i; + } + ets_loop_iter(); + } + while (i < len) { + data[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, long_write_value, 8, 0); + ++i; + } + return true; +} + +bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_out, uint8_t *data_in, size_t len) { + // Process data in chunks, let the pending tasks run in between + size_t chunk_size = 1024; // TODO this should depend on baudrate + size_t count = len / chunk_size; + size_t i = 0; + for (size_t j = 0; j < count; ++j) { + for (size_t k = 0; k < chunk_size; ++k) { + data_in[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, data_out[i], 8, 0); + ++i; + } + ets_loop_iter(); + } + while (i < len) { + data_in[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, data_out[i], 8, 0); + ++i; + } + return true; + +} + +uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t* self) { + return self->frequency; +} diff --git a/ports/esp8266/common-hal/busio/SPI.h b/ports/esp8266/common-hal/busio/SPI.h new file mode 100644 index 00000000000..7b2de082c4c --- /dev/null +++ b/ports/esp8266/common-hal/busio/SPI.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_SPI_H +#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_SPI_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint32_t frequency; + bool locked; + bool deinited; + const mcu_pin_obj_t * mosi; + const mcu_pin_obj_t * miso; + const mcu_pin_obj_t * clock; +} busio_spi_obj_t; + +#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_SPI_H diff --git a/ports/esp8266/common-hal/busio/UART.c b/ports/esp8266/common-hal/busio/UART.c new file mode 100644 index 00000000000..e72dce639cd --- /dev/null +++ b/ports/esp8266/common-hal/busio/UART.c @@ -0,0 +1,146 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 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 "common-hal/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/busio/UART.h" +#include "supervisor/shared/translate.h" + +#include "ets_sys.h" +#include "uart.h" + +#include "py/nlr.h" + +// UartDev is defined and initialized in rom code. +extern UartDevice UartDev; + +void common_hal_busio_uart_construct(busio_uart_obj_t *self, + const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, + uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout, + uint16_t receiver_buffer_size) { + if (rx != mp_const_none || tx != &pin_GPIO2) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("Only tx supported on UART1 (GPIO2)."))); + } + + // set baudrate + UartDev.baut_rate = baudrate; + self->baudrate = baudrate; + + // set data bits + switch (bits) { + case 5: + UartDev.data_bits = UART_FIVE_BITS; + break; + case 6: + UartDev.data_bits = UART_SIX_BITS; + break; + case 7: + UartDev.data_bits = UART_SEVEN_BITS; + break; + case 8: + UartDev.data_bits = UART_EIGHT_BITS; + break; + default: + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, translate("invalid data bits"))); + break; + } + + if (parity == PARITY_NONE) { + UartDev.parity = UART_NONE_BITS; + UartDev.exist_parity = UART_STICK_PARITY_DIS; + } else { + UartDev.exist_parity = UART_STICK_PARITY_EN; + if (parity == PARITY_ODD) { + UartDev.parity = UART_ODD_BITS; + } else { + UartDev.parity = UART_EVEN_BITS; + } + } + + switch (stop) { + case 1: + UartDev.stop_bits = UART_ONE_STOP_BIT; + break; + case 2: + UartDev.stop_bits = UART_TWO_STOP_BIT; + break; + default: + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, translate("invalid stop bits"))); + break; + } + + uart_setup(UART1); + self->deinited = false; +} + +bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { + return self->deinited; +} + +void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { + if (common_hal_busio_uart_deinited(self)) { + return; + } + // Switch GPIO2 back to a GPIO pin. + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2); + self->deinited = true; +} + +size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { + return 0; +} + +// Write characters. +size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { + // write the data + for (size_t i = 0; i < len; ++i) { + uart_tx_one_char(UART1, *data++); + } + + // return number of bytes written + return len; +} + +uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) { + return self->baudrate; +} + +void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) { + UartDev.baut_rate = baudrate; + uart_setup(UART1); + self->baudrate = baudrate; +} + +uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { + return 0; +} + +void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) { +} + +bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { + return true; +} diff --git a/ports/esp8266/common-hal/busio/UART.h b/ports/esp8266/common-hal/busio/UART.h new file mode 100644 index 00000000000..9b75b66a339 --- /dev/null +++ b/ports/esp8266/common-hal/busio/UART.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_UART_H +#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_UART_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint32_t baudrate; + bool deinited; +} busio_uart_obj_t; + +#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_UART_H diff --git a/ports/esp8266/common-hal/busio/__init__.c b/ports/esp8266/common-hal/busio/__init__.c new file mode 100644 index 00000000000..41761b6743a --- /dev/null +++ b/ports/esp8266/common-hal/busio/__init__.c @@ -0,0 +1 @@ +// No busio module functions. diff --git a/ports/esp8266/common-hal/digitalio/DigitalInOut.c b/ports/esp8266/common-hal/digitalio/DigitalInOut.c new file mode 100644 index 00000000000..80584bb5fe8 --- /dev/null +++ b/ports/esp8266/common-hal/digitalio/DigitalInOut.c @@ -0,0 +1,228 @@ +/* + * 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 +#include +#include + +#include "py/nlr.h" +#include "py/runtime.h" +#include "py/mphal.h" + +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "supervisor/shared/translate.h" +#include "common-hal/microcontroller/Pin.h" + +extern volatile bool gpio16_in_use; + +digitalinout_result_t common_hal_digitalio_digitalinout_construct( + digitalio_digitalinout_obj_t* self, const mcu_pin_obj_t* pin) { + self->pin = pin; + if (self->pin->gpio_number == 16) { + WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); // mux configuration for XPD_DCDC and rtc_gpio0 connection + WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); //mux configuration for out enable + WRITE_PERI_REG(RTC_GPIO_ENABLE, READ_PERI_REG(RTC_GPIO_ENABLE) & ~1); //out disable + claim_pin(pin); + } else { + PIN_FUNC_SELECT(self->pin->peripheral, self->pin->gpio_function); + } + return DIGITALINOUT_OK; +} + +bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t* self) { + return self->pin == mp_const_none; +} + +void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self) { + if (common_hal_digitalio_digitalinout_deinited(self)) { + return; + } + if (self->pin->gpio_number < 16) { + uint32_t pin_mask = 1 << self->pin->gpio_number; + gpio_output_set(0x0, 0x0, 0x0, pin_mask); + PIN_FUNC_SELECT(self->pin->peripheral, 0); + PIN_PULLUP_DIS(self->pin->peripheral); + } else { + reset_pin(self->pin); + } + self->pin = mp_const_none; +} + +void common_hal_digitalio_digitalinout_switch_to_input( + digitalio_digitalinout_obj_t* self, digitalio_pull_t pull) { + self->output = false; + + if (self->pin->gpio_number == 16) { + WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); + WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); + WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1)); // input + } else { + PIN_PULLUP_DIS(self->pin->peripheral); + gpio_output_set(0, 0, 0, 1 << self->pin->gpio_number); + } + common_hal_digitalio_digitalinout_set_pull(self, pull); +} + +void common_hal_digitalio_digitalinout_switch_to_output( + digitalio_digitalinout_obj_t* self, bool value, + digitalio_drive_mode_t drive_mode) { + self->output = true; + self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN; + if (self->pin->gpio_number == 16) { + WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); + WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); + WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1) | 1); // output + } else if (!self->open_drain) { + gpio_output_set(0, 0, 1 << self->pin->gpio_number, 0); + PIN_PULLUP_DIS(self->pin->peripheral); + } + common_hal_digitalio_digitalinout_set_value(self, value); +} + +digitalio_direction_t common_hal_digitalio_digitalinout_get_direction( + digitalio_digitalinout_obj_t* self) { + return self->output? DIRECTION_OUTPUT : DIRECTION_INPUT; +} + +void common_hal_digitalio_digitalinout_set_value( + digitalio_digitalinout_obj_t* self, bool value) { + if (self->pin->gpio_number == 16) { + if (self->open_drain && value) { + // configure GPIO16 as input with output register holding 0 + WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); + WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); + WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1)); // input + WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & 1)); // out=1 + return; + } else { + int out_en = self->output; + WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); + WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); + WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1) | out_en); + WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & ~1) | value); + return; + } + } + if (value) { + if (self->open_drain) { + // Disable output. + gpio_output_set(0, 0, 0, 1 << self->pin->gpio_number); + } else { + // Set high + gpio_output_set(1 << self->pin->gpio_number, 0, 0, 0); + } + } else { + if (self->open_drain) { + // Enable the output + gpio_output_set(0, 0, 1 << self->pin->gpio_number, 0); + } + // Set low + gpio_output_set(0, 1 << self->pin->gpio_number, 0, 0); + } +} + +// Register addresses taken from: https://github.com/esp8266/esp8266-wiki/wiki/gpio-registers +volatile uint32_t* PIN_DIR = (uint32_t *) 0x6000030C; +volatile uint32_t* PIN_OUT = (uint32_t *) 0x60000300; +bool common_hal_digitalio_digitalinout_get_value( + digitalio_digitalinout_obj_t* self) { + if (!self->output) { + if (self->pin->gpio_number == 16) { + return READ_PERI_REG(RTC_GPIO_IN_DATA) & 1; + } + return GPIO_INPUT_GET(self->pin->gpio_number); + } else { + if (self->pin->gpio_number == 16) { + if (self->open_drain && READ_PERI_REG(RTC_GPIO_ENABLE) == 0) { + return true; + } else { + return READ_PERI_REG(RTC_GPIO_OUT) & 1; + } + } else { + uint32_t pin_mask = 1 << self->pin->gpio_number; + if (self->open_drain && ((*PIN_DIR) & pin_mask) == 0) { + return true; + } else { + return ((*PIN_OUT) & pin_mask) != 0; + } + } + } +} + +void common_hal_digitalio_digitalinout_set_drive_mode( + digitalio_digitalinout_obj_t* self, + digitalio_drive_mode_t drive_mode) { + bool value = common_hal_digitalio_digitalinout_get_value(self); + self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN; + // True is implemented differently between modes so reset the value to make + // sure its correct for the new mode. + if (value) { + common_hal_digitalio_digitalinout_set_value(self, value); + } +} + +digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( + digitalio_digitalinout_obj_t* self) { + if (self->open_drain) { + return DRIVE_MODE_OPEN_DRAIN; + } else { + return DRIVE_MODE_PUSH_PULL; + } +} + +void common_hal_digitalio_digitalinout_set_pull( + digitalio_digitalinout_obj_t* self, digitalio_pull_t pull) { + if (pull == PULL_DOWN) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, + translate("ESP8266 does not support pull down."))); + return; + } + if (self->pin->gpio_number == 16) { + // PULL_DOWN is the only hardware pull direction available on GPIO16. + // since we don't support pull down, just return without attempting + // to set pull (which won't work anyway). If PULL_UP is requested, + // raise the exception so the user knows PULL_UP is not available + if (pull != PULL_NONE){ + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, + translate("GPIO16 does not support pull up."))); + } + return; + } + if (pull == PULL_NONE) { + PIN_PULLUP_DIS(self->pin->peripheral); + } else { + PIN_PULLUP_EN(self->pin->peripheral); + } +} + +digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( + digitalio_digitalinout_obj_t* self) { + if (self->pin->gpio_number < 16 && + (READ_PERI_REG(self->pin->peripheral) & PERIPHS_IO_MUX_PULLUP) != 0) { + return PULL_UP; + } + return PULL_NONE; +} diff --git a/ports/esp8266/common-hal/digitalio/DigitalInOut.h b/ports/esp8266/common-hal/digitalio/DigitalInOut.h new file mode 100644 index 00000000000..80c23ff9fa7 --- /dev/null +++ b/ports/esp8266/common-hal/digitalio/DigitalInOut.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ESP8266_COMMON_HAL_DIGITALIO_DIGITALINOUT_H +#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_DIGITALIO_DIGITALINOUT_H + +#include "common-hal/microcontroller/Pin.h" +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t * pin; + bool output; + bool open_drain; +} digitalio_digitalinout_obj_t; + +#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_DIGITALIO_DIGITALINOUT_H diff --git a/ports/esp8266/common-hal/digitalio/__init__.c b/ports/esp8266/common-hal/digitalio/__init__.c new file mode 100644 index 00000000000..20fad459593 --- /dev/null +++ b/ports/esp8266/common-hal/digitalio/__init__.c @@ -0,0 +1 @@ +// No digitalio module functions. diff --git a/ports/esp8266/common-hal/microcontroller/Pin.c b/ports/esp8266/common-hal/microcontroller/Pin.c new file mode 100644 index 00000000000..4437d585502 --- /dev/null +++ b/ports/esp8266/common-hal/microcontroller/Pin.c @@ -0,0 +1,118 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/microcontroller/__init__.h" +#include "common-hal/microcontroller/__init__.h" +#include "common-hal/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/Pin.h" + +#include "py/mphal.h" + +#include "eagle_soc.h" + +bool adc_in_use; +bool gpio16_in_use; + +typedef struct { + void (*func)(void *); + void *data; +} pin_intr_handler_t; + +static pin_intr_handler_t _pin_intr_handlers[GPIO_PIN_COUNT]; + +void microcontroller_pin_call_intr_handlers(uint32_t status) { + status &= (1 << GPIO_PIN_COUNT) - 1; + for (int p = 0; status; ++p, status >>= 1) { + if ((status & 1) && _pin_intr_handlers[p].func) { + _pin_intr_handlers[p].func(_pin_intr_handlers[p].data); + } + } +} + +void microcontroller_pin_register_intr_handler(uint8_t gpio_number, void (*func)(void *), void *data) { + common_hal_mcu_disable_interrupts(); + _pin_intr_handlers[gpio_number] = (pin_intr_handler_t){ func, data }; + common_hal_mcu_enable_interrupts(); +} + +bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) { + if (pin == &pin_TOUT) { + return !adc_in_use; + } + if (pin == &pin_XPD_DCDC) { + return !gpio16_in_use; + } + if (pin->gpio_number == NO_GPIO) { + return false; + } + return (READ_PERI_REG(pin->peripheral) & + (PERIPHS_IO_MUX_FUNC<gpio_number)) == 0 && + (READ_PERI_REG(pin->peripheral) & PERIPHS_IO_MUX_PULLUP) == 0; +} + +void claim_pin(const mcu_pin_obj_t* pin) { + if (pin == &pin_XPD_DCDC) { + gpio16_in_use = true; + } + if (pin == &pin_TOUT) { + adc_in_use = true; + } +} + +void reset_pin(const mcu_pin_obj_t* pin) { + if (pin == &pin_XPD_DCDC) { + // Set GPIO16 as input + WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); // mux configuration for XPD_DCDC and rtc_gpio0 connection + WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); //mux configuration for out enable + WRITE_PERI_REG(RTC_GPIO_ENABLE, READ_PERI_REG(RTC_GPIO_ENABLE) & ~1); //out disable + gpio16_in_use = false; + } + if (pin == &pin_TOUT) { + adc_in_use = false; + } +} + +void reset_pins(void) { + for (int i = 0; i < 16; i++) { + // 5 is RXD, 6 is TXD + if ((i > 4 && i < 13) || i == 12) { + continue; + } + uint32_t peripheral = PERIPHS_IO_MUX + i * 4; + PIN_FUNC_SELECT(peripheral, 0); + PIN_PULLUP_DIS(peripheral); + // Disable the pin. + gpio_output_set(0x0, 0x0, 0x0, 1 << i); + } + // Set GPIO16 as input + WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); // mux configuration for XPD_DCDC and rtc_gpio0 connection + WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); //mux configuration for out enable + WRITE_PERI_REG(RTC_GPIO_ENABLE, READ_PERI_REG(RTC_GPIO_ENABLE) & ~1); //out disable + + adc_in_use = false; + gpio16_in_use = false; +} diff --git a/ports/esp8266/common-hal/microcontroller/Pin.h b/ports/esp8266/common-hal/microcontroller/Pin.h new file mode 100644 index 00000000000..b00a4a817eb --- /dev/null +++ b/ports/esp8266/common-hal/microcontroller/Pin.h @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER_PIN_H +#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER_PIN_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + qstr name; + uint8_t gpio_number; + uint8_t gpio_function; + uint32_t peripheral; +} mcu_pin_obj_t; + +// Magic values for gpio_number. +#define NO_GPIO 0xff +#define SPECIAL_CASE 0xfe + +void claim_pin(const mcu_pin_obj_t* pin); +void reset_pin(const mcu_pin_obj_t* pin); +void reset_pins(void); + +void microcontroller_pin_register_intr_handler(uint8_t gpio_number, void (*func)(void *), void *data); +void microcontroller_pin_call_intr_handlers(uint32_t status); + +#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER_PIN_H diff --git a/ports/esp8266/common-hal/microcontroller/Processor.c b/ports/esp8266/common-hal/microcontroller/Processor.c new file mode 100644 index 00000000000..3602228d03e --- /dev/null +++ b/ports/esp8266/common-hal/microcontroller/Processor.c @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert for Adafruit Industries + * + * 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 "common-hal/microcontroller/Processor.h" + +#include + +#include "esp_mphal.h" +#include "user_interface.h" + + +float common_hal_mcu_processor_get_temperature(void) { + return NAN; +} + +uint32_t common_hal_mcu_processor_get_frequency(void) { + return mp_hal_get_cpu_freq(); +} + +void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { + uint32_t id = system_get_chip_id(); + for (int i=0; i<4; i++){ + raw_id[i] = id >> (i * 8); + } +} diff --git a/ports/esp8266/common-hal/microcontroller/Processor.h b/ports/esp8266/common-hal/microcontroller/Processor.h new file mode 100644 index 00000000000..7d7861fd573 --- /dev/null +++ b/ports/esp8266/common-hal/microcontroller/Processor.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H +#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H + +#define COMMON_HAL_MCU_PROCESSOR_UID_LENGTH 4 + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + // Stores no state currently. +} mcu_processor_obj_t; + +#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H diff --git a/ports/esp8266/common-hal/microcontroller/__init__.c b/ports/esp8266/common-hal/microcontroller/__init__.c new file mode 100644 index 00000000000..de9288a775a --- /dev/null +++ b/ports/esp8266/common-hal/microcontroller/__init__.c @@ -0,0 +1,135 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "py/runtime.h" + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/microcontroller/Processor.h" + +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/Processor.h" +#include "supervisor/shared/translate.h" + +#include "eagle_soc.h" +#include "ets_alt_task.h" +#include "etshal.h" +#include "osapi.h" +#include "user_interface.h" +#include "xtirq.h" + +#define ETS_LOOP_ITER_BIT (12) + +void common_hal_mcu_delay_us(uint32_t delay) { + os_delay_us(delay); +} + +static uint16_t saved_interrupt_state; +void common_hal_mcu_disable_interrupts() { + saved_interrupt_state = disable_irq(); + saved_interrupt_state = (saved_interrupt_state & ~(1 << ETS_LOOP_ITER_BIT)) | (ets_loop_iter_disable << ETS_LOOP_ITER_BIT); + ets_loop_iter_disable = 1; +} + +void common_hal_mcu_enable_interrupts() { + ets_loop_iter_disable = (saved_interrupt_state >> ETS_LOOP_ITER_BIT) & 1; + enable_irq(saved_interrupt_state & ~(1 << ETS_LOOP_ITER_BIT)); +} + +void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { + if (runmode == RUNMODE_BOOTLOADER) { + mp_raise_ValueError(translate("Cannot reset into bootloader because no bootloader is present.")); + } else if (runmode == RUNMODE_SAFE_MODE) { + mp_raise_ValueError(translate("ESP8226 does not support safe mode.")); + } +} + +void common_hal_mcu_reset(void) { + system_restart(); +} + +// The singleton microcontroller.Processor object, returned by microcontroller.cpu +// It currently only has properties, and no state. +const mcu_processor_obj_t common_hal_mcu_processor_obj = { + .base = { + .type = &mcu_processor_type, + }, +}; + +// This macro is used to simplify pin definition in boards//pins.c +#define PIN(p_name, p_gpio_number, p_gpio_function, p_peripheral) \ +const mcu_pin_obj_t pin_## p_name = { \ + { &mcu_pin_type }, \ + .name = MP_QSTR_ ## p_name, \ + .gpio_number = p_gpio_number, \ + .gpio_function = p_gpio_function, \ + .peripheral = p_peripheral, \ +} + +// Using microcontroller names from the datasheet. +// https://cdn-shop.adafruit.com/datasheets/ESP8266_Specifications_English.pdf +// PIN(mcu name) // function notes | module name | huzzah name +PIN(TOUT, NO_GPIO, NO_GPIO, NO_GPIO); // adc | ADC | ADC +PIN(XPD_DCDC, 16, SPECIAL_CASE, SPECIAL_CASE); // gpio16 | GPIO16 | GPIO16 +PIN(MTMS, 14, FUNC_GPIO14, PERIPHS_IO_MUX_MTMS_U); // gpio14 / hspi_clk / pwm2 | GPIO14 | GPIO14/SCK +PIN(MTDI, 12, FUNC_GPIO12, PERIPHS_IO_MUX_MTDI_U); // gpio12 / hspi_miso / pwm0 | GPIO12 | GPIO12/MISO +PIN(MTCK, 13, FUNC_GPIO13, PERIPHS_IO_MUX_MTCK_U); // gpio13 / hspi_mosi / U0cts | GPIO13 | GPIO13/MOSI +PIN(MTDO, 15, FUNC_GPIO15, PERIPHS_IO_MUX_MTDO_U); // gpio15 / hspi_cs / u0rts / pwm1 | GPIO15 | GPIO15 +PIN(GPIO2, 2, FUNC_GPIO2, PERIPHS_IO_MUX_GPIO2_U); // U1txd | GPIO2 | GPIO2 +PIN(GPIO0, 0, FUNC_GPIO0, PERIPHS_IO_MUX_GPIO0_U); // spi_Cs2 | GPIO0 | GPIO0 +PIN(GPIO4, 4, FUNC_GPIO4, PERIPHS_IO_MUX_GPIO4_U); // pwm3 on mcu datasheet as vdd which must be wrong | GPIO4 | GPIO4/SDA +PIN(SD_DATA_2, 9, FUNC_GPIO9, PERIPHS_IO_MUX_SD_DATA2_U); // spihd / hspihd / gpio9 | GPIO9 +PIN(SD_DATA_3, 10, FUNC_GPIO10, PERIPHS_IO_MUX_SD_DATA3_U); // spiwp / hspiwp / gpio10 | GPIO10 +PIN(SD_CMD, NO_GPIO, NO_GPIO, PERIPHS_IO_MUX_SD_CMD_U); // spi_cs0 / gpio11 | CS0 +PIN(SD_CLK, NO_GPIO, NO_GPIO, PERIPHS_IO_MUX_SD_CLK_U); // spi_clk / gpio6 | SCLK +PIN(SD_DATA_0, NO_GPIO, NO_GPIO, PERIPHS_IO_MUX_SD_DATA0_U); // spi_miso / gpio7 | MISO +PIN(SD_DATA_1, NO_GPIO, NO_GPIO, PERIPHS_IO_MUX_SD_DATA1_U); // spi_mosi / gpio8 / u1rxd | MOSI +PIN(DVDD, 5, FUNC_GPIO5, PERIPHS_IO_MUX_GPIO5_U); // gpio5 | GPIO5 | GPIO5/SCL +PIN(U0RXD, 3, FUNC_GPIO3, PERIPHS_IO_MUX_U0RXD_U); // gpio3 | RXD0 | RXD +PIN(U0TXD, 1, FUNC_GPIO1, PERIPHS_IO_MUX_U0TXD_U); // gpio1 / spi_cs1 | TXD0 | TXD + +// This maps MCU pin names to pin objects. +STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_TOUT), MP_ROM_PTR(&pin_TOUT) }, + { MP_ROM_QSTR(MP_QSTR_XPD_DCDC), MP_ROM_PTR(&pin_XPD_DCDC) }, + { MP_ROM_QSTR(MP_QSTR_MTMS), MP_ROM_PTR(&pin_MTMS) }, + { MP_ROM_QSTR(MP_QSTR_MTDI), MP_ROM_PTR(&pin_MTDI) }, + { MP_ROM_QSTR(MP_QSTR_MTCK), MP_ROM_PTR(&pin_MTCK) }, + { MP_ROM_QSTR(MP_QSTR_MTDO), MP_ROM_PTR(&pin_MTDO) }, + { MP_ROM_QSTR(MP_QSTR_GPIO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GPIO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GPIO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SD_DATA_2), MP_ROM_PTR(&pin_SD_DATA_2) }, + { MP_ROM_QSTR(MP_QSTR_SD_DATA_3), MP_ROM_PTR(&pin_SD_DATA_3) }, + { MP_ROM_QSTR(MP_QSTR_SD_CMD), MP_ROM_PTR(&pin_SD_CMD) }, + { MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_SD_CLK) }, + { MP_ROM_QSTR(MP_QSTR_SD_DATA_0), MP_ROM_PTR(&pin_SD_DATA_0) }, + { MP_ROM_QSTR(MP_QSTR_SD_DATA_1), MP_ROM_PTR(&pin_SD_DATA_1) }, + { MP_ROM_QSTR(MP_QSTR_DVDD), MP_ROM_PTR(&pin_DVDD) }, + { MP_ROM_QSTR(MP_QSTR_U0RXD), MP_ROM_PTR(&pin_U0RXD) }, + { MP_ROM_QSTR(MP_QSTR_U0TXD), MP_ROM_PTR(&pin_U0TXD) }, +}; +MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_global_dict_table); diff --git a/ports/esp8266/common-hal/microcontroller/__init__.h b/ports/esp8266/common-hal/microcontroller/__init__.h new file mode 100644 index 00000000000..89be4cbb039 --- /dev/null +++ b/ports/esp8266/common-hal/microcontroller/__init__.h @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER___INIT___H +#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER___INIT___H + +#include "common-hal/microcontroller/Pin.h" + +extern const mcu_pin_obj_t pin_TOUT; +extern const mcu_pin_obj_t pin_XPD_DCDC; +extern const mcu_pin_obj_t pin_MTMS; +extern const mcu_pin_obj_t pin_MTDI; +extern const mcu_pin_obj_t pin_MTCK; +extern const mcu_pin_obj_t pin_MTDO; +extern const mcu_pin_obj_t pin_GPIO2; +extern const mcu_pin_obj_t pin_GPIO0; +extern const mcu_pin_obj_t pin_GPIO4; +extern const mcu_pin_obj_t pin_SD_DATA_2; +extern const mcu_pin_obj_t pin_SD_DATA_3; +extern const mcu_pin_obj_t pin_SD_CMD; +extern const mcu_pin_obj_t pin_SD_CLK; +extern const mcu_pin_obj_t pin_SD_DATA_0; +extern const mcu_pin_obj_t pin_SD_DATA_1; +extern const mcu_pin_obj_t pin_DVDD; +extern const mcu_pin_obj_t pin_U0RXD; +extern const mcu_pin_obj_t pin_U0TXD; + +#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER___INIT___H diff --git a/ports/esp8266/common-hal/multiterminal/__init__.c b/ports/esp8266/common-hal/multiterminal/__init__.c new file mode 100644 index 00000000000..492174f0bbb --- /dev/null +++ b/ports/esp8266/common-hal/multiterminal/__init__.c @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Paul Sokolovsky + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "esp_mphal.h" + +#include "shared-bindings/multiterminal/__init__.h" +#include "shared-module/multiterminal/__init__.h" + +void common_hal_multiterminal_schedule_secondary_terminal_read(mp_obj_t socket) { + (void) socket; + mp_hal_signal_dupterm_input(); +} + +mp_obj_t common_hal_multiterminal_get_secondary_terminal() { + return shared_module_multiterminal_get_secondary_terminal(); +} + +void common_hal_multiterminal_set_secondary_terminal(mp_obj_t secondary_terminal) { + shared_module_multiterminal_set_secondary_terminal(secondary_terminal); +} + +void common_hal_multiterminal_clear_secondary_terminal() { + shared_module_multiterminal_clear_secondary_terminal(); +} diff --git a/ports/esp8266/common-hal/neopixel_write/__init__.c b/ports/esp8266/common-hal/neopixel_write/__init__.c new file mode 100644 index 00000000000..25fb0dcea53 --- /dev/null +++ b/ports/esp8266/common-hal/neopixel_write/__init__.c @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/neopixel_write/__init__.h" + +#include "espneopixel.h" + +void common_hal_neopixel_write(const digitalio_digitalinout_obj_t* digitalinout, uint8_t *pixels, uint32_t numBytes) { + esp_neopixel_write(digitalinout->pin->gpio_number, pixels, numBytes, true /*800 kHz*/); +} diff --git a/ports/esp8266/common-hal/os/__init__.c b/ports/esp8266/common-hal/os/__init__.c new file mode 100644 index 00000000000..a686964be83 --- /dev/null +++ b/ports/esp8266/common-hal/os/__init__.c @@ -0,0 +1,82 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2015 Josef Gajdusek + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "esp_mphal.h" +#include "etshal.h" +#include "py/objtuple.h" +#include "py/objstr.h" +#include "extmod/misc.h" +#include "genhdr/mpversion.h" +#include "user_interface.h" + +STATIC const qstr os_uname_info_fields[] = { + MP_QSTR_sysname, MP_QSTR_nodename, + MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine +}; +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, MICROPY_PY_SYS_PLATFORM); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, MICROPY_PY_SYS_PLATFORM); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); + +STATIC mp_obj_tuple_t os_uname_info_obj = { + .base = {&mp_type_attrtuple}, + .len = 5, + .items = { + (mp_obj_t)&os_uname_info_sysname_obj, + (mp_obj_t)&os_uname_info_nodename_obj, + NULL, + (mp_obj_t)&os_uname_info_version_obj, + (mp_obj_t)&os_uname_info_machine_obj, + (void *)os_uname_info_fields, + } +}; + +mp_obj_t common_hal_os_uname(void) { + // We must populate the "release" field each time in case it was GC'd since the last call. + const char *ver = system_get_sdk_version(); + os_uname_info_obj.items[2] = mp_obj_new_str(ver, strlen(ver)); + return (mp_obj_t)&os_uname_info_obj; +} + +static uint32_t last_random; +bool common_hal_os_urandom(uint8_t* buffer, uint32_t length) { + uint32_t i = 0; + while (i < length) { + uint32_t new_random = last_random; + while (new_random == last_random) { + new_random = *WDEV_HWRNG; + } + for (int j = 0; j < 4 && i < length; j++) { + buffer[i] = new_random & 0xff; + i++; + new_random >>= 8; + } + } + return true; +} diff --git a/ports/esp8266/common-hal/pulseio/PWMOut.c b/ports/esp8266/common-hal/pulseio/PWMOut.c new file mode 100644 index 00000000000..f3a7bbc5adf --- /dev/null +++ b/ports/esp8266/common-hal/pulseio/PWMOut.c @@ -0,0 +1,127 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 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 +#include + +#include "esppwm.h" + +#include "py/runtime.h" +#include "shared-bindings/pulseio/PWMOut.h" +#include "supervisor/shared/translate.h" + +#include "eagle_soc.h" +#include "c_types.h" +#include "gpio.h" + +#define PWM_FREQ_MAX 1000 + +// Shared with pybpwm +extern bool pwm_inited; +bool first_channel_variable; + +void pwmout_reset(void) { + first_channel_variable = false; +} + +void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, const mcu_pin_obj_t* pin, uint16_t duty, uint32_t frequency, + bool variable_frequency) { + if (frequency > PWM_FREQ_MAX) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Maximum PWM frequency is %dhz."), PWM_FREQ_MAX)); + } else if (frequency < 1) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, + translate("Minimum PWM frequency is 1hz."))); + } + + // start the PWM subsystem if it's not already running + if (!pwm_inited) { + pwm_init(); + pwm_inited = true; + pwm_set_freq(frequency, 0); + first_channel_variable = variable_frequency; + } else if (first_channel_variable || pwm_get_freq(0) != frequency) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Multiple PWM frequencies not supported. PWM already set to %dhz."), pwm_get_freq(0))); + } + + self->channel = pwm_add(pin->gpio_number, + pin->peripheral, + pin->gpio_function); + self->pin = pin; + if (self->channel == -1) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("PWM not supported on pin %d"), pin->gpio_number)); + } +} + +bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) { + return self->pin == mp_const_none; +} + +void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { + if (common_hal_pulseio_pwmout_deinited(self)) { + return; + } + pwm_delete(self->channel); + pwm_start(); + if (self->pin->gpio_number < 16) { + uint32_t pin_mask = 1 << self->pin->gpio_number; + gpio_output_set(0x0, 0x0, 0x0, pin_mask); + PIN_FUNC_SELECT(self->pin->peripheral, 0); + PIN_PULLUP_DIS(self->pin->peripheral); + } + self->pin = mp_const_none; +} + +void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty) { + // We get 16 bits of duty in but the underlying code is only ten bit. + pwm_set_duty(duty >> 6, self->channel); + pwm_start(); +} + +uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) { + return pwm_get_duty(self->channel) << 6; +} + +void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_t frequency) { + if (frequency > PWM_FREQ_MAX) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Maximum PWM frequency is %dhz."), PWM_FREQ_MAX)); + } else if (frequency < 1) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, + translate("Minimum PWM frequency is 1hz."))); + } + pwm_set_freq(frequency, 0); +} + +uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self) { + return pwm_get_freq(0); +} + +bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self) { + return first_channel_variable; +} diff --git a/ports/esp8266/common-hal/pulseio/PWMOut.h b/ports/esp8266/common-hal/pulseio/PWMOut.h new file mode 100644 index 00000000000..d40da2632c8 --- /dev/null +++ b/ports/esp8266/common-hal/pulseio/PWMOut.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PWMOUT_H +#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PWMOUT_H + +#include "common-hal/microcontroller/Pin.h" + +typedef struct { + mp_obj_base_t base; + int channel; + const mcu_pin_obj_t* pin; +} pulseio_pwmout_obj_t; + +void pwmout_reset(void); + +#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PWMOUT_H diff --git a/ports/esp8266/common-hal/pulseio/PulseIn.c b/ports/esp8266/common-hal/pulseio/PulseIn.c new file mode 100644 index 00000000000..40ba39e5fe9 --- /dev/null +++ b/ports/esp8266/common-hal/pulseio/PulseIn.c @@ -0,0 +1,187 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include +#include +#include "esp_mphal.h" + +#include "mpconfigport.h" +#include "py/gc.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/pulseio/PulseIn.h" +#include "supervisor/shared/translate.h" +#include "common-hal/microcontroller/__init__.h" + +static void pulsein_set_interrupt(pulseio_pulsein_obj_t *self, bool rising, bool falling) { + ETS_GPIO_INTR_DISABLE(); + // Set interrupt mode + GPIO_REG_WRITE( + GPIO_PIN_ADDR(self->pin->gpio_number), + (GPIO_REG_READ(GPIO_PIN_ADDR(self->pin->gpio_number) & ~GPIO_PIN_INT_TYPE_MASK)) | + GPIO_PIN_INT_TYPE_SET( + (rising ? GPIO_PIN_INTR_POSEDGE : 0) | (falling ? GPIO_PIN_INTR_NEGEDGE : 0) + ) + ); + // Clear interrupt status + GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << self->pin->gpio_number); + ETS_GPIO_INTR_ENABLE(); +} + +void pulseio_pulsein_interrupt_handler(void *data) { + pulseio_pulsein_obj_t *self = data; + uint32_t time_us = system_get_time(); + if (self->first_edge) { + self->first_edge = false; + pulsein_set_interrupt(self, true, true); + } else { + uint16_t elapsed_us = (uint16_t)(time_us - self->last_us); + uint16_t i = (self->start + self->len) % self->maxlen; + self->buffer[i] = elapsed_us; + if (self->len < self->maxlen) { + self->len++; + } else { + self->start++; + } + } + self->last_us = time_us; +} + +void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, + const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) { + if (pin->gpio_number == NO_GPIO || pin->gpio_function == SPECIAL_CASE) { + mp_raise_msg_varg(&mp_type_ValueError, translate("No PulseIn support for %q"), pin->name ); + } + PIN_FUNC_SELECT(pin->peripheral, pin->gpio_function); + PIN_PULLUP_DIS(pin->peripheral); + self->pin = pin; + + self->buffer = (uint16_t *) m_malloc(maxlen * sizeof(uint16_t), false); + if (self->buffer == NULL) { + mp_raise_msg_varg(&mp_type_MemoryError, translate("Failed to allocate RX buffer of %d bytes"), maxlen * sizeof(uint16_t)); + } + + self->maxlen = maxlen; + self->idle_state = idle_state; + self->start = 0; + self->len = 0; + self->first_edge = true; + self->last_us = 0; + self->paused = false; + + microcontroller_pin_register_intr_handler(self->pin->gpio_number, + pulseio_pulsein_interrupt_handler, (void *)self); + pulsein_set_interrupt(self, !idle_state, idle_state); +} + +bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self) { + return self->buffer == NULL; +} + +void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) { + pulsein_set_interrupt(self, false, false); + microcontroller_pin_register_intr_handler(self->pin->gpio_number, NULL, NULL); + PIN_FUNC_SELECT(self->pin->peripheral, 0); + m_free(self->buffer); + self->buffer = NULL; +} + +void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) { + pulsein_set_interrupt(self, false, false); + self->paused = true; +} + +void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, + uint16_t trigger_duration) { + // Make sure we're paused. + common_hal_pulseio_pulsein_pause(self); + + // Send the trigger pulse. + if (trigger_duration > 0) { + uint32_t mask = 1 << self->pin->gpio_number; + // switch pin to an output with state opposite idle state + gpio_output_set(self->idle_state ? 0 : mask, self->idle_state ? mask : 0, 0, 0); + gpio_output_set(0, 0, mask, 0); + common_hal_mcu_delay_us((uint32_t)trigger_duration); + // switch pin back to an open input + gpio_output_set(0, 0, 0, mask); + } + + common_hal_mcu_disable_interrupts(); + self->first_edge = true; + pulsein_set_interrupt(self, !self->idle_state, self->idle_state); + common_hal_mcu_enable_interrupts(); + self->paused = false; +} + +void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self) { + common_hal_mcu_disable_interrupts(); + self->start = 0; + self->len = 0; + common_hal_mcu_enable_interrupts(); +} + +uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) { + if (self->len == 0) { + mp_raise_IndexError(translate("pop from an empty PulseIn")); + } + common_hal_mcu_disable_interrupts(); + uint16_t value = self->buffer[self->start]; + self->start = (self->start + 1) % self->maxlen; + self->len--; + common_hal_mcu_enable_interrupts(); + + return value; +} + +uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self) { + return self->maxlen; +} + +bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self) { + return self->paused; +} + +uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) { + return self->len; +} + +uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, + int16_t index) { + common_hal_mcu_disable_interrupts(); + if (index < 0) { + index += self->len; + } + if (index < 0 || index >= self->len) { + common_hal_mcu_enable_interrupts(); + mp_raise_IndexError(translate("index out of range")); + } + uint16_t value = self->buffer[(self->start + index) % self->maxlen]; + common_hal_mcu_enable_interrupts(); + return value; +} diff --git a/ports/esp8266/common-hal/pulseio/PulseIn.h b/ports/esp8266/common-hal/pulseio/PulseIn.h new file mode 100644 index 00000000000..6319280e8a8 --- /dev/null +++ b/ports/esp8266/common-hal/pulseio/PulseIn.h @@ -0,0 +1,50 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PULSEIN_H +#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PULSEIN_H + +#include "py/obj.h" +#include "common-hal/microcontroller/Pin.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t *pin; + uint16_t *buffer; + uint16_t maxlen; + bool idle_state; + bool paused; + volatile uint16_t start; + volatile uint16_t len; + volatile bool first_edge; + volatile uint32_t last_us; +} pulseio_pulsein_obj_t; + +void pulsein_reset(void); + +void pulsein_interrupt_handler(uint32_t); + +#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PULSEIN_H diff --git a/ports/esp8266/common-hal/pulseio/PulseOut.c b/ports/esp8266/common-hal/pulseio/PulseOut.c new file mode 100644 index 00000000000..c5e63013d71 --- /dev/null +++ b/ports/esp8266/common-hal/pulseio/PulseOut.c @@ -0,0 +1,64 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "common-hal/pulseio/PulseOut.h" + +#include + +#include + +#include "ets_alt_task.h" +#include "py/obj.h" +#include "py/runtime.h" +#include "mpconfigport.h" +#include "shared-bindings/pulseio/PulseOut.h" + +void pulseout_set(pulseio_pulseout_obj_t *self, bool state) { + PIN_FUNC_SELECT(self->pin->peripheral, state ? self->pin->gpio_function : 0); +} + +void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self, + const pulseio_pwmout_obj_t* carrier) { + self->pin = carrier->pin; +} + +bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self) { + return self->pin == NULL; +} + +void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) { + self->pin = NULL; + pulseout_set(self, true); +} + +void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, + uint16_t* pulses, uint16_t length) { + for (uint16_t i = 0; i + +#include "py/runtime.h" +#include "shared-bindings/storage/__init__.h" +#include "supervisor/shared/translate.h" + +void common_hal_storage_remount(const char* mount_path, bool readonly) { + mp_raise_NotImplementedError(translate("Unable to remount filesystem")); +} + +void common_hal_storage_erase_filesystem() { + mp_raise_NotImplementedError(translate("Use esptool to erase flash and re-upload Python instead")); +} diff --git a/ports/esp8266/common-hal/time/__init__.c b/ports/esp8266/common-hal/time/__init__.c new file mode 100644 index 00000000000..993e89b1c34 --- /dev/null +++ b/ports/esp8266/common-hal/time/__init__.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "py/mphal.h" + +#include "shared-bindings/time/__init__.h" + +#include "ets_alt_task.h" +#include "user_interface.h" + +inline uint64_t common_hal_time_monotonic() { + return ((uint64_t)system_time_high_word << 32 | (uint64_t)system_get_time()) / 1000; +} + +void common_hal_time_delay_ms(uint32_t delay) { + mp_hal_delay_ms(delay); +} diff --git a/ports/esp8266/esp8266.ld b/ports/esp8266/esp8266.ld index deeb82b4561..3d244f6ad8c 100644 --- a/ports/esp8266/esp8266.ld +++ b/ports/esp8266/esp8266.ld @@ -5,7 +5,7 @@ MEMORY dport0_0_seg : org = 0x3ff00000, len = 0x10 dram0_0_seg : org = 0x3ffe8000, len = 0x14000 iram1_0_seg : org = 0x40100000, len = 0x8000 - irom0_0_seg : org = 0x40209000, len = 0x8f000 + irom0_0_seg : org = 0x40209000, len = 0x91000 } /* define common sections and symbols */ diff --git a/ports/esp8266/esp8266_common.ld b/ports/esp8266/esp8266_common.ld index 6b7eba56a8e..c355105ff4d 100644 --- a/ports/esp8266/esp8266_common.ld +++ b/ports/esp8266/esp8266_common.ld @@ -86,6 +86,11 @@ SECTIONS /* we put some specific text in this section */ + *common-hal/*.o*(.literal* .text*) + *shared-bindings/*.o*(.literal* .text*) + *shared-module/*.o*(.literal* .text*) + *supervisor/*.o*(.literal* .text*) + *py/argcheck.o*(.literal* .text*) *py/asm*.o*(.literal* .text*) *py/bc.o*(.literal* .text*) @@ -137,7 +142,7 @@ SECTIONS *lib/utils/*.o*(.literal*, .text*) *drivers/bus/*.o(.literal* .text*) - build/main.o(.literal* .text*) + build*/main.o(.literal* .text*) *gccollect.o(.literal* .text*) *gchelper.o(.literal* .text*) *help.o(.literal* .text*) @@ -173,7 +178,7 @@ SECTIONS */frozen.o(.rodata.mp_frozen_content) /* frozen modules */ /* for -mforce-l32 */ - build/*.o(.rodata*) + build*/*.o(.rodata*) _irom0_text_end = ABSOLUTE(.); } >irom0_0_seg :irom0_0_phdr diff --git a/ports/esp8266/esp_mphal.c b/ports/esp8266/esp_mphal.c index df97a734302..33d7f2d847a 100644 --- a/ports/esp8266/esp_mphal.c +++ b/ports/esp8266/esp_mphal.c @@ -34,19 +34,17 @@ #include "py/runtime.h" #include "extmod/misc.h" #include "lib/utils/pyexec.h" +#include "supervisor/shared/translate.h" -STATIC byte stdin_ringbuf_array[256]; -ringbuf_t stdin_ringbuf = {stdin_ringbuf_array, sizeof(stdin_ringbuf_array), 0, 0}; +STATIC byte input_buf_array[256]; +ringbuf_t stdin_ringbuf = {input_buf_array, sizeof(input_buf_array)}; void mp_hal_debug_tx_strn_cooked(void *env, const char *str, uint32_t len); const mp_print_t mp_debug_print = {NULL, mp_hal_debug_tx_strn_cooked}; -int uart_attached_to_dupterm; - void mp_hal_init(void) { //ets_wdt_disable(); // it's a pain while developing mp_hal_rtc_init(); uart_init(UART_BIT_RATE_115200, UART_BIT_RATE_115200); - uart_attached_to_dupterm = 0; } void mp_hal_delay_us(uint32_t us) { @@ -56,6 +54,10 @@ void mp_hal_delay_us(uint32_t us) { } } +uint32_t mp_hal_get_cpu_freq(void) { + return system_get_cpu_freq() * 1000000; +} + int mp_hal_stdin_rx_chr(void) { for (;;) { int c = ringbuf_get(&stdin_ringbuf); @@ -83,11 +85,19 @@ void mp_hal_debug_str(const char *str) { #endif void mp_hal_stdout_tx_str(const char *str) { - mp_uos_dupterm_tx_strn(str, strlen(str)); + const char *last = str; + while (*str) { + uart_tx_one_char(UART0, *str++); + } + mp_uos_dupterm_tx_strn(last, str - last); } void mp_hal_stdout_tx_strn(const char *str, uint32_t len) { - mp_uos_dupterm_tx_strn(str, len); + const char *last = str; + while (len--) { + uart_tx_one_char(UART0, *str++); + } + mp_uos_dupterm_tx_strn(last, str - last); } void mp_hal_stdout_tx_strn_cooked(const char *str, uint32_t len) { @@ -97,11 +107,13 @@ void mp_hal_stdout_tx_strn_cooked(const char *str, uint32_t len) { if (str > last) { mp_uos_dupterm_tx_strn(last, str - last); } + uart_tx_one_char(UART0, '\r'); + uart_tx_one_char(UART0, '\n'); mp_uos_dupterm_tx_strn("\r\n", 2); ++str; last = str; } else { - ++str; + uart_tx_one_char(UART0, *str++); } } if (str > last) { @@ -139,7 +151,7 @@ void ets_event_poll(void) { void __assert_func(const char *file, int line, const char *func, const char *expr) { printf("assert:%s:%d:%s: %s\n", file, line, func, expr); nlr_raise(mp_obj_new_exception_msg(&mp_type_AssertionError, - "C-level assert")); + translate("C-level assert"))); } void mp_hal_signal_input(void) { diff --git a/ports/esp8266/esp_mphal.h b/ports/esp8266/esp_mphal.h index 56d9fa35fe3..5ecd392a6b7 100644 --- a/ports/esp8266/esp_mphal.h +++ b/ports/esp8266/esp_mphal.h @@ -40,9 +40,6 @@ void mp_hal_signal_input(void); // Call this when data is available in dupterm object void mp_hal_signal_dupterm_input(void); -// This variable counts how many times the UART is attached to dupterm -extern int uart_attached_to_dupterm; - void mp_hal_init(void); void mp_hal_rtc_init(void); diff --git a/ports/esp8266/espapa102.c b/ports/esp8266/espapa102.c deleted file mode 100644 index 4295fe42d84..00000000000 --- a/ports/esp8266/espapa102.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Robert Foss, Daniel Busch - * - * 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 "py/mpconfig.h" -#if MICROPY_ESP8266_APA102 - -#include -#include "c_types.h" -#include "eagle_soc.h" -#include "user_interface.h" -#include "espapa102.h" - -#define NOP asm volatile(" nop \n\t") - -static inline void _esp_apa102_send_byte(uint32_t clockPinMask, uint32_t dataPinMask, uint8_t byte) { - for (uint32_t i = 0; i < 8; i++) { - if (byte & 0x80) { - // set data pin high - GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, dataPinMask); - } else { - // set data pin low - GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, dataPinMask); - } - - // set clock pin high - GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, clockPinMask); - byte <<= 1; - NOP; - NOP; - - // set clock pin low - GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, clockPinMask); - NOP; - NOP; - } -} - -static inline void _esp_apa102_send_colors(uint32_t clockPinMask, uint32_t dataPinMask, uint8_t *pixels, uint32_t numBytes) { - for (uint32_t i = 0; i < numBytes / 4; i++) { - _esp_apa102_send_byte(clockPinMask, dataPinMask, pixels[i * 4 + 3] | 0xE0); - _esp_apa102_send_byte(clockPinMask, dataPinMask, pixels[i * 4 + 2]); - _esp_apa102_send_byte(clockPinMask, dataPinMask, pixels[i * 4 + 1]); - _esp_apa102_send_byte(clockPinMask, dataPinMask, pixels[i * 4]); - } -} - -static inline void _esp_apa102_start_frame(uint32_t clockPinMask, uint32_t dataPinMask) { - for (uint32_t i = 0; i < 4; i++) { - _esp_apa102_send_byte(clockPinMask, dataPinMask, 0x00); - } -} - -static inline void _esp_apa102_append_additionial_cycles(uint32_t clockPinMask, uint32_t dataPinMask, uint32_t numBytes) { - GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, dataPinMask); - - // we need to write some more clock cycles, because each led - // delays the data by one edge after inverting the clock - for (uint32_t i = 0; i < numBytes / 8 + ((numBytes / 4) % 2); i++) { - GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, clockPinMask); - NOP; - NOP; - - GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, clockPinMask); - NOP; - NOP; - } -} - -static inline void _esp_apa102_end_frame(uint32_t clockPinMask, uint32_t dataPinMask) { - for (uint32_t i = 0; i < 4; i++) { - _esp_apa102_send_byte(clockPinMask, dataPinMask, 0xFF); - } -} - -void esp_apa102_write(uint8_t clockPin, uint8_t dataPin, uint8_t *pixels, uint32_t numBytes) { - uint32_t clockPinMask, dataPinMask; - - clockPinMask = 1 << clockPin; - dataPinMask = 1 << dataPin; - - // start the frame - _esp_apa102_start_frame(clockPinMask, dataPinMask); - - // write pixels - _esp_apa102_send_colors(clockPinMask, dataPinMask, pixels, numBytes); - - // end the frame - _esp_apa102_append_additionial_cycles(clockPinMask, dataPinMask, numBytes); - _esp_apa102_end_frame(clockPinMask, dataPinMask); -} - -#endif diff --git a/ports/esp8266/espapa102.h b/ports/esp8266/espapa102.h deleted file mode 100644 index dd7c5ab7291..00000000000 --- a/ports/esp8266/espapa102.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Robert Foss, Daniel Busch - * - * 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. - */ -#ifndef MICROPY_INCLUDED_ESP8266_ESPAPA102_H -#define MICROPY_INCLUDED_ESP8266_ESPAPA102_H - -void esp_apa102_write(uint8_t clockPin, uint8_t dataPin, uint8_t *pixels, uint32_t numBytes); - -#endif // MICROPY_INCLUDED_ESP8266_ESPAPA102_H diff --git a/ports/esp8266/ets_alt_task.h b/ports/esp8266/ets_alt_task.h index 33a9d3a002b..62f0025a890 100644 --- a/ports/esp8266/ets_alt_task.h +++ b/ports/esp8266/ets_alt_task.h @@ -1,6 +1,9 @@ #ifndef MICROPY_INCLUDED_ESP8266_ETS_ALT_TASK_H #define MICROPY_INCLUDED_ESP8266_ETS_ALT_TASK_H +#include +#include + extern int ets_loop_iter_disable; extern uint32_t system_time_high_word; diff --git a/ports/esp8266/intr.c b/ports/esp8266/intr.c index 456d6cb0464..80641717499 100644 --- a/ports/esp8266/intr.c +++ b/ports/esp8266/intr.c @@ -28,10 +28,16 @@ #include "ets_alt_task.h" #include "modmachine.h" +#include "common-hal/pulseio/PulseIn.h" // this is in a separate file so it can go in iRAM void pin_intr_handler_iram(void *arg) { uint32_t status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, status); + + // machine.Pin handlers pin_intr_handler(status); + + // microcontroller.Pin handlers + microcontroller_pin_call_intr_handlers(status); } diff --git a/ports/esp8266/machine_adc.c b/ports/esp8266/machine_adc.c index b422f0f9ece..2d31ed8ea0f 100644 --- a/ports/esp8266/machine_adc.c +++ b/ports/esp8266/machine_adc.c @@ -28,6 +28,7 @@ #include #include "py/runtime.h" +#include "supervisor/shared/translate.h" #include "user_interface.h" const mp_obj_type_t pyb_adc_type; @@ -53,7 +54,7 @@ STATIC mp_obj_t pyb_adc_make_new(const mp_obj_type_t *type_in, size_t n_args, si return &pyb_adc_vdd3; default: nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "not a valid ADC Channel: %d", chn)); + translate("not a valid ADC Channel: %d"), chn)); } } diff --git a/ports/esp8266/machine_hspi.c b/ports/esp8266/machine_hspi.c index 07770c8c89d..ac464da456d 100644 --- a/ports/esp8266/machine_hspi.c +++ b/ports/esp8266/machine_hspi.c @@ -37,6 +37,7 @@ #include "py/mphal.h" #include "extmod/machine_spi.h" #include "modmachine.h" +#include "supervisor/shared/translate.h" #include "hspi.h" #if MICROPY_PY_MACHINE_SPI @@ -127,13 +128,13 @@ STATIC void machine_hspi_init(mp_obj_base_t *self_in, size_t n_args, const mp_ob spi_init_gpio(HSPI, SPI_CLK_80MHZ_NODIV); spi_clock(HSPI, 0, 0); } else if (self->baudrate > 40000000L) { - mp_raise_ValueError("impossible baudrate"); + mp_raise_ValueError(translate("impossible baudrate")); } else { uint32_t divider = 40000000L / self->baudrate; uint16_t prediv = MIN(divider, SPI_CLKDIV_PRE + 1); uint16_t cntdiv = (divider / prediv) * 2; // cntdiv has to be even if (cntdiv > SPI_CLKCNT_N + 1 || cntdiv == 0 || prediv == 0) { - mp_raise_ValueError("impossible baudrate"); + mp_raise_ValueError(translate("impossible baudrate")); } self->baudrate = 80000000L / (prediv * cntdiv); spi_init_gpio(HSPI, SPI_CLK_USE_DIV); diff --git a/ports/esp8266/machine_pin.c b/ports/esp8266/machine_pin.c index 14505c8f024..0467ffb4bdf 100644 --- a/ports/esp8266/machine_pin.c +++ b/ports/esp8266/machine_pin.c @@ -39,6 +39,8 @@ #include "extmod/virtpin.h" #include "modmachine.h" +#include "supervisor/shared/translate.h" + #define GET_TRIGGER(phys_port) \ GPIO_PIN_INT_TYPE_GET(GPIO_REG_READ(GPIO_PIN_ADDR(phys_port))) #define SET_TRIGGER(phys_port, trig) \ @@ -124,7 +126,7 @@ void pin_intr_handler(uint32_t status) { pyb_pin_obj_t *mp_obj_get_pin_obj(mp_obj_t pin_in) { if (mp_obj_get_type(pin_in) != &pyb_pin_type) { - mp_raise_ValueError("expecting a pin"); + mp_raise_ValueError(translate("expecting a pin")); } pyb_pin_obj_t *self = pin_in; return self; @@ -279,7 +281,7 @@ STATIC mp_obj_t pyb_pin_obj_init_helper(pyb_pin_obj_t *self, size_t n_args, cons // only pull-down seems to be supported by the hardware, and // we only expose pull-up behaviour in software if (pull != GPIO_PULL_NONE) { - mp_raise_ValueError("Pin(16) doesn't support pull"); + mp_raise_ValueError(translate("Pin(16) doesn't support pull")); } } else { PIN_FUNC_SELECT(self->periph, self->func); @@ -318,7 +320,7 @@ mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, pin = (pyb_pin_obj_t*)&pyb_pin_obj[wanted_pin]; } if (pin == NULL || pin->base.type == NULL) { - mp_raise_ValueError("invalid pin"); + mp_raise_ValueError(translate("invalid pin")); } if (n_args > 1 || n_kw > 0) { @@ -384,7 +386,7 @@ STATIC mp_obj_t pyb_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); if (self->phys_port >= 16) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "pin does not have IRQ capabilities")); + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("pin does not have IRQ capabilities"))); } if (n_args > 1 || kw_args->used != 0) { diff --git a/ports/esp8266/machine_pwm.c b/ports/esp8266/machine_pwm.c index 4c5cb872777..a117a41d52f 100644 --- a/ports/esp8266/machine_pwm.c +++ b/ports/esp8266/machine_pwm.c @@ -31,6 +31,7 @@ #include "py/runtime.h" #include "modmachine.h" +#include "supervisor/shared/translate.h" typedef struct _pyb_pwm_obj_t { mp_obj_base_t base; @@ -39,7 +40,7 @@ typedef struct _pyb_pwm_obj_t { uint8_t channel; } pyb_pwm_obj_t; -STATIC bool pwm_inited = false; +bool pwm_inited = false; /******************************************************************************/ // MicroPython bindings for PWM @@ -66,7 +67,7 @@ STATIC void pyb_pwm_init_helper(pyb_pwm_obj_t *self, size_t n_args, const mp_obj int channel = pwm_add(self->pin->phys_port, self->pin->periph, self->pin->func); if (channel == -1) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "PWM not supported on pin %d", self->pin->phys_port)); + translate("PWM not supported on pin %d"), self->pin->phys_port)); } self->channel = channel; diff --git a/ports/esp8266/machine_rtc.c b/ports/esp8266/machine_rtc.c index bbfc172cd8a..9197efb7a8c 100644 --- a/ports/esp8266/machine_rtc.c +++ b/ports/esp8266/machine_rtc.c @@ -29,6 +29,7 @@ #include "py/runtime.h" #include "lib/timeutils/timeutils.h" +#include "supervisor/shared/translate.h" #include "user_interface.h" #include "modmachine.h" @@ -181,7 +182,7 @@ STATIC mp_obj_t pyb_rtc_memory(size_t n_args, const mp_obj_t *args) { mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ); if (bufinfo.len > MEM_USER_MAXLEN) { - mp_raise_ValueError("buffer too long"); + mp_raise_ValueError(translate("buffer too long")); } len = bufinfo.len; @@ -205,7 +206,7 @@ STATIC mp_obj_t pyb_rtc_alarm(mp_obj_t self_in, mp_obj_t alarm_id, mp_obj_t time // check we want alarm0 if (mp_obj_get_int(alarm_id) != 0) { - mp_raise_ValueError("invalid alarm"); + mp_raise_ValueError(translate("invalid alarm")); } // set expiry time (in microseconds) @@ -219,7 +220,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_rtc_alarm_obj, pyb_rtc_alarm); STATIC mp_obj_t pyb_rtc_alarm_left(size_t n_args, const mp_obj_t *args) { // check we want alarm0 if (n_args > 1 && mp_obj_get_int(args[1]) != 0) { - mp_raise_ValueError("invalid alarm"); + mp_raise_ValueError(translate("invalid alarm")); } uint64_t now = pyb_rtc_get_us_since_2000(); @@ -242,7 +243,7 @@ STATIC mp_obj_t pyb_rtc_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k // check we want alarm0 if (args[ARG_trigger].u_int != 0) { - mp_raise_ValueError("invalid alarm"); + mp_raise_ValueError(translate("invalid alarm")); } // set the wake value diff --git a/ports/esp8266/machine_uart.c b/ports/esp8266/machine_uart.c index e8be5e538cf..c6a4e1ba125 100644 --- a/ports/esp8266/machine_uart.c +++ b/ports/esp8266/machine_uart.c @@ -34,6 +34,7 @@ #include "py/runtime.h" #include "py/stream.h" #include "py/mperrno.h" +#include "supervisor/shared/translate.h" #include "modmachine.h" // UartDev is defined and initialized in rom code. @@ -104,7 +105,7 @@ STATIC void pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const mp_o self->bits = 8; break; default: - mp_raise_ValueError("invalid data bits"); + mp_raise_ValueError(translate("invalid data bits")); break; } @@ -140,7 +141,7 @@ STATIC void pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const mp_o self->stop = 2; break; default: - mp_raise_ValueError("invalid stop bits"); + mp_raise_ValueError(translate("invalid stop bits")); break; } @@ -165,7 +166,7 @@ STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size // get uart id mp_int_t uart_id = mp_obj_get_int(args[0]); if (uart_id != 0 && uart_id != 1) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "UART(%d) does not exist", uart_id)); + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, translate("UART(%d) does not exist"), uart_id)); } // create instance @@ -215,7 +216,7 @@ STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, i pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); if (self->uart_id == 1) { - mp_raise_msg(&mp_type_OSError, "UART(1) can't read"); + mp_raise_msg(&mp_type_OSError, translate("UART(1) can't read")); } // make sure we want at least 1 char diff --git a/ports/esp8266/main.c b/ports/esp8266/main.c index 7e5034b04aa..969d35bbf91 100644 --- a/ports/esp8266/main.c +++ b/ports/esp8266/main.c @@ -28,19 +28,65 @@ #include #include "py/compile.h" +#include "py/frozenmod.h" #include "py/runtime.h" #include "py/stackctrl.h" #include "py/mperrno.h" #include "py/mphal.h" #include "py/gc.h" -#include "extmod/misc.h" +#include "lib/oofatfs/ff.h" #include "lib/mp-readline/readline.h" #include "lib/utils/pyexec.h" #include "gccollect.h" #include "user_interface.h" +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/pulseio/PWMOut.h" STATIC char heap[36 * 1024]; +bool maybe_run(const char* filename, pyexec_result_t* exec_result) { + mp_import_stat_t stat = mp_import_stat(filename); + if (stat != MP_IMPORT_STAT_FILE) { + return false; + } + mp_hal_stdout_tx_str(filename); + mp_hal_stdout_tx_str(" output:\r\n"); + pyexec_file(filename, exec_result); + return true; +} + +bool serial_active = false; + +STATIC bool start_mp(void) { + pyexec_frozen_module("_boot.py"); + + pyexec_result_t result; + bool found_boot = maybe_run("settings.txt", &result) || + maybe_run("settings.py", &result) || + maybe_run("boot.py", &result) || + maybe_run("boot.txt", &result); + + if (!found_boot || !(result.return_code & PYEXEC_FORCED_EXIT)) { + maybe_run("code.txt", &result) || + maybe_run("code.py", &result) || + maybe_run("main.py", &result) || + maybe_run("main.txt", &result); + } + + if (result.return_code & PYEXEC_FORCED_EXIT) { + return false; + } + + // We can't detect connections so we wait for any character to mark the serial active. + if (!serial_active) { + mp_hal_stdin_rx_chr(); + serial_active = true; + } + mp_hal_stdout_tx_str("\r\n\r\n"); + mp_hal_stdout_tx_str("Press any key to enter the REPL. Use CTRL-D to soft reset.\r\n"); + return mp_hal_stdin_rx_chr() == CHAR_CTRL_D; +} + STATIC void mp_reset(void) { mp_stack_set_top((void*)0x40000000); mp_stack_set_limit(8192); @@ -49,9 +95,15 @@ STATIC void mp_reset(void) { mp_init(); mp_obj_list_init(mp_sys_path, 0); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_)); + // Frozen modules are in their own pseudo-dir, e.g., ".frozen". + // Prioritize .frozen over /lib. + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_FROZEN_FAKE_DIR_QSTR)); + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); + mp_obj_list_init(mp_sys_argv, 0); + + reset_pins(); #if MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA extern void esp_native_code_init(void); esp_native_code_init(); @@ -59,70 +111,39 @@ STATIC void mp_reset(void) { pin_init0(); readline_init0(); dupterm_task_init(); -#if MICROPY_MODULE_FROZEN - pyexec_frozen_module("_boot.py"); - pyexec_file("boot.py"); - if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) { - pyexec_file("main.py"); - } -#endif - - // Check if there are any dupterm objects registered and if not then - // activate UART(0), or else there will never be any chance to get a REPL - size_t idx; - for (idx = 0; idx < MICROPY_PY_OS_DUPTERM; ++idx) { - if (MP_STATE_VM(dupterm_objs[idx]) != MP_OBJ_NULL) { - break; - } - } - if (idx == MICROPY_PY_OS_DUPTERM) { - mp_obj_t args[2]; - args[0] = MP_OBJ_NEW_SMALL_INT(0); - args[1] = MP_OBJ_NEW_SMALL_INT(115200); - args[0] = pyb_uart_type.make_new(&pyb_uart_type, 2, 0, args); - args[1] = MP_OBJ_NEW_SMALL_INT(1); - extern mp_obj_t os_dupterm(size_t n_args, const mp_obj_t *args); - os_dupterm(2, args); - mp_hal_stdout_tx_str("Activated UART(0) for REPL\r\n"); - } + pwmout_reset(); } -void soft_reset(void) { +bool soft_reset(void) { gc_sweep_all(); mp_hal_stdout_tx_str("PYB: soft reboot\r\n"); mp_hal_delay_us(10000); // allow UART to flush output mp_reset(); - #if MICROPY_REPL_EVENT_DRIVEN - pyexec_event_repl_init(); - #endif + mp_hal_delay_us(1000); // Give the RTOS time to do housekeeping. + return start_mp(); } void init_done(void) { - #if MICROPY_REPL_EVENT_DRIVEN - uart_task_init(); - #endif mp_reset(); + mp_hal_delay_us(1000); // Give the RTOS time to do housekeeping. + bool skip_repl = start_mp(); mp_hal_stdout_tx_str("\r\n"); - #if MICROPY_REPL_EVENT_DRIVEN - pyexec_event_repl_init(); - #endif - #if !MICROPY_REPL_EVENT_DRIVEN -soft_reset: - for (;;) { - if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { - if (pyexec_raw_repl() != 0) { - break; - } - } else { - if (pyexec_friendly_repl() != 0) { - break; + int exit_code = PYEXEC_FORCED_EXIT; + while (true) { + if (!skip_repl) { + if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { + exit_code = pyexec_raw_repl(); + } else { + exit_code = pyexec_friendly_repl(); } } + if (exit_code == PYEXEC_FORCED_EXIT) { + skip_repl = soft_reset(); + } else if (exit_code != 0) { + break; + } } - soft_reset(); - goto soft_reset; - #endif } void user_init(void) { diff --git a/ports/esp8266/makeimg.py b/ports/esp8266/makeimg.py index 091854fa4d8..1071f83e170 100644 --- a/ports/esp8266/makeimg.py +++ b/ports/esp8266/makeimg.py @@ -21,6 +21,7 @@ with open(sys.argv[2], 'rb') as f: data_rom = f.read() + print(SEGS_MAX_SIZE, len(data_flash)) pad = b'\xff' * (SEGS_MAX_SIZE - len(data_flash)) assert len(pad) >= 4 fout.write(pad[:-4]) diff --git a/ports/esp8266/modesp.c b/ports/esp8266/modesp.c index 8f9db4fba2f..b1b30cd8ba3 100644 --- a/ports/esp8266/modesp.c +++ b/ports/esp8266/modesp.c @@ -30,17 +30,15 @@ #include "py/runtime.h" #include "py/mperrno.h" #include "py/mphal.h" -#include "drivers/dht/dht.h" +#include "supervisor/shared/translate.h" #include "uart.h" #include "user_interface.h" #include "mem.h" -#include "espneopixel.h" -#include "espapa102.h" #include "modmachine.h" #define MODESP_INCLUDE_CONSTANTS (1) -void error_check(bool status, const char *msg) { +void error_check(bool status, const compressed_string_t *msg) { if (!status) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, msg)); } @@ -118,7 +116,7 @@ STATIC mp_obj_t esp_flash_write(mp_obj_t offset_in, const mp_obj_t buf_in) { mp_buffer_info_t bufinfo; mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); if (bufinfo.len & 0x3) { - mp_raise_ValueError("len must be multiple of 4"); + mp_raise_ValueError(translate("len must be multiple of 4")); } SpiFlashOpResult res = spi_flash_write(offset, bufinfo.buf, bufinfo.len); if (res == SPI_FLASH_RESULT_OK) { @@ -193,28 +191,6 @@ STATIC mp_obj_t esp_check_fw(void) { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_check_fw_obj, esp_check_fw); - -STATIC mp_obj_t esp_neopixel_write_(mp_obj_t pin, mp_obj_t buf, mp_obj_t is800k) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ); - esp_neopixel_write(mp_obj_get_pin_obj(pin)->phys_port, - (uint8_t*)bufinfo.buf, bufinfo.len, mp_obj_is_true(is800k)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(esp_neopixel_write_obj, esp_neopixel_write_); - -#if MICROPY_ESP8266_APA102 -STATIC mp_obj_t esp_apa102_write_(mp_obj_t clockPin, mp_obj_t dataPin, mp_obj_t buf) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ); - esp_apa102_write(mp_obj_get_pin_obj(clockPin)->phys_port, - mp_obj_get_pin_obj(dataPin)->phys_port, - (uint8_t*)bufinfo.buf, bufinfo.len); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(esp_apa102_write_obj, esp_apa102_write_); -#endif - STATIC mp_obj_t esp_freemem() { return MP_OBJ_NEW_SMALL_INT(system_get_free_heap_size()); } @@ -295,7 +271,7 @@ void *esp_native_code_commit(void *buf, size_t len) { len = (len + 3) & ~3; if (esp_native_code_cur + len > esp_native_code_end) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_MemoryError, - "memory allocation failed, allocating %u bytes for native code", (uint)len)); + translate("memory allocation failed, allocating %u bytes for native code"), (uint)len)); } void *dest; @@ -338,7 +314,7 @@ STATIC mp_obj_t esp_set_native_code_location(mp_obj_t start_in, mp_obj_t len_in) esp_native_code_erased = esp_native_code_start; // memory-mapped flash is limited in extents to 1MByte if (esp_native_code_end > FLASH_END - FLASH_START) { - mp_raise_ValueError("flash location must be below 1MByte"); + mp_raise_ValueError(translate("flash location must be below 1MByte")); } } return mp_const_none; @@ -359,13 +335,6 @@ STATIC const mp_rom_map_elem_t esp_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_flash_erase), MP_ROM_PTR(&esp_flash_erase_obj) }, { MP_ROM_QSTR(MP_QSTR_flash_size), MP_ROM_PTR(&esp_flash_size_obj) }, { MP_ROM_QSTR(MP_QSTR_flash_user_start), MP_ROM_PTR(&esp_flash_user_start_obj) }, - #if MICROPY_ESP8266_NEOPIXEL - { MP_ROM_QSTR(MP_QSTR_neopixel_write), MP_ROM_PTR(&esp_neopixel_write_obj) }, - #endif - #if MICROPY_ESP8266_APA102 - { MP_ROM_QSTR(MP_QSTR_apa102_write), MP_ROM_PTR(&esp_apa102_write_obj) }, - #endif - { MP_ROM_QSTR(MP_QSTR_dht_readinto), MP_ROM_PTR(&dht_readinto_obj) }, { MP_ROM_QSTR(MP_QSTR_freemem), MP_ROM_PTR(&esp_freemem_obj) }, { MP_ROM_QSTR(MP_QSTR_meminfo), MP_ROM_PTR(&esp_meminfo_obj) }, { MP_ROM_QSTR(MP_QSTR_check_fw), MP_ROM_PTR(&esp_check_fw_obj) }, diff --git a/ports/esp8266/modmachine.c b/ports/esp8266/modmachine.c index 7e5f6714bf6..dc7bad1c68d 100644 --- a/ports/esp8266/modmachine.c +++ b/ports/esp8266/modmachine.c @@ -35,6 +35,7 @@ #include "extmod/machine_pulse.h" #include "extmod/machine_i2c.h" #include "modmachine.h" +#include "supervisor/shared/translate.h" #include "xtirq.h" #include "os_type.h" @@ -59,7 +60,7 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) { // set mp_int_t freq = mp_obj_get_int(args[0]) / 1000000; if (freq != 80 && freq != 160) { - mp_raise_ValueError("frequency can only be either 80Mhz or 160MHz"); + mp_raise_ValueError(translate("frequency can only be either 80Mhz or 160MHz")); } system_update_cpu_freq(freq); return mp_const_none; diff --git a/ports/esp8266/modnetwork.c b/ports/esp8266/modnetwork.c index c7f3397c442..1a41aa4d613 100644 --- a/ports/esp8266/modnetwork.c +++ b/ports/esp8266/modnetwork.c @@ -32,6 +32,7 @@ #include "py/runtime.h" #include "py/mphal.h" #include "lib/netutils/netutils.h" +#include "supervisor/shared/translate.h" #include "queue.h" #include "user_interface.h" #include "espconn.h" @@ -46,7 +47,7 @@ typedef struct _wlan_if_obj_t { int if_id; } wlan_if_obj_t; -void error_check(bool status, const char *msg); +void error_check(bool status, const compressed_string_t *msg); const mp_obj_type_t wlan_if_type; STATIC const wlan_if_obj_t wlan_objs[] = { @@ -57,7 +58,7 @@ STATIC const wlan_if_obj_t wlan_objs[] = { STATIC void require_if(mp_obj_t wlan_if, int if_no) { wlan_if_obj_t *self = MP_OBJ_TO_PTR(wlan_if); if (self->if_id != if_no) { - error_check(false, if_no == STATION_IF ? "STA required" : "AP required"); + error_check(false, if_no == STATION_IF ? translate("STA required") : translate("AP required")); } } @@ -83,7 +84,7 @@ STATIC mp_obj_t esp_active(size_t n_args, const mp_obj_t *args) { } else { mode &= ~mask; } - error_check(wifi_set_opmode(mode), "Cannot update i/f status"); + error_check(wifi_set_opmode(mode), translate("Cannot update i/f status")); return mp_const_none; } @@ -138,9 +139,9 @@ STATIC mp_obj_t esp_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k } if (set_config) { - error_check(wifi_station_set_config(&config), "Cannot set STA config"); + error_check(wifi_station_set_config(&config), translate("Cannot set STA config")); } - error_check(wifi_station_connect(), "Cannot connect to AP"); + error_check(wifi_station_connect(), translate("Cannot connect to AP")); return mp_const_none; } @@ -148,7 +149,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp_connect_obj, 1, esp_connect); STATIC mp_obj_t esp_disconnect(mp_obj_t self_in) { require_if(self_in, STATION_IF); - error_check(wifi_station_disconnect(), "Cannot disconnect from AP"); + error_check(wifi_station_disconnect(), translate("Cannot disconnect from AP")); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_disconnect_obj, esp_disconnect); @@ -169,7 +170,7 @@ STATIC mp_obj_t esp_status(size_t n_args, const mp_obj_t *args) { return MP_OBJ_NEW_SMALL_INT(wifi_station_get_rssi()); } } - mp_raise_ValueError("unknown status param"); + mp_raise_ValueError(translate("unknown status param")); } } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_status_obj, 1, 2, esp_status); @@ -218,7 +219,7 @@ STATIC mp_obj_t esp_scan(mp_obj_t self_in) { require_if(self_in, STATION_IF); if ((wifi_get_opmode() & STATION_MODE) == 0) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, - "STA must be active")); + translate("STA must be active"))); } mp_obj_t list = mp_obj_new_list(0, NULL); esp_scan_list = &list; @@ -235,7 +236,7 @@ STATIC mp_obj_t esp_scan(mp_obj_t self_in) { ets_loop_iter(); } if (list == MP_OBJ_NULL) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "scan failed")); + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("scan failed"))); } return list; } @@ -302,7 +303,7 @@ STATIC mp_obj_t esp_ifconfig(size_t n_args, const mp_obj_t *args) { } if (!wifi_set_ip_info(self->if_id, &info)) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, - "wifi_set_ip_info() failed")); + translate("wifi_set_ip_info() failed"))); } dns_setserver(0, &dns_addr); if (restart_dhcp_server) { @@ -315,7 +316,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_ifconfig_obj, 1, 2, esp_ifconfig) STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { if (n_args != 1 && kwargs->used != 0) { - mp_raise_TypeError("either pos or kw args are allowed"); + mp_raise_TypeError(translate("either pos or kw args are allowed")); } wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); @@ -325,9 +326,9 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs } cfg; if (self->if_id == STATION_IF) { - error_check(wifi_station_get_config(&cfg.sta), "can't get STA config"); + error_check(wifi_station_get_config(&cfg.sta), translate("can't get STA config")); } else { - error_check(wifi_softap_get_config(&cfg.ap), "can't get AP config"); + error_check(wifi_softap_get_config(&cfg.ap), translate("can't get AP config")); } int req_if = -1; @@ -342,7 +343,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs mp_buffer_info_t bufinfo; mp_get_buffer_raise(kwargs->table[i].value, &bufinfo, MP_BUFFER_READ); if (bufinfo.len != 6) { - mp_raise_ValueError("invalid buffer length"); + mp_raise_ValueError(translate("invalid buffer length")); } wifi_set_macaddr(self->if_id, bufinfo.buf); break; @@ -401,9 +402,9 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs } if (self->if_id == STATION_IF) { - error_check(wifi_station_set_config(&cfg.sta), "can't set STA config"); + error_check(wifi_station_set_config(&cfg.sta), translate("can't set STA config")); } else { - error_check(wifi_softap_set_config(&cfg.ap), "can't set AP config"); + error_check(wifi_softap_set_config(&cfg.ap), translate("can't set AP config")); } return mp_const_none; @@ -412,7 +413,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs // Get config if (n_args != 2) { - mp_raise_TypeError("can query only one param"); + mp_raise_TypeError(translate("can query only one param")); } mp_obj_t val; @@ -465,7 +466,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs return val; unknown: - mp_raise_ValueError("unknown config param"); + mp_raise_ValueError(translate("unknown config param")); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp_config_obj, 1, esp_config); diff --git a/ports/esp8266/modules/_boot.py b/ports/esp8266/modules/_boot.py index 81eb20dd631..cbaf2aba66d 100644 --- a/ports/esp8266/modules/_boot.py +++ b/ports/esp8266/modules/_boot.py @@ -1,11 +1,12 @@ import gc gc.threshold((gc.mem_free() + gc.mem_alloc()) // 4) -import uos from flashbdev import bdev +import storage try: if bdev: - uos.mount(bdev, '/') + vfs = storage.VfsFat(bdev) + storage.mount(vfs, '/') except OSError: import inisetup inisetup.setup() diff --git a/ports/esp8266/modules/apa102.py b/ports/esp8266/modules/apa102.py deleted file mode 100644 index 41b7c0485c4..00000000000 --- a/ports/esp8266/modules/apa102.py +++ /dev/null @@ -1,17 +0,0 @@ -# APA102 driver for MicroPython on ESP8266 -# MIT license; Copyright (c) 2016 Robert Foss, Daniel Busch - -from esp import apa102_write -from neopixel import NeoPixel - - -class APA102(NeoPixel): - ORDER = (0, 1, 2, 3) - - def __init__(self, clock_pin, data_pin, n, bpp=4): - super().__init__(data_pin, n, bpp) - self.clock_pin = clock_pin - self.clock_pin.init(clock_pin.OUT) - - def write(self): - apa102_write(self.clock_pin, self.pin, self.buf) diff --git a/ports/esp8266/modules/dht.py b/ports/esp8266/modules/dht.py deleted file mode 120000 index 2aa2f5cbfed..00000000000 --- a/ports/esp8266/modules/dht.py +++ /dev/null @@ -1 +0,0 @@ -../../../drivers/dht/dht.py \ No newline at end of file diff --git a/ports/esp8266/modules/ds18x20.py b/ports/esp8266/modules/ds18x20.py deleted file mode 120000 index 1ec92d1c996..00000000000 --- a/ports/esp8266/modules/ds18x20.py +++ /dev/null @@ -1 +0,0 @@ -../../../drivers/onewire/ds18x20.py \ No newline at end of file diff --git a/ports/esp8266/modules/inisetup.py b/ports/esp8266/modules/inisetup.py index 9184c6c3965..46f08924840 100644 --- a/ports/esp8266/modules/inisetup.py +++ b/ports/esp8266/modules/inisetup.py @@ -1,11 +1,15 @@ -import uos -import network from flashbdev import bdev +import network +import storage def wifi(): - import ubinascii + try: + import ubinascii as binascii + except ImportError: + import binascii + ap_if = network.WLAN(network.AP_IF) - essid = b"MicroPython-%s" % ubinascii.hexlify(ap_if.config("mac")[-3:]) + essid = b"MicroPython-%s" % binascii.hexlify(ap_if.config("mac")[-3:]) ap_if.config(essid=essid, authmode=network.AUTH_WPA_WPA2_PSK, password=b"micropythoN") def check_bootsec(): @@ -36,16 +40,14 @@ def setup(): check_bootsec() print("Performing initial setup") wifi() - uos.VfsFat.mkfs(bdev) - vfs = uos.VfsFat(bdev) - uos.mount(vfs, '/') + storage.VfsFat.mkfs(bdev) + vfs = storage.VfsFat(bdev) + storage.mount(vfs, '/') with open("boot.py", "w") as f: f.write("""\ # This file is executed on every boot (including wake-boot from deepsleep) #import esp #esp.osdebug(None) -import uos, machine -uos.dupterm(machine.UART(0, 115200), 1) import gc #import webrepl #webrepl.start() diff --git a/ports/esp8266/modules/neopixel.py b/ports/esp8266/modules/neopixel.py deleted file mode 100644 index b13424d7d82..00000000000 --- a/ports/esp8266/modules/neopixel.py +++ /dev/null @@ -1,32 +0,0 @@ -# NeoPixel driver for MicroPython on ESP8266 -# MIT license; Copyright (c) 2016 Damien P. George - -from esp import neopixel_write - - -class NeoPixel: - ORDER = (1, 0, 2, 3) - - def __init__(self, pin, n, bpp=3): - self.pin = pin - self.n = n - self.bpp = bpp - self.buf = bytearray(n * bpp) - self.pin.init(pin.OUT) - - def __setitem__(self, index, val): - offset = index * self.bpp - for i in range(self.bpp): - self.buf[offset + self.ORDER[i]] = val[i] - - def __getitem__(self, index): - offset = index * self.bpp - return tuple(self.buf[offset + self.ORDER[i]] - for i in range(self.bpp)) - - def fill(self, color): - for i in range(self.n): - self[i] = color - - def write(self): - neopixel_write(self.pin, self.buf, True) diff --git a/ports/esp8266/modules/onewire.py b/ports/esp8266/modules/onewire.py deleted file mode 120000 index 33f30e84f11..00000000000 --- a/ports/esp8266/modules/onewire.py +++ /dev/null @@ -1 +0,0 @@ -../../../drivers/onewire/onewire.py \ No newline at end of file diff --git a/ports/esp8266/modules/webrepl.py b/ports/esp8266/modules/webrepl.py index aa156d14879..a6c30e2cacc 100644 --- a/ports/esp8266/modules/webrepl.py +++ b/ports/esp8266/modules/webrepl.py @@ -1,6 +1,6 @@ # This module should be imported from REPL, not run from command line. import socket -import uos +import multiterminal import network import websocket import websocket_helper @@ -31,9 +31,7 @@ def setup_conn(port, accept_handler): def accept_conn(listen_sock): global client_s cl, remote_addr = listen_sock.accept() - prev = uos.dupterm(None) - uos.dupterm(prev) - if prev: + if multiterminal.get_secondary_terminal(): print("\nConcurrent WebREPL connection from", remote_addr, "rejected") cl.close() return @@ -44,13 +42,13 @@ def accept_conn(listen_sock): ws = _webrepl._webrepl(ws) cl.setblocking(False) # notify REPL on socket incoming data - cl.setsockopt(socket.SOL_SOCKET, 20, uos.dupterm_notify) - uos.dupterm(ws) + cl.setsockopt(socket.SOL_SOCKET, 20, multiterminal.schedule_secondary_terminal_read) + multiterminal.set_secondary_terminal(ws) def stop(): global listen_s, client_s - uos.dupterm(None) + multiterminal.clear_secondary_terminal() if client_s: client_s.close() if listen_s: diff --git a/ports/esp8266/modules/webrepl_setup.py b/ports/esp8266/modules/webrepl_setup.py index 129313a21c9..e87fac99ea2 100644 --- a/ports/esp8266/modules/webrepl_setup.py +++ b/ports/esp8266/modules/webrepl_setup.py @@ -1,5 +1,4 @@ import sys -#import uos as os import os import machine @@ -35,6 +34,12 @@ def exists(fname): except OSError: return False +def copy_stream(s_in, s_out): + buf = bytearray(64) + while 1: + sz = s_in.readinto(buf) + s_out.write(buf, sz) + def get_daemon_status(): with open(RC) as f: @@ -45,6 +50,10 @@ def get_daemon_status(): return True return None +def add_daemon(): + with open(RC) as old_f, open(RC + ".tmp", "w") as new_f: + new_f.write("import webrepl\nwebrepl.start()\n") + copy_stream(old_f, new_f) def change_daemon(action): LINES = ("import webrepl", "webrepl.start()") @@ -97,6 +106,7 @@ def main(): print("Changes will be activated after reboot") resp = input_choice("Would you like to reboot now? (y/n) ", ("y", "n", "")) if resp == "y": + print("Rebooting. Please manually reset if it hangs.") machine.reset() main() diff --git a/ports/esp8266/moduos.c b/ports/esp8266/moduos.c deleted file mode 100644 index 7a32c11c078..00000000000 --- a/ports/esp8266/moduos.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2015 Josef Gajdusek - * - * 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 - -#include "py/objtuple.h" -#include "py/objstr.h" -#include "extmod/misc.h" -#include "extmod/vfs.h" -#include "extmod/vfs_fat.h" -#include "genhdr/mpversion.h" -#include "esp_mphal.h" -#include "user_interface.h" - -STATIC const qstr os_uname_info_fields[] = { - MP_QSTR_sysname, MP_QSTR_nodename, - MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine -}; -STATIC const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, MICROPY_PY_SYS_PLATFORM); -STATIC const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, MICROPY_PY_SYS_PLATFORM); -STATIC const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); -STATIC const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); - -STATIC mp_obj_tuple_t os_uname_info_obj = { - .base = {&mp_type_attrtuple}, - .len = 5, - .items = { - (mp_obj_t)&os_uname_info_sysname_obj, - (mp_obj_t)&os_uname_info_nodename_obj, - NULL, - (mp_obj_t)&os_uname_info_version_obj, - (mp_obj_t)&os_uname_info_machine_obj, - (void *)os_uname_info_fields, - } -}; - -STATIC mp_obj_t os_uname(void) { - // We must populate the "release" field each time in case it was GC'd since the last call. - const char *ver = system_get_sdk_version(); - os_uname_info_obj.items[2] = mp_obj_new_str(ver, strlen(ver)); - return (mp_obj_t)&os_uname_info_obj; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_uname_obj, os_uname); - -STATIC mp_obj_t os_urandom(mp_obj_t num) { - mp_int_t n = mp_obj_get_int(num); - vstr_t vstr; - vstr_init_len(&vstr, n); - for (int i = 0; i < n; i++) { - vstr.buf[i] = *WDEV_HWRNG; - } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom); - -// We wrap the mp_uos_dupterm function to detect if a UART is attached or not -mp_obj_t os_dupterm(size_t n_args, const mp_obj_t *args) { - mp_obj_t prev_obj = mp_uos_dupterm_obj.fun.var(n_args, args); - if (mp_obj_get_type(args[0]) == &pyb_uart_type) { - ++uart_attached_to_dupterm; - } - if (mp_obj_get_type(prev_obj) == &pyb_uart_type) { - --uart_attached_to_dupterm; - } - return prev_obj; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_dupterm_obj, 1, 2, os_dupterm); - -STATIC mp_obj_t os_dupterm_notify(mp_obj_t obj_in) { - (void)obj_in; - mp_hal_signal_dupterm_input(); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_dupterm_notify_obj, os_dupterm_notify); - -STATIC const mp_rom_map_elem_t os_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) }, - { MP_ROM_QSTR(MP_QSTR_uname), MP_ROM_PTR(&os_uname_obj) }, - { MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&os_urandom_obj) }, - #if MICROPY_PY_OS_DUPTERM - { MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&os_dupterm_obj) }, - { MP_ROM_QSTR(MP_QSTR_dupterm_notify), MP_ROM_PTR(&os_dupterm_notify_obj) }, - #endif - #if MICROPY_VFS_FAT - { MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) }, - { MP_ROM_QSTR(MP_QSTR_ilistdir), MP_ROM_PTR(&mp_vfs_ilistdir_obj) }, - { MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mp_vfs_listdir_obj) }, - { MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mp_vfs_mkdir_obj) }, - { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&mp_vfs_rmdir_obj) }, - { MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&mp_vfs_chdir_obj) }, - { MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&mp_vfs_getcwd_obj) }, - { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&mp_vfs_remove_obj) }, - { MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&mp_vfs_rename_obj) }, - { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mp_vfs_stat_obj) }, - { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mp_vfs_statvfs_obj) }, - { MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mp_vfs_mount_obj) }, - { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&mp_vfs_umount_obj) }, - #endif -}; - -STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table); - -const mp_obj_module_t uos_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&os_module_globals, -}; diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h index 97b30908677..435f2c5cd2e 100644 --- a/ports/esp8266/mpconfigport.h +++ b/ports/esp8266/mpconfigport.h @@ -28,7 +28,7 @@ #define MICROPY_ENABLE_SOURCE_LINE (1) #define MICROPY_MODULE_WEAK_LINKS (1) #define MICROPY_CAN_OVERRIDE_BUILTINS (1) -#define MICROPY_USE_INTERNAL_ERRNO (1) +#define MICROPY_USE_INTERNAL_ERRNO (0) #define MICROPY_ENABLE_SCHEDULER (1) #define MICROPY_PY_DESCRIPTORS (1) #define MICROPY_PY_ALL_SPECIAL_METHODS (1) @@ -50,15 +50,16 @@ #define MICROPY_PY_GC (1) #define MICROPY_PY_ARRAY (1) #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) +#define MICROPY_NONSTANDARD_TYPECODES (0) #define MICROPY_PY_COLLECTIONS (1) #define MICROPY_PY_COLLECTIONS_DEQUE (1) #define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1) -#define MICROPY_PY_MATH (1) +#define MICROPY_PY_MATH (0) #define MICROPY_PY_CMATH (0) #define MICROPY_PY_IO (1) #define MICROPY_PY_IO_IOBASE (1) #define MICROPY_PY_IO_FILEIO (1) -#define MICROPY_PY_STRUCT (1) +#define MICROPY_PY_STRUCT (0) #define MICROPY_PY_SYS (1) #define MICROPY_PY_SYS_MAXSIZE (1) #define MICROPY_PY_SYS_EXIT (1) @@ -72,7 +73,7 @@ #define MICROPY_PY_UHEAPQ (1) #define MICROPY_PY_UTIMEQ (1) #define MICROPY_PY_UJSON (1) -#define MICROPY_PY_URANDOM (1) +#define MICROPY_PY_URANDOM (0) #define MICROPY_PY_URE (1) #define MICROPY_PY_USELECT (1) #define MICROPY_PY_UTIME_MP_HAL (1) @@ -93,6 +94,7 @@ #define MICROPY_CPYTHON_COMPAT (1) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) +#define MICROPY_FLOAT_HIGH_QUALITY_HASH (1) #define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_NORMAL) #define MICROPY_WARNINGS (1) #define MICROPY_PY_STR_BYTES_CMP_WARN (1) @@ -109,9 +111,9 @@ #define MICROPY_FATFS_MAX_SS (4096) #define MICROPY_FATFS_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ #define MICROPY_VFS_FAT (1) -#define MICROPY_ESP8266_APA102 (1) #define MICROPY_ESP8266_NEOPIXEL (1) +extern void ets_event_poll(void); #define MICROPY_EVENT_POLL_HOOK {ets_event_poll();} #define MICROPY_VM_HOOK_COUNT (10) #define MICROPY_VM_HOOK_INIT static uint vm_hook_divisor = MICROPY_VM_HOOK_COUNT; @@ -158,37 +160,51 @@ void *esp_native_code_commit(void*, size_t); // extra built in modules to add to the list of known ones extern const struct _mp_obj_module_t esp_module; extern const struct _mp_obj_module_t network_module; -extern const struct _mp_obj_module_t utime_module; -extern const struct _mp_obj_module_t uos_module; +extern const struct _mp_obj_module_t os_module; +extern const struct _mp_obj_module_t random_module; +extern const struct _mp_obj_module_t struct_module; extern const struct _mp_obj_module_t mp_module_lwip; extern const struct _mp_obj_module_t mp_module_machine; extern const struct _mp_obj_module_t mp_module_onewire; +extern const struct _mp_obj_module_t microcontroller_module; +extern const struct _mp_obj_module_t board_module; +extern const struct _mp_obj_module_t math_module; +extern const struct _mp_obj_module_t analogio_module; +extern const struct _mp_obj_module_t digitalio_module; +extern const struct _mp_obj_module_t pulseio_module; +extern const struct _mp_obj_module_t busio_module; +extern const struct _mp_obj_module_t bitbangio_module; +extern const struct _mp_obj_module_t time_module; +extern const struct _mp_obj_module_t multiterminal_module; +extern const struct _mp_obj_module_t neopixel_write_module; #define MICROPY_PORT_BUILTIN_MODULES \ - { MP_ROM_QSTR(MP_QSTR_esp), MP_ROM_PTR(&esp_module) }, \ - { MP_ROM_QSTR(MP_QSTR_usocket), MP_ROM_PTR(&mp_module_lwip) }, \ - { MP_ROM_QSTR(MP_QSTR_network), MP_ROM_PTR(&network_module) }, \ - { MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&utime_module) }, \ - { MP_ROM_QSTR(MP_QSTR_uos), MP_ROM_PTR(&uos_module) }, \ - { MP_ROM_QSTR(MP_QSTR_machine), MP_ROM_PTR(&mp_module_machine) }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_esp), (mp_obj_t)&esp_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&mp_module_lwip }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_usocket), (mp_obj_t)&mp_module_lwip }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_network), (mp_obj_t)&network_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_os), (mp_obj_t)&os_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_machine), (mp_obj_t)&mp_module_machine }, \ { MP_ROM_QSTR(MP_QSTR__onewire), MP_ROM_PTR(&mp_module_onewire) }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)µcontroller_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&board_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_digitalio), (mp_obj_t)&digitalio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_busio), (mp_obj_t)&busio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_random), (mp_obj_t)&random_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&struct_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_multiterminal), (mp_obj_t)&multiterminal_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write),(mp_obj_t)&neopixel_write_module }, \ #define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \ - { MP_ROM_QSTR(MP_QSTR_binascii), MP_ROM_PTR(&mp_module_ubinascii) }, \ - { MP_ROM_QSTR(MP_QSTR_collections), MP_ROM_PTR(&mp_module_collections) }, \ - { MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mp_module_uerrno) }, \ - { MP_ROM_QSTR(MP_QSTR_hashlib), MP_ROM_PTR(&mp_module_uhashlib) }, \ - { MP_ROM_QSTR(MP_QSTR_io), MP_ROM_PTR(&mp_module_io) }, \ { MP_ROM_QSTR(MP_QSTR_json), MP_ROM_PTR(&mp_module_ujson) }, \ - { MP_ROM_QSTR(MP_QSTR_os), MP_ROM_PTR(&uos_module) }, \ - { MP_ROM_QSTR(MP_QSTR_random), MP_ROM_PTR(&mp_module_urandom) }, \ - { MP_ROM_QSTR(MP_QSTR_re), MP_ROM_PTR(&mp_module_ure) }, \ + { MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mp_module_uerrno) }, \ { MP_ROM_QSTR(MP_QSTR_select), MP_ROM_PTR(&mp_module_uselect) }, \ { MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&mp_module_lwip) }, \ - { MP_ROM_QSTR(MP_QSTR_ssl), MP_ROM_PTR(&mp_module_ussl) }, \ - { MP_ROM_QSTR(MP_QSTR_struct), MP_ROM_PTR(&mp_module_ustruct) }, \ - { MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&utime_module) }, \ - { MP_ROM_QSTR(MP_QSTR_zlib), MP_ROM_PTR(&mp_module_uzlib) }, \ #define MP_STATE_PORT MP_STATE_VM diff --git a/ports/esp8266/posix_helpers.c b/ports/esp8266/posix_helpers.c index b72c4ff9d66..adb0145e7da 100644 --- a/ports/esp8266/posix_helpers.c +++ b/ports/esp8266/posix_helpers.c @@ -33,7 +33,7 @@ // Functions for external libs like axTLS, BerkeleyDB, etc. void *malloc(size_t size) { - void *p = gc_alloc(size, false); + void *p = gc_alloc(size, false, false); if (p == NULL) { // POSIX requires ENOMEM to be set in case of error errno = ENOMEM; diff --git a/ports/esp8266/uart.c b/ports/esp8266/uart.c index 52707f98127..4a840533730 100644 --- a/ports/esp8266/uart.c +++ b/ports/esp8266/uart.c @@ -34,11 +34,6 @@ static int uart_os = UART_OS; static os_event_t uart_evt_queue[16]; #endif -// A small, static ring buffer for incoming chars -// This will only be populated if the UART is not attached to dupterm -static byte uart_ringbuf_array[16]; -static ringbuf_t uart_ringbuf = {uart_ringbuf_array, sizeof(uart_ringbuf_array), 0, 0}; - static void uart0_rx_intr_handler(void *para); void soft_reset(void); @@ -175,26 +170,18 @@ static void uart0_rx_intr_handler(void *para) { while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) { uint8 RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xff; - // For efficiency, when connected to dupterm we put incoming chars - // directly on stdin_ringbuf, rather than going via uart_ringbuf - if (uart_attached_to_dupterm) { - if (RcvChar == mp_interrupt_char) { - mp_keyboard_interrupt(); - } else { - ringbuf_put(&stdin_ringbuf, RcvChar); - } + if (RcvChar == mp_interrupt_char) { + mp_keyboard_interrupt(); } else { - ringbuf_put(&uart_ringbuf, RcvChar); + ringbuf_put(&stdin_ringbuf, RcvChar); } } + mp_hal_signal_input(); + // Clear pending FIFO interrupts WRITE_PERI_REG(UART_INT_CLR(UART_REPL), UART_RXFIFO_TOUT_INT_CLR | UART_RXFIFO_FULL_INT_ST); ETS_UART_INTR_ENABLE(); - - if (uart_attached_to_dupterm) { - mp_hal_signal_input(); - } } } @@ -203,7 +190,7 @@ static void uart0_rx_intr_handler(void *para) { bool uart_rx_wait(uint32_t timeout_us) { uint32_t start = system_get_time(); for (;;) { - if (uart_ringbuf.iget != uart_ringbuf.iput) { + if (stdin_ringbuf.iget != stdin_ringbuf.iput) { return true; // have at least 1 char ready for reading } if (system_get_time() - start >= timeout_us) { @@ -214,7 +201,7 @@ bool uart_rx_wait(uint32_t timeout_us) { } int uart_rx_any(uint8 uart) { - if (uart_ringbuf.iget != uart_ringbuf.iput) { + if (stdin_ringbuf.iget != stdin_ringbuf.iput) { return true; // have at least 1 char ready for reading } return false; @@ -230,7 +217,7 @@ int uart_tx_any_room(uint8 uart) { // Returns char from the input buffer, else -1 if buffer is empty. int uart_rx_char(void) { - return ringbuf_get(&uart_ringbuf); + return ringbuf_get(&stdin_ringbuf); } int uart_rx_one_char(uint8 uart_no) { @@ -288,7 +275,7 @@ void uart_task_handler(os_event_t *evt) { } int c, ret = 0; - while ((c = ringbuf_get(&input_buf)) >= 0) { + while ((c = ringbuf_get(&stdin_ringbuf)) >= 0) { if (c == mp_interrupt_char) { mp_keyboard_interrupt(); } diff --git a/ports/nrf/.gitignore b/ports/nrf/.gitignore new file mode 100644 index 00000000000..cda23c7a901 --- /dev/null +++ b/ports/nrf/.gitignore @@ -0,0 +1,9 @@ +# Old Nordic soft devices that don't allow redistribution +######################################################### +drivers/bluetooth/s132_nrf52_2.0.1/ + +!drivers/bluetooth/*/*.hex + +# Build files +##################### +build-*/ diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile new file mode 100755 index 00000000000..6ec16008811 --- /dev/null +++ b/ports/nrf/Makefile @@ -0,0 +1,318 @@ +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# Copyright (c) 2019 Dan Halbert for Adafruit Industries +# +# 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. + +# Select the board to build for. +ifeq ($(BOARD),) + $(info You must provide a BOARD parameter with 'BOARD=') + $(info Possible values are:) + $(info $(sort $(subst /.,,$(subst boards/,,$(wildcard boards/*/.))))) + $(error BOARD not defined) +else + ifeq ($(wildcard boards/$(BOARD)/.),) + $(error Invalid BOARD specified) + endif +endif + +CLI_SD := $(SD) +SD_LOWER = $(shell echo $(SD) | tr '[:upper:]' '[:lower:]') + +# Build directory with SD if it's different from the default. +BUILD ?= $(if $(CLI_SD),build-$(BOARD)-$(SD_LOWER),build-$(BOARD)) + +include ../../py/mkenv.mk +# Board-specific +include boards/$(BOARD)/mpconfigboard.mk +# Port-specific +include mpconfigport.mk +# CircuitPython-specific +include $(TOP)/py/circuitpy_mpconfig.mk + +# qstr definitions (must come before including py.mk) +QSTR_DEFS = qstrdefsport.h + +# include py core make definitions +include $(TOP)/py/py.mk + +include $(TOP)/supervisor/supervisor.mk + +# Include make rules and variables common across CircuitPython builds. +include $(TOP)/py/circuitpy_defns.mk + +ifneq ($(SD), ) + include bluetooth/bluetooth_common.mk +endif + +FROZEN_MPY_DIR = freeze + +CROSS_COMPILE = arm-none-eabi- + +FATFS_DIR = lib/oofatfs + +INC += -I. +INC += -I../.. +INC += -I$(BUILD) +INC += -I$(BUILD)/genhdr +INC += -I./../../lib/cmsis/inc +INC += -I./boards/$(BOARD) +INC += -I./modules/ubluepy +INC += -I./modules/ble +INC += -I./nrfx +INC += -I./nrfx/hal +INC += -I./nrfx/mdk +INC += -I./nrfx/drivers/include +INC += -I./nrfx/drivers/src +INC += -I./bluetooth +INC += -I./peripherals +INC += -I../../lib/mp-readline +INC += -I../../lib/tinyusb/src +INC += -I../../supervisor/shared/usb + +#Debugging/Optimization +ifeq ($(DEBUG), 1) + CFLAGS += -ggdb + # You may want to enable these flags to make setting breakpoints easier. + CFLAGS += -fno-inline -fno-ipa-sra +else + CFLAGS += -Os -DNDEBUG + CFLAGS += -flto -flto-partition=none +endif + + +CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) + +# Undo some warnings. +# nrfx uses undefined preprocessor variables quite casually, so we can't do warning checks for these. +CFLAGS += -Wno-undef +# nrfx does casts that increase alignment requirements. +CFLAGS += -Wno-cast-align + +NRF_DEFINES += -DCONFIG_GPIO_AS_PINRESET +CFLAGS += $(NRF_DEFINES) + +CFLAGS += \ + -mthumb \ + -mabi=aapcs-linux \ + -mfloat-abi=hard \ + -mcpu=cortex-m4 \ + -mfpu=fpv4-sp-d16 + +# TODO: check this +CFLAGS += -D__START=main + +LDFLAGS = $(CFLAGS) -nostartfiles -fshort-enums -Wl,-nostdlib -Wl,-T,$(LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections -specs=nano.specs +LIBS := -lgcc -lc + +LDFLAGS += -mthumb -mcpu=cortex-m4 + +# Use toolchain libm if we're not using our own. +ifndef INTERNAL_LIBM +LIBS += -lm +endif + +# TinyUSB defines +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF5X -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_CDC_TX_BUFSIZE=1024 -DCFG_TUD_MSC_BUFSIZE=4096 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_MIDI_TX_BUFSIZE=128 + +SRC_NRFX = $(addprefix nrfx/,\ + drivers/src/nrfx_power.c \ + drivers/src/nrfx_spim.c \ + drivers/src/nrfx_timer.c \ + drivers/src/nrfx_twim.c \ + drivers/src/nrfx_uarte.c \ + drivers/src/nrfx_gpiote.c \ + drivers/src/nrfx_rtc.c \ + ) + +ifdef EXTERNAL_FLASH_DEVICES + ifeq ($(QSPI_FLASH_FILESYSTEM),1) + SRC_NRFX += nrfx/drivers/src/nrfx_qspi.c + endif +endif + + +SRC_C += \ + background.c \ + fatfs_port.c \ + mphalport.c \ + tick.c \ + boards/$(BOARD)/board.c \ + boards/$(BOARD)/pins.c \ + device/$(MCU_VARIANT)/startup_$(MCU_SUB_VARIANT).c \ + bluetooth/ble_drv.c \ + lib/libc/string0.c \ + lib/mp-readline/readline.c \ + lib/oofatfs/ff.c \ + lib/oofatfs/option/ccsbcs.c \ + lib/timeutils/timeutils.c \ + lib/utils/buffer_helper.c \ + lib/utils/context_manager_helpers.c \ + lib/utils/interrupt_char.c \ + lib/utils/pyexec.c \ + lib/utils/stdout_helpers.c \ + lib/utils/sys_stdio_mphal.c \ + nrfx/hal/nrf_nvmc.c \ + nrfx/mdk/system_$(MCU_SUB_VARIANT).c \ + peripherals/nrf/cache.c \ + peripherals/nrf/clocks.c \ + peripherals/nrf/$(MCU_CHIP)/pins.c \ + peripherals/nrf/$(MCU_CHIP)/power.c \ + peripherals/nrf/nvm.c \ + peripherals/nrf/timers.c \ + sd_mutex.c \ + supervisor/shared/memory.c + +# USB source files for nrf52840 +ifeq ($(MCU_SUB_VARIANT),nrf52840) +SRC_C += \ + lib/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c +endif + +SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ + $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ + $(addprefix common-hal/, $(SRC_COMMON_HAL)) + +SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ + $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ + $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) + +SRC_S = supervisor/cpu.s + +FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py') +FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy)) + +OBJ += $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_NRFX:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_EXPANDED:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o)) +ifeq ($(INTERNAL_LIBM),1) +OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) +endif +OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) + +$(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os +$(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os + +# List of sources for qstr extraction +SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_MOD) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) +# Sources that only hold QSTRs after pre-processing. +SRC_QSTR_PREPROCESSOR += + + +all: $(BUILD)/firmware.bin $(BUILD)/firmware.uf2 + +$(BUILD)/firmware.elf: $(OBJ) + $(STEPECHO) "LINK $@" + $(Q)$(CC) -o $@ $(LDFLAGS) $^ -Wl,--start-group $(LIBS) -Wl,--end-group + $(Q)$(SIZE) $@ | $(PYTHON3) $(TOP)/tools/build_memory_info.py $(LD_FILE) + +$(BUILD)/firmware.bin: $(BUILD)/firmware.elf + $(STEPECHO) "Create $@" + $(Q)$(OBJCOPY) -O binary $^ $@ +# $(Q)$(OBJCOPY) -O binary -j .vectors -j .text -j .data $^ $@ + +$(BUILD)/firmware.hex: $(BUILD)/firmware.elf + $(STEPECHO) "Create $@" + $(Q)$(OBJCOPY) -O ihex $^ $@ +# $(Q)$(OBJCOPY) -O ihex -j .vectors -j .text -j .data $^ $@ + +$(BUILD)/firmware.uf2: $(BUILD)/firmware.hex + $(ECHO) "Create $@" + $(PYTHON3) $(TOP)/tools/uf2/utils/uf2conv.py -f 0xADA52840 -c -o "$(BUILD)/firmware.uf2" $^ + + + +##################### +# Flash with debugger +##################### +FLASHER ?= + +ifeq ($(FLASHER),) + +# Also update to bootloader settting to validate application and skip checksum ( app valid = 0x0001, crc = 0x0000 ) +flash: $(BUILD)/firmware.hex + nrfjprog --program $< --sectorerase -f $(MCU_VARIANT) + nrfjprog --erasepage $(BOOT_SETTING_ADDR) -f $(MCU_VARIANT) + nrfjprog --memwr $(BOOT_SETTING_ADDR) --val 0x00000001 -f $(MCU_VARIANT) + nrfjprog --reset -f $(MCU_VARIANT) + +sd: $(BUILD)/firmware.hex + nrfjprog --eraseall -f $(MCU_VARIANT) + nrfjprog --program $(SOFTDEV_HEX) -f $(MCU_VARIANT) + nrfjprog --program $< --sectorerase -f $(MCU_VARIANT) + nrfjprog --reset -f $(MCU_VARIANT) + +else ifeq ($(FLASHER), pyocd) + +flash: $(BUILD)/firmware.hex + pyocd-flashtool -t $(MCU_VARIANT) $< --sector_erase + #pyocd-tool -t $(MCU_VARIANT) erase $(BOOT_SETTING_ADDR) + pyocd-tool -t $(MCU_VARIANT) write32 $(BOOT_SETTING_ADDR) 0x00000001 + pyocd-tool -t $(MCU_VARIANT) reset + +sd: $(BUILD)/firmware.hex + pyocd-flashtool -t $(MCU_VARIANT) --chip_erase + pyocd-flashtool -t $(MCU_VARIANT) $(SOFTDEV_HEX) + pyocd-flashtool -t $(MCU_VARIANT) $< --sector_erase + pyocd-tool -t $(MCU_VARIANT) reset $(BOOT_SETTING_ADDR) + +endif + +##################### +# Flash with DFU +##################### +.phony: dfu-gen dfu-flash + +NRFUTIL = adafruit-nrfutil + +ifeq ($(MCU_SUB_VARIANT),nrf52840) + DFU_TOUCH = --touch 1200 +else + DFU_TOUCH = +endif + +check_defined = \ + $(strip $(foreach 1,$1, \ + $(call __check_defined,$1,$(strip $(value 2))))) +__check_defined = \ + $(if $(value $1),, \ + $(error Undefined make flag: $1$(if $2, ($2)))) + +## Flash with DFU serial +dfu-flash: $(BUILD)/dfu-package.zip + @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyUSB0) + $(NRFUTIL) --verbose dfu serial --package $^ -p $(SERIAL) -b 115200 --singlebank $(DFU_TOUCH) + +## Create DFU package file +dfu-gen: $(BUILD)/dfu-package.zip + +$(BUILD)/dfu-package.zip: $(BUILD)/firmware.hex + $(NRFUTIL) dfu genpkg --sd-req 0xFFFE --dev-type 0x0052 --application $^ $(BUILD)/dfu-package.zip + + +include $(TOP)/py/mkrules.mk + +# Print out the value of a make variable. +# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile +print-%: + @echo $* = $($*) diff --git a/ports/nrf/README.md b/ports/nrf/README.md new file mode 100644 index 00000000000..5f6d0372044 --- /dev/null +++ b/ports/nrf/README.md @@ -0,0 +1,128 @@ +# CircuitPython Port To The Nordic Semiconductor nRF52 Series + +This is a port of CircuitPython to the Nordic Semiconductor nRF52 series of chips. + +## Supported Features + +* UART +* SPI +* LEDs +* Pins +* ADC +* I2C +* PWM +* Temperature +* RTC (Real Time Counter. Low-Power counter) +* BLE support including: + * Peripheral role + * Scanner role + * _REPL over Bluetooth LE_ (optionally using WebBluetooth) + * ubluepy: Bluetooth LE module for CircuitPython + * 1 non-connectable advertiser while in connection + +## Tested Hardware + +* nRF52840 + * [PCA10056](http://www.nordicsemi.com/eng/Products/nRF52840-Preview-DK) + +## Board Specific Instructions + +For board-specific instructions on building and flashing CircuitPython, see +the following links: + +> **NOTE**: These board specific readmes may be more up to date than the + generic board-neutral documentation further down. + +* Adafruit Feather nRF52840: `boards/feather_nrf52840_express/README.md`: 1MB Flash, 256KB SRAM +* Nordic PCA10056 (uses nRF52840): `boards/pca10056/README.md` +* MakerDiary nRF52840 MDK: `boards/makerdiary_nrf52840_mdk/README.md` +* MakerDiary nRF52840 MDK USB Dongle: `boards/makerdiary_nrf52840_mdk_usb_dongle/README.md` + +For all other board targets, see the generic notes below. + +## Compile and Flash + +Prerequisite steps for building the nrf port: + + git clone .git circuitpython + cd circuitpython + git submodule update --init + make -C mpy-cross + +To build and flash issue the following command inside the ports/nrf/ folder: + + make BOARD=pca10056 + make BOARD=pca10056 flash + +## Compile and Flash with Bluetooth Stack + +First prepare the bluetooth folder by downloading Bluetooth LE stacks and headers: + + ./bluetooth/download_ble_stack.sh + +If the Bluetooth stacks has been downloaded, compile the target with the following command: + + make BOARD=pca10040 SD=s132 + +The **make sd** will trigger a flash of the bluetooth stack before that application is flashed. Note that **make sd** will perform a full erase of the chip, which could cause 3rd party bootloaders to also be wiped. + + make BOARD=pca10040 SD=s132 sd + +Note: further tuning of features to include in bluetooth or even setting up the device to use REPL over Bluetooth can be configured in the `bluetooth_conf.h`. + +## Target Boards and Make Flags + +Target Board (BOARD) | Bluetooth Stack (SD) | Bluetooth Support | Flash Util +-------------------------|-------------------------|------------------------|------------------------------- +pca10056 | s140 | Peripheral and Scanner | [Segger](#segger-targets) +feather_nrf52840_express | s140 | Peripheral and Scanner | UF2 bootloader +makerdiary_nrf52840_mdk | s140 | Peripheral and Scanner | pyocd or ARM mbed DAPLink +makerdiary_nrf52840_mdk_usb_dongle | s140 | Peripheral and Scanner | DFU bootloader & nrfutil +electronut_labs_papyr | s140 | Peripheral and Scanner | UF2 bootloader +electronut_labs_blip | s140 | Peripheral and Scanner | Black Magic Probe + +## Segger Targets + +Install the necessary tools to flash and debug using Segger: + +[JLink Download](https://www.segger.com/downloads/jlink#) + +[nrfjprog linux-32bit Download](https://www.nordicsemi.com/eng/nordic/download_resource/52615/16/95882111/97746) + +[nrfjprog linux-64bit Download](https://www.nordicsemi.com/eng/nordic/download_resource/51386/21/77886419/94917) + +[nrfjprog osx Download](https://www.nordicsemi.com/eng/nordic/download_resource/53402/12/97293750/99977) + +[nrfjprog win32 Download](https://www.nordicsemi.com/eng/nordic/download_resource/33444/40/22191727/53210) + +note: On Linux it might be required to link SEGGER's `libjlinkarm.so` inside nrfjprog's folder. + +## DFU Targets + +run follow command to install [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil) from PyPi + + $ pip3 install --user adafruit-nrfutil + +**make flash** and **make sd** will not work with DFU targets. Hence, **dfu-gen** and **dfu-flash** must be used instead. +* dfu-gen: Generates a Firmware zip to be used by the DFU flash application. +* dfu-flash: Triggers the DFU flash application to upload the firmware from the generated Firmware zip file. + +Example on how to generate and flash feather_nrf52840 target: + + make BOARD=feather_nrf52840 SD=s140 + make BOARD=feather_nrf52840 SD=s140 dfu-gen dfu-flash + +## Bluetooth LE REPL + +The port also implements a BLE REPL driver. This feature is disabled by default, as it will deactivate the UART REPL when activated. As some of the nRF devices only have one UART, using the BLE REPL free's the UART instance such that it can be used as a general UART peripheral not bound to REPL. + +The configuration can be enabled by editing the `bluetooth_conf.h` and set `MICROPY_PY_BLE_NUS` to 1. + +When enabled you have different options to test it: +* [NUS Console for Linux](https://github.com/tralamazza/nus_console) (recommended) +* [WebBluetooth REPL](https://glennrub.github.io/webbluetooth/micropython/repl/) (experimental) + +Other: +* nRF UART application for IPhone/Android + +WebBluetooth mode can also be configured by editing `bluetooth_conf.h` and set `BLUETOOTH_WEBBLUETOOTH_REPL` to 1. This will alternate advertisement between Eddystone URL and regular connectable advertisement. The Eddystone URL will point the phone or PC to download [WebBluetooth REPL](https://glennrub.github.io/webbluetooth/micropython/repl/) (experimental), which subsequently can be used to connect to the Bluetooth REPL from the PC or Phone browser. diff --git a/ports/nrf/background.c b/ports/nrf/background.c new file mode 100644 index 00000000000..94411cbce54 --- /dev/null +++ b/ports/nrf/background.c @@ -0,0 +1,64 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "py/runtime.h" +#include "supervisor/filesystem.h" +#include "supervisor/usb.h" +#include "supervisor/shared/stack.h" + +#if CIRCUITPY_DISPLAYIO +#include "shared-module/displayio/__init__.h" +#endif + +#if CIRCUITPY_AUDIOPWMIO +#include "common-hal/audiopwmio/PWMAudioOut.h" +#endif + +static bool running_background_tasks = false; + +void background_tasks_reset(void) { + running_background_tasks = false; +} + +void run_background_tasks(void) { + // Don't call ourselves recursively. + if (running_background_tasks) { + return; + } + running_background_tasks = true; + filesystem_background(); + usb_background(); +#if CIRCUITPY_AUDIOPWMIO + audiopwmout_background(); +#endif + + #if CIRCUITPY_DISPLAYIO + displayio_background(); + #endif + running_background_tasks = false; + + assert_heap_ok(); +} diff --git a/ports/nrf/background.h b/ports/nrf/background.h new file mode 100644 index 00000000000..d53681c0fde --- /dev/null +++ b/ports/nrf/background.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_BACKGROUND_H +#define MICROPY_INCLUDED_NRF_BACKGROUND_H + +#include + +void background_tasks_reset(void); +void run_background_tasks(void); + +#endif // MICROPY_INCLUDED_NRF_BACKGROUND_H diff --git a/ports/nrf/bluetooth/ble_drv.c b/ports/nrf/bluetooth/ble_drv.c new file mode 100644 index 00000000000..6b17e7af292 --- /dev/null +++ b/ports/nrf/bluetooth/ble_drv.c @@ -0,0 +1,136 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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 +#include + +#include "ble.h" +#include "ble_drv.h" +#include "nrf_nvic.h" +#include "nrf_sdm.h" +#include "nrf_soc.h" +#include "nrfx_power.h" +#include "py/misc.h" +#include "py/mpstate.h" + +nrf_nvic_state_t nrf_nvic_state = { 0 }; + +// Flag indicating progress of internal flash operation. +sd_flash_operation_status_t sd_flash_operation_status; + +__attribute__((aligned(4))) +static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (BLE_GATT_ATT_MTU_DEFAULT)]; + +void ble_drv_reset() { + // Linked list items will be gc'd. + MP_STATE_VM(ble_drv_evt_handler_entries) = NULL; + sd_flash_operation_status = SD_FLASH_OPERATION_DONE; +} + +void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) { + ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries); + while (it != NULL) { + // If event handler and its corresponding param are already on the list, don't add again. + if ((it->func == func) && (it->param == param)) { + return; + } + it = it->next; + } + + // Add a new handler to the front of the list + ble_drv_evt_handler_entry_t *handler = m_new_ll(ble_drv_evt_handler_entry_t, 1); + handler->next = MP_STATE_VM(ble_drv_evt_handler_entries); + handler->param = param; + handler->func = func; + + MP_STATE_VM(ble_drv_evt_handler_entries) = handler; +} + +void ble_drv_remove_event_handler(ble_drv_evt_handler_t func, void *param) { + ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries); + ble_drv_evt_handler_entry_t **prev = &MP_STATE_VM(ble_drv_evt_handler_entries); + while (it != NULL) { + if ((it->func == func) && (it->param == param)) { + // Splice out the matching handler. + *prev = it->next; + return; + } + prev = &(it->next); + it = it->next; + } +} + +extern void tusb_hal_nrf_power_event (uint32_t event); + +void SD_EVT_IRQHandler(void) { + uint32_t evt_id; + while (sd_evt_get(&evt_id) != NRF_ERROR_NOT_FOUND) { + switch (evt_id) { + // usb power event + case NRF_EVT_POWER_USB_DETECTED: + case NRF_EVT_POWER_USB_POWER_READY: + case NRF_EVT_POWER_USB_REMOVED: { + int32_t usbevt = (evt_id == NRF_EVT_POWER_USB_DETECTED ) ? NRFX_POWER_USB_EVT_DETECTED: + (evt_id == NRF_EVT_POWER_USB_POWER_READY) ? NRFX_POWER_USB_EVT_READY : + (evt_id == NRF_EVT_POWER_USB_REMOVED ) ? NRFX_POWER_USB_EVT_REMOVED : -1; + + tusb_hal_nrf_power_event(usbevt); + } + break; + + // Set flag indicating that a flash operation has finished. + case NRF_EVT_FLASH_OPERATION_SUCCESS: + sd_flash_operation_status = SD_FLASH_OPERATION_DONE; + break; + case NRF_EVT_FLASH_OPERATION_ERROR: + sd_flash_operation_status = SD_FLASH_OPERATION_ERROR; + break; + + default: + break; + } + } + + while (1) { + uint16_t evt_len = sizeof(m_ble_evt_buf); + const uint32_t err_code = sd_ble_evt_get(m_ble_evt_buf, &evt_len); + if (err_code != NRF_SUCCESS) { + if (err_code == NRF_ERROR_DATA_SIZE) { + printf("NRF_ERROR_DATA_SIZE\n"); + } + + break; + } + + ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries); + while (it != NULL) { + it->func((ble_evt_t *)m_ble_evt_buf, it->param); + it = it->next; + } + } +} diff --git a/ports/nrf/bluetooth/ble_drv.h b/ports/nrf/bluetooth/ble_drv.h new file mode 100644 index 00000000000..a066f588fa8 --- /dev/null +++ b/ports/nrf/bluetooth/ble_drv.h @@ -0,0 +1,72 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H +#define MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H + +#include "ble.h" + +#define MAX_TX_IN_PROGRESS 10 + +#ifndef BLE_GATT_ATT_MTU_DEFAULT + #define BLE_GATT_ATT_MTU_DEFAULT GATT_MTU_SIZE_DEFAULT +#endif + +#define BLE_CONN_CFG_TAG_CUSTOM 1 + +#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION)) +#define SEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000000) / (RESOLUTION)) +// 0.625 msecs (625 usecs) +#define ADV_INTERVAL_UNIT_FLOAT_SECS (0.000625) +// Microseconds is the base unit. The macros above know that. +#define UNIT_0_625_MS (625) +#define UNIT_1_25_MS (1250) +#define UNIT_10_MS (10000) + +typedef void (*ble_drv_evt_handler_t)(ble_evt_t*, void*); + +typedef enum { + SD_FLASH_OPERATION_DONE, + SD_FLASH_OPERATION_IN_PROGRESS, + SD_FLASH_OPERATION_ERROR, +} sd_flash_operation_status_t; + +// Flag indicating progress of internal flash operation. +extern sd_flash_operation_status_t sd_flash_operation_status; + +typedef struct ble_drv_evt_handler_entry { + struct ble_drv_evt_handler_entry *next; + void *param; + ble_drv_evt_handler_t func; +} ble_drv_evt_handler_entry_t; + +void ble_drv_reset(void); +void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param); +void ble_drv_remove_event_handler(ble_drv_evt_handler_t func, void *param); + +#endif // MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H diff --git a/ports/nrf/bluetooth/ble_uart.c b/ports/nrf/bluetooth/ble_uart.c new file mode 100644 index 00000000000..787a2a11749 --- /dev/null +++ b/ports/nrf/bluetooth/ble_uart.c @@ -0,0 +1,193 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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 + +#include "ble.h" +#include "ble_uart.h" +#include "ringbuffer.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "lib/utils/interrupt_char.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Device.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/UUID.h" + +#if (MICROPY_PY_BLE_NUS == 1) + +static const char default_name[] = "CP-REPL"; // max 8 chars or uuid won't fit in adv data +static const char NUS_UUID[] = "6e400001-b5a3-f393-e0a9-e50e24dcca9e"; + +#define NUS_RX_UUID 0x0002 +#define NUS_TX_UUID 0x0003 +#define BUFFER_SIZE 128 + +ringBuffer_typedef(uint8_t, ringbuffer_t); + +static bleio_device_obj_t m_device; +static bleio_service_obj_t *m_nus; +static bleio_characteristic_obj_t *m_tx_chara; +static bleio_characteristic_obj_t *m_rx_chara; + +static volatile bool m_cccd_enabled; + +static uint8_t m_rx_ring_buffer_data[BUFFER_SIZE]; +static ringbuffer_t m_rx_ring_buffer = { + .size = sizeof(m_rx_ring_buffer_data) + 1, + .elems = m_rx_ring_buffer_data, +}; + +STATIC void on_ble_evt(ble_evt_t *ble_evt, void *param) { + switch (ble_evt->header.evt_id) { + case BLE_GAP_EVT_DISCONNECTED: + { + mp_obj_t device_obj = MP_OBJ_FROM_PTR(&m_device); + mp_call_function_0(mp_load_attr(device_obj, qstr_from_str("start_advertising"))); + break; + } + + case BLE_GATTS_EVT_WRITE: + { + ble_gatts_evt_write_t *write = &ble_evt->evt.gatts_evt.params.write; + + if (write->handle == m_tx_chara->cccd_handle) { + m_cccd_enabled = true; + } else if (write->handle == m_rx_chara->handle) { + for (size_t i = 0; i < write->len; ++i) { +#if MICROPY_KBD_EXCEPTION + if (write->data[i] == mp_interrupt_char) { + mp_keyboard_interrupt(); + } else +#endif + { + bufferWrite(&m_rx_ring_buffer, write->data[i]); + } + } + } + } + } +} + +void ble_uart_init(void) { + mp_obj_t device_obj = MP_OBJ_FROM_PTR(&m_device); + m_device.base.type = &bleio_device_type; + m_device.service_list = mp_obj_new_list(0, NULL); + m_device.notif_handler = mp_const_none; + m_device.conn_handler = mp_const_none; + m_device.conn_handle = 0xFFFF; + m_device.is_peripheral = true; + m_device.name = mp_obj_new_str(default_name, strlen(default_name), false); + common_hal_bleio_adapter_get_address(&m_device.address); + + mp_obj_t nus_uuid_str = mp_obj_new_str(NUS_UUID, strlen(NUS_UUID), false); + mp_obj_t nus_uuid_obj = bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &nus_uuid_str); + mp_obj_t nus_obj = bleio_service_type.make_new(&bleio_service_type, 1, 0, &nus_uuid_obj); + m_nus = MP_OBJ_TO_PTR(nus_obj); + mp_call_function_1(mp_load_attr(device_obj, qstr_from_str("add_service")), nus_obj); + + mp_obj_t tx_uuid_int = mp_obj_new_int(NUS_TX_UUID); + mp_obj_t tx_uuid_obj = bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &tx_uuid_int); + mp_obj_t tx_obj = bleio_characteristic_type.make_new(&bleio_characteristic_type, 1, 0, &tx_uuid_obj); + m_tx_chara = MP_OBJ_TO_PTR(tx_obj); + m_tx_chara->uuid->type = UUID_TYPE_128BIT; + m_tx_chara->uuid->uuid_vs_idx = m_nus->uuid->uuid_vs_idx; + m_tx_chara->props.notify = true; + mp_call_function_1(mp_load_attr(nus_obj, qstr_from_str("add_characteristic")), tx_obj); + + mp_obj_t rx_uuid_int = mp_obj_new_int(NUS_RX_UUID); + mp_obj_t rx_uuid_obj = bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &rx_uuid_int); + mp_obj_t rx_obj = bleio_characteristic_type.make_new(&bleio_characteristic_type, 1, 0, &rx_uuid_obj); + m_rx_chara = MP_OBJ_TO_PTR(rx_obj); + m_rx_chara->uuid->type = UUID_TYPE_128BIT; + m_rx_chara->uuid->uuid_vs_idx = m_nus->uuid->uuid_vs_idx; + m_rx_chara->props.write = true; + m_rx_chara->props.write_wo_resp = true; + mp_call_function_1(mp_load_attr(nus_obj, qstr_from_str("add_characteristic")), rx_obj); + + mp_call_function_0(mp_load_attr(device_obj, qstr_from_str("start_advertising"))); + + ble_drv_add_event_handler(on_ble_evt, &m_device); + + m_cccd_enabled = false; + + while (!m_cccd_enabled) { + RUN_BACKGROUND_TASKS; + } +} + +bool ble_uart_connected(void) { + return (m_device.conn_handle != BLE_CONN_HANDLE_INVALID); +} + +char ble_uart_rx_chr(void) { + while (isBufferEmpty(&m_rx_ring_buffer)) { + RUN_BACKGROUND_TASKS; + } + + uint8_t byte; + bufferRead(&m_rx_ring_buffer, byte); + return (int)byte; +} + +bool ble_uart_stdin_any(void) { + return !isBufferEmpty(&m_rx_ring_buffer); +} + +void ble_uart_stdout_tx_str(const char *text) { + mp_hal_stdout_tx_strn(text, strlen(text)); +} + +int mp_hal_stdin_rx_chr(void) { + return ble_uart_rx_chr(); +} + +void mp_hal_stdout_tx_strn(const char *str, size_t len) { + size_t send_len; + + while (len > 0) { + if (len >= BLE_GATT_ATT_MTU_DEFAULT - 3) { + send_len = (BLE_GATT_ATT_MTU_DEFAULT - 3); + } else { + send_len = len; + } + + mp_buffer_info_t bufinfo = { + .buf = (uint8_t*)str, + .len = send_len, + }; + + common_hal_bleio_characteristic_write_value(m_tx_chara, &bufinfo); + + len -= send_len; + str += send_len; + } +} + +#endif // MICROPY_PY_BLE_NUS diff --git a/ports/nrf/bluetooth/ble_uart.h b/ports/nrf/bluetooth/ble_uart.h new file mode 100644 index 00000000000..d86e6293ae5 --- /dev/null +++ b/ports/nrf/bluetooth/ble_uart.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_UART_H +#define MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_UART_H + +#include + +#include "ble_drv.h" + +void ble_uart_init(void); +bool ble_uart_connected(void); +char ble_uart_rx_chr(void); +bool ble_uart_stdin_any(void); +void ble_uart_stdout_tx_str(const char *text); + +#endif // MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_UART_H diff --git a/ports/nrf/bluetooth/bluetooth_common.mk b/ports/nrf/bluetooth/bluetooth_common.mk new file mode 100644 index 00000000000..67b779c9039 --- /dev/null +++ b/ports/nrf/bluetooth/bluetooth_common.mk @@ -0,0 +1,36 @@ +ifeq ($(SD), s140) + CFLAGS += -DBLUETOOTH_SD=140 + CFLAGS += -DBLE_API_VERSION=4 +else +$(error Incorrect softdevice set flag) +endif + +CFLAGS += -DBLUETOOTH_SD_DEBUG=1 +CFLAGS += -DSOFTDEVICE_PRESENT + +INC += -Ibluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include +INC += -Ibluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include/$(MCU_VARIANT) + +SOFTDEV_HEX_NAME = $(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_softdevice.hex +SOFTDEV_HEX_PATH = bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION) +SOFTDEV_HEX = $(SOFTDEV_HEX_PATH)/$(SOFTDEV_HEX_NAME) + +define STACK_MISSING_ERROR + + +###### ERROR: Bluetooth LE Stack not found ############ +# # +# The build target requires a Bluetooth LE stack. # +# $(SOFTDEV_HEX) not found. # +# # +# Please run the download script: # +# # +# bluetooth/download_ble_stack.sh # +# # +####################################################### + +endef + +ifeq ($(shell test ! -e $(SOFTDEV_HEX) && echo -n no),no) + $(error $(STACK_MISSING_ERROR)) +endif diff --git a/ports/nrf/bluetooth/ringbuffer.h b/ports/nrf/bluetooth/ringbuffer.h new file mode 100644 index 00000000000..9a06e7ccc40 --- /dev/null +++ b/ports/nrf/bluetooth/ringbuffer.h @@ -0,0 +1,99 @@ +/* The MIT License (MIT) + * + * Copyright (c) 2013 Philip Thrasher + * + * 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. + * Philip Thrasher's Crazy Awesome Ring Buffer Macros! + * + * Below you will find some naughty macros for easy owning and manipulating + * generic ring buffers. Yes, they are slightly evil in readability, but they + * are really fast, and they work great. + * + * Example usage: + * + * #include + * + * // So we can use this in any method, this gives us a typedef + * // named 'intBuffer'. + * ringBuffer_typedef(int, intBuffer); + * + * int main() { + * // Declare vars. + * intBuffer myBuffer; + * + * bufferInit(myBuffer,1024,int); + * + * // We must have the pointer. All of the macros deal with the pointer. + * // (except for init.) + * intBuffer* myBuffer_ptr; + * myBuffer_ptr = &myBuffer; + * + * // Write two values. + * bufferWrite(myBuffer_ptr,37); + * bufferWrite(myBuffer_ptr,72); + * + * // Read a value into a local variable. + * int first; + * bufferRead(myBuffer_ptr,first); + * assert(first == 37); // true + * + * int second; + * bufferRead(myBuffer_ptr,second); + * assert(second == 72); // true + * + * return 0; + * } + * + */ + +#ifndef _ringbuffer_h +#define _ringbuffer_h + +#define ringBuffer_typedef(T, NAME) \ + typedef struct { \ + int size; \ + volatile int start; \ + volatile int end; \ + T* elems; \ + } NAME + +#define bufferInit(BUF, S, T) \ + BUF.size = S+1; \ + BUF.start = 0; \ + BUF.end = 0; \ + BUF.elems = (T*)calloc(BUF.size, sizeof(T)) + + +#define bufferDestroy(BUF) free((BUF)->elems) +#define nextStartIndex(BUF) (((BUF)->start + 1) % (BUF)->size) +#define nextEndIndex(BUF) (((BUF)->end + 1) % (BUF)->size) +#define isBufferEmpty(BUF) ((BUF)->end == (BUF)->start) +#define isBufferFull(BUF) (nextEndIndex(BUF) == (BUF)->start) + +#define bufferWrite(BUF, ELEM) \ + (BUF)->elems[(BUF)->end] = ELEM; \ + (BUF)->end = ((BUF)->end + 1) % (BUF)->size; \ + if (isBufferEmpty(BUF)) { \ + (BUF)->start = nextStartIndex(BUF); \ + } + +#define bufferRead(BUF, ELEM) \ + ELEM = (BUF)->elems[(BUF)->start]; \ + (BUF)->start = nextStartIndex(BUF); + +#endif diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/doc/ble_api.dox b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/doc/ble_api.dox new file mode 100644 index 00000000000..a444c5e4ecf --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/doc/ble_api.dox @@ -0,0 +1,3897 @@ +/** + * @addtogroup BLE_COMMON + * @{ + * @defgroup BLE_COMMON_MSC Message Sequence Charts + * @{ + * + * @defgroup BLE_COMMON_ENABLE BLE Stack Enable + * @{ + * @msc + * hscale = "1.5"; + * APP,SD; + * |||; + * APP=>SD [label = "sd_softdevice_enable(clock, assertion_handler);"]; + * APP<SD [label = "sd_ble_cfg_set(cfg_id, cfg, app_ram_base);"]; + * APP<SD [label = "sd_ble_cfg_set(cfg_id, cfg, app_ram_base);"]; + * APP<SD [label = "sd_ble_enable(&app_ram_base);"]; + * APP<SD [label = "sd_ble_enable(&app_ram_base);"]; + * APP<SD [label = "sd_ble_enable(&app_ram_base);"]; + * APP<SD [label = "sd_softdevice_enable(clock, assertion_handler);"]; + * APP<SD [label = "sd_ble_cfg_set(cfg_id, cfg, app_ram_base);"]; + * APP<SD [label = "sd_ble_cfg_set(cfg_id, cfg, app_ram_base);"]; + * APP<SD [label = "sd_ble_enable(&app_ram_base);"]; + * APP<SD [label = "sd_softdevice_enable(clock, assertion_handler);"]; + * APP<SD [label = "sd_ble_cfg_set(BLE_CONN_CFG_GAP, cfg = {conn_cfg_tag = 1, gap_conn_cfg.conn_count = 1, app_ram_base);"]; + * APP<SD [label = "sd_ble_cfg_set(BLE_CONN_CFG_GATT, cfg = {conn_cfg_tag = 1, gatt_conn_cfg, app_ram_base);"]; + * APP<SD [label = "sd_ble_cfg_set(BLE_CONN_CFG_GATTC, cfg = {conn_cfg_tag = 1, gattc_conn_cfg, app_ram_base);"]; + * APP<SD [label = "sd_ble_cfg_set(BLE_CONN_CFG_GATTS, cfg = {conn_cfg_tag = 1, gatts_conn_cfg, app_ram_base);"]; + * APP<SD [label = "sd_ble_enable(&app_ram_base);"]; + * APP<SD [label = "sd_ble_gap_connect(params, conn_cfg_tag = BLE_CONN_CFG_TAG_DEFAULT);"]; + * APP<SD [label = "sd_ble_gap_adv_set_configure(&adv_handle, adv_data, params)"]; + * APP<SD [label = "sd_ble_gap_adv_start(adv_handle, conn_cfg_tag = 1);"]; + * APP<SD [label = "sd_ble_gap_connect(params, conn_cfg_tag = 1);"]; + * APP<SD [label = "sd_softdevice_enable(clock, assertion_handler);"]; + * APP<SD [label = "sd_nvic_EnableIRQ(SD_EVT_IRQn)"]; + * APP<APP [label = "SD_EVT_IRQHandler()"]; + * APP=>SD [label = "sd_ble_evt_get(buffer);"]; + * APP<SD [label = "sd_softdevice_enable(clock, assertion_handler);"]; + * APP<SD [label = "sd_app_evt_wait(void);"]; + * APP rbox APP [label="App Thread Mode blocked, CPU in low power mode"]; + * |||; + * ...; + * |||; + * SD rbox SD [label="Event Available for the App"]; + * APP<SD [label = "sd_ble_evt_get(buffer);"]; + * APP<SD [label = "sd_app_evt_wait(void);"]; + * APP rbox APP [label="App Thread Mode blocked, CPU in low power mode"]; + * |||; + * ...; + * |||; + * SD rbox SD [label="Event Available for the App"]; + * APP<SD [label = "sd_ble_evt_get(buffer);"]; + * APP<SD [label = "sd_app_evt_wait(void);"]; + * APP rbox APP [label="App Thread Mode blocked, CPU in low power mode"]; + * |||; + * ...; + * |||; + * @endmsc + * + * @} + * @} + */ + +/** + * @addtogroup BLE_GAP + * @{ + * @defgroup BLE_GAP_MSC Message Sequence Charts + * @{ + * @defgroup BLE_GAP_ADV_MSC Advertising + * @{ + * @defgroup BLE_GAP_ADV_MSC_LEGACY Advertising using legacy advertising PDUs + * @msc + * hscale = "1.5"; + * APP,SD,SCANNERS; + * |||; + * APP=>SD [label = "sd_ble_gap_adv_set_configure(&adv_handle, adv_data, params)"]; + * APP<SD [label = "sd_ble_gap_adv_start(adv_handle, conn_cfg_tag = BLE_CONN_CFG_TAG_DEFAULT)"]; + * APP<SCANNERS [label = "Advertisement (ADV_IND/ADV_DIRECT_IND/ADV_NONCONN_IND/ADV_SCAN_IND)", textcolor="#000080", linecolor="#000080"]; + * SD->SCANNERS [label = "Advertisement (ADV_IND/ADV_DIRECT_IND/ADV_NONCONN_IND/ADV_SCAN_IND)", textcolor="#000080", linecolor="#000080"]; + * SD->SCANNERS [label = "Advertisement (ADV_IND/ADV_DIRECT_IND/ADV_NONCONN_IND/ADV_SCAN_IND)", textcolor="#000080", linecolor="#000080"]; + * ...; + * SD->SCANNERS [label = "Advertisement (ADV_IND/ADV_DIRECT_IND/ADV_NONCONN_IND/ADV_SCAN_IND)", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #1 App Stops Advertisement "]; + * APP=>SD [label = "sd_ble_gap_adv_stop(adv_handle)"]; + * APP<SD [label = "sd_ble_gap_adv_set_configure(&adv_handle, adv_data, params : properties : type = BLE_GAP_ADV_TYPE_EXTENDED_*)"]; + * APP<SD [label = "sd_ble_gap_adv_start(adv_handle, conn_cfg_tag = BLE_CONN_CFG_TAG_DEFAULT)"]; + * APP<SCANNERS [label = "Advertisement (ADV_EXT_IND) on 1MBPS/CODED PHY", textcolor="#000080", linecolor="#000080"]; + * SD->SCANNERS [label = "Advertisement (AUX_*_IND) on 1MBPS/2MBPS/CODED PHY", textcolor="#000080", linecolor="#000080"]; + * SD->SCANNERS [label = "Advertisement (ADV_EXT_IND) on 1MBPS/CODED PHY", textcolor="#000080", linecolor="#000080"]; + * SD->SCANNERS [label = "Advertisement (AUX_*_IND) on 1MBPS/2MBPS/CODED PHY", textcolor="#000080", linecolor="#000080"]; + * ...; + * SD->SCANNERS [label = "Advertisement (ADV_EXT_IND) on 1MBPS/CODED PHY", textcolor="#000080", linecolor="#000080"]; + * SD->SCANNERS [label = "Advertisement (AUX_*_IND) on 1MBPS/2MBPS/CODED PHY", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #1 App Stops Advertisement "]; + * APP=>SD [label = "sd_ble_gap_adv_stop(adv_handle)"]; + * APP<CENTRAL [label = "Connection Establishment", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONNECTED"]; + * |||; + * --- [label = " Variant #1 Local Disconnection "]; + * APP=>SD [label = "sd_ble_gap_disconnect(reason)"]; + * APP<CENTRAL [label = "Connection Termination", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_DISCONNECTED {reason}"]; + * |||; + * --- [label = " Variant #2 Remote Disconnection "]; + * SD<:CENTRAL [label = "Connection Termination", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_DISCONNECTED {reason}"]; + * @endmsc + * + * @defgroup BLE_GAP_CPU_MSC Peripheral Connection Parameter Update + * @msc + * hscale = "1.5"; + * APP,SD,CENTRAL; + * |||; + * APP rbox CENTRAL [label="Connection Established with conn. params. CP#1"]; + * |||; + * APP=>SD [label = "sd_ble_gap_conn_param_update(CP#2)"]; + * APP<CENTRAL [label = "L2CAP Connection Parameter Update Request", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #1 Central Accepts "]; + * |||; + * SD<:CENTRAL [label = "L2CAP Connection Parameter Update Response: Accepted", textcolor="#000080", linecolor="#000080"]; + * SD<:CENTRAL [label = "LL Connection Update (LL_CONNECTION_UPDATE_IND)", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {CP#2}"]; + * |||; + * --- [label = " Variant #2 Central Rejects "]; + * |||; + * SD<:CENTRAL [label = "L2CAP Connection Parameter Update Response: Rejected", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {CP#1}"]; + * --- [label = " Variant #3 Central Ignores "]; + * |||; + * ...; + * |||; + * SD box SD [label="Timeout"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {CP#1}"]; + * @endmsc + * + * @defgroup BLE_GAP_RSSI_FILT_MSC RSSI for connections with event filter + * @msc + * hscale = "1.5"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * --- [label = " Variant #1: Trigger event when a new RSSI is available"]; + * |||; + * APP=>SD [label = "sd_ble_gap_rssi_start(conn_handle, 0, 0)"]; + * APP<SD [label = "sd_ble_gap_rssi_stop()"]; + * APP<SD [label = "sd_ble_gap_rssi_start(conn_handle, 0x05, 0x00)"]; + * APP<SD [label = "sd_ble_gap_rssi_stop()"]; + * APP<SD [label = "sd_ble_gap_rssi_start(conn_handle, 0x05, 0x03)"]; + * APP<SD [label = "sd_ble_gap_rssi_stop()"]; + * APP<SD [label = "sd_ble_gap_rssi_get(conn_handle, p_rssi, p_ch_index)"]; + * APP<SD [label = "sd_ble_gap_rssi_start(conn_handle, BLE_GAP_RSSI_THRESHOLD_INVALID, 0x00)"]; + * APP<SD [label = "sd_ble_gap_rssi_get(conn_handle, p_rssi, p_ch_index)"]; + * APP<SD [label = "sd_ble_gap_rssi_get(conn_handle, p_rssi, p_ch_index)"]; + * APP<SD [label = "sd_ble_gap_rssi_stop()"]; + * APP<SD [label = "sd_ble_gap_authenticate(params)"]; + * APP<CENTRAL [label = "SMP Security Request", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #1 Central initiates Security Establishment "]; + * |||; + * APP rbox CENTRAL [label="Encryption or Pairing/Bonding initiated by Central"]; + * |||; + * --- [label = " Variant #2 Central ignores "]; + * |||; + * ...; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: Timeout, error_src: local}"]; + * |||; + * @endmsc + * + * @defgroup BLE_GAP_PERIPH_LEGACY_MSC Peripheral Legacy Pairing + * @{ + * + * @defgroup BLE_GAP_PERIPH_PAIRING_JW_MSC Pairing: Just Works + * @msc + * hscale = "2"; + * APP,SD,CENTRAL; + * |||; + * APP rbox CENTRAL [label="Connection Established"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: no_bond, no_mitm, no_io_caps}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: no_bond, no_mitm, no_io_caps, p_keyset: NULL)"]; + * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD abox CENTRAL [label="Legacy Pairing Phase 2", textbgcolor="#7f7fff"]; + * |||; + * APP rbox CENTRAL [label = "Encrypted with STK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_NO_MITM}"]; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; + * @endmsc + * + * @defgroup BLE_GAP_PERIPH_BONDING_JW_MSC Bonding: Just Works + * @msc + * hscale = "2"; + * APP,SD,CENTRAL; + * |||; + * APP rbox CENTRAL [label="Connection Established"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: bond, no_mitm, no_io_caps}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: bond, no_mitm, no_io_caps, p_keyset)"]; + * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD abox CENTRAL [label="Legacy Pairing Phase 2", textbgcolor="#7f7fff"]; + * |||; + * APP rbox CENTRAL [label = "Encrypted with STK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_NO_MITM}"]; + * |||; + * SD abox CENTRAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; + * APP rbox APP [label = "Keys stored in keyset"]; + * @endmsc + * + * @defgroup BLE_GAP_PERIPH_BONDING_PK_PERIPH_MSC Bonding: Passkey Entry, Peripheral displays + * @msc + * hscale = "2"; + * APP,SD,CENTRAL; + * |||; + * APP rbox CENTRAL [label="Connection Established"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: bond, mitm, keyboard}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: bond, mitm, display, p_keyset)"]; + * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_PASSKEY_DISPLAY {passkey, match_request=0}"]; + * APP rbox APP [label="Passkey displayed to the user"]; + * |||; + * SD abox CENTRAL [label="Legacy Pairing Phase 2", textbgcolor="#7f7fff"]; + * |||; + * APP rbox CENTRAL [label = "Encrypted with STK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_MITM}"]; + * |||; + * SD abox CENTRAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; + * APP rbox APP [label = "Keys stored in keyset"]; + * @endmsc + * + * @defgroup BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC Bonding: Passkey Entry, User Inputs on Peripheral or OOB + * @msc + * hscale = "2"; + * APP,SD,CENTRAL; + * |||; + * APP rbox CENTRAL [label="Connection Established"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: bond, mitm, display}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: bond, mitm, keyboard, p_keyset)"]; + * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_KEY_REQUEST {type}"]; + * APP rbox APP [label="User enters Passkey or data received Out Of Band"]; + * APP=>SD [label = "sd_ble_gap_auth_key_reply(passkey or OOB)"]; + * APP<SD [label = "sd_ble_opt_set(opt_id = BLE_GAP_OPT_PASSKEY, p_opt->p_passkey=passkey)"]; + * APP rbox CENTRAL [label="Connection Established"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: bond, mitm, keyboard}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: bond, mitm, display, p_keyset)"]; + * + * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_PASSKEY_DISPLAY {passkey, match_request=0}"]; + * APP rbox APP [label="Passkey displayed to the user"]; + * |||; + * SD abox CENTRAL [label="Legacy Pairing Phase 2", textbgcolor="#7f7fff"]; + * |||; + * APP rbox CENTRAL [label = "Encrypted with STK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_MITM}"]; + * |||; + * SD abox CENTRAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; + * APP rbox APP [label = "Keys stored in keyset"]; + * @endmsc + * + * @defgroup BLE_GAP_PERIPH_PAIRING_CONFIRM_FAIL_MSC Pairing failure: Confirm failed + * This occurs if the random value doesn't match, usually because the user entered a wrong pin + * or out of band data was missing. + * @msc + * hscale = "2"; + * APP,SD,CENTRAL; + * |||; + * APP rbox CENTRAL [label="Connection Established"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: mitm, display}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: mitm, keyboard, p_keyset: NULL)"]; + * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * SD<:CENTRAL [label = "SMP Pairing Confirm", textcolor="#000080", linecolor="#000080"]; + * SD:>CENTRAL [label = "SMP Pairing Confirm", textcolor="#000080", linecolor="#000080"]; + * SD<:CENTRAL [label = "SMP Pairing Random", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: Confirm value, error_src: local}"]; + * SD:>CENTRAL [label = "SMP Pairing failed", textcolor="#000080", linecolor="#000080"]; + * @endmsc + * + * @} + * + * @defgroup BLE_GAP_PERIPH_LESC_MSC Peripheral LESC Pairing + * @{ + * + * @defgroup BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC Pairing: Just Works + * @msc + * hscale = "2"; + * APP,SD,CENTRAL; + * |||; + * APP rbox CENTRAL [label="Connection Established"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, no_bond, no_mitm, no_io_caps}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: lesc, no_bond, no_mitm, no_io_caps, p_pk_own)"]; + * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk}"]; + * SD:>CENTRAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP abox APP [label="App starts DHKey calculation"]; + * |||; + * SD abox CENTRAL [label="LESC Authentication Stage 1", textbgcolor="#7f7fff"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing DHKey Check: Ea", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP abox APP [label="App completes DHKey calculation"]; + * APP=>SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; + * APP<CENTRAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP rbox CENTRAL [label = "Encrypted with LTK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_NO_MITM}"]; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; + * @endmsc + * + * @defgroup BLE_GAP_PERIPH_LESC_BONDING_NC_MSC Bonding: Numeric Comparison + * @msc + * hscale = "2"; + * APP,SD,CENTRAL; + * |||; + * APP rbox CENTRAL [label="Connection Established"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, bond, mitm, display(kbd/yesno)}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: lesc, bond, mitm, display(kbd/yesno), keyset with p_pk_own)"]; + * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk}"]; + * SD:>CENTRAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP abox APP [label="App starts DHKey calculation"]; + * |||; + * SD abox CENTRAL [label="LESC Authentication Stage 1", textbgcolor="#7f7fff"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_PASSKEY_DISPLAY {passkey, match_request=1}"]; + * APP rbox APP [label="Passkey displayed to the user, user compares values"]; + * |||; + * --- [label = " Variant #1 User confirms on both sides "]; + * APP=>SD [label = "sd_ble_gap_auth_key_reply(BLE_GAP_AUTH_KEY_TYPE_PASSKEY, NULL)"]; + * APP<SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; + * APP<CENTRAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP rbox CENTRAL [label = "Encrypted with LTK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {LESC_ENC_MITM}"]; + * |||; + * SD abox CENTRAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; + * APP rbox APP [label = "Keys stored in keyset"]; + * --- [label = " Variant #2 User does not confirm locally "]; + * APP=>SD [label = "sd_ble_gap_auth_key_reply(BLE_GAP_AUTH_KEY_TYPE_NONE, NULL)"]; + * APP<CENTRAL [label = "SMP Pairing failed", textcolor="#000080", linecolor="#000080"]; + * --- [label = " Variant #3 User does not confirm remotely "]; + * SD<:CENTRAL [label = "SMP Pairing failed", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: num comp failure, error_src: remote}"]; + * @endmsc + * + * @defgroup BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC Bonding: Passkey Entry, Peripheral Displays + * @msc + * hscale = "2"; + * APP,SD,CENTRAL; + * |||; + * APP rbox CENTRAL [label="Connection Established"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, bond, mitm, keyboard}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: lesc, bond, mitm, display, keyset with p_pk_own)"]; + * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_PASSKEY_DISPLAY {passkey, match_request=0}"]; + * APP rbox APP [label="Passkey displayed to the user"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk}"]; + * SD:>CENTRAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP abox APP [label="App starts DHKey calculation"]; + * |||; + * --- [label = " Optional keypresses from peer "]; + * SD<:CENTRAL [label = "Keypress Notification", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_KEY_PRESSED {type}"]; + * APP abox APP [label="App displays keypress"]; + * SD<:CENTRAL [label = "Keypress Notification", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_KEY_PRESSED {type}"]; + * APP abox APP [label="App displays keypress"]; + * |||; + * --- [label = ""]; + * SD abox CENTRAL [label="LESC Authentication Stage 1", textbgcolor="#7f7fff"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing DHKey Check: Ea", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP abox APP [label="App completes DHKey calculation"]; + * APP=>SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; + * APP<CENTRAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP rbox CENTRAL [label = "Encrypted with LTK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {LESC_ENC_MITM}"]; + * |||; + * SD abox CENTRAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; + * APP rbox APP [label = "Keys stored in keyset"]; + * @endmsc + * + * @defgroup BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC Bonding: Passkey Entry, User Inputs on Peripheral + * @msc + * hscale = "2"; + * APP,SD,CENTRAL; + * |||; + * APP rbox CENTRAL [label="Connection Established"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, bond, mitm, display}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: lesc, bond, mitm, keyboard, keyset with p_pk_own)"]; + * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_KEY_REQUEST {passkey}"]; + * APP rbox APP [label="User enters Passkey"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk}"]; + * SD:>CENTRAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP abox APP [label="App starts DHKey calculation"]; + * |||; + * --- [label = " Optional keypresses sent to peer "]; + * APP=>SD [label = "sd_ble_gap_keypress_notify(type)"]; + * APP<CENTRAL [label = "Keypress Notification", textcolor="#000080", linecolor="#000080"]; + * APP=>SD [label = "sd_ble_gap_keypress_notify(type)"]; + * APP<CENTRAL [label = "Keypress Notification", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = ""]; + * APP=>SD [label = "sd_ble_gap_auth_key_reply(passkey)"]; + * APP<SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; + * APP<CENTRAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP rbox CENTRAL [label = "Encrypted with LTK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {LESC_ENC_MITM}"]; + * |||; + * SD abox CENTRAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; + * APP rbox APP [label = "Keys stored in keyset"]; + * @endmsc + * + * @defgroup BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC Bonding: Out of Band + * @msc + * hscale = "2"; + * APP,SD,CENTRAL; + * |||; + * APP=>SD [label = "sd_ble_gap_addr_set(addr)"]; + * APP<SD [label = "sd_ble_gap_lesc_oob_data_get(p_pk_own, p_oobd_own)"]; + * APP<SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: lesc, bond, oob, keyset with p_pk_own)"]; + * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk, oobd_req=1}"]; + * SD:>CENTRAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP abox APP [label="App starts DHKey calculation"]; + * |||; + * APP=>SD [label = "sd_ble_gap_lesc_oob_data_set(p_oobd_own, p_oobd_peer)"]; + * APP<SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; + * APP<CENTRAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP rbox CENTRAL [label = "Encrypted with LTK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {LESC_ENC_MITM}"]; + * |||; + * SD abox CENTRAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; + * APP rbox APP [label = "Keys stored in keyset"]; + * @endmsc + * + * @} + * + * @defgroup BLE_GAP_PERIPH_PAIRING_KS_OUT_OF_RANGE_MSC Pairing failure: Keysize out of supported range + * This occurs if the min key size offered by the peer is above 16, or max key size below 7. + * @msc + * hscale = "2"; + * APP,SD,CENTRAL; + * |||; + * APP rbox CENTRAL [label="Connection Established"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: Invalid params, error_src: local}"]; + * SD:>CENTRAL [label = "SMP Pairing failed", textcolor="#000080", linecolor="#000080"]; + * @endmsc + * + * @defgroup BLE_GAP_PERIPH_PAIRING_KS_TOO_SMALL_MSC GAP Failed Pairing: Keysize too small + * This occurs if the max key size offered by the peer is below the min key size specified by + * the app. + * @msc + * hscale = "2"; + * APP,SD,CENTRAL; + * |||; + * APP rbox CENTRAL [label="Connection Established"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS)"]; + * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * SD<:CENTRAL [label = "SMP Pairing Confirm", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: Enc key size, error_src: local}"]; + * SD:>CENTRAL [label = "SMP Pairing failed", textcolor="#000080", linecolor="#000080"]; + * @endmsc + * + * @defgroup BLE_GAP_PERIPH_PAIRING_APP_ERROR_MSC Pairing failure: Pairing aborted by the application + * When the application detects that the pairing should not be performed, for example an + * insufficient IO combination, it can use sd_ble_gap_sec_params_reply() to send + * SMP Pairing failed to the peer. + * + * When the stack handles the response from the application it will also validate + * the passkey (SMP_STC_PASSKEY_ENTRY_FAILED). If any error is detected it will be + * reported when sd_ble_gap_sec_params_reply() is called. + * @msc + * hscale = "2"; + * APP,SD,CENTRAL; + * |||; + * APP rbox CENTRAL [label="Connection Established"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST"]; + * SD abox APP [label="Stack looks for errors", textbgcolor="#7f7fff"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply()"]; + * APP<CENTRAL [label = "SMP Pairing failed", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: , error_src: local}"]; + * @endmsc + * + * @defgroup BLE_GAP_PERIPH_PAIRING_REMOTE_PAIRING_FAIL_MSC Pairing failure: Pairing failed from central + * SMP Pairing Failed may be sent from the central at various times. The application should + * prepare for this and gracefully handle the event. + * @msc + * hscale = "2"; + * APP,SD,CENTRAL; + * |||; + * APP rbox CENTRAL [label="Connection Established"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS)"]; + * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * SD<:CENTRAL [label = "SMP Pairing Failed", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: , error_src: remote}"]; + * @endmsc + * + * @defgroup BLE_GAP_PERIPH_PAIRING_TIMEOUT_MSC Pairing failure: Timeout + * This occurs if the central device doesn't continue the pairing sequence within 30 seconds. + * @msc + * hscale = "2"; + * APP,SD,CENTRAL; + * |||; + * APP rbox CENTRAL [label="Connection Established"]; + * |||; + * SD<:CENTRAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS)"]; + * APP<CENTRAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * --- [ label = "Wait 30 sec" ]; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: Timeout, error_src: local}"]; + * @endmsc + * + * @defgroup BLE_GAP_PERIPH_ENC_MSC Peripheral Encryption Establishment using stored keys + * @msc + * hscale = "1.5"; + * APP,SD,CENTRAL; + * |||; + * APP rbox CENTRAL [label="Connection Established"]; + * |||; + * SD<:CENTRAL [label = "LL Encryption Request (LL_ENC_REQ)", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_INFO_REQUEST {addr, ediv, rand}"]; + * |||; + * --- [label = " Variant #1 App Replies with Keys "]; + * |||; + * APP rbox APP [label = "Load Peripheral Keys"]; + * APP=>SD [label = "sd_ble_gap_sec_info_reply(ediv, rand, LTK)"]; + * APP<CENTRAL [label = "LL Encryption Response (LL_ENC_RSP)", textcolor="#000080", linecolor="#000080"]; + * APP rbox CENTRAL [label = "Encrypted with LTK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE"]; + * |||; + * --- [label = " Variant #2 App Replies without Keys "]; + * |||; + * APP=>SD [label = "sd_ble_gap_sec_info_reply(NULL)"]; + * APP<CENTRAL [label = "LL Reject Ind (LL_REJECT_IND): Pin or Key Missing", textcolor="#000080", linecolor="#000080"]; + * APP rbox CENTRAL [label = "Link is NOT encrypted"]; + * |||; + * --- [label = " Variant #3 App Replies with Incorrect Keys "]; + * |||; + * APP rbox APP [label = "Load Incorrect Peripheral Keys"]; + * APP=>SD [label = "sd_ble_gap_sec_info_reply(ediv, rand, LTK)"]; + * APP<CENTRAL [label = "LL Encryption Response (LL_ENC_RSP)", textcolor="#000080", linecolor="#000080"]; + * APP rbox CENTRAL [label = "Link Terminated due to authentication error"]; + * APP<<=SD [label = "BLE_GAP_EVT_DISCONNECTED {MIC Failure}"]; + * @endmsc + * + * @defgroup BLE_GAP_PERIPH_INVALID_SMP_PDU_MSC Unexpected Security Packet Reception + * @msc + * hscale = "1.5"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * APP rbox PEER [label="No pairing in progress"]; + * |||; + * PEER rbox PEER [label="Peer misbehaving"]; + * |||; + * SD<:PEER [label = "SMP Pairing Failed (or other unexpected SMP PDU)", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {PDU_INVALID}"]; + * |||; + * @endmsc + * @} + * + * + * @defgroup BLE_GAP_SCAN_MSC Scanning + * @{ + * @defgroup BLE_GAP_SCAN_MSC_LEGACY Scanning for advertisers performing legacy advertising + * @msc + * hscale = "1.5"; + * APP,SD,ADVERTISERS; + * |||; + * APP=>SD [label = "sd_ble_gap_scan_start(params : extended = 0, adv_report_buffer)"]; + * APP<SD [label = "sd_ble_gap_scan_start(params = NULL, adv_report_buffer)"]; + * APP<SD [label = "sd_ble_gap_scan_start(params = NULL, adv_report_buffer)"]; + * APP<SD [label = "sd_ble_gap_scan_start(params = NULL, adv_report_buffer)"]; + * APP<SD [label = "sd_ble_gap_scan_start(params : {extended = 0, active = 1}, adv_report_buffer)"]; + * APP<ADVERTISERS [label = "Scan Request (SCAN_REQ)", textcolor="#000080", linecolor="#000080"]; + * SD<-ADVERTISERS [label = "Scan Response (SCAN_RSP)", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_ADV_REPORT {bdaddr, rssi, data}"]; + * ...; + * APP<<=SD [label = "BLE_GAP_EVT_TIMEOUT {BLE_GAP_TIMEOUT_SRC_SCAN}"]; + * |||; + * @endmsc + * @defgroup BLE_GAP_SCAN_MSC_AE Scanning for advertisers performing legacy and extended advertising + * @msc + * hscale = "1.5"; + * APP,SD,ADVERTISERS; + * |||; + * APP=>SD [label = "sd_ble_gap_scan_start(params : {extended = 1, report_incomplete_evts = 0}, adv_report_buffer)"]; + * APP<SD [label = "sd_ble_gap_scan_start(params = NULL, adv_report_buffer)"]; + * APP<SD [label = "sd_ble_gap_scan_start(params = NULL, adv_report_buffer)"]; + * APP<SD [label = "sd_ble_gap_scan_start(params : {extended = 1, active = 1, report_incomplete_evts = 0}, adv_report_buffer)"]; + * APP<ADVERTISERS [label = "Scan Request (AUX_SCAN_REQ) on secondary_phy", textcolor="#000080", linecolor="#000080"]; + * SD<-ADVERTISERS [label = "Scan Response (AUX_SCAN_RSP) on secondary_phy", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_ADV_REPORT {type : {extended_pdu = 1, scannable = 1, scan_response = 1}, data}"]; + * APP=>SD [label = "sd_ble_gap_scan_start(params = NULL, adv_report_buffer)"]; + * APP<ADVERTISERS [label = "Legacy Scan Request (SCAN_REQ)", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_ADV_REPORT {type : {extended_pdu = 0, scannable = 1, scan_response = 0}, adv_data}"]; + * APP=>SD [label = "sd_ble_gap_scan_start(params = NULL, adv_report_buffer)"]; + * APP<SD [label = "sd_ble_gap_scan_start(params = NULL, adv_report_buffer)"]; + * APP<SD [label = "sd_ble_gap_scan_start(params : {extended = 1, report_incomplete_evts = 1}, adv_report_buffer)"]; + * APP<SD [label = "sd_ble_gap_scan_start(params = NULL, adv_report_buffer)"]; + * APP<SD [label = "sd_ble_gap_connect(scan_params : extended = 0, conn_params)"]; + * APP<PERIPHERAL [label = "LL Connect (CONNECT_IND)", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONNECTED"]; + * |||; + * --- [label = " Variant #2 Connection Establishment Cancelled "]; + * APP=>SD [label = "sd_ble_gap_connect_cancel()"]; + * APP<SD [label = "sd_ble_gap_connect(scan_params={extended=1,scan_phys=PHY_A and PHY_B}, conn_params)"]; + * APP<PERIPHERAL [label = "LL Connect Request(AUX_CONNECT_REQ) on secondary_phy", textcolor="#000080", linecolor="#000080"]; + * SD<:PERIPHERAL [label = "LL Connect Response(AUX_CONNECT_RSP) on secondary_phy", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONNECTED"]; + * |||; + * --- [label = " Variant #2 Connection Establishment Cancelled "]; + * APP=>SD [label = "sd_ble_gap_connect_cancel()"]; + * APP<SD [label = "sd_ble_gap_connect(scan_params={extended=1,scan_phys=PHY_A}, conn_params)"]; + * APP<SD [label = "sd_ble_gap_conn_param_update(CP#2)"]; + * APP<PERIPHERAL [label = "LL Connection Update (LL_CONNECTION_UPDATE_IND)", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {CP#2}"]; + * |||; + * --- [label = " Peripheral Solicited procedure"]; + * |||; + * SD<:PERIPHERAL [label = "L2CAP Connection Parameter Update Request {CP#3}", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST {CP#3}"]; + * |||; + * --- [label = " Variant #1 App Accepts "]; + * APP=>SD [label = "sd_ble_gap_conn_param_update(CP#3)"]; + * APP<PERIPHERAL [label = "L2CAP Connection Parameter Update Response: Accepted", textcolor="#000080", linecolor="#000080"]; + * SD:>PERIPHERAL [label = "LL Connection Update (LL_CONNECTION_UPDATE_IND)", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {CP#3}"]; + * |||; + * --- [label = " Variant #2 App Rejects "]; + * |||; + * APP=>SD [label = "sd_ble_gap_conn_param_update(NULL)"]; + * APP<PERIPHERAL [label = "L2CAP Connection Parameter Update Response: Rejected", textcolor="#000080", linecolor="#000080"]; + * |||; + * @endmsc + * + * @defgroup BLE_GAP_CENTRAL_SEC_MSC Central Security Procedures + * @{ + * + * @defgroup BLE_GAP_CENTRAL_SEC_REQ_MSC Security Request Reception + * @msc + * hscale = "1.5"; + * APP,SD,PERIPHERAL; + * |||; + * APP rbox PERIPHERAL [label="Connection Established"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Security Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_REQUEST {bond, mitm}"]; + * |||; + * --- [label = " Variant #1 Central initiates Security Establishment "]; + * |||; + * APP=>SD [label = "sd_ble_gap_encrypt(ediv, rand, LTK)"]; + * APP<SD [label = "sd_ble_gap_authenticate(params)"]; + * APP<SD [label = "sd_ble_gap_authenticate(NULL)"]; + * APP<PERIPHERAL [label = "SMP Pairing Failed: Pairing Not Supported", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: Pairing Not Supp, error_src: local}"]; + * |||; + * @endmsc + * + * @defgroup BLE_GAP_CENTRAL_LEGACY_MSC Central Legacy Pairing + * @{ + * + * @defgroup BLE_GAP_CENTRAL_PAIRING_JW_MSC Pairing: Just Works + * @msc + * hscale = "2"; + * APP,SD,PERIPHERAL; + * |||; + * APP rbox PERIPHERAL [label="Connection Established"]; + * |||; + * APP=>SD [label = "sd_ble_gap_authenticate(no_bond, no_mitm, no_io_caps)"]; + * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: no_bond, no_mitm, no_io_caps}"]; + * |||; + * --- [label = " Variant #1 Central Accepts Peripheral parameters "]; + * |||; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, p_keyset: NULL)"]; + * |||; + * SD abox PERIPHERAL [label="Legacy Pairing Phase 2", textbgcolor="#7f7fff"]; + * |||; + * APP rbox PERIPHERAL [label = "Encrypted with STK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_NO_MITM}"]; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; + * |||; + * --- [label = " Variant #2 Central Rejects Peripheral parameters "]; + * |||; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(BLE_GAP_SEC_STATUS_INVALID_PARAMS, own_params: NULL, p_keyset: NULL)"]; + * |||; + * SD:>PERIPHERAL [label = "SMP Pairing Failed", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {FAILURE}"]; + * @endmsc + * + * @defgroup BLE_GAP_CENTRAL_BONDING_JW_MSC Bonding: Just Works + * @msc + * hscale = "2"; + * APP,SD,PERIPHERAL; + * |||; + * APP rbox PERIPHERAL [label="Connection Established"]; + * |||; + * APP=>SD [label = "sd_ble_gap_authenticate(bond, no_mitm, no_io_caps)"]; + * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: bond, no_mitm, no_io_caps}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, p_keyset)"]; + * |||; + * SD abox PERIPHERAL [label="Legacy Pairing Phase 2", textbgcolor="#7f7fff"]; + * |||; + * APP rbox PERIPHERAL [label = "Encrypted with STK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_NO_MITM}"]; + * |||; + * SD abox PERIPHERAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; + * APP rbox APP [label = "Keys stored in keyset"]; + * @endmsc + * + * @defgroup BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC Bonding: Passkey Entry, Central displays + * @msc + * hscale = "2"; + * APP,SD,PERIPHERAL; + * |||; + * APP rbox PERIPHERAL [label="Connection Established"]; + * |||; + * APP=>SD [label = "sd_ble_gap_authenticate(bond, mitm, display)"]; + * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing Response}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: bond, mitm, keyboard}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, p_keyset)"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_PASSKEY_DISPLAY {passkey, match_request=0}"]; + * APP rbox APP [label="Passkey displayed to the user"]; + * |||; + * SD abox PERIPHERAL [label="Legacy Pairing Phase 2", textbgcolor="#7f7fff"]; + * |||; + * APP rbox PERIPHERAL [label = "Encrypted with STK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_MITM}"]; + * |||; + * SD abox PERIPHERAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; + * APP rbox APP [label = "Keys stored in keyset"]; + * @endmsc + * + * @defgroup BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC Bonding: Passkey Entry, User Inputs on Central or OOB + * @msc + * hscale = "2"; + * APP,SD,PERIPHERAL; + * |||; + * APP rbox PERIPHERAL [label="Connection Established"]; + * |||; + * APP=>SD [label = "sd_ble_gap_authenticate(bond, mitm, keyboard)"]; + * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: bond, mitm, display}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, p_keyset)"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_KEY_REQUEST {type}"]; + * APP rbox APP [label="User enters Passkey or data received Out Of Band"]; + * APP=>SD [label = "sd_ble_gap_auth_key_reply(passkey or OOB)"]; + * APP<SD [label = "sd_ble_gap_authenticate(lesc, no_bond, no_mitm, no_io_caps)"]; + * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, no_bond, no_mitm, no_io_caps}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, p_pk_own)"]; + * APP<PERIPHERAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk}"]; + * |||; + * APP abox APP [label="App starts DHKey calculation"]; + * |||; + * SD abox PERIPHERAL [label="LESC Authentication Stage 1", textbgcolor="#7f7fff"]; + * |||; + * APP abox APP [label="App completes DHKey calculation"]; + * APP=>SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; + * APP<PERIPHERAL [label = "SMP Pairing DHKey Check: Ea", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP rbox PERIPHERAL [label = "Encrypted with LTK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {ENC_NO_MITM}"]; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; + * @endmsc + * + * @defgroup BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC Bonding: Numeric Comparison + * @msc + * hscale = "2"; + * APP,SD,PERIPHERAL; + * |||; + * APP rbox PERIPHERAL [label="Connection Established"]; + * |||; + * APP=>SD [label = "sd_ble_gap_authenticate(lesc, bond, mitm, display(kbd/yesno))"]; + * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, bond, mitm, display(kbd/yesno)}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, keyset with p_pk_own)"]; + * APP<PERIPHERAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk}"]; + * |||; + * APP abox APP [label="App starts DHKey calculation"]; + * |||; + * SD abox PERIPHERAL [label="LESC Authentication Stage 1", textbgcolor="#7f7fff"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_PASSKEY_DISPLAY {passkey, match_request=1}"]; + * APP rbox APP [label="Passkey displayed to the user, user compares values"]; + * |||; + * --- [label = " Variant #1 User confirms on both sides "]; + * APP=>SD [label = "sd_ble_gap_auth_key_reply(BLE_GAP_AUTH_KEY_TYPE_PASSKEY, NULL)"]; + * APP<SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; + * APP<PERIPHERAL [label = "SMP Pairing DHKey Check: Ea", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP rbox PERIPHERAL [label = "Encrypted with LTK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {LESC_ENC_MITM}"]; + * |||; + * SD abox PERIPHERAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; + * APP rbox APP [label = "Keys stored in keyset"]; + * --- [label = " Variant #2 User does not confirm locally "]; + * APP=>SD [label = "sd_ble_gap_auth_key_reply(BLE_GAP_AUTH_KEY_TYPE_NONE, NULL)"]; + * APP<PERIPHERAL [label = "SMP Pairing failed", textcolor="#000080", linecolor="#000080"]; + * --- [label = " Variant #3 User does not confirm remotely "]; + * SD<:PERIPHERAL [label = "SMP Pairing failed", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {auth_status: num comp failure, error_src: remote}"]; + * @endmsc + * + * @defgroup BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC Bonding: Passkey Entry: Central Displays + * @msc + * hscale = "2"; + * APP,SD,PERIPHERAL; + * |||; + * APP rbox PERIPHERAL [label="Connection Established"]; + * |||; + * APP=>SD [label = "sd_ble_gap_authenticate(lesc, bond, mitm, display)"]; + * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, bond, mitm, keyboard}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, keyset with p_pk_own)"]; + * APP<PERIPHERAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk}"]; + * |||; + * APP abox APP [label="App starts DHKey calculation"]; + * |||; + * --- [label = " Optional keypresses from peer "]; + * SD<:PERIPHERAL [label = "Keypress Notification", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_KEY_PRESSED {type}"]; + * APP abox APP [label="App displays keypress"]; + * SD<:PERIPHERAL [label = "Keypress Notification", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_KEY_PRESSED {type}"]; + * APP abox APP [label="App displays keypress"]; + * |||; + * --- [label = ""]; + * SD abox PERIPHERAL [label="LESC Authentication Stage 1", textbgcolor="#7f7fff"]; + * |||; + * APP abox APP [label="App completes DHKey calculation"]; + * APP=>SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; + * APP<PERIPHERAL [label = "SMP Pairing DHKey Check: Ea", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP rbox PERIPHERAL [label = "Encrypted with LTK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {LESC_ENC_MITM}"]; + * |||; + * SD abox PERIPHERAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; + * APP rbox APP [label = "Keys stored in keyset"]; + * @endmsc + * + * @defgroup BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC Bonding: Passkey Entry: User Inputs on Central + * @msc + * hscale = "2"; + * APP,SD,PERIPHERAL; + * |||; + * APP rbox PERIPHERAL [label="Connection Established"]; + * |||; + * APP=>SD [label = "sd_ble_gap_authenticate(lesc, bond, mitm, keyboard)"]; + * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, bond, mitm, display}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, keyset with p_pk_own)"]; + * APP<PERIPHERAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk}"]; + * |||; + * APP abox APP [label="App starts DHKey calculation"]; + * |||; + * --- [label = " Optional keypresses sent to peer "]; + * APP=>SD [label = "sd_ble_gap_keypress_notify(type)"]; + * APP<PERIPHERAL [label = "Keypress Notification", textcolor="#000080", linecolor="#000080"]; + * APP=>SD [label = "sd_ble_gap_keypress_notify(type)"]; + * APP<PERIPHERAL [label = "Keypress Notification", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = ""]; + * APP=>SD [label = "sd_ble_gap_auth_key_reply(passkey)"]; + * APP<SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; + * APP<PERIPHERAL [label = "SMP Pairing DHKey Check: Ea", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP rbox PERIPHERAL [label = "Encrypted with LTK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {LESC_ENC_MITM}"]; + * |||; + * SD abox PERIPHERAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; + * APP rbox APP [label = "Keys stored in keyset"]; + * @endmsc + * + * @defgroup BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC Bonding: Out of Band + * @msc + * hscale = "2"; + * APP,SD,PERIPHERAL; + * |||; + * APP=>SD [label = "sd_ble_gap_addr_set(addr)"]; + * APP<SD [label = "sd_ble_gap_lesc_oob_data_get(p_pk_own, p_oobd_own)"]; + * APP<SD [label = "sd_ble_gap_authenticate(lesc, bond, oob)"]; + * APP<PERIPHERAL [label = "SMP Pairing Request", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_SEC_PARAMS_REQUEST {peer_params: lesc, bond, oob}"]; + * APP=>SD [label = "sd_ble_gap_sec_params_reply(SUCCESS, own_params: NULL, keyset with p_pk_own)"]; + * APP<PERIPHERAL [label = "SMP Pairing Public Key: PKa", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing Public Key: PKb", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_LESC_DHKEY_REQUEST {p_peer_pk, oobd_req=1}"]; + * |||; + * APP abox APP [label="App starts DHKey calculation"]; + * |||; + * APP=>SD [label = "sd_ble_gap_lesc_oob_data_set(p_oobd_own, p_oobd_peer)"]; + * APP<SD [label = "sd_ble_gap_lesc_dhkey_reply(p_dhkey)"]; + * APP<PERIPHERAL [label = "SMP Pairing DHKey Check: Ea", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERAL [label = "SMP Pairing DHKey Check: Eb", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP rbox PERIPHERAL [label = "Encrypted with LTK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {LESC_ENC_MITM}"]; + * |||; + * SD abox PERIPHERAL [label="SMP Pairing Phase 3", textbgcolor="#7f7fff"]; + * |||; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {SUCCESS}"]; + * APP rbox APP [label = "Keys stored in keyset"]; + * @endmsc + * @} + * + * @defgroup BLE_GAP_CENTRAL_INVALID_SMP_PDU_MSC Unexpected Security Packet Reception + * @msc + * hscale = "1.5"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * APP rbox PEER [label="No pairing in progress"]; + * |||; + * PEER rbox PEER [label="Peer misbehaving"]; + * |||; + * SD<:PEER [label = "SMP Pairing Failed (or other unexpected SMP PDU)", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_AUTH_STATUS {PDU_INVALID}"]; + * |||; + * @endmsc + * + * @defgroup BLE_GAP_CENTRAL_ENC_MSC Encryption Establishment using stored keys + * @msc + * hscale = "1.5"; + * APP,SD,PERIPHERAL; + * |||; + * APP rbox PERIPHERAL [label="Connection Established"]; + * |||; + * APP=>SD [label = "sd_ble_gap_encrypt(ediv, rand, LTK)"]; + * APP<PERIPHERAL [label = "LL Encryption Request (LL_ENC_REQ)", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #1 Peripheral replies with keys "]; + * |||; + * PERIPHERAL rbox PERIPHERAL [label = "Peripheral Loads Keys"]; + * SD<:PERIPHERAL [label = "LL Encryption Response (LL_ENC_RSP)", textcolor="#000080", linecolor="#000080"]; + * APP rbox PERIPHERAL [label = "Encrypted with LTK"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE"]; + * |||; + * --- [label = " Variant #2 Peripheral keys missing "]; + * |||; + * PERIPHERAL rbox PERIPHERAL [label = "Peripheral Keys Missing"]; + * SD<:PERIPHERAL [label = "LL Reject Ind (LL_REJECT_IND): Pin or Key Missing", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE"]; + * APP rbox PERIPHERAL [label = "Link is NOT encrypted"]; + * |||; + * --- [label = " Variant #3 Incorrect peripheral keys "]; + * |||; + * PERIPHERAL rbox PERIPHERAL [label = "Peripheral Loads Incorrect Keys"]; + * SD<:PERIPHERAL [label = "LL Encryption Response (LL_ENC_RSP)", textcolor="#000080", linecolor="#000080"]; + * APP rbox PERIPHERAL [label = "Link Terminated due to authentication error"]; + * APP<<=SD [label = "BLE_GAP_EVT_DISCONNECTED {MIC Failure}"]; + * |||; + * @endmsc + * + * @defgroup BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC Central Encryption and Authentication mutual exclusion + * @msc + * hscale = "1.5"; + * APP,SD,PEER; + * |||; + * APP=>SD [label = "sd_ble_gap_encrypt(ediv, rand, LTK)"]; + * APP<PEER [label = "Encryption Start (LL_START_ENC_REQ)", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP note SD [label = " Encryption in progress, authentication disallowed"]; + * |||; + * APP=>SD [label = "sd_ble_gap_authenticate()"]; + * APP<SD [label = "sd_ble_gap_conn_param_update()"]; + * APP<PEER [label = "Connection Update Start (LL_CONNECTION_UPDATE_IND)", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP=>SD [label = "sd_ble_gap_encrypt(ediv, rand, LTK)"]; + * APP<SD [label = "sd_ble_gap_authenticate()"]; + * APP<PEER [label = "Encryption Start (LL_START_ENC_REQ)", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "Encryption Complete (LL_START_ENC_RSP)", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE "]; + * |||; + * APP=>SD [label = "sd_ble_gap_authenticate()"]; + * APP<SD [label = "sd_ble_gap_encrypt(ediv, rand, LTK)"]; + * APP<SD [label = "sd_ble_gap_conn_param_update(conn_handle_3, CP#3)"]; + * APP<PERIPHERALS [label = "Connection Update Start on link #3 (LL_CONNECTION_UPDATE_IND)", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP=>SD [label = "sd_ble_gap_conn_param_update(conn_handle_1, CP#1)"]; + * APP<SD [label = "sd_ble_gap_conn_param_update(conn_handle_2, CP#2)"]; + * APP<PERIPHERALS [label = "L2CAP Connection Parameter Update Response: Accepted", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP note PERIPHERALS [label = " Additional procedure on link #2 fails, since another one is pending"]; + * |||; + * APP=>SD [label = "sd_ble_gap_conn_param_update(conn_handle_2, CP#5)"]; + * APP<PERIPHERALS [label = "Connection Update Start on link #1 (LL_CONNECTION_UPDATE_IND)", textcolor="#000080", linecolor="#000080"]; + * SD<:PERIPHERALS [label = "Connection Update Complete on link #1", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {conn_handle_1, CP#1}"]; + * |||; + * SD:>PERIPHERALS [label = "Connection Update Start on link #2 (LL_CONNECTION_UPDATE_IND)", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP note PERIPHERALS [label = " Peripheral solicited procedure on link #4"]; + * |||; + * SD<:PERIPHERALS [label = "L2CAP Connection Parameter Update Request {CP#4}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST {conn_handle_4, CP#4}"]; + * |||; + * APP=>SD [label = "sd_ble_gap_conn_param_update(conn_handle_4, CP#4)"]; + * APP<PERIPHERALS [label = "L2CAP Connection Parameter Update Response: Accepted", textcolor="#000080", linecolor="#000080"]; + * |||; + * SD<:PERIPHERALS [label = "Connection Update Complete on link #2", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {conn_handle_2, CP#2}"]; + * |||; + * SD:>PERIPHERALS [label = "Connection Update Start on link #4 (LL_CONNECTION_UPDATE_IND)", textcolor="#000080", linecolor="#000080"]; + * SD<:PERIPHERALS [label = "Connection Update Complete on link #4", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {conn_handle_4, CP#4}"]; + * |||; + * @endmsc + * + * @defgroup BLE_GAP_MULTILINK_CTRL_PROC_MSC Central Control Procedure Serialization on multiple links + * @msc + * hscale = "1.5"; + * APP,SD,PERIPHERALS; + * |||; + * APP rbox PERIPHERALS [label="Connection Established with 4 peers, all with conn. params. CP#0"]; + * |||; + * APP note PERIPHERALS [label = " Peripheral solicited procedure on link #2"]; + * |||; + * SD<:PERIPHERALS [label = "L2CAP Connection Parameter Update Request {CP#2}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST {conn_handle_2, CP#3}"]; + * |||; + * APP note PERIPHERALS [label = " Encryption procedure on link #3"]; + * |||; + * APP=>SD [label = "sd_ble_gap_encrypt(conn_handle_3, LTK#3)"]; + * APP<PERIPHERALS [label = "Encryption Start (LL_START_ENC_REQ) on link #3", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP note PERIPHERALS [label = " Connection Update procedure on link #1"]; + * |||; + * APP=>SD [label = "sd_ble_gap_conn_param_update(conn_handle_1, CP#1)"]; + * APP<SD [label = "sd_ble_gap_conn_param_update(conn_handle_2, CP#2)"]; + * APP<PERIPHERALS [label = "L2CAP Connection Parameter Update Response: Accepted", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP note PERIPHERALS [label = " Encryption procedure on link #4"]; + * |||; + * APP=>SD [label = "sd_ble_gap_encrypt(conn_handle_4, LTK#4)"]; + * APP<PERIPHERALS [label = "Encryption Start (LL_START_ENC_REQ) on link #4", textcolor="#000080", linecolor="#000080"]; + * SD<:PERIPHERALS [label = "Encryption Complete (LL_START_ENC_RSP) on link #4", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_SEC_UPDATE {conn_handle_4}"]; + * |||; + * SD:>PERIPHERALS [label = "Connection Update Start (LL_CONNECTION_UPDATE_IND) on link #1", textcolor="#000080", linecolor="#000080"]; + * SD<:PERIPHERALS [label = "Connection Update Complete on link #1", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {conn_handle_1, CP#1}"]; + * |||; + * SD:>PERIPHERALS [label = "Connection Update Start (LL_CONNECTION_UPDATE_IND on link #2", textcolor="#000080", linecolor="#000080"]; + * SD<:PERIPHERALS [label = "Connection Update Complete on link #2", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONN_PARAM_UPDATE {conn_handle_2, CP#2}"]; + * |||; + * @endmsc + * + * @defgroup BLE_GAP_WL_SHARE_MSC Whitelist Sharing + * @msc + * hscale = "1.5"; + * APP,SD; + * |||; + * APP=>SD [label = "sd_ble_gap_adv_set_configure(&adv_handle, adv_data, params: { fp = CONNREQ })"]; + * APP<SD [label = "sd_ble_gap_whitelist_set(WL#1)"]; + * APP<SD [label = "sd_ble_gap_adv_start(adv_handle)"]; + * APP<SD [label = "sd_ble_gap_whitelist_set(WL#2)"]; + * APP<SD [label = "sd_ble_gap_scan_start(use_whitelist = 1, adv_report_buffer)"]; + * APP<SD [label = "sd_ble_gap_adv_stop(adv_handle)"]; + * APP<SD [label = "sd_ble_gap_scan_stop()"]; + * APP<SD [label = "sd_ble_gap_whitelist_set(WL#2)"]; + * APP<SD [label = "sd_ble_gap_scan_start(use_whitelist = 1, adv_report_buffer)"]; + * APP<SD [label = "sd_ble_gap_connect(use_whitelist = 1)"]; + * APP<SD [label = "sd_ble_gap_addr_set(addr)"]; + * APP<SD [label = "sd_ble_gap_adv_set_configure(&adv_handle, adv_data, params: {p_peer_addr = NULL})"]; + * APP<SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: RESOLVABLE } "]; + * APP<SD [label = "sd_ble_gap_adv_start(adv_handle)"]; + * APP<SCANNERS [label = "Advertisement (ADV_*_IND), Addr = Resolvable1", textcolor="#000080", linecolor="#000080"]; + * SD->SCANNERS [label = "Advertisement (ADV_*_IND), Addr = Resolvable1", textcolor="#000080", linecolor="#000080"]; + * SD->SCANNERS [label = "Advertisement (ADV_*_IND), Addr = Resolvable1", textcolor="#000080", linecolor="#000080"]; + * ...; + * SD box SD [label="Private address timeout"]; + * SD->SCANNERS [label = "Advertisement (ADV_*_IND), Addr = Resolvable2", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #2 Advertise with address resolvable by local IRK in device identity list "]; + * |||; + * APP=>SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: RESOLVABLE } "]; + * APP<SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: {{peer_addr1, peer_irk1}}, pp_local_irks: {local_irk1}) "]; + * APP<SD [label = "sd_ble_gap_adv_set_configure(&adv_handle, adv_data, params: {p_peer_addr = peer_addr1})"]; + * APP<SD [label = "sd_ble_gap_adv_start(adv_handle)"]; + * APP<SCANNERS [label = "Advertisement (ADV_*_IND), Addr = Resolvable1", textcolor="#000080", linecolor="#000080"]; + * SD->SCANNERS [label = "Advertisement (ADV_*_IND), Addr = Resolvable1", textcolor="#000080", linecolor="#000080"]; + * SD->SCANNERS [label = "Advertisement (ADV_*_IND), Addr = Resolvable1", textcolor="#000080", linecolor="#000080"]; + * ...; + * SD box SD [label="Private address timeout"]; + * SD->SCANNERS [label = "Advertisement (ADV_*_IND), Addr = Resolvable2", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #3 Advertise with non-resolvable address "]; + * |||; + * APP=>SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: NON_RESOLVABLE } "]; + * APP<SD [label = "sd_ble_gap_adv_set_configure(&adv_handle, adv_data, params: {p_peer_addr = NULL})"]; + * APP<SD [label = "sd_ble_gap_adv_start(adv_handle)"]; + * APP<SCANNERS [label = "Advertisement (ADV_*_IND), Addr = Non-Resolvable1", textcolor="#000080", linecolor="#000080"]; + * SD->SCANNERS [label = "Advertisement (ADV_*_IND), Addr = Non-Resolvable1", textcolor="#000080", linecolor="#000080"]; + * SD->SCANNERS [label = "Advertisement (ADV_*_IND), Addr = Non-Resolvable1", textcolor="#000080", linecolor="#000080"]; + * ...; + * SD box SD [label="Private address timeout"]; + * SD->SCANNERS [label = "Advertisement (ADV_*_IND), Addr = Non-Resolvable2", textcolor="#000080", linecolor="#000080"]; + * @endmsc + * + * @defgroup BLE_GAP_PRIVACY_SCAN_MSC Private Scanning + * @msc + * hscale = "1.5"; + * APP,SD,ADVERTISERS; + * |||; + * APP=>SD [label = "sd_ble_gap_addr_set(addr)"]; + * APP<SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: RESOLVABLE } "]; + * APP<SD [label = "sd_ble_gap_scan_start(params, adv_report_buffer)"]; + * APP<SD [label = "Advertisement (ADV_IND/ADV_SCAN_IND)", textcolor="#000080", linecolor="#000080"]; + * SD->ADVERTISERS [label = "Scan Request packet (SCAN_REQ), Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; + * ADVERTISERS->SD [label = "Scan Response packet (SCAN_RSP)", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #2 Active Scan with address resolvable by local IRKs "]; + * |||; + * APP=>SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: RESOLVABLE } "]; + * APP<SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: {{peer_addr1, peer_irk1}, {peer_addr2, peer_irk2}}, pp_local_irks: {local_irk1, local_irk2}) "]; + * APP<SD [label = "sd_ble_gap_scan_start(params, adv_report_buffer)"]; + * APP<SD [label = "Advertisement (ADV_IND/ADV_SCAN_IND), Addr = peer_addr1", textcolor="#000080", linecolor="#000080"]; + * SD box ADVERTISERS [label = "peer_addr1 is in the device identity list, respond with an address generated from local_irk1"]; + * SD->ADVERTISERS [label = "Scan Request packet (SCAN_REQ), Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; + * ADVERTISERS->SD [label = "Scan Response packet (SCAN_RSP), Addr = peer_addr1", textcolor="#000080", linecolor="#000080"]; + * |||; + * ...; + * ADVERTISERS->SD [label = "Advertisement (ADV_IND/ADV_SCAN_IND), Addr = Resolvable2", textcolor="#000080", linecolor="#000080"]; + * SD box ADVERTISERS [label = "Resolvable2 resolved to device identity peer_addr2 in the device identity list, respond with an address generated from local_irk2"]; + * SD->ADVERTISERS [label = "Scan Request packet (SCAN_REQ), Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; + * ADVERTISERS->SD [label = "Scan Response packet (SCAN_RSP), Addr = peer_addr1", textcolor="#000080", linecolor="#000080"]; + * |||; + * ...; + * ADVERTISERS->SD [label = "Advertisement (ADV_IND/ADV_SCAN_IND), Addr = peer_addr3", textcolor="#000080", linecolor="#000080"]; + * SD box ADVERTISERS [label = "peer_addr3 is not in the device identity list, respond with an address generated from device_irk"]; + * SD->ADVERTISERS [label = "Scan Request packet (SCAN_REQ), Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; + * ADVERTISERS->SD [label = "Scan Response packet (SCAN_RSP), Addr = peer_addr1", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #3 Active Scan with non-resolvable address "]; + * |||; + * APP=>SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: NON_RESOLVABLE } "]; + * APP<SD [label = "sd_ble_gap_scan_start(params, adv_report_buffer)"]; + * APP<SD [label = "Advertisement (ADV_IND/ADV_SCAN_IND)", textcolor="#000080", linecolor="#000080"]; + * SD->ADVERTISERS [label = "Scan Request packet (SCAN_REQ), Addr = Non-Resolvable", textcolor="#000080", linecolor="#000080"]; + * ADVERTISERS->SD [label = "Scan Response packet (SCAN_REQ)", textcolor="#000080", linecolor="#000080"]; + * |||; + * @endmsc + * + * @defgroup BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC Scan Private Devices + * @msc + * hscale = "1.5"; + * APP,SD,ADVERTISERS; + * |||; + * APP=>SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: (Undefined, Undefined), pp_local_irks: NULL) "]; + * APP<SD [label = "sd_ble_gap_scan_start(params, adv_report_buffer)"]; + * APP<SD [label = "Advertisement (ADV_*_IND), Addr = Resolvable1", textcolor="#000080", linecolor="#000080"]; + * SD note ADVERTISERS [label="Resolvable1 resolved to device identity peer_addr1"]; + * APP<<=SD [label = "BLE_GAP_EVT_ADV_REPORT {peer_addr1, rssi, data}"]; + * APP=>SD [label = "sd_ble_gap_scan_start(params = NULL, adv_report_buffer)"]; + * APP<SD [label = "Advertisement (ADV_*_IND), Addr = peer_addr2", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_ADV_REPORT {peer_addr2, rssi, data}"]; + * |||; + * --- [label = " Variant #2 Scan and resolve private devices with whitelist "]; + * |||; + * APP=>SD [label = "sd_ble_gap_whitelist_set({peer_addr1, Resolvable2}) "]; + * APP<SD [label = "sd_ble_gap_scan_start(params, adv_report_buffer)"]; + * APP<SD [label = "Advertisement (ADV_*_IND), Addr = Resolvable1", textcolor="#000080", linecolor="#000080"]; + * SD note ADVERTISERS [label="Resolvable1 resolved to device identity peer_addr1 which is in the whitelist"]; + * APP<<=SD [label = "BLE_GAP_EVT_ADV_REPORT {peer_addr1, rssi, data}"]; + * APP=>SD [label = "sd_ble_gap_scan_start(params = NULL, adv_report_buffer)"]; + * APP<SD [label = "Advertisement (ADV_*_IND), Addr = Resolvable2", textcolor="#000080", linecolor="#000080"]; + * SD note ADVERTISERS [label="Resolvable2 did not resolve to a device identity but is in the whitelist"]; + * APP<<=SD [label = "BLE_GAP_EVT_ADV_REPORT {Resolvable2, rssi, data}"]; + * APP=>SD [label = "sd_ble_gap_scan_start(params = NULL, adv_report_buffer)"]; + * APP<SD [label = "Advertisement (ADV_*_IND), Addr = Resolvable3", textcolor="#000080", linecolor="#000080"]; + * SD note ADVERTISERS [label="Resolvable3 is not in the whitelist, no report generated"]; + * |||; + * --- [label = " Variant #3 Scan directed advertisers and resolve initiator address using device IRK"]; + * |||; + * APP=>SD [label = "sd_ble_gap_scan_start(params, adv_report_buffer)"]; + * APP<SD [label = "Advertisement (ADV_*_IND), Advertiser Addr = Resolvable, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; + * ADVERTISERS box SD [label = "Advertiser Address resolved using peer_irk1, Initiator address resolved using device_irk"]; + * APP<<=SD [label = "BLE_GAP_EVT_ADV_REPORT {peer_addr: peer_addr1"]; + * |||; + * --- [label = " Variant #4 Scan directed advertisers and resolve initiator address using local IRK in device identity list"]; + * |||; + * APP=>SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: (Undefined, Undefined), pp_local_irks: local_irk1) "]; + * APP<SD [label = "sd_ble_gap_scan_start(params, adv_report_buffer)"]; + * APP<SD [label = "Advertisement (ADV_*_IND), Advertiser Addr = Resolvable, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; + * ADVERTISERS box SD [label = "Advertiser Address resolved using peer_irk1, Initiator address resolved using local_irk1"]; + * APP<<=SD [label = "BLE_GAP_EVT_ADV_REPORT {peer_addr: peer_addr1"]; + * |||; + * --- [label = " Variant #5 Scan directed advertisers with unresolved direct address "]; + * |||; + * APP=>SD [label = "sd_ble_gap_scan_start(params: {adv_dir_report = 1}, adv_report)"]; + * APP<SD [label = "Advertisement (ADV_*_IND), Advertiser Addr = peer_addr2, Initiator Addr = Resolvable2", textcolor="#000080", linecolor="#000080"]; + * ADVERTISERS box SD [label = "Resolvable2 could not be resolved, report the unresolved direct address"]; + * APP<<=SD [label = "BLE_GAP_EVT_ADV_REPORT {peer_addr: peer_addr2, direct_addr: Resolvable2}"]; + * |||; + * @endmsc + * + * @defgroup BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC Directed Advertising + * @msc + * hscale = "1.5"; + * APP,SD,INITIATOR; + * |||; + * APP=>SD [label = "sd_ble_gap_addr_set(addr)"]; + * APP<SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: (Undefined, Undefined), pp_local_irks: NULL) "]; + * APP<SD [label = "sd_ble_gap_adv_set_configure(&adv_handle, adv_data, params: {p_peer_addr = peer_addr1, properties.type = directed})"]; + * APP<SD [label = "sd_ble_gap_adv_start(adv_handle)"]; + * APP<INITIATOR[label = "Advertisement (ADV_DIRECT_IND) , Advertiser Addr = addr, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; + * SD->INITIATOR[label = "Advertisement (ADV_DIRECT_IND), Advertiser Addr = addr, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; + * SD->INITIATOR[label = "Advertisement (ADV_DIRECT_IND), Advertiser Addr = addr, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #2 Private directed advertising to private peer using device IRK"]; + * |||; + * APP=>SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: (Undefined, Undefined), pp_local_irks: NULL) "]; + * APP<SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: RESOLVABLE } "]; + * APP<SD [label = "sd_ble_gap_adv_set_configure(&adv_handle, adv_data, params: {p_peer_addr = peer_addr1, properties.type = directed})"]; + * APP<SD [label = "sd_ble_gap_adv_start(adv_handle)"]; + * APP<INITIATOR[label = "Advertisement (ADV_DIRECT_IND), Advertiser Addr = Resolvable, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; + * SD->INITIATOR[label = "Advertisement (ADV_DIRECT_IND), Advertiser Addr = Resolvable, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; + * SD->INITIATOR[label = "Advertisement (ADV_DIRECT_IND), Advertiser Addr = Resolvable, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #3 Private directed advertising to private peer using local IRK in device identity list"]; + * |||; + * APP=>SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: (Undefined, Undefined), pp_local_irks: ) "]; + * APP<SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: RESOLVABLE } "]; + * APP<SD [label = "sd_ble_gap_adv_set_configure(&adv_handle, adv_data, params: {p_peer_addr = peer_addr1, properties.type = directed})"]; + * APP<SD [label = "sd_ble_gap_adv_start(adv_handle)"]; + * APP<INITIATOR[label = "Advertisement (ADV_DIRECT_IND), Advertiser Addr = Resolvable, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; + * SD->INITIATOR[label = "Advertisement (ADV_DIRECT_IND), Advertiser Addr = Resolvable, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; + * SD->INITIATOR[label = "Advertisement (ADV_DIRECT_IND), Advertiser Addr = Resolvable, Initiator Addr = Resolvable", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #4 Private directed advertising to non-private peer using local IRK in device identity list"]; + * |||; + + * APP=>SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: {{peer_addr1, peer_irk=0..0}}, pp_local_irks: {{local_irk1}}) "]; + * APP<SD [label = "sd_ble_gap_privacy_set(params: {mode: DEVICE_PRIVACY, private_addr_type: RESOLVABLE } "]; + * APP<SD [label = "sd_ble_gap_adv_set_configure(&adv_handle, adv_data, params: {p_peer_addr = peer_addr1, properties.type = directed})"]; + * APP<SD [label = "sd_ble_gap_adv_start(adv_handle})"]; + * APP<INITIATOR[label = "Advertisement (ADV_DIRECT_IND), Advertiser Addr = Resolvable, Initiator Addr = peer_addr1", textcolor="#000080", linecolor="#000080"]; + * SD->INITIATOR[label = "Advertisement (ADV_DIRECT_IND), Advertiser Addr = Resolvable, Initiator Addr = peer_addr1", textcolor="#000080", linecolor="#000080"]; + * SD->INITIATOR[label = "Advertisement (ADV_DIRECT_IND), Advertiser Addr = Resolvable, Initiator Addr = peer_addr1", textcolor="#000080", linecolor="#000080"]; + * |||; + * @endmsc + * + * @defgroup BLE_GAP_PERIPH_CONN_PRIV_MSC Peripheral Connection Establishment with Private Peer + * @msc + * hscale = "1.5"; + * APP,SD,CENTRAL; + * |||; + * APP=>SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: (Undefined, Undefined), pp_local_irks: NULL) "]; + * APP<CENTRAL [label = "Connection Establishment", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONNECTED, peer_addr = {peer_addr1, addr_id_peer = 1}"]; + * |||; + * --- [label = " Variant #2 Peer used identity address during connection setup "]; + * |||; + * APP rbox CENTRAL [label="Start Connectable Advertising"]; + * |||; + * SD<:>CENTRAL [label = "Connection Establishment", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONNECTED, peer_addr = {peer_addr1, addr_id_peer = 0}"]; + * |||; + * @endmsc + * + * @defgroup BLE_GAP_CENTRAL_CONN_PRIV_MSC Central Connection Establishment with Private Peer + * @msc + * hscale = "1.5"; + * APP,SD,PERIPHERAL; + * |||; + * APP=>SD [label = "sd_ble_gap_device_identities_set(pp_id_keys: (Undefined, Undefined), pp_local_irks: NULL) "]; + * APP<SD [label = "sd_ble_gap_connect(peer_addr = {peer_addr1, addr_id_peer = 1})"]; + * APP<PERIPHERAL [label = "Scanning", textcolor="#000080", linecolor="#000080"]; + * --- [label = " Variant #1 Peer used resolvable addresses during connection setup "]; + * |||; + * SD<:>PERIPHERAL [label = "Connection Establishment", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONNECTED, peer_addr = {peer_addr1, addr_id_peer = 1}"]; + * |||; + * --- [label = " Variant #2 Peer used identity address during connection setup "]; + * |||; + * SD<:>PERIPHERAL [label = "Connection Establishment", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_CONNECTED, peer_addr = {peer_addr1, addr_id_peer = 0}"]; + * |||; + * @endmsc + * + * @} + * + * @defgroup BLE_GAP_EVT_PHY_MSC PHY Update Procedure + * @{ + * + * @defgroup BLE_GAP_CENTRAL_PHY_UPDATE Central PHY Update + * @msc + * hscale = "1.5"; + * APP,SD,PERIPHERAL; + * |||; + * APP rbox PERIPHERAL [label="Connection Established. Current TX PHY and RX PHY are both 1Mbit"]; + * |||; + * --- [label = " Variant #1 Initiated by Peripheral - no change in PHY "]; + * SD<=PERIPHERAL [label = "PHY Request (LL_PHY_REQ) {tx_phys=2Mbit, rx_phys=2Mbit}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE_REQUEST {peer_preferred_phys={tx_phys=2Mbit, rx_phys=2Mbit}}"]; + * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {tx_phys=1Mbit, rx_phys=1Mbit})"]; + * APP<PERIPHERAL [label = "PHY Update (LL_PHY_UPDATE_IND) - No change", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE {status=Success, {tx_phy=1Mbit, rx_phy=1Mbit}}"]; + * |||; + * --- [label = " Variant #2 Initiated by Peripheral - change of PHY required"]; + * SD<=PERIPHERAL [label = "PHY Request (LL_PHY_REQ) {tx_phys=2Mbit, rx_phys=2Mbit}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE_REQUEST {peer_preferred_phys={tx_phys=2Mbit, rx_phys=2Mbit}}"]; + * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {tx_phys=2Mbit, rx_phys=2Mbit})"]; + * APP<PERIPHERAL [label = "PHY Update (LL_PHY_UPDATE_IND) {M_TO_S_PHY=2Mbit, S_TO_M_PHY=2Mbit}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE {status=Success, {tx_phy=2Mbit, rx_phy=2Mbit}}"]; + * |||; + * --- [label = " Variant #3 Initiated by APP, not supported by peer"]; + * |||; + * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {ALL_PHY, ALL_PHY}) "]; + * APP<PERIPHERAL [label="PHY Request (LL_PHY_REQ)", textcolor="#000080", linecolor="#000080"]; + * SD<=PERIPHERAL [label="Unknown Response (LL_UNKNOWN_RSP)", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label="BLE_GAP_EVT_PHY_UPDATE {Status=Not Supported}"]; + * |||; + * --- [label = " Variant #4 Initiated by APP, change required"]; + * |||; + * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {ALL_PHY, ALL_PHY}) "]; + * APP<PERIPHERAL [label = "PHY Request (LL_PHY_REQ) {ALL_PHY, ALL_PHY}", textcolor="#000080", linecolor="#000080"]; + * SD<=PERIPHERAL [label = "PHY Response (LL_PHY_RSP) {ALL_PHY, ALL_PHY}", textcolor="#000080", linecolor="#000080"]; + * SD=>PERIPHERAL [label = "PHY Update (LL_PHY_UPDATE_IND) {M_TO_S_PHY=2Mbit, S_TO_M_PHY=2Mbit}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE {status=Success, {tx_phy=2Mbit, rx_phy=2Mbit}}"]; + * |||; + * --- [label = " Variant #5 Initiated by Peripheral - APP has no preferences for TX direction"]; + * SD<=PERIPHERAL [label = "PHY Request (LL_PHY_REQ) {tx_phys=2Mbit, rx_phys=1Mbit}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE_REQUEST {peer_preferred_phys={tx_phys=2Mbit, rx_phys=1Mbit}}"]; + * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {tx_phys=BLE_GAP_PHY_AUTO, rx_phys=2Mbit})"]; + * APP<PERIPHERAL [label = "PHY Update (LL_PHY_UPDATE_IND) {M_TO_S_PHY=1Mbit, S_TO_M_PHY=2Mbit}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE {status=Success, {tx_phy=1Mbit, rx_phy=2Mbit}}"]; + * |||; + * --- [label = " Variant #6 Initiated by APP, peer responding with invalid parameters"]; + * |||; + * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {ALL_PHY, ALL_PHY}) "]; + * APP<PERIPHERAL [label="PHY Request (LL_PHY_REQ) {ALL_PHY, ALL_PHY}", textcolor="#000080", linecolor="#000080"]; + * SD<=PERIPHERAL [label="PHY Response (LL_PHY_RSP) {tx_phys=0x00, rx_phys=0x00}", textcolor="#000080", linecolor="#000080"]; + * SD=>PERIPHERAL [label="Unknown Response (LL_UNKNOWN_RSP)", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label="BLE_GAP_EVT_PHY_UPDATE {Status=Invalid LMP Parameters}"]; + * |||; + * @endmsc + * + * @defgroup BLE_GAP_PERIPHERAL_PHY_UPDATE Peripheral PHY Update + * @msc + * hscale = "1.5"; + * APP,SD,CENTRAL; + * |||; + * APP rbox CENTRAL [label="Connection Established. Current TX PHY and RX PHY are both 1Mbit"]; + * |||; + * --- [label = " Variant #1 Initiated by Central - no change in PHY "]; + * SD<=CENTRAL [label = "PHY Request (LL_PHY_REQ) {tx_phys=2Mbit, rx_phys=2Mbit}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE_REQUEST {peer_preferred_phys={tx_phys=2Mbit, rx_phys=2Mbit}}"]; + * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {tx_phys=1Mbit, rx_phys=1Mbit})"]; + * APP<CENTRAL [label = "PHY Response (LL_PHY_RSP) {tx_phys=1Mbit, rx_phys=1Mbit}", textcolor="#000080", linecolor="#000080"]; + * SD<=CENTRAL [label = "PHY Update (LL_PHY_UPDATE_IND) - No change", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE {status=Success, {tx_phy=1Mbit, rx_phy=1Mbit}}"]; + * |||; + * --- [label = " Variant #2 Initiated by Central - change of PHY required"]; + * SD<=CENTRAL [label = "PHY Request (LL_PHY_REQ) {tx_phys=2Mbit, rx_phys=2Mbit}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE_REQUEST {peer_preferred_phys={tx_phys=2Mbit, rx_phys=2Mbit}}"]; + * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {tx_phys=2Mbit, rx_phys=2Mbit})"]; + * APP<CENTRAL [label = "PHY Response (LL_PHY_RSP) {tx_phys=2Mbit, rx_phys=2Mbit}", textcolor="#000080", linecolor="#000080"]; + * SD<=CENTRAL [label = "PHY Update (LL_PHY_UPDATE_IND) {M_TO_S_PHY=2Mbit, S_TO_M_PHY=2Mbit}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE {status=Success, {tx_phy=2Mbit, rx_phy=2Mbit}}"]; + * |||; + * --- [label = " Variant #3 Initiated by APP, not supported by peer"]; + * |||; + * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {ALL_PHY, ALL_PHY}) "]; + * APP<CENTRAL [label="PHY Request (LL_PHY_REQ)", textcolor="#000080", linecolor="#000080"]; + * SD<=CENTRAL [label="Unknown Response (LL_UNKNOWN_RSP)", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label="BLE_GAP_EVT_PHY_UPDATE {Status=Not Supported}"]; + * |||; + * --- [label = " Variant #4 Initiated by APP, change required"]; + * |||; + * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {ALL_PHY, ALL_PHY}) "]; + * APP<CENTRAL [label="PHY Request (LL_PHY_REQ) {ALL_PHY, ALL_PHY}", textcolor="#000080", linecolor="#000080"]; + * SD<=CENTRAL [label="PHY Update (LL_PHY_UPDATE_IND) {M_TO_S_PHY=2Mbit, S_TO_M_PHY=2Mbit}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label="BLE_GAP_EVT_PHY_UPDATE {status=Success, {tx_phy=2Mbit, rx_phy=2Mbit}}"]; + * |||; + * --- [label = " Variant #5 Initiated by Central - APP has no preferences for TX direction"]; + * SD<=CENTRAL [label = "PHY Request (LL_PHY_REQ) {tx_phys=2Mbit, rx_phys=1Mbit}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE_REQUEST {peer_preferred_phys={tx_phys=2Mbit, rx_phys=1Mbit}}"]; + * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {tx_phys=BLE_GAP_PHY_AUTO, rx_phys=2Mbit})"]; + * APP<CENTRAL [label = "PHY Response (LL_PHY_RSP) {tx_phys=ALL_PHY, rx_phys=2Mbit}", textcolor="#000080", linecolor="#000080"]; + * SD<=CENTRAL [label = "PHY Update (LL_PHY_UPDATE_IND) {M_TO_S_PHY=2Mbit, S_TO_M_PHY=1Mbit}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE {status=Success, {tx_phy=1Mbit, rx_phy=2Mbit}}"]; + * |||; + * --- [label = " Variant #6 Collision between self-initiated PHY Update and peer initiated Channel Map Update procedures"]; + * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {tx_phys=2Mbit, rx_phys=2Mbit})"]; + * APP<CENTRAL [label = "PHY Request (LL_PHY_REQ) {tx_phys=2Mbit, rx_phys=2Mbit}", textcolor="#000080", linecolor="#000080"]; + * SD<=CENTRAL [label = "Reject Command (LL_REJECT_EXT_IND) {ErrorCode=Different Transaction Collision}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_PHY_UPDATE {status=Different Transaction Collision, {tx_phy=1Mbit, rx_phy=1Mbit}}"]; + * |||; + * --- [label = " Variant #7 Initiated by APP, peer responding with invalid parameters"]; + * |||; + * APP=>SD [label = "sd_ble_gap_phy_update(conn_handle, {ALL_PHY, ALL_PHY}) "]; + * APP<CENTRAL [label="PHY Request (LL_PHY_REQ) {ALL_PHY, ALL_PHY}", textcolor="#000080", linecolor="#000080"]; + * SD<=CENTRAL [label="PHY Update (LL_PHY_UPDATE_IND) {M_TO_S_PHY=(1Mbit|2Mbit), S_TO_M_PHY=(1Mbit|2Mbit)", textcolor="#000080", linecolor="#000080"]; + * SD=>CENTRAL [label="Unknown Response (LL_UNKNOWN_RSP)", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label="BLE_GAP_EVT_PHY_UPDATE {Status=Invalid LMP Parameters}"]; + * |||; + * @endmsc + * + * @} + + * @defgroup BLE_GAP_DATA_LENGTH_UPDATE_PROCEDURE_MSC Data Length Update Procedure + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * --- [label = " Self initiated, automatic parameters "]; + * |||; + * SD rbox SD [label = "max_tx_octets=27, max_rx_octets=27"]; + * |||; + * ...; + * |||; + * APP=>SD [label = "sd_ble_gap_data_length_update(conn_handle, NULL, NULL)"]; + * APP<PEER [label = "LL Length Request (LL_LENGTH_REQ) {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "LL Length Response (LL_LENGTH_RSP) {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_DATA_LENGTH_UPDATE {.effective_params={.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=2120, .max_rx_time_us=2120}}"]; + * |||; + * ...; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * --- [label = " Self initiated, application set parameters "]; + * |||; + * SD rbox SD [label = "max_tx_octets=27, max_rx_octets=27"]; + * |||; + * ...; + * |||; + * APP=>SD [label = "sd_ble_gap_data_length_update(conn_handle, {.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=BLE_GAP_DATA_LENGTH_AUTO, .max_rx_time_us=BLE_GAP_DATA_LENGTH_AUTO}, NULL)"]; + * APP<PEER [label = "LL Length Request (LL_LENGTH_REQ) {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "LL Length Response (LL_LENGTH_RSP) {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_DATA_LENGTH_UPDATE {.effective_params={.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=2120, .max_rx_time_us=2120}}"]; + * |||; + * ...; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * --- [label = " Peer initiated, automatic parameters "]; + * SD rbox SD [label = "max_tx_octets=27, max_rx_octets=27"]; + * |||; + * ...; + * |||; + * SD<:PEER [label = "LL Length Request (LL_LENGTH_REQ) {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST {.peer_params={.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=2120, .max_rx_time_us=2120}}"]; + * APP=>SD [label = "sd_ble_gap_data_length_update(conn_handle, NULL, NULL)"]; + * APP<PEER [label = "LL Length Response (LL_LENGTH_RSP) {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_DATA_LENGTH_UPDATE {.effective_params={.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=2120, .max_rx_time_us=2120}}"]; + * |||; + * ...; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * --- [label = " Peer initiated, application set parameters"]; + * SD rbox SD [label = "max_tx_octets=27, max_rx_octets=27"]; + * |||; + * ...; + * |||; + * SD<:PEER [label = "LL Length Request (LL_LENGTH_REQ) {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST {.peer_params={.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=2120, .max_rx_time_us=2120}}"]; + * APP=>SD [label = "sd_ble_gap_data_length_update(conn_handle, {.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=BLE_GAP_DATA_LENGTH_AUTO, .max_rx_time_us=BLE_GAP_DATA_LENGTH_AUTO}, NULL)"]; + * APP<PEER [label = "LL Length Response (LL_LENGTH_RSP) {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_DATA_LENGTH_UPDATE {.effective_params={.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=2120, .max_rx_time_us=2120}}"]; + * |||; + * ...; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * --- [label = " Using the limitation out parameter to adjust Link Layer Data Channel PDU size, memory limited "]; + * |||; + * SD rbox SD [label = "max_tx_octets=27, max_rx_octets=27"]; + * |||; + * ...; + * |||; + * APP=>SD [label = "sd_ble_gap_data_length_update(conn_handle, {.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=BLE_GAP_DATA_LENGTH_AUTO, .max_rx_time_us=BLE_GAP_DATA_LENGTH_AUTO}, &limitation)"]; + * APP<SD [label = "sd_ble_gap_data_length_update(conn_handle, {.max_tx_octets=200, .max_rx_octets=200, .max_tx_time_us=BLE_GAP_DATA_LENGTH_AUTO, .max_rx_time_us=BLE_GAP_DATA_LENGTH_AUTO}, &limitation)"]; + * APP<PEER [label = "LL Length Request (LL_LENGTH_REQ) {tx=200, rx=200}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "LL Length Response (LL_LENGTH_RSP) {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_DATA_LENGTH_UPDATE {.effective_params={.max_tx_octets=200, .max_rx_octets=200, .max_tx_time_us=1712, .max_rx_time_us=1712}}"]; + * |||; + * ...; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * --- [label = " Using the limitation out parameter to adjust Link Layer Data Channel PDU size, time limited "]; + * |||; + * SD rbox SD [label = "max_tx_octets=27, max_rx_octets=27"]; + * |||; + * ...; + * |||; + * APP=>SD [label = "sd_ble_gap_data_length_update(conn_handle, {.max_tx_octets=251, .max_rx_octets=251, .max_tx_time_us=BLE_GAP_DATA_LENGTH_AUTO, .max_rx_time_us=BLE_GAP_DATA_LENGTH_AUTO}, &limitation)"]; + * APP<SD [label = "sd_ble_gap_data_length_update(conn_handle, {.max_tx_octets=251-178=73, .max_rx_octets=251-178=73, .max_tx_time_us=BLE_GAP_DATA_LENGTH_AUTO, .max_rx_time_us=BLE_GAP_DATA_LENGTH_AUTO}, &limitation)"]; + * APP<PEER [label = "LL Length Request (LL_LENGTH_REQ) {tx=73, rx=73}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "LL Length Response (LL_LENGTH_RSP) {tx=251, rx=251}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GAP_EVT_DATA_LENGTH_UPDATE {.effective_params={.max_tx_octets=73, .max_rx_octets=73, .max_tx_time_us=696, .max_rx_time_us=696}}"]; + * @endmsc + * @} + * + * @} + * @} + */ + +/** + * @addtogroup BLE_GATTC + * @{ + * @defgroup BLE_GATTC_MSC Message Sequence Charts + * @{ + * @defgroup BLE_GATTC_PRIM_SRVC_DISC_MSC GATTC Primary Service Discovery + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * --- [label = " Variant #1 Discover All Services "]; + * |||; + * APP=>SD [label = "sd_ble_gattc_primary_services_discover(handle, NULL)"]; + * APP<PEER [label = "ATT Read By Group Type Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Read By Group Type Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP {SUCCESS, services}"]; + * APP=>SD [label = "sd_ble_gattc_primary_services_discover(handle + N, NULL)"]; + * APP<PEER [label = "ATT Read By Group Type Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Read By Group Type Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP {SUCCESS, services}"]; + * APP=>SD [label = "sd_ble_gattc_primary_services_discover(handle + N + M, NULL)"]; + * APP<PEER [label = "ATT Read By Group Type Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Error Response: Attribute Not Found", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP {ATTRIBUTE_NOT_FOUND}"]; + * |||; + * --- [label = " Variant #2 Discover a Specific Service "]; + * |||; + * APP=>SD [label = "sd_ble_gattc_primary_services_discover(handle, uuid)"]; + * APP<PEER [label = "ATT Find By Type Value Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Find By Type Value Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP {SUCCESS, services}"]; + * APP=>SD [label = "sd_ble_gattc_primary_services_discover(handle + N, uuid)"]; + * APP<PEER [label = "ATT Find By Type Value Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Find By Type Value Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP {SUCCESS, services}"]; + * APP=>SD [label = "sd_ble_gattc_primary_services_discover(handle + N + M, uuid)"]; + * APP<PEER [label = "ATT Find By Type Value Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Error Response: Attribute Not Found", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP {ATTRIBUTE_NOT_FOUND}"]; + * @endmsc + * + * @defgroup BLE_GATTC_REL_DISC_MSC GATTC Relationship Discovery + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * APP=>SD [label = "sd_ble_gattc_relationships_discover(handle_range)"]; + * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Read By Type Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_REL_DISC_RSP {SUCCESS, includes}"]; + * APP=>SD [label = "sd_ble_gattc_relationships_discover(handle_range + N)"]; + * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Read By Type Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_REL_DISC_RSP {SUCCESS, includes}"]; + * APP=>SD [label = "sd_ble_gattc_relationships_discover(handle_range + N + M)"]; + * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Error Response: Attribute Not Found", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_REL_DISC_RSP {ATTRIBUTE_NOT_FOUND}"]; + * @endmsc + * + * @defgroup BLE_GATTC_CHAR_DISC_MSC GATTC Characteristic Discovery + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * APP=>SD [label = "sd_ble_gattc_characteristics_discover(handle_range)"]; + * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Read By Type Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_CHAR_DISC_RSP {SUCCESS, chars}"]; + * APP=>SD [label = "sd_ble_gattc_characteristics_discover(handle_range + N)"]; + * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Read By Type Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_CHAR_DISC_RSP {SUCCESS, chars}"]; + * APP=>SD [label = "sd_ble_gattc_characteristics_discover(handle_range + N + M)"]; + * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Error Response: Attribute Not Found", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_CHAR_DISC_RSP {ATTRIBUTE_NOT_FOUND}"]; + * @endmsc + * + * @defgroup BLE_GATTC_DESC_DISC_MSC GATTC Descriptor Discovery + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * APP=>SD [label = "sd_ble_gattc_descriptors_discover(handle_range)"]; + * APP<PEER [label = "ATT Find Information Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Find Information Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_DESC_DISC_RSP {SUCCESS, descs}"]; + * APP=>SD [label = "sd_ble_gattc_descriptors_discover(handle_range + N)"]; + * APP<PEER [label = "ATT Find Information Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Find Information Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_DESC_DISC_RSP {SUCCESS, descs}"]; + * APP=>SD [label = "sd_ble_gattc_descriptors_discover(handle_range + N + M)"]; + * APP<PEER [label = "ATT Find Information Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Error Response: Attribute Not Found", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_DESC_DISC_RSP {ATTRIBUTE_NOT_FOUND}"]; + * @endmsc + * + * @defgroup BLE_GATTC_READ_UUID_MSC GATTC Read Characteristic Value by UUID + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * APP=>SD [label = "sd_ble_gattc_char_value_by_uuid_read(uuid, handle_range)"]; + * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Read By Type Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP {SUCCESS, char_values}"]; + * APP=>SD [label = "sd_ble_gattc_char_value_by_uuid_read(uuid, handle_range + N)"]; + * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Read By Type Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP {SUCCESS, char_values}"]; + * APP=>SD [label = "sd_ble_gattc_char_value_by_uuid_read(uuid, handle_range + N + M)"]; + * APP<PEER [label = "ATT Read By Type Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Error Response: Attribute Not Found", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP {ATTRIBUTE_NOT_FOUND}"]; + * @endmsc + * + * @defgroup BLE_GATTC_VALUE_READ_MSC GATTC Characteristic or Descriptor Value Read + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * --- [label = " Variant #1 offset == 0 "]; + * |||; + * APP=>SD [label = "sd_ble_gattc_read(handle, 0)"]; + * APP<PEER [label = "ATT Read Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Read Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_READ_RSP {SUCCESS, value}"]; + * |||; + * --- [label = " Variant #2 offset != 0 "]; + * |||; + * APP=>SD [label = "sd_ble_gattc_read(handle, offset)"]; + * APP<PEER [label = "ATT Read Blob Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Read Blob Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_READ_RSP {SUCCESS, value}"]; + * APP=>SD [label = "sd_ble_gattc_read(handle, offset + N)"]; + * APP<PEER [label = "ATT Read Blob Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Read Blob Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_READ_RSP {SUCCESS, value}"]; + * APP=>SD [label = "sd_ble_gattc_read(handle, offset + N + M + 1)"]; + * APP<PEER [label = "ATT Read Blob Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Error Response: Invalid Offset", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_READ_RSP {INVALID_OFFSET}"]; + * @endmsc + * + * @defgroup BLE_GATTC_READ_MULT_MSC GATTC Read Multiple Characteristic Values + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * --- [label = " Variant #1 Successful request "]; + * |||; + * APP=>SD [label = "sd_ble_gattc_char_values_read(handles)"]; + * APP<PEER [label = "ATT Read Multiple Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Read Multiple Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_CHAR_VALS_READ_RSP {SUCCESS, char_values}"]; + * |||; + * --- [label = " Variant #2 Failing request (invalid handle) "]; + * |||; + * APP=>SD [label = "sd_ble_gattc_char_values_read(handles)"]; + * APP<PEER [label = "ATT Read Multiple Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Error Response: Invalid Handle", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_CHAR_VALS_READ_RSP {INVALID_HANDLE, error_handle=}"]; + * @endmsc + * + * @defgroup BLE_GATTC_VALUE_WRITE_WITHOUT_RESP_MSC GATTC Characteristic Value Write Without Response + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * --- [label = " Variant #1 App does not keep track of the available queue element count for writes without responses "]; + * APP note PEER [label = " This variant makes it possible for APP to transmit writes without responses without keeping track of the available queue element count. However, successful queuing of writes without responses cannot be guaranteed. "]; + * |||; + * APP=>SD [label = "sd_ble_enable()"]; + * APP<SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_CMD, handle, value_1)"]; + * APP<SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_CMD, handle, value_2)"]; + * APP<SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_CMD, handle, value_3)"]; + * APP<SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_CMD, handle, value_4)"]; + * APP<PEER [label = "ATT Write Command {value_1}", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "ATT Write Command {value_2}", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "ATT Write Command {value_4}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE {SUCCESS, 3}"]; + * |||; + * --- [label = " Variant #2 App keeps track of the available queue element count for writes without responses "]; + * APP note PEER [label = " This variant makes it possible for APP to know when successful queuing of writes without responses is guaranteed. "]; + * |||; + * APP=>SD [label = "sd_ble_cfg_set(BLE_CONN_CFG_GATTC, gattc_conn_cfg.write_cmd_tx_queue_size = 2)"]; + * APP<SD [label = "sd_ble_enable()"]; + * APP<SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_CMD, handle, value_1)"]; + * APP<SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_CMD, handle, value_2)"]; + * APP<PEER [label = "ATT Write Command {value_1}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE {SUCCESS, 1}"]; + * APP abox APP [label="available_queue_element_count += 1"]; + * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_CMD, handle, value_3)"]; + * APP<PEER [label = "ATT Write Command {value_2}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE {SUCCESS, 1}"]; + * APP abox APP [label="available_queue_element_count += 1"]; + * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_CMD, handle, value_4)"]; + * APP<PEER [label = "ATT Write Command {value_3}", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "ATT Write Command {value_4}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE {SUCCESS, 2}"]; + * APP abox APP [label="available_queue_element_count += 2"]; + * @endmsc + * + * @defgroup BLE_GATTC_VALUE_WRITE_MSC GATTC Characteristic or Descriptor Value Write + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_WRITE_REQ, handle, value)"]; + * APP<PEER [label = "ATT Write Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Write Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_WRITE_REQ, SUCCESS}"]; + * @endmsc + * + * @defgroup BLE_GATTC_VALUE_LONG_WRITE_MSC GATTC Characteristic or Descriptor Value Long Write + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_PREP_WRITE_REQ, handle, offset_1, value_1)"]; + * APP<PEER [label = "ATT Prepare Write Request {handle, offset_1, value_1}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Prepare Write Response {handle, offset_1, value_1}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_PREP_WRITE_REQ, SUCCESS, value_1}"]; + * |||; + * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_PREP_WRITE_REQ, handle, offset_2, value_2)"]; + * APP<PEER [label = "ATT Prepare Write Request {handle, offset_2, value_2}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Prepare Write Response {handle, offset_2, value_2}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_PREP_WRITE_REQ, SUCCESS, value_2}"]; + * |||; + * ...; + * |||; + * --- [label = " Variant #1 App executes the Long Write procedure "]; + * |||; + * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_EXEC_WRITE_REQ, PREPARED_WRITE)"]; + * APP<PEER [label = "ATT Execute Write Request: flags = 0x01", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_EXEC_WRITE_REQ, SUCCESS}"]; + * |||; + * --- [label = " Variant #2 App cancels the Long Write procedure "]; + * |||; + * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_EXEC_WRITE_REQ, PREPARED_CANCEL)"]; + * APP<PEER [label = "ATT Execute Write Request: flags = 0x00", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_EXEC_WRITE_REQ, SUCCESS}"]; + * @endmsc + * + * @defgroup BLE_GATTC_VALUE_RELIABLE_WRITE_MSC GATTC Characteristic or Descriptor Value Reliable Write + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_PREP_WRITE_REQ, handle_1, offset, value_1)"]; + * APP<PEER [label = "ATT Prepare Write Request {handle_1, offset, value_1}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Prepare Write Response {handle_1, offset, value_1}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_PREP_WRITE_REQ, SUCCESS, value_1}"]; + * |||; + * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_PREP_WRITE_REQ, handle_2, offset, value_2)"]; + * APP<PEER [label = "ATT Prepare Write Request {handle_2, offset, value_2}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Prepare Write Response {handle_2, offset, value_2}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_PREP_WRITE_REQ, SUCCESS, value_2}"]; + * |||; + * ...; + * |||; + * --- [label = " Variant #1 App executes the Reliable Write procedure "]; + * |||; + * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_EXEC_WRITE_REQ, PREPARED_WRITE)"]; + * APP<PEER [label = "ATT Execute Write Request: flags = 0x01", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_EXEC_WRITE_REQ, SUCCESS}"]; + * |||; + * --- [label = " Variant #2 App cancels the Reliable Write procedure "]; + * |||; + * APP=>SD [label = "sd_ble_gattc_write(BLE_GATT_OP_EXEC_WRITE_REQ, PREPARED_CANCEL)"]; + * APP<PEER [label = "ATT Execute Write Request: flags = 0x00", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_WRITE_RSP {BLE_GATT_OP_EXEC_WRITE_REQ, SUCCESS}"]; + * @endmsc + * + * @defgroup BLE_GATTC_HVI_MSC GATTC Handle Value Indication + * GATTC Handle Value Indication MSC + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * SD<:PEER [label = "ATT Handle Value Indication", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_HVX {INDICATION, data}"]; + * APP=>SD [label = "sd_ble_gattc_hv_confirm(handle)"]; + * APP<PEER [label = "ATT Handle Value Confirmation", textcolor="#000080", linecolor="#000080"]; + * @endmsc + * + * @defgroup BLE_GATTC_HVN_MSC GATTC Handle Value Notification + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * SD<:PEER [label = "ATT Handle Value Notification", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTC_EVT_HVX {NOTIFICATION, data}"]; + * @endmsc + * + * @defgroup BLE_GATTC_TIMEOUT_MSC GATTC Timeout + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * APP rbox PEER [label="GATTC procedure API call"]; + * SD:>PEER [label = "ATT Packet", textcolor="#000080", linecolor="#000080"]; + * APP note PEER [label = "No Response from Peer"]; + * |||; + * ...; + * |||; + * SD box SD [label="Timeout"]; + * APP<<=SD [label = "BLE_GATTC_EVT_TIMEOUT {source}"]; + * APP rbox PEER [label="No additional ATT Traffic Allowed", textbgcolour="#ff7f7f"]; + * APP=>SD [label = "Any GATT procedure API call"]; + * APP<SD [label = "sd_ble_cfg_set(BLE_CONN_CFG_GATT, gatt_conn_cfg.att_mtu=100)"]; + * APP<SD [label = "sd_ble_enable()"]; + * APP<SD [label = "sd_ble_gattc_exchange_mtu_request(conn_handle, client_rx_mtu=80)"]; + * APP<PEER [label = "ATT Exchange MTU Request {client_rx_mtu=80}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Exchange MTU Response {server_rx_mtu=75}", textcolor="#000080", linecolor="#000080"]; + * SD rbox SD [label="att_mtu=75"]; + * APP<<=SD [label = "BLE_GATTC_EVT_EXCHANGE_MTU_RSP {SUCCESS, server_rx_mtu=75}"]; + * @endmsc + * + * @} + * @} + */ + +/** + * @addtogroup BLE_GATTS + * @{ + * @defgroup BLE_GATTS_MSC Message Sequence Charts + * @{ + * @defgroup BLE_GATTS_ATT_TABLE_POP_MSC GATTS ATT Table Population + * @msc + * hscale = "1.5"; + * APP,SD; + * |||; + * APP=>SD [label = "sd_ble_gatts_service_add(uuid#1)"]; + * APP<SD [label = "sd_ble_gatts_characteristic_add(handle_srvc#1, char_md, value)"]; + * APP<SD [label = "sd_ble_gatts_descriptor_add(handle_char#1, value)"]; + * APP<SD [label = "sd_ble_gatts_descriptor_add(handle_char#1, value)"]; + * APP<SD [label = "sd_ble_gatts_characteristic_add(handle_srvc#1, char_md, value)"]; + * APP<SD [label = "sd_ble_gatts_descriptor_add(handle_char#2, value)"]; + * APP<SD [label = "sd_ble_gatts_service_add(uuid#2)"]; + * APP<SD [label = "sd_ble_gatts_include_add(handle_srvc#2, handle_srvc#1)"]; + * APP<PEER [label = "ATT Read Response", textcolor="#000080", linecolor="#000080"]; + * @endmsc + * + * @defgroup BLE_GATTS_WRITE_REQ_NO_AUTH_MSC GATTS Write Request without Authorization + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * SD rbox SD [label="Value in ATT Table: current_value"]; + * SD<:PEER [label = "ATT Write Request {peer_value}", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "ATT Write Response", textcolor="#000080", linecolor="#000080"]; + * SD rbox SD [label="Value in ATT Table: peer_value"]; + * APP<<=SD [label = "BLE_GATTS_EVT_WRITE {WRITE_REQ, auth_required=0, peer_value}"]; + * @endmsc + * + * @defgroup BLE_GATTS_WRITE_CMD_NO_AUTH_MSC GATTS Write Command Without Authorization + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * SD rbox SD [label="Value in ATT Table: current_value"]; + * SD<:PEER [label = "ATT Write Command {peer_value}", textcolor="#000080", linecolor="#000080"]; + * SD rbox SD [label="Value in ATT Table: peer_value"]; + * APP<<=SD [label = "BLE_GATTS_EVT_WRITE {WRITE_CMD, auth_required=0, peer_value}"]; + * @endmsc + * + * @defgroup BLE_GATTS_WRITE_CMD_AUTH_MSC GATTS Write Command With Authorization + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * SD rbox SD [label="Value in ATT Table: current_value"]; + * SD<:PEER [label = "ATT Write Command {peer_value}", textcolor="#000080", linecolor="#000080"]; + * SD rbox SD [label="Value in ATT Table: current_value"]; + * APP<<=SD [label = "BLE_GATTS_EVT_WRITE {WRITE_CMD, auth_required=1, peer_value}"]; + * --- [label = " Variant #1 App Authorizes "]; + * APP=>SD [label = "sd_ble_gatts_value_set(peer_value)"]; + * APP<SD [label = "sd_ble_gatts_value_set(app_value)"]; + * APP<SD [label = "sd_ble_gatts_rw_authorize_reply(SUCCESS, app_value)"]; + * APP<PEER [label = "ATT Read Response {app_value}", textcolor="#000080", linecolor="#000080"]; + * --- [label = " Variant #2 App Disallows "]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(READ_NOT_PERMITTED)"]; + * APP<PEER [label = "ATT Error Response", textcolor="#000080", linecolor="#000080"]; + * @endmsc + * + * @defgroup BLE_GATTS_WRITE_REQ_AUTH_MSC GATTS Write Request with Authorization + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * SD rbox SD [label="Value in ATT Table: current_value"]; + * SD<:PEER [label = "ATT Write Request {peer_value}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, peer_value}"]; + * --- [label = " Variant #1 App Authorizes "]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(SUCCESS, peer_value)"]; + * APP<PEER [label = "ATT Write Response", textcolor="#000080", linecolor="#000080"]; + * --- [label = " Variant #2 App Authorizes but changes value "]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(SUCCESS, app_value)"]; + * APP<PEER [label = "ATT Write Response", textcolor="#000080", linecolor="#000080"]; + * --- [label = " Variant #3 App Disallows "]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE_NOT_PERMITTED)"]; + * APP<PEER [label = "ATT Error Response", textcolor="#000080", linecolor="#000080"]; + * @endmsc + * + * @defgroup BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC GATTS Queued Writes: Stack handled, no attributes require authorization + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; + * SD<:PEER [label = "ATT Prepare Write Request {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_EVT_USER_MEM_REQUEST {BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES}"]; + * APP=>SD [label = "sd_ble_user_mem_reply {user_mem_block}"]; + * SD:>PEER [label = "ATT Prepare Write Response {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Prepare Write Request {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "ATT Prepare Write Response {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #1 Attribute Values validation passed "]; + * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; + * SD rbox SD [label="Values in ATT Table:\nhandle_1: peer_value_1\nhandle_2: peer_value_2"]; + * APP<<=SD [label = "BLE_GATTS_EVT_WRITE {EXEC_WRITE_REQ_NOW}"]; + * APP rbox APP [label="App parses the memory it provided"]; + * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_EVT_USER_MEM_RELEASE {user_mem_block}"]; + * |||; + * --- [label = " Variant #2 Attribute Values validation failed "]; + * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; + * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; + * SD:>PEER [label = "ATT Error Response {Invalid Value Length / Offset}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_EVT_USER_MEM_RELEASE {user_mem_block}"]; + * |||; + * @endmsc + * + * @defgroup BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC GATTS Queued Writes: Stack handled, one or more attributes require authorization + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; + * SD<:PEER [label = "ATT Prepare Write Request {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_EVT_USER_MEM_REQUEST {BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES}"]; + * APP=>SD [label = "sd_ble_user_mem_reply {user_mem_block}"]; + * SD:>PEER [label = "ATT Prepare Write Response {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Prepare Write Request {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_2, offset_2, peer_value_2}"]; + * |||; + * --- [label = " Variant #1 App Authorizes both Prepare Write and Execute Write"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; + * SD:>PEER [label = "ATT Prepare Write Response {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_NOW}"]; + * APP rbox APP [label="App parses the memory it provided"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; + * SD rbox SD [label="Values in ATT Table:\nhandle_1: peer_value_1\nhandle_2: peer_value_2"]; + * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_EVT_USER_MEM_RELEASE {user_mem_block}"]; + * |||; + * --- [label = " Variant #2 App Disallows Prepare Write and Authorizes Execute Write "]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, INSUF_AUTHORIZATION)"]; + * SD:>PEER [label = "ATT Error Response {Insufficient Authorization}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_NOW}"]; + * APP rbox APP [label="App parses the memory it provided"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; + * SD rbox SD [label="Values in ATT Table:\nhandle_1: peer_value_1\nhandle_2: current_value_2"]; + * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_EVT_USER_MEM_RELEASE {user_mem_block}"]; + * |||; + * --- [label = " Variant #3 App Authorizes Prepare Write and Disallows Execute Write "]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; + * SD:>PEER [label = "ATT Prepare Write Response {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_NOW}"]; + * APP rbox APP [label="App parses the memory it provided"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, APP_ERROR_CODE)"]; + * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; + * SD:>PEER [label = "ATT Error Response {APP_ERROR_CODE}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_EVT_USER_MEM_RELEASE {user_mem_block}"]; + * @endmsc + * + * @defgroup BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC GATTS Queued Writes: App handled, no attributes require authorization + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * APP rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; + * SD<:PEER [label = "ATT Prepare Write Request {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_EVT_USER_MEM_REQUEST {BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES}"]; + * APP=>SD [label = "sd_ble_user_mem_reply {NULL}"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_1, offset_1, peer_value_1}"]; + * APP rbox APP [label="App queues {handle_1, offset_1, peer_value_1}"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS, handle_1, offset_1, peer_value_1)"]; + * SD:>PEER [label = "ATT Prepare Write Response {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Prepare Write Request {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_2, offset_2, peer_value_2}"]; + * APP rbox APP [label="App queues {handle_2, offset_2, peer_value_2}"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS, handle_2, offset_2, peer_value_2)"]; + * SD:>PEER [label = "ATT Prepare Write Response {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_NOW}"]; + * |||; + * --- [label = " Variant #1 Attribute values in stack memory (VLOC_STACK), attribute values validation passed "]; + * APP=>SD [label = "sd_ble_gatts_value_set {handle_1, offset_1, peer_value_1}"]; + * APP<SD [label = "sd_ble_gatts_value_set {handle_2, offset_2, peer_value_2}"]; + * APP<SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; + * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #2 Attribute values in user memory (VLOC_USER), attribute values validation passed "]; + * APP rbox APP [label="Application traverses its queue and executes the write operations (memcpy)"]; + * APP rbox APP [label="Values in ATT Table:\nhandle_1: peer_value_1\nhandle_2: peer_value_2"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; + * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #3 Attribute values validation failed "]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, INVALID_OFFSET)"]; + * APP rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; + * SD:>PEER [label = "ATT Error Response {Invalid Offset}", textcolor="#000080", linecolor="#000080"]; + * @endmsc + * + * @defgroup BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC GATTS Queued Writes: App handled, one or more attributes require authorization + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * APP rbox APP [label="Values in ATT Table in user memory (VLOC_USER):\nhandle_1: current_value_1\nhandle_2: current_value_2"]; + * SD<:PEER [label = "ATT Prepare Write Request {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_EVT_USER_MEM_REQUEST {BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES}"]; + * APP=>SD [label = "sd_ble_user_mem_reply {NULL}"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_1, offset_1, peer_value_1}"]; + * APP rbox APP [label="App queues {handle_1, offset_1, peer_value_1}"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS, handle_1, offset_1, peer_value_1)"]; + * SD:>PEER [label = "ATT Prepare Write Response {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Prepare Write Request {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_2, offset_2, peer_value_2}"]; + * |||; + * --- [label = " Variant #1 App Authorizes both Prepare Write and Execute Write"]; + * APP rbox APP [label="App queues {handle_2, offset_2, peer_value_2}"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS, handle_2, offset_2, peer_value_2)"]; + * SD:>PEER [label = "ATT Prepare Write Response {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_NOW}"]; + * APP rbox APP [label="Application traverses its queue and executes the write operations (memcpy)"]; + * APP rbox APP [label="Values in ATT Table:\nhandle_1: peer_value_1\nhandle_2: peer_value_2"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; + * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #2 App Disallows Prepare Write and Authorizes Execute Write "]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, INSUF_AUTHORIZATION)"]; + * SD:>PEER [label = "ATT Error Response {Insufficient Authorization}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_NOW}"]; + * APP rbox APP [label="Application traverses its queue and executes the write operations (memcpy)"]; + * APP rbox APP [label="Values in ATT Table:\nhandle_1: peer_value_1\nhandle_2: current_value_2"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; + * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #3 App Authorizes Prepare Write and Disallows Execute Write "]; + * APP rbox APP [label="App queues {handle_2, offset_2, peer_value_2}"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS, handle_2, offset_2, peer_value_2)"]; + * SD:>PEER [label = "ATT Prepare Write Response {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_NOW}"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, APP_ERROR_CODE)"]; + * APP rbox APP [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; + * SD:>PEER [label = "ATT Error Response {APP_ERROR_CODE}", textcolor="#000080", linecolor="#000080"]; + * @endmsc + * + * @defgroup BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC GATTS Queued Writes: Peer cancels operation + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; + * SD<:PEER [label = "ATT Prepare Write Request {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_EVT_USER_MEM_REQUEST {BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES}"]; + * |||; + * --- [label = " Variant #1 Stack handled "]; + * APP=>SD [label = "sd_ble_user_mem_reply {user_mem_block}"]; + * SD:>PEER [label = "ATT Prepare Write Response {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Prepare Write Request {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "ATT Prepare Write Response {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Execute Write Request {CANCEL}", textcolor="#000080", linecolor="#000080"]; + * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; + * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_EVT_USER_MEM_RELEASE {user_mem_block}"]; + * |||; + * --- [label = " Variant #2 App handled "]; + * APP=>SD [label = "sd_ble_user_mem_reply {NULL}"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_1, offset_1, peer_value_1}"]; + * APP rbox APP [label="App queues {handle_1, offset_1, peer_value_1}"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS, handle_1, offset_1, peer_value_1)"]; + * SD:>PEER [label = "ATT Prepare Write Response {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Prepare Write Request {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_2, offset_2, peer_value_2}"]; + * APP rbox APP [label="App queues {handle_2, offset_2, peer_value_2}"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS, handle_2, offset_2, peer_value_2)"]; + * SD:>PEER [label = "ATT Prepare Write Response {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Execute Write Request {CANCEL}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_CANCEL}"]; + * APP rbox APP [label="App erases queue"]; + * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; + * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; + * |||; + * @endmsc + * + * @defgroup BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC GATTS Queued Writes: Prepare Queue Full + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; + * SD<:PEER [label = "ATT Prepare Write Request {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_EVT_USER_MEM_REQUEST {BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES}"]; + * |||; + * --- [label = " Variant #1 Stack handled "]; + * APP=>SD [label = "sd_ble_user_mem_reply {user_mem_block}"]; + * SD:>PEER [label = "ATT Prepare Write Response {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Prepare Write Request {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "ATT Error Response {Prepare Queue Full}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; + * SD rbox SD [label="Values in ATT Table:\nhandle_1: peer_value_1\nhandle_2: current_value_2"]; + * APP<<=SD [label = "BLE_GATTS_EVT_WRITE {EXEC_WRITE_REQ_NOW}"]; + * APP rbox APP [label="App parses the memory it provided"]; + * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_EVT_USER_MEM_RELEASE {user_mem_block}"]; + * |||; + * --- [label = " Variant #2 App handled "]; + * APP=>SD [label = "sd_ble_user_mem_reply {NULL}"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_1, offset_1, peer_value_1}"]; + * APP rbox APP [label="App queues {handle_1, offset_1, peer_value_1}"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS, handle_1, offset_1, peer_value_1)"]; + * SD:>PEER [label = "ATT Prepare Write Response {handle_1, offset_1, peer_value_1}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Prepare Write Request {handle_2, offset_2, peer_value_2}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, PREP_WRITE_REQ, handle_2, offset_2, peer_value_2}"]; + * APP=>SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, PREPARE_QUEUE_FULL)"]; + * SD:>PEER [label = "ATT Error Response {Prepare Queue Full}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST {WRITE, EXEC_WRITE_REQ_NOW}"]; + * APP=>SD [label = "sd_ble_gatts_value_set {handle_1, offset_1, peer_value_1}"]; + * APP<SD [label = "sd_ble_gatts_rw_authorize_reply(WRITE, SUCCESS)"]; + * SD rbox SD [label="Values in ATT Table:\nhandle_1: peer_value_1\nhandle_2: current_value_2"]; + * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; + * @endmsc + * + * @defgroup BLE_GATTS_QUEUED_WRITE_EXECUTE_WITHOUT_PREPARE_MSC GATTS Queued Writes: Execute Write without Prepare Write + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; + * |||; + * SD rbox SD [label="No ATT Prepare Write Request has been received by SD"]; + * |||; + * --- [label = " Variant #1 Write cancelled "]; + * SD<:PEER [label = "ATT Execute Write Request {CANCEL}", textcolor="#000080", linecolor="#000080"]; + * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; + * APP<<=SD [label = "BLE_GATTS_EVT_WRITE {EXEC_WRITE_REQ_CANCEL}"]; + * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; + * |||; + * --- [label = " Variant #2 Write now "]; + * SD<:PEER [label = "ATT Execute Write Request {WRITE}", textcolor="#000080", linecolor="#000080"]; + * SD rbox SD [label="Values in ATT Table:\nhandle_1: current_value_1\nhandle_2: current_value_2"]; + * APP<<=SD [label = "BLE_GATTS_EVT_WRITE {EXEC_WRITE_REQ_NOW}"]; + * SD:>PEER [label = "ATT Execute Write Response", textcolor="#000080", linecolor="#000080"]; + * @endmsc + * + * @defgroup BLE_GATTS_MTU_EXCHANGE GATTS ATT_MTU Exchange + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP=>SD [label = "sd_ble_cfg_set(BLE_CONN_CFG_GATT, gatt_conn_cfg.att_mtu=100)"]; + * APP<SD [label = "sd_ble_enable()"]; + * APP<SD [label = "sd_ble_gatts_exchange_mtu_reply(conn_handle, server_rx_mtu=75)"]; + * APP<PEER [label = "ATT Exchange MTU Response {server_rx_mtu=75}", textcolor="#000080", linecolor="#000080"]; + * SD rbox SD [label="att_mtu=75"]; + * @endmsc + * + * @defgroup BLE_GATTS_HVI_MSC GATTS Handle Value Indication + * @msc + * hscale = "1.5"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * APP rbox PEER [label="Indications Enabled in CCCD"]; + * |||; + * SD rbox SD [label="Value in ATT Table: current_value"]; + * APP=>SD [label = "sd_ble_gatts_hvx(INDICATION, app_value)"]; + * APP<PEER [label = "ATT Handle Value Indication {app_value}", textcolor="#000080", linecolor="#000080"]; + * --- [label = " Variant #1 Peer Confirms "]; + * SD<:PEER [label = "ATT Handle Value Confirmation", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_HVC"]; + * --- [label = " Variant #2 Peer Ignores "]; + * |||; + * ...; + * |||; + * SD box SD [label="Timeout"]; + * APP<<=SD [label = "BLE_GATTS_EVT_TIMEOUT"]; + * @endmsc + * + * @defgroup BLE_GATTS_HVN_MSC GATTS Handle Value Notification + * @msc + * hscale = "1.5"; + * APP,SD,PEER; + * |||; + * --- [label = " Variant #1 App does not keep track of the available queue element count for notifications "]; + * APP note PEER [label = " This variant makes it possible for APP to transmit notifications without keeping track of the available queue element count. However, successful queuing of notifications cannot be guaranteed. "]; + * |||; + * APP=>SD [label = "sd_ble_enable()"]; + * APP<SD [label = "sd_ble_gatts_hvx(NOTIFICATION, app_value_1)"]; + * APP<SD [label = "sd_ble_gatts_hvx(NOTIFICATION, app_value_2)"]; + * APP<SD [label = "sd_ble_gatts_hvx(NOTIFICATION, app_value_3)"]; + * APP<SD [label = "sd_ble_gatts_hvx(NOTIFICATION, app_value_4)"]; + * APP<PEER [label = "ATT Handle Value Notification {app_value_1}", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "ATT Handle Value Notification {app_value_2}", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "ATT Handle Value Notification {app_value_4}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_HVN_TX_COMPLETE {3}"]; + * |||; + * --- [label = " Variant #2 App keeps track of the available queue element count for notifications "]; + * APP note PEER [label = " This variant makes it possible for APP to know when successful queuing of notifications is guaranteed. "]; + * |||; + * APP=>SD [label = "sd_ble_cfg_set(BLE_CONN_CFG_GATTS, gatts_conn_cfg.hvn_tx_queue_size=2)"]; + * APP<SD [label = "sd_ble_enable()"]; + * APP<SD [label = "sd_ble_gatts_hvx(NOTIFICATION, app_value_1)"]; + * APP<SD [label = "sd_ble_gatts_hvx(NOTIFICATION, app_value_2)"]; + * APP<PEER [label = "ATT Handle Value Notification {app_value_1}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_HVN_TX_COMPLETE {1}"]; + * APP abox APP [label="available_queue_element_count += 1"]; + * APP=>SD [label = "sd_ble_gatts_hvx(NOTIFICATION, app_value_3)"]; + * APP<PEER [label = "ATT Handle Value Notification {app_value_2}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_HVN_TX_COMPLETE {1}"]; + * APP abox APP [label="available_queue_element_count += 1"]; + * APP=>SD [label = "sd_ble_gatts_hvx(NOTIFICATION, app_value_4)"]; + * APP<PEER [label = "ATT Handle Value Notification {app_value_3}", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "ATT Handle Value Notification {app_value_4}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_HVN_TX_COMPLETE {2}"]; + * APP abox APP [label="available_queue_element_count += 2"]; + * @endmsc + * + * @defgroup BLE_GATTS_HVX_DISABLED_MSC GATTS Handle Value Indication or Notification disabled + * @msc + * hscale = "1.5"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * APP rbox PEER [label="Indications and Notifications Disabled in CCCD"]; + * |||; + * SD rbox SD [label="Value in ATT Table: current_value"]; + * APP=>SD [label = "sd_ble_gatts_hvx(INDICATION or NOTIFICATION, app_value)"]; + * APP<SD [label = "sd_ble_gatts_hvx(INDICATION or NOTIFICATION, app_value)"]; + * APP<SD [label = "sd_ble_gatts_sys_attr_set()"]; + * APP<SD [label = "sd_ble_gatts_service_changed(N, M)"]; + * APP<PEER [label = "ATT Handle Value Indication {N, M}", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "ATT Handle Value Confirmation", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_SC_CONFIRM"]; + * |||; + * SD rbox PEER [label="Service Discovery"]; + * @endmsc + * + * @defgroup BLE_GATTS_SYS_ATTRS_UNK_PEER_MSC GATTS System Attributes Handling: Unknown Peer + * @msc + * hscale = "1.5"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established with an Unknown Peer"]; + * |||; + * SD<:PEER [label = "ATT Read Request {sys_attr_handle}", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_GATTS_EVT_SYS_ATTR_MISSING"]; + * APP=>SD [label = "sd_ble_gatts_sys_attr_set(NULL)"]; + * APP<PEER [label = "ATT Read Response {sys_attr_value}", textcolor="#000080", linecolor="#000080"]; + * @endmsc + * + * @defgroup BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC GATTS System Attributes Handling: Bonded Peer + * @msc + * hscale = "1.5"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established with a Bonded Peer"]; + * |||; + * APP rbox PEER [label="ATT Traffic"]; + * |||; + * APP rbox PEER [label="Connection Terminated"]; + * APP<<=SD [label = "BLE_GAP_EVT_DISCONNECTED {reason}"]; + * |||; + * APP=>SD [label = "sd_ble_gatts_sys_attr_get()"]; + * APP<SD [label = "sd_ble_gatts_sys_attr_set(sys_attr_data)"]; + * APP<PEER [label = "ATT Read Response {sys_attr_value}", textcolor="#000080", linecolor="#000080"]; + * @endmsc + * + * @defgroup BLE_GATTS_TIMEOUT_MSC GATTS Timeout + * @msc + * hscale = "2"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * APP rbox PEER [label="GATTS procedure API call"]; + * SD:>PEER [label = "ATT Packet", textcolor="#000080", linecolor="#000080"]; + * APP note PEER [label = "No Response from Peer"]; + * |||; + * ...; + * |||; + * SD box SD [label="Timeout"]; + * APP<<=SD [label = "BLE_GATTS_EVT_TIMEOUT {source}"]; + * APP rbox PEER [label="No additional ATT Traffic Allowed", textbgcolour="#ff7f7f"]; + * APP=>SD [label = "Any GATT procedure API call"]; + * APP< + * Queued Write + * + * Parameter + * Size (octets) + * Description + * + * + * Handle + * 2 + * Attribute Handle + * + * + * Offset + * 2 + * Value Offset + * + * + * Length + * 2 + * Value Length + * + * + * Value + * Length + * Attribute Value + * + * + * + * The application can parse the array of Queued Write instances at any time, but it is recommended to do so whenever an Execute Write ATT packet + * has been received over the air. See the GATT Server Queued Writes MSCs for more details. + * The array will be terminated by an Queued Write instance with its handle set to @ref BLE_GATT_HANDLE_INVALID. + * @} + */ + + /** + * @addtogroup BLE_GATTS_SYS_ATTRS_FORMAT User memory layout for System Attributes + * @{ + * The following table shows the memory layout used by the SoftDevice to store a + * system attribute. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
System Attribute
ParameterSize (octets)Description
Handle2Attribute handle
Length2Attribute length
DataLengthAttribute data
+ * + * The application can obtain an array of system attributes by using @c sd_ble_gatts_sys_attr_get(). + * The array is terminated by a CRC-16-CCITT checksum of the data in the array. + * @} + * @} + */ + +/** + * @addtogroup BLE_L2CAP + * @{ + * @defgroup BLE_L2CAP_MSC Message Sequence Charts + * @{ + * @defgroup BLE_L2CAP_CH_SETUP_MSC L2CAP Channel Setup + * @msc + * hscale = "1.5"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * --- [label = " Variant #1 Locally initiated, Establishment success "]; + * APP=>SD [label = "sd_ble_l2cap_ch_setup(conn_handle, local_cid=INVALID, le_psm, rx_mtu, rx_mps, sdu_buf: [len, p_data1])"]; + * APP<PEER [label = "L2CAP LE Credit Based Connection Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "L2CAP LE Credit Based Connection Response: Connection successful", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SETUP {conn_handle, local_cid, tx_mtu, tx_mps, credits}"]; + * |||; + * APP rbox PEER [label="L2CAP Channel Established"]; + * |||; + * --- [label = " Variant #2 Locally initiated, Establishment failure - PEER refusal "]; + * APP=>SD [label = "sd_ble_l2cap_ch_setup(conn_handle, local_cid=INVALID, le_psm, rx_mtu, rx_mps, sdu_buf: [len, p_data1])"]; + * APP<PEER [label = "L2CAP LE Credit Based Connection Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "L2CAP LE Credit Based Connection Response: Connection refused - no resources available", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED {conn_handle, local_cid, sdu_buf: [len, p_data1]}"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SETUP_REFUSED {conn_handle, local_cid, source: REMOTE, status: NO_RESOURCES}"]; + * |||; + * APP rbox PEER [label="L2CAP Channel NOT Established"]; + * |||; + * --- [label = " Variant #3 Locally initiated, Establishment failure - PEER does not respond "]; + * APP=>SD [label = "sd_ble_l2cap_ch_setup(conn_handle, local_cid=INVALID, le_psm, rx_mtu, rx_mps, sdu_buf: p_data=NULL)"]; + * APP<PEER [label = "L2CAP LE Credit Based Connection Request", textcolor="#000080", linecolor="#000080"]; + * SD abox SD [label="Timeout"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SETUP_REFUSED {conn_handle, local_cid, source: LOCAL, status: TIMEOUT}"]; + * |||; + * APP rbox PEER [label="L2CAP Channel NOT Established"]; + * |||; + * --- [label = " Variant #4 Remotely initiated, Establishment success "]; + * SD<:PEER [label = "L2CAP LE Credit Based Connection Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SETUP_REQUEST {conn_handle, local_cid, le_psm, tx_mtu, tx_mps, credits}"]; + * APP=>SD [label = "sd_ble_l2cap_ch_setup(conn_handle, local_cid, rx_mtu, rx_mps, sdu_buf: [len, p_data1], status: SUCCESS)"]; + * APP<PEER [label = "L2CAP LE Credit Based Connection Response: Connection successful", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP rbox PEER [label="L2CAP Channel Established"]; + * |||; + * --- [label = " Variant #5 Remotely initiated, Establishment failure - APP refusal "]; + * SD<:PEER [label = "L2CAP LE Credit Based Connection Request", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SETUP_REQUEST {conn_handle, local_cid, le_psm, tx_mtu, tx_mps, credits}"]; + * APP=>SD [label = "sd_ble_l2cap_ch_setup(conn_handle, local_cid, status: LE_PSM_NOT_SUPPORTED)"]; + * APP<PEER [label = "L2CAP LE Credit Based Connection Response: Connection refused - LE_PSM not supported", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP rbox PEER [label="L2CAP Channel NOT Established"]; + * |||; + * --- [label = " Variant #6 Remotely initiated, Establishment failure - SD refusal "]; + * SD<:PEER [label = "L2CAP LE Credit Based Connection Request", textcolor="#000080", linecolor="#000080"]; + * SD rbox SD [label="The limit of available L2CAP channels has been reached"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SETUP_REFUSED {conn_handle, local_cid=INVALID, source: LOCAL, status: NO_RESOURCES}"]; + * SD:>PEER [label = "L2CAP LE Credit Based Connection Response: Connection refused - no resources available", textcolor="#000080", linecolor="#000080"]; + * |||; + * APP rbox PEER [label="L2CAP Channel NOT Established"]; + * |||; + * @endmsc + * + * @defgroup BLE_L2CAP_CH_RELEASE_MSC L2CAP Channel Release + * @msc + * hscale = "1.5"; + * APP,SD,PEER; + * |||; + * APP rbox PEER [label="Connection Established"]; + * |||; + * APP rbox PEER [label="L2CAP Channel Established"]; + * |||; + * --- [label = " Variant #1 Locally initiated, PEER responds "]; + * APP=>SD [label = "sd_ble_l2cap_ch_release(conn_handle, local_cid)"]; + * APP<PEER [label = "L2CAP Disconnection Request", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "L2CAP Disconnection Response", textcolor="#000080", linecolor="#000080"]; + * SD rbox SD [label="SD currently has three SDU data buffers supplied by APP"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED {conn_handle, local_cid, sdu_buf1}"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED {conn_handle, local_cid, sdu_buf2}"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED {conn_handle, local_cid, sdu_buf3}"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RELEASED {conn_handle, local_cid}"]; + * |||; + * --- [label = " Variant #2 Locally initiated, PEER does not respond "]; + * APP=>SD [label = "sd_ble_l2cap_ch_release(conn_handle, local_cid)"]; + * APP<PEER [label = "L2CAP Disconnection Request", textcolor="#000080", linecolor="#000080"]; + * SD abox SD [label="Timeout"]; + * SD rbox SD [label="SD does not currently have SDU data buffers supplied by APP"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RELEASED {conn_handle, local_cid}"]; + * |||; + * --- [label = " Variant #3 Remotely initiated "]; + * SD<:PEER [label = "L2CAP Disconnection Request", textcolor="#000080", linecolor="#000080"]; + * SD rbox SD [label="SD does not currently have SDU data buffers supplied by APP"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RELEASED {conn_handle, local_cid}"]; + * SD:>PEER [label = "L2CAP Disconnection Response", textcolor="#000080", linecolor="#000080"]; + * |||; + * @endmsc + * + * @defgroup BLE_L2CAP_CH_TX_MSC L2CAP Channel SDU Transmit + * @msc + * hscale = "1.5"; + * APP,SD,PEER; + * |||; + * --- [label = " Variant #1 App ignores transmit credits, SD will transmit data as soon as possible "]; + * APP rbox PEER [label="L2CAP Channel Established, tx_queue_size=2, tx_mps=100, credits=2"]; + * |||; + * APP=>SD [label = "sd_ble_l2cap_ch_tx(conn_handle, local_cid, p_sdu_buf: [len=140, p_data1])"]; + * APP<SD [label = "sd_ble_l2cap_ch_tx(conn_handle, local_cid, p_sdu_buf: [len=80, p_data2])"]; + * APP<SD [label = "sd_ble_l2cap_ch_tx(conn_handle, local_cid, p_sdu_buf: [len=280, p_data3])"]; + * APP<PEER [label = "SDU 1, Segment 1", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "SDU 1, Segment 2", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_TX {conn_handle, local_cid, sdu_buf: [len=140, p_data1]}"]; + * APP abox APP [label="App releases memory pointed by p_data1"]; + * SD rbox SD [label="All credits consumed"]; + * APP=>SD [label = "sd_ble_l2cap_ch_tx(conn_handle, local_cid, p_sdu_buf: [len=280, p_data3])"]; + * APP<PEER [label = "SDU 2, Segment 1", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_TX {conn_handle, local_cid, sdu_buf: [len=80, p_data2]}"]; + * APP abox APP [label="App releases memory pointed by p_data2"]; + * SD:>PEER [label = "SDU 3, Segment 1", textcolor="#000080", linecolor="#000080"]; + * SD rbox SD [label="All credits consumed"]; + * ...; + * SD<:PEER [label = "LE Flow Control Credit (credits=2)", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_CREDIT {conn_handle, local_cid, credits=2}"]; + * SD:>PEER [label = "SDU 3, Segment 2", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "SDU 3, Segment 3", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_TX {conn_handle, local_cid, sdu_buf: [len=280, p_data3]}"]; + * APP abox APP [label="App releases memory pointed by p_data3"]; + * |||; + * --- [label = " Variant #2 App keeps track of transmission credits and transmits only if credits are available "]; + * APP rbox PEER [label="L2CAP Channel Established, tx_queue_size=2, tx_mps=100, credits=2"]; + * APP abox APP [label="available_credits = 2"]; + * |||; + * APP=>SD [label = "sd_ble_l2cap_ch_tx(conn_handle, local_cid, p_sdu_buf: [len=140, p_data1])"]; + * APP<PEER [label = "SDU 1, Segment 1", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "SDU 1, Segment 2", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_TX {conn_handle, local_cid, sdu_buf: [len=140, p_data1]}"]; + * APP abox APP [label="App releases memory pointed by p_data1"]; + * ...; + * SD<:PEER [label = "LE Flow Control Credit (credits=2)", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_CREDIT {conn_handle, local_cid, credits=2}"]; + * APP abox APP [label="available_credits += 2\n// available_credits == 2"]; + * APP=>SD [label = "sd_ble_l2cap_ch_tx(conn_handle, local_cid, p_sdu_buf: [len=80, p_data2])"]; + * APP<SD [label = "sd_ble_l2cap_ch_tx(conn_handle, local_cid, p_sdu_buf: [len=280, p_data3])"]; + * APP<PEER [label = "SDU 2, Segment 1", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_TX {conn_handle, local_cid, sdu_buf: [len=80, p_data2]}"]; + * APP abox APP [label="App releases memory pointed by p_data2"]; + * SD:>PEER [label = "SDU 3, Segment 1", textcolor="#000080", linecolor="#000080"]; + * ...; + * SD<:PEER [label = "LE Flow Control Credit (credits=2)", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_CREDIT {conn_handle, local_cid, credits=2}"]; + * APP abox APP [label="available_credits += 2\n// available_credits == 0"]; + * SD:>PEER [label = "SDU 3, Segment 2", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "SDU 3, Segment 3", textcolor="#000080", linecolor="#000080"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_TX {conn_handle, local_cid, sdu_buf: [len=280, p_data3]}"]; + * APP abox APP [label="App releases memory pointed by p_data3"]; + * |||; + * @endmsc + * + * @defgroup BLE_L2CAP_CH_RX_MSC L2CAP Channel SDU Receive + * @msc + * hscale = "1.5"; + * APP,SD,PEER; + * |||; + * APP=>SD [label = "sd_ble_l2cap_ch_setup(rx_mtu=1000, rx_mps=100, sdu_buf: [len=1000, p_data1])"]; + * APP<PEER [label = "L2CAP LE Credit Based Connection Request (Initial Credits=1)", textcolor="#000080", linecolor="#000080"]; + * APP rbox PEER [label="L2CAP Channel Established, rx_queue_size=2, rx_mtu=1000, rx_mps=100"]; + * |||; + * APP=>SD [label = "sd_ble_l2cap_ch_rx(conn_handle, local_cid, p_sdu_buf: [len=1000, p_data2])"]; + * APP<PEER [label = "LE Flow Control Credit (credits=1)", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "SDU 1, Segment 1", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "LE Flow Control Credit (credits=1)", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "SDU 1, Segment 2", textcolor="#000080", linecolor="#000080"]; + * PEER rbox PEER [label="1 credit left"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RX {conn_handle, local_cid, sdu_len=140, sdu_buf: [len=1000, p_data1]}"]; + * APP abox APP [label="App can process data and release memory pointed by p_data1"]; + * APP=>SD [label = "sd_ble_l2cap_ch_rx(conn_handle, local_cid, p_sdu_buf: [len=1000, p_data3])"]; + * APP<PEER [label = "LE Flow Control Credit (credits=1)", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "SDU 2, Segment 1", textcolor="#000080", linecolor="#000080"]; + * PEER rbox PEER [label="1 credit left"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RX {conn_handle, local_cid, sdu_len=80, sdu_buf: [len=1000, p_data2]}"]; + * APP abox APP [label="App can process data and release memory pointed by p_data2"]; + * SD<:PEER [label = "SDU 3, Segment 1", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "LE Flow Control Credit (credits=2)", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "SDU 3, Segment 2", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "SDU 3, Segment 3", textcolor="#000080", linecolor="#000080"]; + * PEER rbox PEER [label="All credits consumed"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RX {conn_handle, local_cid, sdu_len=280, sdu_buf: [len=1000, p_data3]}"]; + * APP abox APP [label="App can process data and release memory pointed by p_data3"]; + * |||; + * @endmsc + * + * @defgroup BLE_L2CAP_CH_FLOW_CONTROL_MSC L2CAP Channel advanced SDU reception flow control + * @msc + * hscale = "1.5"; + * APP,SD,PEER; + * |||; + * APP=>SD [label = "sd_ble_l2cap_ch_setup(rx_mtu=1000, rx_mps=100, sdu_buf: p_data=NULL)"]; + * APP<PEER [label = "L2CAP LE Credit Based Connection Request (Initial Credits=0)", textcolor="#000080", linecolor="#000080"]; + * APP rbox PEER [label="L2CAP Channel Established, rx_queue_size=2, rx_mtu=1000, rx_mps=100"]; + * |||; + * --- [label = " Variant #1 App overwrites number of credits peer should have at the start of a SDU "]; + * APP=>SD [label = "sd_ble_l2cap_ch_flow_control(conn_handle, local_cid, credits=8)"]; + * APP<SD [label = "sd_ble_l2cap_ch_rx(conn_handle, local_cid, p_sdu_buf: [len=1000, p_data1])"]; + * APP<PEER [label = "LE Flow Control Credit (credits=8)", textcolor="#000080", linecolor="#000080"]; + * APP=>SD [label = "sd_ble_l2cap_ch_rx(conn_handle, local_cid, p_sdu_buf: [len=1000, p_data2])"]; + * APP<PEER [label = "LE Flow Control Credit (credits=2)", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "SDU 1, Segment 2", textcolor="#000080", linecolor="#000080"]; + * PEER rbox PEER [label="8 credits left"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RX {conn_handle, local_cid, sdu_len=140, sdu_buf: [len=1000, p_data1]}"]; + * APP abox APP [label="App can process data and release memory pointed by p_data1"]; + * APP=>SD [label = "sd_ble_l2cap_ch_rx(conn_handle, local_cid, p_sdu_buf: [len=1000, p_data3])"]; + * APP<PEER [label = "LE Flow Control Credit (credits=1)", textcolor="#000080", linecolor="#000080"]; + * PEER rbox PEER [label="8 credits left"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RX {conn_handle, local_cid, sdu_len=80, sdu_buf: [len=1000, p_data2]}"]; + * APP abox APP [label="App can process data and release memory pointed by p_data2"]; + * SD<:PEER [label = "SDU 3, Segment 1", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "SDU 3, Segment 2", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "SDU 3, Segment 3", textcolor="#000080", linecolor="#000080"]; + * PEER rbox PEER [label="5 credits left"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RX {conn_handle, local_cid, sdu_len=280, sdu_buf: [len=1000, p_data3]}"]; + * APP abox APP [label="App can process data and release memory pointed by p_data3"]; + * APP rbox APP [label="Peer has credits remaining so application must provide new reception buffer as soon as possible."]; + * |||; + * --- [label = " Variant #2 App pauses traffic on a L2CAP Channel "]; + * APP=>SD [label = "sd_ble_l2cap_ch_rx(conn_handle, local_cid, p_sdu_buf: [len=1000, p_data1])"]; + * APP<PEER [label = "LE Flow Control Credit (credits=1)", textcolor="#000080", linecolor="#000080"]; + * APP=>SD [label = "sd_ble_l2cap_ch_rx(conn_handle, local_cid, p_sdu_buf: [len=1000, p_data2])"]; + * APP<PEER [label = "LE Flow Control Credit (credits=1)", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "SDU 1, Segment 1", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "LE Flow Control Credit (credits=1)", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "SDU 1, Segment 2", textcolor="#000080", linecolor="#000080"]; + * PEER rbox PEER [label="1 credit left"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RX {conn_handle, local_cid, sdu_len=140, sdu_buf: [len=1000, p_data1]}"]; + * APP abox APP [label="App can process data and release memory pointed by p_data1"]; + * APP=>SD [label = "sd_ble_l2cap_ch_flow_control(conn_handle, local_cid, credits=0)"]; + * APP<SD [label = "sd_ble_l2cap_ch_rx(conn_handle, local_cid, p_sdu_buf: [len=1000, p_data3])"]; + * APP<SD [label = "sd_ble_l2cap_ch_flow_control(conn_handle, local_cid, credits=0)"]; + * APP<SD [label = "sd_ble_l2cap_ch_flow_control(conn_handle, local_cid, credits=BLE_L2CAP_CREDITS_DEFAULT)"]; + * APP<PEER [label = "LE Flow Control Credit (credits=1)", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "SDU 3, Segment 1", textcolor="#000080", linecolor="#000080"]; + * SD:>PEER [label = "LE Flow Control Credit (credits=2)", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "SDU 3, Segment 2", textcolor="#000080", linecolor="#000080"]; + * SD<:PEER [label = "SDU 3, Segment 3", textcolor="#000080", linecolor="#000080"]; + * PEER rbox PEER [label="All credits consumed"]; + * APP<<=SD [label = "BLE_L2CAP_EVT_CH_RX {conn_handle, local_cid, sdu_len=280, sdu_buf: [len=1000, p_data3]}"]; + * APP abox APP [label="App can process data and release memory pointed by p_data3"]; + * |||; + * @endmsc + * @} + * @} + */ + diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble.h new file mode 100644 index 00000000000..da1a06bbcd5 --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble.h @@ -0,0 +1,667 @@ +/* + * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_COMMON BLE SoftDevice Common + @{ + @defgroup ble_api Events, type definitions and API calls + @{ + + @brief Module independent events, type definitions and API calls for the BLE SoftDevice. + + */ + +#ifndef BLE_H__ +#define BLE_H__ + +#include +#include "nrf_svc.h" +#include "nrf_error.h" +#include "ble_err.h" +#include "ble_gap.h" +#include "ble_l2cap.h" +#include "ble_gatt.h" +#include "ble_gattc.h" +#include "ble_gatts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_COMMON_ENUMERATIONS Enumerations + * @{ */ + +/** + * @brief Common API SVC numbers. + */ +enum BLE_COMMON_SVCS +{ + SD_BLE_ENABLE = BLE_SVC_BASE, /**< Enable and initialize the BLE stack */ + SD_BLE_EVT_GET, /**< Get an event from the pending events queue. */ + SD_BLE_UUID_VS_ADD, /**< Add a Vendor Specific base UUID. */ + SD_BLE_UUID_DECODE, /**< Decode UUID bytes. */ + SD_BLE_UUID_ENCODE, /**< Encode UUID bytes. */ + SD_BLE_VERSION_GET, /**< Get the local version information (company ID, Link Layer Version, Link Layer Subversion). */ + SD_BLE_USER_MEM_REPLY, /**< User Memory Reply. */ + SD_BLE_OPT_SET, /**< Set a BLE option. */ + SD_BLE_OPT_GET, /**< Get a BLE option. */ + SD_BLE_CFG_SET, /**< Add a configuration to the BLE stack. */ + SD_BLE_UUID_VS_REMOVE, /**< Remove a Vendor Specific base UUID. */ +}; + +/** + * @brief BLE Module Independent Event IDs. + */ +enum BLE_COMMON_EVTS +{ + BLE_EVT_USER_MEM_REQUEST = BLE_EVT_BASE + 0, /**< User Memory request. @ref ble_evt_user_mem_request_t */ + BLE_EVT_USER_MEM_RELEASE = BLE_EVT_BASE + 1, /**< User Memory release. @ref ble_evt_user_mem_release_t */ +}; + +/**@brief BLE Connection Configuration IDs. + * + * IDs that uniquely identify a connection configuration. + */ +enum BLE_CONN_CFGS +{ + BLE_CONN_CFG_GAP = BLE_CONN_CFG_BASE + 0, /**< BLE GAP specific connection configuration. */ + BLE_CONN_CFG_GATTC = BLE_CONN_CFG_BASE + 1, /**< BLE GATTC specific connection configuration. */ + BLE_CONN_CFG_GATTS = BLE_CONN_CFG_BASE + 2, /**< BLE GATTS specific connection configuration. */ + BLE_CONN_CFG_GATT = BLE_CONN_CFG_BASE + 3, /**< BLE GATT specific connection configuration. */ + BLE_CONN_CFG_L2CAP = BLE_CONN_CFG_BASE + 4, /**< BLE L2CAP specific connection configuration. */ +}; + +/**@brief BLE Common Configuration IDs. + * + * IDs that uniquely identify a common configuration. + */ +enum BLE_COMMON_CFGS +{ + BLE_COMMON_CFG_VS_UUID = BLE_CFG_BASE, /**< Vendor specific base UUID configuration */ +}; + +/**@brief Common Option IDs. + * IDs that uniquely identify a common option. + */ +enum BLE_COMMON_OPTS +{ + BLE_COMMON_OPT_PA_LNA = BLE_OPT_BASE + 0, /**< PA and LNA options */ + BLE_COMMON_OPT_CONN_EVT_EXT = BLE_OPT_BASE + 1, /**< Extended connection events option */ + BLE_COMMON_OPT_EXTENDED_RC_CAL = BLE_OPT_BASE + 2, /**< Extended RC calibration option */ +}; + +/** @} */ + +/** @addtogroup BLE_COMMON_DEFINES Defines + * @{ */ + +/** @brief Required pointer alignment for BLE Events. +*/ +#define BLE_EVT_PTR_ALIGNMENT 4 + +/** @brief Leaves the maximum of the two arguments. +*/ +#define BLE_MAX(a, b) ((a) < (b) ? (b) : (a)) + +/** @brief Maximum possible length for BLE Events. + * @note The highest value used for @ref ble_gatt_conn_cfg_t::att_mtu in any connection configuration shall be used as a parameter. + * If that value has not been configured for any connections then @ref BLE_GATT_ATT_MTU_DEFAULT must be used instead. +*/ +#define BLE_EVT_LEN_MAX(ATT_MTU) ( \ + offsetof(ble_evt_t, evt.gattc_evt.params.prim_srvc_disc_rsp.services) + ((ATT_MTU) - 1) / 4 * sizeof(ble_gattc_service_t) \ +) + +/** @defgroup BLE_USER_MEM_TYPES User Memory Types + * @{ */ +#define BLE_USER_MEM_TYPE_INVALID 0x00 /**< Invalid User Memory Types. */ +#define BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES 0x01 /**< User Memory for GATTS queued writes. */ +/** @} */ + +/** @defgroup BLE_UUID_VS_COUNTS Vendor Specific base UUID counts + * @{ + */ +#define BLE_UUID_VS_COUNT_DEFAULT 10 /**< Default VS UUID count. */ +#define BLE_UUID_VS_COUNT_MAX 254 /**< Maximum VS UUID count. */ +/** @} */ + +/** @defgroup BLE_COMMON_CFG_DEFAULTS Configuration defaults. + * @{ + */ +#define BLE_CONN_CFG_TAG_DEFAULT 0 /**< Default configuration tag, SoftDevice default connection configuration. */ + +/** @} */ + +/** @} */ + +/** @addtogroup BLE_COMMON_STRUCTURES Structures + * @{ */ + +/**@brief User Memory Block. */ +typedef struct +{ + uint8_t *p_mem; /**< Pointer to the start of the user memory block. */ + uint16_t len; /**< Length in bytes of the user memory block. */ +} ble_user_mem_block_t; + +/**@brief Event structure for @ref BLE_EVT_USER_MEM_REQUEST. */ +typedef struct +{ + uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */ +} ble_evt_user_mem_request_t; + +/**@brief Event structure for @ref BLE_EVT_USER_MEM_RELEASE. */ +typedef struct +{ + uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */ + ble_user_mem_block_t mem_block; /**< User memory block */ +} ble_evt_user_mem_release_t; + +/**@brief Event structure for events not associated with a specific function module. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which this event occurred. */ + union + { + ble_evt_user_mem_request_t user_mem_request; /**< User Memory Request Event Parameters. */ + ble_evt_user_mem_release_t user_mem_release; /**< User Memory Release Event Parameters. */ + } params; /**< Event parameter union. */ +} ble_common_evt_t; + +/**@brief BLE Event header. */ +typedef struct +{ + uint16_t evt_id; /**< Value from a BLE__EVT series. */ + uint16_t evt_len; /**< Length in octets including this header. */ +} ble_evt_hdr_t; + +/**@brief Common BLE Event type, wrapping the module specific event reports. */ +typedef struct +{ + ble_evt_hdr_t header; /**< Event header. */ + union + { + ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */ + ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */ + ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */ + ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */ + ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */ + } evt; /**< Event union. */ +} ble_evt_t; + + +/** + * @brief Version Information. + */ +typedef struct +{ + uint8_t version_number; /**< Link Layer Version number. See https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer for assigned values. */ + uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */ + uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */ +} ble_version_t; + +/** + * @brief Configuration parameters for the PA and LNA. + */ +typedef struct +{ + uint8_t enable :1; /**< Enable toggling for this amplifier */ + uint8_t active_high :1; /**< Set the pin to be active high */ + uint8_t gpio_pin :6; /**< The GPIO pin to toggle for this amplifier */ +} ble_pa_lna_cfg_t; + +/** + * @brief PA & LNA GPIO toggle configuration + * + * This option configures the SoftDevice to toggle pins when the radio is active for use with a power amplifier and/or + * a low noise amplifier. + * + * Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided + * by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled. + * + * @note @ref sd_ble_opt_get is not supported for this option. + * @note Setting this option while the radio is in use (i.e. any of the roles are active) may have undefined consequences + * and must be avoided by the application. + */ +typedef struct +{ + ble_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */ + ble_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */ + + uint8_t ppi_ch_id_set; /**< PPI channel used for radio pin setting */ + uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */ + uint8_t gpiote_ch_id; /**< GPIOTE channel used for radio pin toggling */ +} ble_common_opt_pa_lna_t; + +/** + * @brief Configuration of extended BLE connection events. + * + * When enabled the SoftDevice will dynamically extend the connection event when possible. + * + * The connection event length is controlled by the connection configuration as set by @ref ble_gap_conn_cfg_t::event_length. + * The connection event can be extended if there is time to send another packet pair before the start of the next connection interval, + * and if there are no conflicts with other BLE roles requesting radio time. + * + * @note @ref sd_ble_opt_get is not supported for this option. + */ +typedef struct +{ + uint8_t enable : 1; /**< Enable extended BLE connection events, disabled by default. */ +} ble_common_opt_conn_evt_ext_t; + +/** + * @brief Enable/disable extended RC calibration. + * + * If extended RC calibration is enabled and the internal RC oscillator (@ref NRF_CLOCK_LF_SRC_RC) is used as the SoftDevice + * LFCLK source, the SoftDevice as a peripheral will by default try to increase the receive window if two consecutive packets + * are not received. If it turns out that the packets were not received due to clock drift, the RC calibration is started. + * This calibration comes in addition to the periodic calibration that is configured by @ref sd_softdevice_enable(). When + * using only peripheral connections, the periodic calibration can therefore be configured with a much longer interval as the + * peripheral will be able to detect and adjust automatically to clock drift, and calibrate on demand. + * + * If extended RC calibration is disabled and the internal RC oscillator is used as the SoftDevice LFCLK source, the + * RC oscillator is calibrated periodically as configured by @ref sd_softdevice_enable(). + * + * @note @ref sd_ble_opt_get is not supported for this option. + */ +typedef struct +{ + uint8_t enable : 1; /**< Enable extended RC calibration, enabled by default. */ +} ble_common_opt_extended_rc_cal_t; + +/**@brief Option structure for common options. */ +typedef union +{ + ble_common_opt_pa_lna_t pa_lna; /**< Parameters for controlling PA and LNA pin toggling. */ + ble_common_opt_conn_evt_ext_t conn_evt_ext; /**< Parameters for enabling extended connection events. */ + ble_common_opt_extended_rc_cal_t extended_rc_cal; /**< Parameters for enabling extended RC calibration. */ +} ble_common_opt_t; + +/**@brief Common BLE Option type, wrapping the module specific options. */ +typedef union +{ + ble_common_opt_t common_opt; /**< COMMON options, opt_id in @ref BLE_COMMON_OPTS series. */ + ble_gap_opt_t gap_opt; /**< GAP option, opt_id in @ref BLE_GAP_OPTS series. */ +} ble_opt_t; + +/**@brief BLE connection configuration type, wrapping the module specific configurations, set with + * @ref sd_ble_cfg_set. + * + * @note Connection configurations don't have to be set. + * In the case that no configurations has been set, or fewer connection configurations has been set than enabled connections, + * the default connection configuration will be automatically added for the remaining connections. + * When creating connections with the default configuration, @ref BLE_CONN_CFG_TAG_DEFAULT should be used in + * place of @ref ble_conn_cfg_t::conn_cfg_tag. + * + * @sa sd_ble_gap_adv_start() + * @sa sd_ble_gap_connect() + * + * @mscs + * @mmsc{@ref BLE_CONN_CFG} + * @endmscs + + */ +typedef struct +{ + uint8_t conn_cfg_tag; /**< The application chosen tag it can use with the + @ref sd_ble_gap_adv_start() and @ref sd_ble_gap_connect() calls + to select this configuration when creating a connection. + Must be different for all connection configurations added and not @ref BLE_CONN_CFG_TAG_DEFAULT. */ + union { + ble_gap_conn_cfg_t gap_conn_cfg; /**< GAP connection configuration, cfg_id is @ref BLE_CONN_CFG_GAP. */ + ble_gattc_conn_cfg_t gattc_conn_cfg; /**< GATTC connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTC. */ + ble_gatts_conn_cfg_t gatts_conn_cfg; /**< GATTS connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTS. */ + ble_gatt_conn_cfg_t gatt_conn_cfg; /**< GATT connection configuration, cfg_id is @ref BLE_CONN_CFG_GATT. */ + ble_l2cap_conn_cfg_t l2cap_conn_cfg; /**< L2CAP connection configuration, cfg_id is @ref BLE_CONN_CFG_L2CAP. */ + } params; /**< Connection configuration union. */ +} ble_conn_cfg_t; + +/** + * @brief Configuration of Vendor Specific base UUIDs, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_INVALID_PARAM Too many UUIDs configured. + */ +typedef struct +{ + uint8_t vs_uuid_count; /**< Number of 128-bit Vendor Specific base UUID bases to allocate memory for. + Default value is @ref BLE_UUID_VS_COUNT_DEFAULT. Maximum value is + @ref BLE_UUID_VS_COUNT_MAX. */ +} ble_common_cfg_vs_uuid_t; + +/**@brief Common BLE Configuration type, wrapping the common configurations. */ +typedef union +{ + ble_common_cfg_vs_uuid_t vs_uuid_cfg; /**< Vendor Specific base UUID configuration, cfg_id is @ref BLE_COMMON_CFG_VS_UUID. */ +} ble_common_cfg_t; + +/**@brief BLE Configuration type, wrapping the module specific configurations. */ +typedef union +{ + ble_conn_cfg_t conn_cfg; /**< Connection specific configurations, cfg_id in @ref BLE_CONN_CFGS series. */ + ble_common_cfg_t common_cfg; /**< Global common configurations, cfg_id in @ref BLE_COMMON_CFGS series. */ + ble_gap_cfg_t gap_cfg; /**< Global GAP configurations, cfg_id in @ref BLE_GAP_CFGS series. */ + ble_gatts_cfg_t gatts_cfg; /**< Global GATTS configuration, cfg_id in @ref BLE_GATTS_CFGS series. */ +} ble_cfg_t; + +/** @} */ + +/** @addtogroup BLE_COMMON_FUNCTIONS Functions + * @{ */ + +/**@brief Enable the BLE stack + * + * @param[in, out] p_app_ram_base Pointer to a variable containing the start address of the + * application RAM region (APP_RAM_BASE). On return, this will + * contain the minimum start address of the application RAM region + * required by the SoftDevice for this configuration. + * + * @note The memory requirement for a specific configuration will not increase between SoftDevices + * with the same major version number. + * + * @note At runtime the IC's RAM is split into 2 regions: The SoftDevice RAM region is located + * between 0x20000000 and APP_RAM_BASE-1 and the application's RAM region is located between + * APP_RAM_BASE and the start of the call stack. + * + * @details This call initializes the BLE stack, no BLE related function other than @ref + * sd_ble_cfg_set can be called before this one. + * + * @mscs + * @mmsc{@ref BLE_COMMON_ENABLE} + * @endmscs + * + * @retval ::NRF_SUCCESS The BLE stack has been initialized successfully. + * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized and cannot be reinitialized. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_NO_MEM One or more of the following is true: + * - The amount of memory assigned to the SoftDevice by *p_app_ram_base is not + * large enough to fit this configuration's memory requirement. Check *p_app_ram_base + * and set the start address of the application RAM region accordingly. + * - Dynamic part of the SoftDevice RAM region is larger then 64 kB which + * is currently not supported. + * @retval ::NRF_ERROR_RESOURCES The total number of L2CAP Channels configured using @ref sd_ble_cfg_set is too large. + */ +SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(uint32_t * p_app_ram_base)); + +/**@brief Add configurations for the BLE stack + * + * @param[in] cfg_id Config ID, see @ref BLE_CONN_CFGS, @ref BLE_COMMON_CFGS, @ref + * BLE_GAP_CFGS or @ref BLE_GATTS_CFGS. + * @param[in] p_cfg Pointer to a ble_cfg_t structure containing the configuration value. + * @param[in] app_ram_base The start address of the application RAM region (APP_RAM_BASE). + * See @ref sd_ble_enable for details about APP_RAM_BASE. + * + * @note The memory requirement for a specific configuration will not increase between SoftDevices + * with the same major version number. + * + * @note If a configuration is set more than once, the last one set is the one that takes effect on + * @ref sd_ble_enable. + * + * @note Any part of the BLE stack that is NOT configured with @ref sd_ble_cfg_set will have default + * configuration. + * + * @note @ref sd_ble_cfg_set may be called at any time when the SoftDevice is enabled (see @ref + * sd_softdevice_enable) while the BLE part of the SoftDevice is not enabled (see @ref + * sd_ble_enable). + * + * @note Error codes for the configurations are described in the configuration structs. + * + * @mscs + * @mmsc{@ref BLE_COMMON_ENABLE} + * @endmscs + * + * @retval ::NRF_SUCCESS The configuration has been added successfully. + * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid cfg_id supplied. + * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by app_ram_base is not + * large enough to fit this configuration's memory requirement. + */ +SVCALL(SD_BLE_CFG_SET, uint32_t, sd_ble_cfg_set(uint32_t cfg_id, ble_cfg_t const * p_cfg, uint32_t app_ram_base)); + +/**@brief Get an event from the pending events queue. + * + * @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length. + * This buffer must be aligned to the extend defined by @ref BLE_EVT_PTR_ALIGNMENT. + * The buffer should be interpreted as a @ref ble_evt_t struct. + * @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length. + * + * @details This call allows the application to pull a BLE event from the BLE stack. The application is signaled that + * an event is available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt. + * The application is free to choose whether to call this function from thread mode (main context) or directly from the + * Interrupt Service Routine that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher + * priority than the application, this function should be called in a loop (until @ref NRF_ERROR_NOT_FOUND is returned) + * every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. Failure to do so + * could potentially leave events in the internal queue without the application being aware of this fact. + * + * Sizing the p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to + * be copied into application memory. If the buffer provided is not large enough to fit the entire contents of the event, + * @ref NRF_ERROR_DATA_SIZE will be returned and the application can then call again with a larger buffer size. + * The maximum possible event length is defined by @ref BLE_EVT_LEN_MAX. The application may also "peek" the event length + * by providing p_dest as a NULL pointer and inspecting the value of *p_len upon return: + * + * \code + * uint16_t len; + * errcode = sd_ble_evt_get(NULL, &len); + * \endcode + * + * @mscs + * @mmsc{@ref BLE_COMMON_IRQ_EVT_MSC} + * @mmsc{@ref BLE_COMMON_THREAD_EVT_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled. + * @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer. + */ +SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len)); + + +/**@brief Add a Vendor Specific base UUID. + * + * @details This call enables the application to add a Vendor Specific base UUID to the BLE stack's table, for later + * use with all other modules and APIs. This then allows the application to use the shorter, 24-bit @ref ble_uuid_t + * format when dealing with both 16-bit and 128-bit UUIDs without having to check for lengths and having split code + * paths. This is accomplished by extending the grouping mechanism that the Bluetooth SIG standard base UUID uses + * for all other 128-bit UUIDs. The type field in the @ref ble_uuid_t structure is an index (relative to + * @ref BLE_UUID_TYPE_VENDOR_BEGIN) to the table populated by multiple calls to this function, and the UUID field + * in the same structure contains the 2 bytes at indexes 12 and 13. The number of possible 128-bit UUIDs available to + * the application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536, + * although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array. + * + * @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by + * the 16-bit uuid field in @ref ble_uuid_t. + * + * @note If a UUID is already present in the BLE stack's internal table, the corresponding index will be returned in + * p_uuid_type along with an @ref NRF_SUCCESS error code. + * + * @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific base UUID disregarding + * bytes 12 and 13. + * @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be stored. + * + * @retval ::NRF_SUCCESS Successfully added the Vendor Specific base UUID. + * @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid. + * @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs. + */ +SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type)); + + +/**@brief Remove a Vendor Specific base UUID. + * + * @details This call removes a Vendor Specific base UUID that has been added with @ref sd_ble_uuid_vs_add. This function allows + * the application to reuse memory allocated for Vendor Specific base UUIDs. + * + * @note Currently this function can only be called with a p_uuid_type set to @ref BLE_UUID_TYPE_UNKNOWN or the last added UUID type. + * + * @param[in] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t::type corresponds to the UUID type that + * shall be removed. If the type is set to @ref BLE_UUID_TYPE_UNKNOWN, or the pointer is NULL, the last + * Vendor Specific base UUID will be removed. + * @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponds to the UUID type that was + * removed. If function returns with a failure, it contains the last type that is in use by the ATT Server. + * + * @retval ::NRF_SUCCESS Successfully removed the Vendor Specific base UUID. + * @retval ::NRF_ERROR_INVALID_ADDR If p_uuid_type is invalid. + * @retval ::NRF_ERROR_INVALID_PARAM If p_uuid_type points to a non-valid UUID type. + * @retval ::NRF_ERROR_FORBIDDEN If the Vendor Specific base UUID is in use by the ATT Server. + */ + +SVCALL(SD_BLE_UUID_VS_REMOVE, uint32_t, sd_ble_uuid_vs_remove(uint8_t *p_uuid_type)); + + +/** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure. + * + * @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared + * to the corresponding ones in each entry of the table of Vendor Specific base UUIDs populated with @ref sd_ble_uuid_vs_add + * to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index + * relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type. + * + * @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE. + * + * @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes). + * @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes. + * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length. + * @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs. + */ +SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid)); + + +/** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit). + * + * @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed. + * + * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes. + * @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes). + * @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored. + * + * @retval ::NRF_SUCCESS Successfully encoded into the buffer. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type. + */ +SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le)); + + +/**@brief Get Version Information. + * + * @details This call allows the application to get the BLE stack version information. + * + * @param[out] p_version Pointer to a ble_version_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Version information stored successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy (typically doing a locally-initiated disconnection procedure). + */ +SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version)); + + +/**@brief Provide a user memory block. + * + * @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_block Pointer to a user memory block structure or NULL if memory is managed by the application. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully queued a response to the peer. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_LENGTH Invalid user memory block length supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no user memory request pending. + */ +SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block)); + +/**@brief Set a BLE option. + * + * @details This call allows the application to set the value of an option. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} + * @endmscs + * + * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS. + * @param[in] p_opt Pointer to a ble_opt_t structure containing the option value. + * + * @retval ::NRF_SUCCESS Option set successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. + * @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. + */ +SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt)); + + +/**@brief Get a BLE option. + * + * @details This call allows the application to retrieve the value of an option. + * + * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS. + * @param[out] p_opt Pointer to a ble_opt_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Option retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. + * @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. + * @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported. + * + */ +SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt)); + +/** @} */ +#ifdef __cplusplus +} +#endif +#endif /* BLE_H__ */ + +/** + @} + @} +*/ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_err.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_err.h new file mode 100644 index 00000000000..1b4820dc3d6 --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_err.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_COMMON + @{ + @addtogroup nrf_error + @{ + @ingroup BLE_COMMON + @} + + @defgroup ble_err General error codes + @{ + + @brief General error code definitions for the BLE API. + + @ingroup BLE_COMMON +*/ +#ifndef NRF_BLE_ERR_H__ +#define NRF_BLE_ERR_H__ + +#include "nrf_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* @defgroup BLE_ERRORS Error Codes + * @{ */ +#define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */ +#define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */ +#define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */ +#define BLE_ERROR_INVALID_ADV_HANDLE (NRF_ERROR_STK_BASE_NUM+0x004) /**< Invalid advertising handle. */ +#define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x005) /**< Invalid role. */ +#define BLE_ERROR_BLOCKED_BY_OTHER_LINKS (NRF_ERROR_STK_BASE_NUM+0x006) /**< The attempt to change link settings failed due to the scheduling of other links. */ +/** @} */ + + +/** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges + * @brief Assignment of subranges for module specific error codes. + * @note For specific error codes, see ble_.h or ble_error_.h. + * @{ */ +#define NRF_L2CAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */ +#define NRF_GAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */ +#define NRF_GATTC_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */ +#define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */ +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif + + +/** + @} + @} +*/ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_gap.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_gap.h new file mode 100644 index 00000000000..a130d7b51d4 --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_gap.h @@ -0,0 +1,2691 @@ +/* + * Copyright (c) 2011 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_GAP Generic Access Profile (GAP) + @{ + @brief Definitions and prototypes for the GAP interface. + */ + +#ifndef BLE_GAP_H__ +#define BLE_GAP_H__ + +#include +#include "nrf_svc.h" +#include "nrf_error.h" +#include "ble_hci.h" +#include "ble_ranges.h" +#include "ble_types.h" +#include "ble_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup BLE_GAP_ENUMERATIONS Enumerations + * @{ */ + +/**@brief GAP API SVC numbers. + */ +enum BLE_GAP_SVCS +{ + SD_BLE_GAP_ADDR_SET = BLE_GAP_SVC_BASE, /**< Set own Bluetooth Address. */ + SD_BLE_GAP_ADDR_GET = BLE_GAP_SVC_BASE + 1, /**< Get own Bluetooth Address. */ + SD_BLE_GAP_WHITELIST_SET = BLE_GAP_SVC_BASE + 2, /**< Set active whitelist. */ + SD_BLE_GAP_DEVICE_IDENTITIES_SET = BLE_GAP_SVC_BASE + 3, /**< Set device identity list. */ + SD_BLE_GAP_PRIVACY_SET = BLE_GAP_SVC_BASE + 4, /**< Set Privacy settings*/ + SD_BLE_GAP_PRIVACY_GET = BLE_GAP_SVC_BASE + 5, /**< Get Privacy settings*/ + SD_BLE_GAP_ADV_SET_CONFIGURE = BLE_GAP_SVC_BASE + 6, /**< Configure an advertising set. */ + SD_BLE_GAP_ADV_START = BLE_GAP_SVC_BASE + 7, /**< Start Advertising. */ + SD_BLE_GAP_ADV_STOP = BLE_GAP_SVC_BASE + 8, /**< Stop Advertising. */ + SD_BLE_GAP_CONN_PARAM_UPDATE = BLE_GAP_SVC_BASE + 9, /**< Connection Parameter Update. */ + SD_BLE_GAP_DISCONNECT = BLE_GAP_SVC_BASE + 10, /**< Disconnect. */ + SD_BLE_GAP_TX_POWER_SET = BLE_GAP_SVC_BASE + 11, /**< Set TX Power. */ + SD_BLE_GAP_APPEARANCE_SET = BLE_GAP_SVC_BASE + 12, /**< Set Appearance. */ + SD_BLE_GAP_APPEARANCE_GET = BLE_GAP_SVC_BASE + 13, /**< Get Appearance. */ + SD_BLE_GAP_PPCP_SET = BLE_GAP_SVC_BASE + 14, /**< Set PPCP. */ + SD_BLE_GAP_PPCP_GET = BLE_GAP_SVC_BASE + 15, /**< Get PPCP. */ + SD_BLE_GAP_DEVICE_NAME_SET = BLE_GAP_SVC_BASE + 16, /**< Set Device Name. */ + SD_BLE_GAP_DEVICE_NAME_GET = BLE_GAP_SVC_BASE + 17, /**< Get Device Name. */ + SD_BLE_GAP_AUTHENTICATE = BLE_GAP_SVC_BASE + 18, /**< Initiate Pairing/Bonding. */ + SD_BLE_GAP_SEC_PARAMS_REPLY = BLE_GAP_SVC_BASE + 19, /**< Reply with Security Parameters. */ + SD_BLE_GAP_AUTH_KEY_REPLY = BLE_GAP_SVC_BASE + 20, /**< Reply with an authentication key. */ + SD_BLE_GAP_LESC_DHKEY_REPLY = BLE_GAP_SVC_BASE + 21, /**< Reply with an LE Secure Connections DHKey. */ + SD_BLE_GAP_KEYPRESS_NOTIFY = BLE_GAP_SVC_BASE + 22, /**< Notify of a keypress during an authentication procedure. */ + SD_BLE_GAP_LESC_OOB_DATA_GET = BLE_GAP_SVC_BASE + 23, /**< Get the local LE Secure Connections OOB data. */ + SD_BLE_GAP_LESC_OOB_DATA_SET = BLE_GAP_SVC_BASE + 24, /**< Set the remote LE Secure Connections OOB data. */ + SD_BLE_GAP_ENCRYPT = BLE_GAP_SVC_BASE + 25, /**< Initiate encryption procedure. */ + SD_BLE_GAP_SEC_INFO_REPLY = BLE_GAP_SVC_BASE + 26, /**< Reply with Security Information. */ + SD_BLE_GAP_CONN_SEC_GET = BLE_GAP_SVC_BASE + 27, /**< Obtain connection security level. */ + SD_BLE_GAP_RSSI_START = BLE_GAP_SVC_BASE + 28, /**< Start reporting of changes in RSSI. */ + SD_BLE_GAP_RSSI_STOP = BLE_GAP_SVC_BASE + 29, /**< Stop reporting of changes in RSSI. */ + SD_BLE_GAP_SCAN_START = BLE_GAP_SVC_BASE + 30, /**< Start Scanning. */ + SD_BLE_GAP_SCAN_STOP = BLE_GAP_SVC_BASE + 31, /**< Stop Scanning. */ + SD_BLE_GAP_CONNECT = BLE_GAP_SVC_BASE + 32, /**< Connect. */ + SD_BLE_GAP_CONNECT_CANCEL = BLE_GAP_SVC_BASE + 33, /**< Cancel ongoing connection procedure. */ + SD_BLE_GAP_RSSI_GET = BLE_GAP_SVC_BASE + 34, /**< Get the last RSSI sample. */ + SD_BLE_GAP_PHY_UPDATE = BLE_GAP_SVC_BASE + 35, /**< Initiate or respond to a PHY Update Procedure. */ + SD_BLE_GAP_DATA_LENGTH_UPDATE = BLE_GAP_SVC_BASE + 36, /**< Initiate or respond to a Data Length Update Procedure. */ + SD_BLE_GAP_QOS_CHANNEL_SURVEY_START = BLE_GAP_SVC_BASE + 37, /**< Start Quality of Service (QoS) channel survey module. */ + SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP = BLE_GAP_SVC_BASE + 38, /**< Stop Quality of Service (QoS) channel survey module. */ + SD_BLE_GAP_ADV_ADDR_GET = BLE_GAP_SVC_BASE + 39, /**< Get the Address used on air while Advertising. */ +}; + +/**@brief GAP Event IDs. + * IDs that uniquely identify an event coming from the stack to the application. + */ +enum BLE_GAP_EVTS +{ + BLE_GAP_EVT_CONNECTED = BLE_GAP_EVT_BASE, /**< Connected to peer. \n See @ref ble_gap_evt_connected_t */ + BLE_GAP_EVT_DISCONNECTED = BLE_GAP_EVT_BASE + 1, /**< Disconnected from peer. \n See @ref ble_gap_evt_disconnected_t. */ + BLE_GAP_EVT_CONN_PARAM_UPDATE = BLE_GAP_EVT_BASE + 2, /**< Connection Parameters updated. \n See @ref ble_gap_evt_conn_param_update_t. */ + BLE_GAP_EVT_SEC_PARAMS_REQUEST = BLE_GAP_EVT_BASE + 3, /**< Request to provide security parameters. \n Reply with @ref sd_ble_gap_sec_params_reply. \n See @ref ble_gap_evt_sec_params_request_t. */ + BLE_GAP_EVT_SEC_INFO_REQUEST = BLE_GAP_EVT_BASE + 4, /**< Request to provide security information. \n Reply with @ref sd_ble_gap_sec_info_reply. \n See @ref ble_gap_evt_sec_info_request_t. */ + BLE_GAP_EVT_PASSKEY_DISPLAY = BLE_GAP_EVT_BASE + 5, /**< Request to display a passkey to the user. \n In LESC Numeric Comparison, reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_passkey_display_t. */ + BLE_GAP_EVT_KEY_PRESSED = BLE_GAP_EVT_BASE + 6, /**< Notification of a keypress on the remote device.\n See @ref ble_gap_evt_key_pressed_t */ + BLE_GAP_EVT_AUTH_KEY_REQUEST = BLE_GAP_EVT_BASE + 7, /**< Request to provide an authentication key. \n Reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_auth_key_request_t. */ + BLE_GAP_EVT_LESC_DHKEY_REQUEST = BLE_GAP_EVT_BASE + 8, /**< Request to calculate an LE Secure Connections DHKey. \n Reply with @ref sd_ble_gap_lesc_dhkey_reply. \n See @ref ble_gap_evt_lesc_dhkey_request_t */ + BLE_GAP_EVT_AUTH_STATUS = BLE_GAP_EVT_BASE + 9, /**< Authentication procedure completed with status. \n See @ref ble_gap_evt_auth_status_t. */ + BLE_GAP_EVT_CONN_SEC_UPDATE = BLE_GAP_EVT_BASE + 10, /**< Connection security updated. \n See @ref ble_gap_evt_conn_sec_update_t. */ + BLE_GAP_EVT_TIMEOUT = BLE_GAP_EVT_BASE + 11, /**< Timeout expired. \n See @ref ble_gap_evt_timeout_t. */ + BLE_GAP_EVT_RSSI_CHANGED = BLE_GAP_EVT_BASE + 12, /**< RSSI report. \n See @ref ble_gap_evt_rssi_changed_t. */ + BLE_GAP_EVT_ADV_REPORT = BLE_GAP_EVT_BASE + 13, /**< Advertising report. \n See @ref ble_gap_evt_adv_report_t. */ + BLE_GAP_EVT_SEC_REQUEST = BLE_GAP_EVT_BASE + 14, /**< Security Request. \n See @ref ble_gap_evt_sec_request_t. */ + BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST = BLE_GAP_EVT_BASE + 15, /**< Connection Parameter Update Request. \n Reply with @ref sd_ble_gap_conn_param_update. \n See @ref ble_gap_evt_conn_param_update_request_t. */ + BLE_GAP_EVT_SCAN_REQ_REPORT = BLE_GAP_EVT_BASE + 16, /**< Scan request report. \n See @ref ble_gap_evt_scan_req_report_t. */ + BLE_GAP_EVT_PHY_UPDATE_REQUEST = BLE_GAP_EVT_BASE + 17, /**< PHY Update Request. \n Reply with @ref sd_ble_gap_phy_update. \n See @ref ble_gap_evt_phy_update_request_t. */ + BLE_GAP_EVT_PHY_UPDATE = BLE_GAP_EVT_BASE + 18, /**< PHY Update Procedure is complete. \n See @ref ble_gap_evt_phy_update_t. */ + BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST = BLE_GAP_EVT_BASE + 19, /**< Data Length Update Request. \n Reply with @ref sd_ble_gap_data_length_update.\n See @ref ble_gap_evt_data_length_update_request_t. */ + BLE_GAP_EVT_DATA_LENGTH_UPDATE = BLE_GAP_EVT_BASE + 20, /**< LL Data Channel PDU payload length updated. \n See @ref ble_gap_evt_data_length_update_t. */ + BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT = BLE_GAP_EVT_BASE + 21, /**< Channel survey report. \n See @ref ble_gap_evt_qos_channel_survey_report_t. */ + BLE_GAP_EVT_ADV_SET_TERMINATED = BLE_GAP_EVT_BASE + 22, /**< Advertising set terminated. \n See @ref ble_gap_evt_adv_set_terminated_t. */ +}; + +/**@brief GAP Option IDs. + * IDs that uniquely identify a GAP option. + */ +enum BLE_GAP_OPTS +{ + BLE_GAP_OPT_CH_MAP = BLE_GAP_OPT_BASE, /**< Channel Map. @ref ble_gap_opt_ch_map_t */ + BLE_GAP_OPT_LOCAL_CONN_LATENCY = BLE_GAP_OPT_BASE + 1, /**< Local connection latency. @ref ble_gap_opt_local_conn_latency_t */ + BLE_GAP_OPT_PASSKEY = BLE_GAP_OPT_BASE + 2, /**< Set passkey. @ref ble_gap_opt_passkey_t */ + BLE_GAP_OPT_COMPAT_MODE_1 = BLE_GAP_OPT_BASE + 3, /**< Compatibility mode. @ref ble_gap_opt_compat_mode_1_t */ + BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT = BLE_GAP_OPT_BASE + 4, /**< Set Authenticated payload timeout. @ref ble_gap_opt_auth_payload_timeout_t */ + BLE_GAP_OPT_SLAVE_LATENCY_DISABLE = BLE_GAP_OPT_BASE + 5, /**< Disable slave latency. @ref ble_gap_opt_slave_latency_disable_t */ +}; + +/**@brief GAP Configuration IDs. + * + * IDs that uniquely identify a GAP configuration. + */ +enum BLE_GAP_CFGS +{ + BLE_GAP_CFG_ROLE_COUNT = BLE_GAP_CFG_BASE, /**< Role count configuration. */ + BLE_GAP_CFG_DEVICE_NAME = BLE_GAP_CFG_BASE + 1, /**< Device name configuration. */ +}; + +/**@brief GAP TX Power roles. + */ +enum BLE_GAP_TX_POWER_ROLES +{ + BLE_GAP_TX_POWER_ROLE_ADV = 1, /**< Advertiser role. */ + BLE_GAP_TX_POWER_ROLE_SCAN_INIT = 2, /**< Scanner and initiator role. */ + BLE_GAP_TX_POWER_ROLE_CONN = 3, /**< Connection role. */ +}; + +/** @} */ + +/**@addtogroup BLE_GAP_DEFINES Defines + * @{ */ + +/**@defgroup BLE_ERRORS_GAP SVC return values specific to GAP + * @{ */ +#define BLE_ERROR_GAP_UUID_LIST_MISMATCH (NRF_GAP_ERR_BASE + 0x000) /**< UUID list does not contain an integral number of UUIDs. */ +#define BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST (NRF_GAP_ERR_BASE + 0x001) /**< Use of Whitelist not permitted with discoverable advertising. */ +#define BLE_ERROR_GAP_INVALID_BLE_ADDR (NRF_GAP_ERR_BASE + 0x002) /**< The upper two bits of the address do not correspond to the specified address type. */ +#define BLE_ERROR_GAP_WHITELIST_IN_USE (NRF_GAP_ERR_BASE + 0x003) /**< Attempt to modify the whitelist while already in use by another operation. */ +#define BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE (NRF_GAP_ERR_BASE + 0x004) /**< Attempt to modify the device identity list while already in use by another operation. */ +#define BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE (NRF_GAP_ERR_BASE + 0x005) /**< The device identity list contains entries with duplicate identity addresses. */ +/**@} */ + + +/**@defgroup BLE_GAP_ROLES GAP Roles + * @{ */ +#define BLE_GAP_ROLE_INVALID 0x0 /**< Invalid Role. */ +#define BLE_GAP_ROLE_PERIPH 0x1 /**< Peripheral Role. */ +#define BLE_GAP_ROLE_CENTRAL 0x2 /**< Central Role. */ +/**@} */ + + +/**@defgroup BLE_GAP_TIMEOUT_SOURCES GAP Timeout sources + * @{ */ +#define BLE_GAP_TIMEOUT_SRC_SCAN 0x01 /**< Scanning timeout. */ +#define BLE_GAP_TIMEOUT_SRC_CONN 0x02 /**< Connection timeout. */ +#define BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD 0x03 /**< Authenticated payload timeout. */ +/**@} */ + + +/**@defgroup BLE_GAP_ADDR_TYPES GAP Address types + * @{ */ +#define BLE_GAP_ADDR_TYPE_PUBLIC 0x00 /**< Public (identity) address.*/ +#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 /**< Random static (identity) address. */ +#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02 /**< Random private resolvable address. */ +#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03 /**< Random private non-resolvable address. */ +#define BLE_GAP_ADDR_TYPE_ANONYMOUS 0x7F /**< An advertiser may advertise without its address. + This type of advertising is called anonymous. */ +/**@} */ + + +/**@brief The default interval in seconds at which a private address is refreshed. */ +#define BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S (900) /* 15 minutes. */ +/**@brief The maximum interval in seconds at which a private address can be refreshed. */ +#define BLE_GAP_MAX_PRIVATE_ADDR_CYCLE_INTERVAL_S (41400) /* 11 hours 30 minutes. */ + + +/** @brief BLE address length. */ +#define BLE_GAP_ADDR_LEN (6) + +/**@defgroup BLE_GAP_PRIVACY_MODES Privacy modes + * @{ */ +#define BLE_GAP_PRIVACY_MODE_OFF 0x00 /**< Device will send and accept its identity address for its own address. */ +#define BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY 0x01 /**< Device will send and accept only private addresses for its own address. */ +#define BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY 0x02 /**< Device will send and accept only private addresses for its own address, + and will not accept a peer using identity address as sender address when + the peer IRK is exchanged, non-zero and added to the identity list. */ +/**@} */ + +/** @brief Invalid power level. */ +#define BLE_GAP_POWER_LEVEL_INVALID 127 + +/** @brief Advertising set handle not set. */ +#define BLE_GAP_ADV_SET_HANDLE_NOT_SET (0xFF) + +/** @brief The default number of advertising sets. */ +#define BLE_GAP_ADV_SET_COUNT_DEFAULT (1) + +/** @brief The maximum number of advertising sets supported by this SoftDevice. */ +#define BLE_GAP_ADV_SET_COUNT_MAX (1) + +/**@defgroup BLE_GAP_ADV_SET_DATA_SIZES Advertising data sizes. + * @{ */ +#define BLE_GAP_ADV_SET_DATA_SIZE_MAX (31) /**< Maximum data length for an advertising set. + If more advertising data is required, use extended advertising instead. */ +#define BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED (255) /**< Maximum supported data length for an extended advertising set. */ + +#define BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED (238) /**< Maximum supported data length for an extended connectable advertising set. */ +/**@}. */ + +/** @brief Set ID not available in advertising report. */ +#define BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE 0xFF + +/**@defgroup BLE_GAP_EVT_ADV_SET_TERMINATED_REASON GAP Advertising Set Terminated reasons + * @{ */ +#define BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_TIMEOUT 0x01 /**< Timeout value reached. */ +#define BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_LIMIT_REACHED 0x02 /**< @ref ble_gap_adv_params_t::max_adv_evts was reached. */ +/**@} */ + +/**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format + * @note Found at https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm + * @{ */ +#define BLE_GAP_AD_TYPE_FLAGS 0x01 /**< Flags for discoverability. */ +#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE 0x02 /**< Partial list of 16 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE 0x03 /**< Complete list of 16 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE 0x04 /**< Partial list of 32 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE 0x05 /**< Complete list of 32 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE 0x06 /**< Partial list of 128 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE 0x07 /**< Complete list of 128 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME 0x08 /**< Short local device name. */ +#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 0x09 /**< Complete local device name. */ +#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL 0x0A /**< Transmit power level. */ +#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE 0x0D /**< Class of device. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C 0x0E /**< Simple Pairing Hash C. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R 0x0F /**< Simple Pairing Randomizer R. */ +#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE 0x10 /**< Security Manager TK Value. */ +#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS 0x11 /**< Security Manager Out Of Band Flags. */ +#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE 0x12 /**< Slave Connection Interval Range. */ +#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT 0x14 /**< List of 16-bit Service Solicitation UUIDs. */ +#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT 0x15 /**< List of 128-bit Service Solicitation UUIDs. */ +#define BLE_GAP_AD_TYPE_SERVICE_DATA 0x16 /**< Service Data - 16-bit UUID. */ +#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS 0x17 /**< Public Target Address. */ +#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS 0x18 /**< Random Target Address. */ +#define BLE_GAP_AD_TYPE_APPEARANCE 0x19 /**< Appearance. */ +#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A /**< Advertising Interval. */ +#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B /**< LE Bluetooth Device Address. */ +#define BLE_GAP_AD_TYPE_LE_ROLE 0x1C /**< LE Role. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 0x1D /**< Simple Pairing Hash C-256. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E /**< Simple Pairing Randomizer R-256. */ +#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20 /**< Service Data - 32-bit UUID. */ +#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21 /**< Service Data - 128-bit UUID. */ +#define BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE 0x22 /**< LE Secure Connections Confirmation Value */ +#define BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE 0x23 /**< LE Secure Connections Random Value */ +#define BLE_GAP_AD_TYPE_URI 0x24 /**< URI */ +#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D /**< 3D Information Data. */ +#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF /**< Manufacturer Specific Data. */ +/**@} */ + + +/**@defgroup BLE_GAP_ADV_FLAGS GAP Advertisement Flags + * @{ */ +#define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE (0x01) /**< LE Limited Discoverable Mode. */ +#define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02) /**< LE General Discoverable Mode. */ +#define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04) /**< BR/EDR not supported. */ +#define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER (0x08) /**< Simultaneous LE and BR/EDR, Controller. */ +#define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST (0x10) /**< Simultaneous LE and BR/EDR, Host. */ +#define BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE (BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE Limited Discoverable Mode, BR/EDR not supported. */ +#define BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE (BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE General Discoverable Mode, BR/EDR not supported. */ +/**@} */ + + +/**@defgroup BLE_GAP_ADV_INTERVALS GAP Advertising interval max and min + * @{ */ +#define BLE_GAP_ADV_INTERVAL_MIN 0x000020 /**< Minimum Advertising interval in 625 us units, i.e. 20 ms. */ +#define BLE_GAP_ADV_INTERVAL_MAX 0x004000 /**< Maximum Advertising interval in 625 us units, i.e. 10.24 s. */ + /**@} */ + + +/**@defgroup BLE_GAP_SCAN_INTERVALS GAP Scan interval max and min + * @{ */ +#define BLE_GAP_SCAN_INTERVAL_MIN 0x0004 /**< Minimum Scan interval in 625 us units, i.e. 2.5 ms. */ +#define BLE_GAP_SCAN_INTERVAL_MAX 0xFFFF /**< Maximum Scan interval in 625 us units, i.e. 40,959.375 s. */ + /** @} */ + + +/**@defgroup BLE_GAP_SCAN_WINDOW GAP Scan window max and min + * @{ */ +#define BLE_GAP_SCAN_WINDOW_MIN 0x0004 /**< Minimum Scan window in 625 us units, i.e. 2.5 ms. */ +#define BLE_GAP_SCAN_WINDOW_MAX 0xFFFF /**< Maximum Scan window in 625 us units, i.e. 40,959.375 s. */ + /** @} */ + + +/**@defgroup BLE_GAP_SCAN_TIMEOUT GAP Scan timeout max and min + * @{ */ +#define BLE_GAP_SCAN_TIMEOUT_MIN 0x0001 /**< Minimum Scan timeout in 10 ms units, i.e 10 ms. */ +#define BLE_GAP_SCAN_TIMEOUT_UNLIMITED 0x0000 /**< Continue to scan forever. */ + /** @} */ + +/**@defgroup BLE_GAP_SCAN_BUFFER_SIZE GAP Minimum scanner buffer size + * + * Scan buffers are used for storing advertising data received from an advertiser. + * If ble_gap_scan_params_t::extended is set to 0, @ref BLE_GAP_SCAN_BUFFER_MIN is the minimum scan buffer length. + * else the minimum scan buffer size is @ref BLE_GAP_SCAN_BUFFER_EXTENDED_MIN. + * @{ */ +#define BLE_GAP_SCAN_BUFFER_MIN (31) /**< Minimum data length for an + advertising set. */ +#define BLE_GAP_SCAN_BUFFER_MAX (31) /**< Maximum data length for an + advertising set. */ +#define BLE_GAP_SCAN_BUFFER_EXTENDED_MIN (255) /**< Minimum data length for an + extended advertising set. */ +#define BLE_GAP_SCAN_BUFFER_EXTENDED_MAX (1650) /**< Maximum data length for an + extended advertising set. */ +#define BLE_GAP_SCAN_BUFFER_EXTENDED_MAX_SUPPORTED (255) /**< Maximum supported data length for + an extended advertising set. */ +/** @} */ + +/**@defgroup BLE_GAP_ADV_TYPES GAP Advertising types + * + * Advertising types defined in Bluetooth Core Specification v5.0, Vol 6, Part B, Section 4.4.2. + * + * The maximum advertising data length is defined by @ref BLE_GAP_ADV_SET_DATA_SIZE_MAX. + * The maximum supported data length for an extended advertiser is defined by + * @ref BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED + * Note that some of the advertising types do not support advertising data. Non-scannable types do not support + * scan response data. + * + * @{ */ +#define BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED 0x01 /**< Connectable and scannable undirected + advertising events. */ +#define BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE 0x02 /**< Connectable non-scannable directed advertising + events. Advertising interval is less that 3.75 ms. + Use this type for fast reconnections. + @note Advertising data is not supported. */ +#define BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED 0x03 /**< Connectable non-scannable directed advertising + events. + @note Advertising data is not supported. */ +#define BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED 0x04 /**< Non-connectable scannable undirected + advertising events. */ +#define BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED 0x05 /**< Non-connectable non-scannable undirected + advertising events. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED 0x06 /**< Connectable non-scannable undirected advertising + events using extended advertising PDUs. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_DIRECTED 0x07 /**< Connectable non-scannable directed advertising + events using extended advertising PDUs. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_UNDIRECTED 0x08 /**< Non-connectable scannable undirected advertising + events using extended advertising PDUs. + @note Only scan response data is supported. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_DIRECTED 0x09 /**< Non-connectable scannable directed advertising + events using extended advertising PDUs. + @note Only scan response data is supported. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED 0x0A /**< Non-connectable non-scannable undirected advertising + events using extended advertising PDUs. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_DIRECTED 0x0B /**< Non-connectable non-scannable directed advertising + events using extended advertising PDUs. */ +/**@} */ + +/**@defgroup BLE_GAP_ADV_FILTER_POLICIES GAP Advertising filter policies + * @{ */ +#define BLE_GAP_ADV_FP_ANY 0x00 /**< Allow scan requests and connect requests from any device. */ +#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01 /**< Filter scan requests with whitelist. */ +#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02 /**< Filter connect requests with whitelist. */ +#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03 /**< Filter both scan and connect requests with whitelist. */ +/**@} */ + +/**@defgroup BLE_GAP_ADV_DATA_STATUS GAP Advertising data status + * @{ */ +#define BLE_GAP_ADV_DATA_STATUS_COMPLETE 0x00 /**< All data in the advertising event have been received. */ +#define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA 0x01 /**< More data to be received. + @note This value will only be used if + @ref ble_gap_scan_params_t::report_incomplete_evts and + @ref ble_gap_adv_report_type_t::extended_pdu are set to true. */ +#define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_TRUNCATED 0x02 /**< Incomplete data. Buffer size insufficient to receive more. + @note This value will only be used if + @ref ble_gap_adv_report_type_t::extended_pdu is set to true. */ +#define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MISSED 0x03 /**< Failed to receive the remaining data. + @note This value will only be used if + @ref ble_gap_adv_report_type_t::extended_pdu is set to true. */ +/**@} */ + +/**@defgroup BLE_GAP_SCAN_FILTER_POLICIES GAP Scanner filter policies + * @{ */ +#define BLE_GAP_SCAN_FP_ACCEPT_ALL 0x00 /**< Accept all advertising packets except directed advertising packets + not addressed to this device. */ +#define BLE_GAP_SCAN_FP_WHITELIST 0x01 /**< Accept advertising packets from devices in the whitelist except directed + packets not addressed to this device. */ +#define BLE_GAP_SCAN_FP_ALL_NOT_RESOLVED_DIRECTED 0x02 /**< Accept all advertising packets specified in @ref BLE_GAP_SCAN_FP_ACCEPT_ALL. + In addition, accept directed advertising packets, where the advertiser's + address is a resolvable private address that cannot be resolved. */ +#define BLE_GAP_SCAN_FP_WHITELIST_NOT_RESOLVED_DIRECTED 0x03 /**< Accept all advertising packets specified in @ref BLE_GAP_SCAN_FP_WHITELIST. + In addition, accept directed advertising packets, where the advertiser's + address is a resolvable private address that cannot be resolved. */ +/**@} */ + +/**@defgroup BLE_GAP_ADV_TIMEOUT_VALUES GAP Advertising timeout values in 10 ms units + * @{ */ +#define BLE_GAP_ADV_TIMEOUT_HIGH_DUTY_MAX (128) /**< Maximum high duty advertising time in 10 ms units. Corresponds to 1.28 s. */ +#define BLE_GAP_ADV_TIMEOUT_LIMITED_MAX (18000) /**< Maximum advertising time in 10 ms units corresponding to TGAP(lim_adv_timeout) = 180 s in limited discoverable mode. */ +#define BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED (0) /**< Unlimited advertising in general discoverable mode. + For high duty cycle advertising, this corresponds to @ref BLE_GAP_ADV_TIMEOUT_HIGH_DUTY_MAX. */ +/**@} */ + + +/**@defgroup BLE_GAP_DISC_MODES GAP Discovery modes + * @{ */ +#define BLE_GAP_DISC_MODE_NOT_DISCOVERABLE 0x00 /**< Not discoverable discovery Mode. */ +#define BLE_GAP_DISC_MODE_LIMITED 0x01 /**< Limited Discovery Mode. */ +#define BLE_GAP_DISC_MODE_GENERAL 0x02 /**< General Discovery Mode. */ +/**@} */ + + +/**@defgroup BLE_GAP_IO_CAPS GAP IO Capabilities + * @{ */ +#define BLE_GAP_IO_CAPS_DISPLAY_ONLY 0x00 /**< Display Only. */ +#define BLE_GAP_IO_CAPS_DISPLAY_YESNO 0x01 /**< Display and Yes/No entry. */ +#define BLE_GAP_IO_CAPS_KEYBOARD_ONLY 0x02 /**< Keyboard Only. */ +#define BLE_GAP_IO_CAPS_NONE 0x03 /**< No I/O capabilities. */ +#define BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY 0x04 /**< Keyboard and Display. */ +/**@} */ + + +/**@defgroup BLE_GAP_AUTH_KEY_TYPES GAP Authentication Key Types + * @{ */ +#define BLE_GAP_AUTH_KEY_TYPE_NONE 0x00 /**< No key (may be used to reject). */ +#define BLE_GAP_AUTH_KEY_TYPE_PASSKEY 0x01 /**< 6-digit Passkey. */ +#define BLE_GAP_AUTH_KEY_TYPE_OOB 0x02 /**< Out Of Band data. */ +/**@} */ + + +/**@defgroup BLE_GAP_KP_NOT_TYPES GAP Keypress Notification Types + * @{ */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_START 0x00 /**< Passkey entry started. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_IN 0x01 /**< Passkey digit entered. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_OUT 0x02 /**< Passkey digit erased. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_CLEAR 0x03 /**< Passkey cleared. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_END 0x04 /**< Passkey entry completed. */ +/**@} */ + + +/**@defgroup BLE_GAP_SEC_STATUS GAP Security status + * @{ */ +#define BLE_GAP_SEC_STATUS_SUCCESS 0x00 /**< Procedure completed with success. */ +#define BLE_GAP_SEC_STATUS_TIMEOUT 0x01 /**< Procedure timed out. */ +#define BLE_GAP_SEC_STATUS_PDU_INVALID 0x02 /**< Invalid PDU received. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE1_BEGIN 0x03 /**< Reserved for Future Use range #1 begin. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE1_END 0x80 /**< Reserved for Future Use range #1 end. */ +#define BLE_GAP_SEC_STATUS_PASSKEY_ENTRY_FAILED 0x81 /**< Passkey entry failed (user canceled or other). */ +#define BLE_GAP_SEC_STATUS_OOB_NOT_AVAILABLE 0x82 /**< Out of Band Key not available. */ +#define BLE_GAP_SEC_STATUS_AUTH_REQ 0x83 /**< Authentication requirements not met. */ +#define BLE_GAP_SEC_STATUS_CONFIRM_VALUE 0x84 /**< Confirm value failed. */ +#define BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP 0x85 /**< Pairing not supported. */ +#define BLE_GAP_SEC_STATUS_ENC_KEY_SIZE 0x86 /**< Encryption key size. */ +#define BLE_GAP_SEC_STATUS_SMP_CMD_UNSUPPORTED 0x87 /**< Unsupported SMP command. */ +#define BLE_GAP_SEC_STATUS_UNSPECIFIED 0x88 /**< Unspecified reason. */ +#define BLE_GAP_SEC_STATUS_REPEATED_ATTEMPTS 0x89 /**< Too little time elapsed since last attempt. */ +#define BLE_GAP_SEC_STATUS_INVALID_PARAMS 0x8A /**< Invalid parameters. */ +#define BLE_GAP_SEC_STATUS_DHKEY_FAILURE 0x8B /**< DHKey check failure. */ +#define BLE_GAP_SEC_STATUS_NUM_COMP_FAILURE 0x8C /**< Numeric Comparison failure. */ +#define BLE_GAP_SEC_STATUS_BR_EDR_IN_PROG 0x8D /**< BR/EDR pairing in progress. */ +#define BLE_GAP_SEC_STATUS_X_TRANS_KEY_DISALLOWED 0x8E /**< BR/EDR Link Key cannot be used for LE keys. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE2_BEGIN 0x8F /**< Reserved for Future Use range #2 begin. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE2_END 0xFF /**< Reserved for Future Use range #2 end. */ +/**@} */ + + +/**@defgroup BLE_GAP_SEC_STATUS_SOURCES GAP Security status sources + * @{ */ +#define BLE_GAP_SEC_STATUS_SOURCE_LOCAL 0x00 /**< Local failure. */ +#define BLE_GAP_SEC_STATUS_SOURCE_REMOTE 0x01 /**< Remote failure. */ +/**@} */ + + +/**@defgroup BLE_GAP_CP_LIMITS GAP Connection Parameters Limits + * @{ */ +#define BLE_GAP_CP_MIN_CONN_INTVL_NONE 0xFFFF /**< No new minimum connection interval specified in connect parameters. */ +#define BLE_GAP_CP_MIN_CONN_INTVL_MIN 0x0006 /**< Lowest minimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ +#define BLE_GAP_CP_MIN_CONN_INTVL_MAX 0x0C80 /**< Highest minimum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ +#define BLE_GAP_CP_MAX_CONN_INTVL_NONE 0xFFFF /**< No new maximum connection interval specified in connect parameters. */ +#define BLE_GAP_CP_MAX_CONN_INTVL_MIN 0x0006 /**< Lowest maximum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ +#define BLE_GAP_CP_MAX_CONN_INTVL_MAX 0x0C80 /**< Highest maximum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ +#define BLE_GAP_CP_SLAVE_LATENCY_MAX 0x01F3 /**< Highest slave latency permitted, in connection events. */ +#define BLE_GAP_CP_CONN_SUP_TIMEOUT_NONE 0xFFFF /**< No new supervision timeout specified in connect parameters. */ +#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN 0x000A /**< Lowest supervision timeout permitted, in units of 10 ms, i.e. 100 ms. */ +#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MAX 0x0C80 /**< Highest supervision timeout permitted, in units of 10 ms, i.e. 32 s. */ +/**@} */ + + +/**@defgroup BLE_GAP_DEVNAME GAP device name defines. + * @{ */ +#define BLE_GAP_DEVNAME_DEFAULT "nRF5x" /**< Default device name value. */ +#define BLE_GAP_DEVNAME_DEFAULT_LEN 31 /**< Default number of octets in device name. */ +#define BLE_GAP_DEVNAME_MAX_LEN 248 /**< Maximum number of octets in device name. */ +/**@} */ + + +/**@brief Disable RSSI events for connections */ +#define BLE_GAP_RSSI_THRESHOLD_INVALID 0xFF + +/**@defgroup BLE_GAP_PHYS GAP PHYs + * @{ */ +#define BLE_GAP_PHY_AUTO 0x00 /**< Automatic PHY selection. Refer @ref sd_ble_gap_phy_update for more information.*/ +#define BLE_GAP_PHY_1MBPS 0x01 /**< 1 Mbps PHY. */ +#define BLE_GAP_PHY_2MBPS 0x02 /**< 2 Mbps PHY. */ +#define BLE_GAP_PHY_CODED 0x04 /**< Coded PHY. */ +#define BLE_GAP_PHY_NOT_SET 0xFF /**< PHY is not configured. */ + +/**@brief Supported PHYs in connections, for scanning, and for advertising. */ +#define BLE_GAP_PHYS_SUPPORTED (BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS | BLE_GAP_PHY_CODED) /**< All PHYs are supported. */ + +/**@} */ + +/**@defgroup BLE_GAP_CONN_SEC_MODE_SET_MACROS GAP attribute security requirement setters + * + * See @ref ble_gap_conn_sec_mode_t. + * @{ */ +/**@brief Set sec_mode pointed to by ptr to have no access rights.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0) +/**@brief Set sec_mode pointed to by ptr to require no protection, open link.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0) +/**@brief Set sec_mode pointed to by ptr to require encryption, but no MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0) +/**@brief Set sec_mode pointed to by ptr to require encryption and MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0) +/**@brief Set sec_mode pointed to by ptr to require LESC encryption and MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 4;} while(0) +/**@brief Set sec_mode pointed to by ptr to require signing or encryption, no MITM protection needed.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0) +/**@brief Set sec_mode pointed to by ptr to require signing or encryption with MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0) +/**@} */ + + +/**@brief GAP Security Random Number Length. */ +#define BLE_GAP_SEC_RAND_LEN 8 + + +/**@brief GAP Security Key Length. */ +#define BLE_GAP_SEC_KEY_LEN 16 + + +/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key Length. */ +#define BLE_GAP_LESC_P256_PK_LEN 64 + + +/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman DHKey Length. */ +#define BLE_GAP_LESC_DHKEY_LEN 32 + + +/**@brief GAP Passkey Length. */ +#define BLE_GAP_PASSKEY_LEN 6 + + +/**@brief Maximum amount of addresses in the whitelist. */ +#define BLE_GAP_WHITELIST_ADDR_MAX_COUNT (8) + + +/**@brief Maximum amount of identities in the device identities list. */ +#define BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT (8) + + +/**@brief Default connection count for a configuration. */ +#define BLE_GAP_CONN_COUNT_DEFAULT (1) + + +/**@defgroup BLE_GAP_EVENT_LENGTH GAP event length defines. + * @{ */ +#define BLE_GAP_EVENT_LENGTH_MIN (2) /**< Minimum event length, in 1.25 ms units. */ +#define BLE_GAP_EVENT_LENGTH_CODED_PHY_MIN (6) /**< The shortest event length in 1.25 ms units supporting LE Coded PHY. */ +#define BLE_GAP_EVENT_LENGTH_DEFAULT (3) /**< Default event length, in 1.25 ms units. */ +/**@} */ + + +/**@defgroup BLE_GAP_ROLE_COUNT GAP concurrent connection count defines. + * @{ */ +#define BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT (1) /**< Default maximum number of connections concurrently acting as peripherals. */ +#define BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT (3) /**< Default maximum number of connections concurrently acting as centrals. */ +#define BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT (1) /**< Default number of SMP instances shared between all connections acting as centrals. */ +#define BLE_GAP_ROLE_COUNT_COMBINED_MAX (20) /**< Maximum supported number of concurrent connections in the peripheral and central roles combined. */ + +/**@} */ + +/**@brief Automatic data length parameter. */ +#define BLE_GAP_DATA_LENGTH_AUTO 0 + +/**@defgroup BLE_GAP_AUTH_PAYLOAD_TIMEOUT Authenticated payload timeout defines. + * @{ */ +#define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX (48000) /**< Maximum authenticated payload timeout in 10 ms units, i.e. 8 minutes. */ +#define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MIN (1) /**< Minimum authenticated payload timeout in 10 ms units, i.e. 10 ms. */ +/**@} */ + +/**@defgroup GAP_SEC_MODES GAP Security Modes + * @{ */ +#define BLE_GAP_SEC_MODE 0x00 /**< No key (may be used to reject). */ +/**@} */ + +/**@brief The total number of channels in Bluetooth Low Energy. */ +#define BLE_GAP_CHANNEL_COUNT (40) + +/**@defgroup BLE_GAP_QOS_CHANNEL_SURVEY_INTERVALS Quality of Service (QoS) Channel survey interval defines + * @{ */ +#define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_CONTINUOUS (0) /**< Continuous channel survey. */ +#define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_MIN_US (7500) /**< Minimum channel survey interval in microseconds (7.5 ms). */ +#define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_MAX_US (4000000) /**< Maximum channel survey interval in microseconds (4 s). */ + /**@} */ + +/** @} */ + + +/**@addtogroup BLE_GAP_STRUCTURES Structures + * @{ */ + +/**@brief Advertising event properties. */ +typedef struct +{ + uint8_t type; /**< Advertising type. See @ref BLE_GAP_ADV_TYPES. */ + uint8_t anonymous : 1; /**< Omit advertiser's address from all PDUs. + @note Anonymous advertising is only available for + @ref BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED and + @ref BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_DIRECTED. */ + uint8_t include_tx_power : 1; /**< This feature is not supported on this SoftDevice. */ +} ble_gap_adv_properties_t; + + +/**@brief Advertising report type. */ +typedef struct +{ + uint16_t connectable : 1; /**< Connectable advertising event type. */ + uint16_t scannable : 1; /**< Scannable advertising event type. */ + uint16_t directed : 1; /**< Directed advertising event type. */ + uint16_t scan_response : 1; /**< Received a scan response. */ + uint16_t extended_pdu : 1; /**< Received an extended advertising set. */ + uint16_t status : 2; /**< Data status. See @ref BLE_GAP_ADV_DATA_STATUS. */ + uint16_t reserved : 9; /**< Reserved for future use. */ +} ble_gap_adv_report_type_t; + +/**@brief Advertising Auxiliary Pointer. */ +typedef struct +{ + uint16_t aux_offset; /**< Time offset from the beginning of advertising packet to the auxiliary packet in 100 us units. */ + uint8_t aux_phy; /**< Indicates the PHY on which the auxiliary advertising packet is sent. See @ref BLE_GAP_PHYS. */ +} ble_gap_aux_pointer_t; + +/**@brief Bluetooth Low Energy address. */ +typedef struct +{ + uint8_t addr_id_peer : 1; /**< Only valid for peer addresses. + This bit is set by the SoftDevice to indicate whether the address has been resolved from + a Resolvable Private Address (when the peer is using privacy). + If set to 1, @ref addr and @ref addr_type refer to the identity address of the resolved address. + + This bit is ignored when a variable of type @ref ble_gap_addr_t is used as input to API functions. */ + uint8_t addr_type : 7; /**< See @ref BLE_GAP_ADDR_TYPES. */ + uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format. + @ref addr is not used if @ref addr_type is @ref BLE_GAP_ADDR_TYPE_ANONYMOUS. */ +} ble_gap_addr_t; + + +/**@brief GAP connection parameters. + * + * @note When ble_conn_params_t is received in an event, both min_conn_interval and + * max_conn_interval will be equal to the connection interval set by the central. + * + * @note If both conn_sup_timeout and max_conn_interval are specified, then the following constraint applies: + * conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval + * that corresponds to the following Bluetooth Spec requirement: + * The Supervision_Timeout in milliseconds shall be larger than + * (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds. + */ +typedef struct +{ + uint16_t min_conn_interval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t max_conn_interval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t slave_latency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t conn_sup_timeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/ +} ble_gap_conn_params_t; + + +/**@brief GAP connection security modes. + * + * Security Mode 0 Level 0: No access permissions at all (this level is not defined by the Bluetooth Core specification).\n + * Security Mode 1 Level 1: No security is needed (aka open link).\n + * Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n + * Security Mode 1 Level 3: MITM protected encrypted link required.\n + * Security Mode 1 Level 4: LESC MITM protected encrypted link using a 128-bit strength encryption key required.\n + * Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n + * Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n + */ +typedef struct +{ + uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */ + uint8_t lv : 4; /**< Level (1, 2, 3 or 4), 0 for no permissions at all. */ + +} ble_gap_conn_sec_mode_t; + + +/**@brief GAP connection security status.*/ +typedef struct +{ + ble_gap_conn_sec_mode_t sec_mode; /**< Currently active security mode for this connection.*/ + uint8_t encr_key_size; /**< Length of currently active encryption key, 7 to 16 octets (only applicable for bonding procedures). */ +} ble_gap_conn_sec_t; + +/**@brief Identity Resolving Key. */ +typedef struct +{ + uint8_t irk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing IRK. */ +} ble_gap_irk_t; + + +/**@brief Channel mask (40 bits). + * Every channel is represented with a bit positioned as per channel index defined in Bluetooth Core Specification v5.0, + * Vol 6, Part B, Section 1.4.1. The LSB contained in array element 0 represents channel index 0, and bit 39 represents + * channel index 39. If a bit is set to 1, the channel is not used. + */ +typedef uint8_t ble_gap_ch_mask_t[5]; + + +/**@brief GAP advertising parameters. */ +typedef struct +{ + ble_gap_adv_properties_t properties; /**< The properties of the advertising events. */ + ble_gap_addr_t const *p_peer_addr; /**< Address of a known peer. + @note ble_gap_addr_t::addr_type cannot be + @ref BLE_GAP_ADDR_TYPE_ANONYMOUS. + - When privacy is enabled and the local device uses + @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE addresses, + the device identity list is searched for a matching entry. If + the local IRK for that device identity is set, the local IRK + for that device will be used to generate the advertiser address + field in the advertising packet. + - If @ref ble_gap_adv_properties_t::type is directed, this must be + set to the targeted scanner or initiator. If the peer address is + in the device identity list, the peer IRK for that device will be + used to generate @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE + target addresses used in the advertising event PDUs. */ + uint32_t interval; /**< Advertising interval in 625 us units. @sa BLE_GAP_ADV_INTERVALS. + @note If @ref ble_gap_adv_properties_t::type is set to + @ref BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE + advertising, this parameter is ignored. */ + uint16_t duration; /**< Advertising duration in 10 ms units. When timeout is reached, + an event of type @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised. + @sa BLE_GAP_ADV_TIMEOUT_VALUES. + @note The SoftDevice will always complete at least one advertising + event even if the duration is set too low. */ + uint8_t max_adv_evts; /**< Maximum advertising events that shall be sent prior to disabling + advertising. Setting the value to 0 disables the limitation. When + the count of advertising events specified by this parameter + (if not 0) is reached, advertising will be automatically stopped + and an event of type @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised + @note If @ref ble_gap_adv_properties_t::type is set to + @ref BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE, + this parameter is ignored. */ + ble_gap_ch_mask_t channel_mask; /**< Channel mask for primary and secondary advertising channels. + At least one of the primary channels, that is channel index 37-39, must be used. + Masking away secondary advertising channels is not supported. */ + uint8_t filter_policy; /**< Filter Policy. @sa BLE_GAP_ADV_FILTER_POLICIES. */ + uint8_t primary_phy; /**< Indicates the PHY on which the primary advertising channel packets + are transmitted. If set to @ref BLE_GAP_PHY_AUTO, @ref BLE_GAP_PHY_1MBPS + will be used. + Valid values are @ref BLE_GAP_PHY_1MBPS and @ref BLE_GAP_PHY_CODED. + @note The primary_phy shall indicate @ref BLE_GAP_PHY_1MBPS if + @ref ble_gap_adv_properties_t::type is not an extended advertising type. */ + uint8_t secondary_phy; /**< Indicates the PHY on which the secondary advertising channel packets + are transmitted. + If set to @ref BLE_GAP_PHY_AUTO, @ref BLE_GAP_PHY_1MBPS will be used. + Valid values are + @ref BLE_GAP_PHY_1MBPS, @ref BLE_GAP_PHY_2MBPS, and @ref BLE_GAP_PHY_CODED. + If @ref ble_gap_adv_properties_t::type is an extended advertising type + and connectable, this is the PHY that will be used to establish a + connection and send AUX_ADV_IND packets on. + @note This parameter will be ignored when + @ref ble_gap_adv_properties_t::type is not an extended advertising type. */ + uint8_t set_id:4; /**< The advertising set identifier distinguishes this advertising set from other + advertising sets transmitted by this and other devices. + @note This parameter will be ignored when + @ref ble_gap_adv_properties_t::type is not an extended advertising type. */ + uint8_t scan_req_notification:1; /**< Enable scan request notifications for this advertising set. When a + scan request is received and the scanner address is allowed + by the filter policy, @ref BLE_GAP_EVT_SCAN_REQ_REPORT is raised. + @note This parameter will be ignored when + @ref ble_gap_adv_properties_t::type is a non-scannable + advertising type. */ +} ble_gap_adv_params_t; + + +/**@brief GAP advertising data buffers. + * + * The application must provide the buffers for advertisement. The memory shall reside in application RAM, and + * shall never be modified while advertising. The data shall be kept alive until either: + * - @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised. + * - @ref BLE_GAP_EVT_CONNECTED is raised with @ref ble_gap_evt_connected_t::adv_handle set to the corresponding + * advertising handle. + * - Advertising is stopped. + * - Advertising data is changed. + * To update advertising data while advertising, provide new buffers to @ref sd_ble_gap_adv_set_configure. */ +typedef struct +{ + ble_data_t adv_data; /**< Advertising data. + @note + Advertising data can only be specified for a @ref ble_gap_adv_properties_t::type + that is allowed to contain advertising data. */ + ble_data_t scan_rsp_data; /**< Scan response data. + @note + Scan response data can only be specified for a @ref ble_gap_adv_properties_t::type + that is scannable. */ +} ble_gap_adv_data_t; + + +/**@brief GAP scanning parameters. */ +typedef struct +{ + uint8_t extended : 1; /**< If 1, the scanner will accept extended advertising packets. + If set to 0, the scanner will not receive advertising packets + on secondary advertising channels, and will not be able + to receive long advertising PDUs. */ + uint8_t report_incomplete_evts : 1; /**< If 1, events of type @ref ble_gap_evt_adv_report_t may have + @ref ble_gap_adv_report_type_t::status set to + @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. + This parameter is ignored when used with @ref sd_ble_gap_connect + @note This may be used to abort receiving more packets from an extended + advertising event, and is only available for extended + scanning, see @ref sd_ble_gap_scan_start. + @note This feature is not supported by this SoftDevice. */ + uint8_t active : 1; /**< If 1, perform active scanning by sending scan requests. + This parameter is ignored when used with @ref sd_ble_gap_connect. */ + uint8_t filter_policy : 2; /**< Scanning filter policy. @sa BLE_GAP_SCAN_FILTER_POLICIES. + @note Only @ref BLE_GAP_SCAN_FP_ACCEPT_ALL and + @ref BLE_GAP_SCAN_FP_WHITELIST are valid when used with + @ref sd_ble_gap_connect */ + uint8_t scan_phys; /**< Bitfield of PHYs to scan on. If set to @ref BLE_GAP_PHY_AUTO, + scan_phys will default to @ref BLE_GAP_PHY_1MBPS. + - If @ref ble_gap_scan_params_t::extended is set to 0, the only + supported PHY is @ref BLE_GAP_PHY_1MBPS. + - When used with @ref sd_ble_gap_scan_start, + the bitfield indicates the PHYs the scanner will use for scanning + on primary advertising channels. The scanner will accept + @ref BLE_GAP_PHYS_SUPPORTED as secondary advertising channel PHYs. + - When used with @ref sd_ble_gap_connect, the + bitfield indicates the PHYs on where a connection may be initiated. + If scan_phys contains @ref BLE_GAP_PHY_1MBPS and/or @ref BLE_GAP_PHY_2MBPS, + the primary scan PHY is @ref BLE_GAP_PHY_1MBPS. + If scan_phys also contains @ref BLE_GAP_PHY_CODED, the primary scan + PHY will also contain @ref BLE_GAP_PHY_CODED. If the only scan PHY is + @ref BLE_GAP_PHY_CODED, the primary scan PHY is + @ref BLE_GAP_PHY_CODED only. */ + uint16_t interval; /**< Scan interval in 625 us units. @sa BLE_GAP_SCAN_INTERVALS. */ + uint16_t window; /**< Scan window in 625 us units. @sa BLE_GAP_SCAN_WINDOW. + If scan_phys contains both @ref BLE_GAP_PHY_1MBPS and + @ref BLE_GAP_PHY_CODED interval shall be larger than or + equal to twice the scan window. */ + uint16_t timeout; /**< Scan timeout in 10 ms units. @sa BLE_GAP_SCAN_TIMEOUT. */ + ble_gap_ch_mask_t channel_mask; /**< Channel mask for primary and secondary advertising channels. + At least one of the primary channels, that is channel index 37-39, must be + set to 0. + Masking away secondary channels is not supported. */ +} ble_gap_scan_params_t; + + +/**@brief Privacy. + * + * The privacy feature provides a way for the device to avoid being tracked over a period of time. + * The privacy feature, when enabled, hides the local device identity and replaces it with a private address + * that is automatically refreshed at a specified interval. + * + * If a device still wants to be recognized by other peers, it needs to share it's Identity Resolving Key (IRK). + * With this key, a device can generate a random private address that can only be recognized by peers in possession of that key, + * and devices can establish connections without revealing their real identities. + * + * Both network privacy (@ref BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY) and device privacy (@ref BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY) + * are supported. + * + * @note If the device IRK is updated, the new IRK becomes the one to be distributed in all + * bonding procedures performed after @ref sd_ble_gap_privacy_set returns. + * The IRK distributed during bonding procedure is the device IRK that is active when @ref sd_ble_gap_sec_params_reply is called. + */ +typedef struct +{ + uint8_t privacy_mode; /**< Privacy mode, see @ref BLE_GAP_PRIVACY_MODES. Default is @ref BLE_GAP_PRIVACY_MODE_OFF. */ + uint8_t private_addr_type; /**< The private address type must be either @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */ + uint16_t private_addr_cycle_s; /**< Private address cycle interval in seconds. Providing an address cycle value of 0 will use the default value defined by @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. */ + ble_gap_irk_t *p_device_irk; /**< When used as input, pointer to IRK structure that will be used as the default IRK. If NULL, the device default IRK will be used. + When used as output, pointer to IRK structure where the current default IRK will be written to. If NULL, this argument is ignored. + By default, the default IRK is used to generate random private resolvable addresses for the local device unless instructed otherwise. */ +} ble_gap_privacy_params_t; + + +/**@brief PHY preferences for TX and RX + * @note tx_phys and rx_phys are bit fields. Multiple bits can be set in them to indicate multiple preferred PHYs for each direction. + * @code + * p_gap_phys->tx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS; + * p_gap_phys->rx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS; + * @endcode + * + */ +typedef struct +{ + uint8_t tx_phys; /**< Preferred transmit PHYs, see @ref BLE_GAP_PHYS. */ + uint8_t rx_phys; /**< Preferred receive PHYs, see @ref BLE_GAP_PHYS. */ +} ble_gap_phys_t; + +/** @brief Keys that can be exchanged during a bonding procedure. */ +typedef struct +{ + uint8_t enc : 1; /**< Long Term Key and Master Identification. */ + uint8_t id : 1; /**< Identity Resolving Key and Identity Address Information. */ + uint8_t sign : 1; /**< Connection Signature Resolving Key. */ + uint8_t link : 1; /**< Derive the Link Key from the LTK. */ +} ble_gap_sec_kdist_t; + + +/**@brief GAP security parameters. */ +typedef struct +{ + uint8_t bond : 1; /**< Perform bonding. */ + uint8_t mitm : 1; /**< Enable Man In The Middle protection. */ + uint8_t lesc : 1; /**< Enable LE Secure Connection pairing. */ + uint8_t keypress : 1; /**< Enable generation of keypress notifications. */ + uint8_t io_caps : 3; /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */ + uint8_t oob : 1; /**< The OOB data flag. + - In LE legacy pairing, this flag is set if a device has out of band authentication data. + The OOB method is used if both of the devices have out of band authentication data. + - In LE Secure Connections pairing, this flag is set if a device has the peer device's out of band authentication data. + The OOB method is used if at least one device has the peer device's OOB data available. */ + uint8_t min_key_size; /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */ + uint8_t max_key_size; /**< Maximum encryption key size in octets between min_key_size and 16. */ + ble_gap_sec_kdist_t kdist_own; /**< Key distribution bitmap: keys that the local device will distribute. */ + ble_gap_sec_kdist_t kdist_peer; /**< Key distribution bitmap: keys that the remote device will distribute. */ +} ble_gap_sec_params_t; + + +/**@brief GAP Encryption Information. */ +typedef struct +{ + uint8_t ltk[BLE_GAP_SEC_KEY_LEN]; /**< Long Term Key. */ + uint8_t lesc : 1; /**< Key generated using LE Secure Connections. */ + uint8_t auth : 1; /**< Authenticated Key. */ + uint8_t ltk_len : 6; /**< LTK length in octets. */ +} ble_gap_enc_info_t; + + +/**@brief GAP Master Identification. */ +typedef struct +{ + uint16_t ediv; /**< Encrypted Diversifier. */ + uint8_t rand[BLE_GAP_SEC_RAND_LEN]; /**< Random Number. */ +} ble_gap_master_id_t; + + +/**@brief GAP Signing Information. */ +typedef struct +{ + uint8_t csrk[BLE_GAP_SEC_KEY_LEN]; /**< Connection Signature Resolving Key. */ +} ble_gap_sign_info_t; + + +/**@brief GAP LE Secure Connections P-256 Public Key. */ +typedef struct +{ + uint8_t pk[BLE_GAP_LESC_P256_PK_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key. Stored in the standard SMP protocol format: {X,Y} both in little-endian. */ +} ble_gap_lesc_p256_pk_t; + + +/**@brief GAP LE Secure Connections DHKey. */ +typedef struct +{ + uint8_t key[BLE_GAP_LESC_DHKEY_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman Key. Stored in little-endian. */ +} ble_gap_lesc_dhkey_t; + + +/**@brief GAP LE Secure Connections OOB data. */ +typedef struct +{ + ble_gap_addr_t addr; /**< Bluetooth address of the device. */ + uint8_t r[BLE_GAP_SEC_KEY_LEN]; /**< Random Number. */ + uint8_t c[BLE_GAP_SEC_KEY_LEN]; /**< Confirm Value. */ +} ble_gap_lesc_oob_data_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_CONNECTED. */ +typedef struct +{ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 + and the address is the device's identity address. */ + uint8_t role; /**< BLE role for this connection, see @ref BLE_GAP_ROLES */ + ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ + uint8_t adv_handle; /**< Advertising handle in which advertising has ended. + This variable is only set if role is set to @ref BLE_GAP_ROLE_PERIPH. */ + ble_gap_adv_data_t adv_data; /**< Advertising buffers corresponding to the terminated + advertising set. The advertising buffers provided in + @ref sd_ble_gap_adv_set_configure are now released. + This variable is only set if role is set to @ref BLE_GAP_ROLE_PERIPH. */ +} ble_gap_evt_connected_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_DISCONNECTED. */ +typedef struct +{ + uint8_t reason; /**< HCI error code, see @ref BLE_HCI_STATUS_CODES. */ +} ble_gap_evt_disconnected_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE. */ +typedef struct +{ + ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ +} ble_gap_evt_conn_param_update_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_PHY_UPDATE_REQUEST. */ +typedef struct +{ + ble_gap_phys_t peer_preferred_phys; /**< The PHYs the peer prefers to use. */ +} ble_gap_evt_phy_update_request_t; + +/**@brief Event Structure for @ref BLE_GAP_EVT_PHY_UPDATE. */ +typedef struct +{ + uint8_t status; /**< Status of the procedure, see @ref BLE_HCI_STATUS_CODES.*/ + uint8_t tx_phy; /**< TX PHY for this connection, see @ref BLE_GAP_PHYS. */ + uint8_t rx_phy; /**< RX PHY for this connection, see @ref BLE_GAP_PHYS. */ +} ble_gap_evt_phy_update_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. */ +typedef struct +{ + ble_gap_sec_params_t peer_params; /**< Initiator Security Parameters. */ +} ble_gap_evt_sec_params_request_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_SEC_INFO_REQUEST. */ +typedef struct +{ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ + ble_gap_master_id_t master_id; /**< Master Identification for LTK lookup. */ + uint8_t enc_info : 1; /**< If 1, Encryption Information required. */ + uint8_t id_info : 1; /**< If 1, Identity Information required. */ + uint8_t sign_info : 1; /**< If 1, Signing Information required. */ +} ble_gap_evt_sec_info_request_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_PASSKEY_DISPLAY. */ +typedef struct +{ + uint8_t passkey[BLE_GAP_PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ + uint8_t match_request : 1; /**< If 1 requires the application to report the match using @ref sd_ble_gap_auth_key_reply + with either @ref BLE_GAP_AUTH_KEY_TYPE_NONE if there is no match or + @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY if there is a match. */ +} ble_gap_evt_passkey_display_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_KEY_PRESSED. */ +typedef struct +{ + uint8_t kp_not; /**< Keypress notification type, see @ref BLE_GAP_KP_NOT_TYPES. */ +} ble_gap_evt_key_pressed_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_KEY_REQUEST. */ +typedef struct +{ + uint8_t key_type; /**< See @ref BLE_GAP_AUTH_KEY_TYPES. */ +} ble_gap_evt_auth_key_request_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST. */ +typedef struct +{ + ble_gap_lesc_p256_pk_t *p_pk_peer; /**< LE Secure Connections remote P-256 Public Key. This will point to the application-supplied memory + inside the keyset during the call to @ref sd_ble_gap_sec_params_reply. */ + uint8_t oobd_req :1; /**< LESC OOB data required. A call to @ref sd_ble_gap_lesc_oob_data_set is required to complete the procedure. */ +} ble_gap_evt_lesc_dhkey_request_t; + + +/**@brief Security levels supported. + * @note See Bluetooth Specification Version 4.2 Volume 3, Part C, Chapter 10, Section 10.2.1. +*/ +typedef struct +{ + uint8_t lv1 : 1; /**< If 1: Level 1 is supported. */ + uint8_t lv2 : 1; /**< If 1: Level 2 is supported. */ + uint8_t lv3 : 1; /**< If 1: Level 3 is supported. */ + uint8_t lv4 : 1; /**< If 1: Level 4 is supported. */ +} ble_gap_sec_levels_t; + + +/**@brief Encryption Key. */ +typedef struct +{ + ble_gap_enc_info_t enc_info; /**< Encryption Information. */ + ble_gap_master_id_t master_id; /**< Master Identification. */ +} ble_gap_enc_key_t; + + +/**@brief Identity Key. */ +typedef struct +{ + ble_gap_irk_t id_info; /**< Identity Resolving Key. */ + ble_gap_addr_t id_addr_info; /**< Identity Address. */ +} ble_gap_id_key_t; + + +/**@brief Security Keys. */ +typedef struct +{ + ble_gap_enc_key_t *p_enc_key; /**< Encryption Key, or NULL. */ + ble_gap_id_key_t *p_id_key; /**< Identity Key, or NULL. */ + ble_gap_sign_info_t *p_sign_key; /**< Signing Key, or NULL. */ + ble_gap_lesc_p256_pk_t *p_pk; /**< LE Secure Connections P-256 Public Key. When in debug mode the application must use the value defined + in the Core Bluetooth Specification v4.2 Vol.3, Part H, Section 2.3.5.6.1 */ +} ble_gap_sec_keys_t; + + +/**@brief Security key set for both local and peer keys. */ +typedef struct +{ + ble_gap_sec_keys_t keys_own; /**< Keys distributed by the local device. For LE Secure Connections the encryption key will be generated locally and will always be stored if bonding. */ + ble_gap_sec_keys_t keys_peer; /**< Keys distributed by the remote device. For LE Secure Connections, p_enc_key must always be NULL. */ +} ble_gap_sec_keyset_t; + + +/**@brief Data Length Update Procedure parameters. */ +typedef struct +{ + uint16_t max_tx_octets; /**< Maximum number of payload octets that a Controller supports for transmission of a single Link Layer Data Channel PDU. */ + uint16_t max_rx_octets; /**< Maximum number of payload octets that a Controller supports for reception of a single Link Layer Data Channel PDU. */ + uint16_t max_tx_time_us; /**< Maximum time, in microseconds, that a Controller supports for transmission of a single Link Layer Data Channel PDU. */ + uint16_t max_rx_time_us; /**< Maximum time, in microseconds, that a Controller supports for reception of a single Link Layer Data Channel PDU. */ +} ble_gap_data_length_params_t; + + +/**@brief Data Length Update Procedure local limitation. */ +typedef struct +{ + uint16_t tx_payload_limited_octets; /**< If > 0, the requested TX packet length is too long by this many octets. */ + uint16_t rx_payload_limited_octets; /**< If > 0, the requested RX packet length is too long by this many octets. */ + uint16_t tx_rx_time_limited_us; /**< If > 0, the requested combination of TX and RX packet lengths is too long by this many microseconds. */ +} ble_gap_data_length_limitation_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_STATUS. */ +typedef struct +{ + uint8_t auth_status; /**< Authentication status, see @ref BLE_GAP_SEC_STATUS. */ + uint8_t error_src : 2; /**< On error, source that caused the failure, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ + uint8_t bonded : 1; /**< Procedure resulted in a bond. */ + uint8_t lesc : 1; /**< Procedure resulted in a LE Secure Connection. */ + ble_gap_sec_levels_t sm1_levels; /**< Levels supported in Security Mode 1. */ + ble_gap_sec_levels_t sm2_levels; /**< Levels supported in Security Mode 2. */ + ble_gap_sec_kdist_t kdist_own; /**< Bitmap stating which keys were exchanged (distributed) by the local device. If bonding with LE Secure Connections, the enc bit will be always set. */ + ble_gap_sec_kdist_t kdist_peer; /**< Bitmap stating which keys were exchanged (distributed) by the remote device. If bonding with LE Secure Connections, the enc bit will never be set. */ +} ble_gap_evt_auth_status_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_CONN_SEC_UPDATE. */ +typedef struct +{ + ble_gap_conn_sec_t conn_sec; /**< Connection security level. */ +} ble_gap_evt_conn_sec_update_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_TIMEOUT. */ +typedef struct +{ + uint8_t src; /**< Source of timeout event, see @ref BLE_GAP_TIMEOUT_SOURCES. */ + union + { + ble_data_t adv_report_buffer; /**< If source is set to @ref BLE_GAP_TIMEOUT_SRC_SCAN, the released + scan buffer is contained in this field. */ + } params; /**< Event Parameters. */ +} ble_gap_evt_timeout_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_RSSI_CHANGED. */ +typedef struct +{ + int8_t rssi; /**< Received Signal Strength Indication in dBm. + @note ERRATA-153 requires the rssi sample to be compensated based on a temperature measurement. */ + uint8_t ch_index; /**< Data Channel Index on which the Signal Strength is measured (0-36). */ +} ble_gap_evt_rssi_changed_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_ADV_SET_TERMINATED */ +typedef struct +{ + uint8_t reason; /**< Reason for why the advertising set terminated. See + @ref BLE_GAP_EVT_ADV_SET_TERMINATED_REASON. */ + uint8_t adv_handle; /**< Advertising handle in which advertising has ended. */ + uint8_t num_completed_adv_events; /**< If @ref ble_gap_adv_params_t::max_adv_evts was not set to 0, + this field indicates the number of completed advertising events. */ + ble_gap_adv_data_t adv_data; /**< Advertising buffers corresponding to the terminated + advertising set. The advertising buffers provided in + @ref sd_ble_gap_adv_set_configure are now released. */ +} ble_gap_evt_adv_set_terminated_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_ADV_REPORT. + * + * @note If @ref ble_gap_adv_report_type_t::status is set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, + * not all fields in the advertising report may be available. + * + * @note When ble_gap_adv_report_type_t::status is not set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, + * scanning will be paused. To continue scanning, call @ref sd_ble_gap_scan_start. + */ +typedef struct +{ + ble_gap_adv_report_type_t type; /**< Advertising report type. See @ref ble_gap_adv_report_type_t. */ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr is resolved: + @ref ble_gap_addr_t::addr_id_peer is set to 1 and the address is the + peer's identity address. */ + ble_gap_addr_t direct_addr; /**< Contains the target address of the advertising event if + @ref ble_gap_adv_report_type_t::directed is set to 1. If the + SoftDevice was able to resolve the address, + @ref ble_gap_addr_t::addr_id_peer is set to 1 and the direct_addr + contains the local identity address. If the target address of the + advertising event is @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE, + and the SoftDevice was unable to resolve it, the application may try + to resolve this address to find out if the advertising event was + directed to us. */ + uint8_t primary_phy; /**< Indicates the PHY on which the primary advertising packet was received. + See @ref BLE_GAP_PHYS. */ + uint8_t secondary_phy; /**< Indicates the PHY on which the secondary advertising packet was received. + See @ref BLE_GAP_PHYS. This field is set to @ref BLE_GAP_PHY_NOT_SET if no packets + were received on a secondary advertising channel. */ + int8_t tx_power; /**< TX Power reported by the advertiser in the last packet header received. + This field is set to @ref BLE_GAP_POWER_LEVEL_INVALID if the + last received packet did not contain the Tx Power field. + @note TX Power is only included in extended advertising packets. */ + int8_t rssi; /**< Received Signal Strength Indication in dBm of the last packet received. + @note ERRATA-153 requires the rssi sample to be compensated based on a temperature measurement. */ + uint8_t ch_index; /**< Channel Index on which the last advertising packet is received (0-39). */ + uint8_t set_id; /**< Set ID of the received advertising data. Set ID is not present + if set to @ref BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE. */ + uint16_t data_id:12; /**< The advertising data ID of the received advertising data. Data ID + is not present if @ref ble_gap_evt_adv_report_t::set_id is set to + @ref BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE. */ + ble_data_t data; /**< Received advertising or scan response data. If + @ref ble_gap_adv_report_type_t::status is not set to + @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, the data buffer provided + in @ref sd_ble_gap_scan_start is now released. */ + ble_gap_aux_pointer_t aux_pointer; /**< The offset and PHY of the next advertising packet in this extended advertising + event. @note This field is only set if @ref ble_gap_adv_report_type_t::status + is set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. */ +} ble_gap_evt_adv_report_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_SEC_REQUEST. */ +typedef struct +{ + uint8_t bond : 1; /**< Perform bonding. */ + uint8_t mitm : 1; /**< Man In The Middle protection requested. */ + uint8_t lesc : 1; /**< LE Secure Connections requested. */ + uint8_t keypress : 1; /**< Generation of keypress notifications requested. */ +} ble_gap_evt_sec_request_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST. */ +typedef struct +{ + ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ +} ble_gap_evt_conn_param_update_request_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_SCAN_REQ_REPORT. */ +typedef struct +{ + uint8_t adv_handle; /**< Advertising handle for the advertising set which received the Scan Request */ + int8_t rssi; /**< Received Signal Strength Indication in dBm. + @note ERRATA-153 requires the rssi sample to be compensated based on a temperature measurement. */ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 + and the address is the device's identity address. */ +} ble_gap_evt_scan_req_report_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST. */ +typedef struct +{ + ble_gap_data_length_params_t peer_params; /**< Peer data length parameters. */ +} ble_gap_evt_data_length_update_request_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE. */ +typedef struct +{ + ble_gap_data_length_params_t effective_params; /**< The effective data length parameters. */ +} ble_gap_evt_data_length_update_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT. */ +typedef struct +{ + int8_t channel_energy[BLE_GAP_CHANNEL_COUNT]; /**< The measured energy on the Bluetooth Low Energy + channels, in dBm, indexed by Channel Index. + If no measurement is available for the given channel, channel_energy is set to + @ref BLE_GAP_POWER_LEVEL_INVALID. */ +} ble_gap_evt_qos_channel_survey_report_t; + +/**@brief GAP event structure. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which event occurred. */ + union /**< union alternative identified by evt_id in enclosing struct. */ + { + ble_gap_evt_connected_t connected; /**< Connected Event Parameters. */ + ble_gap_evt_disconnected_t disconnected; /**< Disconnected Event Parameters. */ + ble_gap_evt_conn_param_update_t conn_param_update; /**< Connection Parameter Update Parameters. */ + ble_gap_evt_sec_params_request_t sec_params_request; /**< Security Parameters Request Event Parameters. */ + ble_gap_evt_sec_info_request_t sec_info_request; /**< Security Information Request Event Parameters. */ + ble_gap_evt_passkey_display_t passkey_display; /**< Passkey Display Event Parameters. */ + ble_gap_evt_key_pressed_t key_pressed; /**< Key Pressed Event Parameters. */ + ble_gap_evt_auth_key_request_t auth_key_request; /**< Authentication Key Request Event Parameters. */ + ble_gap_evt_lesc_dhkey_request_t lesc_dhkey_request; /**< LE Secure Connections DHKey calculation request. */ + ble_gap_evt_auth_status_t auth_status; /**< Authentication Status Event Parameters. */ + ble_gap_evt_conn_sec_update_t conn_sec_update; /**< Connection Security Update Event Parameters. */ + ble_gap_evt_timeout_t timeout; /**< Timeout Event Parameters. */ + ble_gap_evt_rssi_changed_t rssi_changed; /**< RSSI Event Parameters. */ + ble_gap_evt_adv_report_t adv_report; /**< Advertising Report Event Parameters. */ + ble_gap_evt_adv_set_terminated_t adv_set_terminated; /**< Advertising Set Terminated Event Parameters. */ + ble_gap_evt_sec_request_t sec_request; /**< Security Request Event Parameters. */ + ble_gap_evt_conn_param_update_request_t conn_param_update_request; /**< Connection Parameter Update Parameters. */ + ble_gap_evt_scan_req_report_t scan_req_report; /**< Scan Request Report Parameters. */ + ble_gap_evt_phy_update_request_t phy_update_request; /**< PHY Update Request Event Parameters. */ + ble_gap_evt_phy_update_t phy_update; /**< PHY Update Parameters. */ + ble_gap_evt_data_length_update_request_t data_length_update_request; /**< Data Length Update Request Event Parameters. */ + ble_gap_evt_data_length_update_t data_length_update; /**< Data Length Update Event Parameters. */ + ble_gap_evt_qos_channel_survey_report_t qos_channel_survey_report; /**< Quality of Service (QoS) Channel Survey Report Parameters. */ + } params; /**< Event Parameters. */ +} ble_gap_evt_t; + + +/** + * @brief BLE GAP connection configuration parameters, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_CONN_COUNT The connection count for the connection configurations is zero. + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - The sum of conn_count for all connection configurations combined exceeds UINT8_MAX. + * - The event length is smaller than @ref BLE_GAP_EVENT_LENGTH_MIN. + */ +typedef struct +{ + uint8_t conn_count; /**< The number of concurrent connections the application can create with this configuration. + The default and minimum value is @ref BLE_GAP_CONN_COUNT_DEFAULT. */ + uint16_t event_length; /**< The time set aside for this connection on every connection interval in 1.25 ms units. + The default value is @ref BLE_GAP_EVENT_LENGTH_DEFAULT, the minimum value is @ref BLE_GAP_EVENT_LENGTH_MIN. + The event length and the connection interval are the primary parameters + for setting the throughput of a connection. + See the SoftDevice Specification for details on throughput. */ +} ble_gap_conn_cfg_t; + + +/** + * @brief Configuration of maximum concurrent connections in the different connected roles, set with + * @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_CONN_COUNT The sum of periph_role_count and central_role_count is too + * large. The maximum supported sum of concurrent connections is + * @ref BLE_GAP_ROLE_COUNT_COMBINED_MAX. + * @retval ::NRF_ERROR_INVALID_PARAM central_sec_count is larger than central_role_count. + * @retval ::NRF_ERROR_RESOURCES The adv_set_count is too large. The maximum + * supported advertising handles is + * @ref BLE_GAP_ADV_SET_COUNT_MAX. + */ +typedef struct +{ + uint8_t adv_set_count; /**< Maximum number of advertising sets. Default value is @ref BLE_GAP_ADV_SET_COUNT_DEFAULT. */ + uint8_t periph_role_count; /**< Maximum number of connections concurrently acting as a peripheral. Default value is @ref BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT. */ + uint8_t central_role_count; /**< Maximum number of connections concurrently acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT. */ + uint8_t central_sec_count; /**< Number of SMP instances shared between all connections acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT. */ + uint8_t qos_channel_survey_role_available:1; /**< If set, the Quality of Service (QoS) channel survey module is available to the + application using @ref sd_ble_gap_qos_channel_survey_start. */ +} ble_gap_cfg_role_count_t; + + +/** + * @brief Device name and its properties, set with @ref sd_ble_cfg_set. + * + * @note If the device name is not configured, the default device name will be + * @ref BLE_GAP_DEVNAME_DEFAULT, the maximum device name length will be + * @ref BLE_GAP_DEVNAME_DEFAULT_LEN, vloc will be set to @ref BLE_GATTS_VLOC_STACK and the device name + * will have no write access. + * + * @note If @ref max_len is more than @ref BLE_GAP_DEVNAME_DEFAULT_LEN and vloc is set to @ref BLE_GATTS_VLOC_STACK, + * the attribute table size must be increased to have room for the longer device name (see + * @ref sd_ble_cfg_set and @ref ble_gatts_cfg_attr_tab_size_t). + * + * @note If vloc is @ref BLE_GATTS_VLOC_STACK : + * - p_value must point to non-volatile memory (flash) or be NULL. + * - If p_value is NULL, the device name will initially be empty. + * + * @note If vloc is @ref BLE_GATTS_VLOC_USER : + * - p_value cannot be NULL. + * - If the device name is writable, p_value must point to volatile memory (RAM). + * + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - Invalid device name location (vloc). + * - Invalid device name security mode. + * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true: + * - The device name length is invalid (must be between 0 and @ref BLE_GAP_DEVNAME_MAX_LEN). + * - The device name length is too long for the given Attribute Table. + * @retval ::NRF_ERROR_NOT_SUPPORTED Device name security mode is not supported. + */ +typedef struct +{ + ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ + uint8_t vloc:2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ + uint8_t *p_value; /**< Pointer to where the value (device name) is stored or will be stored. */ + uint16_t current_len; /**< Current length in bytes of the memory pointed to by p_value.*/ + uint16_t max_len; /**< Maximum length in bytes of the memory pointed to by p_value.*/ +} ble_gap_cfg_device_name_t; + + +/**@brief Configuration structure for GAP configurations. */ +typedef union +{ + ble_gap_cfg_role_count_t role_count_cfg; /**< Role count configuration, cfg_id is @ref BLE_GAP_CFG_ROLE_COUNT. */ + ble_gap_cfg_device_name_t device_name_cfg; /**< Device name configuration, cfg_id is @ref BLE_GAP_CFG_DEVICE_NAME. */ +} ble_gap_cfg_t; + + +/**@brief Channel Map option. + * + * @details Used with @ref sd_ble_opt_get to get the current channel map + * or @ref sd_ble_opt_set to set a new channel map. When setting the + * channel map, it applies to all current and future connections. When getting the + * current channel map, it applies to a single connection and the connection handle + * must be supplied. + * + * @note Setting the channel map may take some time, depending on connection parameters. + * The time taken may be different for each connection and the get operation will + * return the previous channel map until the new one has taken effect. + * + * @note After setting the channel map, by spec it can not be set again until at least 1 s has passed. + * See Bluetooth Specification Version 4.1 Volume 2, Part E, Section 7.3.46. + * + * @retval ::NRF_SUCCESS Get or set successful. + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - Less then two bits in @ref ch_map are set. + * - Bits for primary advertising channels (37-39) are set. + * @retval ::NRF_ERROR_BUSY Channel map was set again before enough time had passed. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied for get. + * + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle (only applicable for get) */ + uint8_t ch_map[5]; /**< Channel Map (37-bit). */ +} ble_gap_opt_ch_map_t; + + +/**@brief Local connection latency option. + * + * @details Local connection latency is a feature which enables the slave to improve + * current consumption by ignoring the slave latency set by the peer. The + * local connection latency can only be set to a multiple of the slave latency, + * and cannot be longer than half of the supervision timeout. + * + * @details Used with @ref sd_ble_opt_set to set the local connection latency. The + * @ref sd_ble_opt_get is not supported for this option, but the actual + * local connection latency (unless set to NULL) is set as a return parameter + * when setting the option. + * + * @note The latency set will be truncated down to the closest slave latency event + * multiple, or the nearest multiple before half of the supervision timeout. + * + * @note The local connection latency is disabled by default, and needs to be enabled for new + * connections and whenever the connection is updated. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle */ + uint16_t requested_latency; /**< Requested local connection latency. */ + uint16_t * p_actual_latency; /**< Pointer to storage for the actual local connection latency (can be set to NULL to skip return value). */ +} ble_gap_opt_local_conn_latency_t; + +/**@brief Disable slave latency + * + * @details Used with @ref sd_ble_opt_set to temporarily disable slave latency of a peripheral connection + * (see @ref ble_gap_conn_params_t::slave_latency). And to re-enable it again. When disabled, the + * peripheral will ignore the slave_latency set by the central. + * + * @note Shall only be called on peripheral links. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle */ + uint8_t disable : 1; /**< Set to 1 to disable slave latency. Set to 0 enable it again.*/ +} ble_gap_opt_slave_latency_disable_t; + +/**@brief Passkey Option. + * + * @details Structure containing the passkey to be used during pairing. This can be used with @ref + * sd_ble_opt_set to make the SoftDevice use a preprogrammed passkey for authentication + * instead of generating a random one. + * + * @note Repeated pairing attempts using the same preprogrammed passkey makes pairing vulnerable to MITM attacks. + * + * @note @ref sd_ble_opt_get is not supported for this option. + * + */ +typedef struct +{ + uint8_t const * p_passkey; /**< Pointer to 6-digit ASCII string (digit 0..9 only, no NULL termination) passkey to be used during pairing. If this is NULL, the SoftDevice will generate a random passkey if required.*/ +} ble_gap_opt_passkey_t; + + +/**@brief Compatibility mode 1 option. + * + * @details This can be used with @ref sd_ble_opt_set to enable and disable + * compatibility mode 1. Compatibility mode 1 is disabled by default. + * + * @note Compatibility mode 1 enables interoperability with devices that do not support a value of + * 0 for the WinOffset parameter in the Link Layer CONNECT_IND packet. This applies to a + * limited set of legacy peripheral devices from another vendor. Enabling this compatibility + * mode will only have an effect if the local device will act as a central device and + * initiate a connection to a peripheral device. In that case it may lead to the connection + * creation taking up to one connection interval longer to complete for all connections. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_INVALID_STATE When connection creation is ongoing while mode 1 is set. + */ +typedef struct +{ + uint8_t enable : 1; /**< Enable compatibility mode 1.*/ +} ble_gap_opt_compat_mode_1_t; + + +/**@brief Authenticated payload timeout option. + * + * @details This can be used with @ref sd_ble_opt_set to change the Authenticated payload timeout to a value other + * than the default of @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX. + * + * @note The authenticated payload timeout event ::BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD will be generated + * if auth_payload_timeout time has elapsed without receiving a packet with a valid MIC on an encrypted + * link. + * + * @note The LE ping procedure will be initiated before the timer expires to give the peer a chance + * to reset the timer. In addition the stack will try to prioritize running of LE ping over other + * activities to increase chances of finishing LE ping before timer expires. To avoid side-effects + * on other activities, it is recommended to use high timeout values. + * Recommended timeout > 2*(connInterval * (6 + connSlaveLatency)). + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. auth_payload_timeout was outside of allowed range. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle */ + uint16_t auth_payload_timeout; /**< Requested timeout in 10 ms unit, see @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT. */ +} ble_gap_opt_auth_payload_timeout_t; + +/**@brief Option structure for GAP options. */ +typedef union +{ + ble_gap_opt_ch_map_t ch_map; /**< Parameters for the Channel Map option. */ + ble_gap_opt_local_conn_latency_t local_conn_latency; /**< Parameters for the Local connection latency option */ + ble_gap_opt_passkey_t passkey; /**< Parameters for the Passkey option.*/ + ble_gap_opt_compat_mode_1_t compat_mode_1; /**< Parameters for the compatibility mode 1 option.*/ + ble_gap_opt_auth_payload_timeout_t auth_payload_timeout; /**< Parameters for the authenticated payload timeout option.*/ + ble_gap_opt_slave_latency_disable_t slave_latency_disable; /**< Parameters for the Disable slave latency option */ +} ble_gap_opt_t; +/**@} */ + + +/**@addtogroup BLE_GAP_FUNCTIONS Functions + * @{ */ + +/**@brief Set the local Bluetooth identity address. + * + * The local Bluetooth identity address is the address that identifies this device to other peers. + * The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC. + * + * @note The identity address cannot be changed while advertising, scanning or creating a connection. + * + * @note This address will be distributed to the peer during bonding. + * If the address changes, the address stored in the peer device will not be valid and the ability to + * reconnect using the old address will be lost. + * + * @note By default the SoftDevice will set an address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC upon being + * enabled. The address is a random number populated during the IC manufacturing process and remains unchanged + * for the lifetime of each IC. + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @endmscs + * + * @param[in] p_addr Pointer to address structure. + * + * @retval ::NRF_SUCCESS Address successfully set. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_INVALID_STATE The identity address cannot be changed while advertising, + * scanning or creating a connection. + */ +SVCALL(SD_BLE_GAP_ADDR_SET, uint32_t, sd_ble_gap_addr_set(ble_gap_addr_t const *p_addr)); + + +/**@brief Get local Bluetooth identity address. + * + * @note This will always return the identity address irrespective of the privacy settings, + * i.e. the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC. + * + * @param[out] p_addr Pointer to address structure to be filled in. + * + * @retval ::NRF_SUCCESS Address successfully retrieved. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. + */ +SVCALL(SD_BLE_GAP_ADDR_GET, uint32_t, sd_ble_gap_addr_get(ble_gap_addr_t *p_addr)); + + +/**@brief Get the Bluetooth device address used by the advertiser. + * + * @note This function will return the local Bluetooth address used in advertising PDUs. When + * using privacy, the SoftDevice will generate a new private address every + * @ref ble_gap_privacy_params_t::private_addr_cycle_s configured using + * @ref sd_ble_gap_privacy_set. Hence depending on when the application calls this API, the + * address returned may not be the latest address that is used in the advertising PDUs. + * + * @param[in] adv_handle The advertising handle to get the address from. + * @param[out] p_addr Pointer to address structure to be filled in. + * + * @retval ::NRF_SUCCESS Address successfully retrieved. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. + * @retval ::BLE_ERROR_INVALID_ADV_HANDLE The provided advertising handle was not found. + * @retval ::NRF_ERROR_INVALID_STATE The advertising set is currently not advertising. + */ +SVCALL(SD_BLE_GAP_ADV_ADDR_GET, uint32_t, sd_ble_gap_adv_addr_get(uint8_t adv_handle, ble_gap_addr_t *p_addr)); + + +/**@brief Set the active whitelist in the SoftDevice. + * + * @note Only one whitelist can be used at a time and the whitelist is shared between the BLE roles. + * The whitelist cannot be set if a BLE role is using the whitelist. + * + * @note If an address is resolved using the information in the device identity list, then the whitelist + * filter policy applies to the peer identity address and not the resolvable address sent on air. + * + * @mscs + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC} + * @endmscs + * + * @param[in] pp_wl_addrs Pointer to a whitelist of peer addresses, if NULL the whitelist will be cleared. + * @param[in] len Length of the whitelist, maximum @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. + * + * @retval ::NRF_SUCCESS The whitelist is successfully set/cleared. + * @retval ::NRF_ERROR_INVALID_ADDR The whitelist (or one of its entries) provided is invalid. + * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE The whitelist is in use by a BLE role and cannot be set or cleared. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_DATA_SIZE The given whitelist size is invalid (zero or too large); this can only return when + * pp_wl_addrs is not NULL. + */ +SVCALL(SD_BLE_GAP_WHITELIST_SET, uint32_t, sd_ble_gap_whitelist_set(ble_gap_addr_t const * const * pp_wl_addrs, uint8_t len)); + + +/**@brief Set device identity list. + * + * @note Only one device identity list can be used at a time and the list is shared between the BLE roles. + * The device identity list cannot be set if a BLE role is using the list. + * + * @param[in] pp_id_keys Pointer to an array of peer identity addresses and peer IRKs, if NULL the device identity list will be cleared. + * @param[in] pp_local_irks Pointer to an array of local IRKs. Each entry in the array maps to the entry in pp_id_keys at the same index. + * To fill in the list with the currently set device IRK for all peers, set to NULL. + * @param[in] len Length of the device identity list, maximum @ref BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT. + * + * @mscs + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS The device identity list successfully set/cleared. + * @retval ::NRF_ERROR_INVALID_ADDR The device identity list (or one of its entries) provided is invalid. + * This code may be returned if the local IRK list also has an invalid entry. + * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE The device identity list is in use and cannot be set or cleared. + * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE The device identity list contains multiple entries with the same identity address. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_DATA_SIZE The given device identity list size invalid (zero or too large); this can + * only return when pp_id_keys is not NULL. + */ +SVCALL(SD_BLE_GAP_DEVICE_IDENTITIES_SET, uint32_t, sd_ble_gap_device_identities_set(ble_gap_id_key_t const * const * pp_id_keys, ble_gap_irk_t const * const * pp_local_irks, uint8_t len)); + + +/**@brief Set privacy settings. + * + * @note Privacy settings cannot be changed while advertising, scanning or creating a connection. + * + * @param[in] p_privacy_params Privacy settings. + * + * @mscs + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_INVALID_ADDR The pointer to privacy settings is NULL or invalid. + * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer. + * @retval ::NRF_ERROR_INVALID_PARAM Out of range parameters are provided. + * @retval ::NRF_ERROR_INVALID_STATE Privacy settings cannot be changed while advertising, scanning + * or creating a connection. + */ +SVCALL(SD_BLE_GAP_PRIVACY_SET, uint32_t, sd_ble_gap_privacy_set(ble_gap_privacy_params_t const *p_privacy_params)); + + +/**@brief Get privacy settings. + * + * @note ::ble_gap_privacy_params_t::p_device_irk must be initialized to NULL or a valid address before this function is called. + * If it is initialized to a valid address, the address pointed to will contain the current device IRK on return. + * + * @param[in,out] p_privacy_params Privacy settings. + * + * @retval ::NRF_SUCCESS Privacy settings read. + * @retval ::NRF_ERROR_INVALID_ADDR The pointer given for returning the privacy settings may be NULL or invalid. + * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer. + */ +SVCALL(SD_BLE_GAP_PRIVACY_GET, uint32_t, sd_ble_gap_privacy_get(ble_gap_privacy_params_t *p_privacy_params)); + + +/**@brief Configure an advertising set. Set, clear or update advertising and scan response data. + * + * @note The format of the advertising data will be checked by this call to ensure interoperability. + * Limitations imposed by this API call to the data provided include having a flags data type in the scan response data and + * duplicating the local name in the advertising data and scan response data. + * + * @note In order to update advertising data while advertising, new advertising buffers must be provided. + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in,out] p_adv_handle Provide a pointer to a handle containing @ref BLE_GAP_ADV_SET_HANDLE_NOT_SET to configure + * a new advertising set. On success, a new handle is then returned through the pointer. + * Provide a pointer to an existing advertising handle to configure an existing advertising set. + * @param[in] p_adv_data Advertising data. If set to NULL, no advertising data will be used. See @ref ble_gap_adv_data_t. + * @param[in] p_adv_params Advertising parameters. When this function is used to update advertising data while advertising, + * this parameter must be NULL. See @ref ble_gap_adv_params_t. + * + * @retval ::NRF_SUCCESS Advertising set successfully configured. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied: + * - Invalid advertising data configuration specified. See @ref ble_gap_adv_data_t. + * - Invalid configuration of p_adv_params. See @ref ble_gap_adv_params_t. + * - Use of whitelist requested but whitelist has not been set, + * see @ref sd_ble_gap_whitelist_set. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR ble_gap_adv_params_t::p_peer_addr is invalid. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - It is invalid to provide non-NULL advertising set parameters while advertising. + * - It is invalid to provide the same data buffers while advertising. To update + * advertising data, provide new advertising buffers. + * @retval ::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST Discoverable mode and whitelist incompatible. + * @retval ::BLE_ERROR_INVALID_ADV_HANDLE The provided advertising handle was not found. Use @ref BLE_GAP_ADV_SET_HANDLE_NOT_SET to + * configure a new advertising handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_FLAGS Invalid combination of advertising flags supplied. + * @retval ::NRF_ERROR_INVALID_DATA Invalid data type(s) supplied. Check the advertising data format specification + * given in Bluetooth Specification Version 5.0, Volume 3, Part C, Chapter 11. + * @retval ::NRF_ERROR_INVALID_LENGTH Invalid data length(s) supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported data length or advertising parameter configuration. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to configure a new advertising handle. Update an + * existing advertising handle instead. + * @retval ::BLE_ERROR_GAP_UUID_LIST_MISMATCH Invalid UUID list supplied. + */ +SVCALL(SD_BLE_GAP_ADV_SET_CONFIGURE, uint32_t, sd_ble_gap_adv_set_configure(uint8_t *p_adv_handle, ble_gap_adv_data_t const *p_adv_data, ble_gap_adv_params_t const *p_adv_params)); + + +/**@brief Start advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). + * + * @note Only one advertiser may be active at any time. + * + * @events + * @event{@ref BLE_GAP_EVT_CONNECTED, Generated after connection has been established through connectable advertising.} + * @event{@ref BLE_GAP_EVT_ADV_SET_TERMINATED, Advertising set has terminated.} + * @event{@ref BLE_GAP_EVT_SCAN_REQ_REPORT, A scan request was received.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in] adv_handle Advertising handle to advertise on, received from @ref sd_ble_gap_adv_set_configure. + * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or + * @ref BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. For non-connectable + * advertising, this is ignored. + * + * @retval ::NRF_SUCCESS The BLE stack has started advertising. + * @retval ::NRF_ERROR_INVALID_STATE adv_handle is not configured or already advertising. + * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached; connectable advertiser cannot be started. + * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Advertising handle not found. Configure a new adveriting handle with @ref sd_ble_gap_adv_set_configure. + * @retval ::NRF_ERROR_NOT_FOUND conn_cfg_tag not found. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied: + * - Invalid configuration of p_adv_params. See @ref ble_gap_adv_params_t. + * - Use of whitelist requested but whitelist has not been set, see @ref sd_ble_gap_whitelist_set. + * @retval ::NRF_ERROR_RESOURCES Either: + * - adv_handle is configured with connectable advertising, but the event_length parameter + * associated with conn_cfg_tag is too small to be able to establish a connection on + * the selected advertising phys. Use @ref sd_ble_cfg_set to increase the event length. + * - Not enough BLE role slots available. + Stop one or more currently active roles (Central, Peripheral, Broadcaster or Observer) and try again. + * - p_adv_params is configured with connectable advertising, but the event_length parameter + * associated with conn_cfg_tag is too small to be able to establish a connection on + * the selected advertising phys. Use @ref sd_ble_cfg_set to increase the event length. + */ +SVCALL(SD_BLE_GAP_ADV_START, uint32_t, sd_ble_gap_adv_start(uint8_t adv_handle, uint8_t conn_cfg_tag)); + + +/**@brief Stop advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in] adv_handle The advertising handle that should stop advertising. + * + * @retval ::NRF_SUCCESS The BLE stack has stopped advertising. + * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Invalid advertising handle. + * @retval ::NRF_ERROR_INVALID_STATE The advertising handle is not advertising. + */ +SVCALL(SD_BLE_GAP_ADV_STOP, uint32_t, sd_ble_gap_adv_stop(uint8_t adv_handle)); + + + +/**@brief Update connection parameters. + * + * @details In the central role this will initiate a Link Layer connection parameter update procedure, + * otherwise in the peripheral role, this will send the corresponding L2CAP request and wait for + * the central to perform the procedure. In both cases, and regardless of success or failure, the application + * will be informed of the result with a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE event. + * + * @details This function can be used as a central both to reply to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST or to start the procedure unrequested. + * + * @events + * @event{@ref BLE_GAP_EVT_CONN_PARAM_UPDATE, Result of the connection parameter update procedure.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CPU_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CPU_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CPU_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_conn_params Pointer to desired connection parameters. If NULL is provided on a peripheral role, + * the parameters in the PPCP characteristic of the GAP service will be used instead. + * If NULL is provided on a central role and in response to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, the peripheral request will be rejected + * + * @retval ::NRF_SUCCESS The Connection Update procedure has been started successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. + * @retval ::NRF_ERROR_INVALID_STATE Disconnection in progress or link has not been established. + * @retval ::NRF_ERROR_BUSY Procedure already in progress, wait for pending procedures to complete and retry. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + */ +SVCALL(SD_BLE_GAP_CONN_PARAM_UPDATE, uint32_t, sd_ble_gap_conn_param_update(uint16_t conn_handle, ble_gap_conn_params_t const *p_conn_params)); + + +/**@brief Disconnect (GAP Link Termination). + * + * @details This call initiates the disconnection procedure, and its completion will be communicated to the application + * with a @ref BLE_GAP_EVT_DISCONNECTED event. + * + * @events + * @event{@ref BLE_GAP_EVT_DISCONNECTED, Generated when disconnection procedure is complete.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CONN_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES (accepted values are @ref BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION and @ref BLE_HCI_CONN_INTERVAL_UNACCEPTABLE). + * + * @retval ::NRF_SUCCESS The disconnection procedure has been started successfully. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_INVALID_STATE Disconnection in progress or link has not been established. + */ +SVCALL(SD_BLE_GAP_DISCONNECT, uint32_t, sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code)); + + +/**@brief Set the radio's transmit power. + * + * @param[in] role The role to set the transmit power for, see @ref BLE_GAP_TX_POWER_ROLES for + * possible roles. + * @param[in] handle The handle parameter is interpreted depending on role: + * - If role is @ref BLE_GAP_TX_POWER_ROLE_CONN, this value is the specific connection handle. + * - If role is @ref BLE_GAP_TX_POWER_ROLE_ADV, the advertising set identified with the advertising handle, + * will use the specified transmit power, and include it in the advertising packet headers if + * @ref ble_gap_adv_properties_t::include_tx_power set. + * - For all other roles handle is ignored. + * @param[in] tx_power Radio transmit power in dBm (see note for accepted values). + * + * @note Supported tx_power values: -40dBm, -20dBm, -16dBm, -12dBm, -8dBm, -4dBm, 0dBm, +2dBm, +3dBm, +4dBm, +5dBm, +6dBm, +7dBm and +8dBm. + * @note The initiator will have the same transmit power as the scanner. + * @note When a connection is created it will inherit the transmit power from the initiator or + * advertiser leading to the connection. + * + * @retval ::NRF_SUCCESS Successfully changed the transmit power. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Advertising handle not found. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_TX_POWER_SET, uint32_t, sd_ble_gap_tx_power_set(uint8_t role, uint16_t handle, int8_t tx_power)); + + +/**@brief Set GAP Appearance value. + * + * @param[in] appearance Appearance (16-bit), see @ref BLE_APPEARANCES. + * + * @retval ::NRF_SUCCESS Appearance value set successfully. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + */ +SVCALL(SD_BLE_GAP_APPEARANCE_SET, uint32_t, sd_ble_gap_appearance_set(uint16_t appearance)); + + +/**@brief Get GAP Appearance value. + * + * @param[out] p_appearance Pointer to appearance (16-bit) to be filled in, see @ref BLE_APPEARANCES. + * + * @retval ::NRF_SUCCESS Appearance value retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_GAP_APPEARANCE_GET, uint32_t, sd_ble_gap_appearance_get(uint16_t *p_appearance)); + + +/**@brief Set GAP Peripheral Preferred Connection Parameters. + * + * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the desired parameters. + * + * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters set successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + */ +SVCALL(SD_BLE_GAP_PPCP_SET, uint32_t, sd_ble_gap_ppcp_set(ble_gap_conn_params_t const *p_conn_params)); + + +/**@brief Get GAP Peripheral Preferred Connection Parameters. + * + * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters will be stored. + * + * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_GAP_PPCP_GET, uint32_t, sd_ble_gap_ppcp_get(ble_gap_conn_params_t *p_conn_params)); + + +/**@brief Set GAP device name. + * + * @note If the device name is located in application flash memory (see @ref ble_gap_cfg_device_name_t), + * it cannot be changed. Then @ref NRF_ERROR_FORBIDDEN will be returned. + * + * @param[in] p_write_perm Write permissions for the Device Name characteristic, see @ref ble_gap_conn_sec_mode_t. + * @param[in] p_dev_name Pointer to a UTF-8 encoded, non NULL-terminated string. + * @param[in] len Length of the UTF-8, non NULL-terminated string pointed to by p_dev_name in octets (must be smaller or equal than @ref BLE_GAP_DEVNAME_MAX_LEN). + * + * @retval ::NRF_SUCCESS GAP device name and permissions set successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + * @retval ::NRF_ERROR_FORBIDDEN Device name is not writable. + */ +SVCALL(SD_BLE_GAP_DEVICE_NAME_SET, uint32_t, sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const *p_write_perm, uint8_t const *p_dev_name, uint16_t len)); + + +/**@brief Get GAP device name. + * + * @note If the device name is longer than the size of the supplied buffer, + * p_len will return the complete device name length, + * and not the number of bytes actually returned in p_dev_name. + * The application may use this information to allocate a suitable buffer size. + * + * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated string will be placed. Set to NULL to obtain the complete device name length. + * @param[in,out] p_len Length of the buffer pointed by p_dev_name, complete device name length on output. + * + * @retval ::NRF_SUCCESS GAP device name retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + */ +SVCALL(SD_BLE_GAP_DEVICE_NAME_GET, uint32_t, sd_ble_gap_device_name_get(uint8_t *p_dev_name, uint16_t *p_len)); + + +/**@brief Initiate the GAP Authentication procedure. + * + * @details In the central role, this function will send an SMP Pairing Request (or an SMP Pairing Failed if rejected), + * otherwise in the peripheral role, an SMP Security Request will be sent. + * + * @events + * @event{Depending on the security parameters set and the packet exchanges with the peer\, the following events may be generated:} + * @event{@ref BLE_GAP_EVT_SEC_PARAMS_REQUEST} + * @event{@ref BLE_GAP_EVT_SEC_INFO_REQUEST} + * @event{@ref BLE_GAP_EVT_PASSKEY_DISPLAY} + * @event{@ref BLE_GAP_EVT_KEY_PRESSED} + * @event{@ref BLE_GAP_EVT_AUTH_KEY_REQUEST} + * @event{@ref BLE_GAP_EVT_LESC_DHKEY_REQUEST} + * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE} + * @event{@ref BLE_GAP_EVT_AUTH_STATUS} + * @event{@ref BLE_GAP_EVT_TIMEOUT} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_SEC_REQ_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing or bonding procedure. + * In the peripheral role, only the bond, mitm, lesc and keypress fields of this structure are used. + * In the central role, this pointer may be NULL to reject a Security Request. + * + * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - No link has been established. + * - An encryption is already executing or queued. + * @retval ::NRF_ERROR_NO_MEM The maximum number of authentication procedures that can run in parallel for the given role is reached. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. + * @retval ::NRF_ERROR_TIMEOUT A SMP timeout has occurred, and further SMP operations on this link is prohibited. + */ +SVCALL(SD_BLE_GAP_AUTHENTICATE, uint32_t, sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const *p_sec_params)); + + +/**@brief Reply with GAP security parameters. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_CONFIRM_FAIL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_KS_TOO_SMALL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_APP_ERROR_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_REMOTE_PAIRING_FAIL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_TIMEOUT_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS. + * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters structure. In the central role this must be set to NULL, as the parameters have + * already been provided during a previous call to @ref sd_ble_gap_authenticate. + * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys generated and/or distributed as a result of the ongoing security procedure + * will be stored into the memory referenced by the pointers inside this structure. The keys will be stored and available to the application + * upon reception of a @ref BLE_GAP_EVT_AUTH_STATUS event. + * Note that the SoftDevice expects the application to provide memory for storing the + * peer's keys. So it must be ensured that the relevant pointers inside this structure are not NULL. The pointers to the local key + * can, however, be NULL, in which case, the local key data will not be available to the application upon reception of the + * @ref BLE_GAP_EVT_AUTH_STATUS event. + * + * @retval ::NRF_SUCCESS Successfully accepted security parameter from the application. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Security parameters has not been requested. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. + */ +SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const *p_sec_params, ble_gap_sec_keyset_t const *p_sec_keyset)); + + +/**@brief Reply with an authentication key. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST or a @ref BLE_GAP_EVT_PASSKEY_DISPLAY, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] key_type See @ref BLE_GAP_AUTH_KEY_TYPES. + * @param[in] p_key If key type is @ref BLE_GAP_AUTH_KEY_TYPE_NONE, then NULL. + * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL termination) + * or NULL when confirming LE Secure Connections Numeric Comparison. + * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, then a 16-byte OOB key value in little-endian format. + * + * @retval ::NRF_SUCCESS Authentication key successfully set. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Authentication key has not been requested. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_AUTH_KEY_REPLY, uint32_t, sd_ble_gap_auth_key_reply(uint16_t conn_handle, uint8_t key_type, uint8_t const *p_key)); + + +/**@brief Reply with an LE Secure connections DHKey. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_dhkey LE Secure Connections DHKey. + * + * @retval ::NRF_SUCCESS DHKey successfully set. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - The peer is not authenticated. + * - The application has not pulled a @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_DHKEY_REPLY, uint32_t, sd_ble_gap_lesc_dhkey_reply(uint16_t conn_handle, ble_gap_lesc_dhkey_t const *p_dhkey)); + + +/**@brief Notify the peer of a local keypress. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] kp_not See @ref BLE_GAP_KP_NOT_TYPES. + * + * @retval ::NRF_SUCCESS Keypress notification successfully queued for transmission. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - Authentication key not requested. + * - Passkey has not been entered. + * - Keypresses have not been enabled by both peers. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time. + */ +SVCALL(SD_BLE_GAP_KEYPRESS_NOTIFY, uint32_t, sd_ble_gap_keypress_notify(uint16_t conn_handle, uint8_t kp_not)); + + +/**@brief Generate a set of OOB data to send to a peer out of band. + * + * @note The @ref ble_gap_addr_t included in the OOB data returned will be the currently active one (or, if a connection has already been established, + * the one used during connection setup). The application may manually overwrite it with an updated value. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. Can be @ref BLE_CONN_HANDLE_INVALID if a BLE connection has not been established yet. + * @param[in] p_pk_own LE Secure Connections local P-256 Public Key. + * @param[out] p_oobd_own The OOB data to be sent out of band to a peer. + * + * @retval ::NRF_SUCCESS OOB data successfully generated. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_OOB_DATA_GET, uint32_t, sd_ble_gap_lesc_oob_data_get(uint16_t conn_handle, ble_gap_lesc_p256_pk_t const *p_pk_own, ble_gap_lesc_oob_data_t *p_oobd_own)); + +/**@brief Provide the OOB data sent/received out of band. + * + * @note An authentication procedure with OOB selected as an algorithm must be in progress when calling this function. + * @note A @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event with the oobd_req set to 1 must have been received prior to calling this function. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_oobd_own The OOB data sent out of band to a peer or NULL if the peer has not received OOB data. + * Must correspond to @ref ble_gap_sec_params_t::oob flag in @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. + * @param[in] p_oobd_peer The OOB data received out of band from a peer or NULL if none received. + * Must correspond to @ref ble_gap_sec_params_t::oob flag + * in @ref sd_ble_gap_authenticate in the central role or + * in @ref sd_ble_gap_sec_params_reply in the peripheral role. + * + * @retval ::NRF_SUCCESS OOB data accepted. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - Authentication key not requested + * - Not expecting LESC OOB data + * - Have not actually exchanged passkeys. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_OOB_DATA_SET, uint32_t, sd_ble_gap_lesc_oob_data_set(uint16_t conn_handle, ble_gap_lesc_oob_data_t const *p_oobd_own, ble_gap_lesc_oob_data_t const *p_oobd_peer)); + + +/**@brief Initiate GAP Encryption procedure. + * + * @details In the central role, this function will initiate the encryption procedure using the encryption information provided. + * + * @events + * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE, The connection security has been updated.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_master_id Pointer to a @ref ble_gap_master_id_t master identification structure. + * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. + * + * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE No link has been established. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Peripheral role. + * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, wait for pending procedures to complete and retry. + */ +SVCALL(SD_BLE_GAP_ENCRYPT, uint32_t, sd_ble_gap_encrypt(uint16_t conn_handle, ble_gap_master_id_t const *p_master_id, ble_gap_enc_info_t const *p_enc_info)); + + +/**@brief Reply with GAP security information. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * @note Data signing is not yet supported, and p_sign_info must therefore be NULL. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_ENC_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. May be NULL to signal none is available. + * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t identity information structure. May be NULL to signal none is available. + * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information structure. May be NULL to signal none is available. + * + * @retval ::NRF_SUCCESS Successfully accepted security information. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - No link has been established. + * - No @ref BLE_GAP_EVT_SEC_REQUEST pending. + * - LE long term key requested command not allowed. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_SEC_INFO_REPLY, uint32_t, sd_ble_gap_sec_info_reply(uint16_t conn_handle, ble_gap_enc_info_t const *p_enc_info, ble_gap_irk_t const *p_id_info, ble_gap_sign_info_t const *p_sign_info)); + + +/**@brief Get the current connection security. + * + * @param[in] conn_handle Connection handle. + * @param[out] p_conn_sec Pointer to a @ref ble_gap_conn_sec_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Current connection security successfully retrieved. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_CONN_SEC_GET, uint32_t, sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t *p_conn_sec)); + + +/**@brief Start reporting the received signal strength to the application. + * + * A new event is reported whenever the RSSI value changes, until @ref sd_ble_gap_rssi_stop is called. + * + * @events + * @event{@ref BLE_GAP_EVT_RSSI_CHANGED, New RSSI data available. How often the event is generated is + * dependent on the settings of the threshold_dbm + * and skip_count input parameters.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] threshold_dbm Minimum change in dBm before triggering the @ref BLE_GAP_EVT_RSSI_CHANGED event. Events are disabled if threshold_dbm equals @ref BLE_GAP_RSSI_THRESHOLD_INVALID. + * @param[in] skip_count Number of RSSI samples with a change of threshold_dbm or more before sending a new @ref BLE_GAP_EVT_RSSI_CHANGED event. + * + * @retval ::NRF_SUCCESS Successfully activated RSSI reporting. + * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is already ongoing. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_RSSI_START, uint32_t, sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count)); + + +/**@brief Stop reporting the received signal strength. + * + * @note An RSSI change detected before the call but not yet received by the application + * may be reported after @ref sd_ble_gap_rssi_stop has been called. + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * + * @retval ::NRF_SUCCESS Successfully deactivated RSSI reporting. + * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_RSSI_STOP, uint32_t, sd_ble_gap_rssi_stop(uint16_t conn_handle)); + + +/**@brief Get the received signal strength for the last connection event. + * + * @ref sd_ble_gap_rssi_start must be called to start reporting RSSI before using this function. @ref NRF_ERROR_NOT_FOUND + * will be returned until RSSI was sampled for the first time after calling @ref sd_ble_gap_rssi_start. + * @note ERRATA-153 requires the rssi sample to be compensated based on a temperature measurement. + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[out] p_rssi Pointer to the location where the RSSI measurement shall be stored. + * @param[out] p_ch_index Pointer to the location where Channel Index for the RSSI measurement shall be stored. + * + * @retval ::NRF_SUCCESS Successfully read the RSSI. + * @retval ::NRF_ERROR_NOT_FOUND No sample is available. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing. + */ +SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, int8_t *p_rssi, uint8_t *p_ch_index)); + + +/**@brief Start or continue scanning (GAP Discovery procedure, Observer Procedure). + * + * @note A call to this function will require the application to keep the memory pointed by + * p_adv_report_buffer alive until the buffer is released. The buffer is released when the scanner is stopped + * or when this function is called with another buffer. + * + * @note The scanner will automatically stop in the following cases: + * - @ref sd_ble_gap_scan_stop is called. + * - @ref sd_ble_gap_connect is called. + * - A @ref BLE_GAP_EVT_TIMEOUT with source set to @ref BLE_GAP_TIMEOUT_SRC_SCAN is received. + * - When a @ref BLE_GAP_EVT_ADV_REPORT event is received and @ref ble_gap_adv_report_type_t::status is not set to + * @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. In this case scanning is only paused to let the application + * access received data. The application must call this function to continue scanning, or call @ref sd_ble_gap_scan_stop + * to stop scanning. + * + * @note If a @ref BLE_GAP_EVT_ADV_REPORT event is received with @ref ble_gap_adv_report_type_t::status set to + * @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, the scanner will continue scanning, and the application will + * receive more reports from this advertising event. The following reports will include the old and new received data. + * + * @events + * @event{@ref BLE_GAP_EVT_ADV_REPORT, An advertising or scan response packet has been received.} + * @event{@ref BLE_GAP_EVT_TIMEOUT, Scanner has timed out.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_SCAN_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in] p_scan_params Pointer to scan parameters structure. When this function is used to continue + * scanning, this parameter must be NULL. + * @param[in] p_adv_report_buffer Pointer to buffer used to store incoming advertising data. + * The memory pointed to should be kept alive until the scanning is stopped. + * See @ref BLE_GAP_SCAN_BUFFER_SIZE for minimum and maximum buffer size. + * If the scanner receives advertising data larger than can be stored in the buffer, + * a @ref BLE_GAP_EVT_ADV_REPORT will be raised with @ref ble_gap_adv_report_type_t::status + * set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_TRUNCATED. + * + * @retval ::NRF_SUCCESS Successfully initiated scanning procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - Scanning is already ongoing and p_scan_params was not NULL + * - Scanning is not running and p_scan_params was NULL. + * - The scanner has timed out when this function is called to continue scanning. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. See @ref ble_gap_scan_params_t. + * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported parameters supplied. See @ref ble_gap_scan_params_t. + * @retval ::NRF_ERROR_INVALID_LENGTH The provided buffer length is invalid. See @ref BLE_GAP_SCAN_BUFFER_MIN. + * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again + */ +SVCALL(SD_BLE_GAP_SCAN_START, uint32_t, sd_ble_gap_scan_start(ble_gap_scan_params_t const *p_scan_params, ble_data_t const * p_adv_report_buffer)); + + +/**@brief Stop scanning (GAP Discovery procedure, Observer Procedure). + * + * @note The buffer provided in @ref sd_ble_gap_scan_start is released. + * + * @mscs + * @mmsc{@ref BLE_GAP_SCAN_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully stopped scanning procedure. + * @retval ::NRF_ERROR_INVALID_STATE Not in the scanning state. + */ +SVCALL(SD_BLE_GAP_SCAN_STOP, uint32_t, sd_ble_gap_scan_stop(void)); + + +/**@brief Create a connection (GAP Link Establishment). + * + * @note If a scanning procedure is currently in progress it will be automatically stopped when calling this function. + * The scanning procedure will be stopped even if the function returns an error. + * + * @events + * @event{@ref BLE_GAP_EVT_CONNECTED, A connection was established.} + * @event{@ref BLE_GAP_EVT_TIMEOUT, Failed to establish a connection.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} + * @endmscs + * + * @param[in] p_peer_addr Pointer to peer identity address. If @ref ble_gap_scan_params_t::filter_policy is set to use + * whitelist, then p_peer_addr is ignored. + * @param[in] p_scan_params Pointer to scan parameters structure. + * @param[in] p_conn_params Pointer to desired connection parameters. + * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or + * @ref BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. + * + * @retval ::NRF_SUCCESS Successfully initiated connection procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid parameter(s) pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * - Invalid parameter(s) in p_scan_params or p_conn_params. + * - Use of whitelist requested but whitelist has not been set, see @ref sd_ble_gap_whitelist_set. + * - Peer address was not present in the device identity list, see @ref sd_ble_gap_device_identities_set. + * @retval ::NRF_ERROR_NOT_FOUND conn_cfg_tag not found. + * @retval ::NRF_ERROR_INVALID_STATE The SoftDevice is in an invalid state to perform this operation. This may be due to an + * existing locally initiated connect procedure, which must complete before initiating again. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Peer address. + * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached. + * @retval ::NRF_ERROR_RESOURCES Either: + * - Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Observer) and try again. + * - The event_length parameter associated with conn_cfg_tag is too small to be able to + * establish a connection on the selected @ref ble_gap_scan_params_t::scan_phys. + * Use @ref sd_ble_cfg_set to increase the event length. + */ +SVCALL(SD_BLE_GAP_CONNECT, uint32_t, sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, ble_gap_conn_params_t const *p_conn_params, uint8_t conn_cfg_tag)); + + +/**@brief Cancel a connection establishment. + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully canceled an ongoing connection procedure. + * @retval ::NRF_ERROR_INVALID_STATE No locally initiated connect procedure started or connection + * completed occurred. + */ +SVCALL(SD_BLE_GAP_CONNECT_CANCEL, uint32_t, sd_ble_gap_connect_cancel(void)); + + +/**@brief Initiate or respond to a PHY Update Procedure + * + * @details This function is used to initiate or respond to a PHY Update Procedure. It will always + * generate a @ref BLE_GAP_EVT_PHY_UPDATE event if successfully executed. + * If this function is used to initiate a PHY Update procedure and the only option + * provided in @ref ble_gap_phys_t::tx_phys and @ref ble_gap_phys_t::rx_phys is the + * currently active PHYs in the respective directions, the SoftDevice will generate a + * @ref BLE_GAP_EVT_PHY_UPDATE with the current PHYs set and will not initiate the + * procedure in the Link Layer. + * + * If @ref ble_gap_phys_t::tx_phys or @ref ble_gap_phys_t::rx_phys is @ref BLE_GAP_PHY_AUTO, + * then the stack will select PHYs based on the peer's PHY preferences and the local link + * configuration. The PHY Update procedure will for this case result in a PHY combination + * that respects the time constraints configured with @ref sd_ble_cfg_set and the current + * link layer data length. + * + * When acting as a central, the SoftDevice will select the fastest common PHY in each direction. + * + * If the peer does not support the PHY Update Procedure, then the resulting + * @ref BLE_GAP_EVT_PHY_UPDATE event will have a status set to + * @ref BLE_HCI_UNSUPPORTED_REMOTE_FEATURE. + * + * If the PHY procedure was rejected by the peer due to a procedure collision, the status + * will be @ref BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION or + * @ref BLE_HCI_DIFFERENT_TRANSACTION_COLLISION. + * If the peer responds to the PHY Update procedure with invalid parameters, the status + * will be @ref BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS. + * If the PHY procedure was rejected by the peer for a different reason, the status will + * contain the reason as specified by the peer. + * + * @events + * @event{@ref BLE_GAP_EVT_PHY_UPDATE, Result of the PHY Update Procedure.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_PHY_UPDATE} + * @mmsc{@ref BLE_GAP_PERIPHERAL_PHY_UPDATE} + * @endmscs + * + * @param[in] conn_handle Connection handle to indicate the connection for which the PHY Update is requested. + * @param[in] p_gap_phys Pointer to PHY structure. + * + * @retval ::NRF_SUCCESS Successfully requested a PHY Update. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE No link has been established. + * @retval ::NRF_ERROR_RESOURCES The connection event length configured for this link is not sufficient for the combination of + * @ref ble_gap_phys_t::tx_phys, @ref ble_gap_phys_t::rx_phys, and @ref ble_gap_data_length_params_t. + * The connection event length is configured with @ref BLE_CONN_CFG_GAP using @ref sd_ble_cfg_set. + * @retval ::NRF_ERROR_BUSY Procedure is already in progress or not allowed at this time. Process pending events and wait for the pending procedure to complete and retry. + * + */ +SVCALL(SD_BLE_GAP_PHY_UPDATE, uint32_t, sd_ble_gap_phy_update(uint16_t conn_handle, ble_gap_phys_t const *p_gap_phys)); + + +/**@brief Initiate or respond to a Data Length Update Procedure. + * + * @note If the application uses @ref BLE_GAP_DATA_LENGTH_AUTO for one or more members of + * p_dl_params, the SoftDevice will choose the highest value supported in current + * configuration and connection parameters. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_dl_params Pointer to local parameters to be used in Data Length Update + * Procedure. Set any member to @ref BLE_GAP_DATA_LENGTH_AUTO to let + * the SoftDevice automatically decide the value for that member. + * Set to NULL to use automatic values for all members. + * @param[out] p_dl_limitation Pointer to limitation to be written when local device does not + * have enough resources or does not support the requested Data Length + * Update parameters. Ignored if NULL. + * + * @mscs + * @mmsc{@ref BLE_GAP_DATA_LENGTH_UPDATE_PROCEDURE_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully set Data Length Extension initiation/response parameters. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter supplied. + * @retval ::NRF_ERROR_INVALID_STATE No link has been established. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED The requested parameters are not supported by the SoftDevice. Inspect + * p_dl_limitation to see which parameter is not supported. + * @retval ::NRF_ERROR_RESOURCES The connection event length configured for this link is not sufficient for the requested parameters. + * Use @ref sd_ble_cfg_set with @ref BLE_CONN_CFG_GAP to increase the connection event length. + * Inspect p_dl_limitation to see where the limitation is. + * @retval ::NRF_ERROR_BUSY Peer has already initiated a Data Length Update Procedure. Process the + * pending @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST event to respond. + */ +SVCALL(SD_BLE_GAP_DATA_LENGTH_UPDATE, uint32_t, sd_ble_gap_data_length_update(uint16_t conn_handle, ble_gap_data_length_params_t const *p_dl_params, ble_gap_data_length_limitation_t *p_dl_limitation)); + +/**@brief Start the Quality of Service (QoS) channel survey module. + * + * @details The channel survey module provides measurements of the energy levels on + * the Bluetooth Low Energy channels. When the module is enabled, @ref BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT + * events will periodically report the measured energy levels for each channel. + * + * @note The measurements are scheduled with lower priority than other Bluetooth Low Energy roles, + * Radio Timeslot API events and Flash API events. + * + * @note The channel survey module will attempt to do measurements so that the average interval + * between measurements will be interval_us. However due to the channel survey module + * having the lowest priority of all roles and modules, this may not be possible. In that + * case fewer than expected channel survey reports may be given. + * + * @note In order to use the channel survey module, @ref ble_gap_cfg_role_count_t::qos_channel_survey_role_available + * must be set. This is done using @ref sd_ble_cfg_set. + * + * @param[in] interval_us Requested average interval for the measurements and reports. See + * @ref BLE_GAP_QOS_CHANNEL_SURVEY_INTERVALS for valid ranges. If set + * to @ref BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_CONTINUOUS, the channel + * survey role will be scheduled at every available opportunity. + * + * @retval ::NRF_SUCCESS The module is successfully started. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter supplied. interval_us is out of the + * allowed range. + * @retval ::NRF_ERROR_INVALID_STATE Trying to start the module when already running. + * @retval ::NRF_ERROR_RESOURCES The channel survey module is not available to the application. + * Set @ref ble_gap_cfg_role_count_t::qos_channel_survey_role_available using + * @ref sd_ble_cfg_set. + */ +SVCALL(SD_BLE_GAP_QOS_CHANNEL_SURVEY_START, uint32_t, sd_ble_gap_qos_channel_survey_start(uint32_t interval_us)); + +/**@brief Stop the Quality of Service (QoS) channel survey module. + * + * @retval ::NRF_SUCCESS The module is successfully stopped. + * @retval ::NRF_ERROR_INVALID_STATE Trying to stop the module when it is not running. + */ +SVCALL(SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP, uint32_t, sd_ble_gap_qos_channel_survey_stop(void)); + + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_GAP_H__ + +/** + @} +*/ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_gatt.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_gatt.h new file mode 100644 index 00000000000..9cb577cc856 --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_gatt.h @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_GATT Generic Attribute Profile (GATT) Common + @{ + @brief Common definitions and prototypes for the GATT interfaces. + */ + +#ifndef BLE_GATT_H__ +#define BLE_GATT_H__ + +#include +#include "nrf_svc.h" +#include "nrf_error.h" +#include "ble_hci.h" +#include "ble_ranges.h" +#include "ble_types.h" +#include "ble_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_GATT_DEFINES Defines + * @{ */ + +/** @brief Default ATT MTU, in bytes. */ +#define BLE_GATT_ATT_MTU_DEFAULT 23 + +/**@brief Invalid Attribute Handle. */ +#define BLE_GATT_HANDLE_INVALID 0x0000 + +/**@brief First Attribute Handle. */ +#define BLE_GATT_HANDLE_START 0x0001 + +/**@brief Last Attribute Handle. */ +#define BLE_GATT_HANDLE_END 0xFFFF + +/** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources + * @{ */ +#define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */ +/** @} */ + +/** @defgroup BLE_GATT_WRITE_OPS GATT Write operations + * @{ */ +#define BLE_GATT_OP_INVALID 0x00 /**< Invalid Operation. */ +#define BLE_GATT_OP_WRITE_REQ 0x01 /**< Write Request. */ +#define BLE_GATT_OP_WRITE_CMD 0x02 /**< Write Command. */ +#define BLE_GATT_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ +#define BLE_GATT_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ +#define BLE_GATT_OP_EXEC_WRITE_REQ 0x05 /**< Execute Write Request. */ +/** @} */ + +/** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags + * @{ */ +#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00 /**< Cancel prepared write. */ +#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 /**< Execute prepared write. */ +/** @} */ + +/** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations + * @{ */ +#define BLE_GATT_HVX_INVALID 0x00 /**< Invalid Operation. */ +#define BLE_GATT_HVX_NOTIFICATION 0x01 /**< Handle Value Notification. */ +#define BLE_GATT_HVX_INDICATION 0x02 /**< Handle Value Indication. */ +/** @} */ + +/** @defgroup BLE_GATT_STATUS_CODES GATT Status Codes + * @{ */ +#define BLE_GATT_STATUS_SUCCESS 0x0000 /**< Success. */ +#define BLE_GATT_STATUS_UNKNOWN 0x0001 /**< Unknown or not applicable status. */ +#define BLE_GATT_STATUS_ATTERR_INVALID 0x0100 /**< ATT Error: Invalid Error Code. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_HANDLE 0x0101 /**< ATT Error: Invalid Attribute Handle. */ +#define BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED 0x0102 /**< ATT Error: Read not permitted. */ +#define BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED 0x0103 /**< ATT Error: Write not permitted. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_PDU 0x0104 /**< ATT Error: Used in ATT as Invalid PDU. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION 0x0105 /**< ATT Error: Authenticated link required. */ +#define BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED 0x0106 /**< ATT Error: Used in ATT as Request Not Supported. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_OFFSET 0x0107 /**< ATT Error: Offset specified was past the end of the attribute. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION 0x0108 /**< ATT Error: Used in ATT as Insufficient Authorization. */ +#define BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL 0x0109 /**< ATT Error: Used in ATT as Prepare Queue Full. */ +#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND 0x010A /**< ATT Error: Used in ATT as Attribute not found. */ +#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_LONG 0x010B /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_ENC_KEY_SIZE 0x010C /**< ATT Error: Encryption key size used is insufficient. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH 0x010D /**< ATT Error: Invalid value size. */ +#define BLE_GATT_STATUS_ATTERR_UNLIKELY_ERROR 0x010E /**< ATT Error: Very unlikely error. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION 0x010F /**< ATT Error: Encrypted link required. */ +#define BLE_GATT_STATUS_ATTERR_UNSUPPORTED_GROUP_TYPE 0x0110 /**< ATT Error: Attribute type is not a supported grouping attribute. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_RESOURCES 0x0111 /**< ATT Error: Encrypted link required. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_BEGIN 0x0112 /**< ATT Error: Reserved for Future Use range #1 begin. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_END 0x017F /**< ATT Error: Reserved for Future Use range #1 end. */ +#define BLE_GATT_STATUS_ATTERR_APP_BEGIN 0x0180 /**< ATT Error: Application range begin. */ +#define BLE_GATT_STATUS_ATTERR_APP_END 0x019F /**< ATT Error: Application range end. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_BEGIN 0x01A0 /**< ATT Error: Reserved for Future Use range #2 begin. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_END 0x01DF /**< ATT Error: Reserved for Future Use range #2 end. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_BEGIN 0x01E0 /**< ATT Error: Reserved for Future Use range #3 begin. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_END 0x01FC /**< ATT Error: Reserved for Future Use range #3 end. */ +#define BLE_GATT_STATUS_ATTERR_CPS_WRITE_REQ_REJECTED 0x01FC /**< ATT Common Profile and Service Error: Write request rejected. */ +#define BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR 0x01FD /**< ATT Common Profile and Service Error: Client Characteristic Configuration Descriptor improperly configured. */ +#define BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG 0x01FE /**< ATT Common Profile and Service Error: Procedure Already in Progress. */ +#define BLE_GATT_STATUS_ATTERR_CPS_OUT_OF_RANGE 0x01FF /**< ATT Common Profile and Service Error: Out Of Range. */ +/** @} */ + + +/** @defgroup BLE_GATT_CPF_FORMATS Characteristic Presentation Formats + * @note Found at http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml + * @{ */ +#define BLE_GATT_CPF_FORMAT_RFU 0x00 /**< Reserved For Future Use. */ +#define BLE_GATT_CPF_FORMAT_BOOLEAN 0x01 /**< Boolean. */ +#define BLE_GATT_CPF_FORMAT_2BIT 0x02 /**< Unsigned 2-bit integer. */ +#define BLE_GATT_CPF_FORMAT_NIBBLE 0x03 /**< Unsigned 4-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT8 0x04 /**< Unsigned 8-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT12 0x05 /**< Unsigned 12-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT16 0x06 /**< Unsigned 16-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT24 0x07 /**< Unsigned 24-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT32 0x08 /**< Unsigned 32-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT48 0x09 /**< Unsigned 48-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT64 0x0A /**< Unsigned 64-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT128 0x0B /**< Unsigned 128-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT8 0x0C /**< Signed 2-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT12 0x0D /**< Signed 12-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT16 0x0E /**< Signed 16-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT24 0x0F /**< Signed 24-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT32 0x10 /**< Signed 32-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT48 0x11 /**< Signed 48-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT64 0x12 /**< Signed 64-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT128 0x13 /**< Signed 128-bit integer. */ +#define BLE_GATT_CPF_FORMAT_FLOAT32 0x14 /**< IEEE-754 32-bit floating point. */ +#define BLE_GATT_CPF_FORMAT_FLOAT64 0x15 /**< IEEE-754 64-bit floating point. */ +#define BLE_GATT_CPF_FORMAT_SFLOAT 0x16 /**< IEEE-11073 16-bit SFLOAT. */ +#define BLE_GATT_CPF_FORMAT_FLOAT 0x17 /**< IEEE-11073 32-bit FLOAT. */ +#define BLE_GATT_CPF_FORMAT_DUINT16 0x18 /**< IEEE-20601 format. */ +#define BLE_GATT_CPF_FORMAT_UTF8S 0x19 /**< UTF-8 string. */ +#define BLE_GATT_CPF_FORMAT_UTF16S 0x1A /**< UTF-16 string. */ +#define BLE_GATT_CPF_FORMAT_STRUCT 0x1B /**< Opaque Structure. */ +/** @} */ + +/** @defgroup BLE_GATT_CPF_NAMESPACES GATT Bluetooth Namespaces + * @{ + */ +#define BLE_GATT_CPF_NAMESPACE_BTSIG 0x01 /**< Bluetooth SIG defined Namespace. */ +#define BLE_GATT_CPF_NAMESPACE_DESCRIPTION_UNKNOWN 0x0000 /**< Namespace Description Unknown. */ +/** @} */ + +/** @} */ + +/** @addtogroup BLE_GATT_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE GATT connection configuration parameters, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_INVALID_PARAM att_mtu is smaller than @ref BLE_GATT_ATT_MTU_DEFAULT. + */ +typedef struct +{ + uint16_t att_mtu; /**< Maximum size of ATT packet the SoftDevice can send or receive. + The default and minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. + @mscs + @mmsc{@ref BLE_GATTC_MTU_EXCHANGE} + @mmsc{@ref BLE_GATTS_MTU_EXCHANGE} + @endmscs + */ +} ble_gatt_conn_cfg_t; + +/**@brief GATT Characteristic Properties. */ +typedef struct +{ + /* Standard properties */ + uint8_t broadcast :1; /**< Broadcasting of the value permitted. */ + uint8_t read :1; /**< Reading the value permitted. */ + uint8_t write_wo_resp :1; /**< Writing the value with Write Command permitted. */ + uint8_t write :1; /**< Writing the value with Write Request permitted. */ + uint8_t notify :1; /**< Notification of the value permitted. */ + uint8_t indicate :1; /**< Indications of the value permitted. */ + uint8_t auth_signed_wr :1; /**< Writing the value with Signed Write Command permitted. */ +} ble_gatt_char_props_t; + +/**@brief GATT Characteristic Extended Properties. */ +typedef struct +{ + /* Extended properties */ + uint8_t reliable_wr :1; /**< Writing the value with Queued Write operations permitted. */ + uint8_t wr_aux :1; /**< Writing the Characteristic User Description descriptor permitted. */ +} ble_gatt_char_ext_props_t; + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_GATT_H__ + +/** @} */ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_gattc.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_gattc.h new file mode 100644 index 00000000000..7fb3920244d --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_gattc.h @@ -0,0 +1,715 @@ +/* + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_GATTC Generic Attribute Profile (GATT) Client + @{ + @brief Definitions and prototypes for the GATT Client interface. + */ + +#ifndef BLE_GATTC_H__ +#define BLE_GATTC_H__ + +#include +#include "nrf.h" +#include "nrf_svc.h" +#include "nrf_error.h" +#include "ble_ranges.h" +#include "ble_types.h" +#include "ble_err.h" +#include "ble_gatt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations + * @{ */ + +/**@brief GATTC API SVC numbers. */ +enum BLE_GATTC_SVCS +{ + SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER = BLE_GATTC_SVC_BASE, /**< Primary Service Discovery. */ + SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, /**< Relationship Discovery. */ + SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, /**< Characteristic Discovery. */ + SD_BLE_GATTC_DESCRIPTORS_DISCOVER, /**< Characteristic Descriptor Discovery. */ + SD_BLE_GATTC_ATTR_INFO_DISCOVER, /**< Attribute Information Discovery. */ + SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, /**< Read Characteristic Value by UUID. */ + SD_BLE_GATTC_READ, /**< Generic read. */ + SD_BLE_GATTC_CHAR_VALUES_READ, /**< Read multiple Characteristic Values. */ + SD_BLE_GATTC_WRITE, /**< Generic write. */ + SD_BLE_GATTC_HV_CONFIRM, /**< Handle Value Confirmation. */ + SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. */ +}; + +/** + * @brief GATT Client Event IDs. + */ +enum BLE_GATTC_EVTS +{ + BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. \n See @ref ble_gattc_evt_prim_srvc_disc_rsp_t. */ + BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. \n See @ref ble_gattc_evt_rel_disc_rsp_t. */ + BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. \n See @ref ble_gattc_evt_char_disc_rsp_t. */ + BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. \n See @ref ble_gattc_evt_desc_disc_rsp_t. */ + BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, /**< Attribute Information Response event. \n See @ref ble_gattc_evt_attr_info_disc_rsp_t. */ + BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. \n See @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t. */ + BLE_GATTC_EVT_READ_RSP, /**< Read Response event. \n See @ref ble_gattc_evt_read_rsp_t. */ + BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. \n See @ref ble_gattc_evt_char_vals_read_rsp_t. */ + BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. \n See @ref ble_gattc_evt_write_rsp_t. */ + BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. \n Confirm indication with @ref sd_ble_gattc_hv_confirm. \n See @ref ble_gattc_evt_hvx_t. */ + BLE_GATTC_EVT_EXCHANGE_MTU_RSP, /**< Exchange MTU Response event. \n See @ref ble_gattc_evt_exchange_mtu_rsp_t. */ + BLE_GATTC_EVT_TIMEOUT, /**< Timeout event. \n See @ref ble_gattc_evt_timeout_t. */ + BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE /**< Write without Response transmission complete. \n See @ref ble_gattc_evt_write_cmd_tx_complete_t. */ +}; + +/** @} */ + +/** @addtogroup BLE_GATTC_DEFINES Defines + * @{ */ + +/** @defgroup BLE_ERRORS_GATTC SVC return values specific to GATTC + * @{ */ +#define BLE_ERROR_GATTC_PROC_NOT_PERMITTED (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */ +/** @} */ + +/** @defgroup BLE_GATTC_ATTR_INFO_FORMAT Attribute Information Formats + * @{ */ +#define BLE_GATTC_ATTR_INFO_FORMAT_16BIT 1 /**< 16-bit Attribute Information Format. */ +#define BLE_GATTC_ATTR_INFO_FORMAT_128BIT 2 /**< 128-bit Attribute Information Format. */ +/** @} */ + +/** @defgroup BLE_GATTC_DEFAULTS GATT Client defaults + * @{ */ +#define BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Write without Response that can be queued for transmission. */ +/** @} */ + +/** @} */ + +/** @addtogroup BLE_GATTC_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE GATTC connection configuration parameters, set with @ref sd_ble_cfg_set. + */ +typedef struct +{ + uint8_t write_cmd_tx_queue_size; /**< The guaranteed minimum number of Write without Response that can be queued for transmission. + The default value is @ref BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT */ +} ble_gattc_conn_cfg_t; + +/**@brief Operation Handle Range. */ +typedef struct +{ + uint16_t start_handle; /**< Start Handle. */ + uint16_t end_handle; /**< End Handle. */ +} ble_gattc_handle_range_t; + + +/**@brief GATT service. */ +typedef struct +{ + ble_uuid_t uuid; /**< Service UUID. */ + ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */ +} ble_gattc_service_t; + + +/**@brief GATT include. */ +typedef struct +{ + uint16_t handle; /**< Include Handle. */ + ble_gattc_service_t included_srvc; /**< Handle of the included service. */ +} ble_gattc_include_t; + + +/**@brief GATT characteristic. */ +typedef struct +{ + ble_uuid_t uuid; /**< Characteristic UUID. */ + ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ + uint8_t char_ext_props : 1; /**< Extended properties present. */ + uint16_t handle_decl; /**< Handle of the Characteristic Declaration. */ + uint16_t handle_value; /**< Handle of the Characteristic Value. */ +} ble_gattc_char_t; + + +/**@brief GATT descriptor. */ +typedef struct +{ + uint16_t handle; /**< Descriptor Handle. */ + ble_uuid_t uuid; /**< Descriptor UUID. */ +} ble_gattc_desc_t; + + +/**@brief Write Parameters. */ +typedef struct +{ + uint8_t write_op; /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */ + uint8_t flags; /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */ + uint16_t handle; /**< Handle to the attribute to be written. */ + uint16_t offset; /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */ + uint16_t len; /**< Length of data in bytes. */ + uint8_t const *p_value; /**< Pointer to the value data. */ +} ble_gattc_write_params_t; + +/**@brief Attribute Information for 16-bit Attribute UUID. */ +typedef struct +{ + uint16_t handle; /**< Attribute handle. */ + ble_uuid_t uuid; /**< 16-bit Attribute UUID. */ +} ble_gattc_attr_info16_t; + +/**@brief Attribute Information for 128-bit Attribute UUID. */ +typedef struct +{ + uint16_t handle; /**< Attribute handle. */ + ble_uuid128_t uuid; /**< 128-bit Attribute UUID. */ +} ble_gattc_attr_info128_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Service count. */ + ble_gattc_service_t services[1]; /**< Service data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_prim_srvc_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Include count. */ + ble_gattc_include_t includes[1]; /**< Include data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_rel_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Characteristic count. */ + ble_gattc_char_t chars[1]; /**< Characteristic data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_char_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Descriptor count. */ + ble_gattc_desc_t descs[1]; /**< Descriptor data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_desc_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Attribute count. */ + uint8_t format; /**< Attribute information format, see @ref BLE_GATTC_ATTR_INFO_FORMAT. */ + union { + ble_gattc_attr_info16_t attr_info16[1]; /**< Attribute information for 16-bit Attribute UUID. + @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ + ble_gattc_attr_info128_t attr_info128[1]; /**< Attribute information for 128-bit Attribute UUID. + @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ + } info; /**< Attribute information union. */ +} ble_gattc_evt_attr_info_disc_rsp_t; + +/**@brief GATT read by UUID handle value pair. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + uint8_t *p_value; /**< Pointer to the Attribute Value, length is available in @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t::value_len. */ +} ble_gattc_handle_value_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP. */ +typedef struct +{ + uint16_t count; /**< Handle-Value Pair Count. */ + uint16_t value_len; /**< Length of the value in Handle-Value(s) list. */ + uint8_t handle_value[1]; /**< Handle-Value(s) list. To iterate through the list use @ref sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter. + @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_char_val_by_uuid_read_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + uint16_t offset; /**< Offset of the attribute data. */ + uint16_t len; /**< Attribute data length. */ + uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_read_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */ +typedef struct +{ + uint16_t len; /**< Concatenated Attribute values length. */ + uint8_t values[1]; /**< Attribute values. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_char_vals_read_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + uint8_t write_op; /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */ + uint16_t offset; /**< Data offset. */ + uint16_t len; /**< Data length. */ + uint8_t data[1]; /**< Data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_write_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */ +typedef struct +{ + uint16_t handle; /**< Handle to which the HVx operation applies. */ + uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ + uint16_t len; /**< Attribute data length. */ + uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_hvx_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. */ +typedef struct +{ + uint16_t server_rx_mtu; /**< Server RX MTU size. */ +} ble_gattc_evt_exchange_mtu_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */ +typedef struct +{ + uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ +} ble_gattc_evt_timeout_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE. */ +typedef struct +{ + uint8_t count; /**< Number of write without response transmissions completed. */ +} ble_gattc_evt_write_cmd_tx_complete_t; + +/**@brief GATTC event structure. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which event occurred. */ + uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ + uint16_t error_handle; /**< In case of error: The handle causing the error. In all other cases @ref BLE_GATT_HANDLE_INVALID. */ + union + { + ble_gattc_evt_prim_srvc_disc_rsp_t prim_srvc_disc_rsp; /**< Primary Service Discovery Response Event Parameters. */ + ble_gattc_evt_rel_disc_rsp_t rel_disc_rsp; /**< Relationship Discovery Response Event Parameters. */ + ble_gattc_evt_char_disc_rsp_t char_disc_rsp; /**< Characteristic Discovery Response Event Parameters. */ + ble_gattc_evt_desc_disc_rsp_t desc_disc_rsp; /**< Descriptor Discovery Response Event Parameters. */ + ble_gattc_evt_char_val_by_uuid_read_rsp_t char_val_by_uuid_read_rsp; /**< Characteristic Value Read by UUID Response Event Parameters. */ + ble_gattc_evt_read_rsp_t read_rsp; /**< Read Response Event Parameters. */ + ble_gattc_evt_char_vals_read_rsp_t char_vals_read_rsp; /**< Characteristic Values Read Response Event Parameters. */ + ble_gattc_evt_write_rsp_t write_rsp; /**< Write Response Event Parameters. */ + ble_gattc_evt_hvx_t hvx; /**< Handle Value Notification/Indication Event Parameters. */ + ble_gattc_evt_exchange_mtu_rsp_t exchange_mtu_rsp; /**< Exchange MTU Response Event Parameters. */ + ble_gattc_evt_timeout_t timeout; /**< Timeout Event Parameters. */ + ble_gattc_evt_attr_info_disc_rsp_t attr_info_disc_rsp; /**< Attribute Information Discovery Event Parameters. */ + ble_gattc_evt_write_cmd_tx_complete_t write_cmd_tx_complete; /**< Write without Response transmission complete Event Parameters. */ + } params; /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */ +} ble_gattc_evt_t; +/** @} */ + +/** @addtogroup BLE_GATTC_FUNCTIONS Functions + * @{ */ + +/**@brief Initiate or continue a GATT Primary Service Discovery procedure. + * + * @details This function initiates or resumes a Primary Service discovery procedure, starting from the supplied handle. + * If the last service has not been reached, this function must be called again with an updated start handle value to continue the search. + * + * @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with + * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. + * + * @events + * @event{@ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_PRIM_SRVC_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] start_handle Handle to start searching from. + * @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Primary Service Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const *p_srvc_uuid)); + + +/**@brief Initiate or continue a GATT Relationship Discovery procedure. + * + * @details This function initiates or resumes the Find Included Services sub-procedure. If the last included service has not been reached, + * this must be called again with an updated handle range to continue the search. + * + * @events + * @event{@ref BLE_GATTC_EVT_REL_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_REL_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Relationship Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, sd_ble_gattc_relationships_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); + + +/**@brief Initiate or continue a GATT Characteristic Discovery procedure. + * + * @details This function initiates or resumes a Characteristic discovery procedure. If the last Characteristic has not been reached, + * this must be called again with an updated handle range to continue the discovery. + * + * @note If any of the discovered characteristics have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with + * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. + * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_CHAR_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Characteristic Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, sd_ble_gattc_characteristics_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); + + +/**@brief Initiate or continue a GATT Characteristic Descriptor Discovery procedure. + * + * @details This function initiates or resumes a Characteristic Descriptor discovery procedure. If the last Descriptor has not been reached, + * this must be called again with an updated handle range to continue the discovery. + * + * @events + * @event{@ref BLE_GATTC_EVT_DESC_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_DESC_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Descriptor Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, sd_ble_gattc_descriptors_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); + + +/**@brief Initiate or continue a GATT Read using Characteristic UUID procedure. + * + * @details This function initiates or resumes a Read using Characteristic UUID procedure. If the last Characteristic has not been reached, + * this must be called again with an updated handle range to continue the discovery. + * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_READ_UUID_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_uuid Pointer to a Characteristic value UUID to read. + * @param[in] p_handle_range A pointer to the range of handles to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Read using Characteristic UUID procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, ble_uuid_t const *p_uuid, ble_gattc_handle_range_t const *p_handle_range)); + + +/**@brief Initiate or continue a GATT Read (Long) Characteristic or Descriptor procedure. + * + * @details This function initiates or resumes a GATT Read (Long) Characteristic or Descriptor procedure. If the Characteristic or Descriptor + * to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read the + * complete value. + * + * @events + * @event{@ref BLE_GATTC_EVT_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_VALUE_READ_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] handle The handle of the attribute to be read. + * @param[in] offset Offset into the attribute value to be read. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset)); + + +/**@brief Initiate a GATT Read Multiple Characteristic Values procedure. + * + * @details This function initiates a GATT Read Multiple Characteristic Values procedure. + * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_READ_MULT_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read. + * @param[in] handle_count The number of handles in p_handles. + * + * @retval ::NRF_SUCCESS Successfully started the Read Multiple Characteristic Values procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(uint16_t conn_handle, uint16_t const *p_handles, uint16_t handle_count)); + + +/**@brief Perform a Write (Characteristic Value or Descriptor, with or without response, signed or not, long or reliable) procedure. + * + * @details This function can perform all write procedures described in GATT. + * + * @note Only one write with response procedure can be ongoing per connection at a time. + * If the application tries to write with response while another write with response procedure is ongoing, + * the function call will return @ref NRF_ERROR_BUSY. + * A @ref BLE_GATTC_EVT_WRITE_RSP event will be issued as soon as the write response arrives from the peer. + * + * @note The number of Write without Response that can be queued is configured by @ref ble_gattc_conn_cfg_t::write_cmd_tx_queue_size + * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES. + * A @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event will be issued as soon as the transmission of the write without response is complete. + * + * @note The application can keep track of the available queue element count for writes without responses by following the procedure below: + * - Store initial queue element count in a variable. + * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS. + * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event. + * + * @events + * @event{@ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE, Write without response transmission complete.} + * @event{@ref BLE_GATTC_EVT_WRITE_RSP, Write response received from the peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_VALUE_WRITE_WITHOUT_RESP_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_WRITE_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_LONG_WRITE_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_RELIABLE_WRITE_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_write_params A pointer to a write parameters structure. + * + * @retval ::NRF_SUCCESS Successfully started the Write procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + * @retval ::NRF_ERROR_BUSY For write with response, procedure already in progress. Wait for a @ref BLE_GATTC_EVT_WRITE_RSP event and retry. + * @retval ::NRF_ERROR_RESOURCES Too many writes without responses queued. + * Wait for a @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event and retry. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params)); + + +/**@brief Send a Handle Value Confirmation to the GATT Server. + * + * @mscs + * @mmsc{@ref BLE_GATTC_HVI_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] handle The handle of the attribute in the indication. + * + * @retval ::NRF_SUCCESS Successfully queued the Handle Value Confirmation for transmission. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no Indication pending to be confirmed. + * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle)); + +/**@brief Discovers information about a range of attributes on a GATT server. + * + * @events + * @event{@ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, Generated when information about a range of attributes has been received.} + * @endevents + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range The range of handles to request information about. + * + * @retval ::NRF_SUCCESS Successfully started an attribute information discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_ATTR_INFO_DISCOVER, uint32_t, sd_ble_gattc_attr_info_discover(uint16_t conn_handle, ble_gattc_handle_range_t const * p_handle_range)); + +/**@brief Start an ATT_MTU exchange by sending an Exchange MTU Request to the server. + * + * @details The SoftDevice sets ATT_MTU to the minimum of: + * - The Client RX MTU value, and + * - The Server RX MTU value from @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. + * + * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT. + * + * @events + * @event{@ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_MTU_EXCHANGE} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] client_rx_mtu Client RX MTU size. + * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. + * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration + used for this connection. + * - The value must be equal to Server RX MTU size given in @ref sd_ble_gatts_exchange_mtu_reply + * if an ATT_MTU exchange has already been performed in the other direction. + * + * @retval ::NRF_SUCCESS Successfully sent request to the server. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state or an ATT_MTU exchange was already requested once. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid Client RX MTU size supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, uint32_t, sd_ble_gattc_exchange_mtu_request(uint16_t conn_handle, uint16_t client_rx_mtu)); + +/**@brief Iterate through Handle-Value(s) list in @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event. + * + * @param[in] p_gattc_evt Pointer to event buffer containing @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event. + * @note If the buffer contains different event, behavior is undefined. + * @param[in,out] p_iter Iterator, points to @ref ble_gattc_handle_value_t structure that will be filled in with + * the next Handle-Value pair in each iteration. If the function returns other than + * @ref NRF_SUCCESS, it will not be changed. + * - To start iteration, initialize the structure to zero. + * - To continue, pass the value from previous iteration. + * + * \code + * ble_gattc_handle_value_t iter; + * memset(&iter, 0, sizeof(ble_gattc_handle_value_t)); + * while (sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(&ble_evt.evt.gattc_evt, &iter) == NRF_SUCCESS) + * { + * app_handle = iter.handle; + * memcpy(app_value, iter.p_value, ble_evt.evt.gattc_evt.params.char_val_by_uuid_read_rsp.value_len); + * } + * \endcode + * + * @retval ::NRF_SUCCESS Successfully retrieved the next Handle-Value pair. + * @retval ::NRF_ERROR_NOT_FOUND No more Handle-Value pairs available in the list. + */ +__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter); + +/** @} */ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter) +{ + uint32_t value_len = p_gattc_evt->params.char_val_by_uuid_read_rsp.value_len; + uint8_t *p_first = p_gattc_evt->params.char_val_by_uuid_read_rsp.handle_value; + uint8_t *p_next = p_iter->p_value ? p_iter->p_value + value_len : p_first; + + if ((p_next - p_first) / (sizeof(uint16_t) + value_len) < p_gattc_evt->params.char_val_by_uuid_read_rsp.count) + { + p_iter->handle = (uint16_t)p_next[1] << 8 | p_next[0]; + p_iter->p_value = p_next + sizeof(uint16_t); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_NOT_FOUND; + } +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +#ifdef __cplusplus +} +#endif +#endif /* BLE_GATTC_H__ */ + +/** + @} +*/ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_gatts.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_gatts.h new file mode 100644 index 00000000000..394d8d18972 --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_gatts.h @@ -0,0 +1,845 @@ +/* + * Copyright (c) 2011 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_GATTS Generic Attribute Profile (GATT) Server + @{ + @brief Definitions and prototypes for the GATTS interface. + */ + +#ifndef BLE_GATTS_H__ +#define BLE_GATTS_H__ + +#include +#include "nrf_svc.h" +#include "nrf_error.h" +#include "ble_hci.h" +#include "ble_ranges.h" +#include "ble_types.h" +#include "ble_err.h" +#include "ble_gatt.h" +#include "ble_gap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations + * @{ */ + +/** + * @brief GATTS API SVC numbers. + */ +enum BLE_GATTS_SVCS +{ + SD_BLE_GATTS_SERVICE_ADD = BLE_GATTS_SVC_BASE, /**< Add a service. */ + SD_BLE_GATTS_INCLUDE_ADD, /**< Add an included service. */ + SD_BLE_GATTS_CHARACTERISTIC_ADD, /**< Add a characteristic. */ + SD_BLE_GATTS_DESCRIPTOR_ADD, /**< Add a generic attribute. */ + SD_BLE_GATTS_VALUE_SET, /**< Set an attribute value. */ + SD_BLE_GATTS_VALUE_GET, /**< Get an attribute value. */ + SD_BLE_GATTS_HVX, /**< Handle Value Notification or Indication. */ + SD_BLE_GATTS_SERVICE_CHANGED, /**< Perform a Service Changed Indication to one or more peers. */ + SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more attributes. */ + SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */ + SD_BLE_GATTS_SYS_ATTR_GET, /**< Retrieve the persistent system attributes. */ + SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, /**< Retrieve the first valid user handle. */ + SD_BLE_GATTS_ATTR_GET, /**< Retrieve the UUID and/or metadata of an attribute. */ + SD_BLE_GATTS_EXCHANGE_MTU_REPLY /**< Reply to Exchange MTU Request. */ +}; + +/** + * @brief GATT Server Event IDs. + */ +enum BLE_GATTS_EVTS +{ + BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. \n See @ref ble_gatts_evt_write_t. */ + BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request. \n Reply with @ref sd_ble_gatts_rw_authorize_reply. \n See @ref ble_gatts_evt_rw_authorize_request_t. */ + BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending. \n Respond with @ref sd_ble_gatts_sys_attr_set. \n See @ref ble_gatts_evt_sys_attr_missing_t. */ + BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. \n See @ref ble_gatts_evt_hvc_t. */ + BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. \n No additional event structure applies. */ + BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. \n Reply with @ref sd_ble_gatts_exchange_mtu_reply. \n See @ref ble_gatts_evt_exchange_mtu_request_t. */ + BLE_GATTS_EVT_TIMEOUT, /**< Peer failed to respond to an ATT request in time. \n See @ref ble_gatts_evt_timeout_t. */ + BLE_GATTS_EVT_HVN_TX_COMPLETE /**< Handle Value Notification transmission complete. \n See @ref ble_gatts_evt_hvn_tx_complete_t. */ +}; + +/**@brief GATTS Configuration IDs. + * + * IDs that uniquely identify a GATTS configuration. + */ +enum BLE_GATTS_CFGS +{ + BLE_GATTS_CFG_SERVICE_CHANGED = BLE_GATTS_CFG_BASE, /**< Service changed configuration. */ + BLE_GATTS_CFG_ATTR_TAB_SIZE, /**< Attribute table size configuration. */ +}; + +/** @} */ + +/** @addtogroup BLE_GATTS_DEFINES Defines + * @{ */ + +/** @defgroup BLE_ERRORS_GATTS SVC return values specific to GATTS + * @{ */ +#define BLE_ERROR_GATTS_INVALID_ATTR_TYPE (NRF_GATTS_ERR_BASE + 0x000) /**< Invalid attribute type. */ +#define BLE_ERROR_GATTS_SYS_ATTR_MISSING (NRF_GATTS_ERR_BASE + 0x001) /**< System Attributes missing. */ +/** @} */ + +/** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths + * @{ */ +#define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */ +#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */ +/** @} */ + +/** @defgroup BLE_GATTS_SRVC_TYPES GATT Server Service Types + * @{ */ +#define BLE_GATTS_SRVC_TYPE_INVALID 0x00 /**< Invalid Service Type. */ +#define BLE_GATTS_SRVC_TYPE_PRIMARY 0x01 /**< Primary Service. */ +#define BLE_GATTS_SRVC_TYPE_SECONDARY 0x02 /**< Secondary Type. */ +/** @} */ + + +/** @defgroup BLE_GATTS_ATTR_TYPES GATT Server Attribute Types + * @{ */ +#define BLE_GATTS_ATTR_TYPE_INVALID 0x00 /**< Invalid Attribute Type. */ +#define BLE_GATTS_ATTR_TYPE_PRIM_SRVC_DECL 0x01 /**< Primary Service Declaration. */ +#define BLE_GATTS_ATTR_TYPE_SEC_SRVC_DECL 0x02 /**< Secondary Service Declaration. */ +#define BLE_GATTS_ATTR_TYPE_INC_DECL 0x03 /**< Include Declaration. */ +#define BLE_GATTS_ATTR_TYPE_CHAR_DECL 0x04 /**< Characteristic Declaration. */ +#define BLE_GATTS_ATTR_TYPE_CHAR_VAL 0x05 /**< Characteristic Value. */ +#define BLE_GATTS_ATTR_TYPE_DESC 0x06 /**< Descriptor. */ +#define BLE_GATTS_ATTR_TYPE_OTHER 0x07 /**< Other, non-GATT specific type. */ +/** @} */ + + +/** @defgroup BLE_GATTS_OPS GATT Server Operations + * @{ */ +#define BLE_GATTS_OP_INVALID 0x00 /**< Invalid Operation. */ +#define BLE_GATTS_OP_WRITE_REQ 0x01 /**< Write Request. */ +#define BLE_GATTS_OP_WRITE_CMD 0x02 /**< Write Command. */ +#define BLE_GATTS_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ +#define BLE_GATTS_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ +#define BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL 0x05 /**< Execute Write Request: Cancel all prepared writes. */ +#define BLE_GATTS_OP_EXEC_WRITE_REQ_NOW 0x06 /**< Execute Write Request: Immediately execute all prepared writes. */ +/** @} */ + +/** @defgroup BLE_GATTS_VLOCS GATT Value Locations + * @{ */ +#define BLE_GATTS_VLOC_INVALID 0x00 /**< Invalid Location. */ +#define BLE_GATTS_VLOC_STACK 0x01 /**< Attribute Value is located in stack memory, no user memory is required. */ +#define BLE_GATTS_VLOC_USER 0x02 /**< Attribute Value is located in user memory. This requires the user to maintain a valid buffer through the lifetime of the attribute, since the stack + will read and write directly to the memory using the pointer provided in the APIs. There are no alignment requirements for the buffer. */ +/** @} */ + +/** @defgroup BLE_GATTS_AUTHORIZE_TYPES GATT Server Authorization Types + * @{ */ +#define BLE_GATTS_AUTHORIZE_TYPE_INVALID 0x00 /**< Invalid Type. */ +#define BLE_GATTS_AUTHORIZE_TYPE_READ 0x01 /**< Authorize a Read Operation. */ +#define BLE_GATTS_AUTHORIZE_TYPE_WRITE 0x02 /**< Authorize a Write Request Operation. */ +/** @} */ + +/** @defgroup BLE_GATTS_SYS_ATTR_FLAGS System Attribute Flags + * @{ */ +#define BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS (1 << 0) /**< Restrict system attributes to system services only. */ +#define BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS (1 << 1) /**< Restrict system attributes to user services only. */ +/** @} */ + +/** @defgroup BLE_GATTS_SERVICE_CHANGED Service Changed Inclusion Values + * @{ + */ +#define BLE_GATTS_SERVICE_CHANGED_DEFAULT (1) /**< Default is to include the Service Changed characteristic in the Attribute Table. */ +/** @} */ + +/** @defgroup BLE_GATTS_ATTR_TAB_SIZE Attribute Table size + * @{ + */ +#define BLE_GATTS_ATTR_TAB_SIZE_MIN (248) /**< Minimum Attribute Table size */ +#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT (1408) /**< Default Attribute Table size. */ +/** @} */ + +/** @defgroup BLE_GATTS_DEFAULTS GATT Server defaults + * @{ + */ +#define BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Handle Value Notifications that can be queued for transmission. */ +/** @} */ + +/** @} */ + +/** @addtogroup BLE_GATTS_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE GATTS connection configuration parameters, set with @ref sd_ble_cfg_set. + */ +typedef struct +{ + uint8_t hvn_tx_queue_size; /**< Minimum guaranteed number of Handle Value Notifications that can be queued for transmission. + The default value is @ref BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT */ +} ble_gatts_conn_cfg_t; + +/**@brief Attribute metadata. */ +typedef struct +{ + ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */ + ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ + uint8_t vlen :1; /**< Variable length attribute. */ + uint8_t vloc :2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ + uint8_t rd_auth :1; /**< Read authorization and value will be requested from the application on every read operation. */ + uint8_t wr_auth :1; /**< Write authorization will be requested from the application on every Write Request operation (but not Write Command). */ +} ble_gatts_attr_md_t; + + +/**@brief GATT Attribute. */ +typedef struct +{ + ble_uuid_t const *p_uuid; /**< Pointer to the attribute UUID. */ + ble_gatts_attr_md_t const *p_attr_md; /**< Pointer to the attribute metadata structure. */ + uint16_t init_len; /**< Initial attribute value length in bytes. */ + uint16_t init_offs; /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */ + uint16_t max_len; /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */ + uint8_t *p_value; /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer + that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location. + The stack may access that memory directly without the application's knowledge. For writable characteristics, this value must not be a location in flash memory.*/ +} ble_gatts_attr_t; + +/**@brief GATT Attribute Value. */ +typedef struct +{ + uint16_t len; /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/ + uint16_t offset; /**< Attribute value offset. */ + uint8_t *p_value; /**< Pointer to where value is stored or will be stored. + If value is stored in user memory, only the attribute length is updated when p_value == NULL. + Set to NULL when reading to obtain the complete length of the attribute value */ +} ble_gatts_value_t; + + +/**@brief GATT Characteristic Presentation Format. */ +typedef struct +{ + uint8_t format; /**< Format of the value, see @ref BLE_GATT_CPF_FORMATS. */ + int8_t exponent; /**< Exponent for integer data types. */ + uint16_t unit; /**< Unit from Bluetooth Assigned Numbers. */ + uint8_t name_space; /**< Namespace from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ + uint16_t desc; /**< Namespace description from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ +} ble_gatts_char_pf_t; + + +/**@brief GATT Characteristic metadata. */ +typedef struct +{ + ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ + ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic Extended Properties. */ + uint8_t const *p_char_user_desc; /**< Pointer to a UTF-8 encoded string (non-NULL terminated), NULL if the descriptor is not required. */ + uint16_t char_user_desc_max_size; /**< The maximum size in bytes of the user description descriptor. */ + uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */ + ble_gatts_char_pf_t const *p_char_pf; /**< Pointer to a presentation format structure or NULL if the CPF descriptor is not required. */ + ble_gatts_attr_md_t const *p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */ + ble_gatts_attr_md_t const *p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */ + ble_gatts_attr_md_t const *p_sccd_md; /**< Attribute metadata for the Server Characteristic Configuration Descriptor, or NULL for default values. */ +} ble_gatts_char_md_t; + + +/**@brief GATT Characteristic Definition Handles. */ +typedef struct +{ + uint16_t value_handle; /**< Handle to the characteristic value. */ + uint16_t user_desc_handle; /**< Handle to the User Description descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ + uint16_t cccd_handle; /**< Handle to the Client Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ + uint16_t sccd_handle; /**< Handle to the Server Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ +} ble_gatts_char_handles_t; + + +/**@brief GATT HVx parameters. */ +typedef struct +{ + uint16_t handle; /**< Characteristic Value Handle. */ + uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ + uint16_t offset; /**< Offset within the attribute value. */ + uint16_t *p_len; /**< Length in bytes to be written, length in bytes written after return. */ + uint8_t const *p_data; /**< Actual data content, use NULL to use the current attribute value. */ +} ble_gatts_hvx_params_t; + +/**@brief GATT Authorization parameters. */ +typedef struct +{ + uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ + uint8_t update : 1; /**< If set, data supplied in p_data will be used to update the attribute value. + Please note that for @ref BLE_GATTS_AUTHORIZE_TYPE_WRITE operations this bit must always be set, + as the data to be written needs to be stored and later provided by the application. */ + uint16_t offset; /**< Offset of the attribute value being updated. */ + uint16_t len; /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */ + uint8_t const *p_data; /**< Pointer to new value used to update the attribute value. */ +} ble_gatts_authorize_params_t; + +/**@brief GATT Read or Write Authorize Reply parameters. */ +typedef struct +{ + uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ + union { + ble_gatts_authorize_params_t read; /**< Read authorization parameters. */ + ble_gatts_authorize_params_t write; /**< Write authorization parameters. */ + } params; /**< Reply Parameters. */ +} ble_gatts_rw_authorize_reply_params_t; + +/**@brief Service Changed Inclusion configuration parameters, set with @ref sd_ble_cfg_set. */ +typedef struct +{ + uint8_t service_changed : 1; /**< If 1, include the Service Changed characteristic in the Attribute Table. Default is @ref BLE_GATTS_SERVICE_CHANGED_DEFAULT. */ +} ble_gatts_cfg_service_changed_t; + +/**@brief Attribute table size configuration parameters, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true: + * - The specified Attribute Table size is too small. + * The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. + * - The specified Attribute Table size is not a multiple of 4. + */ +typedef struct +{ + uint32_t attr_tab_size; /**< Attribute table size. Default is @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, minimum is @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. */ +} ble_gatts_cfg_attr_tab_size_t; + +/**@brief Config structure for GATTS configurations. */ +typedef union +{ + ble_gatts_cfg_service_changed_t service_changed; /**< Include service changed characteristic, cfg_id is @ref BLE_GATTS_CFG_SERVICE_CHANGED. */ + ble_gatts_cfg_attr_tab_size_t attr_tab_size; /**< Attribute table size, cfg_id is @ref BLE_GATTS_CFG_ATTR_TAB_SIZE. */ +} ble_gatts_cfg_t; + + +/**@brief Event structure for @ref BLE_GATTS_EVT_WRITE. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + ble_uuid_t uuid; /**< Attribute UUID. */ + uint8_t op; /**< Type of write operation, see @ref BLE_GATTS_OPS. */ + uint8_t auth_required; /**< Writing operation deferred due to authorization requirement. Application may use @ref sd_ble_gatts_value_set to finalize the writing operation. */ + uint16_t offset; /**< Offset for the write operation. */ + uint16_t len; /**< Length of the received data. */ + uint8_t data[1]; /**< Received data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gatts_evt_write_t; + +/**@brief Event substructure for authorized read requests, see @ref ble_gatts_evt_rw_authorize_request_t. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + ble_uuid_t uuid; /**< Attribute UUID. */ + uint16_t offset; /**< Offset for the read operation. */ +} ble_gatts_evt_read_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. */ +typedef struct +{ + uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ + union { + ble_gatts_evt_read_t read; /**< Attribute Read Parameters. */ + ble_gatts_evt_write_t write; /**< Attribute Write Parameters. */ + } request; /**< Request Parameters. */ +} ble_gatts_evt_rw_authorize_request_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. */ +typedef struct +{ + uint8_t hint; /**< Hint (currently unused). */ +} ble_gatts_evt_sys_attr_missing_t; + + +/**@brief Event structure for @ref BLE_GATTS_EVT_HVC. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ +} ble_gatts_evt_hvc_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST. */ +typedef struct +{ + uint16_t client_rx_mtu; /**< Client RX MTU size. */ +} ble_gatts_evt_exchange_mtu_request_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_TIMEOUT. */ +typedef struct +{ + uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ +} ble_gatts_evt_timeout_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_HVN_TX_COMPLETE. */ +typedef struct +{ + uint8_t count; /**< Number of notification transmissions completed. */ +} ble_gatts_evt_hvn_tx_complete_t; + +/**@brief GATTS event structure. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which the event occurred. */ + union + { + ble_gatts_evt_write_t write; /**< Write Event Parameters. */ + ble_gatts_evt_rw_authorize_request_t authorize_request; /**< Read or Write Authorize Request Parameters. */ + ble_gatts_evt_sys_attr_missing_t sys_attr_missing; /**< System attributes missing. */ + ble_gatts_evt_hvc_t hvc; /**< Handle Value Confirmation Event Parameters. */ + ble_gatts_evt_exchange_mtu_request_t exchange_mtu_request; /**< Exchange MTU Request Event Parameters. */ + ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */ + ble_gatts_evt_hvn_tx_complete_t hvn_tx_complete; /**< Handle Value Notification transmission complete Event Parameters. */ + } params; /**< Event Parameters. */ +} ble_gatts_evt_t; + +/** @} */ + +/** @addtogroup BLE_GATTS_FUNCTIONS Functions + * @{ */ + +/**@brief Add a service declaration to the Attribute Table. + * + * @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to + * add a secondary service declaration that is not referenced by another service later in the Attribute Table. + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] type Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES. + * @param[in] p_uuid Pointer to service UUID. + * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully added a service declaration. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + */ +SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const *p_uuid, uint16_t *p_handle)); + + +/**@brief Add an include declaration to the Attribute Table. + * + * @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential population is supported at this time). + * + * @note The included service must already be present in the Attribute Table prior to this call. + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] service_handle Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. + * @param[in] inc_srvc_handle Handle of the included service. + * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully added an include declaration. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required. + * @retval ::NRF_ERROR_NOT_SUPPORTED Feature is not supported, service_handle must be that of the last added service. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + */ +SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, sd_ble_gatts_include_add(uint16_t service_handle, uint16_t inc_srvc_handle, uint16_t *p_include_handle)); + + +/**@brief Add a characteristic declaration, a characteristic value declaration and optional characteristic descriptor declarations to the Attribute Table. + * + * @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential population is supported at this time). + * + * @note Several restrictions apply to the parameters, such as matching permissions between the user description descriptor and the writable auxiliaries bits, + * readable (no security) and writable (selectable) CCCDs and SCCDs and valid presentation format values. + * + * @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic permissions. + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] service_handle Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. + * @param[in] p_char_md Characteristic metadata. + * @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value. + * @param[out] p_handles Pointer to the structure where the assigned handles will be stored. + * + * @retval ::NRF_SUCCESS Successfully added a characteristic. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, service handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. + */ +SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_add(uint16_t service_handle, ble_gatts_char_md_t const *p_char_md, ble_gatts_attr_t const *p_attr_char_value, ble_gatts_char_handles_t *p_handles)); + + +/**@brief Add a descriptor to the Attribute Table. + * + * @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is supported at this time). + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] char_handle Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. + * @param[in] p_attr Pointer to the attribute structure. + * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully added a descriptor. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, characteristic handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a characteristic context is required. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. + */ +SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle)); + +/**@brief Set the value of a given attribute. + * + * @note Values other than system attributes can be set at any time, regardless of whether any active connections exist. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute. + * @param[in] handle Attribute handle. + * @param[in,out] p_value Attribute value information. + * + * @retval ::NRF_SUCCESS Successfully set the value of the attribute. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden handle supplied, certain attributes are not modifiable by the application. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute. + */ +SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); + +/**@brief Get the value of a given attribute. + * + * @note If the attribute value is longer than the size of the supplied buffer, + * @ref ble_gatts_value_t::len will return the total attribute value length (excluding offset), + * and not the number of bytes actually returned in @ref ble_gatts_value_t::p_value. + * The application may use this information to allocate a suitable buffer size. + * + * @note When retrieving system attribute values with this function, the connection handle + * may refer to an already disconnected connection. Refer to the documentation of + * @ref sd_ble_gatts_sys_attr_get for further information. + * + * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute. + * @param[in] handle Attribute handle. + * @param[in,out] p_value Attribute value information. + * + * @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid attribute offset supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute. + * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. + */ +SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); + +/**@brief Notify or Indicate an attribute value. + * + * @details This function checks for the relevant Client Characteristic Configuration descriptor value to verify that the relevant operation + * (notification or indication) has been enabled by the client. It is also able to update the attribute value before issuing the PDU, so that + * the application can atomically perform a value update and a server initiated transaction with a single API call. + * + * @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution. + * The Attribute Table has been updated if one of the following error codes is returned: @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY, + * @ref NRF_ERROR_FORBIDDEN, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and @ref NRF_ERROR_RESOURCES. + * The caller can check whether the value has been updated by looking at the contents of *(@ref ble_gatts_hvx_params_t::p_len). + * + * @note Only one indication procedure can be ongoing per connection at a time. + * If the application tries to indicate an attribute value while another indication procedure is ongoing, + * the function call will return @ref NRF_ERROR_BUSY. + * A @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from the peer. + * + * @note The number of Handle Value Notifications that can be queued is configured by @ref ble_gatts_conn_cfg_t::hvn_tx_queue_size + * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES. + * A @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event will be issued as soon as the transmission of the notification is complete. + * + * @note The application can keep track of the available queue element count for notifications by following the procedure below: + * - Store initial queue element count in a variable. + * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS. + * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event. + * + * @events + * @event{@ref BLE_GATTS_EVT_HVN_TX_COMPLETE, Notification transmission complete.} + * @event{@ref BLE_GATTS_EVT_HVC, Confirmation received from the peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} + * @mmsc{@ref BLE_GATTS_HVN_MSC} + * @mmsc{@ref BLE_GATTS_HVI_MSC} + * @mmsc{@ref BLE_GATTS_HVX_DISABLED_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in,out] p_hvx_params Pointer to an HVx parameters structure. If @ref ble_gatts_hvx_params_t::p_data + * contains a non-NULL pointer the attribute value will be updated with the contents + * pointed by it before sending the notification or indication. If the attribute value + * is updated, @ref ble_gatts_hvx_params_t::p_len is updated by the SoftDevice to + * contain the number of actual bytes written, else it will be set to 0. + * + * @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true: + * - Invalid Connection State + * - Notifications and/or indications not enabled in the CCCD + * - An ATT_MTU exchange is ongoing + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate. + * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_FORBIDDEN The connection's current security level is lower than the one required by the write permissions of the CCCD associated with this characteristic. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + * @retval ::NRF_ERROR_BUSY For @ref BLE_GATT_HVX_INDICATION Procedure already in progress. Wait for a @ref BLE_GATTS_EVT_HVC event and retry. + * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. + * @retval ::NRF_ERROR_RESOURCES Too many notifications queued. + * Wait for a @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params)); + +/**@brief Indicate the Service Changed attribute value. + * + * @details This call will send a Handle Value Indication to one or more peers connected to inform them that the Attribute + * Table layout has changed. As soon as the peer has confirmed the indication, a @ref BLE_GATTS_EVT_SC_CONFIRM event will + * be issued. + * + * @note Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here. + * + * @events + * @event{@ref BLE_GATTS_EVT_SC_CONFIRM, Confirmation of attribute table change received from peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTS_SC_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] start_handle Start of affected attribute handle range. + * @param[in] end_handle End of affected attribute handle range. + * + * @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_NOT_SUPPORTED Service Changed not enabled at initialization. See @ref + * sd_ble_cfg_set and @ref ble_gatts_cfg_service_changed_t. + * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true: + * - Invalid Connection State + * - Notifications and/or indications not enabled in the CCCD + * - An ATT_MTU exchange is ongoing + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the application. + * @retval ::NRF_ERROR_BUSY Procedure already in progress. + * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, sd_ble_gatts_service_changed(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle)); + +/**@brief Respond to a Read/Write authorization request. + * + * @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_READ_REQ_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_WRITE_REQ_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application. + * + * @note @ref ble_gatts_authorize_params_t::p_data is ignored when this function is used to respond + * to a @ref BLE_GATTS_AUTHORIZE_TYPE_READ event if @ref ble_gatts_authorize_params_t::update + * is set to 0. + * + * @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending. + * @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid, + * handle supplied does not match requested handle, + * or invalid data to be written provided by the application. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params)); + + +/**@brief Update persistent system attribute information. + * + * @details Supply information about persistent system attributes to the stack, + * previously obtained using @ref sd_ble_gatts_sys_attr_get. + * This call is only allowed for active connections, and is usually + * made immediately after a connection is established with an known bonded device, + * often as a response to a @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. + * + * p_sysattrs may point directly to the application's stored copy of the system attributes + * obtained using @ref sd_ble_gatts_sys_attr_get. + * If the pointer is NULL, the system attribute info is initialized, assuming that + * the application does not have any previously saved system attribute data for this device. + * + * @note The state of persistent system attributes is reset upon connection establishment and then remembered for its duration. + * + * @note If this call returns with an error code different from @ref NRF_SUCCESS, the storage of persistent system attributes may have been completed only partially. + * This means that the state of the attribute table is undefined, and the application should either provide a new set of attributes using this same call or + * reset the SoftDevice to return to a known state. + * + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be modified. + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be modified. + * + * @mscs + * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_UNK_PEER_MSC} + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_sys_attr_data Pointer to a saved copy of system attributes supplied to the stack, or NULL. + * @param[in] len Size of data pointed by p_sys_attr_data, in octets. + * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS + * + * @retval ::NRF_SUCCESS Successfully set the system attribute information. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. + * @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref sd_ble_gatts_sys_attr_get. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + */ +SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags)); + + +/**@brief Retrieve persistent system attribute information from the stack. + * + * @details This call is used to retrieve information about values to be stored persistently by the application + * during the lifetime of a connection or after it has been terminated. When a new connection is established with the same bonded device, + * the system attribute information retrieved with this function should be restored using using @ref sd_ble_gatts_sys_attr_set. + * If retrieved after disconnection, the data should be read before a new connection established. The connection handle for + * the previous, now disconnected, connection will remain valid until a new one is created to allow this API call to refer to it. + * Connection handles belonging to active connections can be used as well, but care should be taken since the system attributes + * may be written to at any time by the peer during a connection's lifetime. + * + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be returned. + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be returned. + * + * @mscs + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle of the recently terminated connection. + * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. The format of the data is described + * in @ref BLE_GATTS_SYS_ATTRS_FORMAT. NULL can be provided to obtain the length of the data. + * @param[in,out] p_len Size of application buffer if p_sys_attr_data is not NULL. Unconditionally updated to actual length of system attribute data. + * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS + * + * @retval ::NRF_SUCCESS Successfully retrieved the system attribute information. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. + * @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer. + * @retval ::NRF_ERROR_NOT_FOUND No system attributes found. + */ +SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags)); + + +/**@brief Retrieve the first valid user attribute handle. + * + * @param[out] p_handle Pointer to an integer where the handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully retrieved the handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, uint32_t, sd_ble_gatts_initial_user_handle_get(uint16_t *p_handle)); + +/**@brief Retrieve the attribute UUID and/or metadata. + * + * @param[in] handle Attribute handle + * @param[out] p_uuid UUID of the attribute. Use NULL to omit this field. + * @param[out] p_md Metadata of the attribute. Use NULL to omit this field. + * + * @retval ::NRF_SUCCESS Successfully retrieved the attribute metadata, + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. Returned when both @c p_uuid and @c p_md are NULL. + * @retval ::NRF_ERROR_NOT_FOUND Attribute was not found. + */ +SVCALL(SD_BLE_GATTS_ATTR_GET, uint32_t, sd_ble_gatts_attr_get(uint16_t handle, ble_uuid_t * p_uuid, ble_gatts_attr_md_t * p_md)); + +/**@brief Reply to an ATT_MTU exchange request by sending an Exchange MTU Response to the client. + * + * @details This function is only used to reply to a @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event. + * + * @details The SoftDevice sets ATT_MTU to the minimum of: + * - The Client RX MTU value from @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, and + * - The Server RX MTU value. + * + * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT. + * + * @mscs + * @mmsc{@ref BLE_GATTS_MTU_EXCHANGE} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] server_rx_mtu Server RX MTU size. + * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. + * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration + * used for this connection. + * - The value must be equal to Client RX MTU size given in @ref sd_ble_gattc_exchange_mtu_request + * if an ATT_MTU exchange has already been performed in the other direction. + * + * @retval ::NRF_SUCCESS Successfully sent response to the client. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no ATT_MTU exchange request pending. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid Server RX MTU size supplied. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection. + */ +SVCALL(SD_BLE_GATTS_EXCHANGE_MTU_REPLY, uint32_t, sd_ble_gatts_exchange_mtu_reply(uint16_t conn_handle, uint16_t server_rx_mtu)); +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_GATTS_H__ + +/** + @} +*/ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_hci.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_hci.h new file mode 100644 index 00000000000..f0dde9a03ad --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_hci.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_COMMON + @{ +*/ + + +#ifndef BLE_HCI_H__ +#define BLE_HCI_H__ +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes + * @{ */ + +#define BLE_HCI_STATUS_CODE_SUCCESS 0x00 /**< Success. */ +#define BLE_HCI_STATUS_CODE_UNKNOWN_BTLE_COMMAND 0x01 /**< Unknown BLE Command. */ +#define BLE_HCI_STATUS_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02 /**< Unknown Connection Identifier. */ +/*0x03 Hardware Failure +0x04 Page Timeout +*/ +#define BLE_HCI_AUTHENTICATION_FAILURE 0x05 /**< Authentication Failure. */ +#define BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING 0x06 /**< Pin or Key missing. */ +#define BLE_HCI_MEMORY_CAPACITY_EXCEEDED 0x07 /**< Memory Capacity Exceeded. */ +#define BLE_HCI_CONNECTION_TIMEOUT 0x08 /**< Connection Timeout. */ +/*0x09 Connection Limit Exceeded +0x0A Synchronous Connection Limit To A Device Exceeded +0x0B ACL Connection Already Exists*/ +#define BLE_HCI_STATUS_CODE_COMMAND_DISALLOWED 0x0C /**< Command Disallowed. */ +/*0x0D Connection Rejected due to Limited Resources +0x0E Connection Rejected Due To Security Reasons +0x0F Connection Rejected due to Unacceptable BD_ADDR +0x10 Connection Accept Timeout Exceeded +0x11 Unsupported Feature or Parameter Value*/ +#define BLE_HCI_STATUS_CODE_INVALID_BTLE_COMMAND_PARAMETERS 0x12 /**< Invalid BLE Command Parameters. */ +#define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION 0x13 /**< Remote User Terminated Connection. */ +#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES 0x14 /**< Remote Device Terminated Connection due to low resources.*/ +#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF 0x15 /**< Remote Device Terminated Connection due to power off. */ +#define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION 0x16 /**< Local Host Terminated Connection. */ +/* +0x17 Repeated Attempts +0x18 Pairing Not Allowed +0x19 Unknown LMP PDU +*/ +#define BLE_HCI_UNSUPPORTED_REMOTE_FEATURE 0x1A /**< Unsupported Remote Feature. */ +/* +0x1B SCO Offset Rejected +0x1C SCO Interval Rejected +0x1D SCO Air Mode Rejected*/ +#define BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS 0x1E /**< Invalid LMP Parameters. */ +#define BLE_HCI_STATUS_CODE_UNSPECIFIED_ERROR 0x1F /**< Unspecified Error. */ +/*0x20 Unsupported LMP Parameter Value +0x21 Role Change Not Allowed +*/ +#define BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT 0x22 /**< LMP Response Timeout. */ +#define BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION 0x23 /**< LMP Error Transaction Collision/LL Procedure Collision. */ +#define BLE_HCI_STATUS_CODE_LMP_PDU_NOT_ALLOWED 0x24 /**< LMP PDU Not Allowed. */ +/*0x25 Encryption Mode Not Acceptable +0x26 Link Key Can Not be Changed +0x27 Requested QoS Not Supported +*/ +#define BLE_HCI_INSTANT_PASSED 0x28 /**< Instant Passed. */ +#define BLE_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED 0x29 /**< Pairing with Unit Key Unsupported. */ +#define BLE_HCI_DIFFERENT_TRANSACTION_COLLISION 0x2A /**< Different Transaction Collision. */ +/* +0x2B Reserved +0x2C QoS Unacceptable Parameter +0x2D QoS Rejected +0x2E Channel Classification Not Supported +0x2F Insufficient Security +*/ +#define BLE_HCI_PARAMETER_OUT_OF_MANDATORY_RANGE 0x30 /**< Parameter Out Of Mandatory Range. */ +/* +0x31 Reserved +0x32 Role Switch Pending +0x33 Reserved +0x34 Reserved Slot Violation +0x35 Role Switch Failed +0x36 Extended Inquiry Response Too Large +0x37 Secure Simple Pairing Not Supported By Host. +0x38 Host Busy - Pairing +0x39 Connection Rejected due to No Suitable Channel Found*/ +#define BLE_HCI_CONTROLLER_BUSY 0x3A /**< Controller Busy. */ +#define BLE_HCI_CONN_INTERVAL_UNACCEPTABLE 0x3B /**< Connection Interval Unacceptable. */ +#define BLE_HCI_DIRECTED_ADVERTISER_TIMEOUT 0x3C /**< Directed Advertisement Timeout. */ +#define BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE 0x3D /**< Connection Terminated due to MIC Failure. */ +#define BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED 0x3E /**< Connection Failed to be Established. */ + +/** @} */ + + +#ifdef __cplusplus +} +#endif +#endif // BLE_HCI_H__ + +/** @} */ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_l2cap.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_l2cap.h new file mode 100644 index 00000000000..edaf6641f80 --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_l2cap.h @@ -0,0 +1,506 @@ +/* + * Copyright (c) 2011 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP) + @{ + @brief Definitions and prototypes for the L2CAP interface. + */ + +#ifndef BLE_L2CAP_H__ +#define BLE_L2CAP_H__ + +#include +#include "nrf_svc.h" +#include "nrf_error.h" +#include "ble_ranges.h" +#include "ble_types.h" +#include "ble_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup BLE_L2CAP_TERMINOLOGY Terminology + * @{ + * @details + * + * L2CAP SDU + * - A data unit that the application can send/receive to/from a peer. + * + * L2CAP PDU + * - A data unit that is exchanged between local and remote L2CAP entities. + * It consists of L2CAP protocol control information and payload fields. + * The payload field can contain an L2CAP SDU or a part of an L2CAP SDU. + * + * L2CAP MTU + * - The maximum length of an L2CAP SDU. + * + * L2CAP MPS + * - The maximum length of an L2CAP PDU payload field. + * + * Credits + * - A value indicating the number of L2CAP PDUs that the receiver of the credit can send to the peer. + * @} */ + +/**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations + * @{ */ + +/**@brief L2CAP API SVC numbers. */ +enum BLE_L2CAP_SVCS +{ + SD_BLE_L2CAP_CH_SETUP = BLE_L2CAP_SVC_BASE + 0, /**< Set up an L2CAP channel. */ + SD_BLE_L2CAP_CH_RELEASE = BLE_L2CAP_SVC_BASE + 1, /**< Release an L2CAP channel. */ + SD_BLE_L2CAP_CH_RX = BLE_L2CAP_SVC_BASE + 2, /**< Receive an SDU on an L2CAP channel. */ + SD_BLE_L2CAP_CH_TX = BLE_L2CAP_SVC_BASE + 3, /**< Transmit an SDU on an L2CAP channel. */ + SD_BLE_L2CAP_CH_FLOW_CONTROL = BLE_L2CAP_SVC_BASE + 4, /**< Advanced SDU reception flow control. */ +}; + +/**@brief L2CAP Event IDs. */ +enum BLE_L2CAP_EVTS +{ + BLE_L2CAP_EVT_CH_SETUP_REQUEST = BLE_L2CAP_EVT_BASE + 0, /**< L2CAP Channel Setup Request event. + \n See @ref ble_l2cap_evt_ch_setup_request_t. */ + BLE_L2CAP_EVT_CH_SETUP_REFUSED = BLE_L2CAP_EVT_BASE + 1, /**< L2CAP Channel Setup Refused event. + \n See @ref ble_l2cap_evt_ch_setup_refused_t. */ + BLE_L2CAP_EVT_CH_SETUP = BLE_L2CAP_EVT_BASE + 2, /**< L2CAP Channel Setup Completed event. + \n See @ref ble_l2cap_evt_ch_setup_t. */ + BLE_L2CAP_EVT_CH_RELEASED = BLE_L2CAP_EVT_BASE + 3, /**< L2CAP Channel Released event. + \n No additional event structure applies. */ + BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED = BLE_L2CAP_EVT_BASE + 4, /**< L2CAP Channel SDU data buffer released event. + \n See @ref ble_l2cap_evt_ch_sdu_buf_released_t. */ + BLE_L2CAP_EVT_CH_CREDIT = BLE_L2CAP_EVT_BASE + 5, /**< L2CAP Channel Credit received. + \n See @ref ble_l2cap_evt_ch_credit_t. */ + BLE_L2CAP_EVT_CH_RX = BLE_L2CAP_EVT_BASE + 6, /**< L2CAP Channel SDU received. + \n See @ref ble_l2cap_evt_ch_rx_t. */ + BLE_L2CAP_EVT_CH_TX = BLE_L2CAP_EVT_BASE + 7, /**< L2CAP Channel SDU transmitted. + \n See @ref ble_l2cap_evt_ch_tx_t. */ +}; + +/** @} */ + +/**@addtogroup BLE_L2CAP_DEFINES Defines + * @{ */ + +/**@brief Maximum number of L2CAP channels per connection. */ +#define BLE_L2CAP_CH_COUNT_MAX (64) + +/**@brief Minimum L2CAP MTU, in bytes. */ +#define BLE_L2CAP_MTU_MIN (23) + +/**@brief Minimum L2CAP MPS, in bytes. */ +#define BLE_L2CAP_MPS_MIN (23) + +/**@brief Invalid CID. */ +#define BLE_L2CAP_CID_INVALID (0x0000) + +/**@brief Default number of credits for @ref sd_ble_l2cap_ch_flow_control. */ +#define BLE_L2CAP_CREDITS_DEFAULT (1) + +/**@defgroup BLE_L2CAP_CH_SETUP_REFUSED_SRCS L2CAP channel setup refused sources + * @{ */ +#define BLE_L2CAP_CH_SETUP_REFUSED_SRC_LOCAL (0x01) /**< Local. */ +#define BLE_L2CAP_CH_SETUP_REFUSED_SRC_REMOTE (0x02) /**< Remote. */ + /** @} */ + + /** @defgroup BLE_L2CAP_CH_STATUS_CODES L2CAP channel status codes + * @{ */ +#define BLE_L2CAP_CH_STATUS_CODE_SUCCESS (0x0000) /**< Success. */ +#define BLE_L2CAP_CH_STATUS_CODE_LE_PSM_NOT_SUPPORTED (0x0002) /**< LE_PSM not supported. */ +#define BLE_L2CAP_CH_STATUS_CODE_NO_RESOURCES (0x0004) /**< No resources available. */ +#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHENTICATION (0x0005) /**< Insufficient authentication. */ +#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHORIZATION (0x0006) /**< Insufficient authorization. */ +#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC_KEY_SIZE (0x0007) /**< Insufficient encryption key size. */ +#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC (0x0008) /**< Insufficient encryption. */ +#define BLE_L2CAP_CH_STATUS_CODE_INVALID_SCID (0x0009) /**< Invalid Source CID. */ +#define BLE_L2CAP_CH_STATUS_CODE_SCID_ALLOCATED (0x000A) /**< Source CID already allocated. */ +#define BLE_L2CAP_CH_STATUS_CODE_UNACCEPTABLE_PARAMS (0x000B) /**< Unacceptable parameters. */ +#define BLE_L2CAP_CH_STATUS_CODE_NOT_UNDERSTOOD (0x8000) /**< Command Reject received instead of LE Credit Based Connection Response. */ +#define BLE_L2CAP_CH_STATUS_CODE_TIMEOUT (0xC000) /**< Operation timed out. */ +/** @} */ + +/** @} */ + +/**@addtogroup BLE_L2CAP_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE L2CAP connection configuration parameters, set with @ref sd_ble_cfg_set. + * + * @note These parameters are set per connection, so all L2CAP channels created on this connection + * will have the same parameters. + * + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - rx_mps is smaller than @ref BLE_L2CAP_MPS_MIN. + * - tx_mps is smaller than @ref BLE_L2CAP_MPS_MIN. + * - ch_count is greater than @ref BLE_L2CAP_CH_COUNT_MAX. + * @retval ::NRF_ERROR_NO_MEM rx_mps or tx_mps is set too high. + */ +typedef struct +{ + uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall + be able to receive on L2CAP channels on connections with this + configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */ + uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall + be able to transmit on L2CAP channels on connections with this + configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */ + uint8_t rx_queue_size; /**< Number of SDU data buffers that can be queued for reception per + L2CAP channel. The minimum value is one. */ + uint8_t tx_queue_size; /**< Number of SDU data buffers that can be queued for transmission + per L2CAP channel. The minimum value is one. */ + uint8_t ch_count; /**< Number of L2CAP channels the application can create per connection + with this configuration. The default value is zero, the maximum + value is @ref BLE_L2CAP_CH_COUNT_MAX. + @note if this parameter is set to zero, all other parameters in + @ref ble_l2cap_conn_cfg_t are ignored. */ +} ble_l2cap_conn_cfg_t; + +/**@brief L2CAP channel RX parameters. */ +typedef struct +{ + uint16_t rx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP shall be able to + receive on this L2CAP channel. + - Must be equal to or greater than @ref BLE_L2CAP_MTU_MIN. */ + uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall be + able to receive on this L2CAP channel. + - Must be equal to or greater than @ref BLE_L2CAP_MPS_MIN. + - Must be equal to or less than @ref ble_l2cap_conn_cfg_t::rx_mps. */ + ble_data_t sdu_buf; /**< SDU data buffer for reception. + - If @ref ble_data_t::p_data is non-NULL, initial credits are + issued to the peer. + - If @ref ble_data_t::p_data is NULL, no initial credits are + issued to the peer. */ +} ble_l2cap_ch_rx_params_t; + +/**@brief L2CAP channel setup parameters. */ +typedef struct +{ + ble_l2cap_ch_rx_params_t rx_params; /**< L2CAP channel RX parameters. */ + uint16_t le_psm; /**< LE Protocol/Service Multiplexer. Used when requesting + setup of an L2CAP channel, ignored otherwise. */ + uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES. + Used when replying to a setup request of an L2CAP + channel, ignored otherwise. */ +} ble_l2cap_ch_setup_params_t; + +/**@brief L2CAP channel TX parameters. */ +typedef struct +{ + uint16_t tx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP is able to + transmit on this L2CAP channel. */ + uint16_t peer_mps; /**< The maximum L2CAP PDU payload size, in bytes, that the peer is + able to receive on this L2CAP channel. */ + uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP is able + to transmit on this L2CAP channel. This is effective tx_mps, + selected by the SoftDevice as + MIN( @ref ble_l2cap_ch_tx_params_t::peer_mps, @ref ble_l2cap_conn_cfg_t::tx_mps ) */ + uint16_t credits; /**< Initial credits given by the peer. */ +} ble_l2cap_ch_tx_params_t; + +/**@brief L2CAP Channel Setup Request event. */ +typedef struct +{ + ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */ + uint16_t le_psm; /**< LE Protocol/Service Multiplexer. */ +} ble_l2cap_evt_ch_setup_request_t; + +/**@brief L2CAP Channel Setup Refused event. */ +typedef struct +{ + uint8_t source; /**< Source, see @ref BLE_L2CAP_CH_SETUP_REFUSED_SRCS */ + uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES */ +} ble_l2cap_evt_ch_setup_refused_t; + +/**@brief L2CAP Channel Setup Completed event. */ +typedef struct +{ + ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */ +} ble_l2cap_evt_ch_setup_t; + +/**@brief L2CAP Channel SDU Data Buffer Released event. */ +typedef struct +{ + ble_data_t sdu_buf; /**< Returned reception or transmission SDU data buffer. The SoftDevice + returns SDU data buffers supplied by the application, which have + not yet been returned previously via a @ref BLE_L2CAP_EVT_CH_RX or + @ref BLE_L2CAP_EVT_CH_TX event. */ +} ble_l2cap_evt_ch_sdu_buf_released_t; + +/**@brief L2CAP Channel Credit received event. */ +typedef struct +{ + uint16_t credits; /**< Additional credits given by the peer. */ +} ble_l2cap_evt_ch_credit_t; + +/**@brief L2CAP Channel received SDU event. */ +typedef struct +{ + uint16_t sdu_len; /**< Total SDU length, in bytes. */ + ble_data_t sdu_buf; /**< SDU data buffer. + @note If there is not enough space in the buffer + (sdu_buf.len < sdu_len) then the rest of the SDU will be + silently discarded by the SoftDevice. */ +} ble_l2cap_evt_ch_rx_t; + +/**@brief L2CAP Channel transmitted SDU event. */ +typedef struct +{ + ble_data_t sdu_buf; /**< SDU data buffer. */ +} ble_l2cap_evt_ch_tx_t; + +/**@brief L2CAP event structure. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which the event occured. */ + uint16_t local_cid; /**< Local Channel ID of the L2CAP channel, or + @ref BLE_L2CAP_CID_INVALID if not present. */ + union + { + ble_l2cap_evt_ch_setup_request_t ch_setup_request; /**< L2CAP Channel Setup Request Event Parameters. */ + ble_l2cap_evt_ch_setup_refused_t ch_setup_refused; /**< L2CAP Channel Setup Refused Event Parameters. */ + ble_l2cap_evt_ch_setup_t ch_setup; /**< L2CAP Channel Setup Completed Event Parameters. */ + ble_l2cap_evt_ch_sdu_buf_released_t ch_sdu_buf_released;/**< L2CAP Channel SDU Data Buffer Released Event Parameters. */ + ble_l2cap_evt_ch_credit_t credit; /**< L2CAP Channel Credit Received Event Parameters. */ + ble_l2cap_evt_ch_rx_t rx; /**< L2CAP Channel SDU Received Event Parameters. */ + ble_l2cap_evt_ch_tx_t tx; /**< L2CAP Channel SDU Transmitted Event Parameters. */ + } params; /**< Event Parameters. */ +} ble_l2cap_evt_t; + +/** @} */ + +/**@addtogroup BLE_L2CAP_FUNCTIONS Functions + * @{ */ + +/**@brief Set up an L2CAP channel. + * + * @details This function is used to: + * - Request setup of an L2CAP channel: sends an LE Credit Based Connection Request packet to a peer. + * - Reply to a setup request of an L2CAP channel (if called in response to a + * @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST event): sends an LE Credit Based Connection + * Response packet to a peer. + * + * @note A call to this function will require the application to keep the SDU data buffer alive + * until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX or + * @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. + * + * @events + * @event{@ref BLE_L2CAP_EVT_CH_SETUP, Setup successful.} + * @event{@ref BLE_L2CAP_EVT_CH_SETUP_REFUSED, Setup failed.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_L2CAP_CH_SETUP_MSC} + * @endmscs + * + * @param[in] conn_handle Connection Handle. + * @param[in,out] p_local_cid Pointer to a uint16_t containing Local Channel ID of the L2CAP channel: + * - As input: @ref BLE_L2CAP_CID_INVALID when requesting setup of an L2CAP + * channel or local_cid provided in the @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST + * event when replying to a setup request of an L2CAP channel. + * - As output: local_cid for this channel. + * @param[in] p_params L2CAP channel parameters. + * + * @retval ::NRF_SUCCESS Successfully queued request or response for transmission. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_LENGTH Supplied higher rx_mps than has been configured on this link. + * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (L2CAP channel already set up). + * @retval ::NRF_ERROR_NOT_FOUND CID not found. + * @retval ::NRF_ERROR_RESOURCES The limit has been reached for available L2CAP channels, + * see @ref ble_l2cap_conn_cfg_t::ch_count. + */ +SVCALL(SD_BLE_L2CAP_CH_SETUP, uint32_t, sd_ble_l2cap_ch_setup(uint16_t conn_handle, uint16_t *p_local_cid, ble_l2cap_ch_setup_params_t const *p_params)); + +/**@brief Release an L2CAP channel. + * + * @details This sends a Disconnection Request packet to a peer. + * + * @events + * @event{@ref BLE_L2CAP_EVT_CH_RELEASED, Release complete.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_L2CAP_CH_RELEASE_MSC} + * @endmscs + * + * @param[in] conn_handle Connection Handle. + * @param[in] local_cid Local Channel ID of the L2CAP channel. + * + * @retval ::NRF_SUCCESS Successfully queued request for transmission. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is + * in progress for the L2CAP channel). + * @retval ::NRF_ERROR_NOT_FOUND CID not found. + */ +SVCALL(SD_BLE_L2CAP_CH_RELEASE, uint32_t, sd_ble_l2cap_ch_release(uint16_t conn_handle, uint16_t local_cid)); + +/**@brief Receive an SDU on an L2CAP channel. + * + * @details This may issue additional credits to the peer using an LE Flow Control Credit packet. + * + * @note A call to this function will require the application to keep the memory pointed by + * @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX + * or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. + * + * @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::rx_queue_size SDU data buffers + * for reception per L2CAP channel. + * + * @events + * @event{@ref BLE_L2CAP_EVT_CH_RX, The SDU is received.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_L2CAP_CH_RX_MSC} + * @endmscs + * + * @param[in] conn_handle Connection Handle. + * @param[in] local_cid Local Channel ID of the L2CAP channel. + * @param[in] p_sdu_buf Pointer to the SDU data buffer. + * + * @retval ::NRF_SUCCESS Buffer accepted. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is + * in progress for an L2CAP channel). + * @retval ::NRF_ERROR_NOT_FOUND CID not found. + * @retval ::NRF_ERROR_RESOURCES Too many SDU data buffers supplied. Wait for a + * @ref BLE_L2CAP_EVT_CH_RX event and retry. + */ +SVCALL(SD_BLE_L2CAP_CH_RX, uint32_t, sd_ble_l2cap_ch_rx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf)); + +/**@brief Transmit an SDU on an L2CAP channel. + * + * @note A call to this function will require the application to keep the memory pointed by + * @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_TX + * or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. + * + * @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::tx_queue_size SDUs for + * transmission per L2CAP channel. + * + * @note The application can keep track of the available credits for transmission by following + * the procedure below: + * - Store initial credits given by the peer in a variable. + * (Initial credits are provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.) + * - Decrement the variable, which stores the currently available credits, by + * ceiling((@ref ble_data_t::len + 2) / tx_mps) when a call to this function returns + * @ref NRF_SUCCESS. (tx_mps is provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.) + * - Increment the variable, which stores the currently available credits, by additional + * credits given by the peer in a @ref BLE_L2CAP_EVT_CH_CREDIT event. + * + * @events + * @event{@ref BLE_L2CAP_EVT_CH_TX, The SDU is transmitted.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_L2CAP_CH_TX_MSC} + * @endmscs + * + * @param[in] conn_handle Connection Handle. + * @param[in] local_cid Local Channel ID of the L2CAP channel. + * @param[in] p_sdu_buf Pointer to the SDU data buffer. + * + * @retval ::NRF_SUCCESS Successfully queued L2CAP SDU for transmission. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is + * in progress for the L2CAP channel). + * @retval ::NRF_ERROR_NOT_FOUND CID not found. + * @retval ::NRF_ERROR_DATA_SIZE Invalid SDU length supplied, must not be more than + * @ref ble_l2cap_ch_tx_params_t::tx_mtu provided in + * @ref BLE_L2CAP_EVT_CH_SETUP event. + * @retval ::NRF_ERROR_RESOURCES Too many SDUs queued for transmission. Wait for a + * @ref BLE_L2CAP_EVT_CH_TX event and retry. + */ +SVCALL(SD_BLE_L2CAP_CH_TX, uint32_t, sd_ble_l2cap_ch_tx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf)); + +/**@brief Advanced SDU reception flow control. + * + * @details Adjust the way the SoftDevice issues credits to the peer. + * This may issue additional credits to the peer using an LE Flow Control Credit packet. + * + * @mscs + * @mmsc{@ref BLE_L2CAP_CH_FLOW_CONTROL_MSC} + * @endmscs + * + * @param[in] conn_handle Connection Handle. + * @param[in] local_cid Local Channel ID of the L2CAP channel or @ref BLE_L2CAP_CID_INVALID to set + * the value that will be used for newly created channels. + * @param[in] credits Number of credits that the SoftDevice will make sure the peer has every + * time it starts using a new reception buffer. + * - @ref BLE_L2CAP_CREDITS_DEFAULT is the default value the SoftDevice will + * use if this function is not called. + * - If set to zero, the SoftDevice will stop issuing credits for new reception + * buffers the application provides or has provided. SDU reception that is + * currently ongoing will be allowed to complete. + * @param[out] p_credits NULL or pointer to a uint16_t. If a valid pointer is provided, it will be + * written by the SoftDevice with the number of credits that is or will be + * available to the peer. If the value written by the SoftDevice is 0 when + * credits parameter was set to 0, the peer will not be able to send more + * data until more credits are provided by calling this function again with + * credits > 0. This parameter is ignored when local_cid is set to + * @ref BLE_L2CAP_CID_INVALID. + * + * @note Application should take care when setting number of credits higher than default value. In + * this case the application must make sure that the SoftDevice always has reception buffers + * available (see @ref sd_ble_l2cap_ch_rx) for that channel. If the SoftDevice does not have + * such buffers available, packets may be NACKed on the Link Layer and all Bluetooth traffic + * on the connection handle may be stalled until the SoftDevice again has an available + * reception buffer. This applies even if the application has used this call to set the + * credits back to default, or zero. + * + * @retval ::NRF_SUCCESS Flow control parameters accepted. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is + * in progress for an L2CAP channel). + * @retval ::NRF_ERROR_NOT_FOUND CID not found. + */ +SVCALL(SD_BLE_L2CAP_CH_FLOW_CONTROL, uint32_t, sd_ble_l2cap_ch_flow_control(uint16_t conn_handle, uint16_t local_cid, uint16_t credits, uint16_t *p_credits)); + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_L2CAP_H__ + +/** + @} +*/ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_ranges.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_ranges.h new file mode 100644 index 00000000000..0935bca0710 --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_ranges.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_COMMON + @{ + @defgroup ble_ranges Module specific SVC, event and option number subranges + @{ + + @brief Definition of SVC, event and option number subranges for each API module. + + @note + SVCs, event and option numbers are split into subranges for each API module. + Each module receives its entire allocated range of SVC calls, whether implemented or not, + but return BLE_ERROR_NOT_SUPPORTED for unimplemented or undefined calls in its range. + + Note that the symbols BLE__SVC_LAST is the end of the allocated SVC range, + rather than the last SVC function call actually defined and implemented. + + Specific SVC, event and option values are defined in each module's ble_.h file, + which defines names of each individual SVC code based on the range start value. +*/ + +#ifndef BLE_RANGES_H__ +#define BLE_RANGES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_SVC_BASE 0x60 /**< Common BLE SVC base. */ +#define BLE_SVC_LAST 0x6B /**< Common BLE SVC last. */ + +#define BLE_GAP_SVC_BASE 0x6C /**< GAP BLE SVC base. */ +#define BLE_GAP_SVC_LAST 0x9A /**< GAP BLE SVC last. */ + +#define BLE_GATTC_SVC_BASE 0x9B /**< GATTC BLE SVC base. */ +#define BLE_GATTC_SVC_LAST 0xA7 /**< GATTC BLE SVC last. */ + +#define BLE_GATTS_SVC_BASE 0xA8 /**< GATTS BLE SVC base. */ +#define BLE_GATTS_SVC_LAST 0xB7 /**< GATTS BLE SVC last. */ + +#define BLE_L2CAP_SVC_BASE 0xB8 /**< L2CAP BLE SVC base. */ +#define BLE_L2CAP_SVC_LAST 0xBF /**< L2CAP BLE SVC last. */ + + +#define BLE_EVT_INVALID 0x00 /**< Invalid BLE Event. */ + +#define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */ +#define BLE_EVT_LAST 0x0F /**< Common BLE Event last. */ + +#define BLE_GAP_EVT_BASE 0x10 /**< GAP BLE Event base. */ +#define BLE_GAP_EVT_LAST 0x2F /**< GAP BLE Event last. */ + +#define BLE_GATTC_EVT_BASE 0x30 /**< GATTC BLE Event base. */ +#define BLE_GATTC_EVT_LAST 0x4F /**< GATTC BLE Event last. */ + +#define BLE_GATTS_EVT_BASE 0x50 /**< GATTS BLE Event base. */ +#define BLE_GATTS_EVT_LAST 0x6F /**< GATTS BLE Event last. */ + +#define BLE_L2CAP_EVT_BASE 0x70 /**< L2CAP BLE Event base. */ +#define BLE_L2CAP_EVT_LAST 0x8F /**< L2CAP BLE Event last. */ + + +#define BLE_OPT_INVALID 0x00 /**< Invalid BLE Option. */ + +#define BLE_OPT_BASE 0x01 /**< Common BLE Option base. */ +#define BLE_OPT_LAST 0x1F /**< Common BLE Option last. */ + +#define BLE_GAP_OPT_BASE 0x20 /**< GAP BLE Option base. */ +#define BLE_GAP_OPT_LAST 0x3F /**< GAP BLE Option last. */ + +#define BLE_GATT_OPT_BASE 0x40 /**< GATT BLE Option base. */ +#define BLE_GATT_OPT_LAST 0x5F /**< GATT BLE Option last. */ + +#define BLE_GATTC_OPT_BASE 0x60 /**< GATTC BLE Option base. */ +#define BLE_GATTC_OPT_LAST 0x7F /**< GATTC BLE Option last. */ + +#define BLE_GATTS_OPT_BASE 0x80 /**< GATTS BLE Option base. */ +#define BLE_GATTS_OPT_LAST 0x9F /**< GATTS BLE Option last. */ + +#define BLE_L2CAP_OPT_BASE 0xA0 /**< L2CAP BLE Option base. */ +#define BLE_L2CAP_OPT_LAST 0xBF /**< L2CAP BLE Option last. */ + + +#define BLE_CFG_INVALID 0x00 /**< Invalid BLE configuration. */ + +#define BLE_CFG_BASE 0x01 /**< Common BLE configuration base. */ +#define BLE_CFG_LAST 0x1F /**< Common BLE configuration last. */ + +#define BLE_CONN_CFG_BASE 0x20 /**< BLE connection configuration base. */ +#define BLE_CONN_CFG_LAST 0x3F /**< BLE connection configuration last. */ + +#define BLE_GAP_CFG_BASE 0x40 /**< GAP BLE configuration base. */ +#define BLE_GAP_CFG_LAST 0x5F /**< GAP BLE configuration last. */ + +#define BLE_GATT_CFG_BASE 0x60 /**< GATT BLE configuration base. */ +#define BLE_GATT_CFG_LAST 0x7F /**< GATT BLE configuration last. */ + +#define BLE_GATTC_CFG_BASE 0x80 /**< GATTC BLE configuration base. */ +#define BLE_GATTC_CFG_LAST 0x9F /**< GATTC BLE configuration last. */ + +#define BLE_GATTS_CFG_BASE 0xA0 /**< GATTS BLE configuration base. */ +#define BLE_GATTS_CFG_LAST 0xBF /**< GATTS BLE configuration last. */ + +#define BLE_L2CAP_CFG_BASE 0xC0 /**< L2CAP BLE configuration base. */ +#define BLE_L2CAP_CFG_LAST 0xDF /**< L2CAP BLE configuration last. */ + + + + + +#ifdef __cplusplus +} +#endif +#endif /* BLE_RANGES_H__ */ + +/** + @} + @} +*/ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_types.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_types.h new file mode 100644 index 00000000000..88c93180c83 --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_types.h @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_COMMON + @{ + @defgroup ble_types Common types and macro definitions + @{ + + @brief Common types and macro definitions for the BLE SoftDevice. + */ + +#ifndef BLE_TYPES_H__ +#define BLE_TYPES_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_TYPES_DEFINES Defines + * @{ */ + +/** @defgroup BLE_CONN_HANDLES BLE Connection Handles + * @{ */ +#define BLE_CONN_HANDLE_INVALID 0xFFFF /**< Invalid Connection Handle. */ +#define BLE_CONN_HANDLE_ALL 0xFFFE /**< Applies to all Connection Handles. */ +/** @} */ + + +/** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs + * @{ */ +/* Generic UUIDs, applicable to all services */ +#define BLE_UUID_UNKNOWN 0x0000 /**< Reserved UUID. */ +#define BLE_UUID_SERVICE_PRIMARY 0x2800 /**< Primary Service. */ +#define BLE_UUID_SERVICE_SECONDARY 0x2801 /**< Secondary Service. */ +#define BLE_UUID_SERVICE_INCLUDE 0x2802 /**< Include. */ +#define BLE_UUID_CHARACTERISTIC 0x2803 /**< Characteristic. */ +#define BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP 0x2900 /**< Characteristic Extended Properties Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CHAR_USER_DESC 0x2901 /**< Characteristic User Description Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG 0x2902 /**< Client Characteristic Configuration Descriptor. */ +#define BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG 0x2903 /**< Server Characteristic Configuration Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT 0x2904 /**< Characteristic Presentation Format Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT 0x2905 /**< Characteristic Aggregate Format Descriptor. */ +/* GATT specific UUIDs */ +#define BLE_UUID_GATT 0x1801 /**< Generic Attribute Profile. */ +#define BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED 0x2A05 /**< Service Changed Characteristic. */ +/* GAP specific UUIDs */ +#define BLE_UUID_GAP 0x1800 /**< Generic Access Profile. */ +#define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME 0x2A00 /**< Device Name Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE 0x2A01 /**< Appearance Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR 0x2A03 /**< Reconnection Address Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_PPCP 0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_CAR 0x2AA6 /**< Central Address Resolution Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_RPA_ONLY 0x2AC9 /**< Resolvable Private Address Only Characteristic. */ +/** @} */ + + +/** @defgroup BLE_UUID_TYPES Types of UUID + * @{ */ +#define BLE_UUID_TYPE_UNKNOWN 0x00 /**< Invalid UUID type. */ +#define BLE_UUID_TYPE_BLE 0x01 /**< Bluetooth SIG UUID (16-bit). */ +#define BLE_UUID_TYPE_VENDOR_BEGIN 0x02 /**< Vendor UUID types start at this index (128-bit). */ +/** @} */ + + +/** @defgroup BLE_APPEARANCES Bluetooth Appearance values + * @note Retrieved from http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml + * @{ */ +#define BLE_APPEARANCE_UNKNOWN 0 /**< Unknown. */ +#define BLE_APPEARANCE_GENERIC_PHONE 64 /**< Generic Phone. */ +#define BLE_APPEARANCE_GENERIC_COMPUTER 128 /**< Generic Computer. */ +#define BLE_APPEARANCE_GENERIC_WATCH 192 /**< Generic Watch. */ +#define BLE_APPEARANCE_WATCH_SPORTS_WATCH 193 /**< Watch: Sports Watch. */ +#define BLE_APPEARANCE_GENERIC_CLOCK 256 /**< Generic Clock. */ +#define BLE_APPEARANCE_GENERIC_DISPLAY 320 /**< Generic Display. */ +#define BLE_APPEARANCE_GENERIC_REMOTE_CONTROL 384 /**< Generic Remote Control. */ +#define BLE_APPEARANCE_GENERIC_EYE_GLASSES 448 /**< Generic Eye-glasses. */ +#define BLE_APPEARANCE_GENERIC_TAG 512 /**< Generic Tag. */ +#define BLE_APPEARANCE_GENERIC_KEYRING 576 /**< Generic Keyring. */ +#define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 640 /**< Generic Media Player. */ +#define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 704 /**< Generic Barcode Scanner. */ +#define BLE_APPEARANCE_GENERIC_THERMOMETER 768 /**< Generic Thermometer. */ +#define BLE_APPEARANCE_THERMOMETER_EAR 769 /**< Thermometer: Ear. */ +#define BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832 /**< Generic Heart rate Sensor. */ +#define BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833 /**< Heart Rate Sensor: Heart Rate Belt. */ +#define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 896 /**< Generic Blood Pressure. */ +#define BLE_APPEARANCE_BLOOD_PRESSURE_ARM 897 /**< Blood Pressure: Arm. */ +#define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 898 /**< Blood Pressure: Wrist. */ +#define BLE_APPEARANCE_GENERIC_HID 960 /**< Human Interface Device (HID). */ +#define BLE_APPEARANCE_HID_KEYBOARD 961 /**< Keyboard (HID Subtype). */ +#define BLE_APPEARANCE_HID_MOUSE 962 /**< Mouse (HID Subtype). */ +#define BLE_APPEARANCE_HID_JOYSTICK 963 /**< Joystick (HID Subtype). */ +#define BLE_APPEARANCE_HID_GAMEPAD 964 /**< Gamepad (HID Subtype). */ +#define BLE_APPEARANCE_HID_DIGITIZERSUBTYPE 965 /**< Digitizer Tablet (HID Subtype). */ +#define BLE_APPEARANCE_HID_CARD_READER 966 /**< Card Reader (HID Subtype). */ +#define BLE_APPEARANCE_HID_DIGITAL_PEN 967 /**< Digital Pen (HID Subtype). */ +#define BLE_APPEARANCE_HID_BARCODE 968 /**< Barcode Scanner (HID Subtype). */ +#define BLE_APPEARANCE_GENERIC_GLUCOSE_METER 1024 /**< Generic Glucose Meter. */ +#define BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088 /**< Generic Running Walking Sensor. */ +#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089 /**< Running Walking Sensor: In-Shoe. */ +#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090 /**< Running Walking Sensor: On-Shoe. */ +#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091 /**< Running Walking Sensor: On-Hip. */ +#define BLE_APPEARANCE_GENERIC_CYCLING 1152 /**< Generic Cycling. */ +#define BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153 /**< Cycling: Cycling Computer. */ +#define BLE_APPEARANCE_CYCLING_SPEED_SENSOR 1154 /**< Cycling: Speed Sensor. */ +#define BLE_APPEARANCE_CYCLING_CADENCE_SENSOR 1155 /**< Cycling: Cadence Sensor. */ +#define BLE_APPEARANCE_CYCLING_POWER_SENSOR 1156 /**< Cycling: Power Sensor. */ +#define BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR 1157 /**< Cycling: Speed and Cadence Sensor. */ +#define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 3136 /**< Generic Pulse Oximeter. */ +#define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 3137 /**< Fingertip (Pulse Oximeter subtype). */ +#define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN 3138 /**< Wrist Worn(Pulse Oximeter subtype). */ +#define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 /**< Generic Weight Scale. */ +#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Activity. */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD 5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */ +/** @} */ + +/** @brief Set .type and .uuid fields of ble_uuid_struct to specified UUID value. */ +#define BLE_UUID_BLE_ASSIGN(instance, value) do {\ + instance.type = BLE_UUID_TYPE_BLE; \ + instance.uuid = value;} while(0) + +/** @brief Copy type and uuid members from src to dst ble_uuid_t pointer. Both pointers must be valid/non-null. */ +#define BLE_UUID_COPY_PTR(dst, src) do {\ + (dst)->type = (src)->type; \ + (dst)->uuid = (src)->uuid;} while(0) + +/** @brief Copy type and uuid members from src to dst ble_uuid_t struct. */ +#define BLE_UUID_COPY_INST(dst, src) do {\ + (dst).type = (src).type; \ + (dst).uuid = (src).uuid;} while(0) + +/** @brief Compare for equality both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ +#define BLE_UUID_EQ(p_uuid1, p_uuid2) \ + (((p_uuid1)->type == (p_uuid2)->type) && ((p_uuid1)->uuid == (p_uuid2)->uuid)) + +/** @brief Compare for difference both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ +#define BLE_UUID_NEQ(p_uuid1, p_uuid2) \ + (((p_uuid1)->type != (p_uuid2)->type) || ((p_uuid1)->uuid != (p_uuid2)->uuid)) + +/** @} */ + +/** @addtogroup BLE_TYPES_STRUCTURES Structures + * @{ */ + +/** @brief 128 bit UUID values. */ +typedef struct +{ + uint8_t uuid128[16]; /**< Little-Endian UUID bytes. */ +} ble_uuid128_t; + +/** @brief Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */ +typedef struct +{ + uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */ + uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */ +} ble_uuid_t; + +/**@brief Data structure. */ +typedef struct +{ + uint8_t *p_data; /**< Pointer to the data buffer provided to/from the application. */ + uint16_t len; /**< Length of the data buffer, in bytes. */ +} ble_data_t; + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* BLE_TYPES_H__ */ + +/** + @} + @} +*/ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf52/nrf_mbr.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf52/nrf_mbr.h new file mode 100644 index 00000000000..e0c80e278c3 --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf52/nrf_mbr.h @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @defgroup nrf_mbr_api Master Boot Record API + @{ + + @brief APIs for updating SoftDevice and BootLoader + +*/ + +#ifndef NRF_MBR_H__ +#define NRF_MBR_H__ + +#include "nrf_svc.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup NRF_MBR_DEFINES Defines + * @{ */ + +/**@brief MBR SVC Base number. */ +#define MBR_SVC_BASE (0x18) + +/**@brief Page size in words. */ +#define MBR_PAGE_SIZE_IN_WORDS (1024) + +/** @brief The size that must be reserved for the MBR when a SoftDevice is written to flash. +This is the offset where the first byte of the SoftDevice hex file is written.*/ +#define MBR_SIZE (0x1000) + +/** @} */ + +/** @addtogroup NRF_MBR_ENUMS Enumerations + * @{ */ + +/**@brief nRF Master Boot Record API SVC numbers. */ +enum NRF_MBR_SVCS +{ + SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */ +}; + +/**@brief Possible values for ::sd_mbr_command_t.command */ +enum NRF_MBR_COMMANDS +{ + SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see ::sd_mbr_command_copy_bl_t*/ + SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/ + SD_MBR_COMMAND_INIT_SD, /**< Initialize forwarding interrupts to SD, and run reset function in SD. Does not require any parameters in ::sd_mbr_command_t params.*/ + SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/ + SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Change the address the MBR starts after a reset. @see ::sd_mbr_command_vector_table_base_set_t*/ + SD_MBR_COMMAND_RESERVED, + SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET, /**< Start forwarding all interrupts to this address. @see ::sd_mbr_command_irq_forward_address_set_t*/ +}; + +/** @} */ + +/** @addtogroup NRF_MBR_TYPES Types + * @{ */ + +/**@brief This command copies part of a new SoftDevice + * + * The destination area is erased before copying. + * If dst is in the middle of a flash page, that whole flash page will be erased. + * If (dst+len) is in the middle of a flash page, that whole flash page will be erased. + * + * The user of this function is responsible for setting the BPROT registers. + * + * @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly. + * @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. + */ +typedef struct +{ + uint32_t *src; /**< Pointer to the source of data to be copied.*/ + uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/ + uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of @ref MBR_PAGE_SIZE_IN_WORDS words.*/ +} sd_mbr_command_copy_sd_t; + + +/**@brief This command works like memcmp, but takes the length in words. + * + * @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal. + * @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal. + */ +typedef struct +{ + uint32_t *ptr1; /**< Pointer to block of memory. */ + uint32_t *ptr2; /**< Pointer to block of memory. */ + uint32_t len; /**< Number of 32 bit words to compare.*/ +} sd_mbr_command_compare_t; + + +/**@brief This command copies a new BootLoader. + * + * With this command, destination of BootLoader is always the address written in + * NRF_UICR->BOOTADDR. + * + * Destination is erased by this function. + * If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased. + * + * This function will use the flash protect peripheral (BPROT or ACL) to protect the flash that is + * not intended to be written. + * + * On success, this function will not return. It will start the new BootLoader from reset-vector as normal. + * + * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. + * @retval ::NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set. + * @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area. + * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info) + */ +typedef struct +{ + uint32_t *bl_src; /**< Pointer to the source of the Bootloader to be be copied.*/ + uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */ +} sd_mbr_command_copy_bl_t; + +/**@brief Change the address the MBR starts after a reset + * + * Once this function has been called, this address is where the MBR will start to forward + * interrupts to after a reset. + * + * To restore default forwarding this function should be called with @ref address set to 0. The + * MBR will then start forwarding interrupts to the address in NFR_UICR->BOOTADDR or to the + * SoftDevice if the BOOTADDR is not set. + * + * On success, this function will not return. It will reset the device. + * + * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. + * @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size. + * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info) + */ +typedef struct +{ + uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/ +} sd_mbr_command_vector_table_base_set_t; + +/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR + * + * Unlike sd_mbr_command_vector_table_base_set_t, this function does not reset, and it does not + * change where the MBR starts after reset. + * + * @retval ::NRF_SUCCESS + */ +typedef struct +{ + uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/ +} sd_mbr_command_irq_forward_address_set_t; + +/**@brief Input structure containing data used when calling ::sd_mbr_command + * + * Depending on what command value that is set, the corresponding params value type must also be + * set. See @ref NRF_MBR_COMMANDS for command types and corresponding params value type. If command + * @ref SD_MBR_COMMAND_INIT_SD is set, it is not necessary to set any values under params. + */ +typedef struct +{ + uint32_t command; /**< Type of command to be issued. See @ref NRF_MBR_COMMANDS. */ + union + { + sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/ + sd_mbr_command_compare_t compare; /**< Parameters for verify.*/ + sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader. Requires parameter page. */ + sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set. Requires parameter page.*/ + sd_mbr_command_irq_forward_address_set_t irq_forward_address_set; /**< Parameters for irq forward address set*/ + } params; /**< Command parameters. */ +} sd_mbr_command_t; + +/** @} */ + +/** @addtogroup NRF_MBR_FUNCTIONS Functions + * @{ */ + +/**@brief Issue Master Boot Record commands + * + * Commands used when updating a SoftDevice and bootloader. + * + * The @ref SD_MBR_COMMAND_COPY_BL and @ref SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET requires + * parameters to be retained by the MBR when resetting the IC. This is done in a separate flash + * page provided by the application. The UICR register UICR.NRFFW[1] must be set to an address + * corresponding to a page in the application flash space. This page will be cleared by the MBR and + * used to store the command before reset. When the UICR.NRFFW[1] field is set the page it refers + * to must not be used by the application. If the UICR.NRFFW[1] is set to 0xFFFFFFFF (the default) + * MBR commands which use flash will be unavailable and return @ref NRF_ERROR_NO_MEM. + * + * @param[in] param Pointer to a struct describing the command. + * + * @note For return values, see ::sd_mbr_command_copy_sd_t, ::sd_mbr_command_copy_bl_t, + * ::sd_mbr_command_compare_t, ::sd_mbr_command_vector_table_base_set_t, + * ::sd_mbr_command_irq_forward_address_set_t + * + * @retval ::NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF). + * @retval ::NRF_ERROR_INVALID_PARAM if an invalid command is given. +*/ +SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param)); + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // NRF_MBR_H__ + +/** + @} +*/ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_error.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_error.h new file mode 100644 index 00000000000..6badee98e56 --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_error.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + /** + @defgroup nrf_error SoftDevice Global Error Codes + @{ + + @brief Global Error definitions +*/ + +/* Header guard */ +#ifndef NRF_ERROR_H__ +#define NRF_ERROR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions + * @{ */ +#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base +#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base +#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base +#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base +/** @} */ + +#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command +#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing +#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled +#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error +#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation +#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found +#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported +#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter +#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state +#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length +#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags +#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data +#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Invalid Data size +#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out +#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer +#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation +#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address +#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy +#define NRF_ERROR_CONN_COUNT (NRF_ERROR_BASE_NUM + 18) ///< Maximum connection count exceeded. +#define NRF_ERROR_RESOURCES (NRF_ERROR_BASE_NUM + 19) ///< Not enough resources for operation + +#ifdef __cplusplus +} +#endif +#endif // NRF_ERROR_H__ + +/** + @} +*/ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_error_sdm.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_error_sdm.h new file mode 100644 index 00000000000..530959b9d67 --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_error_sdm.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + /** + @addtogroup nrf_sdm_api + @{ + @defgroup nrf_sdm_error SoftDevice Manager Error Codes + @{ + + @brief Error definitions for the SDM API +*/ + +/* Header guard */ +#ifndef NRF_ERROR_SDM_H__ +#define NRF_ERROR_SDM_H__ + +#include "nrf_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown LFCLK source. +#define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts). +#define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erroneous SoftDevice flashing). + +#ifdef __cplusplus +} +#endif +#endif // NRF_ERROR_SDM_H__ + +/** + @} + @} +*/ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_error_soc.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_error_soc.h new file mode 100644 index 00000000000..1e784b8db38 --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_error_soc.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup nrf_soc_api + @{ + @defgroup nrf_soc_error SoC Library Error Codes + @{ + + @brief Error definitions for the SoC library + +*/ + +/* Header guard */ +#ifndef NRF_ERROR_SOC_H__ +#define NRF_ERROR_SOC_H__ + +#include "nrf_error.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* Mutex Errors */ +#define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken + +/* NVIC errors */ +#define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available +#define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed +#define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return + +/* Power errors */ +#define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown +#define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown +#define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return + +/* Rand errors */ +#define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values + +/* PPI errors */ +#define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel +#define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group + +#ifdef __cplusplus +} +#endif +#endif // NRF_ERROR_SOC_H__ +/** + @} + @} +*/ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_nvic.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_nvic.h new file mode 100644 index 00000000000..1f79cc3c8c2 --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_nvic.h @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup nrf_nvic_api SoftDevice NVIC API + * @{ + * + * @note In order to use this module, the following code has to be added to a .c file: + * \code + * nrf_nvic_state_t nrf_nvic_state = {0}; + * \endcode + * + * @note Definitions and declarations starting with __ (double underscore) in this header file are + * not intended for direct use by the application. + * + * @brief APIs for the accessing NVIC when using a SoftDevice. + * + */ + +#ifndef NRF_NVIC_H__ +#define NRF_NVIC_H__ + +#include +#include "nrf.h" +#include "nrf_svc.h" +#include "nrf_error.h" +#include "nrf_error_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup NRF_NVIC_DEFINES Defines + * @{ */ + +/**@defgroup NRF_NVIC_ISER_DEFINES SoftDevice NVIC internal definitions + * @{ */ + +#define __NRF_NVIC_NVMC_IRQn (30) /**< The peripheral ID of the NVMC. IRQ numbers are used to identify peripherals, but the NVMC doesn't have an IRQ number in the MDK. */ + +#define __NRF_NVIC_ISER_COUNT (2) /**< The number of ISER/ICER registers in the NVIC that are used. */ + +/**@brief Interrupt priority levels used by the SoftDevice. */ +#define __NRF_NVIC_SD_IRQ_PRIOS ((uint8_t)( \ + (1U << 0) /**< Priority level high .*/ \ + | (1U << 1) /**< Priority level medium. */ \ + | (1U << 4) /**< Priority level low. */ \ + )) + +/**@brief Interrupt priority levels available to the application. */ +#define __NRF_NVIC_APP_IRQ_PRIOS ((uint8_t)~__NRF_NVIC_SD_IRQ_PRIOS) + +/**@brief Interrupts used by the SoftDevice, with IRQn in the range 0-31. */ +#define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \ + (1U << POWER_CLOCK_IRQn) \ + | (1U << RADIO_IRQn) \ + | (1U << RTC0_IRQn) \ + | (1U << TIMER0_IRQn) \ + | (1U << RNG_IRQn) \ + | (1U << ECB_IRQn) \ + | (1U << CCM_AAR_IRQn) \ + | (1U << TEMP_IRQn) \ + | (1U << __NRF_NVIC_NVMC_IRQn) \ + | (1U << (uint32_t)SWI5_IRQn) \ + )) + +/**@brief Interrupts used by the SoftDevice, with IRQn in the range 32-63. */ +#define __NRF_NVIC_SD_IRQS_1 ((uint32_t)0) + +/**@brief Interrupts available for to application, with IRQn in the range 0-31. */ +#define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0) + +/**@brief Interrupts available for to application, with IRQn in the range 32-63. */ +#define __NRF_NVIC_APP_IRQS_1 (~__NRF_NVIC_SD_IRQS_1) + +/**@} */ + +/**@} */ + +/**@addtogroup NRF_NVIC_VARIABLES Variables + * @{ */ + +/**@brief Type representing the state struct for the SoftDevice NVIC module. */ +typedef struct +{ + uint32_t volatile __irq_masks[__NRF_NVIC_ISER_COUNT]; /**< IRQs enabled by the application in the NVIC. */ + uint32_t volatile __cr_flag; /**< Non-zero if already in a critical region */ +} nrf_nvic_state_t; + +/**@brief Variable keeping the state for the SoftDevice NVIC module. This must be declared in an + * application source file. */ +extern nrf_nvic_state_t nrf_nvic_state; + +/**@} */ + +/**@addtogroup NRF_NVIC_INTERNAL_FUNCTIONS SoftDevice NVIC internal functions + * @{ */ + +/**@brief Disables IRQ interrupts globally, including the SoftDevice's interrupts. + * + * @retval The value of PRIMASK prior to disabling the interrupts. + */ +__STATIC_INLINE int __sd_nvic_irq_disable(void); + +/**@brief Enables IRQ interrupts globally, including the SoftDevice's interrupts. + */ +__STATIC_INLINE void __sd_nvic_irq_enable(void); + +/**@brief Checks if IRQn is available to application + * @param[in] IRQn IRQ to check + * + * @retval 1 (true) if the IRQ to check is available to the application + */ +__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn); + +/**@brief Checks if priority is available to application + * @param[in] priority priority to check + * + * @retval 1 (true) if the priority to check is available to the application + */ +__STATIC_INLINE uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority); + +/**@} */ + +/**@addtogroup NRF_NVIC_FUNCTIONS SoftDevice NVIC public functions + * @{ */ + +/**@brief Enable External Interrupt. + * @note Corresponds to NVIC_EnableIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt was enabled. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn); + +/**@brief Disable External Interrupt. + * @note Corresponds to NVIC_DisableIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt was disabled. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn); + +/**@brief Get Pending Interrupt. + * @note Corresponds to NVIC_GetPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS. + * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ. + * + * @retval ::NRF_SUCCESS The interrupt is available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq); + +/**@brief Set Pending Interrupt. + * @note Corresponds to NVIC_SetPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt is set pending. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn); + +/**@brief Clear Pending Interrupt. + * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt pending flag is cleared. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn); + +/**@brief Set Interrupt Priority. + * @note Corresponds to NVIC_SetPriority in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * @pre Priority is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS. + * @param[in] priority A valid IRQ priority for use by the application. + * + * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority); + +/**@brief Get Interrupt Priority. + * @note Corresponds to NVIC_GetPriority in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS. + * @param[out] p_priority Return value from NVIC_GetPriority. + * + * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority); + +/**@brief System Reset. + * @note Corresponds to NVIC_SystemReset in CMSIS. + * + * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN + */ +__STATIC_INLINE uint32_t sd_nvic_SystemReset(void); + +/**@brief Enter critical region. + * + * @post Application interrupts will be disabled. + * @note sd_nvic_critical_region_enter() and ::sd_nvic_critical_region_exit() must be called in matching pairs inside each + * execution context + * @sa sd_nvic_critical_region_exit + * + * @param[out] p_is_nested_critical_region If 1, the application is now in a nested critical region. + * + * @retval ::NRF_SUCCESS + */ +__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region); + +/**@brief Exit critical region. + * + * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter. + * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called. + * + * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter. + * + * @retval ::NRF_SUCCESS + */ +__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region); + +/**@} */ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE int __sd_nvic_irq_disable(void) +{ + int pm = __get_PRIMASK(); + __disable_irq(); + return pm; +} + +__STATIC_INLINE void __sd_nvic_irq_enable(void) +{ + __enable_irq(); +} + +__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn) +{ + if (IRQn < 32) + { + return ((1UL<= (1 << __NVIC_PRIO_BITS)) + || (((1 << priority) & __NRF_NVIC_APP_IRQ_PRIOS) == 0) + ) + { + return 0; + } + return 1; +} + + +__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + if (!__sd_nvic_is_app_accessible_priority(NVIC_GetPriority(IRQn))) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; + } + + if (nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] |= (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); + } + else + { + NVIC_EnableIRQ(IRQn); + } + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + + if (nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] &= ~(1UL << ((uint32_t)(IRQn) & 0x1F)); + } + else + { + NVIC_DisableIRQ(IRQn); + } + + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + *p_pending_irq = NVIC_GetPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + NVIC_SetPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + NVIC_ClearPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + + if (!__sd_nvic_is_app_accessible_priority(priority)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; + } + + NVIC_SetPriority(IRQn, (uint32_t)priority); + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + *p_priority = (NVIC_GetPriority(IRQn) & 0xFF); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_SystemReset(void) +{ + NVIC_SystemReset(); + return NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN; +} + +__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region) +{ + int was_masked = __sd_nvic_irq_disable(); + if (!nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__cr_flag = 1; + nrf_nvic_state.__irq_masks[0] = ( NVIC->ICER[0] & __NRF_NVIC_APP_IRQS_0 ); + NVIC->ICER[0] = __NRF_NVIC_APP_IRQS_0; + nrf_nvic_state.__irq_masks[1] = ( NVIC->ICER[1] & __NRF_NVIC_APP_IRQS_1 ); + NVIC->ICER[1] = __NRF_NVIC_APP_IRQS_1; + *p_is_nested_critical_region = 0; + } + else + { + *p_is_nested_critical_region = 1; + } + if (!was_masked) + { + __sd_nvic_irq_enable(); + } + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region) +{ + if (nrf_nvic_state.__cr_flag && (is_nested_critical_region == 0)) + { + int was_masked = __sd_nvic_irq_disable(); + NVIC->ISER[0] = nrf_nvic_state.__irq_masks[0]; + NVIC->ISER[1] = nrf_nvic_state.__irq_masks[1]; + nrf_nvic_state.__cr_flag = 0; + if (!was_masked) + { + __sd_nvic_irq_enable(); + } + } + + return NRF_SUCCESS; +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_NVIC_H__ + +/**@} */ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_sdm.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_sdm.h new file mode 100644 index 00000000000..282e762e004 --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_sdm.h @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @defgroup nrf_sdm_api SoftDevice Manager API + @{ + + @brief APIs for SoftDevice management. + +*/ + +#ifndef NRF_SDM_H__ +#define NRF_SDM_H__ + +#include +#include "nrf.h" +#include "nrf_svc.h" +#include "nrf_error.h" +#include "nrf_error_sdm.h" +#include "nrf_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup NRF_SDM_DEFINES Defines + * @{ */ +#ifdef NRFSOC_DOXYGEN +/// Declared in nrf_mbr.h +#define MBR_SIZE 0 +#warning test +#endif + +/** @brief The major version for the SoftDevice binary distributed with this header file. */ +#define SD_MAJOR_VERSION (6) + +/** @brief The minor version for the SoftDevice binary distributed with this header file. */ +#define SD_MINOR_VERSION (1) + +/** @brief The bugfix version for the SoftDevice binary distributed with this header file. */ +#define SD_BUGFIX_VERSION (0) + +/** @brief The SoftDevice variant of this firmware. */ +#define SD_VARIANT_ID 140 + +/** @brief The full version number for the SoftDevice binary this header file was distributed + * with, as a decimal number in the form Mmmmbbb, where: + * - M is major version (one or more digits) + * - mmm is minor version (three digits) + * - bbb is bugfix version (three digits). */ +#define SD_VERSION (SD_MAJOR_VERSION * 1000000 + SD_MINOR_VERSION * 1000 + SD_BUGFIX_VERSION) + +/** @brief SoftDevice Manager SVC Base number. */ +#define SDM_SVC_BASE 0x10 + +/** @brief SoftDevice unique string size in bytes. */ +#define SD_UNIQUE_STR_SIZE 20 + +/** @brief Invalid info field. Returned when an info field does not exist. */ +#define SDM_INFO_FIELD_INVALID (0) + +/** @brief Defines the SoftDevice Information Structure location (address) as an offset from +the start of the SoftDevice (without MBR)*/ +#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000) + +/** @brief Defines the absolute SoftDevice Information Structure location (address) when the + * SoftDevice is installed just above the MBR (the usual case). */ +#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE) + +/** @brief Defines the offset for the SoftDevice Information Structure size value relative to the + * SoftDevice base address. The size value is of type uint8_t. */ +#define SD_INFO_STRUCT_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET) + +/** @brief Defines the offset for the SoftDevice size value relative to the SoftDevice base address. + * The size value is of type uint32_t. */ +#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08) + +/** @brief Defines the offset for FWID value relative to the SoftDevice base address. The FWID value + * is of type uint16_t. */ +#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C) + +/** @brief Defines the offset for the SoftDevice ID relative to the SoftDevice base address. The ID + * is of type uint32_t. */ +#define SD_ID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x10) + +/** @brief Defines the offset for the SoftDevice version relative to the SoftDevice base address in + * the same format as @ref SD_VERSION, stored as an uint32_t. */ +#define SD_VERSION_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x14) + +/** @brief Defines the offset for the SoftDevice unique string relative to the SoftDevice base address. + * The SD_UNIQUE_STR is stored as an array of uint8_t. The size of array is @ref SD_UNIQUE_STR_SIZE. + */ +#define SD_UNIQUE_STR_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x18) + +/** @brief Defines a macro for retrieving the actual SoftDevice Information Structure size value + * from a given base address. Use @ref MBR_SIZE as the argument when the SoftDevice is + * installed just above the MBR (the usual case). */ +#define SD_INFO_STRUCT_SIZE_GET(baseaddr) (*((uint8_t *) ((baseaddr) + SD_INFO_STRUCT_SIZE_OFFSET))) + +/** @brief Defines a macro for retrieving the actual SoftDevice size value from a given base + * address. Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above + * the MBR (the usual case). */ +#define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET))) + +/** @brief Defines the amount of flash that is used by the SoftDevice. + * Add @ref MBR_SIZE to find the first available flash address when the SoftDevice is installed + * just above the MBR (the usual case). + */ +#define SD_FLASH_SIZE 0x25000 + +/** @brief Defines a macro for retrieving the actual FWID value from a given base address. Use + * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual + * case). */ +#define SD_FWID_GET(baseaddr) (*((uint16_t *) ((baseaddr) + SD_FWID_OFFSET))) + +/** @brief Defines a macro for retrieving the actual SoftDevice ID from a given base address. Use + * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the + * usual case). */ +#define SD_ID_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_ID_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ + ? (*((uint32_t *) ((baseaddr) + SD_ID_OFFSET))) : SDM_INFO_FIELD_INVALID) + +/** @brief Defines a macro for retrieving the actual SoftDevice version from a given base address. + * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR + * (the usual case). */ +#define SD_VERSION_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_VERSION_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ + ? (*((uint32_t *) ((baseaddr) + SD_VERSION_OFFSET))) : SDM_INFO_FIELD_INVALID) + +/** @brief Defines a macro for retrieving the address of SoftDevice unique str based on a given base address. + * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR + * (the usual case). */ +#define SD_UNIQUE_STR_ADDR_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_UNIQUE_STR_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ + ? (((uint8_t *) ((baseaddr) + SD_UNIQUE_STR_OFFSET))) : SDM_INFO_FIELD_INVALID) + +/**@defgroup NRF_FAULT_ID_RANGES Fault ID ranges + * @{ */ +#define NRF_FAULT_ID_SD_RANGE_START 0x00000000 /**< SoftDevice ID range start. */ +#define NRF_FAULT_ID_APP_RANGE_START 0x00001000 /**< Application ID range start. */ +/**@} */ + +/**@defgroup NRF_FAULT_IDS Fault ID types + * @{ */ +#define NRF_FAULT_ID_SD_ASSERT (NRF_FAULT_ID_SD_RANGE_START + 1) /**< SoftDevice assertion. The info parameter is reserved for future used. */ +#define NRF_FAULT_ID_APP_MEMACC (NRF_FAULT_ID_APP_RANGE_START + 1) /**< Application invalid memory access. The info parameter will contain 0x00000000, + in case of SoftDevice RAM access violation. In case of SoftDevice peripheral + register violation the info parameter will contain the sub-region number of + PREGION[0], on whose address range the disallowed write access caused the + memory access fault. */ +/**@} */ + +/** @} */ + +/** @addtogroup NRF_SDM_ENUMS Enumerations + * @{ */ + +/**@brief nRF SoftDevice Manager API SVC numbers. */ +enum NRF_SD_SVCS +{ + SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */ + SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */ + SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */ + SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */ + SVC_SDM_LAST /**< Placeholder for last SDM SVC */ +}; + +/** @} */ + +/** @addtogroup NRF_SDM_DEFINES Defines + * @{ */ + +/**@defgroup NRF_CLOCK_LF_ACCURACY Clock accuracy + * @{ */ + +#define NRF_CLOCK_LF_ACCURACY_250_PPM (0) /**< Default: 250 ppm */ +#define NRF_CLOCK_LF_ACCURACY_500_PPM (1) /**< 500 ppm */ +#define NRF_CLOCK_LF_ACCURACY_150_PPM (2) /**< 150 ppm */ +#define NRF_CLOCK_LF_ACCURACY_100_PPM (3) /**< 100 ppm */ +#define NRF_CLOCK_LF_ACCURACY_75_PPM (4) /**< 75 ppm */ +#define NRF_CLOCK_LF_ACCURACY_50_PPM (5) /**< 50 ppm */ +#define NRF_CLOCK_LF_ACCURACY_30_PPM (6) /**< 30 ppm */ +#define NRF_CLOCK_LF_ACCURACY_20_PPM (7) /**< 20 ppm */ +#define NRF_CLOCK_LF_ACCURACY_10_PPM (8) /**< 10 ppm */ +#define NRF_CLOCK_LF_ACCURACY_5_PPM (9) /**< 5 ppm */ +#define NRF_CLOCK_LF_ACCURACY_2_PPM (10) /**< 2 ppm */ +#define NRF_CLOCK_LF_ACCURACY_1_PPM (11) /**< 1 ppm */ + +/** @} */ + +/**@defgroup NRF_CLOCK_LF_SRC Possible LFCLK oscillator sources + * @{ */ + +#define NRF_CLOCK_LF_SRC_RC (0) /**< LFCLK RC oscillator. */ +#define NRF_CLOCK_LF_SRC_XTAL (1) /**< LFCLK crystal oscillator. */ +#define NRF_CLOCK_LF_SRC_SYNTH (2) /**< LFCLK Synthesized from HFCLK. */ + +/** @} */ + +/** @} */ + +/** @addtogroup NRF_SDM_TYPES Types + * @{ */ + +/**@brief Type representing LFCLK oscillator source. */ +typedef struct +{ + uint8_t source; /**< LF oscillator clock source, see @ref NRF_CLOCK_LF_SRC. */ + uint8_t rc_ctiv; /**< Only for ::NRF_CLOCK_LF_SRC_RC: Calibration timer interval in 1/4 second + units (nRF52: 1-32). + @note To avoid excessive clock drift, 0.5 degrees Celsius is the + maximum temperature change allowed in one calibration timer + interval. The interval should be selected to ensure this. + + @note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC. */ + uint8_t rc_temp_ctiv; /**< Only for ::NRF_CLOCK_LF_SRC_RC: How often (in number of calibration + intervals) the RC oscillator shall be calibrated if the temperature + hasn't changed. + 0: Always calibrate even if the temperature hasn't changed. + 1: Only calibrate if the temperature has changed (legacy - nRF51 only). + 2-33: Check the temperature and only calibrate if it has changed, + however calibration will take place every rc_temp_ctiv + intervals in any case. + + @note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC. + + @note For nRF52, the application must ensure calibration at least once + every 8 seconds to ensure +/-500 ppm clock stability. The + recommended configuration for ::NRF_CLOCK_LF_SRC_RC on nRF52 is + rc_ctiv=16 and rc_temp_ctiv=2. This will ensure calibration at + least once every 8 seconds and for temperature changes of 0.5 + degrees Celsius every 4 seconds. See the Product Specification + for the nRF52 device being used for more information.*/ + uint8_t accuracy; /**< External clock accuracy used in the LL to compute timing + windows, see @ref NRF_CLOCK_LF_ACCURACY.*/ +} nrf_clock_lf_cfg_t; + +/**@brief Fault Handler type. + * + * When certain unrecoverable errors occur within the application or SoftDevice the fault handler will be called back. + * The protocol stack will be in an undefined state when this happens and the only way to recover will be to + * perform a reset, using e.g. CMSIS NVIC_SystemReset(). + * If the application returns from the fault handler the SoftDevice will call NVIC_SystemReset(). + * + * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the fault callback. + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault. + * @param[in] info Optional additional information regarding the fault. Refer to each Fault identifier for details. + * + * @note When id is set to @ref NRF_FAULT_ID_APP_MEMACC, pc will contain the address of the instruction being executed at the time when + * the fault is detected by the CPU. The CPU program counter may have advanced up to 2 instructions (no branching) after the one that triggered the fault. + */ +typedef void (*nrf_fault_handler_t)(uint32_t id, uint32_t pc, uint32_t info); + +/** @} */ + +/** @addtogroup NRF_SDM_FUNCTIONS Functions + * @{ */ + +/**@brief Enables the SoftDevice and by extension the protocol stack. + * + * @note Some care must be taken if a low frequency clock source is already running when calling this function: + * If the LF clock has a different source then the one currently running, it will be stopped. Then, the new + * clock source will be started. + * + * @note This function has no effect when returning with an error. + * + * @post If return code is ::NRF_SUCCESS + * - SoC library and protocol stack APIs are made available. + * - A portion of RAM will be unavailable (see relevant SDS documentation). + * - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation). + * - Interrupts will not arrive from protected peripherals or interrupts. + * - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice. + * - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation). + * - Chosen low frequency clock source will be running. + * + * @param p_clock_lf_cfg Low frequency clock source and accuracy. + If NULL the clock will be configured as an RC source with rc_ctiv = 16 and .rc_temp_ctiv = 2 + In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock. + * @param fault_handler Callback to be invoked in case of fault, cannot be NULL. + * + * @retval ::NRF_SUCCESS + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated. + * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level. + * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid clock source configuration supplied in p_clock_lf_cfg. + */ +SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler)); + + +/**@brief Disables the SoftDevice and by extension the protocol stack. + * + * Idempotent function to disable the SoftDevice. + * + * @post SoC library and protocol stack APIs are made unavailable. + * @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest). + * @post All peripherals used by the SoftDevice will be reset to default values. + * @post All of RAM become available. + * @post All interrupts are forwarded to the application. + * @post LFCLK source chosen in ::sd_softdevice_enable will be left running. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void)); + +/**@brief Check if the SoftDevice is enabled. + * + * @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled)); + +/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice + * + * This function is only intended to be called when a bootloader is enabled. + * + * @param[in] address The base address of the interrupt vector table for forwarded interrupts. + + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address)); + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // NRF_SDM_H__ + +/** + @} +*/ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_soc.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_soc.h new file mode 100644 index 00000000000..beb4d3a541c --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_soc.h @@ -0,0 +1,1079 @@ +/* + * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup nrf_soc_api SoC Library API + * @{ + * + * @brief APIs for the SoC library. + * + */ + +#ifndef NRF_SOC_H__ +#define NRF_SOC_H__ + +#include +#include "nrf.h" +#include "nrf_svc.h" +#include "nrf_error.h" +#include "nrf_error_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup NRF_SOC_DEFINES Defines + * @{ */ + +/**@brief The number of the lowest SVC number reserved for the SoC library. */ +#define SOC_SVC_BASE (0x20) /**< Base value for SVCs that are available when the SoftDevice is disabled. */ +#define SOC_SVC_BASE_NOT_AVAILABLE (0x2C) /**< Base value for SVCs that are not available when the SoftDevice is disabled. */ + +/**@brief Guaranteed time for application to process radio inactive notification. */ +#define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US (62) + +/**@brief The minimum allowed timeslot extension time. */ +#define NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US (200) + +/**@brief The maximum processing time to handle a timeslot extension. */ +#define NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US (17) + +/**@brief The latest time before the end of a timeslot the timeslot can be extended. */ +#define NRF_RADIO_MIN_EXTENSION_MARGIN_US (79) + +#define SOC_ECB_KEY_LENGTH (16) /**< ECB key length. */ +#define SOC_ECB_CLEARTEXT_LENGTH (16) /**< ECB cleartext length. */ +#define SOC_ECB_CIPHERTEXT_LENGTH (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */ + +#define SD_EVT_IRQn (SWI2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ +#define SD_EVT_IRQHandler (SWI2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. + The default interrupt priority for this handler is set to 6 */ +#define RADIO_NOTIFICATION_IRQn (SWI1_IRQn) /**< The radio notification IRQ number. */ +#define RADIO_NOTIFICATION_IRQHandler (SWI1_IRQHandler) /**< The radio notification IRQ handler. + The default interrupt priority for this handler is set to 6 */ +#define NRF_RADIO_LENGTH_MIN_US (100) /**< The shortest allowed radio timeslot, in microseconds. */ +#define NRF_RADIO_LENGTH_MAX_US (100000) /**< The longest allowed radio timeslot, in microseconds. */ + +#define NRF_RADIO_DISTANCE_MAX_US (128000000UL - 1UL) /**< The longest timeslot distance, in microseconds, allowed for the distance parameter (see @ref nrf_radio_request_normal_t) in the request. */ + +#define NRF_RADIO_EARLIEST_TIMEOUT_MAX_US (128000000UL - 1UL) /**< The longest timeout, in microseconds, allowed when requesting the earliest possible timeslot. */ + +#define NRF_RADIO_START_JITTER_US (2) /**< The maximum jitter in @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START relative to the requested start time. */ + +/**@brief Mask of PPI channels reserved by the SoftDevice when the SoftDevice is disabled. */ +#define NRF_SOC_SD_PPI_CHANNELS_SD_DISABLED_MSK ((uint32_t)(0)) + +/**@brief Mask of PPI channels reserved by the SoftDevice when the SoftDevice is enabled. */ +#define NRF_SOC_SD_PPI_CHANNELS_SD_ENABLED_MSK ((uint32_t)( \ + (1U << 17) \ + | (1U << 18) \ + | (1U << 19) \ + | (1U << 20) \ + | (1U << 21) \ + | (1U << 22) \ + | (1U << 23) \ + | (1U << 24) \ + | (1U << 25) \ + | (1U << 26) \ + | (1U << 27) \ + | (1U << 28) \ + | (1U << 29) \ + | (1U << 30) \ + | (1U << 31) \ + )) + +/**@brief Mask of PPI channels available to the application when the SoftDevice is disabled. */ +#define NRF_SOC_APP_PPI_CHANNELS_SD_DISABLED_MSK (~NRF_SOC_SD_PPI_CHANNELS_SD_DISABLED_MSK) + +/**@brief Mask of PPI channels available to the application when the SoftDevice is enabled. */ +#define NRF_SOC_APP_PPI_CHANNELS_SD_ENABLED_MSK (~NRF_SOC_SD_PPI_CHANNELS_SD_ENABLED_MSK) + +/**@brief Mask of PPI groups reserved by the SoftDevice when the SoftDevice is disabled. */ +#define NRF_SOC_SD_PPI_GROUPS_SD_DISABLED_MSK ((uint32_t)(0)) + +/**@brief Mask of PPI groups reserved by the SoftDevice when the SoftDevice is enabled. */ +#define NRF_SOC_SD_PPI_GROUPS_SD_ENABLED_MSK ((uint32_t)( \ + (1U << 4) \ + | (1U << 5) \ + )) + +/**@brief Mask of PPI groups available to the application when the SoftDevice is disabled. */ +#define NRF_SOC_APP_PPI_GROUPS_SD_DISABLED_MSK (~NRF_SOC_SD_PPI_GROUPS_SD_DISABLED_MSK) + +/**@brief Mask of PPI groups available to the application when the SoftDevice is enabled. */ +#define NRF_SOC_APP_PPI_GROUPS_SD_ENABLED_MSK (~NRF_SOC_SD_PPI_GROUPS_SD_ENABLED_MSK) + +/**@} */ + +/**@addtogroup NRF_SOC_ENUMS Enumerations + * @{ */ + +/**@brief The SVC numbers used by the SVC functions in the SoC library. */ +enum NRF_SOC_SVCS +{ + SD_PPI_CHANNEL_ENABLE_GET = SOC_SVC_BASE, + SD_PPI_CHANNEL_ENABLE_SET = SOC_SVC_BASE + 1, + SD_PPI_CHANNEL_ENABLE_CLR = SOC_SVC_BASE + 2, + SD_PPI_CHANNEL_ASSIGN = SOC_SVC_BASE + 3, + SD_PPI_GROUP_TASK_ENABLE = SOC_SVC_BASE + 4, + SD_PPI_GROUP_TASK_DISABLE = SOC_SVC_BASE + 5, + SD_PPI_GROUP_ASSIGN = SOC_SVC_BASE + 6, + SD_PPI_GROUP_GET = SOC_SVC_BASE + 7, + SD_FLASH_PAGE_ERASE = SOC_SVC_BASE + 8, + SD_FLASH_WRITE = SOC_SVC_BASE + 9, + SD_PROTECTED_REGISTER_WRITE = SOC_SVC_BASE + 11, + SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE, + SD_MUTEX_ACQUIRE = SOC_SVC_BASE_NOT_AVAILABLE + 1, + SD_MUTEX_RELEASE = SOC_SVC_BASE_NOT_AVAILABLE + 2, + SD_RAND_APPLICATION_POOL_CAPACITY_GET = SOC_SVC_BASE_NOT_AVAILABLE + 3, + SD_RAND_APPLICATION_BYTES_AVAILABLE_GET = SOC_SVC_BASE_NOT_AVAILABLE + 4, + SD_RAND_APPLICATION_VECTOR_GET = SOC_SVC_BASE_NOT_AVAILABLE + 5, + SD_POWER_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 6, + SD_POWER_SYSTEM_OFF = SOC_SVC_BASE_NOT_AVAILABLE + 7, + SD_POWER_RESET_REASON_GET = SOC_SVC_BASE_NOT_AVAILABLE + 8, + SD_POWER_RESET_REASON_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 9, + SD_POWER_POF_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 10, + SD_POWER_POF_THRESHOLD_SET = SOC_SVC_BASE_NOT_AVAILABLE + 11, + SD_POWER_POF_THRESHOLDVDDH_SET = SOC_SVC_BASE_NOT_AVAILABLE + 12, + SD_POWER_RAM_POWER_SET = SOC_SVC_BASE_NOT_AVAILABLE + 13, + SD_POWER_RAM_POWER_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 14, + SD_POWER_RAM_POWER_GET = SOC_SVC_BASE_NOT_AVAILABLE + 15, + SD_POWER_GPREGRET_SET = SOC_SVC_BASE_NOT_AVAILABLE + 16, + SD_POWER_GPREGRET_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 17, + SD_POWER_GPREGRET_GET = SOC_SVC_BASE_NOT_AVAILABLE + 18, + SD_POWER_DCDC_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 19, + SD_POWER_DCDC0_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 20, + SD_APP_EVT_WAIT = SOC_SVC_BASE_NOT_AVAILABLE + 21, + SD_CLOCK_HFCLK_REQUEST = SOC_SVC_BASE_NOT_AVAILABLE + 22, + SD_CLOCK_HFCLK_RELEASE = SOC_SVC_BASE_NOT_AVAILABLE + 23, + SD_CLOCK_HFCLK_IS_RUNNING = SOC_SVC_BASE_NOT_AVAILABLE + 24, + SD_RADIO_NOTIFICATION_CFG_SET = SOC_SVC_BASE_NOT_AVAILABLE + 25, + SD_ECB_BLOCK_ENCRYPT = SOC_SVC_BASE_NOT_AVAILABLE + 26, + SD_ECB_BLOCKS_ENCRYPT = SOC_SVC_BASE_NOT_AVAILABLE + 27, + SD_RADIO_SESSION_OPEN = SOC_SVC_BASE_NOT_AVAILABLE + 28, + SD_RADIO_SESSION_CLOSE = SOC_SVC_BASE_NOT_AVAILABLE + 29, + SD_RADIO_REQUEST = SOC_SVC_BASE_NOT_AVAILABLE + 30, + SD_EVT_GET = SOC_SVC_BASE_NOT_AVAILABLE + 31, + SD_TEMP_GET = SOC_SVC_BASE_NOT_AVAILABLE + 32, + SD_POWER_USBPWRRDY_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 33, + SD_POWER_USBDETECTED_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 34, + SD_POWER_USBREMOVED_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 35, + SD_POWER_USBREGSTATUS_GET = SOC_SVC_BASE_NOT_AVAILABLE + 36, + SVC_SOC_LAST = SOC_SVC_BASE_NOT_AVAILABLE + 37 +}; + +/**@brief Possible values of a ::nrf_mutex_t. */ +enum NRF_MUTEX_VALUES +{ + NRF_MUTEX_FREE, + NRF_MUTEX_TAKEN +}; + +/**@brief Power modes. */ +enum NRF_POWER_MODES +{ + NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */ + NRF_POWER_MODE_LOWPWR /**< Low power mode. See power management in the reference manual. */ +}; + + +/**@brief Power failure thresholds */ +enum NRF_POWER_THRESHOLDS +{ + NRF_POWER_THRESHOLD_V17 = 4UL, /**< 1.7 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V18, /**< 1.8 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V19, /**< 1.9 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V20, /**< 2.0 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V22, /**< 2.2 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V23, /**< 2.3 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V24, /**< 2.4 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V25, /**< 2.5 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V26, /**< 2.6 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V27, /**< 2.7 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V28 /**< 2.8 Volts power failure threshold. */ +}; + +/**@brief Power failure thresholds for high voltage */ +enum NRF_POWER_THRESHOLDVDDHS +{ + NRF_POWER_THRESHOLDVDDH_V27, /**< 2.7 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V28, /**< 2.8 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V29, /**< 2.9 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V30, /**< 3.0 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V31, /**< 3.1 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V32, /**< 3.2 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V33, /**< 3.3 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V34, /**< 3.4 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V35, /**< 3.5 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V36, /**< 3.6 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V37, /**< 3.7 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V38, /**< 3.8 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V39, /**< 3.9 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V40, /**< 4.0 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V41, /**< 4.1 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V42 /**< 4.2 Volts power failure threshold. */ +}; + + +/**@brief DC/DC converter modes. */ +enum NRF_POWER_DCDC_MODES +{ + NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */ + NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */ +}; + +/**@brief Radio notification distances. */ +enum NRF_RADIO_NOTIFICATION_DISTANCES +{ + NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */ + NRF_RADIO_NOTIFICATION_DISTANCE_800US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_1740US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_2680US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_3620US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_4560US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_5500US /**< The distance from the active notification to start of radio activity. */ +}; + + +/**@brief Radio notification types. */ +enum NRF_RADIO_NOTIFICATION_TYPES +{ + NRF_RADIO_NOTIFICATION_TYPE_NONE = 0, /**< The event does not have a radio notification signal. */ + NRF_RADIO_NOTIFICATION_TYPE_INT_ON_ACTIVE, /**< Using interrupt for notification when the radio will be enabled. */ + NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE, /**< Using interrupt for notification when the radio has been disabled. */ + NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, /**< Using interrupt for notification both when the radio will be enabled and disabled. */ +}; + +/**@brief The Radio signal callback types. */ +enum NRF_RADIO_CALLBACK_SIGNAL_TYPE +{ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_START, /**< This signal indicates the start of the radio timeslot. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0, /**< This signal indicates the NRF_TIMER0 interrupt. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO, /**< This signal indicates the NRF_RADIO interrupt. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED, /**< This signal indicates extend action failed. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED /**< This signal indicates extend action succeeded. */ +}; + +/**@brief The actions requested by the signal callback. + * + * This code gives the SOC instructions about what action to take when the signal callback has + * returned. + */ +enum NRF_RADIO_SIGNAL_CALLBACK_ACTION +{ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE, /**< Return without action. */ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND, /**< Request an extension of the current + timeslot. Maximum execution time for this action: + @ref NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US. + This action must be started at least + @ref NRF_RADIO_MIN_EXTENSION_MARGIN_US before + the end of the timeslot. */ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, /**< End the current radio timeslot. */ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END /**< Request a new radio timeslot and end the current timeslot. */ +}; + +/**@brief Radio timeslot high frequency clock source configuration. */ +enum NRF_RADIO_HFCLK_CFG +{ + NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED, /**< The SoftDevice will guarantee that the high frequency clock source is the + external crystal for the whole duration of the timeslot. This should be the + preferred option for events that use the radio or require high timing accuracy. + @note The SoftDevice will automatically turn on and off the external crystal, + at the beginning and end of the timeslot, respectively. The crystal may also + intentionally be left running after the timeslot, in cases where it is needed + by the SoftDevice shortly after the end of the timeslot. */ + NRF_RADIO_HFCLK_CFG_NO_GUARANTEE /**< This configuration allows for earlier and tighter scheduling of timeslots. + The RC oscillator may be the clock source in part or for the whole duration of the timeslot. + The RC oscillator's accuracy must therefore be taken into consideration. + @note If the application will use the radio peripheral in timeslots with this configuration, + it must make sure that the crystal is running and stable before starting the radio. */ +}; + +/**@brief Radio timeslot priorities. */ +enum NRF_RADIO_PRIORITY +{ + NRF_RADIO_PRIORITY_HIGH, /**< High (equal priority as the normal connection priority of the SoftDevice stack(s)). */ + NRF_RADIO_PRIORITY_NORMAL, /**< Normal (equal priority as the priority of secondary activities of the SoftDevice stack(s)). */ +}; + +/**@brief Radio timeslot request type. */ +enum NRF_RADIO_REQUEST_TYPE +{ + NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request radio timeslot as early as possible. This should always be used for the first request in a session. */ + NRF_RADIO_REQ_TYPE_NORMAL /**< Normal radio timeslot request. */ +}; + +/**@brief SoC Events. */ +enum NRF_SOC_EVTS +{ + NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */ + NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */ + NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */ + NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */ + NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */ + NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */ + NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio timeslot signal callback handler return was invalid. */ + NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio timeslot session is idle. */ + NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio timeslot session is closed. */ + NRF_EVT_POWER_USB_POWER_READY, /**< Event indicating that a USB 3.3 V supply is ready. */ + NRF_EVT_POWER_USB_DETECTED, /**< Event indicating that voltage supply is detected on VBUS. */ + NRF_EVT_POWER_USB_REMOVED, /**< Event indicating that voltage supply is removed from VBUS. */ + NRF_EVT_NUMBER_OF_EVTS +}; + +/**@} */ + + +/**@addtogroup NRF_SOC_STRUCTURES Structures + * @{ */ + +/**@brief Represents a mutex for use with the nrf_mutex functions. + * @note Accessing the value directly is not safe, use the mutex functions! + */ +typedef volatile uint8_t nrf_mutex_t; + +/**@brief Parameters for a request for a timeslot as early as possible. */ +typedef struct +{ + uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ + uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ + uint32_t length_us; /**< The radio timeslot length (in the range 100 to 100,000] microseconds). */ + uint32_t timeout_us; /**< Longest acceptable delay until the start of the requested timeslot (up to @ref NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */ +} nrf_radio_request_earliest_t; + +/**@brief Parameters for a normal radio timeslot request. */ +typedef struct +{ + uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ + uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ + uint32_t distance_us; /**< Distance from the start of the previous radio timeslot (up to @ref NRF_RADIO_DISTANCE_MAX_US microseconds). */ + uint32_t length_us; /**< The radio timeslot length (in the range [100..100,000] microseconds). */ +} nrf_radio_request_normal_t; + +/**@brief Radio timeslot request parameters. */ +typedef struct +{ + uint8_t request_type; /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */ + union + { + nrf_radio_request_earliest_t earliest; /**< Parameters for requesting a radio timeslot as early as possible. */ + nrf_radio_request_normal_t normal; /**< Parameters for requesting a normal radio timeslot. */ + } params; /**< Parameter union. */ +} nrf_radio_request_t; + +/**@brief Return parameters of the radio timeslot signal callback. */ +typedef struct +{ + uint8_t callback_action; /**< The action requested by the application when returning from the signal callback, see @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION. */ + union + { + struct + { + nrf_radio_request_t * p_next; /**< The request parameters for the next radio timeslot. */ + } request; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */ + struct + { + uint32_t length_us; /**< Requested extension of the radio timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */ + } extend; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */ + } params; /**< Parameter union. */ +} nrf_radio_signal_callback_return_param_t; + +/**@brief The radio timeslot signal callback type. + * + * @note In case of invalid return parameters, the radio timeslot will automatically end + * immediately after returning from the signal callback and the + * @ref NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN event will be sent. + * @note The returned struct pointer must remain valid after the signal callback + * function returns. For instance, this means that it must not point to a stack variable. + * + * @param[in] signal_type Type of signal, see @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE. + * + * @return Pointer to structure containing action requested by the application. + */ +typedef nrf_radio_signal_callback_return_param_t * (*nrf_radio_signal_callback_t) (uint8_t signal_type); + +/**@brief AES ECB parameter typedefs */ +typedef uint8_t soc_ecb_key_t[SOC_ECB_KEY_LENGTH]; /**< Encryption key type. */ +typedef uint8_t soc_ecb_cleartext_t[SOC_ECB_CLEARTEXT_LENGTH]; /**< Cleartext data type. */ +typedef uint8_t soc_ecb_ciphertext_t[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Ciphertext data type. */ + +/**@brief AES ECB data structure */ +typedef struct +{ + soc_ecb_key_t key; /**< Encryption key. */ + soc_ecb_cleartext_t cleartext; /**< Cleartext data. */ + soc_ecb_ciphertext_t ciphertext; /**< Ciphertext data. */ +} nrf_ecb_hal_data_t; + +/**@brief AES ECB block. Used to provide multiple blocks in a single call + to @ref sd_ecb_blocks_encrypt.*/ +typedef struct +{ + soc_ecb_key_t const * p_key; /**< Pointer to the Encryption key. */ + soc_ecb_cleartext_t const * p_cleartext; /**< Pointer to the Cleartext data. */ + soc_ecb_ciphertext_t * p_ciphertext; /**< Pointer to the Ciphertext data. */ +} nrf_ecb_hal_data_block_t; + +/**@} */ + +/**@addtogroup NRF_SOC_FUNCTIONS Functions + * @{ */ + +/**@brief Initialize a mutex. + * + * @param[in] p_mutex Pointer to the mutex to initialize. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_MUTEX_NEW, uint32_t, sd_mutex_new(nrf_mutex_t * p_mutex)); + +/**@brief Attempt to acquire a mutex. + * + * @param[in] p_mutex Pointer to the mutex to acquire. + * + * @retval ::NRF_SUCCESS The mutex was successfully acquired. + * @retval ::NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN The mutex could not be acquired. + */ +SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t * p_mutex)); + +/**@brief Release a mutex. + * + * @param[in] p_mutex Pointer to the mutex to release. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t * p_mutex)); + +/**@brief Query the capacity of the application random pool. + * + * @param[out] p_pool_capacity The capacity of the pool. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY_GET, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity)); + +/**@brief Get number of random bytes available to the application. + * + * @param[out] p_bytes_available The number of bytes currently available in the pool. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available)); + +/**@brief Get random bytes from the application pool. + * + * @param[out] p_buff Pointer to unit8_t buffer for storing the bytes. + * @param[in] length Number of bytes to take from pool and place in p_buff. + * + * @retval ::NRF_SUCCESS The requested bytes were written to p_buff. + * @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes available. +*/ +SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length)); + +/**@brief Gets the reset reason register. + * + * @param[out] p_reset_reason Contents of the NRF_POWER->RESETREAS register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RESET_REASON_GET, uint32_t, sd_power_reset_reason_get(uint32_t * p_reset_reason)); + +/**@brief Clears the bits of the reset reason register. + * + * @param[in] reset_reason_clr_msk Contains the bits to clear from the reset reason register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t reset_reason_clr_msk)); + +/**@brief Sets the power mode when in CPU sleep. + * + * @param[in] power_mode The power mode to use when in CPU sleep, see @ref NRF_POWER_MODES. @sa sd_app_evt_wait + * + * @retval ::NRF_SUCCESS The power mode was set. + * @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown. + */ +SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(uint8_t power_mode)); + +/**@brief Puts the chip in System OFF mode. + * + * @retval ::NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN + */ +SVCALL(SD_POWER_SYSTEM_OFF, uint32_t, sd_power_system_off(void)); + +/**@brief Enables or disables the power-fail comparator. + * + * Enabling this will give a SoftDevice event (NRF_EVT_POWER_FAILURE_WARNING) when the power failure warning occurs. + * The event can be retrieved with sd_evt_get(); + * + * @param[in] pof_enable True if the power-fail comparator should be enabled, false if it should be disabled. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable)); + +/**@brief Enables or disables the USB power ready event. + * + * Enabling this will give a SoftDevice event (NRF_EVT_POWER_USB_POWER_READY) when a USB 3.3 V supply is ready. + * The event can be retrieved with sd_evt_get(); + * + * @param[in] usbpwrrdy_enable True if the power ready event should be enabled, false if it should be disabled. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_USBPWRRDY_ENABLE, uint32_t, sd_power_usbpwrrdy_enable(uint8_t usbpwrrdy_enable)); + +/**@brief Enables or disables the power USB-detected event. + * + * Enabling this will give a SoftDevice event (NRF_EVT_POWER_USB_DETECTED) when a voltage supply is detected on VBUS. + * The event can be retrieved with sd_evt_get(); + * + * @param[in] usbdetected_enable True if the power ready event should be enabled, false if it should be disabled. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_USBDETECTED_ENABLE, uint32_t, sd_power_usbdetected_enable(uint8_t usbdetected_enable)); + +/**@brief Enables or disables the power USB-removed event. + * + * Enabling this will give a SoftDevice event (NRF_EVT_POWER_USB_REMOVED) when a voltage supply is removed from VBUS. + * The event can be retrieved with sd_evt_get(); + * + * @param[in] usbremoved_enable True if the power ready event should be enabled, false if it should be disabled. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_USBREMOVED_ENABLE, uint32_t, sd_power_usbremoved_enable(uint8_t usbremoved_enable)); + +/**@brief Get USB supply status register content. + * + * @param[out] usbregstatus The content of USBREGSTATUS register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_USBREGSTATUS_GET, uint32_t, sd_power_usbregstatus_get(uint32_t * usbregstatus)); + +/**@brief Sets the power failure comparator threshold value. + * + * @note: Power failure comparator threshold setting. This setting applies both for normal voltage + * mode (supply connected to both VDD and VDDH) and high voltage mode (supply connected to + * VDDH only). + * + * @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDS. + * + * @retval ::NRF_SUCCESS The power failure threshold was set. + * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown. + */ +SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(uint8_t threshold)); + +/**@brief Sets the power failure comparator threshold value for high voltage. + * + * @note: Power failure comparator threshold setting for high voltage mode (supply connected to + * VDDH only). This setting does not apply for normal voltage mode (supply connected to both + * VDD and VDDH). + * + * @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDVDDHS. + * + * @retval ::NRF_SUCCESS The power failure threshold was set. + * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown. + */ +SVCALL(SD_POWER_POF_THRESHOLDVDDH_SET, uint32_t, sd_power_pof_thresholdvddh_set(uint8_t threshold)); + +/**@brief Writes the NRF_POWER->RAM[index].POWERSET register. + * + * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERSET register to write to. + * @param[in] ram_powerset Contains the word to write to the NRF_POWER->RAM[index].POWERSET register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RAM_POWER_SET, uint32_t, sd_power_ram_power_set(uint8_t index, uint32_t ram_powerset)); + +/**@brief Writes the NRF_POWER->RAM[index].POWERCLR register. + * + * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERCLR register to write to. + * @param[in] ram_powerclr Contains the word to write to the NRF_POWER->RAM[index].POWERCLR register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RAM_POWER_CLR, uint32_t, sd_power_ram_power_clr(uint8_t index, uint32_t ram_powerclr)); + +/**@brief Get contents of NRF_POWER->RAM[index].POWER register, indicates power status of RAM[index] blocks. + * + * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWER register to read from. + * @param[out] p_ram_power Content of NRF_POWER->RAM[index].POWER register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RAM_POWER_GET, uint32_t, sd_power_ram_power_get(uint8_t index, uint32_t * p_ram_power)); + +/**@brief Set bits in the general purpose retention registers (NRF_POWER->GPREGRET*). + * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. + * @param[in] gpregret_msk Bits to be set in the GPREGRET register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_id, uint32_t gpregret_msk)); + +/**@brief Clear bits in the general purpose retention registers (NRF_POWER->GPREGRET*). + * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. + * @param[in] gpregret_msk Bits to be clear in the GPREGRET register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_id, uint32_t gpregret_msk)); + +/**@brief Get contents of the general purpose retention registers (NRF_POWER->GPREGRET*). + * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. + * @param[out] p_gpregret Contents of the GPREGRET register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t gpregret_id, uint32_t *p_gpregret)); + +/**@brief Enable or disable the DC/DC regulator for the regulator stage 1 (REG1). + * + * @param[in] dcdc_mode The mode of the DCDC, see @ref NRF_POWER_DCDC_MODES. + * + * @retval ::NRF_SUCCESS + * @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid. + */ +SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(uint8_t dcdc_mode)); + +/**@brief Enable or disable the DC/DC regulator for the regulator stage 0 (REG0). + * + * For more details on the REG0 stage, please see product specification. + * + * @param[in] dcdc_mode The mode of the DCDC0, see @ref NRF_POWER_DCDC_MODES. + * + * @retval ::NRF_SUCCESS + * @retval ::NRF_ERROR_INVALID_PARAM The dcdc_mode is invalid. + */ +SVCALL(SD_POWER_DCDC0_MODE_SET, uint32_t, sd_power_dcdc0_mode_set(uint8_t dcdc_mode)); + +/**@brief Request the high frequency crystal oscillator. + * + * Will start the high frequency crystal oscillator, the startup time of the crystal varies + * and the ::sd_clock_hfclk_is_running function can be polled to check if it has started. + * + * @see sd_clock_hfclk_is_running + * @see sd_clock_hfclk_release + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_CLOCK_HFCLK_REQUEST, uint32_t, sd_clock_hfclk_request(void)); + +/**@brief Releases the high frequency crystal oscillator. + * + * Will stop the high frequency crystal oscillator, this happens immediately. + * + * @see sd_clock_hfclk_is_running + * @see sd_clock_hfclk_request + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_CLOCK_HFCLK_RELEASE, uint32_t, sd_clock_hfclk_release(void)); + +/**@brief Checks if the high frequency crystal oscillator is running. + * + * @see sd_clock_hfclk_request + * @see sd_clock_hfclk_release + * + * @param[out] p_is_running 1 if the external crystal oscillator is running, 0 if not. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_CLOCK_HFCLK_IS_RUNNING, uint32_t, sd_clock_hfclk_is_running(uint32_t * p_is_running)); + +/**@brief Waits for an application event. + * + * An application event is either an application interrupt or a pended interrupt when the interrupt + * is disabled. + * + * When the application waits for an application event by calling this function, an interrupt that + * is enabled will be taken immediately on pending since this function will wait in thread mode, + * then the execution will return in the application's main thread. + * + * In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M + * MCU's System Control Register (SCR), CMSIS_SCB. In that case, when a disabled interrupt gets + * pended, this function will return to the application's main thread. + * + * @note The application must ensure that the pended flag is cleared using ::sd_nvic_ClearPendingIRQ + * in order to sleep using this function. This is only necessary for disabled interrupts, as + * the interrupt handler will clear the pending flag automatically for enabled interrupts. + * + * @note If an application interrupt has happened since the last time sd_app_evt_wait was + * called this function will return immediately and not go to sleep. This is to avoid race + * conditions that can occur when a flag is updated in the interrupt handler and processed + * in the main loop. + * + * @post An application interrupt has happened or a interrupt pending flag is set. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_APP_EVT_WAIT, uint32_t, sd_app_evt_wait(void)); + +/**@brief Get PPI channel enable register contents. + * + * @param[out] p_channel_enable The contents of the PPI CHEN register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ENABLE_GET, uint32_t, sd_ppi_channel_enable_get(uint32_t * p_channel_enable)); + +/**@brief Set PPI channel enable register. + * + * @param[in] channel_enable_set_msk Mask containing the bits to set in the PPI CHEN register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ENABLE_SET, uint32_t, sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk)); + +/**@brief Clear PPI channel enable register. + * + * @param[in] channel_enable_clr_msk Mask containing the bits to clear in the PPI CHEN register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ENABLE_CLR, uint32_t, sd_ppi_channel_enable_clr(uint32_t channel_enable_clr_msk)); + +/**@brief Assign endpoints to a PPI channel. + * + * @param[in] channel_num Number of the PPI channel to assign. + * @param[in] evt_endpoint Event endpoint of the PPI channel. + * @param[in] task_endpoint Task endpoint of the PPI channel. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_CHANNEL The channel number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ASSIGN, uint32_t, sd_ppi_channel_assign(uint8_t channel_num, const volatile void * evt_endpoint, const volatile void * task_endpoint)); + +/**@brief Task to enable a channel group. + * + * @param[in] group_num Number of the channel group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_TASK_ENABLE, uint32_t, sd_ppi_group_task_enable(uint8_t group_num)); + +/**@brief Task to disable a channel group. + * + * @param[in] group_num Number of the PPI group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_TASK_DISABLE, uint32_t, sd_ppi_group_task_disable(uint8_t group_num)); + +/**@brief Assign PPI channels to a channel group. + * + * @param[in] group_num Number of the channel group. + * @param[in] channel_msk Mask of the channels to assign to the group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_ASSIGN, uint32_t, sd_ppi_group_assign(uint8_t group_num, uint32_t channel_msk)); + +/**@brief Gets the PPI channels of a channel group. + * + * @param[in] group_num Number of the channel group. + * @param[out] p_channel_msk Mask of the channels assigned to the group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t * p_channel_msk)); + +/**@brief Configures the Radio Notification signal. + * + * @note + * - The notification signal latency depends on the interrupt priority settings of SWI used + * for notification signal. + * - To ensure that the radio notification signal behaves in a consistent way, the radio + * notifications must be configured when there is no protocol stack or other SoftDevice + * activity in progress. It is recommended that the radio notification signal is + * configured directly after the SoftDevice has been enabled. + * - In the period between the ACTIVE signal and the start of the Radio Event, the SoftDevice + * will interrupt the application to do Radio Event preparation. + * - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have + * to shorten the connection events to have time for the Radio Notification signals. + * + * @param[in] type Type of notification signal, see @ref NRF_RADIO_NOTIFICATION_TYPES. + * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio + * notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is + * recommended (but not required) to be used with + * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE. + * + * @param[in] distance Distance between the notification signal and start of radio activity, see @ref NRF_RADIO_NOTIFICATION_DISTANCES. + * This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or + * @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used. + * + * @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid. + * @retval ::NRF_ERROR_INVALID_STATE A protocol stack or other SoftDevice is running. Stop all + * running activities and retry. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(uint8_t type, uint8_t distance)); + +/**@brief Encrypts a block according to the specified parameters. + * + * 128-bit AES encryption. + * + * @note: + * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while + * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application + * main or low interrupt level. + * + * @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input + * parameters and one output parameter). + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data)); + +/**@brief Encrypts multiple data blocks provided as an array of data block structures. + * + * @details: Performs 128-bit AES encryption on multiple data blocks + * + * @note: + * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while + * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application + * main or low interrupt level. + * + * @param[in] block_count Count of blocks in the p_data_blocks array. + * @param[in,out] p_data_blocks Pointer to the first entry in a contiguous array of + * @ref nrf_ecb_hal_data_block_t structures. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_ECB_BLOCKS_ENCRYPT, uint32_t, sd_ecb_blocks_encrypt(uint8_t block_count, nrf_ecb_hal_data_block_t * p_data_blocks)); + +/**@brief Gets any pending events generated by the SoC API. + * + * The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned. + * + * @param[out] p_evt_id Set to one of the values in @ref NRF_SOC_EVTS, if any events are pending. + * + * @retval ::NRF_SUCCESS An event was pending. The event id is written in the p_evt_id parameter. + * @retval ::NRF_ERROR_NOT_FOUND No pending events. + */ +SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t * p_evt_id)); + +/**@brief Get the temperature measured on the chip + * + * This function will block until the temperature measurement is done. + * It takes around 50 us from call to return. + * + * @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees Celsius. + * + * @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp + */ +SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t * p_temp)); + +/**@brief Flash Write +* +* Commands to write a buffer to flash +* +* If the SoftDevice is enabled: +* This call initiates the flash access command, and its completion will be communicated to the +* application with exactly one of the following events: +* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. +* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. +* +* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the + * write has been completed +* +* @note +* - This call takes control over the radio and the CPU during flash erase and write to make sure that +* they will not interfere with the flash access. This means that all interrupts will be blocked +* for a predictable time (depending on the NVMC specification in the device's Product Specification +* and the command parameters). +* - The data in the p_src buffer should not be modified before the @ref NRF_EVT_FLASH_OPERATION_SUCCESS +* or the @ref NRF_EVT_FLASH_OPERATION_ERROR have been received if the SoftDevice is enabled. +* - This call will make the SoftDevice trigger a hardfault when the page is written, if it is +* protected. +* +* +* @param[in] p_dst Pointer to start of flash location to be written. +* @param[in] p_src Pointer to buffer with data to be written. +* @param[in] size Number of 32-bit words to write. Maximum size is the number of words in one +* flash page. See the device's Product Specification for details. +* +* @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned. +* @retval ::NRF_ERROR_BUSY The previous command has not yet completed. +* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or higher than the maximum allowed size. +* @retval ::NRF_ERROR_FORBIDDEN Tried to write to an address outside the application flash area. +* @retval ::NRF_SUCCESS The command was accepted. +*/ +SVCALL(SD_FLASH_WRITE, uint32_t, sd_flash_write(uint32_t * p_dst, uint32_t const * p_src, uint32_t size)); + + +/**@brief Flash Erase page +* +* Commands to erase a flash page +* If the SoftDevice is enabled: +* This call initiates the flash access command, and its completion will be communicated to the +* application with exactly one of the following events: +* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. +* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. +* +* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the +* erase has been completed +* +* @note +* - This call takes control over the radio and the CPU during flash erase and write to make sure that +* they will not interfere with the flash access. This means that all interrupts will be blocked +* for a predictable time (depending on the NVMC specification in the device's Product Specification +* and the command parameters). +* - This call will make the SoftDevice trigger a hardfault when the page is erased, if it is +* protected. +* +* +* @param[in] page_number Page number of the page to erase +* +* @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. +* @retval ::NRF_ERROR_INVALID_ADDR Tried to erase to a non existing flash page. +* @retval ::NRF_ERROR_BUSY The previous command has not yet completed. +* @retval ::NRF_ERROR_FORBIDDEN Tried to erase a page outside the application flash area. +* @retval ::NRF_SUCCESS The command was accepted. +*/ +SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number)); + + + +/**@brief Opens a session for radio timeslot requests. + * + * @note Only one session can be open at a time. + * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot + * starts. From this point the NRF_RADIO and NRF_TIMER0 peripherals can be freely accessed + * by the application. + * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0) is called whenever the NRF_TIMER0 + * interrupt occurs. + * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO) is called whenever the NRF_RADIO + * interrupt occurs. + * @note p_radio_signal_callback() will be called at ARM interrupt priority level 0. This + * implies that none of the sd_* API calls can be used from p_radio_signal_callback(). + * + * @param[in] p_radio_signal_callback The signal callback. + * + * @retval ::NRF_ERROR_INVALID_ADDR p_radio_signal_callback is an invalid function pointer. + * @retval ::NRF_ERROR_BUSY If session cannot be opened. + * @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. + * @retval ::NRF_SUCCESS Otherwise. + */ + SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback)); + +/**@brief Closes a session for radio timeslot requests. + * + * @note Any current radio timeslot will be finished before the session is closed. + * @note If a radio timeslot is scheduled when the session is closed, it will be canceled. + * @note The application cannot consider the session closed until the @ref NRF_EVT_RADIO_SESSION_CLOSED + * event is received. + * + * @retval ::NRF_ERROR_FORBIDDEN If session not opened. + * @retval ::NRF_ERROR_BUSY If session is currently being closed. + * @retval ::NRF_SUCCESS Otherwise. + */ + SVCALL(SD_RADIO_SESSION_CLOSE, uint32_t, sd_radio_session_close(void)); + +/**@brief Requests a radio timeslot. + * + * @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST + * and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type @ref NRF_RADIO_REQ_TYPE_EARLIEST. + * @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by + * p_request->distance_us and is given relative to the start of the previous timeslot. + * @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event. + * @note Timeslots scheduled too close will lead to a @ref NRF_EVT_RADIO_BLOCKED event. + * @note See the SoftDevice Specification for more on radio timeslot scheduling, distances and lengths. + * @note If an opportunity for the first radio timeslot is not found before 100 ms after the call to this + * function, it is not scheduled, and instead a @ref NRF_EVT_RADIO_BLOCKED event is sent. + * The application may then try to schedule the first radio timeslot again. + * @note Successful requests will result in nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START). + * Unsuccessful requests will result in a @ref NRF_EVT_RADIO_BLOCKED event, see @ref NRF_SOC_EVTS. + * @note The jitter in the start time of the radio timeslots is +/- @ref NRF_RADIO_START_JITTER_US us. + * @note The nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) call has a latency relative to the + * specified radio timeslot start, but this does not affect the actual start time of the timeslot. + * @note NRF_TIMER0 is reset at the start of the radio timeslot, and is clocked at 1MHz from the high frequency + * (16 MHz) clock source. If p_request->hfclk_force_xtal is true, the high frequency clock is + * guaranteed to be clocked from the external crystal. + * @note The SoftDevice will neither access the NRF_RADIO peripheral nor the NRF_TIMER0 peripheral + * during the radio timeslot. + * + * @param[in] p_request Pointer to the request parameters. + * + * @retval ::NRF_ERROR_FORBIDDEN If session not opened or the session is not IDLE. + * @retval ::NRF_ERROR_INVALID_ADDR If the p_request pointer is invalid. + * @retval ::NRF_ERROR_INVALID_PARAM If the parameters of p_request are not valid. + * @retval ::NRF_SUCCESS Otherwise. + */ + SVCALL(SD_RADIO_REQUEST, uint32_t, sd_radio_request(nrf_radio_request_t const * p_request)); + +/**@brief Write register protected by the SoftDevice + * + * This function writes to a register that is write-protected by the SoftDevice. Please refer to your + * SoftDevice Specification for more details about which registers that are protected by SoftDevice. + * This function can write to the following protected peripheral: + * - ACL + * + * @note Protected registers may be read directly. + * @note Register that are write-once will return @ref NRF_SUCCESS on second set, even the value in + * the register has not changed. See the Product Specification for more details about register + * properties. + * + * @param[in] p_register Pointer to register to be written. + * @param[in] value Value to be written to the register. + * + * @retval ::NRF_ERROR_INVALID_ADDR This function can not write to the reguested register. + * @retval ::NRF_SUCCESS Value successfully written to register. + * + */ +SVCALL(SD_PROTECTED_REGISTER_WRITE, uint32_t, sd_protected_register_write(volatile uint32_t * p_register, uint32_t value)); + +/**@} */ + +#ifdef __cplusplus +} +#endif +#endif // NRF_SOC_H__ + +/**@} */ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_svc.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_svc.h new file mode 100644 index 00000000000..292c6929828 --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/nrf_svc.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_SVC__ +#define NRF_SVC__ + +#include "stdint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SVCALL_AS_NORMAL_FUNCTION +#define SVCALL(number, return_type, signature) return_type signature +#else + +#ifndef SVCALL +#if defined (__CC_ARM) +#define SVCALL(number, return_type, signature) return_type __svc(number) signature +#elif defined (__GNUC__) +#ifdef __cplusplus +#define GCC_CAST_CPP (uint16_t) +#else +#define GCC_CAST_CPP +#endif +#define SVCALL(number, return_type, signature) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ + __attribute__((naked)) \ + __attribute__((unused)) \ + static return_type signature \ + { \ + __asm( \ + "svc %0\n" \ + "bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \ + ); \ + } \ + _Pragma("GCC diagnostic pop") + +#elif defined (__ICCARM__) +#define PRAGMA(x) _Pragma(#x) +#define SVCALL(number, return_type, signature) \ +PRAGMA(swi_number = (number)) \ + __swi return_type signature; +#else +#define SVCALL(number, return_type, signature) return_type signature +#endif +#endif // SVCALL + +#endif // SVCALL_AS_NORMAL_FUNCTION + +#ifdef __cplusplus +} +#endif +#endif // NRF_SVC__ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_license-agreement.txt b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_license-agreement.txt new file mode 100644 index 00000000000..a71adee7b9b --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_license-agreement.txt @@ -0,0 +1,35 @@ +Copyright (c) 2007 - 2018, Nordic Semiconductor ASA +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, must reproduce the above copyright notice, this list of + conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + +3. Neither the name of Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_migration-document.pdf b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_migration-document.pdf new file mode 100644 index 00000000000..2093d0c1482 Binary files /dev/null and b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_migration-document.pdf differ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_release-notes.pdf b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_release-notes.pdf new file mode 100644 index 00000000000..fff6b2d1e24 Binary files /dev/null and b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_release-notes.pdf differ diff --git a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_softdevice.hex b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_softdevice.hex new file mode 100644 index 00000000000..8529afede25 --- /dev/null +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_softdevice.hex @@ -0,0 +1,9614 @@ +:020000040000FA +:1000000000040020990900002D0600007909000075 +:1000100037060000410600004B060000000000000B +:10002000000000000000000000000000BD0900000A +:1000300055060000000000005F0600006906000091 +:10004000730600007D060000870600009106000090 +:100050009B060000A5060000AF060000B9060000E0 +:10006000C3060000CD060000D7060000E106000030 +:10007000EB060000F5060000FF060000090700007F +:10008000130700001D0700002707000031070000CC +:100090003B070000450700004F070000590700001C +:1000A000630700006D07000077070000810700006C +:1000B0008B070000950700009F070000A9070000BC +:1000C000B3070000BD070000C7070000D10700000C +:1000D000DB070000E5070000EF070000F90700005C +:1000E000030800000D0800001708000021080000A8 +:1000F0002B080000350800003F08000049080000F8 +:10010000530800001FB500F003F88DE80F001FBD75 +:1001100000F038BC70B50B46010B184400F6FF70B8 +:10012000040B4FF080500022090303692403406947 +:1001300043431D1B104600F0E9F929462046BDE85F +:10014000704000F0E3B9F0B54FF6FF734FF4B475AB +:100150001A466E1E12E0A94201D3344600E00C4656 +:10016000B1EB040130F8027B641E3B441A44F9D120 +:100170009CB204EB134394B204EB12420029EAD17F +:1001800098B200EB134002EB124140EA0140F0BD8F +:10019000C34992B00446D1E90001CDE91001FF2224 +:1001A0004021684600F094FB94E80F008DE80F00B2 +:1001B000684610A902E004C841F8042D8842FAD12B +:1001C00010216846FFF7BFFF1090AA208DF8440069 +:1001D00000F0FAF800F0DDF84FF01024A0691022CA +:1001E0006946803000F0DEF8A069082210A900F00E +:1001F000D9F800F0C2F870B504460068A94D072888 +:1002000069D2DFE800F033041929561E2500D4E92D +:10021000026564682946304600F0FDF82A4621460A +:10022000304600F0BFF8AA002146304600F024FB1B +:10023000002800D0032070BD00F0D6FB4FF48050A2 +:1002400007E0201D00F0C6F80028F4D100F0CCFB38 +:1002500060682860002070BD241D94E807009200AB +:1002600000F00AFB0028F6D00E2070BD00F0BEF8AA +:100270000028FAD1D4E9010100EB81034FF080504E +:10028000026945696A43934209D84FF010225369C5 +:1002900003EB81030169406941438B4201D9092085 +:1002A00070BD5069401C01D10F2070BD2046FFF782 +:1002B0006FFF00F09BF80028F7D1201D00F08AF8AE +:1002C0000028F2D160680028F0D100F07DF800F03D +:1002D00060F800F052F8072070BD10B50C461828E1 +:1002E00002D00120086010BD2068FFF784FF206065 +:1002F00010BD4FF01024A069401C05D0A569A66967 +:1003000080353079AA2808D06069401C2DD06069FA +:100310000068401C29D060692CE010212846FFF7B6 +:1003200012FF316881421CD1A16901F18002C03104 +:1003300005E030B108CA51F8040D984201D10120FE +:1003400000E000208A42F4D158B1286810B1042896 +:1003500003D0FEE7284600F070F85249686808604C +:1003600008E000F016F800F008F84FF4805001683B +:10037000491C01D000F012FBFEE7BFF34F8F4A4843 +:1003800001684A4A01F4E06111430160BFF34F8FF5 +:10039000FEE74FF010208169491C02D0806900F00F +:1003A0008CB870472DE9F04117460D4606460024EB +:1003B00006E03046296800F093F8641C2D1D361DB8 +:1003C000BC42F6D3BDE8F0814FF0102080694FF4B5 +:1003D00080519FE64FF080510A69496900684A439D +:1003E000824201D810207047002070474FF08050A3 +:1003F0000169406941434FF01020826902F5805243 +:10040000914201D2092070478069401C01D0002030 +:1004100070470420704770B50C4605464FF480665F +:1004200008E0284600F049F8B44205D3A4F58064FA +:1004300005F58055002CF4D170BD4168044609B122 +:10044000012600E000264FF010256869A26892009E +:1004500000F012FAF8B1A06881006869FFF75AFE4F +:10046000BEB16E694FF08050A56864680169426949 +:100470005143A1420DD9016940694143A94208D9BC +:1004800029463046FFF7C7FF2A4621463046FFF788 +:1004900089FFFFF772FFFFF797FFFFF77AFFF8E793 +:1004A0000C0A0000000000200CED00E00400FA053A +:1004B000144801680029FCD07047134A02211160DA +:1004C00010490B68002BFCD00F4B1B1D18600868EF +:1004D0000028FCD00020106008680028FCD070477D +:1004E000094B10B501221A60064A1468002CFCD092 +:1004F000016010680028FCD00020186010680028F7 +:10050000FCD010BD00E4014004E5014070B50C468C +:10051000054600F073F810B900F07EF828B12146C6 +:100520002846BDE8704000F007B821462846BDE8DF +:10053000704000F037B800007FB5002200920192B1 +:10054000029203920A0B000B6946012302440AE05F +:10055000440900F01F0651F8245003FA06F635430B +:1005600041F82450401C8242F2D80D490868009A94 +:1005700010430860081D0168019A1143016000F0F2 +:100580003DF800280AD0064910310868029A104345 +:100590000860091D0868039A104308607FBD0000C9 +:1005A0000006004030B50F4C002200BF04EB0213E0 +:1005B000D3F800582DB9D3F8045815B9D3F8085812 +:1005C0001DB1521C082AF1D330BD082AFCD204EB1D +:1005D0000212C2F80008C3F804180220C3F8080881 +:1005E00030BD000000E001404FF08050D0F83001F5 +:1005F000082801D000207047012070474FF080503C +:10060000D0F83011062905D0D0F83001401C01D0B7 +:1006100000207047012070474FF08050D0F8300123 +:100620000A2801D0002070470120704708208F4918 +:1006300009680958084710208C4909680958084773 +:1006400014208A4909680958084718208749096809 +:100650000958084730208549096809580847382053 +:1006600082490968095808473C20804909680958A7 +:10067000084740207D4909680958084744207B49BC +:1006800009680958084748207849096809580847FF +:100690004C20764909680958084750207349096871 +:1006A00009580847542071490968095808475820D3 +:1006B0006E490968095808475C206C49096809585F +:1006C0000847602069490968095808476420674954 +:1006D00009680958084768206449096809580847A3 +:1006E0006C20624909680958084770205F49096809 +:1006F0000958084774205D49096809580847782057 +:100700005A490968095808477C2058490968095816 +:1007100008478020554909680958084784205349EB +:100720000968095808478820504909680958084746 +:100730008C204E4909680958084790204B490968A0 +:1007400009580847942049490968095808479820DA +:1007500046490968095808479C20444909680958CE +:100760000847A0204149096809580847A4203F4983 +:10077000096809580847A8203C49096809580847EA +:10078000AC203A49096809580847B0203749096838 +:1007900009580847B4203549096809580847B8205E +:1007A0003249096809580847BC2030490968095886 +:1007B0000847C0202D49096809580847C4202B491B +:1007C000096809580847C82028490968095808478E +:1007D000CC202649096809580847D02023490968D0 +:1007E00009580847D4202149096809580847D820E2 +:1007F0001E49096809580847DC201C49096809583E +:100800000847E0201949096809580847E4201749B2 +:10081000096809580847E820144909680958084731 +:10082000EC201249096809580847F0200F49096867 +:1008300009580847F4200D49096809580847F82065 +:100840000A49096809580847FC20084909680958F5 +:1008500008475FF480700549096809580847000097 +:1008600003480449024A034B70470000000000207F +:10087000180A0000180A000040EA010310B59B079F +:100880000FD1042A0DD310C808C9121F9C42F8D0FA +:1008900020BA19BA884201D9012010BD4FF0FF30AB +:1008A00010BD1AB1D30703D0521C07E0002010BDC1 +:1008B00010F8013B11F8014B1B1B07D110F8013B4D +:1008C00011F8014B1B1B01D1921EF1D1184610BD2E +:1008D00002F0FF0343EA032242EA024200F005B8B5 +:1008E0007047704770474FF000020429C0F0128033 +:1008F00010F0030C00F01B80CCF1040CBCF1020FD3 +:1009000018BF00F8012BA8BF20F8022BA1EB0C01A7 +:1009100000F00DB85FEAC17C24BF00F8012B00F89D +:10092000012B48BF00F8012B70474FF0000200B5C3 +:10093000134694469646203922BFA0E80C50A0E802 +:100940000C50B1F12001BFF4F7AF090728BFA0E8B0 +:100950000C5048BF0CC05DF804EB890028BF40F87C +:10096000042B08BF704748BF20F8022B11F0804FBE +:1009700018BF00F8012B7047014B1B68DB68184754 +:100980000000002009480A497047FFF7FBFFFFF706 +:10099000B9FB00BD20BFFDE7064B1847064A1060B3 +:1009A000016881F30888406800470000180A0000C9 +:1009B000180A0000F3020000000000201EF0040FDF +:1009C0000CBFEFF30881EFF30981886902380078E2 +:1009D000182803D100E00000074A1047074A1268B0 +:1009E0002C3212681047000000B5054B1B68054A01 +:1009F0009B58984700BD0000DB020000000000206B +:100A0000080A0000040000000010000000000000C0 +:080A100000FFFFFF0090D0037E +:10100000801300204958020045C00000AF5702007D +:1010100045C0000045C0000045C0000000000000C1 +:10102000000000000000000000000000A5580200C1 +:1010300045C000000000000045C0000045C00000A1 +:101040000D5902001359020045C0000045C00000C0 +:1010500045C0000045C0000045C0000045C000007C +:101060001959020045C0000045C000001F59020088 +:1010700045C00000255902002B59020031590200D9 +:1010800045C0000045C0000045C0000045C000004C +:1010900045C0000045C0000045C0000045C000003C +:1010A00045C000003759020045C0000045C000009F +:1010B00045C0000045C0000045C0000045C000001C +:1010C0003D59020045C0000045C0000045C0000079 +:1010D00045C0000045C0000045C0000045C00000FC +:1010E00045C0000045C0000045C0000045C00000EC +:1010F00045C0000045C0000045C0000045C00000DC +:1011000045C0000045C0000000F002F824F08BFB51 +:101110000AA090E8000C82448344AAF10107DA4552 +:1011200001D124F080FBAFF2090EBAE80F0013F0F2 +:10113000010F18BFFB1A43F001031847EC4C0200E3 +:101140000C4D02000A444FF0000C10F8013B13F064 +:10115000070408BF10F8014B1D1108BF10F8015B10 +:10116000641E05D010F8016B641E01F8016BF9D103 +:1011700013F0080F1EBF10F8014BAD1C0C1B09D15A +:101180006D1E58BF01F801CBFAD505E014F8016BCC +:1011900001F8016B6D1EF9D59142D6D3704700005E +:1011A0000023002400250026103A28BF78C1FBD870 +:1011B000520728BF30C148BF0B6070471FB500F011 +:1011C0003DF88DE80F001FBD1EF0040F0CBFEFF3BC +:1011D0000880EFF30980014A1047000087BF000034 +:1011E000F0B44046494652465B460FB402A0013077 +:1011F00001B50648004700BF01BC86460FBC8046CB +:10120000894692469B46F0BC7047000009110000D9 +:101210008269034981614FF001001044704700006A +:101220002512000001B41EB400B514F08DFE01B407 +:101230000198864601BC01B01EBD000024F0F0BA42 +:1012400070B51A4C054609202070A01C00F0D1F89A +:101250005920A08029462046BDE8704008F0BAB861 +:1012600008F0C3B870B50C461149097829B1A0F14E +:1012700060015E2908D3012013E0602804D06928AA +:1012800002D043F201000CE020CC0A4E94E80E009C +:1012900006EB8000A0F58050241FD0F8806E284611 +:1012A000B047206070BD012070470000080000209A +:1012B00018000020885902003249884201D20120DA +:1012C00070470020704770B50446A0F500002E4E10 +:1012D000B0F1786F02D23444A4F500042948844266 +:1012E00001D2012500E0002500F043F848B125B9FE +:1012F000B44204D32548006808E0012070BD0020F6 +:1013000070BD002DF9D1B442F9D321488442F6D200 +:10131000F3E710B50446A0F50000B0F1786F03D2F2 +:1013200019480444A4F5000400F023F84FF080416C +:1013300030B11648006804E08C4204D2012003E07A +:1013400013488442F8D2002080F0010010BD10B58F +:1013500020B1FFF7DEFF08B1012010BD002010BD55 +:1013600010B520B1FFF7AFFF08B1012010BD00207C +:1013700010BD084808490068884201D10120704723 +:101380000020704700600200000000201C000020C8 +:101390000800002054000020BEBAFECA10B5044662 +:1013A0000021012000F03DF800210B2000F039F869 +:1013B0000421192000F035F804210D2000F031F847 +:1013C00004210E2000F02DF804210F2000F029F850 +:1013D0000421C84300F025F80621162000F021F86A +:1013E0000621152000F01DF82046FFF729FF0020F8 +:1013F00010BDAE2101807047FFF732BF1148704722 +:1014000010487047104A10B514680F4B0F4A083344 +:101410001A60FFF727FF0C48001D046010BD7047DD +:1014200070474907090E002804DB00F1E02080F82E +:101430000014704700F00F0000F1E02080F8141D48 +:101440007047000003F9004210050240010000014E +:10145000FE48002101604160018170472DE9F7439A +:10146000044692B091464068FFF771FF40B1606852 +:10147000FFF776FF20B9607800F00300022801D062 +:10148000012000E00020F14E30724846FFF71BFFBC +:1014900018B1102015B0BDE8F0834946012001F0D5 +:1014A0008EFE0028F6D101258DF842504FF4C05031 +:1014B000ADF84000002210A9284606F001FC0028E3 +:1014C000E8D18DF842504FF428504FF00008ADF8A5 +:1014D000400047461C216846CDF81C8024F03BF9AB +:1014E0009DF81C0008AA20F00F00401C20F0F0001E +:1014F00010308DF81C0020788DF81D0061789DF863 +:101500001E0061F3420040F001008DF81E009DF8BE +:1015100000000AA940F002008DF800002089ADF813 +:101520003000ADF83270608907AFADF834000B972A +:10153000606810AC0E900A94684606F0B4F9002872 +:10154000A8D1BDF8200030808DF8425042F601202D +:10155000ADF840009DF81E0008AA20F00600801C8F +:1015600020F001008DF81E000220ADF83000ADF82B +:10157000340013A80E900AA9684606F094F90028D2 +:1015800088D1BDF820007080311D484600F033F945 +:10159000002887D18DF8425042F6A620ADF84000D1 +:1015A0001C216846CDF81C8024F0D5F89DF81C005D +:1015B000ADF8345020F00F00401C20F0F000103047 +:1015C0008DF81C009DF81D0008AA20F0FF008DF882 +:1015D0001D009DF81E000AA920F0060040F0010041 +:1015E000801C8DF81E009DF800008DF8445040F0DE +:1015F00002008DF80000CDE90A4711A80E90ADF861 +:101600003050684606F04FF9002899D1BDF8200007 +:10161000F08000203EE73EB504460820ADF800000B +:101620002046FFF750FE08B110203EBD21460120A4 +:1016300001F0C5FD0028F8D12088ADF804006088CD +:10164000ADF80600A088ADF80800E088ADF80A0003 +:101650007E4801AB6A468088002106F02DFDBDF86A +:1016600000100829E1D003203EBD1FB5044600202C +:1016700002900820ADF80800CDF80CD02046FFF706 +:1016800022FE10B1102004B010BD704802AA81885B +:101690004FF6FF7006F052FF0028F4D1BDF8081095 +:1016A000082901D00320EEE7BDF800102180BDF825 +:1016B00002106180BDF80410A180BDF80610E18021 +:1016C000E1E701B582B00220ADF800005F4802AB4F +:1016D0006A464088002106F0EFFCBDF800100229A0 +:1016E00000D003200EBD1CB5002100910221ADF8F1 +:1016F00000100190FFF70DFE08B110201CBD5348EB +:101700006A4641884FF6FF7006F018FFBDF80010DA +:101710000229F3D003201CBDFEB54C4C06461546ED +:10172000207A0F46C00705D00846FFF7CCFD18B158 +:101730001020FEBD0F20FEBDF82D01D90C20FEBDEE +:101740003046FFF7C0FD18BB208801A905F0B0FDA9 +:101750000028F4D130788DF80500208801A906F022 +:1017600089FC0028EBD100909DF800009DF8051041 +:1017700040F002008DF80000090703D040F0080097 +:101780008DF800002088694606F011FC0028D6D1AB +:10179000ADF8085020883B4602AA002106F08CFCD8 +:1017A000BDF80810A942CAD00320FEBD7CB505468D +:1017B0000020009001900888ADF800000C462846F3 +:1017C0000195FFF7C4FD18B92046FFF7A2FD08B147 +:1017D00010207CBD15B1BDF8000050B11B486A4611 +:1017E00001884FF6FF7006F0A9FEBDF800102180B9 +:1017F0007CBD0C207CBD30B593B0044600200D4666 +:101800000090142101A823F0A6FF1C2108A823F0B2 +:10181000A2FF9DF80000CDF808D020F00F00401C7A +:1018200020F0F00010308DF800009DF8010020F04D +:10183000FF008DF801009DF8200040F002008DF8B7 +:10184000200001208DF8460002E000001C0200206C +:1018500042F60420ADF8440011A801902088ADF8AC +:101860003C006088ADF83E00A088ADF84000E088FC +:10187000ADF842009DF8020006AA20F00600801C88 +:1018800020F001008DF802000820ADF80C00ADF842 +:1018900010000FA8059001A908A806F004F8002878 +:1018A00003D1BDF818002880002013B030BD00001F +:1018B000F0B5007B059F1E4614460D46012800D05A +:1018C000FFDF0C2030803A203880002C08D0287AA6 +:1018D000032806D0287B012800D0FFDF1720608175 +:1018E000F0BDA889FBE72DE9F04786B0144691F8D2 +:1018F0000C900E9A0D46B9F1010F0BD01021007B10 +:101900002E8A8846052807D0062833D0FFDF06B088 +:10191000BDE8F0870221F2E7E8890C2100EB4000E6 +:1019200001EB4000188033201080002CEFD0E889B4 +:10193000608100271AE00096688808F1020301AA76 +:10194000696900F084FF06EB0800801C07EB470183 +:1019500086B204EB4102BDF8040090810DF106014E +:1019600040460E3212F09DFD7F1CBFB26089B84226 +:10197000E1D8CCE734201080E889B9F1010F11D00B +:10198000122148430E301880002CC0D0E8896081B5 +:101990004846B9F1010F00D00220207300270DF155 +:1019A000040A1FE00621ECE70096688808F10203AC +:1019B00001AA696900F04BFF06EB0800801C86B2A3 +:1019C000B9F1010F12D007EBC70004EB4000BDF8DE +:1019D0000410C18110220AF10201103023F01AFE16 +:1019E0007F1CBFB26089B842DED890E707EB4701A1 +:1019F00004EB4102BDF80400D0810AF10201404627 +:101A0000103212F04EFDEBE72DE9F0470E4688B09C +:101A100090F80CC096F80C80378AF5890C20109944 +:101A200002F10C044FF0000ABCF1030F08D0BCF126 +:101A3000040F3ED0BCF1070F7DD0FFDF08B067E791 +:101A400005EB850C00EB4C00188031200880002A43 +:101A5000F4D0A8F1060000F0FF09558125E0182117 +:101A600001A823F078FE00977088434601AA7169A7 +:101A700000F0EDFEBDF804002080BDF80600E08017 +:101A8000BDF808002081A21C0DF10A01484612F0A1 +:101A900008FDB9F1000F00D018B184F804A0A4F833 +:101AA00002A007EB080087B20A346D1EADB2D6D291 +:101AB000C4E705EB850C00EB4C0018803220088051 +:101AC000002ABBD0A8F1050000F0FF09558137E0DE +:101AD00000977088434601AA716900F0B8FE9DF82E +:101AE0000600BDF80410E1802179420860F300018E +:101AF00062F34101820862F38201C20862F3C3010A +:101B0000020962F30411420962F34511820962F38A +:101B100086112171C0096071BDF80700208122463D +:101B20000DF10901484612F0BCFC18B184F802A07E +:101B3000A4F800A000E007E007EB080087B20A3431 +:101B40006D1EADB2C4D279E7A8F1020084B205FBE4 +:101B500008F000F10E0CA3F800C035230B80002A1A +:101B6000A6D055819481009783B270880E32716936 +:101B700000F06DFE62E72DE9F84F1E460A9D0C4607 +:101B800081462AB1607A00F58070D080E0891081AA +:101B900099F80C000C274FF000084FF00E0A0D28A2 +:101BA00073D2DFE800F09E070E1C28303846556AD5 +:101BB00073737300214648460095FFF779FEBDE830 +:101BC000F88F207B9146082802D0032800D0FFDF41 +:101BD000378030200AE000BFA9F80A80EFE7207BB9 +:101BE0009146042800D0FFDF378031202880B9F1EA +:101BF000000FF1D1E3E7207B9146042800D0FFDFFE +:101C000037803220F2E7207B9146022800D0FFDFA8 +:101C100037803320EAE7207B1746022800D0FFDF19 +:101C20003420A6F800A02880002FC8D0A7F80A808A +:101C3000C5E7207B1746042800D0FFDF3520A6F833 +:101C400000A02880002FBAD04046A7F80A8012E0F2 +:101C5000207B1746052802D0062800D0FFDF102081 +:101C6000308036202880002FA9D0E0897881A7F81D +:101C70000E80B9F80E00B881A1E7207B91460728B5 +:101C800000D0FFDF37803720B0E72AE04FF01200A6 +:101C900018804FF038001700288090D0E0897881B4 +:101CA000A7F80E80A7F8108099F80C000A2805D034 +:101CB0000B2809D00C280DD0FFDF80E7207B0A28F5 +:101CC00000D0FFDF01200AE0207B0B2800D0FFDFDF +:101CD000042004E0207B0C2800D0FFDF05203873AF +:101CE0006DE7FFDF6BE770B50C46054601F0ABFB17 +:101CF00020B10078222804D2082070BD43F20200EF +:101D000070BD0521284610F03FFE206008B100207C +:101D100070BD032070BD30B44880087820F00F00FB +:101D2000C01C20F0F000903001F8080B1DCA81E8BB +:101D30001D0030BC07F0CFBB2DE9FF4784B0002762 +:101D40008246029707989046894612300AF0CAF9EF +:101D5000401D20F00306079828B907A95046FFF751 +:101D6000C2FF002854D1B9F1000F05D00798017BBC +:101D700019BB052504681BE098F80000092803D06A +:101D80000D2812D0FFDF46E0079903254868B0B35D +:101D9000497B42887143914239D98AB2B3B2011D5D +:101DA00010F065FC0446078002E0079C0425083417 +:101DB0000CB1208810B1032D29D02CE00798012107 +:101DC00012300AF0C1F9ADF80C00024602AB294608 +:101DD000504608F0EEF9070001D1A01C02900798C8 +:101DE0003A461230C8F80400A8F802A003A94046F9 +:101DF000029B0AF0B6F9D8B10A2817D200E006E033 +:101E0000DFE800F007091414100B0D14141213204E +:101E100014E6002012E6112010E608200EE643F238 +:101E200003000BE6072009E60D2007E6032005E680 +:101E3000BDF80C002346CDE900702A4650460799AC +:101E400000F015FD57B9032D08D10798B3B2417BB7 +:101E5000406871438AB2011D10F01DFCB9F1000FFA +:101E6000D7D0079981F80C90D3E72DE9FE4F914622 +:101E70001A881C468A468046FAB102AB494608F0E9 +:101E800098F9050019D04046A61C278810F0C0FE1E +:101E90003246072629463B46009610F0CEFA2088A7 +:101EA0002346CDE900504A465146404600F0DFFC4B +:101EB000002020800120BDE8FE8F0020FBE710B548 +:101EC00086B01C46AAB104238DF800301388ADF803 +:101ED00008305288ADF80A208A788DF80E200988DB +:101EE000ADF80C1000236A462146FFF725FF06B027 +:101EF00010BD1020FBE770B50D46052110F044FD24 +:101F0000040000D1FFDF294604F11200BDE8704053 +:101F10000AF003B92DE9F8430D468046002607F084 +:101F2000D7FA04462878102878D2DFE800F0773B0B +:101F30003453313112313131083131313131287975 +:101F4000001FC0B2022801D0102810D114BBFFDF3F +:101F500035E004B9FFDF0521404610F015FD007B98 +:101F6000032806D004280BD0072828D0FFDF072637 +:101F700055E02879801FC0B2022820D050B1F6E782 +:101F80002879401FC0B2022819D0102817D0EEE7D8 +:101F900004B9FFDF13E004B9FFDF287901280ED16F +:101FA000172137E00521404610F0EEFC070000D174 +:101FB000FFDF07F1120140460AF08CF82CB12A46E7 +:101FC00021464046FFF7A7FE29E01321404602F0D4 +:101FD000F7FC24E004B9FFDF0521404610F0D4FCF3 +:101FE000060000D1FFDF694606F112000AF07CF816 +:101FF000060000D0FFDFA988172901D2172200E0D0 +:102000000A46BDF80000824202D9014602E005E01E +:102010001729C5D3404600F03AFCD0E7FFDF304631 +:10202000BDE8F883401D20F0030219B102FB01F066 +:10203000001D00E000201044704713B5009848B11F +:102040000024684610F0BDFA002C02D1F74A00992E +:1020500011601CBD01240020F4E72DE9F0470C4677 +:1020600015462421204623F076FB05B9FFDFA8782A +:1020700060732888DFF8B4A3401D20F00301AF7817 +:102080008946DAF8000010F0BAFA060000D1FFDF46 +:102090004FF000082660A6F8008077B109FB07F131 +:1020A000091D0AD0DAF8000010F0A9FA060000D1E4 +:1020B000FFDF6660C6F8008001E0C4F8048029886C +:1020C00004F11200BDE8F04709F0F6BF2DE9F04732 +:1020D000804601F112000D4681460AF003F8401DCA +:1020E000D24F20F003026E7B14462968386810F046 +:1020F000B1FA3EB104FB06F2121D03D069683868DC +:1021000010F0A8FA052010F0E7FB0446052010F0B7 +:10211000EBFB201A012802D1386810F065FA494615 +:102120004046BDE8F04709F0DCBF70B50546052123 +:1021300010F02AFC040000D1FFDF04F11201284650 +:10214000BDE8704009F0C6BF2DE9F04F91B04FF0E7 +:10215000000BADF834B0ADF804B047880C46054626 +:1021600092460521384610F00FFC060000D1FFDF33 +:1021700024B1A780A4F806B0A4F808B029780922F1 +:102180000B20B2EB111F7DD12A7A04F11001382700 +:102190004FF00C084FF001090391102A73D2DFE8C9 +:1021A00002F072F2F1F07F08D2888D9F3DDBF3EEF2 +:1021B000B6B6307B022800D0FFDFA88908EBC0014B +:1021C000ADF804103021ADF83410002C25D060811A +:1021D000B5F80E9000271DE004EBC708317C88F8A5 +:1021E0000E10F189A8F80C10CDF80090688804232F +:1021F00004AA296900F02BFBBDF81010A8F81010F4 +:1022000009F10400BDF812107F1C1FFA80F9A8F82C +:102210001210BFB26089B842DED80DE1307B0228CF +:1022200000D0FFDFE98908EBC100ADF804003020E1 +:10223000ADF83400287B0A90001FC0B20F90002C2C +:10224000EBD06181B5F81090002725E0CDF8009023 +:102250006888696903AA0A9B00F0F9FA0A9804EBF6 +:10226000C70848441FFA80F908F10C0204A90F9826 +:1022700012F017F918B188F80EB0A8F80CB0BDF834 +:102280000C1001E0D4E0CFE0A8F81010BDF80E105B +:102290007F1CA8F81210BFB26089B842D6D8CBE034 +:1022A0000DA8009001AB224629463046FFF71BFBE4 +:1022B000C2E0307B082805D0FFDF03E0307B082830 +:1022C00000D0FFDFE8891030ADF804003620ADF80B +:1022D0003400002C3FD0A9896181F189A18127E0D8 +:1022E000307B092800D0FFDFA88900F10C01ADF890 +:1022F00004103721ADF83410002C2CD06081E8890F +:102300000090AB89688804F10C02296956E0E889DD +:102310003921103080B2ADF80400ADF83410002C33 +:1023200074D0A9896181287A0E280AD002212173EC +:10233000E989E181288A0090EB8968886969039AB4 +:102340003CE00121F3E70DA8009001AB22462946AD +:102350003046FFF759FB6FE0307B0A2800D0FFDFE3 +:102360001220ADF80400ADF834704CB3A989618136 +:10237000A4F810B0A4F80EB084F80C905CE020E053 +:1023800002E031E039E042E0307B0B2800D0FFDF93 +:10239000288AADF834701230ADF8040084B10421FD +:1023A0002173A9896181E989E181298A2182688A69 +:1023B00000902B8A688804F11202696900F047FADC +:1023C0003AE0307B0C2800D0FFDF1220ADF804008B +:1023D000ADF834703CB305212173A4F80AB0A4F819 +:1023E0000EB0A4F810B027E00DA8009001AB224673 +:1023F00029463046FFF75CFA1EE00DA8009001ABBD +:10240000224629463046FFF7B6FB15E034E03B2173 +:10241000ADF80400ADF8341074B3A4F80690A4F835 +:1024200008B084F80AB007E0FFDF05E010000020E4 +:10243000297A012917D0FFDFBDF80400AAF80000AF +:102440006CB1BDF834002080BDF804006080BDF898 +:102450003400392803D03C2801D086F80CB011B0E4 +:102460000020BDE8F08F3C21ADF80400ADF8341039 +:1024700014B1697AA172DFE7AAF80000EFE72DE94D +:10248000F84356880F46804615460521304610F021 +:102490007BFA040000D1FFDF123400943B46414632 +:1024A00030466A6809F091FFBAE570B50D4605211E +:1024B00010F06AFA040000D1FFDF294604F112008F +:1024C000BDE8704009F01BBE70B50D46052110F047 +:1024D0005BFA040000D1FFDF294604F11200BDE8D9 +:1024E000704009F039BE70B50546052110F04CFA70 +:1024F000040000D1FFDF04F1080321462846BDE8AF +:1025000070400422B1E470B50546052110F03CFA94 +:10251000040000D1FFDF214628462368BDE8704053 +:102520000522A2E470B50646052110F02DFA04003C +:1025300000D1FFDF04F1120009F0D4FD401D20F0AE +:10254000030511E0011D008803224318214630468F +:10255000FFF78BFC00280BD0607BABB2684382B2E4 +:102560006068011D10F0CDF8606841880029E9D14C +:1025700070BD70B50E46054606F0AAFF040000D1F6 +:10258000FFDF0120207266726580207820F00F0046 +:10259000C01C20F0F00030302070BDE8704006F024 +:1025A0009ABF2DE9F0438BB00D461446814606A92B +:1025B000FFF799FB002814D14FF6FF7601274FF45F +:1025C00020588CB103208DF800001020ADF81000C9 +:1025D00007A8059007AA204604A911F081FF78B149 +:1025E00007200BB0BDE8F0830820ADF808508DF847 +:1025F0000E708DF80000ADF80A60ADF80C800CE0AC +:102600000698A17801742188C1818DF80E70ADF80B +:102610000850ADF80C80ADF80A606A4602214846C1 +:10262000069BFFF789FBDCE708B501228DF8022045 +:1026300042F60202ADF800200A4603236946FFF77E +:102640003EFC08BD08B501228DF8022042F60302C7 +:10265000ADF800200A4604236946FFF730FC08BDA8 +:1026600000B587B079B102228DF800200A88ADF854 +:1026700008204988ADF80A1000236A460521FFF7B3 +:102680005BFB07B000BD1020FBE709B1072316E490 +:102690000720704770B588B00D461446064606A957 +:1026A000FFF721FB00280ED17CB10620ADF80850C1 +:1026B0008DF80000ADF80A40069B6A460821DC81CF +:1026C0003046FFF739FB08B070BD05208DF80000DB +:1026D000ADF80850F0E700B587B059B107238DF881 +:1026E0000030ADF80820039100236A460921FFF766 +:1026F00023FBC6E71020C4E770B588B00C46064639 +:10270000002506A9FFF7EFFA0028DCD10698012181 +:10271000123009F019FD9CB12178062921D2DFE899 +:1027200001F0200505160318801E80B2C01EE28845 +:1027300080B20AB1A3681BB1824203D90C20C2E760 +:102740001020C0E7042904D0A08850B901E0062079 +:10275000B9E7012913D0022905D004291CD0052985 +:102760002AD00720AFE709208DF800006088ADF877 +:102770000800E088ADF80A00A068039023E00A2072 +:102780008DF800006088ADF80800E088ADF80A0018 +:10279000A0680A25039016E00B208DF800006088E1 +:1027A000ADF80800A088ADF80A00E088ADF80C008C +:1027B000A0680B25049006E00C208DF800006078DE +:1027C0008DF808000C256A4629463046069BFFF71F +:1027D000B3FA78E700B587B00D228DF80020ADF888 +:1027E000081000236A461946FFF7A6FA49E700B524 +:1027F00087B071B102228DF800200A88ADF8082058 +:102800004988ADF80A1000236A460621FFF794FABA +:1028100037E7102035E770B586B0064601200D4633 +:10282000ADF808108DF80000014600236A463046D6 +:10283000FFF782FA040008D12946304605F056FC1D +:102840000021304605F070FC204606B070BDF8B59A +:102850001C4615460E46069F10F0C8F92346FF1D7C +:10286000BCB231462A4600940FF0B3FDF8BD30B437 +:102870001146DDE902423CB1032903D0002330BCFC +:1028800008F022BB0123FAE71A8030BC704770B50C +:102890000C460546FFF72FFB2146284605F035FC80 +:1028A0002846BDE87040012105F03EBC4FF0E02213 +:1028B0004FF400400021C2F88001BFF34F8FBFF3F7 +:1028C0006F8F1748016001601649900208607047D9 +:1028D000134900B500220A600A60124B4FF0607283 +:1028E0001A60002808BF00BD0F4A104BDFF840C037 +:1028F00001280CD002281CBFFFDF00BD03200860A8 +:102900001A604FF4000000BFCCF8000000BD0220A8 +:1029100008601A604FF04070F6E700B5FFDF00BDB9 +:1029200000F5004008F501409C02002014F500402D +:1029300004F5014070B50B2000F0BDF9082000F04F +:10294000BAF900210B2000F0D4F90021082000F092 +:10295000D0F9F44C01256560A5600020C4F8400161 +:10296000C4F84401C4F848010B2000F0B5F9082070 +:1029700000F0B2F90B2000F091F9256070BD10B5A0 +:102980000B2000F098F9082000F095F9E5480121A6 +:1029900041608160E4490A68002AFCD10021C0F846 +:1029A0004011C0F84411C0F848110B2000F094F910 +:1029B000BDE81040082000F08FB910B50B2000F0E2 +:1029C0008BF9BDE81040082000F086B900B530B1A1 +:1029D000012806D0022806D0FFDF002000BDD34822 +:1029E00000BDD34800BDD248001D00BD70B5D1491F +:1029F0004FF000400860D04DC00BC5F80803CF4829 +:102A000000240460C5F840410820C43500F053F9A3 +:102A1000C5F83C41CA48047070BD08B5C14A0021E0 +:102A200028B1012811D002281CD0FFDF08BD4FF4C7 +:102A30008030C2F80803C2F84803BB483C3001604C +:102A4000C2F84011BDE80840D0E74FF40030C2F8AA +:102A50000803C2F84803B44840300160C2F844118A +:102A6000B3480CE04FF48020C2F80803C2F84803D2 +:102A7000AD4844300160C2F84811AD48001D0068FF +:102A8000009008BD70B516460D460446022800D9D0 +:102A9000FFDF0022A348012304F110018B4000EB6B +:102AA0008401C1F8405526B1C1F84021C0F8043373 +:102AB00003E0C0F80833C1F84021C0F8443370BDCA +:102AC0002DE9F0411D46144630B1012833D00228CB +:102AD00038D0FFDFBDE8F081891E002221F07F4160 +:102AE0001046FFF7CFFF012D23D00020944D924FC9 +:102AF000012668703E61914900203C39086002203F +:102B0000091D08608D490420303908608B483D3428 +:102B1000046008206C6000F0DFF83004C7F804039C +:102B2000082000F0BBF88349F007091F08602E70E9 +:102B3000D0E70120DAE7012B02D00022012005E0D6 +:102B40000122FBE7012B04D000220220BDE8F04166 +:102B500098E70122F9E774480068704770B500F003 +:102B6000D8F8704C0546D4F840010026012809D158 +:102B7000D4F80803C00305D54FF48030C4F8080327 +:102B8000C4F84061D4F8440101280CD1D4F80803FA +:102B9000800308D54FF40030C4F80803C4F844613A +:102BA000012012F06AFCD4F8480101280CD1D4F8B5 +:102BB0000803400308D54FF48020C4F80803C4F884 +:102BC0004861022012F059FC5E48056070BD70B586 +:102BD00000F09FF85A4D0446287850B1FFF706FFE1 +:102BE000687818B10020687012F047FC55480460FE +:102BF00070BD0320F8E74FF0E0214FF40010C1F85A +:102C000000027047152000F067B84B4901200861A9 +:102C1000082000F061B848494FF47C10C1F808035F +:102C20000020024601EB8003C3F84025C3F8402191 +:102C3000401CC0B20628F5D37047410A43F609523A +:102C40005143C0F3080010FB02F000F5807001EB67 +:102C50005020704710B5430B48F2376463431B0C98 +:102C60005C020C60384C03FB0400384B4CF2F72438 +:102C700043435B0D13FB04F404EB402000F580702C +:102C80004012107008681844086010BD2C48406855 +:102C9000704729490120C1F800027047002809DB6C +:102CA00000F01F02012191404009800000F1E02066 +:102CB000C0F80011704700280DDB00F01F02012151 +:102CC00091404009800000F1E020C0F88011BFF37E +:102CD0004F8FBFF36F8F7047002809DB00F01F0292 +:102CE000012191404009800000F1E020C0F88012ED +:102CF00070474907090E002804DB00F1E02080F846 +:102D00000014704700F00F0000F1E02080F8141D5F +:102D100070470C48001F00680A4A0D49121D1160D7 +:102D20007047000000B0004004B500404081004002 +:102D300044B1004008F5014000800040408500405B +:102D40003400002014050240F7C2FFFF6F0C0100A1 +:102D5000010000010A4810B5046809490948083112 +:102D6000086012F01EFC0648001D046010BD0649F4 +:102D7000002008604FF0E0210220C1F88002704777 +:102D80001005024001000001FC1F004010B50D209D +:102D900000F077F8C4B26FF0040000F072F8C0B22F +:102DA000844200D0FFDF3E490120086010BD70B5AD +:102DB0000D2000F048F83B4C0020C4F8000101252C +:102DC000C4F804530D2000F04FF825604FF0E021C7 +:102DD0006014C1F8000170BD10B50D2000F033F88B +:102DE0003048012141600021C0F80011BDE81040C9 +:102DF0000D2000F039B82C4810B504682A492B483A +:102E0000083108602749D1F80001012804D0FFDF0C +:102E10002548001D046010BD2148001D00680022E7 +:102E2000C0B2C1F8002113F009F8F1E710B51D4850 +:102E3000D0F800110029FBD0FFF7DDFFBDE81040FE +:102E40000D2000F011B800280DDB00F01F02012159 +:102E500091404009800000F1E020C0F88011BFF3EC +:102E60004F8FBFF36F8F7047002809DB00F01F0200 +:102E7000012191404009800000F1E020C0F880125B +:102E80007047002804DB00F1E02090F8000405E022 +:102E900000F00F0000F1E02090F8140D4009704799 +:102EA00004D5004000D000401005024001000001A0 +:102EB0004FF0E0214FF00070C1F8800101F5C071C2 +:102EC000BFF34F8FBFF36F8FC1F80001384B8022E3 +:102ED00083F8002441F8800C704700B502460420B6 +:102EE000344903E001EBC0031B792BB1401EC0B293 +:102EF000F8D2FFDFFF2000BD41F8302001EBC00118 +:102F000000224A718A7101220A7100BD294A0021FA +:102F100002EBC0000171704710B50446042800D3CD +:102F2000FFDF244800EBC4042079012800D0FFDF34 +:102F30006079A179401CC0B2814200D060714FF02D +:102F4000E0214FF00070C1F8000210BD2DE9F04102 +:102F500019480568184919480831086014480426BA +:102F600090F80004134F4009154C042818D0FFDFD7 +:102F700016E0217807EBC1000279012A08D14279D5 +:102F800083799A4204D04279827157F831008047A0 +:102F90002078401CC0B22070042801D3002020708B +:102FA000761EF6B2E5D20448001D0560BDE8F0814A +:102FB00019E000E0D40500201005024001000001E6 +:102FC000500000200548064A0168914201D10021C5 +:102FD000016004490120086070470000540000208F +:102FE000BEBAFECA40E5014070B50C46054609F080 +:102FF00089FB21462846BDE870400AF06EBC704748 +:103000002CFFFFFFDBE5B15100600200AE00FFFFC7 +:103010008C00000068915B008308DF2FACFED6397E +:1030200029D64B9DC15EF1868A16B47C30B5F84D29 +:103030000446062CA9780ED2DFE804F0030E0E0E2B +:103040000509FFDF08E0022906D0FFDF04E00329BD +:1030500002D0FFDF00E0FFDFAC7030BD30B50446CA +:103060001038EB4D07280CD2DFE800F0040C060CFA +:103070000C0C0C00FFDF05E0287E112802D0FFDFDA +:1030800000E0FFDF2C7630BD2DE9F04111F092FB1E +:10309000044612F063FD201AC5B206200FF01CFC96 +:1030A000044606200FF020FC211AD94C207E12285D +:1030B00018D000200F1807200FF00EFC064607203E +:1030C0000FF012FC301A3918207E13280CD0002083 +:1030D0000144A078042809D000200844281AC0B26E +:1030E000BDE8F0810120E5E70120F1E70120F4E7E8 +:1030F000C74810B590F825004108C54800F12600E2 +:1031000005D00DF006FBBDE8104006F003B80DF049 +:10311000E1FAF8E730B50446A1F120000D460A288F +:103120004AD2DFE800F005070C1C2328353A3F445B +:10313000FFDF42E0207820283FD1FFDF3DE0B448A8 +:103140008178052939D0007E122836D020782428AD +:1031500033D0252831D023282FD0FFDF2DE0207851 +:1031600022282AD0232828D8FFDF26E0207822280A +:1031700023D0FFDF21E0207822281ED024281CD075 +:1031800026281AD0272818D0292816D0FFDF14E0C7 +:103190002078252811D0FFDF0FE0207825280CD0DB +:1031A000FFDF0AE02078252807D0FFDF05E0207840 +:1031B000282802D0FFDF00E0FFDF257030BD1FB5FB +:1031C00004466A46002001F035FEB4B1BDF8022085 +:1031D0004FF6FF700621824201D1ADF80210BDF812 +:1031E0000420824201D1ADF80410BDF808108142DC +:1031F00003D14FF44860ADF8080068460EF0EBF8D4 +:1032000005F088FF04B010BD70B514460D460646A3 +:10321000FEF759F858B90DB1A54201D90C2070BD7F +:10322000002408E056F82400FEF74DF808B11020FD +:1032300070BD641CE4B2AC42F4D3002070BD2DE933 +:10324000F04105461F4690460E4600240068FEF7F2 +:1032500087F830B9A98828680844401EFEF780F82E +:1032600008B110203CE728680028A88802D0B8429E +:1032700002D850E00028F5D0092031E72968085D20 +:10328000B8B1671CCA5D152A2ED03CDC152A3AD28B +:10329000DFE802F03912222228282A2A313139396E +:1032A00039393939393939392200085D30BB641C64 +:1032B000A4B2A242F9D833E00228DDD1A01C085CF8 +:1032C00088F80000072801D2400701D40A2007E748 +:1032D000307840F0010015E0C143C90707E001283C +:1032E00007D010E00620FBE60107A1F1805100297C +:1032F000F5D01846F4E63078810701D50B20EFE6CB +:1033000040F0020030702868005D384484B2A8881C +:10331000A04202D2B0E74FF4485382B2A242ADD8E5 +:103320000020DDE610B5027843F2022354080122A2 +:10333000022C12D003DC3CB1012C16D106E0032C88 +:1033400010D07F2C11D112E0002011E080790324ED +:10335000B4EB901F09D10A700BE08079B2EB901F9B +:1033600003D1F8E780798009F5D0184610BDFF2019 +:103370000870002010BD08B500208DF8000024481A +:1033800090F82E1049B190F82F0002280ED0032893 +:103390000ED0FFDF9DF8000008BD1D4869462530AE +:1033A00001F097FD0028F5D0FFDFF3E7032000E0F0 +:1033B00001208DF80000EDE738B50C46054669465A +:1033C00001F087FD00280DD19DF80010207861F3F1 +:1033D0004700207055F8010FC4F80100A888A4F830 +:1033E0000500002038BD38B51378A8B1022813D0E5 +:1033F000FF281AD007A46D46246800944C7905EB89 +:103400009414247864F347031370032809D00FE061 +:10341000E80100200302FF0123F0FE0313700228DD +:10342000F3D1D8B240F0010005E043F0FE00107087 +:10343000107820F0010010700868C2F80100888838 +:10344000A2F8050038BD02210FF09EBA38B50C462F +:103450000978222901D2082038BDADF800008DF886 +:10346000022068460DF097F905F054FE050003D1DF +:1034700021212046FFF74EFE284638BD1CB500200E +:103480008DF80000CDF80100ADF80500FB4890F87C +:103490002E00022801D0012000E000208DF8070056 +:1034A00068460DF0DAFA002800D0FFDF1CBD0022CC +:1034B0000A80437892B263F3451222F040020A80F8 +:1034C00000780C282BD2DFE800F02A06090E11162E +:1034D000191C1F220C2742F0110009E042F01D00C8 +:1034E00008800020704742F0110012E042F0100006 +:1034F00040F00200F4E742F01000F1E742F0010072 +:10350000EEE742F0010004E042F00200E8E742F09A +:10351000020040F00400E3E742F00400E0E7072087 +:1035200070472DE9FF478AB00025BDF82C60824620 +:103530001C4691468DF81C50700703D56068FDF756 +:10354000C2FE68B9CD4F4FF0010897F82E0058B170 +:1035500097F82F00022807D16068FDF701FF18B126 +:1035600010200EB0BDE8F087300702D5A089802872 +:103570003ED8700705D4B9F1000F02D097F82400A7 +:10358000A0B3E07DC0F300108DF81B00627D072022 +:10359000032162B3012A2DD0022AE2D0042AE0D10D +:1035A0008DF81710F00628D4A27D07202AB3012A2F +:1035B00023D0022A24D0042AD3D18DF8191000BFB9 +:1035C0008DF81590606810B307A9FFF7ABFE0028CF +:1035D000C7D19DF81C00FF2816D0606850F8011F65 +:1035E000CDF80F108088ADF8130014E000E001E082 +:1035F0000720B6E78DF81780D4E78DF81980DFE74C +:1036000002208DF81900DBE743F20220A9E7CDF88C +:103610000F50ADF81350E07B40B9207C30B9607C8E +:1036200020B9A07C10B9E07CC00601D0062098E744 +:103630008DF800A0BDF82C00ADF80200A068019044 +:10364000A068029004F10F0001F037FC8DF80C0027 +:10365000FFF791FE8DF80D009DF81C008DF80E000F +:103660008DF816508DF81850E07D08A900F00F0075 +:103670008DF81A0068460DF0E9FF05F04BFD70E784 +:10368000F0B58FB000258DF830508DF814508DF8BE +:10369000345006468DF828500195029503950495FF +:1036A00019B10FC901AC84E80F00744CA07805284B +:1036B00001D004280CD101986168884200D120B95A +:1036C0000398E168884203D110B108200FB0F0BD23 +:1036D000207DC00601D51F2700E0FF273B460DAA2D +:1036E00005A903A8FFF7ABFD0028EFD1A08AC10709 +:1036F00002D0C00600D4EE273B460AAA0CA901A8B6 +:10370000FFF79DFD0028E1D19DF81400C00701D00E +:103710000A20DBE7A08A410708D4A17D31B19DF8DA +:103720002810890702D043F20120CFE79DF8281026 +:10373000C90709D0400707D4208818B144F2506166 +:10374000884201D90720C1E78DF818508DF819601B +:10375000BDF80800ADF81A000198079006A80DF012 +:103760008FFF05F0D7FC0028B0D18DF820508DF8E0 +:103770002160BDF81000ADF822000398099008A858 +:103780000DF09DFF05F0C6FC00289FD101AD241D62 +:1037900095E80F0084E80F00002097E770B586B029 +:1037A0000D46040005D0FDF7DBFD20B1102006B06A +:1037B00070BD0820FBE72078C107A98802D0FF2947 +:1037C00002D303E01F2901D20920F0E7800763D468 +:1037D000FFF75AFC38B12178C1F3C100012804D0A9 +:1037E000032802D005E01320E1E7244890F82400E4 +:1037F000C8B1C8074FF001064FF0000502D08DF8A0 +:103800000F6001E08DF80F50FFF7B5FD8DF8000057 +:1038100020786946C0F3C1008DF8010060788DF80A +:103820000250C20801D00720C1E730B3C20701D05F +:103830008DF80260820705D59DF8022042F0020251 +:103840008DF80220400705D59DF8020040F00400E5 +:103850008DF80200002022780B18C2F38002DA7083 +:1038600001EB40026388D380401CA388C0B253811F +:103870000228F0D3207A78B905E001E0E8010020C1 +:103880008DF80260E6E7607A30B9A07A20B9E07A74 +:1038900010B9207BC00601D0062088E704F108009B +:1038A00001F00BFB8DF80E0068460DF09FFA05F055 +:1038B00031FC002889D18DF810608DF81150E08816 +:1038C000ADF81200ADF8145004A80DF0E2FA05F0BE +:1038D00021FC002888D12078C00701D0152000E005 +:1038E0001320FFF7BBFB002061E72DE9FF47022013 +:1038F000FB4E8DF804000027708EADF80600B84628 +:1039000043F202094CE001A80EF0A5FF050006D025 +:10391000708EA8B3A6F83280ADF806803EE0039C16 +:10392000A07F01072DD504F124000090A28EBDF8E0 +:103930000800214604F1360301F057FC050005D0CC +:103940004D452AD0112D3CD0FFDF3AE0A07F20F07A +:103950000801E07F420862F3C711A177810861F393 +:103960000000E07794F8210000F01F0084F82000A8 +:103970002078282826D129212046FFF7CBFB21E0FB +:1039800014E040070AD5BDF8080004F10E0101F06B +:10399000AAFA05000DD04D4510D100257F1CFFB2BD +:1039A00002200EF099FF401CB842ACD8052D11D072 +:1039B00008E0A07F20F00400A07703E0112D00D0E4 +:1039C000FFDF0025BDF806007086052D04D02846CF +:1039D00004B0C7E5A6F832800020F9E770B50646C6 +:1039E000FFF731FD054605F073FD040000D1FFDF50 +:1039F0006680207820F00F00801C20F0F00020303E +:103A000020700320207295F83E006072BDE870407F +:103A100005F061BD2DE9F04786B0040000D1FFDF5D +:103A20002078AF4D20F00F00801C20F0F0007030A7 +:103A3000207060680178491F1B2933D2DFE801F04C +:103A4000FE32323255FD320EFDFD42FC323232780A +:103A5000FCFCFBFA3232FCFCF9F8FC00C68830466C +:103A6000FFF7F1FC0546304607F02CF9E0B160683D +:103A7000007A85F83E0021212846FFF74BFB3046AF +:103A8000FEF753FB304603F053FE3146012012F09F +:103A900095FCA87F20F01000A877FFF726FF0028EC +:103AA00000D0FFDF06B05DE5207820F0F000203088 +:103AB00020700320207266806068007A607205F0D2 +:103AC0000AFDD8E7C5882846FFF7BDFC00B9FFDF2F +:103AD00060680079012800D0FFDF6068017A06B0D5 +:103AE0002846BDE8F04707F0CCBCC6883046FFF753 +:103AF000AAFC050000D1FFDF05F0EDFC606831464F +:103B00000089288160684089688160688089A8810F +:103B1000012012F053FC0020A875A87F00F00300DC +:103B20000228BFD1FFF7E1FE0028BBD0FFDFB9E7D5 +:103B300000790228B6D000B1FFDF05F0CCFC666842 +:103B4000B6F806A0307A361D012806D0687E814678 +:103B500005F04CFA070003D101E0E878F7E7FFDF52 +:103B60000022022150460EF006FF040000D1FFDFC4 +:103B700022212046FFF7CEFA3079012800D002201A +:103B8000A17F804668F30101A177308B2081708B83 +:103B90006081B08BA08184F822908DF80880B8688D +:103BA0000090F86801906A46032150460EF0E3FE4B +:103BB00000B9FFDFB888ADF81000B8788DF81200B2 +:103BC00004AA052150460EF0D6FE00B9FFDFB888E2 +:103BD000ADF80C00F8788DF80E0003AA04215046C9 +:103BE0000EF0C9FE00B9FFDF062106F1120001F058 +:103BF00098F940B37079800700D5FFDF7179E07DD7 +:103C000061F34700E075D6F80600A0617089A083D3 +:103C1000062106F10C0001F084F9F0B195F82500B9 +:103C20004108607861F347006070D5F8260006E02F +:103C30003EE036E06DE055E04AE02CE040E0C4F8BC +:103C40000200688D12E0E07D20F0FE00801CE0752F +:103C5000D6F81200A061F08AD9E7607820F0FE0063 +:103C6000801C6070F068C4F80200308AE080B8F10F +:103C7000010F04D0B8F1020F05D0FFDF12E70320D7 +:103C8000FFF7D4F90EE7287E122800D0FFDF1120BD +:103C9000FFF7E4F906E706B02046BDE8F04701F07B +:103CA0002DBD05F018FC15F8300F40F0020005E0BE +:103CB00005F011FC15F8300F40F004002870F1E613 +:103CC000287E132809D01528D8D11620FFF7C6F969 +:103CD00006B0BDE8F04705F0FEBB1420F6E7000093 +:103CE000E8010020A978052909D00429C6D105F0EA +:103CF000F2FB022006B0BDE8F047FFF797B9007964 +:103D00000028BBD0E87801F0BFF805F0E4FB032001 +:103D1000F0E7287E122802D1687E01F0B5F8112064 +:103D2000D4E72DE9F047054600784FF00008000978 +:103D3000DFF8C0A891460C464646012875D00228F7 +:103D400074D007280AD00A2871D0FFDFA9F80060D4 +:103D500014B1A4F800806680002003E4696801279C +:103D600004F108000A784FF0020C4FF6FF73172A8F +:103D70007ED00EDC142A32D006DC052A68D0092A4F +:103D800010D0102A75D120E0152A73D0162AF9D147 +:103D9000F8E0183A082A6CD2DFE802F0F36B6B0AFD +:103DA000CAF2DFF1C8884FF01208102621468DE1D3 +:103DB0004FF01C080A26BCB38888A0806868807908 +:103DC00020726868C0796072C0E74FF01B08142643 +:103DD00054B30320207268688088A080B6E70A790F +:103DE0003C2AB3D00D1D4FF010082C26E4B1698891 +:103DF000A180298B6182298B2182698BA182A98B69 +:103E0000E1826B790246A91D1846FFF7ECFA297981 +:103E1000002001290CD084F80FC0FF212176E06139 +:103E200020626062A06291E70FE02EE151E18CE137 +:103E3000E77320760AF1040090E80E00DAF810002B +:103E4000C4E90930C4E9071280E7A9F8006083E7F4 +:103E50002C264FF01D08002CF7D00546A380887B48 +:103E60002A880F1D60F300022A80887B400802E048 +:103E70009DE007E1BEE060F341022A80887B800874 +:103E800060F382022A80887BB91CC00860F3C302F9 +:103E90002A80B87A0011401C60F3041202F07F00FF +:103EA00028807878AA1CFFF79EFA387D05F1090270 +:103EB00007F11501FFF797FA387B01F041F82874F4 +:103EC000787B01F03DF86874F87EA874787AE8741D +:103ED000387F2875B87B6875388AE882DAF81C0064 +:103EE000A861B87A524697F808A0C0F34111012999 +:103EF00004D0108C504503D2824609E0FFDF10E069 +:103F0000022903D0288820F0600009E0504504D140 +:103F1000288820F06000403002E0288840F06000EF +:103F20002880A4F824A0524607F11D01A86996E054 +:103F300011264FF02008002C87D0A380686804F178 +:103F40000A02007920726868007B607269688B1DC4 +:103F500048791946FFF747FAF8E60A264FF0210894 +:103F6000002CE9D08888A080686880792072686811 +:103F7000C07960729AF8301021F004019FE065E08A +:103F80004CE06FE00B264FF02208002CD4D0C888FC +:103F9000A0806868007920726868007A00F0D0FF1D +:103FA00060726868407A00F0CBFFA072CEE61C26F3 +:103FB0004FF02608002CBFD0A3806868407960725B +:103FC0006868007AA0720AF1040090E80E00DAF83E +:103FD0001000C4E90530C4E90312686800793C2880 +:103FE00003D0432803D0FFDFB0E62772AEE684F8A3 +:103FF00008C0ABE610264FF02408002C9CD088881F +:10400000A0806868807920816868807A60816868AB +:104010000089A08168688089E08197E610264FF0CA +:104020002308002C88D08888A0806868C0882081F8 +:1040300068680089608168684089A08168688089B3 +:10404000E0819AF8301021F0020138E030264FF07C +:104050002508002C85D0A38069682822496821F0B2 +:10406000D9FA73E614264FF01B08002C8ED0A380DB +:10407000686800790128BAD02772DAE90710C4E924 +:10408000031063E64A46214660E0287A012803D0FF +:10409000022817D0FFDF59E610264FF01F08002C2A +:1040A00089D06888A080A8892081E8896081288AD1 +:1040B000A081688AE0819AF8301021F001018AF825 +:1040C000301043E64FF012081026688800F016FF03 +:1040D0003CE6287AC8B3012838D0022836D0032815 +:1040E00001D0FFDF32E609264FF01108002C85D001 +:1040F0006F883846FFF7A7F990F822A0A780687A62 +:104100002072042138460EF051FC052138460EF08D +:104110004DFC002138460EF049FC012138460EF0D6 +:1041200045FC032138460EF041FC022138460EF0D2 +:104130003DFC062138460EF039FC072138460EF0CA +:1041400035FC504600F0A0FE00E6FFE72846BDE83B +:10415000F04701F05DBC70B5012803D0052800D000 +:10416000FFDF70BD8DB22846FFF76DF9040000D166 +:10417000FFDF20782128F4D005F0AAF980B101787A +:1041800021F00F01891C21F0F00110310170022192 +:10419000017245800020A075BDE8704005F09BB914 +:1041A00021462846BDE870401322FFF74FB92DE99C +:1041B000F04116460C00804600D1FFDF307820F039 +:1041C0000F00801C20F0F0001030307020780128A3 +:1041D00004D0022818D0FFDFBDE8F0814046FFF789 +:1041E00032F9050000D1FFDF0320A87505F073F94F +:1041F00094E80F00083686E80F00FE4810F8301FDC +:1042000041F001010170E7E74046FFF71CF90500A6 +:1042100000D1FFDFA1884FF6FF700027814202D155 +:10422000E288824203D0814201D1E08840B105F0AA +:1042300052F994E80F00083686E80F00AF75CBE717 +:10424000A87D0128C8D178230022414612F00CF83D +:104250000220A875C0E738B505460C460846FDF7AC +:1042600032F818BB203D062D4AD2DFE805F0031BCB +:10427000373C42300021052012F076F808B11120B9 +:1042800038BDA01C0DF0FAF804F044FF050038D149 +:10429000002208231146052011F0E6FF052830D042 +:1042A000FFDF2EE06068FDF752F808B1102038BD3E +:1042B000618820886A460DF099FB04F02BFF050009 +:1042C0001FD16068E8B1BDF80010018019E0A07846 +:1042D00000F0010120880DF0BAFB0EE0206801F02B +:1042E00043FE05460DE0207800F001000CF0DBF9FC +:1042F00003E0618820880DF0F4FA04F00BFFF0E78A +:104300000725284638BD70B505460C460846FDF71A +:1043100000F808B1102070BD202D07D0212D0DD040 +:10432000222D0BD0252D09D0072070BD2088A11C7F +:104330000CF08EFABDE8704004F0ECBE062070BDB3 +:10434000AC482530704708B53421AA4821F003FA5B +:104350000120FEF76BFE1120FEF780FEA54968469E +:10436000263105F04BF8A3489DF8002010F8251FD2 +:1043700062F3470121F001010170002141724FF405 +:104380006171A0F8071002218172FEF7B1FE00B141 +:10439000FFDFFDF75DF801F07CF908BD10B50C46B4 +:1043A0004021204621F0B5F9A07F20F00300A0773E +:1043B000202020700020A07584F8230010BD7047D5 +:1043C0002DE9FC410746FCF77EFF10B11020BDE847 +:1043D000FC81884E06F12501D6F825000090B6F83C +:1043E0002950ADF8045096F82B408DF80640384619 +:1043F000FEF7E2FF0028EAD1FEF77AFE0028E6D0B9 +:10440000009946F8251FB580B471E0E710B5044661 +:10441000FCF77FFF08B1102010BD76487549224691 +:1044200090F8250026314008FEF7DDFF002010BD82 +:104430003EB504460D460846FCF76BFF08B1102058 +:104440003EBD14B143F204003EBD6A4880780528A1 +:1044500003D0042801D008203EBD694602A80AF016 +:104460009CFA2A4669469DF80800FEF7BCFF00202A +:104470003EBDFEB50D4604004FF0000711D00822E6 +:10448000FEF7C2FE002811D1002608E054F82600ED +:104490006946FEF747FF002808D1761CF6B2AE4207 +:1044A000F4D30CF047F810B143F20320FEBD514E97 +:1044B00086F824700CB300271BE000BF54F82700D7 +:1044C00002A9FEF72FFF00B1FFDF9DF808008DF86D +:1044D000000054F8270050F8011FCDF80110808823 +:1044E000ADF8050068460CF04AF800B1FFDF7F1C0C +:1044F000FFB2AF42E2D386F824500020FEBD2DE982 +:10450000F0478AB01546894604001ED00F4608229F +:104510002946FEF779FE002811D1002613E000BFDE +:1045200054F826006946103000F0D3FC002806D16C +:104530003FB157F82600FCF7C6FE10B110200AB0B4 +:104540000BE4761CF6B2AE42EAD30026A5F10108D0 +:104550001CE000BF06F1010A0AF0FF0712E000BFED +:1045600054F82600017C4A0854F827100B7CB2EB63 +:10457000530F05D106221130113121F01FF858B127 +:104580007F1CFFB2AF42EBD30AF0FF064645E1DBEA +:104590004E4624B1012003E043F20520CFE700207E +:1045A0000CF012F810B90CF01BF810B143F2042013 +:1045B000C5E774B300270DF1170828E054F8270069 +:1045C0006946103000F085FC00B1FFDF54F8270089 +:1045D000102250F8111FCDF801108088ADF80500A9 +:1045E00054F827100DF1070021F014F8AEB156F879 +:1045F000271001E0E80100201022404621F00AF8CF +:1046000068460BF0A1FF00B1FFDF7F1CFFB2AF4295 +:10461000D4D3FEF733FF002091E7404601F098FC29 +:10462000EEE730B585B00446FCF74DFE18B960687A +:10463000FCF796FE10B1102005B030BD60884AF23C +:10464000B811884206D82078F84D28B1012806D044 +:10465000022804D00720EFE7FEF74AFD18E0607853 +:10466000022804D0032802D043F20220E4E785F8B0 +:104670002F00C1B200200090ADF8040002292CD018 +:10468000032927D0FFDF68460CF043F804F042FD11 +:104690000028D1D1606801F04EFC207858B101208B +:1046A0008DF800000DF1010001F052FC68460DF09C +:1046B00032FA00B1FFDF207885F82E00FEF7DEFE2B +:1046C000608860B1A88580B20BF076FF00B1FFDF93 +:1046D0000020B1E78DF80500D5E74020FAE74FF458 +:1046E0006170EFE710B50446FCF713FE20B960686F +:1046F00038B1FCF72CFE08B1102010BD606801F045 +:1047000027FCCA4830F82C1F6180C178617080781E +:104710002070002010BD2DE9F84314468946064656 +:10472000FCF7F7FDA0B94846FCF71AFE80B9204611 +:10473000FCF716FE60B9BD4DA878012800D13CB148 +:104740003178FF2906D049B143F20400BDE8F8836F +:104750001020FBE7012801D00420F7E7CCB305289F +:1047600011D004280FD069462046FEF7A0FE00288D +:10477000ECD1217D49B1012909D0022909D00329B1 +:1047800009D00720E2E70820E0E7024604E0012222 +:1047900002E0022200E00322804623461746002062 +:1047A0000099FEF7BEFE0028D0D1A0892880A07B0A +:1047B000E875BDF80000A882AF75BDF800100907C4 +:1047C00001D5A18931B1A1892980C00704D0032076 +:1047D00003E006E08021F7E70220FEF727FC86F8D9 +:1047E00000804946BDE8F8430020FEF749BF7CB58C +:1047F0008E4C05460E46A078022803D0032801D02F +:1048000008207CBD15B143F204007CBD07200EF0EA +:104810006BF810B9A078032806D0FEF735FC28B154 +:10482000A078032804D009E012207CBD13207CBDB1 +:10483000304600F00CFB0028F9D1E670FEF79BFD36 +:1048400009F0E8FF01208DF800008DF801008DF8D7 +:1048500002502088ADF80400E07D8DF8060068461F +:104860000DF002F804F056FC0028E0D1A0780328EF +:1048700004D00420FEF7DAFB00207CBDE07800F0D5 +:10488000F6FA0520F6E71CB510B143F204001CBD92 +:10489000664CA078042803D0052801D008201CBD50 +:1048A00000208DF8000001218DF801108DF8020024 +:1048B00068460CF0D9FF04F02DFC0028EFD1A07859 +:1048C000052805D05FF00200FEF7B0FB00201CBDFC +:1048D000E07800F0D9FA0320F6E72DE9FC418046A4 +:1048E0000E4603250846FCF73BFD002866D14046EE +:1048F000FEF7A9FD040004D02078222804D2082065 +:1049000065E543F2020062E5A07F00F003073EB1D7 +:10491000012F0CD000203146FEF751FC0500EFD1ED +:10492000012F06D0022F1AD0FFDF28464FE50120C5 +:10493000F1E7A07D3146022801D011B107E0112036 +:1049400045E56846FCF791FE0028D9D16946404606 +:1049500006F05AFD0500E8D10120A075E5E7A07D2D +:10496000032804D1314890F83000C00701D02EB39D +:104970000EE026B1A07F40071ED4002100E00121F7 +:10498000404606F061FD0500CFD1A075002ECCD0C9 +:104990003146404600F0A7FA05461128C5D1A07F50 +:1049A0004107C2D4316844F80E1F7168616040F05D +:1049B000040020740025B8E71125B6E7102006E5AD +:1049C00070B50C460546FEF73EFD010005D02246B7 +:1049D0002846BDE87040FEF739BD43F2020070BDC5 +:1049E00010B5012807D1114B9B78012B00D011B1D4 +:1049F00043F2040010BD0BF011FEBDE8104004F0BE +:104A000089BB012300F04ABA00231A46194600F078 +:104A100045BA70B506460C460846FCF754FC18B972 +:104A20002068FCF776FC18B1102070BDE80100206A +:104A3000F94D2A7E112A04D0132A00D33EB1082052 +:104A4000F3E721463046FEF7A9FE60B1EDE7092005 +:104A5000132A0DD0142A0BD0A188FF29E5D31520E5 +:104A6000FEF7FCFA0020D4E90012C5E90712DCE7E2 +:104A7000A1881F29D9D31320F2E71CB5E648007E90 +:104A8000132801D208201CBD00208DF800006846C4 +:104A90000CF0FFF904F03EFB0028F4D11120FEF7E2 +:104AA000DDFA00201CBD2DE9F04FDFF86CA3814634 +:104AB00091B09AF818009B4615460C46132803D36C +:104AC000FFF7DBFF00281FD12046FCF7FCFBE8BB0B +:104AD0002846FCF7F8FBC8BB20784FF00107C00759 +:104AE0004FF0000102D08DF83A7001E08DF83A10D5 +:104AF00020788846C0F3C1008DF8000060788DF8FA +:104B00000910C10803D0072011B0BDE8F08F70B3C1 +:104B1000C10701D08DF80970810705D59DF80910EE +:104B200041F002018DF80910400705D59DF80900F4 +:104B300040F004008DF8090000206E4606EB4001AD +:104B400062884A81A2880A82401C00E00DE0C0B25F +:104B50000328F3D32078C0F3C100012825D003280F +:104B600023D04846FCF7AFFB28B11020CCE7FFE785 +:104B70008DF80970E0E799F80000400808D0012896 +:104B800009D0022807D0032805D043F20220BBE752 +:104B90008DF8028001E08DF80270484650F8011F40 +:104BA000CDF803108088ADF80700FEF7E4FB8DF820 +:104BB00001000020424606EB40012B88CB826B8827 +:104BC0008B83AB884B84EB880B85401CCA85C0B2B5 +:104BD0008A860328EFD3E088ADF83C0068460CF0E5 +:104BE00094FA00288FD19AF818005546112801D060 +:104BF000082089E706200DF077FE38B12078C0F351 +:104C0000C100012804D0032802D006E012207BE76F +:104C100095F8240000283FF476AFFEF735FA022815 +:104C200001D2132070E7584600F011F900289DD1F9 +:104C300085F819B068460CF0A8FB04F06BFA040084 +:104C400094D1687E00F013F91220FEF707FA20468F +:104C50005AE770B5704D287E122801D00820E4E68E +:104C60000CF096FB04F056FA040005D1687E00F0C3 +:104C70000BF91120FEF7F2F92046D6E670B506468C +:104C800015460C460846FCF744FB18B92846FCF7C5 +:104C900040FB08B11020C8E62A46214630460CF0F9 +:104CA00085FE04F037FA0028F5D121787F29F2D16A +:104CB0000520BAE67CB505460C460846FCF703FB22 +:104CC00008B110207CBD2846FEF7BDFB20B100785E +:104CD000222804D208207CBD43F202007CBD4E484D +:104CE00090F83000400701D511207CBD2078C00825 +:104CF00002D16078C00801D007207CBDADF800501B +:104D000020788DF8020060788DF803000220ADF85D +:104D1000040068460BF09EFF04F0FCF97CBD70B502 +:104D200086B014460D460646FEF78DFB28B1007886 +:104D3000222805D2082006B077E643F20200FAE7FF +:104D40002846FCF70DFB20B944B12046FCF7FFFADA +:104D500008B11020EFE700202060A0802E4890F8D6 +:104D60003000800701D51120E5E703A930460BF09C +:104D7000C2FD10B104F0CEF9DDE7ADF80060BDF87A +:104D80001400ADF80200BDF81600ADF80400BDF83F +:104D90001000BDF81210ADF80600ADF808107DB196 +:104DA000298809B1ADF80610698809B1ADF802107B +:104DB000A98809B1ADF80810E98809B1ADF8041067 +:104DC000DCB1BDF80610814201D9081A2080BDF877 +:104DD0000210BDF81400814201D9081A6080BDF8A4 +:104DE0000800BDF80410BDF816200144BDF81200FB +:104DF0001044814201D9081AA08068460BF02CFEAD +:104E0000B8E71CB505490968CDE9001068460CF003 +:104E10007EF904F07FF91CBDE8010020FC5A020075 +:104E20001CB500200090019068460CF070F904F069 +:104E300071F9F0E710800888508048889080C88811 +:104E400010818888D080002050819081704710B5F3 +:104E5000044604F0CBF830B1407830B1204604F07D +:104E6000DEFB002010BD052010BD122010BD10B5C6 +:104E700004F0BCF8040000D1FFDF607800B9FFDF68 +:104E80006078401E607010BD10B504F0AFF80400EB +:104E900000D1FFDF6078401C607010BD1CB5ADF81C +:104EA00000008DF802308DF803108DF8042068465C +:104EB0000CF03FFD04F02EF9ADE70CB528A2D2E9C5 +:104EC0000012CDE900120079694601EB501000781C +:104ED0000CBD0278520804D0012A02D043F202200D +:104EE0007047FEF71FBA1FB56A46FFF7A3FF684673 +:104EF0000CF081FA04F00EF904B010BD70B50C008E +:104F000006460DD0FEF79FFA050000D1FFDFA68010 +:104F100028892081288960816889A081A889E08109 +:104F200083E510B500231A4603E0845C2343521C3A +:104F3000D2B28A42F9D30BB1002010BD012010BDBE +:104F400000B540B1012805D0022803D0032804D0C1 +:104F5000FFDF002000BDFF2000BD042000BD0000D9 +:104F6000070605040302010010B50446FCF7ABF97F +:104F700008B1102010BD2078C0F30210042807D813 +:104F80006078072804D3A178102901D8814201D282 +:104F9000072010BDE078410706D421794A0703D4E1 +:104FA000000701D4080701D5062010BD002010BD60 +:104FB00010B513785C08837F64F3C7138377137885 +:104FC0009C08C37F64F30003C3771078C309487853 +:104FD00063F34100487013781C090B7864F347139E +:104FE0000B701378DB0863F3000048705078487149 +:104FF00010BD10B5C4780B7864F300030B70C4784F +:10500000640864F341030B70C478A40864F382035A +:105010000B70C478E40864F3C3030B700379117850 +:1050200063F30001117003795B0863F341011170B0 +:1050300003799B0863F3820111700079C00860F363 +:10504000C301117010BD70B514460D46064604F03C +:105050003FFA80B10178182221F00F01891C21F05C +:10506000F001A03100F8081B214620F018FBBDE834 +:10507000704004F030BA29463046BDE87040132233 +:10508000FEF7E4B92DE9F047064608A8894690E8FE +:1050900030041F4690461421284620F05CFB002176 +:1050A000CAF80010B8F1000F03D0B9F1000F03D116 +:1050B00014E03878C00711D02068FCF72AF9C0BB8B +:1050C000B8F1000F07D12068123028602068143032 +:1050D00068602068A8602168CAF8001038788007E6 +:1050E00024D56068FCF733F918BBB9F1000F21D063 +:1050F000FFF726F90168C6F868118188A6F86C11D7 +:10510000807986F86E0101F0F8FCF94FEF60626873 +:1051100062B196F8680106F2691140081032FEF794 +:1051200062F910223946606820F074FA0020BDE868 +:10513000F08706E0606820B1E8606068C6F8640146 +:10514000F4E71020F3E730B5054608780C4620F068 +:105150000F00401C20F0F001103121700020607021 +:1051600095F8230030B104280FD0052811D0062867 +:1051700014D0FFDF20780121B1EB101F04D295F885 +:10518000200000F01F00607030BD21F0F0002030E2 +:1051900002E021F0F00030302070EBE721F0F00069 +:1051A0004030F9E7F0B591B0022715460C460646A7 +:1051B0003A46ADF80870092103AB04F0FAFF0490F9 +:1051C000002810D004208DF804008DF80170E03420 +:1051D000099605948DF818500AA968460FF0C4F88E +:1051E00000B1FFDF012011B0F0BD10B588B00C4652 +:1051F0000A99ADF80000C3B11868CDF802005868EC +:10520000CDF80600ADF80A20102203A820F002FA1B +:1052100068460CF060F903F07DFF002803D1A17F00 +:1052200041F01001A17708B010BD0020CDF80200B8 +:10523000E6E72DE9F84F0646808A0D4680B28246A1 +:10524000FEF701F904463078DFF8A48200274FF01A +:105250000209A8F120080F2870D2DFE800F06FF2F1 +:105260003708387D8CC8F1F0EFF35FF3F300A07FCF +:1052700000F00300022809D05FF0000080F0010177 +:1052800050460DF081FB050003D101E00120F5E758 +:10529000FFDF98F85C10C90702D0D8F860000BE077 +:1052A000032105F11D0010F0AAFDD5F81D0091495C +:1052B000B0FBF1F201FB1200C5F81D0070686867D1 +:1052C000B068A8672078252800D0FFDFCAE0A07F5B +:1052D00000F00300022809D05FF0000080F0010117 +:1052E00050460DF051FB060003D101E00120F5E727 +:1052F000FFDF3078810702D52178252904D040F0DE +:1053000001003070BDE8F88F85F80090307F28717B +:1053100006F11D002D36C5E90206F3E7A07F00F077 +:105320000300022808D0002080F0010150460DF053 +:105330002BFB040004D102E00120F5E7A7E1FFDF29 +:105340002078C10604D5072028703D346C60D9E769 +:1053500040F008002070D5E7E07F000700D5FFDFB0 +:10536000307CB28800F0010301B05046BDE8F04F38 +:10537000092105F0A9BD04B9FFDF716821B1102230 +:1053800004F1240020F046F928212046FDF7C2FE52 +:10539000A07F00F0030002280ED104F124000023B6 +:1053A00000901A4621465046FFF71FFF112807D0EC +:1053B00029212046FDF7AEFE307A84F82000A1E7CF +:1053C000A07F000700D5FFDF14F81E0F40F0080093 +:1053D0002070E782A761E761C109607861F341004D +:1053E000014660F382016170307AE0708AE7A07F45 +:1053F00000F00300022809D05FF0000080F00101F6 +:1054000050460DF0C1FA040003D101E00120F5E798 +:10541000FFDF022104F1850010F0F1FC0420287068 +:1054200004F5B4706860B4F88500288230481038FC +:105430007C346C61C5E9028064E703E024E15BE051 +:105440002DE015E0A07F00F00300022807D0002027 +:1054500080F0010150460DF097FA18B901E00120E3 +:10546000F6E7FFDF324621465046BDE8F84FEAE551 +:1054700004B9FFDF20782128A1D93079012803D190 +:10548000E07F40F00800E077324621465046FFF7C3 +:10549000DAFD2046BDE8F84F2321FDF73BBE327907 +:1054A000AA8005F108030921504604F082FEE86055 +:1054B00010B10520287025E7A07F00F00300022826 +:1054C00008D0002080F0010150460DF05DFA040084 +:1054D00003D101E00120F5E7FFDF04F162010223BF +:1054E0001022081F0DF0D7F807703179417009E7D5 +:1054F0004802002040420F00A07F00F00300022875 +:1055000008D0002080F0010150460DF03DFA050062 +:1055100003D101E00120F5E7FFDF95F8840000F0FA +:10552000030001287AD1A07F00F00307E07F10F08C +:10553000010602D0022F04D133E095F8A000C00785 +:105540002BD0D5F8601121B395F88320087C62F345 +:1055500087000874A17FCA09D5F8601162F3410081 +:105560000874D5F8601166F300000874AEB1D5F880 +:105570006001102204F12401883520F04BF8287EC8 +:1055800040F001002876287820F0010005F888090D +:1055900000E016B1022F04D02DE095F88800C00776 +:1055A00027D0D5F85C1121B395F88320087C62F3ED +:1055B00087000874A17FCA09D5F85C1162F3410025 +:1055C0000874D5F85C1166F3000008748EB1D5F844 +:1055D0005C01102204F12401883520F01BF82878A2 +:1055E00040F0010005F8180B287820F0010005F8BC +:1055F000A009022F44D0002000EB400005EBC000C2 +:1056000090F88800800709D595F87C00D5F86421CA +:10561000400805F17D011032FDF7E5FE8DF80090A0 +:1056200095F884006A4600F003008DF8010095F8B3 +:1056300088108DF8021095F8A0008DF8030021461F +:10564000504601F043FA2078252805D0212807D0BC +:10565000FFDF2078222803D922212046FDF75AFDBA +:10566000A07F00F0030002280CD0002080F0010190 +:1056700050460DF09BF900283FF44FAEFFDF41E6A6 +:105680000120B9E70120F1E7706847703AE6FFDFD3 +:1056900038E670B5FE4C002584F85C5025660EF0A7 +:1056A00030FE04F11001204603F0CEFE84F83050A5 +:1056B00070BD70B50D46FDF7C6FE040000D1FFDFDA +:1056C0004FF4B871284620F046F804F12400286110 +:1056D000A07F00F00300022808D0012105F1E000BE +:1056E0000EF010FE002800D0FFDF70BD0221F5E7AC +:1056F0000A46014602F1E0000EF024BE70B50546F0 +:10570000406886B001780A2906D00D2933D00E29C9 +:105710002FD0FFDF06B070BD86883046FDF793FEC0 +:10572000040000D1FFDF20782128F3D028281BD1E6 +:10573000686802210E3001F0BEF9A8B1686808213E +:10574000801D01F0B8F978B104F1240130460CF065 +:105750008DF803F0DFFC00B1FFDF06B02046BDE8A6 +:1057600070402921FDF7D6BC06B0BDE8704003F0BB +:10577000B2BE012101726868C6883046FDF763FE3B +:10578000040000D1FFDFA07F00F00301022902D155 +:1057900020F01000A077207821280AD06868017ACC +:1057A00009B1007980B1A07F00F00300022862D027 +:1057B000FFDFA07F00F003000228ABD1FEF795F8D1 +:1057C0000028A7D0FFDFA5E703F085FEA17F08062C +:1057D0002BD5E07FC00705D094F8200000F01F0013 +:1057E000102820D05FF0050084F8230020782928B5 +:1057F0001DD02428DDD13146042010F0DFFD222108 +:105800002046FDF787FCA07F00F00300022830D07F +:105810005FF0000080F0010130460DF0C7F800286D +:10582000C7D0FFDFC5E70620DEE70420DCE701F094 +:105830000300022808D0002080F0010130460DF05E +:10584000A3F8050003D101E00120F5E7FFDF2521E2 +:105850002046FDF75FFC03208DF80000694605F146 +:10586000E0000EF066FD0228A3D00028A1D0FFDFE3 +:105870009FE70120CEE703F02EFE9AE72DE9F043E3 +:1058800087B09946164688460746FDF7DCFD0400BA +:105890004BD02078222848D3232846D0E07F000729 +:1058A00043D4A07F00F00300022809D05FF000007D +:1058B00080F0010138460DF067F8050002D00CE0D9 +:1058C0000120F5E7A07F00F00300022805D00121A8 +:1058D000002238460DF04FF805466946284601F08B +:1058E0001CF9009800B9FFDF45B10098E03505616B +:1058F0002078222806D0242804D007E00099002030 +:10590000086103E025212046FDF704FC00980121F1 +:1059100041704762868001A9C0E902890EF024FD2A +:10592000022802D0002800D0FFDF07B0BDE8F083D6 +:1059300070B586B00546FDF786FD017822291ED98F +:10594000807F00F00300022808D0002080F00101D1 +:1059500028460DF019F804002FD101E00120F5E7E9 +:10596000FFDF2AE0B4F85E0004F1620630440178FB +:10597000427829B121462846FFF714FCB0B9C9E6A0 +:10598000ADF804200921284602AB04F012FC039074 +:105990000028F4D005208DF80000694604F1E000ED +:1059A0000EF0C7FC022801D000B1FFDF0223102255 +:1059B000314604F15E000CF0A4FEB4F8600000284B +:1059C000D0D1A7E610B586B00446FDF73CFD0178BE +:1059D00022291BD9807F00F00300022808D0002074 +:1059E00080F0010120460CF0CFFF040003D101E05C +:1059F0000120F5E7FFDF06208DF80000694604F17D +:105A0000E0000EF096FC002800D0FFDF06B010BDCD +:105A10002DE9F05F05460C46002700789046010905 +:105A20003E4604F1080BBA4602297DD0072902D070 +:105A30000A2909D146E0686801780A2905D00D29AC +:105A400030D00E292ED0FFDFBBE114271C26002CFE +:105A50006BD08088A080FDF7F6FC5FEA000900D1DA +:105A6000FFDF99F817005A46400809F11801FDF7C1 +:105A7000BAFC6868C0892082696851F8060FC4F8CA +:105A800012004868C4F81600A07E20F0060001E06D +:105A90002802002040F00100A07699F81E0040F096 +:105AA00020014DE01A270A26002CD1D0C088A08002 +:105AB000FDF7C9FC050000D1FFDF59462846FFF776 +:105AC00042FB7EE10CB1A88BA080287A0B287DD008 +:105AD00006DC01287BD0022808D0032804D135E059 +:105AE0000D2875D00E2874D0FFDF6AE11E27092625 +:105AF000002CADD0A088FDF7A6FC5FEA000900D11C +:105B0000FFDF287B00F003000128207A1BD020F063 +:105B100001002072297B890861F341002072297BF2 +:105B2000C90861F3820001E041E1F2E02072297BC3 +:105B3000090961F3C300207299F81E0040F040018A +:105B400089F81E103DE140F00100E2E713270D2621 +:105B5000002CAAD0A088FDF776FC8146807F00F05B +:105B60000300022808D0002080F00101A0880CF07A +:105B70000BFF050003D101E00120F5E7FFDF99F8F5 +:105B80001E0000F00302022A50D0686F817801F0F5 +:105B900003010129217A4BD021F001012172837880 +:105BA0009B0863F3410121728378DB0863F3820170 +:105BB000217283781B0963F3C3012172037863F3B5 +:105BC00006112172437863F3C71103E061E0A9E095 +:105BD00090E0A1E0217284F809A0C178A172022AA4 +:105BE00029D00279E17A62F30001E1720279520868 +:105BF00062F34101E1720279920862F38201E1727B +:105C00000279D20862F3C301E1724279217B62F327 +:105C1000000121734279520862F3410121734279F4 +:105C2000920862F382012173407928E0A86FADE702 +:105C300041F00101B2E74279E17A62F30001E172D9 +:105C40004279520862F34101E1724279920862F3AB +:105C50008201E1724279D20862F3C301E1720279F2 +:105C6000217B62F3000121730279520862F3410142 +:105C700021730279920862F3820121730079C008CE +:105C800060F3C301217399F80000232831D926213C +:105C900040E018271026E4B3A088FDF7D4FB834624 +:105CA000807F00F00300022809D0002080F001016D +:105CB000A0880CF069FE5FEA000903D101E0012031 +:105CC000F4E7FFDFE868A06099F8000040F0040105 +:105CD00089F8001099F80100800708D50120207389 +:105CE0009BF8000023286CD92721584651E084F8FE +:105CF0000CA066E015270F265CB1A088FDF7A3FB7A +:105D0000814606225946E86808F0C1FA0120A073CE +:105D1000A0E041E048463CE016270926E4B3287B92 +:105D200020724EE0287B19270E26ACB3C4F808A0D9 +:105D3000A4F80CA0012807D0022805D0032805D01C +:105D4000042803D0FFDF0DE0207207E0697B042800 +:105D500001F00F0141F0800121721ED0607A20F025 +:105D600003006072A088FDF76EFB054600782128CD +:105D700027D0232800D0FFDFA87F00F003000228EF +:105D800013D0002080F00101A0880CF00FFE22212A +:105D90002846FDF7BFF914E004E0607A20F0030024 +:105DA000401CDEE7A8F8006010E00120EAE70CB133 +:105DB0006888A080287A68B301280AD002284FD0CA +:105DC000FFDFA8F800600CB1278066800020BDE8E6 +:105DD000F09F15270F26002CE4D0A088FDF733FB99 +:105DE000807F00F00300022808D0002080F001012D +:105DF000A0880CF0C9FD050003D101E00120F5E702 +:105E0000FFDFD5F81D000622594608F040FA84F855 +:105E10000EA0D6E717270926002CC3D0A088FDF7CF +:105E200012FB8146807F00F00300022808D000208A +:105E300080F00101A0880CF0A7FD050003D101E06E +:105E40000120F5E7FFDF6878800701D5022000E038 +:105E50000120207299F800002328B2D9272159E7A0 +:105E600019270E26002C9DD0A088FDF7ECFA5FEADA +:105E7000000900D1FFDFC4F808A0A4F80CA084F842 +:105E800008A0A07A40F00300A07299F81E10C9097A +:105E900061F38200A07299F81F2099F81E1012EA8F +:105EA000D11F05D099F8201001F01F0110292BD027 +:105EB00020F00800A07299F81F10607A61F3C30007 +:105EC0006072697A01F003010129A2D140F0040057 +:105ED000607299F81E0000F003000228E87A16D0DC +:105EE000217B60F300012173AA7A607B62F30000DA +:105EF0006073EA7A520862F341012173A97A490872 +:105F000061F3410060735CE740F00800D2E7617B19 +:105F100060F300016173AA7A207B62F300002073B2 +:105F2000EA7A520862F341016173A97A490861F380 +:105F30004100207345E710B5FE4C30B101461022F8 +:105F400004F120001FF066FB012084F8300010BD32 +:105F500010B5044600F0D1FDF64920461022BDE8F8 +:105F6000104020311FF056BB70B5F24D06004FF0C7 +:105F7000000413D0FBF7A7F908B110240CE00621A8 +:105F8000304608F06BF9411C05D028665FF001002F +:105F900085F85C0000E00724204670BD0020F7E78C +:105FA000007810F00F0204D0012A05D0022A0CD18B +:105FB00010E0000909D10AE00009012807D00228F1 +:105FC00005D0032803D0042801D0072070470870AB +:105FD000002070470620704705282AD2DFE800F02D +:105FE00003070F171F00087820F0FF001EE0087855 +:105FF00020F00F00401C20F0F000103016E0087870 +:1060000020F00F00401C20F0F00020300EE0087857 +:1060100020F00F00401C20F0F000303006E008783F +:1060200020F00F00401C20F0F000403008700020ED +:106030007047072070472DE9F041804688B00D4633 +:1060400000270846FBF78CF9A8B94046FDF7FBF995 +:10605000040003D02078222815D104E043F2020086 +:1060600008B0BDE8F08145B9A07F410603D500F036 +:106070000300022801D01020F2E7A07FC10601D45E +:10608000010702D50DB10820EAE7E17F090701D534 +:106090000D20E5E700F00300022805D125B12846D0 +:1060A000FEF762FF0700DBD1A07F00F003000228AB +:1060B00008D0002080F0010140460CF065FC06008D +:1060C00002D00FE00120F5E7A07F00F003000228D6 +:1060D0000ED0002080F00101002240460CF04BFC65 +:1060E000060007D0A07F00F00300022804D009E0DA +:1060F0000120EFE70420B3E725B12A4631462046C8 +:10610000FEF756FF6946304600F007FD009800B9DB +:10611000FFDF0099022006F1E0024870C1F82480F8 +:106120004A6100220A81A27F02F00302022A1CD0E7 +:1061300001200871287800F00102087E62F3010056 +:1061400008762A78520862F3820008762A78920844 +:1061500062F3C30008762A78D20862F30410087646 +:1061600024212046FCF7D6FF33E035B30871301DFB +:1061700088613078400908777078C0F3400048772C +:10618000287800F00102887F62F301008877A27FFF +:10619000D20962F382008877E27F62F3C3008877D6 +:1061A000727862F304108877A878C87701F1210229 +:1061B00028462031FEF71DFF03E00320087105206B +:1061C000087625212046FCF7A5FFA07F20F040009F +:1061D000A07701A900980EF0C7F8022801D000B1FD +:1061E000FFDF38463CE72DE9FF4F534A0D4699B093 +:1061F0009A4607CA0AAB002783E807001998FDF7FB +:1062000022F9060006D03078262806D008201DB0D6 +:10621000BDE8F08F43F20200F9E7B07F00F0030918 +:10622000B9F1020F0AD05DB91B98FEF79DFE002858 +:10623000EDD1B07F00F00300022801D11B9890BB84 +:10624000B07F00F00300022808D0002080F0010198 +:1062500019980CF099FB040003D101E00120F5E747 +:10626000FFDF852D28D007DCF5B1812D1ED0822DD2 +:106270001ED0832D08D11DE0862D1FD0882D1FD064 +:10628000892D1FD08A2D1FD00F2020710F281DD0DF +:1062900003F01EF9E0B101208DF83C00201D1090A4 +:1062A0002079B8B15BE111E00020EEE70120ECE7D6 +:1062B0000220EAE70320E8E70520E6E70620E4E716 +:1062C0000820E2E70920E0E70A20DEE707209EE752 +:1062D00011209CE7B9F1020F03D0A56F03D1A06F85 +:1062E00002E0656FFAE7606F804632D04FF0010040 +:1062F00001904FF002000090214630461B9AFEF7B5 +:1063000057FE1B98007800F00101A87861F30100A6 +:10631000A870B17FC90961F38200A870F17F61F3B1 +:10632000C300A870617861F30410A8702078400958 +:10633000287003E028020020045B02006078C0F3AC +:10634000400068701B988078E870002068712871A0 +:1063500003E00220019001200090A87898F8021034 +:10636000C0F3C000C1F3C00108405FEA000B2DD0AC +:106370005046FAF7A8FF78BBDAF80C00FAF7A3FF4B +:1063800050BBDAF81C00FAF79EFF28BBDAF80C00C5 +:10639000A060DAF81C00E060607898F8012042EA1A +:1063A000500100BF61F34100607098F80210C0B264 +:1063B00000EA111161F3000060700020207700995D +:1063C00006F11700022908D0012107E0607898F84B +:1063D000012002EA5001E5E732E0002104EB8101EF +:1063E00048610199701C022901D0012100E00021BF +:1063F00004EB81014861A87800F00300012857D11F +:1064000098F8020000F00300012851D1B9F1020F01 +:1064100004D02A1D691D1B98FEF7EBFD287998F81A +:10642000041008408DF83400697998F8052011406F +:106430008DF8381008433BD05046FAF744FF08B1B6 +:106440001020E4E60AF110010491B9F1020F17D00F +:106450000846002104F18C03CDE9000304F5AE7277 +:1064600002920DAB5A462046FEF70CFE0028E8D1FA +:10647000B9F1020F08D0504608D14FF0010107E0F2 +:1064800050464FF00101E5E70498F5E74FF00001B1 +:1064900004F1A403CDE9000304F5B072029281F087 +:1064A00001010EAB5A462046FEF7ECFD0028C8D18C +:1064B0006078800734D4A87898F80210C0F3800080 +:1064C000C1F3800108432BD0297898F800000AAA6C +:1064D000B9F1020F06D032F811204300DA4002F081 +:1064E00003070AE032F810204B00DA4012F00307ED +:1064F00005D0012F0BD0022F0BD0032F07D0BBF1FB +:10650000000F0DD0012906D0042904D008E002278D +:10651000F5E70127F3E7012801D0042800D104277B +:10652000B07F40F08000B077F17F6BF30001F1772E +:106530006078800706D50320A071BBF1000F0ED153 +:10654000002028E00220022F18D0012F18D0042F9D +:1065500029D00020A071B07F20F08000B0772521E5 +:106560003046FCF7D7FD0FA904F1E0000DF0E1FE85 +:1065700010B1022800D0FFDF002048E6A071DFE75D +:10658000A0710D2104F120001FF0E5F8207840F003 +:106590000200207001208DF85C0017AA314619987E +:1065A00000F094FADBE70120A071D8E72DE9F04371 +:1065B00087B09046894604460025FCF744FF060054 +:1065C00006D03078272806D0082007B0BDE8F08331 +:1065D00043F20200F9E7B07F00F00300022809D07F +:1065E0005FF0000080F0010120460CF0CDF90400BE +:1065F00003D101E00120F5E7FFDFA7795FEA090099 +:1066000005D0012821D0B9F1020F26D110E0B8F150 +:10661000000F22D1012F05D0022F05D0032F05D066 +:10662000FFDF2DE00C252BE0012529E0022527E0E6 +:106630004046FAF748FEB0B9032F0ED1102241466A +:1066400004F11D001EF0E6FF1AE0012F02D0022F18 +:1066500003D104E0B8F1000F12D00720B5E740469F +:10666000FAF731FE08B11020AFE7102104F11D0048 +:106670001FF04FF80621404607F0F0FDC4F81D005A +:106680002078252140F0020020703046FCF742FDC2 +:106690002078C10713D020F00100207002208DF86F +:1066A000000004F11D0002908DF804506946C330CB +:1066B0000DF03FFE022803D010B1FFDF00E0257788 +:1066C000002082E730B587B00D460446FCF7BBFEDC +:1066D000A0B1807F00F00300022812D05FF000001C +:1066E00080F0010120460CF04FF904000ED028463E +:1066F000FAF7E9FD38B1102007B030BD43F20200CF +:10670000FAE70120ECE72078400701D40820F3E7FE +:10671000294604F13D00202205461EF07BFF20782B +:1067200040F01000207001070FD520F00800207005 +:1067300007208DF80000694604F1E00001950DF096 +:10674000F8FD022801D000B1FFDF0020D4E770B5CA +:106750000D460646FCF777FE18B10178272921D1AE +:1067600002E043F2020070BD807F00F003000228C7 +:1067700008D0002080F0010130460CF005F904003B +:1067800003D101E00120F5E7FFDFA079022809D15C +:106790006078C00706D02A4621463046FEF702FD43 +:1067A00010B10FE0082070BDB4F860000E280BD2C5 +:1067B00004F1620102231022081F0BF06CFF01217B +:1067C00001704570002070BD112070BD70B5064687 +:1067D00014460D460846FAF776FD18B92046FAF732 +:1067E00098FD08B1102070BDA6F57F40FF380ED08F +:1067F0003046FCF728FE38B1417822464B08811C10 +:106800001846FCF7F0FD07E043F2020070BD204699 +:10681000FDF7FCFD0028F9D11021E01D0FF0EFFA83 +:10682000E21D294604F1170000F087F9002070BD31 +:106830002DE9F04104468AB01546884600270846EF +:10684000FAF78EFD18B92846FAF78AFD10B1102024 +:106850000AB006E42046FCF7F6FD060003D03078C7 +:1068600027281AD102E043F20200F1E7B07F00F0DE +:106870000300022808D0002080F0010120460CF01F +:1068800083F8040003D101E00120F5E7FFDF207861 +:10689000400702D56078800701D40820D8E7B07F90 +:1068A00000F00300022803D0A06F03D1A16F02E023 +:1068B000606FFAE7616F407800B19DB1487810B120 +:1068C000B8F1000F0ED0ADB1EA1D06A8E16800F0E6 +:1068D00034F9102206A905F117001EF06FFE18B159 +:1068E000042707E00720B3E71022E91D04F12D007B +:1068F0001EF090FEB8F1000F06D0102208F107013B +:1069000004F11D001EF086FE2078252140F00200D3 +:1069100020703046FCF7FEFB2078C10715D020F030 +:106920000100207002208DF8000004F11D0002908B +:10693000103003908DF804706946B3300DF0F9FC07 +:10694000022803D010B1FFDF00E0277700207FE7A7 +:10695000F8B515460E460746FCF775FD040004D051 +:106960002078222804D00820F8BD43F20200F8BDA8 +:10697000A07F00F00300022802D043F20500F8BD1A +:106980003046FAF7A0FC18B92846FAF79CFC08B183 +:106990001020F8BD00953288B31C21463846FEF71A +:1069A00024FC112815D00028F3D1297C4A08A17FA6 +:1069B00062F3C711A177297CE27F61F30002E277DD +:1069C000297C890884F82010A17F21F04001A1775B +:1069D000F8BDA17F0907FBD4D6F80200C4F8360041 +:1069E000D6F80600C4F83A003088A086102229465E +:1069F00004F124001EF00EFE287C4108E07F61F3C4 +:106A00004100E077297C61F38200E077287C8008F0 +:106A100084F82100A07F40F00800A0770020D3E791 +:106A200070B50D4606460BB1072070BDFCF70BFD97 +:106A3000040007D02078222802D3A07F800604D447 +:106A4000082070BD43F2020070BDADB1294630464A +:106A50000AF00CFF02F05EFB297C4A08A17F62F37A +:106A6000C711A177297CE27F61F30002E277297CDC +:106A7000890884F8201004E030460AF01AFF02F07A +:106A800049FBA17F21F02001A17770BD70B50D46B3 +:106A9000FCF7D9FC040005D02846FAF73AFC20B1EF +:106AA000102070BD43F2020070BD29462046FEF75B +:106AB0004AFB002070BD04E010F8012B0AB1002051 +:106AC0007047491E89B2F7D20120704770B515464C +:106AD000064602F0FDFC040000D1FFDF207820F024 +:106AE0000F00801C20F0F0002030207066802868A5 +:106AF000A060BDE8704002F0EEBC10B5134C94F8F5 +:106B00003000002808D104F12001A1F110000DF09F +:106B100052FC012084F8300010BD10B190F8B9206B +:106B20002AB10A4890F8350018B1002003E0B830C7 +:106B300001E0064834300860704708B50023009330 +:106B400013460A460CF01BF908BD0000280200207D +:106B500018B18178012938D101E0102070470188EF +:106B600042F60112881A914231D018DC42F6010235 +:106B7000A1EB020091422AD00CDC41B3B1F5C05F19 +:106B800025D06FF4C050081821D0A0F57060FF38F0 +:106B90001BD11CE001281AD002280AD117E0B0F559 +:106BA000807F14D008DC012811D002280FD00328E0 +:106BB0000DD0FF2809D10AE0B0F5817F07D0A0F5FC +:106BC0008070033803D0012801D0002070470F20C7 +:106BD00070470A281FD008DC0A2818D2DFE800F026 +:106BE000191B1F1F171F231D1F21102815D008DC7C +:106BF0000B2812D00C2810D00D2816D00F2806D143 +:106C00000DE011280BD084280BD087280FD003204B +:106C100070470020704705207047072070470F20FD +:106C2000704704207047062070470C20704743F2DD +:106C30000200704738B50C46050041D06946FFF7A1 +:106C4000AFF9002819D19DF80010607861F30200B7 +:106C500060706946681CFFF7A3F900280DD19DF804 +:106C60000010607861F3C5006070A978C1F341013C +:106C7000012903D0022905D0072038BD217821F051 +:106C8000200102E0217841F020012170410704D069 +:106C9000A978C90861F386106070607810F0380F29 +:106CA00007D0A978090961F3C710607010F0380F98 +:106CB00002D16078400603D5207840F04000207073 +:106CC000002038BD70B50446002008801546606875 +:106CD000FFF7B0FF002816D12089A189884211D87A +:106CE00060688078C0070AD0B1F5007F0AD840F20A +:106CF0000120B1FBF0F200FB1210288007E0B1F593 +:106D0000FF7F01D90C2070BD01F2012129800020F4 +:106D100070BD10B50478137864F300031370047821 +:106D2000640864F3410313700478A40864F38203D5 +:106D300013700478E40864F3C3031370047824091F +:106D400064F3041313700478640964F34513137037 +:106D50000078800960F38613137031B10878C10799 +:106D600001D1800701D5012000E0002060F3C713A6 +:106D7000137010BD4278530702D002F0070306E0FB +:106D800012F0380F02D0C2F3C20300E001234A78A8 +:106D900063F302024A70407810F0380F02D0C0F35B +:106DA000C20005E0430702D000F0070000E0012028 +:106DB00060F3C5024A7070472DE9F04F95B00D00A1 +:106DC000824612D0122128461EF0A3FC4FF6FF7B0C +:106DD00005AA0121584607F05CF8002426463746EC +:106DE0004FF420586FF4205973E0102015B0BDE81F +:106DF000F08F00BF9DF81E0001280AD1BDF81C10BD +:106E000041450BD011EB09000AD001280CD0022813 +:106E10000CD0042C0ED0052C0FD10DE0012400E085 +:106E20000224BDF81A6008E0032406E00424BDF83B +:106E30001A7002E0052400E00624BDF81A1051453E +:106E400047D12C74BEB34FF0000810AA4FF0070AC8 +:106E5000CDE90282CDE900A80DF13C091023CDF85F +:106E6000109042463146584607F0C6F808BBBDF8B8 +:106E70003C002A46C0B210A90DF013FBC8B9AE8180 +:106E8000CFB1CDE900A80DF1080C0AAE40468CE860 +:106E90004102132300223946584607F0ADF840B9A5 +:106EA000BDF83C00F11CC01EC0B22A1D0DF0F9FA5D +:106EB00010B103209AE70AE0BDF82900E881062C0A +:106EC00005D19DF81E00A872BDF81C002881002085 +:106ED0008CE705A806F0E9FF00288BD0FFF779FEC4 +:106EE00084E72DE9F0471C46DDE90978DDF82090BC +:106EF00015460E00824600D1FFDF0CB1208818B184 +:106F0000D5B11120BDE8F087022D01D0012100E0AC +:106F1000002106F1140005F0ABFEA8F800000246BF +:106F20003B462946504603F044F9C9F8000008B929 +:106F3000A41C3C600020E5E71320E3E7F0B414460E +:106F4000DDE904528DB1002314B1022C09D101E016 +:106F5000012306E00D7CEE0703D025F00105012397 +:106F60000D742146F0BC03F0AFBF1A80F0BC70472F +:106F70002DE9FE4F91461A881C468A468046FAB192 +:106F800002AB494603F015F9050019D04046A61C8E +:106F900027880BF03DFE3246072629463B460096E1 +:106FA0000BF04BFA20882346CDE900504A46514663 +:106FB0004046FFF7C3FF002020800120BDE8FE8F80 +:106FC0000020FBE72DE9F04786B082460EA89046E8 +:106FD00090E8B000894604AA05A903A88DE8070037 +:106FE0001E462A4621465046FFF77BFF039901B112 +:106FF00001213970002818D1F94904F1140204ABB9 +:107000000860039805998DE80700424649465046B6 +:1070100006F0E5F9A8B1092811D2DFE800F005086B +:107020000510100A0C0C0E00002006B06AE71120B3 +:10703000FBE70720F9E70820F7E70D20F5E7032035 +:10704000F3E7BDF810100398CDE9000133462A4656 +:1070500021465046FFF772FFE6E72DE9F04389B07D +:107060000D46DDE9108781461C461646142103A80B +:107070001EF071FB012002218DF810108DF80C001C +:107080008DF81170ADF8146064B1A278D20709D000 +:107090008DF81600E088ADF81A00A088ADF8180049 +:1070A000A068079008A80095CDE90110424603A901 +:1070B00048466B68FFF786FF09B0BDE8F083F0B57E +:1070C0008BB000240646069407940727089405A869 +:1070D0000994019400970294CDE903400D461023D2 +:1070E0002246304606F088FF78B90AA806A901941E +:1070F00000970294CDE90310BDF814300022294610 +:10710000304606F04FFD002801D0FFF762FD0BB0BE +:10711000F0BD06F0EFBB2DE9FC410C468046002691 +:1071200002F0D6F9054620780D287DD2DFE800F080 +:10713000BC0713B325BD49496383AF959B00A8489D +:10714000006820B1417841F010014170ADE0404647 +:1071500002F0EEF9A9E0042140460BF015FC07000F +:1071600000D1FFDF07F11401404605F015FDA5BB76 +:1071700013214046FDF724FC97E0042140460BF024 +:1071800003FC070000D1FFDFE088ADF8000000201D +:10719000B8819DF80000010704D5C00602D5A0887B +:1071A000B88105E09DF8010040067ED5A088F881F1 +:1071B00005B9FFDF22462946404601F0BDFC022604 +:1071C00073E0E188ADF800109DF8011009060FD5B5 +:1071D000072803D006280AD00AE024E0042140460C +:1071E0000BF0D2FB060000D1FFDFA088F081022661 +:1071F000CDB9FFDF17E0042140460BF0C5FB0700C7 +:1072000000D1FFDF07F1140006F0ABFB90F0010F97 +:1072100002D1E079000648D5387C022640F0020011 +:10722000387405B9FFDF00E03EE0224629464046BB +:1072300001F082FC39E0042140460BF0A5FB017C03 +:10724000002D01F00206C1F340016171017C21F0C3 +:1072500002010174E7D1FFDFE5E702260121404684 +:1072600002F098F921E0042140460BF08DFB054621 +:10727000606800902089ADF804000122694640460C +:1072800002F0A9F9287C20F0020028740DE0002DFE +:10729000C9D1FFDFC7E7022600214046FBF714F9FA +:1072A000002DC0D1FFDFBEE7FFDF3046BDE8FC8127 +:1072B0003EB50C0009D001466B4601AA002006F03D +:1072C0001DFF20B1FFF785FC3EBD10203EBD002014 +:1072D0002080A0709DF8050002A900F00700FEF7CD +:1072E0007BFE50B99DF8080020709DF8050002A9AA +:1072F000C0F3C200FEF770FE08B103203EBD9DF84A +:10730000080060709DF80500C109A07861F30410C1 +:10731000A0709DF80510890961F3C300A0709DF865 +:107320000410890601D5022100E0012161F3420029 +:107330009DF8001061F30000A07000203EBD70B504 +:10734000144606460D4651EA040005D075B10846BC +:10735000F9F7FDFF78B901E0072070BD29463046F6 +:1073600006F02DFF10B1BDE8704032E454B1204664 +:10737000F9F7EDFF08B1102070BD21463046BDE899 +:10738000704095E7002070BD2DE9FC5F0C469046EB +:107390000546002701780822007A3E46B2EB111F0D +:1073A0007ED104F10A0100910A31821E4FF0020AD7 +:1073B00004F1080B0191092A73D2DFE802F0ECDF37 +:1073C00005F427277AA9CD00688804210BF0DCFAA0 +:1073D000060000D1FFDFB08920B152270726C2E0A6 +:1073E0008C02002051271026002C7DD06888A080B8 +:1073F0000120A071A88900220099FFF7A0FF0028B2 +:1074000073D1A8892081288AE081D1E0B5F8129053 +:10741000072824D1E87B000621D5512709F1140063 +:1074200086B2002CE1D0A88900220099FFF787FFDF +:1074300000285AD16888A08084F806A0A8892081F5 +:107440000120A073288A2082A4F81290A88A0090B4 +:1074500068884B46A969019A01F04BFBA8E05027C8 +:1074600009F1120086B2002C3ED0A88900225946AC +:10747000FFF765FF002838D16888A080A889E080E0 +:10748000287A072813D002202073288AE081E87B1D +:10749000C0096073A4F81090A88A0090688801E081 +:1074A00083E080E04B4604F11202A969D4E7012091 +:1074B000EAE7B5F81290512709F1140086B2002CC2 +:1074C00066D0688804210BF05FFA83466888A08044 +:1074D000A88900220099FFF732FF00286ED184F8B6 +:1074E00006A0A889208101E052E067E00420A07393 +:1074F000288A2082A4F81290A88A009068884B46B7 +:10750000A969019A01F0F5FAA989ABF80E104FE0CC +:107510006888FBF798FF0746688804210BF034FA67 +:10752000064607B9FFDF06B9FFDF687BC00702D058 +:107530005127142601E0502712264CB36888A080FA +:10754000502F06D084F806A0287B594601F0E1FAB6 +:107550002EE0287BA11DF9E7FE49A88949898142CF +:1075600005D1542706269CB16888A08020E05327C7 +:107570000BE06888A080A889E08019E06888042171 +:107580000BF002FA00B9FFDF55270826002CF0D1D6 +:10759000A8F8006011E056270726002CF8D068886C +:1075A000A080002013E0FFDF02E0012808D0FFDF09 +:1075B000A8F800600CB1278066800020BDE8FC9F21 +:1075C00057270726002CE3D06888A080687AA0712E +:1075D000EEE7401D20F0030009B14143091D01EB16 +:1075E0004000704713B5DB4A00201071009848B185 +:1075F000002468460AF0E5FF002C02D1D64A009923 +:1076000011601CBD01240020F4E770B50D4606464C +:1076100086B014465C2128461EF09DF804B9FFDFB1 +:10762000A0786874A2782188284601F09CFA00208E +:10763000A881E881228805F11401304605F091FA0D +:107640006A460121304606F024FC19E09DF803004B +:10765000000715D5BDF806103046FFF730FD9DF840 +:107660000300BDF8061040F010008DF80300BDF8CF +:107670000300ADF81400FF233046059A06F06AFDBA +:10768000684606F012FC0028E0D006B070BD10B5C8 +:107690000C4601F1140005F09BFA0146627C20467D +:1076A000BDE8104001F094BA30B50446A94891B045 +:1076B0004FF6FF75C18905AA284606F0EAFB30E0BF +:1076C0009DF81E00A0422AD001282AD1BDF81C0036 +:1076D000B0F5205F03D042F60101884221D100209D +:1076E00002AB0AAA0CA9019083E8070007200090CA +:1076F000BDF81A1010230022284606F07DFC38B988 +:10770000BDF828000BAAC0B20CA90CF0CAFE10B13B +:10771000032011B030BD9DF82E00A04201D1002001 +:10772000F7E705A806F0C1FB0028C9D00520F0E75F +:1077300070B5054604210BF027F9040000D1FFDFE6 +:1077400004F114010C46284605F026FA2146284685 +:10775000BDE8704005F027BA70B58AB00C46064601 +:10776000FBF771FE050014D02878222827D30CB12E +:10777000A08890B101208DF80C0003208DF8100036 +:1077800000208DF8110054B1A088ADF818002068D1 +:1077900007E043F202000AB070BD0920FBE7ADF834 +:1077A00018000590042130460BF0EEF8040000D1DB +:1077B000FFDF04F1140005F022FA000701D40820CD +:1077C000E9E701F085FE60B108A802210094CDE947 +:1077D000011095F8232003A930466368FFF7F2FBF8 +:1077E000D9E71120D7E72DE9F04FB2F802A0834680 +:1077F00089B0154689465046FBF725FE0746042109 +:1078000050460BF0C1F80026044605964FF00208DA +:107810000696ADF81C6007B9FFDF04B9FFDF4146EB +:10782000504603F0BCFE50B907AA06A905A88DE88A +:1078300007004246214650466368FFF752FB454821 +:1078400007AB0660DDE9051204F11400CDF80090E5 +:10785000CDE90320CDE9013197F823205946504660 +:107860006B6805F015FA06000AD0022E04D0032E2C +:1078700014D0042E00D0FFDF09B03046BDE8F08FF1 +:10788000BDF81C000028F7D00599CDE9001042464C +:10789000214650466368FFF751FBEDE7687840F0FA +:1078A00008006870E8E72DE9F04F99B004464FF002 +:1078B00000082848ADF81C80ADF82080ADF8248081 +:1078C000A0F80880ADF81480ADF81880ADF82C80D1 +:1078D000ADF82880007916460D464746012808D0A5 +:1078E000022806D0032804D0042802D0082019B0AA +:1078F000C4E72046F9F7E7FC80BB2846F9F7E3FC2C +:1079000060BB6068F9F72CFD40BB606848B16089D6 +:107910002189884202D8B1F5007F01D90C20E6E721 +:1079200080460EAA06A92846FFF7CCF90028DED12A +:1079300068688078C0F34100022808D19DF81900DA +:1079400010F0380F03D02869F9F701FD30B905A907 +:10795000206904E08C0200201400002020E0FFF7E2 +:1079600069F90028C3D1206948B1607880079DF883 +:10797000150000F0380001D5F0B300E0E0BB9DF841 +:10798000140080060ED59DF8150010F0380F03D0B6 +:107990006068F9F7DCFC18B96068F9F7E1FC08B138 +:1079A0001020A4E70AA96069FFF744F900289ED1D6 +:1079B000606940B19DF8290000F0070101293CD120 +:1079C00010F0380F39D00BA9A069FFF733F9002860 +:1079D0008DD19DF8280080062FD49DF82C008006BC +:1079E0002BD4A06950B19DF82D0000F007010129AA +:1079F00023D110F0380F00E01FE01ED0E06818B16E +:107A00000078D0B11C2818D20FAA611C2046FFF7BD +:107A100080F90121384661F30F2082468DF852101B +:107A2000B94642F603000F46ADF850000DF13F0293 +:107A300018A928680CF054FD08B1072057E79DF8F5 +:107A4000600015A9CDF80090C01CCDE9019100F0AF +:107A5000FF0B00230BF20122514614A806F05CF93B +:107A6000F0BBBDF854000C90FD492A8928690092AA +:107A7000CDE901016B89BDF838202868069906F028 +:107A80004BF901007ED120784FF0020AC10601D4E3 +:107A900080062BD5ADF80C90606950B90AA906A8EC +:107AA000FFF768F99DF8290020F00700401C8DF8C9 +:107AB00029009DF8280008A940F0C8008DF828008A +:107AC0008DF8527042F60210ADF8500003AACDF8BE +:107AD00000A0CDE90121002340F2032214A800E018 +:107AE0001EE00A9906F018F901004BD1DC484D461A +:107AF00008385B460089ADF83D000FA8CDE902903B +:107B0000CDF80490CDF810904FF007090022CDF881 +:107B10000090BDF854104FF6FF7006F043F810B116 +:107B2000FFF757F8E3E69DF83C00000625D5294607 +:107B3000012060F30F218DF852704FF42450ADF8FE +:107B40005000ADF80C5062789DF80C00002362F3F1 +:107B500000008DF80C006278CDF800A0520862F3A6 +:107B600041008DF80C0003AACDE9012540F2032263 +:107B700014A806F0D1F8010004D1606888B3206928 +:107B8000A8B900E086E005A906A8FFF7F3F8607839 +:107B9000800706D49DF8150020F038008DF81500F8 +:107BA00005E09DF8140040F040008DF814008DF8B9 +:107BB000527042F60110ADF85000208940F20121C8 +:107BC000B0FBF1F201FB1202606809ABCDF8008056 +:107BD000CDE90103002314A8059906F09DF80100E2 +:107BE00058D12078C00729D0ADF80C50A06950B901 +:107BF0000BA906A8FFF7BEF89DF82D0020F007009E +:107C0000401C8DF82D009DF82C008DF8527040F02E +:107C100040008DF82C0042F60310ADF8500007A983 +:107C200003AACDF800A0CDE90121002340F20322F0 +:107C300014A80B9906F070F801002BD1E06868B326 +:107C40002946012060F30F218DF8527042F604108E +:107C5000ADF85000E068002302788DF85820407895 +:107C60008DF85900E06816AA4088ADF85A00E0681F +:107C700000798DF85C00E068C088ADF85D00CDF853 +:107C80000090CDE901254FF4027214A806F044F8E3 +:107C9000010003D00C9800F0C7FF28E670480321CC +:107CA0000838017156B100893080BDF82400708019 +:107CB000BDF82000B080BDF81C00F080002016E662 +:107CC00070B501258AB016460B46012802D002285D +:107CD00016D104E08DF80E504FF4205003E08DF8DB +:107CE0000E5042F60100ADF80C005BB10024601CA0 +:107CF00060F30F2404AA08A918460CF0F1FB18B190 +:107D0000072048E5102046E504A99DF820205448A6 +:107D1000CDE90021801E02900023214603A802F233 +:107D2000012205F0F9FF10B1FEF753FF33E54C488F +:107D300008380EB1C1883180057100202BE5F0B5FF +:107D400093B0074601268DF83E6041F60100ADF87C +:107D50003C0012AA0FA93046FFF7B2FF002848D115 +:107D60003F4C0025083CE7B31C2102A81DF0F3FCA2 +:107D70009DF808008DF83E6040F020008DF8080066 +:107D800042F60520ADF83C000E959DF83A0011959D +:107D900020F00600801C8DF83A009DF838006A46F5 +:107DA00020F0FF008DF838009DF8390009A920F077 +:107DB000FF008DF839000420ADF82C00ADF830003C +:107DC0000EA80A9011A80D900FA80990ADF82E509A +:107DD00002A8FFF768FD00280BD1BDF80000608104 +:107DE00000E008E0BDF80400A081401CE08125719E +:107DF000002013B0F0BD6581A581BDF84800F4E70F +:107E00002DE9F74F1649A0B00024083917940A79D4 +:107E1000A146012A04D0022A02D0082023B02DE571 +:107E2000CA88824201D00620F8E721988A46824219 +:107E300001D10720F2E701202146ADF848004FF6B6 +:107E4000FF788DF86E0042F6020B60F30F21ADF85B +:107E50004A80ADF86CB006918DF8724002E00000E7 +:107E6000940200201CA9ADF870401391ADF8508029 +:107E700012A806F03EF800252E462F460DAB07222D +:107E800012A9404606F038F878B10A285DD195B3BA +:107E90008EB3ADF86450ADF866609DF85E008DF865 +:107EA000144019AC012864D06BE09DF83A001FB370 +:107EB000012859D1BDF8381059451FD118A809A972 +:107EC00001940294CDE9031007200090BDF836100C +:107ED00010230022404606F08FF8B0BBBDF86000CA +:107EE000042801D006284AD1BDF8241021988142E7 +:107EF0003AD10F2092E73AE0012835D1BDF8380099 +:107F0000B0F5205F03D042F6010188422CD1BAF8C7 +:107F10000600BDF83610884201D1012700E0002795 +:107F200005B19EB1219881421ED118A809AA0194D9 +:107F30000294CDE90320072000900D461023002273 +:107F4000404606F059F800B902E02DE04E460BE03D +:107F5000BDF86000022801D0102810D1C0B217AAC5 +:107F600009A90CF09EFA50B9BDF8369086E70520B5 +:107F700054E705A917A8221D0CF0B2FA08B1032096 +:107F80004CE79DF814000023001DC2B28DF81420A8 +:107F900022980092CDE901401BA8069905F0BCFE8D +:107FA00010B902228AF80420FEF713FE36E710B556 +:107FB0000B46401E88B084B205AA00211846FEF781 +:107FC000A8FE00200DF1080C06AA05A901908CE876 +:107FD0000700072000900123002221464FF6FF7082 +:107FE00005F0E0FD0446BDF81800012800D0FFDFD1 +:107FF0002046FEF7EEFD08B010BDF0B5F74F044681 +:1080000087B038790E46032804D0042802D008200F +:1080100007B0F0BD04AA03A92046FEF753FE0500F1 +:10802000F6D160688078C0F3410002280AD19DF83B +:108030000D0010F0380F05D02069F9F788F908B164 +:108040001020E5E7208905AA21698DE807006389EA +:10805000BDF810202068039905F05EFE10B1FEF710 +:10806000B8FDD5E716B1BDF8140030800420387192 +:108070002846CDE7F8B50C0006460CD001464FF671 +:10808000FF7500236A46284606F038F828B100BF7D +:10809000FEF79FFDF8BD1020F8BD69462046FEF7AB +:1080A000C9FD0028F8D1A078314600F00103284628 +:1080B000009A06F04FF8EBE730B587B0144600227F +:1080C0000DF1080C05AD01928CE82C0007220092FE +:1080D0000A46014623884FF6FF7005F063FDBDF8A0 +:1080E00014102180FEF775FD07B030BD70B50D4648 +:1080F00004210AF049FC040000D1FFDF294604F105 +:108100001400BDE8704004F073BD70B50D46042145 +:108110000AF03AFC040000D1FFDF294604F1140004 +:10812000BDE8704004F087BD70B50D4604210AF02B +:108130002BFC040000D1FFDF294604F11400BDE848 +:10814000704004F09FBD70B5054604210AF01CFC88 +:10815000040000D1FFDF214628462368BDE87040B7 +:108160000122FEF705BF70B5064604210AF00CFC9B +:10817000040000D1FFDF04F1140004F029FD401DCC +:1081800020F0030511E0011D00880022431821465C +:108190003046FEF7EDFE00280BD0607CABB26843A2 +:1081A00082B2A068011D0AF0ACFAA06841880029DB +:1081B000E9D170BD70B5054604210AF0E5FB040065 +:1081C00000D1FFDF214628466368BDE870400222E7 +:1081D000FEF7CEBE70B50E46054601F079F90400F3 +:1081E00000D1FFDF0120207266726580207820F0C8 +:1081F0000F00001D20F0F00040302070BDE87040FE +:1082000001F069B910B50446012900D0FFDF20460E +:10821000BDE810400121FAF757B92DE9F04F97B0AA +:108220004FF0000A0C008346ADF814A0D04619D0D8 +:10823000E06830B1A068A8B10188ADF81410A0F8CA +:1082400000A05846FBF7FFF8070043F2020961D08F +:10825000387822285CD3042158460AF095FB0500A3 +:1082600005D103E0102017B0BDE8F08FFFDF05F166 +:10827000140004F0ADFC401D20F00306A078012896 +:1082800003D0022801D00720EDE7218807AA58462D +:1082900005F0FFFD30BB07A805F007FE10BB07A8DF +:1082A00005F003FE48B99DF82600012805D1BDF868 +:1082B0002400A0F52451023902D04FF45050D2E7E7 +:1082C000E068B0B1CDE902A00720009005AACDF882 +:1082D00004A00492A2882188BDF81430584605F005 +:1082E00061FC10B1FEF775FCBDE7A168BDF8140094 +:1082F00008809DF81F00C00602D543F20140B2E796 +:108300000B9838B1A1780078012905D080071AD4DC +:108310000820A8E74846A6E7C007F9D002208DF854 +:108320003C00A8684FF00009A0B1697C4288714305 +:1083300091420FD98AB2B3B2011D0AF098F9804672 +:10834000A0F800A006E003208DF83C00D5F80080DE +:108350004FF001099DF8200010F0380F00D1FFDF29 +:108360009DF820001E49C0F3C200084497F823106E +:1083700010F8010C884201D90F2074E72088ADF86D +:10838000400014A90095CDE90191434607220FA9A9 +:108390005846FEF717FE002891D19DF8500050B9BD +:1083A000A078012807D1687CB3B2704382B2A86874 +:1083B000011D0AF070F9002055E770B50646154614 +:1083C0000C460846FEF7C4FB002805D12A46214684 +:1083D0003046BDE8704073E470BD11E58C020020AA +:1083E0000E5B020070B51E4614460D0009D044B164 +:1083F000616831B138B1FC49C988814203D0072096 +:1084000070BD102070BD2068FEF7A2FB0028F9D1D6 +:10841000324621462846BDE87040FFF744BA70B5A1 +:1084200015460C0006D038B1EF490989814203D0C6 +:10843000072070BD102070BD2068FEF789FB002862 +:10844000F9D129462046BDE87040D6E570B506460C +:1084500086B00D4614461046F8F75BFFD0BB606847 +:10846000F8F77EFFB0BBA6F57F40FF3803D030465B +:10847000FAF7E9FF80B128466946FEF79DFC00281F +:108480000CD19DF810100F2008293DD2DFE801F033 +:1084900008060606060A0A0843F2020006B070BD86 +:1084A0000320FBE79DF80210012908D1BDF8001058 +:1084B000B1F5C05FF2D06FF4C052D142EED09DF85A +:1084C000061001290DD1BDF80410A1F52851062987 +:1084D00007D200E029E0DFE801F00303040303030F +:1084E000DCE79DF80A1001290FD1BDF80810B1F59D +:1084F000245FD3D0A1F60211B1F50051CED00129ED +:10850000CCD0022901D1C9E7FFDF606878B9002328 +:1085100005AA2946304605F0F1FD10B1FEF759FBDA +:10852000BCE79DF81400800601D41020B6E76188EE +:10853000224628466368FFF7BFFDAFE72DE9F04309 +:10854000814687B0884614461046F8F7E2FE18B117 +:10855000102007B0BDE8F083002306AA4146484634 +:1085600005F0CCFD18B100BFFEF733FBF1E79DF835 +:108570001800C00602D543F20140EAE700250727AC +:1085800005A8019500970295CDE9035062884FF642 +:10859000FF734146484605F02FFD060013D1606881 +:1085A000F8F7B7FE60B960680195CDE90250009711 +:1085B0000495238862884146484605F01DFD06461D +:1085C000BDF8140020803046CEE739B1864B0A88CA +:1085D0009B899A4202D843F2030070471DE610B50A +:1085E00086B0814C0423ADF81430638943B1A4896B +:1085F0008C4201D2914205D943F2030006B010BD6E +:108600000620FBE7ADF81010002100910191ADF8B4 +:10861000003002218DF8021005A9029104A90391EE +:10862000ADF812206946FFF7F8FDE7E72DE9FC47B2 +:1086300081460D460846F8F746FE88BB4846FAF7DD +:1086400002FF5FEA00080AD098F80000222829D328 +:10865000042148460AF098F9070005D103E043F2E7 +:108660000200BDE8FC87FFDF07F1140004F0C7FA41 +:1086700006462878012803D0022804D00720F0E716 +:10868000B0070FD502E016F01C0F0BD0A8792C1DF7 +:10869000C00709D0E08838B1A068F8F714FE18B117 +:1086A0001020DEE70820DCE721882A780720B1F5D2 +:1086B000847F35D01EDC40F20315A1F20313A942DA +:1086C00026D00EDCB1F5807FCBD003DCF9B10129D7 +:1086D00026D1C6E7A1F58073013BC2D0012B1FD183 +:1086E00013E0012BBDD0022B1AD0032BB9D0042BE1 +:1086F00016D112E0A1F20912082A11D2DFE802F025 +:108700000B04041010101004ABE7022AA9D007E0F4 +:10871000012AA6D004E0320700E0F206002AA0DA1F +:10872000CDB200F0D5FE50B198F82300CDE9000598 +:10873000FA89234639464846FEF78FFC91E7112017 +:108740008FE72DE9F04F8BB01F4615460C46834648 +:108750000026FAF778FE28B10078222805D20820F2 +:108760000BB081E543F20200FAE7B80801D0072018 +:10877000F6E7032F00D100274FF6FF79CCB1022D89 +:1087800073D32046F8F7ECFD30B904EB0508A8F1E7 +:108790000100F8F7E5FD08B11020E1E7AD1EAAB22F +:1087A0002146484605F085FD38F8021C88425CD118 +:1087B000ADB20D49B80702D58889401C00E0012000 +:1087C0001FFA80F8F80701D08F8900E04F4605AA0C +:1087D0004146584605F05DFB4FF0070A4FF000098F +:1087E000DCB320460BE000008C02002040881028FB +:1087F0003BD8361D304486B2AE4236D2A01902882C +:108800004245F3D351E000BF9DF8170002074CD555 +:1088100094B304EB0608361DB8F80230B6B2102B3C +:1088200023D89A19AA4220D8B8F8002091421CD126 +:10883000C0061CD5CDE900A90DF1080C0AAAA119A2 +:1088400048468CE80700B8F800100022584605F0AA +:10885000A9F920B1FEF7BDF982E726E005E0B8F8F6 +:108860000200BDF82810884201D00B2078E7B8F844 +:108870000200304486B207E0FFE7C00604D5584640 +:10888000FEF71DFC002888D19DF81700BDF81A10CE +:1088900020F010008DF81700BDF81700ADF80000AB +:1088A000FF235846009A05F055FC05A805F0FDFA8F +:1088B00018B9BDF81A10B942A6D9042158460AF0D1 +:1088C00063F8040000D1FFDFA2895AB1CDE900A905 +:1088D0004D46002321465846FEF7BFFB0028BBD17A +:1088E000A5813DE700203BE72DE9FF4F8BB01E46F9 +:1088F00017000D464FF0000412D0B00802D0072038 +:108900000FB0B1E4032E00D100265DB10846F8F7A0 +:108910001EFD28B93888691E0844F8F718FD08B10B +:108920001020EDE7C64AB00701D5D18900E001214A +:10893000F0074FF6FF7802D0D089401E00E0404695 +:1089400086B206AA0B9805F0A4FA4FF000094FF082 +:10895000070B0DF1140A38E09DF81B00000734D511 +:10896000CDF80490CDF800B0CDF80890CDE9039A89 +:10897000434600220B9805F03FFB60BB05B3BDF8F2 +:1089800014103A8821442819091D8A4230D3BDF8B1 +:108990001E2020F8022BBDF8142020F8022BCDE970 +:1089A00000B9CDE90290CDF810A0BDF81E10BDF8B9 +:1089B000143000220B9805F01FFB08B103209FE73D +:1089C000BDF814002044001D84B206A805F06DFA1D +:1089D00020B10A2806D0FEF7FCF891E7BDF81E107A +:1089E000B142B9D934B17DB13888A11C884203D2D3 +:1089F0000C2085E7052083E722462946404605F0FE +:108A000058FC014628190180A41C3C80002077E70F +:108A100010B50446F8F77DFC08B1102010BD884859 +:108A2000C0892080002010BDF0B58BB00D460646F1 +:108A3000142103A81CF08FFE01208DF80C008DF886 +:108A4000100000208DF81100ADF814503046FAF7F0 +:108A5000FAFC48B10078222812D30421304609F0EC +:108A600093FF040005D103E043F202000BB0F0BD18 +:108A7000FFDF04F11400074604F0C1F8800601D4BA +:108A80000820F3E7207C022140F00100207409A8AF +:108A90000094CDE90110072203A930466368FEF770 +:108AA00091FA20B1217C21F001012174DEE72946F1 +:108AB0003046F9F7FAFC08A9384604F08FF800B1FF +:108AC000FFDFBDF82040172C01D2172000E0204620 +:108AD000A84201D92C4602E0172C00D217242146C7 +:108AE0003046FFF712FB21463046F9F704FA002022 +:108AF000BCE7F8B51C4615460E46069F0AF076F808 +:108B00002346FF1DBCB231462A46009409F061FCA1 +:108B1000F8BD70B50C4605460E2120461CF0F9FD47 +:108B2000002020802DB1012D01D0FFDF70BD062077 +:108B300000E00520A07170BD10B54880087813468C +:108B400020F00F00001D20F0F00080300C4608706F +:108B50001422194604F108001CF0A1FD00F0BBFC32 +:108B60003748046010BD2DE9F047DFF8D890491D63 +:108B7000064621F0030117460C46D9F8000009F01B +:108B80003EFD050000D1FFDF4FF000083560A5F87D +:108B900000802146D9F8000009F031FD050000D120 +:108BA000FFDF7560A5F800807FB104FB07F1091DA8 +:108BB0000BD0D9F8000009F022FD040000D1FFDF3E +:108BC000B460C4F80080BDE8F087C6F80880FAE712 +:108BD0002DE9F0411746491D21F00302194D0646C3 +:108BE00001681446286809F035FD22467168286836 +:108BF00009F030FD3FB104FB07F2121D03D0B1684C +:108C0000286809F027FD042009F066FE04460420C8 +:108C100009F06AFE201A012804D12868BDE8F04155 +:108C200009F0E2BCBDE8F08110B50C4605F0FDF896 +:108C300000B1FFDF2046BDE81040FDF7CABF0000CD +:108C40008C0200201400002038B50C468288817BFD +:108C500019B14189914200D90A462280C188121D6A +:108C600090B26A4608F02BFFBDF80000032800D33D +:108C70000320C1B2208800F0D7FF38BD38B50C46BC +:108C80008288817B19B10189914200D90A462280EC +:108C9000C188121D90B26A4608F011FFBDF80000AD +:108CA000022800D30220C1B2208800F0BDFF401C82 +:108CB000C0B238BD2DE9FE4F82468B46F9481446B6 +:108CC0000BF10302D0E90010CDE9011022F00302FC +:108CD00068464FF49071009209F073FCF24E002C3C +:108CE00002D1F24A00999160009901440091357FC8 +:108CF00005F1010504D1E8B20BF06CFB00B1FFDF18 +:108D0000009800EB0510C01C20F0030100915CB935 +:108D1000707AB27A1044C2B200200870308C80B2EF +:108D200004F00BFF00B1FFDF0098316A08440090A7 +:108D30002146684600F03BFF80460098C01C20F0AA +:108D400003000090B37AF27A717A04B1002009F03E +:108D50002EFD0099084400902146684600F06FFF00 +:108D6000D14800273D4690F801900CE0284600F0DD +:108D700001FF064681788088F9F754F971786D1CF7 +:108D800000FB0177EDB24D45F0D10098C01C20F0FA +:108D90000300009004B100203946F9F74EF900991C +:108DA000002708440090C0483D4690F801900CE030 +:108DB000284600F0DFFE0646C1788088FEF709FCF1 +:108DC00071786D1C00FB0177EDB24D45F0D1009834 +:108DD000C01C20F00300009004B100203946FEF7CB +:108DE00001FC00994FF0000908440090AE484D4640 +:108DF00047780EE0284600F0BDFE0646807B30B185 +:108E000006F1080001F00FFF727800FB02996D1C5B +:108E1000EDB2BD42EED10098C01C20F003000090DE +:108E200004B10020494601F002FF00990844009077 +:108E30002146684600F075FE0098C01D20F007002E +:108E40000090DAF80010814204D3A0EB0B01B1F5D9 +:108E5000803F04DB4FF00408CAF8000004E0CAF8C1 +:108E60000000B8F1000F02D04046BDE8FE8F34BBD1 +:108E70008F490020009A03F079F8FBF764FA8A48DA +:108E800001AA00211030F8F7E9FA00B1FFDF8648A7 +:108E9000407FFEF754FF00B1FFDF83484FF4F671C7 +:108EA00040301CF058FC80480421403080F8E91123 +:108EB00080F8EA11062180F8EB11032101710020EE +:108EC000D3E770B5784C06464034207804EB401563 +:108ED000E078083590B9A01990F8E80100280ED084 +:108EE000A0780F2800D3FFDF202128461CF033FC98 +:108EF000687866F3020068700120E070284670BD53 +:108F00002DE9F04105460C460027007805219046E2 +:108F10003E46B1EB101F00D0FFDF287A50B1012888 +:108F20000ED0FFDFA8F800600CB12780668000201B +:108F3000BDE8F0810127092674B16888A08008E0A7 +:108F40000227142644B16888A0802869E060A88AB6 +:108F50002082287B2072E5E7A8F80060E7E730B5BB +:108F6000514C012000212070617020726072032238 +:108F7000A272E07221732174052121831F21618374 +:108F800060744CA161610A2121776077474D4FF4ED +:108F9000B06020626868C11C21F00301814200D0EA +:108FA000FFDF6868606030BD30B5404C15686368AD +:108FB00010339D4202D20420136030BD3A4B5D78DD +:108FC0005A6802EB0512107051700320D0801720F0 +:108FD00090800120D0709070002090735878401CD1 +:108FE0005870606810306060002030BD70B5064673 +:108FF0002D480024457807E0204600F0BBFD0178AD +:10900000B14204D0641CE4B2AC42F5D1002070BD82 +:10901000F7B5074608780C4610B3FFF7E7FF05469B +:10902000A7F12006202F06D0052E19D2DFE806F082 +:109030000F2B2B151A0000F0A8FD0DB1697800E088 +:109040000021401AA17880B20844FF2808D8A078EF +:1090500030B1A088022831D202E0608817282DD2D2 +:109060000720FEBD207AE0B161881729F8D3A188D6 +:109070001729F5D3A1790029F2D0E1790029EFD0A1 +:10908000402804D9ECE7242F18D1207A48B1618810 +:109090004FF6FB70814202D8A18881420ED904208C +:1090A000FEBD0BE0145B0200A803002018000020A6 +:1090B000000000206E5246357800000065B9207827 +:1090C00002AA0121FFF770FF0028E9D12078FFF7FD +:1090D0008DFF050000D1FFDF052E18D2DFE806F076 +:1090E000030B0E081100A0786870A088E8800FE0DC +:1090F0006088A8800CE0A078A87009E0A078E870EB +:1091000006E054F8020FA8606068E86000E0FFDF46 +:109110000020C5E71A2835D00DDC132832D2DFE84D +:1091200000F01B31203131272723252D3131293102 +:109130003131312F0F00302802D003DC1E2821D11D +:10914000072070473A3809281CD2DFE800F0151BC9 +:109150000F1B1B1B1B1B07000020704743F2040062 +:10916000704743F202007047042070470D2070479B +:109170000F20704708207047112070471320704758 +:10918000062070470320704710B5007800F00100FA +:1091900008F087FCBDE81040BCE710B5007800F08F +:1091A000010008F087FCBDE81040B3E70EB5017878 +:1091B00001F001018DF80010417801F001018DF8F6 +:1091C00001100178C1F340018DF802104178C1F31C +:1091D00040018DF80310017889088DF8041041785A +:1091E00089088DF8051081788DF80610C1788DF802 +:1091F000071000798DF80800684607F097FAFFF726 +:1092000089FF0EBD2DE9F84FDFF8F883FE4C0026EC +:109210004FF490771FE0012000F054FD0120FFF78C +:1092200050FE05463946D8F8080009F0E8F96860AC +:1092300000B9FFDF686807F008F9B0B12846FAF70F +:10924000E9FB284600F044FD28B93A466968D8F899 +:10925000080009F0FFF994F9E9010428DBDA02209B +:1092600009F03AFB07460025A5E03A466968D8F8B8 +:10927000080009F0EFF9F2E7B8F802104046491C7F +:1092800089B2A8F80210B94201D30021418002211D +:10929000B8F8020009F078FB002864D0B8F80200A2 +:1092A000694608F070FBFFF735FF00B1FFDF9DF85E +:1092B000000078B1B8F8020009F0AAFC5FEA0009E2 +:1092C00000D1FFDF484608F018FF18B1B8F80200D7 +:1092D00002F054F9B8F8020009F088FC5FEA0009CE +:1092E00000D1FFDF484608F000FFE0BB0321B8F8DB +:1092F000020009F049FB5FEA000B47D1FFDF45E0C0 +:10930000DBF8100010B10078FF2849D0022000F0EF +:10931000D9FC0220FFF7D5FD8246484608F0F1FF50 +:10932000CAF8040000B9FFDFDAF8040009F0B9F860 +:10933000002100900170B8F802105046AAF80210FF +:1093400001F01EFE484609F0AEF800B9FFDF5046B6 +:1093500000F0BEFC18B99AF80100000704D5009887 +:10936000CBF8100012E024E0DBF8100038B10178EF +:10937000491C11F0FF01017008D1FFDF06E0002257 +:109380001146484600F0CBFB00B9FFDF94F9EA0133 +:10939000022805DBB8F8020001F0B7FD0028AFD1C4 +:1093A00094F9E901042804DB484609F0E0F800B12B +:1093B00001266D1CEDB2BD4204D294F9EA010228E7 +:1093C000BFF65AAF002E7FF422AFBDE8F84F03205E +:1093D00000F078BC10B58B4CE06008682061AFF2FB +:1093E000DB10F9F77AFD607010BD87480021403826 +:1093F00001708448017085494160704770B5054629 +:109400004FF080500C46D0F8A410491C05D1D0F87C +:10941000A810C9430904090C0BD050F8A01F01F093 +:1094200001012970416821608068A080287830B9E6 +:1094300070BD062120460CF0E2FC01202870607906 +:1094400040F0C000607170BD70B54FF080540D46A3 +:10945000D4F88010491C0BD1D4F88410491C07D1D2 +:10946000D4F88810491C03D1D4F88C10491C0CD0B6 +:10947000D4F880100160D4F884104160D4F88810CA +:109480008160D4F88C10C16002E010210CF0B7FCB0 +:10949000D4F89000401C0BD1D4F89400401C07D1A4 +:1094A000D4F89800401C03D1D4F89C00401C09D08B +:1094B00054F8900F286060686860A068A860E06851 +:1094C000E86070BD2846BDE8704010210CF097BCE4 +:1094D0004D480079F5E470B54B4CE07830B3207816 +:1094E00004EB4010407A00F00700204490F9E801B6 +:1094F000002800DCFFDF2078002504EB4010407AD4 +:1095000000F00700011991F8E801401E81F8E80118 +:109510002078401CC0B220700F2800D12570A078A0 +:10952000401CA0700CF062FBE57070BDFFDF70BDE9 +:109530003EB50546032109F027FA0446284609F0FE +:1095400055FB054604B9FFDF206918B10078FF28F4 +:1095500000D1FFDF01AA6946284600F0E0FA60B9B1 +:10956000FFDF0AE0002202A9284600F0D8FA00B97D +:10957000FFDF9DF8080000B1FFDF9DF80000411EED +:109580008DF80010EED220690199884201D10020A7 +:1095900020613EBD70B50546A0F57F400C46FF3802 +:1095A00000D1FFDF012C01D0FFDF70BDFFF790FF7E +:1095B000040000D1FFDF207820F00F00401D20F0D4 +:1095C000F000503020706580002020720120207350 +:1095D000BDE870407FE72DE9F04116460D4607468D +:1095E000FFF776FF040000D1FFDF207820F00F00A6 +:1095F000401D20F0F0005030207067800120207264 +:10960000286805E018000020E8030020F813002077 +:109610002061A888A0822673BDE8F0415BE77FB592 +:10962000FFF7E4FC040000D1FFDF02A92046FFF7AA +:109630000BFB054603A92046FFF720FB8DF80050E1 +:109640008DF80100BDF80800001DADF80200BDF85E +:109650000C00001DADF80400E088ADF80600684677 +:1096600008F007FA002800D0FFDF7FBD2DE9F041A8 +:10967000FB4C0646207808B1082059E43046F7F73D +:1096800048FE08B1102053E4F64D287808B9FFF7DA +:1096900066FCA87A697A0844C7B200F076FAB84244 +:1096A00007D2381AC1B232460020FFF77DFC0028ED +:1096B000E3D16068C01C20F00300606000F05DFB37 +:1096C000616801220844804601463046FFF7F2FAFD +:1096D000070012D00020FFF789FC06000BD006F12E +:1096E0001300616820F00300884200D0FFDF687833 +:1096F000401E6870666038461AE4002241463046D3 +:10970000FFF7D8FA00B1FFDF306860604FF6FF70F6 +:1097100060800120207000200AE42DE9F041044619 +:10972000CF4817460E46007808B10820A5E708463E +:10973000F7F7C9FD08B110209FE7CA4D287808B98E +:10974000FFF70DFC601E1E2807D8012C22D13078AF +:10975000FE281FD8287700208FE7A4F120001F28BB +:1097600005D8E0B23A463146BDE8F04150E4A4F1F4 +:1097700040001F2805D831462046BDE8F04100F0E2 +:10978000CFBAA4F1A0001F2804D80020A02C03D039 +:10979000A12C06D0072070E7317801F0010169772C +:1097A0006BE731680922F82901D38B0701D01046F5 +:1097B00063E76B7C03F00303012B04D16B8BD7337E +:1097C0009CB28C42F3D8296257E72DE9F0478146D5 +:1097D0000E460846F7F79DFD48B94846F7F7B7FD2E +:1097E00028B909F1030020F00301494502D01020F7 +:1097F000BDE8F0879B484FF0000A4030817869B19E +:109800004178804600EB4114083437883246002105 +:10981000204600F06BFA050004D027E0A6F800A06F +:109820000520E5E7B9F1000F24D03088B84201D90E +:109830000C251FE0607800F00705284600F042FA8A +:1098400008EB0507324697F8E8014946401C87F8BF +:10985000E801204607F5F47700F048FA0546387825 +:10986000401E3870032000F02DFA2DB10C2D01D0D0 +:10987000A6F800A02846BBE76078794E00F0070103 +:10988000012923D002290CD0032934D0FFDF98F816 +:1098900001104046491CC9B288F801100F2935D083 +:1098A00036E0616821B1000702D46088FFF740FE0E +:1098B00098F8EA014746012802D17078F9F72CFBA5 +:1098C00097F9EA010428E2DBFFDFE0E7616821B1F4 +:1098D0004FF49072B06808F0BDFE98F8E901474671 +:1098E000032802D17078F9F717FB97F9E9010428EA +:1098F000CDDBFFDFCBE7C00602D56088FFF718FE9F +:1099000098F9EB010628C2DBFFDFC0E780F801A071 +:109910008178491E8170617801F0070101EB080030 +:1099200090F8E811491C80F8E811A3E770B50D46DE +:109930000446F7F7C8FC18B92846F7F7EAFC08B15F +:10994000102070BD29462046BDE870400AF079BD60 +:1099500070B505460AF098FDC4B22846F7F7F7FC43 +:1099600008B1102070BD35B128782C7018B1A04214 +:1099700001D0072070BD2046FDF796FE052805D1D1 +:109980000AF086FD012801D0002070BD0F2070BDB7 +:1099900070B5044615460E460846F7F794FC18B90C +:1099A0002846F7F7B6FC08B1102070BD022C03D092 +:1099B000102C01D0092070BD2A46314620460AF0FD +:1099C00070FD0028F7D0052070BD70B514460D4617 +:1099D0000646F7F778FC38B92846F7F79AFC18B925 +:1099E0002046F7F7B4FC08B1102070BD2246294686 +:1099F00030460AF075FD0028F7D0072070BD3EB54F +:109A00000446F7F786FC08B110203EBD684606F014 +:109A1000F4FDFFF77FFB0028F7D19DF806002070CA +:109A2000BDF808006080BDF80A00A08000203EBD9F +:109A300070B505460C460846F7F789FC20B93CB1DD +:109A40002068F7F766FC08B1102070BDA08828B127 +:109A500021462846BDE87040FDF77EBE092070BD56 +:109A600018000020A803002070B504460D460846E3 +:109A7000F7F729FC30B9601E1E2814D82846F7F7DE +:109A800022FC08B11020EAE7032C01D90720E6E701 +:109A900004B9FFDFFC4800EB840050F8041C2846A2 +:109AA000BDE870400847A4F120001F2805D82946CA +:109AB0002046BDE87040FAF7CEBBF02CE6D1A8688E +:109AC000F7F701FC0028DDD1284608F03AF8BDE898 +:109AD0007040FFF71FBB70B504460D460846F7F708 +:109AE00018FC30B9601E1E280FD82846F7F7EBFB8C +:109AF00008B11020B3E7012C03D0022C01D0032CB5 +:109B000001D10620ABE70720A9E7A4F120001F2818 +:109B1000F9D829462046BDE87040FAF7F4BB08F0B2 +:109B2000B3BA38B50446D948007B00F00105D9B96D +:109B300004F064FB0DB1226800E00022D4484178B3 +:109B4000C06806F048FCD2481030C0788DF800009C +:109B500010B1012802D004E0012000E000208DF8BF +:109B60000000684606F0C3FD002D02D020682830B2 +:109B7000206038BD30B5C54D04466878A04200D895 +:109B8000FFDF686800EB041030BD70B5BF480025EA +:109B90002C46467807E02046FFF7ECFF4078641C2F +:109BA0002844C5B2E4B2B442F5D1284657E72DE9BE +:109BB000F0410C4607464FF0000800F00CF906464D +:109BC000FF2801D94FF013083868C01C20F00302A9 +:109BD0003A6054EA080421D1AC48F3B2072124309A +:109BE0000CF012FB09E0072C10D2DFE804F00604A9 +:109BF00008080A040600A74804E0A74802E0A748AE +:109C000000E0A7480CF020FB054600E0FFDFA5427E +:109C100000D0FFDF641CE4B2072CE4D3386800EB0B +:109C200006103860404628E5021D5143452900D200 +:109C300045210844C01CB0FBF2F0C0B270472DE9CA +:109C4000FC5F064691484FF000088B464746444665 +:109C500090F8019022E02046FFF78CFF050000D12C +:109C6000FFDF687869463844C7B22846FEF7ECFF44 +:109C7000824601A92846FFF701F80346BDF8040013 +:109C80005246001D81B2BDF80000001D80B208F0F0 +:109C9000F9FE6A78641C00FB0288E4B24C45DAD114 +:109CA0003068C01C20F003003060BBF1000F00D012 +:109CB00000204246394608F0F3FE3168084430601F +:109CC000BDE8FC9F7149403108710020C8707047A1 +:109CD0006E494031CA782AB10A7801EB4211083145 +:109CE000814201D001207047002070472DE9F041EA +:109CF00006460078154600F00F0400201080601E14 +:109D00000F46052800D3FFDF5F482A46183800EBCE +:109D10008400394650F8043C3046BDE8F04118470D +:109D200070B50C46402802D0412806D120E0A0782A +:109D300061780D18E178814201D907208FE62078FB +:109D4000012801D913208AE6FF2D08D80AF032FD38 +:109D500006460BF003FF301A801EA84201DA1220DB +:109D60007DE64A482168816021790173002076E60A +:109D7000BDE87040084600F059B82DE9F0470027CB +:109D8000DFF808A13E463D46B9463C469AF80180B8 +:109D90000AE02046FFF7EEFE4178807B0E4410FB80 +:109DA0000155641CE4B27F1C4445F2D109EB8700E5 +:109DB000C6EBC60100EB81009AF8092000EB850193 +:109DC00001EBC2019AF80A209AF80B0001EBC201DC +:109DD00001EB80000CE52DE9F047DFF8B09000269C +:109DE000344699F8090099F80A2099F8017002445C +:109DF000D5B299F80B20104400F0FF0808E0204687 +:109E0000FFF7B8FE817B407811FB0066641CE4B26A +:109E1000BC42F4D199F8091099F80A002944294460 +:109E2000414400B1012008443044E1E438B504461F +:109E3000407800F00300012803D002280BD007204F +:109E400038BD606858B1F7F78BFAD0B96068F7F79A +:109E50007EFA20B915E06068F7F735FA88B96946E7 +:109E60002046FCF79DF80028EAD1607800F0030056 +:109E7000022817D19DF80000A0B16068F7F767FAD3 +:109E800080B1102038BD0000345B0200A803002020 +:109E90001800002057410000FBAC0000E92F000033 +:109EA000C74101006189F8290DD8208988420AD864 +:109EB000607800F003020A48012A06D1D731026A0D +:109EC00089B28A4201D20920DCE794E80E0000F151 +:109ED000100585E80E000AB9002101830020D1E7B2 +:109EE000A80300202DE9F04107461446884608469D +:109EF00001F022FD064608EB88001C22796802EB7F +:109F0000C0000D18688C58B14146384601F01CFD60 +:109F1000014678680078C200082305F120000CE0B3 +:109F2000E88CA8B14146384601F015FD0146786835 +:109F300008234078C20005F1240008F0E2FB38B1A4 +:109F4000062121726681D0E90010C4E9031009E0FE +:109F5000287809280BD00520207266816868E060A7 +:109F6000002028702046BDE8F04101F0DBBC07204E +:109F700020726681F4E72DE9F04116460D4607464A +:109F8000406801EB85011C2202EBC1014418204608 +:109F900001F003FD40B10021708865F30F2160F3EB +:109FA0001F4106200CF00AFA09202070324629468B +:109FB0003846BDE8F04195E72DE9F0410E460746E9 +:109FC00000241C21F07816E004EB8403726801EB96 +:109FD000C303D25C6AB1FFF77BFA050000D1FFDF53 +:109FE0006F802A4621463046FFF7C5FF0120BDE8B5 +:109FF000F081641CE4B2A042E6D80020F7E770B517 +:10A00000064600241C21C0780AE000BF04EB84034C +:10A01000726801EBC303D5182A782AB1641CE4B234 +:10A02000A042F3D8402070BD282128461BF071FBC8 +:10A03000706880892881204670BD70B50346002075 +:10A040001C25DC780DE000BF00EB80065A6805EBAC +:10A05000C6063244167816B1128A8A4204D0401CD1 +:10A06000C0B28442F0D8402070BDF0B50446002054 +:10A070001C26E5780EE000BF00EB8007636806EB66 +:10A08000C7073B441F788F4202D15B78934204D0CC +:10A09000401CC0B28542EFD84020F0BD00780328B4 +:10A0A00001D000207047012070470078022801D0BD +:10A0B00000207047012070470078072801D0002059 +:10A0C0007047012070472DE9F04106468846107818 +:10A0D000F1781546884200D3FFDF2C781C27641CDA +:10A0E000F078E4B2A04201D8201AC4B204EB840193 +:10A0F000706807EBC1010844017821B141468847E7 +:10A1000008B12C7073E72878A042E8D1402028706D +:10A110006DE770B514460B880122A240134207D1A7 +:10A1200013430B8001230A22011D08F0B4FA0470C6 +:10A1300070BD2DE9FF4F81B00878DDE90E7B9A46AE +:10A1400091460E4640072CD4019808F061FD0400AA +:10A1500000D1FFDF07F1040820461FFA88F107F05D +:10A16000A0FE050000D1FFDF204629466A4608F020 +:10A17000EAF80098A0F80370A0F805A0284608F0B7 +:10A1800090F9017869F306016BF3C711017020465D +:10A190001FFA88F107F0C8FE00B9FFDF019806F04A +:10A1A0008CF806EB0900017F491C017705B0BDE87A +:10A1B000F08F2DE9F84F0E469A4691460746032147 +:10A1C00008F0E2FB0446008DDFF8B885002518B1E1 +:10A1D00098F80000B0421ED1384608F019FD07007B +:10A1E00000D1FFDF09F10401384689B207F059FEBA +:10A1F000050010D0384629466A4608F0A4F80098B1 +:10A2000000210A460180817006F010F90098C01DF7 +:10A21000CAF8000021E098F80000B04216D104F11D +:10A22000260734F8341F012000FA06F911EA090F55 +:10A2300000D0FFDF2088012340EA090020800A22A5 +:10A24000391D384608F042FA067006E0324604F13D +:10A25000340104F12600FFF75CFF0A2188F80010A2 +:10A260002846BDE8F88FFEB515460C46064602ABFB +:10A270000C220621FFF79DFF002827D00299607865 +:10A2800012220A70801C487008224A80A07002982E +:10A290002988052381806988C180A9880181E9888E +:10A2A000418100250C20CDE90005062221463046DB +:10A2B000FFF73FFF2946002266F31F41F0231046B7 +:10A2C0000BF0D2FF6078801C60700120FEBDFEB5EF +:10A2D00014460D460622064602AB1146FFF769FFFB +:10A2E000002812D0029B132000211870A878587003 +:10A2F000022058809C800620CDE9000102460523FB +:10A3000029463046FFF715FF0120FEBD2DE9FE432B +:10A310000C46804644E002AB0E2207214046FFF780 +:10A3200048FF002841D060681C2267788678BF1CEF +:10A3300006EB860102EBC101451802981421017059 +:10A3400047700A214180698A0181E98A4181A9888F +:10A350008180A9898181304601F0EEFA02990523B6 +:10A360000722C8806F700420287000250E20CDE9D8 +:10A37000000521464046FFF7DCFE294666F30F2123 +:10A3800068F31F41F023002206200BF06DFF607878 +:10A39000FD49801C607062682046921CFFF793FEA6 +:10A3A000606880784028B6D10120BDE8FE83FEB504 +:10A3B0000D46064638E002AB0E2207213046FFF775 +:10A3C000F8FE002835D068681C23C17801EB8102B3 +:10A3D00003EBC20284180298152202706278427060 +:10A3E0000A224280A2894281A2888281084601F025 +:10A3F000A3FA014602988180618AC180E18A0181C5 +:10A40000A088B8B10020207000210E20CDE9000105 +:10A410000523072229463046FFF78BFE6A68DB4991 +:10A420002846D21CFFF74FFE6868C0784028C2D18A +:10A430000120FEBD0620E6E72DE9FE430C468146DD +:10A4400044E0204601F093FAD0B302AB0822072182 +:10A450004846FFF7AEFE0028A7D060681C2265784A +:10A460000679AD1C06EB860102EBC1014718029884 +:10A47000B7F81080062101704570042141803046F4 +:10A4800001F05AFA0146029805230722C180A0F87C +:10A4900004807D70082038700025CDE90005214634 +:10A4A0004846FFF746FE294666F30F2169F31F4130 +:10A4B000F023002206200BF0D7FE6078801C60702D +:10A4C0006268B3492046121DFFF7FDFD60680179FF +:10A4D0004029B6D1012068E72DE9F34F83B00E463D +:10A4E00080E0304601F043FA002875D071681C20E6 +:10A4F00091F8068008EB880200EBC2000C18414678 +:10A50000304601F028FA0146A078C3007068407810 +:10A51000C20004F1240008F010F907468088E18B9E +:10A52000401A80B2002581B3AA46218B814200D80F +:10A5300008468146024602AB07210398FFF739FE21 +:10A54000010028D0BAF1000F03D0029AB888022582 +:10A5500010808B46E28B3968A9EB05001FFA80FA60 +:10A560000A440398009208F053FBED1D009A5946E7 +:10A570005346009507F061FFE08B504480B2E083C2 +:10A58000B988884209D1012508E0FFE7801C4FF017 +:10A59000010A80B2C9E7002008E60025CDE9009550 +:10A5A000238A072231460398FFF7C3FDE089401E46 +:10A5B000E0818DB1A078401CA0707068F17842787D +:10A5C00011FB02F1CAB2816901230E3008F063F871 +:10A5D00080F800800020E08372686E493046921D4A +:10A5E000FFF771FD7068817940297FF47AAF01200F +:10A5F000DCE570B5064648680D4614468179402969 +:10A6000010D104EB84011C2202EBC101084401F0CB +:10A61000E5F9002806D06868294684713046BDE80F +:10A62000704059E770BDFEB50C460746002645E070 +:10A63000204601F09CF9D8B360681C22417901EBF7 +:10A64000810102EBC1014518688900B9FFDF02AB47 +:10A65000082207213846FFF7ACFD002833D00299C5 +:10A66000607816220A70801C487004204880606858 +:10A67000407901F061F901460298052307228180A3 +:10A680006989C1800820CDE9000621463846FFF7D8 +:10A6900050FD6078801C6070A88969890844B0F515 +:10A6A000803F00D3FFDFA88969890844A8816E81B3 +:10A6B000626839492046521DFFF705FD60684179FF +:10A6C0004029B5D10120FEBD30B5438C458BC3F385 +:10A6D000C704002345B1838B641EED1AC38A6D1E27 +:10A6E0001D4495FBF3F3E4B22CB1008918B1A042EC +:10A6F00000D8204603444FF6FF70834200D3034640 +:10A7000013800C7030BD2DE9FC41074616460D46FE +:10A71000486802EB86011C2202EBC10144186A461C +:10A7200001A92046FFF7D0FFA089618901448AB2C0 +:10A73000BDF80010914212D0081A00D500206081A7 +:10A740006868407940280AD1204601F03DF9002888 +:10A7500005D06868294646713846FFF764FFBDE8B2 +:10A76000FC812DE9FE4F894680461546508803211D +:10A7700008F00AF98346B8F8020040280ED24020BB +:10A780000DE000002C0000209DA00000ABA0000008 +:10A79000B9A00000DDB90000C9B90000403880B29E +:10A7A00082460146584601F0E2F800287ED00AEBC6 +:10A7B0008A001C22DBF8041002EBC0000C182046B3 +:10A7C00001F0EBF8002877D1B8F80000E18A884260 +:10A7D0003CD8A189D1B348456ED100265146584690 +:10A7E00001F0B2F8218C0F18608B48B9B9F1020F53 +:10A7F00062D3B8F804006083618A884226D80226B2 +:10A80000A9EB06001FFA80F9B888A28B801A0028ED +:10A8100014DD4946814500DA084683B268886968D4 +:10A82000029139680A44CDE9003208F0DFF9DDE928 +:10A830000121F61D009B009607F0CBFDA18B01EBDB +:10A84000090080B2A083618B884207D9688803B071 +:10A8500052465946BDE8F04F01F0DDB81FD14FF028 +:10A8600009002872B8F802006881D7E90001C5E93B +:10A870000401608BA881284601F054F851465846DF +:10A8800001F062F80146DBF8040008230078C200FA +:10A8900004F1200007F035FF0020A0836083A08929 +:10A8A0000AF0FF02401EA081688800E004E003B0C7 +:10A8B0005946BDE8F04F26E7BDE8FE8F2DE9F0418F +:10A8C000064615460F461C461846F6F7FCFC18B916 +:10A8D0002068F6F71EFD08B1102013E47168688C3B +:10A8E0000978B0EBC10F01D313200BE43946304691 +:10A8F00001F02AF80146706808230078C20005F1CB +:10A90000200007F0C8FED4E90012C0E900120020C0 +:10A91000E3E710B50446032108F036F80146007855 +:10A9200000F00300022805D02046BDE8104001F1E8 +:10A93000140298E48A8A2046BDE81040C7E470B546 +:10A940000446032108F020F8054601462046FFF79B +:10A9500073FD002816D029462046FFF764FE002824 +:10A9600010D029462046FFF722FD00280AD02946AC +:10A970002046FFF7CBFC002804D029462046BDE83E +:10A980007040A9E570BD2DE9F0410C4680461EE0FF +:10A99000E178427811FB02F1CAB2816901230E30DD +:10A9A00007F0AFFE077860681C22C179491EC171AB +:10A9B00007EB8701606802EBC10146183946204663 +:10A9C00000F0D5FF18B1304600F0E0FF20B160681C +:10A9D000C1790029DCD180E7FEF77AFD050000D1BE +:10A9E000FFDF0A202872384600F0A6FF688139464A +:10A9F000204600F0B0FF0146606808234078C2009E +:10AA000006F1240007F07DFED0E90010C5E903102F +:10AA1000A5F80280284600F085FFB07800B9FFDF76 +:10AA2000B078401EB07058E770B50C46054603215B +:10AA300007F0AAFF01464068C2792244C271284645 +:10AA4000BDE870409FE72DE9FE4F824650781446DE +:10AA50000F464FF0000800284FD0012807D00228E9 +:10AA600022D0FFDF2068B8606068F86024E702AB9E +:10AA70000E2208215046FFF79CFB0028F2D00298D6 +:10AA8000152105230170217841700A214180C0F809 +:10AA90000480C0F80880A0F80C80628882810E20B3 +:10AAA000CDE90008082221E0A678304600F044FFF6 +:10AAB000054606EB86012C22786802EBC1010822CC +:10AAC000465A02AB11465046FFF773FB0028C9D027 +:10AAD00002980721017021784170042141800821EA +:10AAE0008580C680CDE9001805230A4639465046C0 +:10AAF000FFF71FFB87F80880DEE6A678022516B16F +:10AB0000022E13D0FFDF2A1D914602AB08215046CA +:10AB1000FFF74FFB0028A5D002980121022E0170FB +:10AB2000217841704580868002D005E00625EAE75D +:10AB3000A188C180E1880181CDE900980523082220 +:10AB400039465046D4E710B50446032107F01CFFF0 +:10AB5000014600F108022046BDE8104073E72DE9E8 +:10AB6000F05F0C4601281DD0957992F80480567943 +:10AB700005EB85011F2202EBC10121F0030B08EB5D +:10AB8000060111FB05F14FF6FF7202EAC10909F156 +:10AB9000030115FB0611F94F21F0031A40B10128FA +:10ABA0003DD124E06168E57891F800804E78DFE7D8 +:10ABB0005946786807F023FD606000B9FFDF594609 +:10ABC00060681AF0C8FDE5705146786807F017FD17 +:10ABD0006168486100B9FFDF6068426902EB090102 +:10ABE0008161606880F800806068467017E0606886 +:10ABF00052464169786807F02DFD5A4661687868C9 +:10AC000007F028FD032007F067FE0446032007F045 +:10AC10006BFE201A012802D1786807F0E5FC0BEBE7 +:10AC20000A00BDE8F09F02460021022097E773B5B5 +:10AC3000D24D0A202870009848B100244FEA0D0038 +:10AC400007F0BFFC002C01D1009969607CBD012494 +:10AC50000020F5E770B50C461546382120461AF05D +:10AC60007AFD012666700A2104F11C001AF073FDBA +:10AC700005B9FFDF297A207861F301002070A879F7 +:10AC8000002817D02A4621460020FFF768FF616898 +:10AC9000402088706168C870616808716168487197 +:10ACA000616888716168288808816168688848815E +:10ACB0006068868170BDC878002802D0002201201B +:10ACC0004DE7704770B50546002165F31F41002030 +:10ACD0000BF074FB0321284607F056FE040000D158 +:10ACE000FFDF21462846FFF767F9002804D02078C7 +:10ACF00040F010002070012070BD2DE9FF4180461A +:10AD00000E460F0CFEF7E4FB050007D06F80032111 +:10AD1000384607F039FE040008D106E004B0384692 +:10AD2000BDE8F0411321F9F74BBEFFDF5FEA0800F1 +:10AD300005D0B8F1060F18D0FFDFBDE8FF812078FD +:10AD40002A4620F0080020700020ADF80200022002 +:10AD50008DF800004FF6FF70ADF80400ADF8060066 +:10AD600069463846F9F723FAE7E7C6F3072101EB0E +:10AD700081021C23606803EBC202805C042803D0BC +:10AD800008280AD0FFDFD8E7012000904FF44043A5 +:10AD90002A46204600F008FECFE704B02A462046A7 +:10ADA000BDE8F041FFF7E7B82DE9F05F0027B0F804 +:10ADB0000A9090460C4605463E46B9F1400F01D236 +:10ADC000402001E0A9F140001FFA80FA287AC01E55 +:10ADD00008286BD2DFE800F00D04192058363C47F4 +:10ADE00072271026002C6CD0D5E90301C4E90201BA +:10ADF0005CE070271226002C63D00A2205F10C01BA +:10AE000004F108001AF04BFC50E071270C26002CCE +:10AE100057D0E868A06049E0742710269CB3D5E9B4 +:10AE20000301C4E902016888032107F0ADFD8346F0 +:10AE3000FEF74EFB02466888508051465846FFF7A1 +:10AE400051F833E075270A26ECB1A88920812DE05E +:10AE500076271426BCB105F10C0004F1080307C8DD +:10AE600083E8070022E07727102664B1D5E90301C3 +:10AE7000C4E902016888032107F086FD014668885D +:10AE8000FFF781FD12E01CE073270826CCB168882B +:10AE9000032107F079FD01460078C00606D56888D1 +:10AEA000FFF78AF810B96888F8F798FDA8F80060ED +:10AEB0002CB12780A4F8069066806888A0800020C6 +:10AEC000AFE6A8F80060FAE72DE9FC410C461E4603 +:10AED00017468046032107F057FD05460A2C0AD283 +:10AEE000DFE804F005050505050509090907042340 +:10AEF00003E0062301E0FFDF0023CDE900762246D0 +:10AF000029464046FFF715F929E438B50546A0F56E +:10AF10007F40FF3830D0284607F068FE040000D19B +:10AF2000FFDF204607F0EDF9002815D001466A46FC +:10AF3000204607F008FA00980321B0F8054028469B +:10AF400007F022FD0546052C03D0402C05D24024F5 +:10AF500004E0007A80B1002038BD403CA4B2214614 +:10AF600000F005FD40B1686804EB84013E2202EB6D +:10AF7000C101405A0028EFD0012038BD2C0000202C +:10AF80002DE9F04F054689B0408807F02FFE0400F8 +:10AF900000D1FFDF06AA2046696800F0C1FC069CCC +:10AFA000001F34F8031F218063886380228881B2E8 +:10AFB0008A4205D1042B0AD0052B1DD0062B15D0B3 +:10AFC0002A462046FFF7CDFB09B0BDE8F08F1646B4 +:10AFD000241D2A4621463046F7F751FA0828F3D1B6 +:10AFE0002A4621463046FCF7FEFBEDE76888211D26 +:10AFF0006B68FAF743FCE7E717466888032107F018 +:10B00000C3FC4FF000088DF804800646ADF80680BA +:10B01000042FD9D36279002AD6D020794FF6FF7950 +:10B020004FF01C0A13282CD008DC012878D0062801 +:10B0300047D0072875D0122874D106E0142872D0A2 +:10B04000152871D016286DD1ACE10C2F6AD130785B +:10B0500000F00301022965D140F0080030706079EA +:10B06000B07001208DF804002089ADF808006089D7 +:10B07000ADF80A00A089ADF80C00E089ADF80E002B +:10B0800019E0B07890429FD1307801079CD5062F07 +:10B090009AD120F0080030706888414660F31F4163 +:10B0A00000200BF08BF902208DF80400ADF8089019 +:10B0B0002089ADF80A0068882A4601A9F9F777F8CF +:10B0C00082E7082F80D12789B4F80A90402F01D257 +:10B0D000402001E0A7F1400080B2804601463046A2 +:10B0E00000F045FC08B3716808EB88002C2202EBE5 +:10B0F000C000095A4945E3D1FE4807AAD0E9021029 +:10B10000CDE9071060798DF81C0008F0FF048DF878 +:10B110001E4068883146FFF796FC2A46214639E0F2 +:10B12000B6E014E03CE039E0E6E0F248D0E9001097 +:10B13000CDE907106079ADF820708DF81C00ADF8EE +:10B140002290688807AA3146FFF77DFC3CE7082F6C +:10B15000B6D16089B4F80880402801D2402000E0D0 +:10B16000403887B23946304600F001FC0028A7D0AD +:10B1700007EB870271680AEBC2000844028A424565 +:10B180009ED1017808299BD140786179884297D176 +:10B19000F9B22A463046FEF7EEFE15E70E2F07D02D +:10B1A000CDF81C80CDF8208060798DF81C00C8E7B0 +:10B1B0006189E7898B46B4F80C903046FEF73DFF75 +:10B1C000ABF14001402901D309204AE0B9F1170F42 +:10B1D00001D3172F01D20B2043E040280ED000EB03 +:10B1E000800271680AEBC20008440178012903D18A +:10B1F000407861798842A9D00A2032E03046FEF7D3 +:10B20000FEFE014640282BD001EB810372680AEB59 +:10B21000C30002EB0008012288F80020627988F858 +:10B220000120706822894089B84200D93846248AB2 +:10B2300003232B72AA82EF812882A5F80C906C82DE +:10B24000084600F079FB6881A8F81490A8F81870F7 +:10B25000A8F80E40A8F810B0284600F063FBB3E64B +:10B26000042005212972A5F80A80E88101212973AB +:10B27000A049D1E90421CDE9072161798DF81C109D +:10B28000ADF81E00688807AA3146FFF7DCFBE3E74C +:10B29000062FE4D3B078904215D13078010712D54B +:10B2A00020F0080030706888414660F31F4100209C +:10B2B0000BF084F802208DF804002089ADF8080016 +:10B2C000ADF80A90F7E604213046FEF7CEFE0446BC +:10B2D0004028C4D00220830300902A4621463046ED +:10B2E00000F062FB4146688864F30F2160F31F4160 +:10B2F00006200BF063F867E60E2FB0D1042130462C +:10B30000FEF7B3FE81464028A9D04146688869F31C +:10B310000F2160F31F4106200BF050F8208A0790A0 +:10B32000E08900907068A7894089B84200D9384602 +:10B330008346B4F80A8020890590484600F0FCFA5C +:10B340006881079840B10220079B00902A46494631 +:10B35000304600F029FB37E6B8F1170F1ED3172F40 +:10B360001CD30420287200986882EF81A5F810B0E1 +:10B37000A5F80C8009EB89020AEBC2007168009AFB +:10B380000C180598A4F81480A4F818B0E281208263 +:10B39000284600F0C7FA0620207015E601200B238E +:10B3A0000090D3E7082FA6D121893046FEF745FE4D +:10B3B000074640289FD007EB870271680AEBC2005E +:10B3C0000844804600F0E9FA002894D16489B8F86E +:10B3D0000E002044B0F5803F05D368883A463146D8 +:10B3E00000F019FBF0E5002C85D0A8F80E00688865 +:10B3F0003A463146FFF7FDF808202872384600F03B +:10B400009BFA6881AC8127E770B50D46064603219B +:10B4100007F0BAFA040004D02078000704D5112000 +:10B4200070BD43F2020070BD2A4621463046FEF749 +:10B430001AFF18B9286860616868A061207840F038 +:10B4400008002070002070BD70B50D46064603212F +:10B4500007F09AFA040004D02078000704D40820EA +:10B4600070BD43F2020070BD2A4621463046FEF709 +:10B470002EFF00B9A582207820F00800207000205F +:10B4800070BD2DE9F04F0E4691B08046032107F0C4 +:10B490007BFA0446404607F0BBFB074600200790B6 +:10B4A00008900990ADF830000A9002900390049043 +:10B4B00004B9FFDF0DF108091FBBFFDF21E03846AB +:10B4C0000BA9002206F0E0FD9DF82C0000F07F059E +:10B4D0000A2D00D3FFDF6019017F491E01779DF817 +:10B4E0002C0000060DD52A460CA907A8FEF711FE70 +:10B4F00002E00000405B020019F80510491C09F841 +:10B500000510761EF6B2DAD204F13400FA4D04F1D9 +:10B51000260BDFF8E8A304F12A07069010E058464E +:10B52000069900F06AFA064628700A2800D3FFDF61 +:10B530005AF8261040468847E08CC05DB04202D0E1 +:10B54000208D0028EBD10A202870EC4D4E4628357E +:10B550000EE00CA907A800F050FA0446375D55F834 +:10B56000240000B9FFDF55F82420394640469047B3 +:10B57000BDF81E000028ECD111B026E510B503215E +:10B5800007F002FA040000D1FFDF0A2104F11C00D9 +:10B590001AF0E1F8207840F00400207010BD10B5DA +:10B5A0000C46032107F0F0F92044007F002800D06A +:10B5B000012010BD2DE9F84F89461546824603212A +:10B5C00007F0E2F9070004D02846F5F77CFE40B901 +:10B5D00003E043F20200BDE8F88F4846F5F799FE14 +:10B5E00008B11020F7E7786828B16988008981429E +:10B5F00001D90920EFE7B9F800001C2418B1402850 +:10B6000009D2402008E03846FEF7F9FC8046402881 +:10B6100019D11320DFE7403880B280460146384612 +:10B6200000F0A5F948B108EB8800796804EBC00088 +:10B63000085C012803D00820CDE70520CBE7FDF703 +:10B6400047FF06000BD008EB8800796804EBC000C8 +:10B650000C18B9F8000020B1E88910B113E01120EE +:10B66000B9E72888172802D36888172801D207204D +:10B67000B1E7686838B12B1D224641463846FFF7CE +:10B680001DF90028A7D104F10C0269462046FFF7F6 +:10B690001BF8288860826888E082B9F8000030B121 +:10B6A00002202070E889A080E889A0B12BE0032067 +:10B6B0002070A889A08078688178402905D180F819 +:10B6C000028039465046FEF721FE404600F034F92C +:10B6D000A9F8000021E07868218B4089884200D9D0 +:10B6E00008462083A6F802A004203072B9F80000B2 +:10B6F0007081E0897082F181208B3082A08AB081D4 +:10B70000304600F00FF97868C178402905D180F8FB +:10B71000038039465046FEF74AFE00205BE770B5CD +:10B720000D460646032107F02FF9040003D0402DF3 +:10B7300004D2402503E043F2020070BD403DADB2AB +:10B74000294600F014F958B105EB85011C22606808 +:10B7500002EBC101084400F020F918B1082070BDC7 +:10B76000052070BD2A462146304600F054F90020DD +:10B7700070BD2DE9F0410D4616468046032107F0C5 +:10B7800003F90446402D01D2402500E0403DADB212 +:10B790008CB1294600F0EBF880B105EB85011C2245 +:10B7A000606802EBC1014718384600F0F6F838B17E +:10B7B0000820BDE8F08143F20200FAE70520F8E72F +:10B7C00033463A4629462046FFF778F80028F0D15C +:10B7D000EAB221464046FEF796FF0020E9E72DE950 +:10B7E000F0410D4616468046032107F0CDF8044689 +:10B7F000402D01D2402500E0403DAFB224B130469B +:10B80000F5F761FD38B902E043F20200D1E7306894 +:10B81000F5F759FD08B11020CBE73946204600F076 +:10B82000A6F860B107EB87011C22606802EBC1013A +:10B830004518284600F0B1F818B10820B9E70520EE +:10B84000B7E7B088A98A884201D90C20B1E76168BE +:10B85000E88C4978B0EBC10F01D31320A9E7394632 +:10B86000204600F078F80146606808234078C2005E +:10B8700005F1240006F00FFFD6E90012C0E900121E +:10B88000FAB221464046FEF7B4FE002091E72DE9CA +:10B89000F0470D461F4690468146032107F074F895 +:10B8A0000446402D01D2402001E0A5F1400086B2BF +:10B8B0003CB14DB13846F5F74AFD50B11020BDE816 +:10B8C000F08743F20200FAE76068C8B1A0F80C8084 +:10B8D00024E03146204600F04AF888B106EB8601A4 +:10B8E0001C22606802EBC1014518284600F055F89B +:10B8F00040B10820E3E700002C000020585B020064 +:10B900000520DCE7A5F80880F2B221464846FEF79C +:10B91000FAFE1FB1A8896989084438800020CEE763 +:10B9200006F011BD017821F00F01491C21F0F00152 +:10B9300010310170FDF7CFBD10B50446402800D985 +:10B94000FFDF4034A0B210BD406842690078484330 +:10B9500002EBC0007047C2784068037812FB03F224 +:10B960004378406901FB032100EBC1007047C278B6 +:10B970008A4209D9406801EB81011C2202EBC10116 +:10B98000405C08B10120704700207047007806280D +:10B9900001D901207047002070470078062801D0A7 +:10B9A0000120704700207047F0B401EB81061C278E +:10B9B000446807EBC6063444049D05262670E380E0 +:10B9C0002571F0BCFEF78EBA10B5418911B1FFF7B1 +:10B9D000DDFF08B1002010BD012010BD10B5C18CE5 +:10B9E0008278B1EBC20F04D9C18911B1FFF7CEFF44 +:10B9F00008B1002010BD012010BD10B50C46012378 +:10BA00000A22011D06F07DFE007821880122824075 +:10BA10009143218010BDF0B402EB82051C264C68D6 +:10BA200006EBC505072363554B681C79402C03D1F1 +:10BA30001A71F0BCFEF700BDF0BC704710B5EFF313 +:10BA4000108000F0010472B6F9484178491C417039 +:10BA50004078012801D10AF0F1F8002C00D162B63B +:10BA600010BD70B5F24CA07848B90125A570FFF75C +:10BA7000E5FF0AF0F4F820B100200AF0BEF800203B +:10BA800070BD4FF08040E570C0F80453F7E770B523 +:10BA9000EFF3108000F0010572B6E54C607800B954 +:10BAA000FFDF6078401E6070607808B90AF0CAF85D +:10BAB000002D00D162B670BDDD4810B5817821B18E +:10BAC0000021C1708170FFF7E2FF002010BD10B5AA +:10BAD00004460AF0C4F8D6498978084000D001200D +:10BAE0002060002010BD10B5FFF7A8FF0AF0B7F8DE +:10BAF00002220123CE49540728B1CE4802602361B7 +:10BB00000320087202E00A72C4F80433002088712E +:10BB100010BD2DE9F05FDFF818934278817889F83D +:10BB20000420002689F80510074689F80660007889 +:10BB3000DFF804B3354620B1012811D0022811D016 +:10BB4000FFDF0AF09EF84FF0804498B10AF0A0F8A9 +:10BB5000B0420FD130460AF09FF80028FAD041E0F9 +:10BB60000126EEE7FFF76AFF58460168C907FCD0D7 +:10BB70000226E6E70120E060C4F80451AF490E60F8 +:10BB80000107D1F84412AD4AC1F3423124321160A9 +:10BB9000AA49343108604FF0020AC4F804A3A06037 +:10BBA000A7480168C94341F3001101F10108016888 +:10BBB00041F01001016000E020BFD4F8040100282A +:10BBC000FAD030460AF068F80028FAD0B8F1000F31 +:10BBD00004D19B48016821F010010160C4F808A35A +:10BBE000C4F8045199F805004E4688B1387878B900 +:10BBF0000AF035F880460AF0C9F901466FF00042B4 +:10BC0000B8F1000F02D0C6E9032101E0C6E9031232 +:10BC1000DBF80000C00701D00AF01DF8387810B139 +:10BC20003572BDE8F09F4FF01808C4F80883C4F8D7 +:10BC30002C510127C4F81870D4F82C010028FBD02F +:10BC4000C4F80C51C4F810517948C01D0AF036F8F8 +:10BC50003570FFF748FF6761784930792031086017 +:10BC6000C4F80483DDE770B5050000D1FFDF4FF0B5 +:10BC700080424FF0FF30C2F808030021C2F80011E3 +:10BC8000C2F80411C2F80C11C2F81011684C6170AE +:10BC900009F0F1FF10B10120A070607066480068E3 +:10BCA000C00701D009F0D7FF2846BDE8704030E753 +:10BCB0005F48007A002800D0012070472DE9FF5F1F +:10BCC0006048D0F800805F4A5F49083211608406FE +:10BCD000D4F8080100B10120D4F8241101B10121E8 +:10BCE0008A46D4F81C1101B101218946D4F82011EB +:10BCF00009B1012700E00027D4F8001101B10121AA +:10BD00008B46D4F8041101B101210391D4F80C1130 +:10BD100001B101210291D4F8101101B10121444D6A +:10BD2000019129780026009120B1C4F80861012012 +:10BD300009F063FFBAF1000F04D0C4F824610920B0 +:10BD400009F05BFFB9F1000F04D0C4F81C610A20B0 +:10BD500009F053FF27B1C4F820610B2009F04DFF13 +:10BD60003348C01D09F0B2FF00B1FFDFDFF8C49017 +:10BD70000127BBF1000F10D0C4F80873E87818B1A0 +:10BD8000EE70002009F039FF287A022805D103203F +:10BD900028720221C9F800102761039808B1C4F87D +:10BDA0000461029850B1C4F80C61287A032800D0CD +:10BDB000FFDFC9F800602F72FFF769FE019838B104 +:10BDC000C4F81061287A012801D100F05DF867619C +:10BDD000009838B12E70287A012801D1FFF783FE30 +:10BDE000FFF755FE1248C01D09F086FF1549091DD1 +:10BDF000C1F80080BDE8FF9F0D4810B5C01D09F0D7 +:10BE000065FF0B4940B1012008704FF0E021C1F8F7 +:10BE10000002BDE8104011E6087A012801D1FFF7C1 +:10BE200062FE0348BDE81040C01D09F065BF000078 +:10BE30003C000020340C00400C0400401805004079 +:10BE400010ED00E0100502400100000170B5224C29 +:10BE5000A07808B909F0F6FE01208507A861207ACC +:10BE6000002603280AD100BFD5F80C0120B9002014 +:10BE700009F012FF0028F7D1C5F80C6126724FF0C7 +:10BE8000FF30C5F8080370BD70B5134C6079F0B190 +:10BE9000012803D0A179401E814218DA09F0DFFEA3 +:10BEA00005460AF073F86179012902D9A179491C84 +:10BEB000A1710DB1216900E0E168411A022902DA9D +:10BEC00011F1020F06DC0DB1206100E0E060BDE879 +:10BED000704008E670BD00003C00002010B5202036 +:10BEE00000F07FF8202000F08DF84D49202081F8E7 +:10BEF0000004F5F783FA4B4908604B48D0F8041367 +:10BF000041F00101C0F80413D0F8041341F080712E +:10BF1000C0F80413424901201C39C1F8000110BDCA +:10BF200010B5202000F05DF83E480021C8380160BF +:10BF3000001D01603D4A481E10603B4AC2F80803DC +:10BF4000384B1960C2F80001C2F860013849086036 +:10BF5000BDE81040202000F055B834493548091F8D +:10BF60000860704731493348086070472D48C83829 +:10BF70000160001D521E026070472C4901200860BC +:10BF8000BFF34F8F70472DE9F0412849D0F8188052 +:10BF900028480860244CD4F800010025244E6F1E68 +:10BFA00028B14046F5F788F940B9002111E0D4F8EE +:10BFB000600198B14046F5F77FF948B1C4F80051E7 +:10BFC000C4F860513760BDE8F041202000F01AB895 +:10BFD00031684046BDE8F04119F0E8BBFFDFBDE83D +:10BFE000F08100280DDB00F01F0201219140400983 +:10BFF000800000F1E020C0F88011BFF34F8FBFF345 +:10C000006F8F7047002809DB00F01F02012191406B +:10C010004009800000F1E020C0F880127047000065 +:10C0200020E000E0C806024000000240180502407F +:10C0300000040240010000010F4A12680D498A42C3 +:10C040000CD118470C4A12680A4B9A4206D101B526 +:10C0500009F06EFFFFF781FFBDE80140074909685D +:10C060000958084706480749054A064B704700002B +:10C0700000000000BEBAFECA5400002004000020E8 +:10C080008013002080130020F8B51D46DDE9064727 +:10C090000E000AD006F0BCFD2346FF1DBCB231469F +:10C0A0002A46009406F0C9F9F8BDD019224619466F +:10C0B00019F0B0FA2046F8BD70B50D4604461021BF +:10C0C00019F027FB258117206081A07B40F00A0032 +:10C0D000A07370BD4FF6FF720A80014602200AF07D +:10C0E0006DB9704700897047827BD30701D19207F1 +:10C0F00003D4808908800020704705207047827B28 +:10C10000920700D58181704701460020098841F6D9 +:10C11000FE52114200D00120704700B50346807BDB +:10C12000C00701D0052000BD59811846FFF7ECFF7C +:10C13000C00703D0987B40F004009873987B40F0D0 +:10C1400001009873002000BD827B520700D509B121 +:10C150004089704717207047827B61F3C302827366 +:10C1600070472DE9FC5F0E46044601789646012093 +:10C1700000FA01F14DF6FF5201EA020962684FF63A +:10C18000FF7B1188594502D10920BDE8FC9FB9F118 +:10C19000000F05D041F6FE55294201D00120F4E7F9 +:10C1A00041EA090111801D0014D000232B7094F87E +:10C1B00000C0052103221F464FF0020ABCF10E0FFA +:10C1C00076D2DFE80CF0F909252F47646B774791A9 +:10C1D00093B4D1D80420D8E7616820898B7B9B0772 +:10C1E00067D517284AD30B89834247D389891729F2 +:10C1F00001D3814242D185F800A0A5F80100328028 +:10C20000616888816068817B21F002018173C6E0EA +:10C21000042028702089A5F801006089A5F8030092 +:10C220003180BCE0208A3188C01D1FFA80F841456A +:10C2300024D3062028702089A5F801006089A5F87C +:10C240000300A089A5F805000721208ACDE9000197 +:10C25000636941E00CF0FF00082810D00820287026 +:10C260002089A5F801006089A5F8030031806A1DC6 +:10C27000694604F10C0008F033F910B15EE01020BB +:10C28000EDE730889DF800100844308087E00A20F0 +:10C2900028702089A5F80100328044E00C20287025 +:10C2A0002089A5F801006089A5F8030031803AE0F3 +:10C2B00082E064E02189338800EB41021FFA82F8B2 +:10C2C00043453BD3B8F1050F38D30E222A700BEA51 +:10C2D0004101CDE90010E36860882A467146FFF706 +:10C2E000D3FEA6F800805AE040202870608931888B +:10C2F000C01C1FFA80F8414520D32878714620F0F1 +:10C300003F00123028702089A5F801006089CDE92E +:10C31000000260882A46E368FFF7B6FEA6F80080B0 +:10C32000287840063BD461682089888037E0A0895E +:10C330003288401D1FFA80F8424501D204273DE0B3 +:10C34000162028702089A5F801006089A5F803004F +:10C35000A089CDE9000160882A4671462369FFF76C +:10C3600093FEA6F80080DEE718202870207A687017 +:10C37000A6F800A013E061680A88920401D405279A +:10C380001CE0C9882289914201D0062716E01E21AF +:10C39000297030806068018821F400510180B9F172 +:10C3A000000F0BD0618878230022022009F05CFF87 +:10C3B00061682078887006E0338003276068018810 +:10C3C00021EA090101803846DFE62DE9FF4F85B0FB +:10C3D0001746129C0D001E461CD03078C10703D0B2 +:10C3E00000F03F00192801D9012100E0002120467A +:10C3F000FFF7AAFEA8420DD32088A0F57F41FF39A0 +:10C4000008D03078410601D4000605D5082009B0CF +:10C41000BDE8F08F0720FAE700208DF800008DF8C6 +:10C42000010030786B1E00F03F0C0121A81E4FF078 +:10C43000050A4FF002094FF0030B9AB2BCF1200F2E +:10C4400075D2DFE80CF08B10745E7468748C749C89 +:10C4500074B674BB74C974D574E2747474F274F0F5 +:10C4600074EF74EE748B052D78D18DF80090A07860 +:10C470008DF804007088ADF8060030798DF8010061 +:10C48000707800F03F000C2829D00ADCA0F10200EF +:10C49000092863D2DFE800F0126215621A621D6299 +:10C4A0002000122824D004DC0E281BD01028DBD159 +:10C4B0001BE016281FD01828D6D11FE0207880074F +:10C4C00001E020784007002848DAEFE020780007F4 +:10C4D000F9E72078C006F6E720788006F3E72078B1 +:10C4E0004006F0E720780006EDE72088C005EAE77F +:10C4F00020884005E7E720880005E4E72088C0049D +:10C50000E1E72078800729D5032D27D18DF800B0E9 +:10C51000B6F8010082E0217849071FD5062D1DD30A +:10C5200081B27078012803D0022817D102E0CAE056 +:10C53000022000E0102004228DF8002072788DF88F +:10C540000420801CB1FBF0F2ADF8062092B2424309 +:10C550008A4203D10397ADF80890A7E07AE02078EB +:10C56000000777D598B282088DF800A0ADF80420B6 +:10C57000B0EB820F6ED10297ADF8061096E02178ED +:10C58000C90667D5022D65D381B206208DF800005B +:10C59000707802285ED300BFB1FBF0F28DF8040082 +:10C5A000ADF8062092B242438A4253D1ADF80890CA +:10C5B0007BE0207880064DD5072003E020784006F8 +:10C5C0007FD508208DF80000A088ADF80400ADF8F4 +:10C5D0000620ADF8081068E02078000671D5092023 +:10C5E000ADF804208DF80000ADF8061002975DE06C +:10C5F0002188C90565D5022D63D381B20A208DF843 +:10C600000000707804285CD3C6E72088400558D520 +:10C61000012D56D10B208DF80000A088ADF8040044 +:10C6200044E021E026E016E0FFE72088000548D539 +:10C63000052D46D30C208DF80000A088ADF804002D +:10C64000B6F803006D1FADF80850ADF80600ADF860 +:10C650000AA02AE035E02088C00432D5012D30D16F +:10C660000D208DF8000021E02088800429D4B6F840 +:10C670000100E080A07B000723D5032D21D3307873 +:10C6800000F03F001B2818D00F208DF800002088F4 +:10C6900040F40050A4F80000B6F80100ADF8040022 +:10C6A000ED1EADF80650ADF808B003976946059841 +:10C6B000F5F730FC050008D016E00E208DF80000DC +:10C6C000EAE7072510E008250EE0307800F03F008B +:10C6D0001B2809D01D2807D00220059909F06EFEFD +:10C6E000208800F400502080A07B400708D5204619 +:10C6F000FFF70AFDC00703D1A07B20F00400A07360 +:10C70000284684E61FB5022806D101208DF80000D6 +:10C7100088B26946F5F7FEFB1FBD0000F8B51D465F +:10C72000DDE906470E000AD006F072FA2346FF1D27 +:10C73000BCB231462A46009405F07FFEF8BDD01900 +:10C740002246194618F066FF2046F8BD2DE9FF4F36 +:10C750008DB09B46DDE91B57DDF87CA00C46082B0D +:10C7600005D0E06901F002F950B11020D2E028882C +:10C77000092140F0100028808AF80010022617E0F6 +:10C78000E16901208871E2694FF420519180E169EB +:10C790008872E06942F601010181E069002181733C +:10C7A0002888112140F0200028808AF800100426F3 +:10C7B00038780A900A2038704FF0020904F1180006 +:10C7C0004D460C9001F095FBB04681E0BBF1100F97 +:10C7D0000ED1022D0CD0A9EB0800801C80B20221E2 +:10C7E000CDE9001005AB52461E990D98FFF796FF54 +:10C7F000BDF816101A98814203D9F74800790F90B6 +:10C8000004E003D10A9808B138702FE04FF002011C +:10C81000CDE900190DF1160352461E990D98FFF748 +:10C820007DFF1D980088401B801B83B2C6F1FF006E +:10C83000984200D203461E990BA8D9B15FF00002BE +:10C84000DDF878C0CDE9032009EB060189B2CDE916 +:10C8500001C10F980090BDF8161000220D9801F04C +:10C86000CBFB387070B1C0B2832807D0BDF816007A +:10C8700020833AE00AEB09018A19E1E7022011B0AE +:10C88000BDE8F08FBDF82C00811901F0FF08022DE2 +:10C890000DD09AF80120424506D1BDF82010814202 +:10C8A00007D0B8F1FF0F04D09AF801801FE08AF892 +:10C8B0000180C94800680178052902D1BDF8161029 +:10C8C000818009EB08001FFA80F905EB080085B2AA +:10C8D000DDE90C1005AB0F9A01F00EFB28B91D988D +:10C8E0000088411B4145BFF671AF022D13D0BBF14B +:10C8F000100F0CD1A9EB0800801C81B20220CDE9F9 +:10C90000000105AB52461E990D98FFF707FF1D98D1 +:10C910000580002038700020B1E72DE9F8439C46DF +:10C92000089E13460027B26B9AB3491F8CB2F18F51 +:10C93000A1F57F45FF3D05D05518AD882944891DD7 +:10C940008DB200E000252919B6F83C800831414538 +:10C9500020D82A44BCF8011022F8021BBCF80310AE +:10C9600022F8021B984622F8024B914606F03EF947 +:10C970004FF00C0C41464A462346CDF800C005F066 +:10C9800028FDF587B16B00202944A41D21440880AF +:10C9900003E001E0092700E083273846BDE8F8837B +:10C9A00010B50B88848F9C420CD9846BE0180488E6 +:10C9B00044B1848824F40044A41D23440B801060F7 +:10C9C000002010BD0A2010BD2DE9F0478AB00025D7 +:10C9D000904689468246ADF8185007274BE00598E7 +:10C9E00006888088000446D4A8F8006007A801954E +:10C9F00000970295CDE903504FF4007300223146B1 +:10CA0000504601F0F9FA04003CD1BDF81800ADF829 +:10CA10002000059804888188B44216D10A0414D4F1 +:10CA200001950295039521F400410097049541F486 +:10CA3000804342882146504601F0B4F804000BD1EF +:10CA40000598818841F40041818005AA08A94846DB +:10CA5000FFF7A6FF0400DCD000970598029501952A +:10CA6000039504950188BDF81C300022504601F062 +:10CA700099F80A2C06D105AA06A94846FFF790FFA7 +:10CA80000400ACD0ADF8185004E00598818821F47A +:10CA90000041818005AA06A94846FFF781FF0028CA +:10CAA000F3D00A2C03D020460AB0BDE8F08700205E +:10CAB000FAE710B50C46896B86B051B10C218DF8A0 +:10CAC0000010A18FADF80810A16B01916946FAF72B +:10CAD00022FB00204FF6FF71A063E187A08706B01C +:10CAE00010BD2DE9F0410D460746896B0020069EDA +:10CAF0001446002911D0012B0FD132462946384661 +:10CB0000FFF762FF002808D1002C06D032462946E4 +:10CB10003846BDE8F04100F038BFBDE8F0812DE9AE +:10CB2000FC411446DDE9087C0E46DDE90A15521D7C +:10CB3000BCF800E092B2964502D20720BDE8FC8125 +:10CB4000ACF8002017222A70A5F80160A5F8033080 +:10CB50000522CDE900423B462A46FFF7DFFD0020D3 +:10CB6000ECE770B50C4615464821204618F0F3FD59 +:10CB700004F1080044F81C0F00204FF6FF71E0613B +:10CB800061842084A5841720E08494F82A0040F072 +:10CB90000A0084F82A0070BD4FF6FF720A80014631 +:10CBA000032009F00BBC30B585B00C460546FFF7F5 +:10CBB00080FFA18E284629B101218DF80010694619 +:10CBC000FAF7A9FA0020E0622063606305B030BD87 +:10CBD000B0F84000704700005800002090F8462050 +:10CBE000920703D4408808800020F3E70620F1E78D +:10CBF00090F846209207EDD5A0F84410EAE70146E8 +:10CC0000002009880A0700D5012011F0F00F01D09B +:10CC100040F00200CA0501D540F004008A0501D5A4 +:10CC200040F008004A0501D540F010000905D1D5B3 +:10CC300040F02000CEE700B5034690F84600C0075C +:10CC400001D0062000BDA3F842101846FFF7D7FF19 +:10CC500010F03E0F05D093F8460040F0040083F832 +:10CC6000460013F8460F40F001001870002000BD88 +:10CC700090F84620520700D511B1B0F84200A9E75C +:10CC80001720A7E710F8462F61F3C3020270A1E74F +:10CC90002DE9FF4F9BB00E00DDE92B34DDE929784B +:10CCA000289D24D02878C10703D000F03F00192820 +:10CCB00001D9012100E000212046FFF7D9FFB04251 +:10CCC00015D32878410600F03F010CD41E290CD062 +:10CCD000218811F47F6F0AD13A8842B1A1F57F42D1 +:10CCE000FF3A04D001E0122901D1000602D5042048 +:10CCF0001FB0C5E5F9491D984FF0000A08718DF87D +:10CD000018A08DF83CA00FAA0A60ADF81CA0ADF8E1 +:10CD100050A02978994601F03F02701F5B1C04F176 +:10CD2000180C4FF0060E4FF0040BCDF858C01F2A18 +:10CD30007ED2DFE802F07D7D107D267DAC7DF47D26 +:10CD4000F37DF27DF17DF47DF07D7D7DEF7DEE7DE7 +:10CD50007D7D7D7DED0094F84610B5F801008907D2 +:10CD600001D5032E02D08DF818B022E34FF40061F4 +:10CD7000ADF85010608003218DF83C10ADF84000F4 +:10CD8000D8E2052EEFD1B5F801002083ADF81C00E4 +:10CD9000B5F80310618308B1884201D901207FE111 +:10CDA0000020A07220814FF6FF702084169801F0B9 +:10CDB000A0F8052089F800000220029083460AAB03 +:10CDC0001D9A16991B9801F097F890BB9DF82E00BC +:10CDD000012804D0022089F80100102003E001207E +:10CDE00089F8010002200590002203A90BA807F092 +:10CDF00077FBE8BB9DF80C00059981423DD13A884C +:10CE0000801CA2EB0B01814237DB02990220CDE9A5 +:10CE100000010DF12A034A4641461B98FFF77EFCAC +:10CE200002980BF1020B801C80B217AA03A901E043 +:10CE3000A0E228E002900BA807F052FB02999DF8AF +:10CE40000C00CDE9000117AB4A4641461B98FFF79D +:10CE500065FC9DF80C100AAB0BEB01001FFA80FB80 +:10CE600002981D9A084480B2029016991B9800E01F +:10CE700003E001F041F80028B6D0BBF1020F02D068 +:10CE8000A7F800B053E20A208DF818004FE2002105 +:10CE90000391072EFFF467AFB5F801002083ADF8CA +:10CEA0001C00B5F80320628300283FF477AF90425E +:10CEB0003FF674AF0120A072B5F805002081002074 +:10CEC000A073E06900F052FD78B9E1690120887132 +:10CED000E2694FF420519180E1698872E06942F67D +:10CEE00001010181E06900218173F01F20841E98F7 +:10CEF000606207206084169800F0FBFF072089F825 +:10CF000000000120049002900020ADF82A0028E0E3 +:10CF10001DE2A3E13AE1EAE016E2AEE086E049E094 +:10CF20000298012814D0E0698079012803D1BDF866 +:10CF30002800ADF80E00049803ABCDE900B04A46D6 +:10CF400041461B98FFF7EAFB0498001D80B204904D +:10CF5000BDF82A00ADF80C00ADF80E00059880B2BF +:10CF600002900AAB1D9A16991B9800F0C5FF28B9CC +:10CF700002983988001D05908142D1D2029801287B +:10CF800081D0E0698079012805D0BDF82810A1F58D +:10CF90007F40FF3803D1BDF82800ADF80E0004989B +:10CFA00003ABCDE900B04A4641461B98FFF7B6FBFC +:10CFB0000298BBE1072E02D0152E7FF4D4AEB5F84F +:10CFC00001102183ADF81C10B5F8032062830029FD +:10CFD0003FF4E4AE91423FF6E1AE0121A1724FF081 +:10CFE000000BA4F808B084F80EB0052E07D0C0B22C +:10CFF000691DE26907F055FA00287FF444AF4FF647 +:10D00000FF70208401A906AA14A8CDF800B081E819 +:10D0100085032878214600F03F031D9A1B98FFF7EF +:10D0200095FB8246208BADF81C0080E10120032E89 +:10D03000C3D14021ADF85010B5F801102183ADF8EF +:10D040001C100AAAB8F1000F00D00023CDE902039A +:10D0500004921D98CDF80480009038880022401E6C +:10D0600083B21B9800F0C8FF8DF8180090BB0B200E +:10D0700089F80000BDF8280037E04FF0010C052EBC +:10D080009BD18020ADF85000B5F801102183B5F890 +:10D0900003002084ADF81C10B0F5007F03D90720F1 +:10D0A0008DF8180085E140F47C4222840CA8B8F188 +:10D0B000000F00D00023CDE90330CDE9018C1D988D +:10D0C00000903888401E83B21B9800F095FF8DF8C1 +:10D0D000180028B18328A8D10220BDE05800002004 +:10D0E0000D2189F80010BDF83000401C1EE1032E10 +:10D0F00004D248067FF537AE002017E1B5F80110DD +:10D10000ADF81C102878400602D58DF83CE002E00E +:10D1100007208DF83C004FF000080320CDE90208FD +:10D120001E9BCDF810801D980193A6F1030B009073 +:10D130001FFA8BF342461B9800F034FD8DF818005F +:10D140008DF83C80297849060DD52088C00506D584 +:10D15000208BBDF81C10884201D1C4F824804046C1 +:10D160008DF81880E2E0832801D14FF0020A4FF4D5 +:10D170008070ADF85000BDF81C002083A4F820B0EA +:10D180001E986062032060841321CCE0052EFFF41A +:10D19000EAADB5F80110ADF81C10A28F62B3A2F58C +:10D1A0007F43FE3B28D008228DF83C204FF0000B37 +:10D1B0000523CDE9023BDDF878C0CDF810B01D9A0B +:10D1C00080B2CDF804C040F400430092B5F80320CB +:10D1D0001B9800F0E7FC8DF83CB04FF400718DF81F +:10D1E0001800ADF85010832810D0F8B1A18FA1F528 +:10D1F0007F40FE3807D0DCE00B228DF83C204FF654 +:10D20000FE72A287D2E7A4F83CB0D2E000942B468D +:10D2100031461E9A1B98FFF780FB8DF8180008B165 +:10D2200083284BD1BDF81C00208355E700942B4682 +:10D2300031461E9A1B98FFF770FB8DF81800E8BB6B +:10D24000E18FA06B0844811D8DE8820343888288AA +:10D2500001881B98FFF763FC824668E095F801801F +:10D26000022E70D15FEA080002D0B8F1010F6AD136 +:10D2700009208DF83C0007A800908DF840804346B7 +:10D28000002221461B98FFF72CFC8DF842004FF03E +:10D29000000B8DF843B050B9B8F1010F12D0B8F1BE +:10D2A000000F04D1A18FA1F57F40FF380AD0A08FD5 +:10D2B00040B18DF83CB04FF4806000E037E0ADF84D +:10D2C00050000DE00FA91B98F9F725FF82468DF855 +:10D2D0003CB04FF48060ADF85000BAF1020F06D0B8 +:10D2E000FC480068C07928B18DF8180027E0A4F840 +:10D2F000188044E0BAF1000F03D081208DF81800A7 +:10D300003DE007A800904346012221461B98FFF705 +:10D31000E8FB8DF8180021461B98FFF7CAFB9DF823 +:10D32000180020B9192189F80010012038809DF8D3 +:10D330003C0020B10FA91B98F9F7EDFE8246BAF127 +:10D34000000F33D01BE018E08DF818E031E02078B2 +:10D35000000712D5012E10D10A208DF83C00E0887C +:10D36000ADF8400003201B9909F028F80820ADF81B +:10D370005000C1E648067FF5F6AC4FF0040A20885D +:10D38000BDF8501008432080BDF8500080050BD533 +:10D39000A18FA1F57F40FE3806D11E98E062289843 +:10D3A0002063A6864FF0030A5046A1E49DF81800BA +:10D3B00078B1012089F80000297889F80110BDF8BA +:10D3C0001C10A9F802109DF8181089F80410052007 +:10D3D00038802088BDF8501088432080E4E72DE98C +:10D3E000FF4F8846087895B0012181404FF209002F +:10D3F000249C0140ADF820102088DDF88890A0F52D +:10D400007F424FF0000AFF3A06D039B1000705D538 +:10D41000012019B0BDE8F08F0820FAE7239E4FF0F5 +:10D42000000B0EA886F800B018995D460988ADF883 +:10D430003410A8498DF81CB0179A0A718DF838B0CD +:10D44000086098F8000001283BD0022809D0032882 +:10D450006FD1307820F03F001D303070B8F80400F4 +:10D46000E08098F800100320022904D1317821F0DF +:10D470003F011B31317094F84610090759D505ABAF +:10D48000B9F1000F13D0002102AA82E80B00072097 +:10D49000CDE90009BDF83400B8F80410C01E83B20D +:10D4A0000022159800F0A8FD0028D1D101E0F11C60 +:10D4B000EAE7B8F80400A6F80100BDF81400C01CA3 +:10D4C00004E198F805108DF81C1098F80400012864 +:10D4D00006D04FF4007A02282CD00328B8D16CE192 +:10D4E0002188B8F8080011F40061ADF8201020D0B0 +:10D4F00017281CD3B4F84010814218D3B4F8441054 +:10D50000172901D3814212D1317821F03F01C91C82 +:10D510003170A6F801000321ADF83410A4F84400DE +:10D5200094F8460020F0020084F8460065E10525E5 +:10D530007EE177E1208808F1080700F4FE60ADF88D +:10D54000200010F0F00F1BD010F0C00F03D038886F +:10D55000228B9042EBD199B9B878C00710D0B96846 +:10D560000720CDE902B1CDF804B00090CDF810B09D +:10D57000FB88BA883988159800F014FB0028D6D1AA +:10D580002398BDF82010401C80294ED006DC1029BD +:10D590000DD020290BD0402987D124E0B1F5807F20 +:10D5A0006ED051457ED0B1F5806F97D1DEE0C806D0 +:10D5B00001D5082000E0102082460DA907AA052009 +:10D5C000CDE902218DF83800ADF83CB0CDE90496E4 +:10D5D00008A93888CDE9000153460722214615984D +:10D5E000FFF7B4F8A8E09DF81C2001214FF00A0ACB +:10D5F000002A9BD105ABB9F1000F00D00020CDE986 +:10D6000002100720CDE90009BDF834000493401E44 +:10D6100083B2218B0022159800F0EEFC8DF81C00DF +:10D620000B203070BDF8140020E09DF81C20012173 +:10D630004FF00C0A002A22D113ABB9F1000F00D031 +:10D640000020CDE902100720CDE900090493BDF8C0 +:10D650003400228C401E83B2218B159800F0CCFC44 +:10D660008DF81C000D203070BDF84C00401CADF84A +:10D67000340005208DF83800208BADF83C00BCE06C +:10D680003888218B88427FF452AF9DF81C004FF000 +:10D69000120A00281CD1606AA8B1B878C0073FF40C +:10D6A00046AF00E018E0BA680720CDE902B2CDF835 +:10D6B00004B00090CDF810B0FB88BA88159800F03F +:10D6C00071FA8DF81C00132030700120ADF8340081 +:10D6D00093E00000580000203988208B8142D2D18D +:10D6E0009DF81C004FF0160A0028A06B08D0E0B38C +:10D6F0004FF6FF7000215F46ADF808B0019027E0BB +:10D7000068B1B978C907BED1E18F0DAB0844821D5D +:10D7100003968DE80C0243888288018809E0B87876 +:10D72000C007BCD0BA680DAB03968DE80C02BB886D +:10D73000FA881598FFF7F3F905005ED0072D72D02F +:10D7400076E0019005AA02A92046FFF729F90146D3 +:10D75000E28FBDF80800824201D00029F1D0E08FAD +:10D76000A16B084407800198E08746E09DF81C0003 +:10D770004FF0180A40B1208BC8B138882083214669 +:10D780001598FFF796F938E004F118000090237E11 +:10D79000012221461598FFF7A4F98DF81C000028F6 +:10D7A000EDD1192030700120ADF83400E7E70525F0 +:10D7B00021461598FFF77DF93AE0208800F40070C3 +:10D7C000ADF8200050452DD1A08FA0F57F41FE3946 +:10D7D00001D006252CE0D8F808004FF0160A48B111 +:10D7E000A063B8F80C10A1874FF6FF71E187A0F88D +:10D7F00000B002E04FF6FF70A087BDF8200030F4C3 +:10D800007F611AD0782300220320159908F02CFD9F +:10D8100098F8000020712088BDF82010084320806F +:10D820000EE000E007252088BDF820108843208006 +:10D83000208810F47F6F1CD03AE02188814321803A +:10D840009DF8380020B10EA91598F9F764FC05463B +:10D850009DF81C000028EBD086F801A00120307054 +:10D86000208B70809DF81C0030710520ADF83400CD +:10D87000DEE7A18EE1B118980DAB0088ADF8340059 +:10D880002398CDE90304CDE90139206B0090E36AC8 +:10D89000179A1598FFF7FCF9054601208DF8380016 +:10D8A0000EA91598F9F737FC00B10546A4F834B075 +:10D8B00094F8460040070AD52046FFF7A0F910F07B +:10D8C0003E0F04D114F8460F20F004002070189881 +:10D8D000BDF83410018028469BE500B585B00328CB +:10D8E00006D102208DF8000088B26946F9F713FCD2 +:10D8F00005B000BD10B5384C0B782268012B02D062 +:10D90000022B2AD111E013780BB1052B01D104238E +:10D91000137023688A889A802268CB88D380226813 +:10D920000B891381498951810DE08B88938022688E +:10D93000CB88D38022680B8913814B8953818B89D3 +:10D940009381096911612168F9F7E5FB22680021DB +:10D950000228117003D0002800D0812010BD832040 +:10D9600010BD806B002800D001207047817801290C +:10D9700009D10088B0F5205F03D042F6010188424A +:10D9800001D10020704707207047F0B587B0002410 +:10D9900015460E460746ADF8184011E00598008878 +:10D9A000288005980194811DCDE902410721049446 +:10D9B0000091838842880188384600F0F3F830B936 +:10D9C00005AA06A93046FEF7EBFF0028E6D00A2894 +:10D9D00000D1002007B0F0BD5800002010B58B78B2 +:10D9E00083B102789A4205D10B885BB102E08B7952 +:10D9F000091D4BB18B789A42F9D1B0F801300C88EF +:10DA0000A342F4D1002010BD812010BD072826D0EC +:10DA100012B1012A27D103E0497801F0070102E0A1 +:10DA20004978C1F3C20105291DD2DFE801F00318CE +:10DA3000080C12000AB10320704702207047042826 +:10DA40000DD250B10DE0052809D2801E022808D35E +:10DA500003E0062803D0032803D0052070470020E8 +:10DA600070470F20704781207047C0B282060BD4E8 +:10DA7000000607D5FE48807A4143C01D01EBD00067 +:10DA800080B27047084670470020704770B5138811 +:10DA90000B800B781C0625D5F54CA47A844204D85B +:10DAA00043F010000870002070BD956800F0070674 +:10DAB00005EBD0052D78F54065F304130B70137852 +:10DAC000D17803F0030341EA032140F20123B1FBC3 +:10DAD000F3F503FB15119268E41D00FB012000EB38 +:10DAE000D40070BD906870BD37B51446BDF8041001 +:10DAF00011809DF804100A061ED5C1F30013DC49FD +:10DB0000A568897A814208D8FE2811D1C91DC908A3 +:10DB10005A42284617F0F5FD0AE005EBD00100F067 +:10DB20000702012508789540A843934018430870E0 +:10DB3000207820F0100020703EBD2DE9F04107460E +:10DB4000C81C0E4620F00300B04202D08620BDE87B +:10DB5000F081C74D002034462E60AF802881AA7224 +:10DB6000E8801AE0E988491CE980810614D4E1784C +:10DB700000F0030041EA002040F20121B0FBF1F285 +:10DB800001FB12012068FFF770FF2989084480B269 +:10DB90002881381A3044A0600C3420784107E1D441 +:10DBA0000020D4E72DE9FF4F89B01646DDE9168A3B +:10DBB0000F46994623F44045084600F00DFB04004B +:10DBC0000FD0099804F0A6FE0290207800060AD52E +:10DBD000A748817A0298814205D887200DB0BDE818 +:10DBE000F08F0120FAE7224601A90298FFF74EFFC5 +:10DBF000834600208DF80C004046B8F1070F1AD07C +:10DC000001222146FFF702FF0028E7D120784006D5 +:10DC100011D502208DF80C00ADF81070BDF804008D +:10DC2000ADF81200ADF814601898ADF81650CDF8A4 +:10DC30001CA0ADF818005FEA094004D500252E4667 +:10DC4000A84601270CE02178E07801F0030140EAC2 +:10DC5000012040F20121B0FBF1F2804601FB128766 +:10DC60005FEA494009D5B84507D1A178207901F08C +:10DC7000030140EA0120B04201D3BE4201D907208E +:10DC8000ACE7A8191FFA80F9B94501D90D20A5E71D +:10DC90009DF80C0028B103A90998F9F73AFA002871 +:10DCA0009CD1B84507D1A0784FEA192161F3010052 +:10DCB000A07084F804901A9800B10580199850EA71 +:10DCC0000A0027D0199830B10BEB06002A461999A3 +:10DCD00017F0A0FC0EE00BEB06085746189E0998BB +:10DCE00004F084FF2B46F61DB5B239464246009536 +:10DCF00004F06FFB224601A90298FFF7C7FE9DF8CA +:10DD00000400224620F010008DF80400DDE9011027 +:10DD1000FFF7EAFE002061E72DE9FF4FDFF85091A1 +:10DD200082461746B9F80610D9F8000001EB410108 +:10DD300000EB810440F20120B2FBF0F185B000FB62 +:10DD400011764D46DDF84C8031460698FFF78DFE82 +:10DD500029682A898B46611A0C3101441144AB8829 +:10DD600089B28B4202D8842009B038E70699CDB237 +:10DD7000290603D5A90601D50620F5E7B9F806C09E +:10DD80000CF1010C1FFA8CFCA9F806C0149909B11A +:10DD9000A1F800C0A90602D5C4F8088007E0104425 +:10DDA00080B2A9F80800191A01EB0B00A060224606 +:10DDB000FE200699FFF798FEE77026712078390A51 +:10DDC00061F30100320AA17840F0040062F301011E +:10DDD000A17020709AF802006071BAF80000E0802B +:10DDE00000262673280602D599F80A7000E001275C +:10DDF000A80601D54FF000084D4600244FF0070952 +:10DE00000FE0CDE902680196CDF800900496E9880C +:10DE10002046129B089AFFF7C5FE0028A4D1641C77 +:10DE2000E4B2BC42EDD300209EE72DE9F0478046E6 +:10DE300000F0D2F9070005D0002644460C4D40F210 +:10DE4000012919E00120BDE8F087204600F0C4F95F +:10DE50000278C17802F0030241EA0222B2FBF9F330 +:10DE600009FB13210068FFF700FE304486B201E091 +:10DE7000F4050020641CA4B2E988601E8142E4DC41 +:10DE8000A8F10100E8802889801B288100203870D3 +:10DE9000D9E710B5144631B1491E218004F03AFD8E +:10DEA000A070002010BD012010BD10B5D24904465D +:10DEB0000088CA88904201D30A2010BD096800EB8F +:10DEC000400001EB80025079A072D08820819178C7 +:10DED000107901F0030140EA0120A081A078E11C43 +:10DEE000FFF7D4FD20612088401C2080E0800020C6 +:10DEF00010BD0121018270472DE9FF4F85B04FF61B +:10DF0000FF788246A3F8008048681F460D46807857 +:10DF10008DF8060048680088ADF8040000208DF8F0 +:10DF20000A00088A0C88A04200D304462C8241E0F3 +:10DF3000288A401C2882701D6968FFF74FFDB8BB16 +:10DF40003988414501D1601E38806888A04236D3A7 +:10DF5000B178307901F0030140EA012901A9701D6F +:10DF6000FFF73CFD20BB298941452CD000223146DA +:10DF70000798FFF74BFDD8B92989494518D1E968B9 +:10DF80000391B5F80AC0D6F808B05046CDF800C0E5 +:10DF900004F02CFEDDF800C05A460CF1070C1FFA05 +:10DFA0008CFC4B460399CDF800C004F0DCF950B16D +:10DFB000641CA4B2204600F00FF90600B8D1641E1C +:10DFC0002C820A20D0E67C807079B871F088B88005 +:10DFD0003178F07801F0030140EA01207881A7F858 +:10DFE0000C90504604F096FC324607F10801FFF70A +:10DFF0004DFD38610020B7E62DE9FF4F87B081461F +:10E000001C469246DDF860B0DDF85480089800F0B8 +:10E01000E3F805000CD0484604F07CFC297809069A +:10E0200008D57549897A814204D887200BB0D6E596 +:10E030000120FBE7CAF309062A4601A9FFF726FDDE +:10E040000746149807281CD000222946FFF7DEFC5B +:10E050000028EBD12878400613D501208DF8080060 +:10E060000898ADF80C00BDF80400ADF80E00ADF84E +:10E070001060ADF8124002A94846F9F74AF80028A6 +:10E08000D4D12978E87801F0030140EA0121AA7887 +:10E09000287902F0030240EA0220564507D0B1F584 +:10E0A000007F04D9611E814201DD0B20BEE786425C +:10E0B00001D90720BAE7801B85B2A54200D92546C1 +:10E0C000BBF1000F01D0ABF80050179818B1B91987 +:10E0D0002A4617F09FFAB8F1000F0DD03E4448468B +:10E0E0004446169F04F094FD2146FF1DBCB2324603 +:10E0F0002B46009404F0A1F9002097E72DE9F041A8 +:10E1000007461D461646084600F066F804000BD088 +:10E11000384604F0FFFB2178090607D53649897A8D +:10E12000814203D8872012E5012010E522463146BE +:10E13000FFF7ACFC65B12178E07801F0030140EA1B +:10E140000120B0F5007F01D8012000E000202870F8 +:10E150000020FCE42DE9F04107461D46164608461E +:10E1600000F03AF804000BD0384604F0D3FB2178D5 +:10E17000090607D52049897A814203D88720E6E439 +:10E180000120E4E422463146FFF7AEFCFF2D14D017 +:10E190002178E07801F0030240EA022040F20122F7 +:10E1A000B0FBF2F302FB130015B900F2012080B2BC +:10E1B000E070000A60F3010121700020C7E410B58F +:10E1C0000C4600F009F828B1C18821804079A07080 +:10E1D000002010BD012010BD0749CA88824209D322 +:10E1E00040B1096800EB40006FF00B0202EB8000C9 +:10E1F0000844704700207047F405002010B508F06F +:10E20000C3FAF4F753FB08F025F9BDE8104008F015 +:10E21000EDB9302834BF012000207047202834BFDA +:10E220004FF0A0420C4A012300F01F0003FA00F057 +:10E23000002914BFC2F80C05C2F808057047202851 +:10E2400034BF4FF0A041044900F01F00012202FA40 +:10E2500000F0C1F8180570470003005070B5034680 +:10E26000002002466FF02F050EE09C5CA4F1300602 +:10E270000A2E02D34FF0FF3070BD00EB800005EB9B +:10E280004000521C2044D2B28A42EED370BD30B559 +:10E290000A230BE0B0FBF3F403FB1404B0FBF3F030 +:10E2A0008D183034521E05F8014CD2B2002AF1D13B +:10E2B00030BD30B500234FF6FF7510E0040A44EA84 +:10E2C000002084B2C85C6040C0F30314604005EADB +:10E2D00000344440E0B25B1C84EA40109BB293429D +:10E2E000ECD330BD2DE9F041FA4B0026012793F81D +:10E2F00060501C7893F864C0B8B183F88D40A3F8DF +:10E300008E1083F88C2083F88A70BCF1000F0CBF4C +:10E3100083F8906083F89050EF488068008804F09C +:10E3200065FCBDE8F04104F0FBB84FF6FF7083F8E0 +:10E330008D40A3F88E0083F88C2083F88A70BCF19E +:10E34000000F14BF83F8905083F89060BDE8F0810F +:10E3500070B5E14E0446306890F898100025012908 +:10E3600019D090F89210012924D090F86810012952 +:10E370002AD090F88A1001291CBF002070BD65705A +:10E3800017212170D0F88C106160B0F890102181B5 +:10E3900080F88A5016E065701C212170D0F8991021 +:10E3A0006160D0F89D10A16090F8A110217380F8F1 +:10E3B000985007E0657007212170D0F894106160D3 +:10E3C00080F89250012070BD65701421217000F119 +:10E3D0006A012022201D17F01DF9012121723068E9 +:10E3E00080F86850BB48B0F86C20A0F89420B26860 +:10E3F000537B80F8963080F89210108804F0F6FB7A +:10E4000004F09DF8DEE7B448006890F86810002931 +:10E4100014BFB0F86C004FF6FF70704770B5AE4C8B +:10E4200006462068002808BFFFDF002520684570E9 +:10E430006660002808BFFFDF2068417800291CBF04 +:10E44000FFDF70BDA42117F086F92068FF2101705D +:10E450007F2180F8361013214184282180F865102F +:10E46000012180F8581080F85D5008F0C3FDBDE828 +:10E47000704008F01CB898490968097881420CBFBF +:10E480000120002070479448006890F82200C0F3F3 +:10E49000400070479048006890F8220000F00100AA +:10E4A00070478D48006890F82200C0F30010704754 +:10E4B0002DE9F04388480024036893F82400B3F85A +:10E4C00022C0C0F38001C0F34002114400F00100FB +:10E4D0000144CCF3001060B3BCF1130F21D00BDC6E +:10E4E000BCF1100F02BF7D4830F81100BDE8F08389 +:10E4F000BCF1120F15D008E0BCF1150F09D0BCF12A +:10E500001D0F04BF7648BDE8F083FFDF2046BDE85D +:10E51000F083744A002032F8112011FB0020BDE87E +:10E52000F083714A002032F8112011FB0020BDE871 +:10E53000F08393F85A2093F85B002E264FF47A77F5 +:10E540004FF014084FF04009022A04BF4AF2D745A1 +:10E55000B5FBF7F510D0012A04BF4AF22F75B5FBC1 +:10E56000F7F510D04AF62315B5FBF7F5082A08BFD2 +:10E570004E4613D0042A18D02646082A0ED0042A64 +:10E5800013D0022A49D004F12806042A0FD0082A01 +:10E590001CBF4FF01908082204D00AE04FF01408FD +:10E5A00006F5A8764FF0400203E006F5A8764FF096 +:10E5B000100218FB026212FB0152C1EB01114B4D1C +:10E5C00001EB810105EB810111441CF0010F4FF4B7 +:10E5D000C8724FF4BF7504BFCCF34006002E77D04D +:10E5E000CCF3400601F5A571EEB1082804BF16462C +:10E5F00040270CD0042804BF2E46102707D002283D +:10E6000007BF04F11806042704F12806082707EBC2 +:10E61000870706EB870631441CE004F118064FF02B +:10E6200019080422C5E7082804BF164640270CD065 +:10E63000042804BF2E46102707D0022807BF04F184 +:10E640001806042704F12806082707EB871706EBAE +:10E650008706314401F19C0693F8651010F00C0F09 +:10E6600008BF00213144082804BF164640270CD0BB +:10E67000042804BF2E46102707D0022807BF04F144 +:10E680001806042704F128060827C7EBC70707EB7D +:10E69000470706EB4706314498311CF0010F27D09D +:10E6A000082808BF40200CD0042804BF2A461020A8 +:10E6B00007D0022807BF04F11802042004F1280241 +:10E6C000082000EB400303EB0010104401444AE033 +:10E6D0004DE000000006002060000020BC5B02004E +:10E6E0008E891300C45B0200B45B0200D4FEFFFFFE +:10E6F000082804BF944640260CD0042804BFAC462A +:10E70000102607D0022807BF04F1180C042604F1D4 +:10E71000280C082606EB86169B8F0CEB860C6144B2 +:10E72000EB2B20D944F2552C0B3303FB0CF39B0D40 +:10E73000082807D0042802D0022805D008E02A467D +:10E74000102008E0402006E004F11802042002E056 +:10E7500004F12802082000EB801002EB800000F595 +:10E76000A57003FB001101F26510BDE8F08301F50F +:10E77000A571082804BF944640260CD0042804BF85 +:10E78000AC46102607D0022807BF04F1180C042657 +:10E7900004F1280C082606EB8616B3F844300CEB7F +:10E7A000860C6144EB2BDED944F2552C0B3303FB72 +:10E7B0000CF39B0D0828C5D00428C0D00228C7D16F +:10E7C000C2E7FE4840F271210068806A4843704702 +:10E7D000FA48006890F83500002818BF01207047FB +:10E7E00010B5F74C207B022818BF032808D1207DE4 +:10E7F00004F115010DF023FC08281CBF012010BDF9 +:10E80000207B002816BF022800200120BDE8104010 +:10E8100009F054B9EA4908737047E849096881F872 +:10E82000300070472DE9F047E44C2168087B002850 +:10E8300016BF022800200120487301F10E0109F0E3 +:10E8400027F92168087B022816BF0328012200222D +:10E8500081F82F204FF0080081F82D00487B01F14E +:10E860000E034FF001064FF00007012804BF5B794B +:10E8700013F0C00F0AD001F10E03012804D158791A +:10E8800000F0C000402801D0002000E0012081F805 +:10E890002E00002A04BF91F8220010F0040F07D0C8 +:10E8A000087D01F115010DF0CAFB216881F82D00EA +:10E8B0002068476006F0AAF92168C14D4FF00009B1 +:10E8C000886095F82D000DF0D6FB804695F82F0056 +:10E8D000002818BFB8F1000F04D095F82D000DF0F6 +:10E8E00091F968B195F8300000281CBF95F82E000A +:10E8F00000281DD0697B05F10E0001290ED012E021 +:10E900006E734A4605F10E01404609F016F995F876 +:10E910002D1005F10E000DF0A5FC09E0407900F086 +:10E92000C000402831D0394605F10E0009F03CF90D +:10E930002068C77690F8220010F0040F08BFBDE8E9 +:10E94000F087002795F82D000DF010FA050008BF9C +:10E95000BDE8F08710210EF0C8F9002818BFBDE807 +:10E96000F08720683A4600F11C01C676284609F077 +:10E97000E4F8206800F11C0160680EF0DBFD6068BF +:10E98000BDE8F04701210EF0F0BD0DF0A8FC4A46AD +:10E9900005F10E0109F0D1F8CAE7884A1268137B25 +:10E9A0000370D2F80E000860508A8880704778B5EE +:10E9B00083490446814D407B08732A682078107093 +:10E9C0006088ADF8000080B200F00101C0F34003A0 +:10E9D00041EA4301C0F3800341EA8301C0F3C0036D +:10E9E00041EAC301C0F3001341EA0311C0F340132D +:10E9F00041EA4311C0F3801041EA80105084E07D69 +:10EA0000012808BF012607D0022808BF022603D02C +:10EA1000032814BFFFDF0826286880F85A60607E4C +:10EA2000012808BF012607D0022808BF022603D00C +:10EA3000032814BFFFDF0826286880F85B60217B6D +:10EA400080F82410418C1D290CBF0021616881626F +:10EA5000617D80F83510A17B002916BF02290021B5 +:10EA600001210175D4F80F10C0F81510B4F8131077 +:10EA7000A0F81910A17EB0F8662061F30302A0F897 +:10EA80006620E17E012918BF002180F834100020A3 +:10EA900078BD4A480068408CC0F3001131B1C0F322 +:10EAA0008000002804BF1F20704702E0C0F340012F +:10EAB00009B10020704710F0010F14BFEE20FF20B5 +:10EAC00070473E480068408CC0F3001119B1C0F394 +:10EAD000800028B102E0C0F3400008B10020704778 +:10EAE000012070473549002209680A664B8C1D2BAE +:10EAF0000CBF81F8642081F86400704700232F4A1E +:10EB0000126882F859309164A2F84C00012082F812 +:10EB100059007047294A0023126882F85830A2F839 +:10EB200054000120116582F8580070472349096894 +:10EB300081F85D0070472148006890F95D007047DA +:10EB40001E48006890F82200C0F3401070471B4830 +:10EB5000006890F82200C0F3C000704701207047A1 +:10EB60001648006890F85B00704770B508F02CFA02 +:10EB700008F00BFA08F00EF908F08CF90F4C206839 +:10EB8000016E491C016690F83300002530B108F091 +:10EB900031FA07F08CFC206880F83350206845700B +:10EBA00090F8371021B1BDE87040042009F06BBC2B +:10EBB00090F8641001B3006E814203E06000002011 +:10EBC0000006002018D8042009F05DFC206890F8A9 +:10EBD000220010F0010F07D0A06843220188BDE891 +:10EBE00070400120FFF77EBBBDE8704043224FF626 +:10EBF000FF710020FFF776BBBDE87040002009F0F0 +:10EC000042BC2DE9F04782B00F468146FE4E4FF0E0 +:10EC100000083068458C15F0030F10D015F0010F77 +:10EC200005F0020005D0002808BF4FF0010806D00B +:10EC300004E0002818BF4FF0020800D1FFDF4FF0BA +:10EC4000000A544615F0010F05F002000DD080B9FE +:10EC500015F0040F0DD04AF00800002F1CBF40F043 +:10EC6000010040F0020440D08FE010B115F0040F15 +:10EC70000DD015F0070F10D015F0010F05F00200B0 +:10EC800036D0002808BF15F0040F27D03DE0002F34 +:10EC900018BF4AF0090478D134E02FB14AF00804D3 +:10ECA00015F0200F14D070E0316805F02002B1F8A3 +:10ECB0004400104308BF4AF0010466D04AF018042B +:10ECC00015F0200F61D191F85A10082959D155E05B +:10ECD000316891F85A10082950D152E04AF00800E2 +:10ECE000002F18BF40F001044FD140F010044CE059 +:10ECF000002818BF15F0040F07D0002F18BF4AF0E6 +:10ED00000B0442D14AF018043FE015F0030F3BD149 +:10ED100015F0040F38D077B131684AF0080091F847 +:10ED20005A1008290CBF40F0020420F0020415F02C +:10ED3000200F21D029E0316805F02002B1F844000D +:10ED4000104308BF4AF003041FD04AF0180015F022 +:10ED5000200F08D091F85A10082914BF40F002047F +:10ED600020F0020411E091F85A20082A14BF40F064 +:10ED7000010020F00100EDE7082902D024F0010491 +:10ED800003E044F0010400E0FFDF15F0400F1BD06A +:10ED9000C7B93168B1F84400002804BF488C10F0AE +:10EDA000010F0BD110F0020F08BF10F0200F05D19A +:10EDB00015F0010F08BF15F0020F03D091F85A00AB +:10EDC000082801D044F040047068A0F800A0017841 +:10EDD00021F02001017007210EF078FB4146706898 +:10EDE0000EF06BFD214670680EF073FD14F0010FFC +:10EDF0000AD006230022854970680EF044FD306871 +:10EE0000417B70680EF0A4FB14F0020F18D0D6E915 +:10EE10000010B9F1000F4FF006034FF0010207D0C8 +:10EE20001C310EF030FD012170680EF09EFB07E0F2 +:10EE300015310EF028FD3068017D70680EF095FBED +:10EE400014F0040F18BFFFDF14F0080F17D0CDF82F +:10EE500000A03068BDF800100223B0F86600020977 +:10EE600062F30B01ADF800109DF80110032260F36E +:10EE700007118DF80110694670680EF004FD012F2E +:10EE800061D13068B0F84410E9B390F82200C0F3C3 +:10EE90004000C0BB70680EF00CFD401CC7B230686B +:10EEA000B0F84420B0F85610551AC7F1FF018D4252 +:10EEB000A8BF0D46AA423AD990F8220010F0010FDF +:10EEC00035D144F01004214670680EF002FDF81CA4 +:10EED000C0B2ED1E284482B23068B0F86610036EEE +:10EEE000090951FA83F190F85C30494F1944BC4646 +:10EEF0000023E1FB07C31B096FF0240C03FB0C117B +:10EF000080F85C1000E01EE090F85B00012101F049 +:10EF100037F80090BDF800009DF80210032340EA86 +:10EF200001400190042201A970680EF0ACFC306829 +:10EF3000AAB2016C70680EF0FAFC3068B0F8561096 +:10EF40002944A0F8561014F0400F06D0D6E900105E +:10EF5000012306225D310EF096FC14F0200F18BF3D +:10EF6000FFDF0020002818BFFFDF02B0BDE8F087F8 +:10EF70002DE9F843244C2068002808BFFFDF2068F3 +:10EF8000417839BB0178FF2924D0002680F8316010 +:10EF9000A0F85660867080F83760304607F08EFF24 +:10EFA00007F0B3FC206890F95D0007F048FD1948B0 +:10EFB00007F04BFD184807F067FF606807F081FF16 +:10EFC000206890F8240010F0010F06D0252007F0EB +:10EFD00044FD09E00C20BDE8F88310F0020F18BFD3 +:10EFE000262075D007F039FD206890F85A102520AA +:10EFF00007F049FC206880F82C6007F059FF206872 +:10F0000090F85A10002009E0600000200E06002051 +:10F0100053E4B36EB05B0200AD5B020007F07BFD12 +:10F020000F21052007F0DFFC206890F82E10002942 +:10F0300001BF90F82F10002990F8220010F0040F63 +:10F0400075D005F0E3FD054620682946806806F086 +:10F05000F9FADFF83084074690FBF8F008FB1070EF +:10F060004142284605F0D3FA2168886097FBF8F002 +:10F070004A68104448600CF0DFFF0146206842688F +:10F0800091426FD8C0E90165FF4D4FF0010895F836 +:10F090002D000CF0F0FF814695F82F000127002885 +:10F0A00018BFB9F1000F04D095F82D000CF0AAFD9F +:10F0B000A8B195F8300000281CBF95F82E00002854 +:10F0C00025D0697B05F10E00012916D01AE0FFE773 +:10F0D00010F0040F14BF2720FFDF83D184E73A46E6 +:10F0E0006F7305F10E01484608F027FD95F82D10C5 +:10F0F00005F10E000DF0B6F809E0407900F0C0000F +:10F10000402815D0414605F10E0008F04DFD20685D +:10F1100090F8220010F0040F24D095F82D000CF088 +:10F1200025FE05001ED010210DF0DFFD40B119E0D5 +:10F130000DF0D5F83A4605F10E0108F0FEFCE6E7C1 +:10F1400020683A4600F11C01C776284608F0F5FC15 +:10F15000206800F11C0160680EF0ECF90121606884 +:10F160000EF003FA2068417B0E3007F020FC206887 +:10F1700090F8581059B3B0F85410A0F84410016D2D +:10F18000016490F82210C1F30011E9B9B0F86600EB +:10F1900002210509ADF80050684606F011FE28B1BD +:10F1A000BDF80000C0F30B00A84204D1BDF8000078 +:10F1B000401CADF800002168BDF80000B1F86620E1 +:10F1C00060F30F12A1F86620206880F8586020686C +:10F1D00090F8591031B1B0F84C108187816C81637F +:10F1E00080F85960B0F86610026E090951FA82F190 +:10F1F00090F85C20DFF894C2114463460022E1FBE2 +:10F200000C3212096FF0240302FB031180F85C102A +:10F210000CF095FF032160680DF014F8216881F867 +:10F2200033000020BDE8F8839949886070472DE9D4 +:10F23000F043974C83B0226892F831303BB1508C48 +:10F240001D2808BFFFDF03B0BDE8F0438DE40126B1 +:10F250000027F1B1054692F85C0007F0FEFB20683C +:10F2600090F85B10FF2007F00EFB20684FF4A571AB +:10F2700090F85B20002007F050FD206890F82210E5 +:10F2800011F0030F00F02E81002D00F0258100F019 +:10F2900029B992F822108046D07EC1F300110029CE +:10F2A00056D0054660680780017821F02001017082 +:10F2B000518C132937D01FDC102908BF022144D0FC +:10F2C000122908BF062140D0FFDF6F4D606805F1AD +:10F2D0000E010EF021F9697B60680EF039F92068A3 +:10F2E000418C1D2918BF152965D0B0F84420016C48 +:10F2F00060680EF046F95EE0152918BF1D29E3D1BC +:10F300004FF001010EF0E2F86068017841F0200151 +:10F310000170216885B11C310EF00CF90121606883 +:10F320000EF023F9D1E700210EF0D0F860680178E3 +:10F3300041F020010170C8E715310EF0FBF820689C +:10F34000017D60680EF011F9BFE70EF0BFF8BCE771 +:10F350000021FFF756FC6068C17811F03F0F2AD0FA +:10F36000017911F0100F26D00EF0AEF82368024696 +:10F3700093F82410C1F38000C1F3400C604401F005 +:10F38000010100EB010C93F82C10C1F38000C1F3D4 +:10F390004005284401F001010844ACEB0000C1B273 +:10F3A00093F85A0000F0ECFD009003230422694614 +:10F3B00060680EF068FA2068002590F8241090F834 +:10F3C0002C0021EA000212F0010F18BF01250ED116 +:10F3D00011F0020F04D010F0020F08BF022506D072 +:10F3E00011F0040F03D010F0040F08BF0425B8F18A +:10F3F000000F2BD0012D1BD0022D08BF26201BD0C3 +:10F40000042D14BFFFDF272016D0206890F85A1073 +:10F41000252007F038FA206890F82210C1F3001177 +:10F4200069B101224FF49671002007F076FC0DE0DF +:10F43000252007F012FBE8E707F00FFBE5E790F85F +:10F440005A204FF49671002007F067FC206890F86E +:10F450002C10294380F82C1090F8242032EA010166 +:10F460001DD04670418C13292CD027DC102904BFF5 +:10F4700003B0BDE8F083122924D000BFC1F300100F +:10F48000002807E040420F000006002053E4B36E5E +:10F490006000002018BFFFDF03B0BDE8F083418C9F +:10F4A0001D2908BF80F82C70DBD0C1F300110029A2 +:10F4B00014BF80F8316080F83170D2E7152918BF89 +:10F4C0001D29DBD190F85A2003B04FF00101BDE8AF +:10F4D000F043084607F002BE90F85B200121084681 +:10F4E00007F0FCFD2168002DC87E7CD04A8C3D468B +:10F4F000C2F34000002808BF47F0080512F0400F93 +:10F5000018BF45F04005002819BFD1F83890B1F870 +:10F510003C80D1F84090B1F84480606807210780B2 +:10F520000DF0D4FF002160680EF0C7F9294660682D +:10F530000EF0CFF915F0080F15D02068BDF80010B7 +:10F540000223B0F86600020962F30B01ADF8001067 +:10F550009DF80110032260F307118DF80110694630 +:10F5600060680EF090F960680EF06CF82168C0F1E8 +:10F57000FE00B1F85620A8EB02018142A8BF014667 +:10F58000CFB2D019404542D245F0100160680EF06C +:10F59000A0F960680EF056F82168C0F1FE00B1F8DD +:10F5A0005610A8EB01018142A8BF0146CFB26068A6 +:10F5B0000EF07FF93844421C2068B0F86610036EE4 +:10F5C000090951FA83F190F85C30FF4D1944AC46BB +:10F5D0000023E1FB05C31B096FF0240C03FB0C1196 +:10F5E00080F85C1000E038E090F85B00012100F04A +:10F5F000C7FC0090BDF800009DF80210032340EA0C +:10F6000001400190042201A960680EF03CF92168D4 +:10F6100091F8220010F0400F05D0012306225D3141 +:10F6200060680EF030F920683A46B0F8560000EBFA +:10F63000090160680EF07BF92068B0F85610394473 +:10F64000A0F8561008F0D0F8002818BFFFDF206897 +:10F650004670867003B0BDE8F0830121FFF7D1FA50 +:10F66000F0E7DA4810B50068417841B90078FF2822 +:10F6700005D000210846FFF7DAFD002010BD07F095 +:10F68000A3FC07F082FC07F085FB07F003FC0C20CD +:10F6900010BD10B5CD4C206890F8220010F0010F7D +:10F6A0001CBFA06801884FF03C0212BF01204FF63A +:10F6B000FF710020FEF716FE2168012081F8370057 +:10F6C00010BDC249096881F8320070472DE9F04148 +:10F6D000002508F0A4FE002800F00581BB4C20683E +:10F6E000417801270026012906D0022901D00329EB +:10F6F0007ED0FFDFBDE8F081817802260029418CB1 +:10F7000046D0C1F34002002A08BF11F0010F70D0AB +:10F7100090F85B204FF001014FF0000007F0DEFC95 +:10F72000216891F82200C0F34000002814BF0C208B +:10F73000222091F85B1007F0A6F82068467090F838 +:10F74000330058B106F09FFE206890F85B0010F07F +:10F750000C0F0CBF4020452007F042FC206890F8B9 +:10F760003400002818BF07F089FC216891F85B007D +:10F7700091F8651010F00C0F08BF0021962007F0DB +:10F78000C1FB08F028F8002818BFFFDFBDE8F081B2 +:10F79000C1F3001282B110293FD090F8330020B19C +:10F7A00006F071FE402007F01BFC206890F8221044 +:10F7B00011F0040F36D043E090F8242090F82C305C +:10F7C0009A422AD1B0F84400002808BF11F0010F76 +:10F7D00005D111F0020F08BF11F0200F7ED04FF0BD +:10F7E00001014FF00000FFF722FD2068418C01E08D +:10F7F00040E034E011F0010F04BFC1F340010029E3 +:10F8000007D1B0F85610B0F84420914218BFBDE8B7 +:10F81000F08180F83170BDE8F081BDE8F041002151 +:10F82000012004E590F83510012914BF03291025A3 +:10F8300045F00E0190F85A204FF0000007F04EFC02 +:10F84000206890F83400002818BF07F017FC00214A +:10F85000962007F057FB20684670BDE8F081B0F8AD +:10F860005610B0F8440081423DD0BDE8F04101217E +:10F870000846DCE48178D9B1418C11F0010F1CD02D +:10F8800080F8687090F86A20B0F86C100120FEF7DC +:10F8900029FD2068467007F097FB07F076FB07F01C +:10F8A00079FA07F0F7FABDE8F041032008F0EBBD64 +:10F8B0008178BDE8F0410120B9E411F0020F04BFE6 +:10F8C000FFDFBDE8F081B0F85610808F81420AD08A +:10F8D00001210846FFF7ABFC032000E003E02168AC +:10F8E0004870BDE8F081BDE8F041FFF73EB9FFF791 +:10F8F0003CB910B5354C206890F8341049B1363019 +:10F9000007F0CBFB18B921687F2081F8360007F09B +:10F91000ABFB206890F8330018B107F06BFB06F0E2 +:10F92000C6FD08F07CFDA8B1206890F82210C1F354 +:10F93000001179B14078022818BFFFDF00210120B3 +:10F94000FFF775FC2068417800291EBF4078012828 +:10F95000FFDF10BDBDE81040FFF707B92DE9F04704 +:10F960001A4C0F4680462168B8F1030F488C08BF37 +:10F97000C0F3400508D000F0010591F832000028DE +:10F9800018BF4FF0010901D14FF0000907F059F8F5 +:10F990000646B8F1030F0CBF4FF002084FF0010804 +:10F9A00035EA090008BFBDE8F087206890F8330009 +:10F9B00090B10CF0A7FB38700146FF280CD06068AE +:10F9C000C01C0CF078FB03E053E4B36E6000002031 +:10F9D00038780CF0A4FB064360680178C1F380120C +:10F9E00021680B7D9A4208D10622C01C153115F002 +:10F9F000E5FD002808BF012000D000203978FF294C +:10FA000006D0C8B9206890F82D00884216D113E0BE +:10FA1000A0B1616811F8030BC0F380100CF00FFB6C +:10FA200005460CF06FFC38B128460CF09FF918B170 +:10FA300010210DF05AF908B1012000E000202168E2 +:10FA400091F8221011F0040F01D0F0B11AE0CEB9F4 +:10FA5000FE4890F83500002818BF404515D1616870 +:10FA600011F8030BC0F380100CF0E9FA04460CF017 +:10FA700049FC38B120460CF079F918B110210DF08D +:10FA800034F910B10120BDE8F0870020BDE8F0870F +:10FA90002DE9F04FEE4D074683B0286800264078E8 +:10FAA000022818BFFFDF28684FF07F0990F8341054 +:10FAB00049B1363007F0F1FA002804BF286880F811 +:10FAC000369007F0D1FA68680DF022FD0446002F49 +:10FAD00000F0048268680DF0A6FE002800F0FE81A8 +:10FAE00006F07DFF002800F0F981FF20DFF864B305 +:10FAF000DFF8588300274FF0010A062C80F00082BF +:10FB0000DFE804F0EFEFEF03EFF78DF80000694650 +:10FB10000320FFF723FF002800F0E480296891F814 +:10FB2000340010B191F89800D0B12868817801298B +:10FB30004CD06868042107800DF0C8FC08F10E0164 +:10FB400068680DF0E9FC98F80D1068680DF000FD8C +:10FB50002868828F816B68680DF037FD00F04DB921 +:10FB60009DF8000081F898A00A7881F89920FF2874 +:10FB70000FD001F19B029A310CF086FA002808BFE1 +:10FB8000FFDF286890F89A1041F0020180F89A107F +:10FB90000DE068680278C2F3801281F89A20D0F8EC +:10FBA0000320C1F89B20B0F80700A1F89F00286847 +:10FBB00000F1A10490F836007F2808BFFFDF286815 +:10FBC00090F83610217080F83690AEE790F8220059 +:10FBD0009BF80490C0F38014686864F386190721C9 +:10FBE00007800DF073FC002168680DF066FE494641 +:10FBF00068680DF06EFE0623002208F10E016868A9 +:10FC00000DF041FE2868417B68680DF0A1FC686832 +:10FC10000DF018FD29688A8FC0F1FE018A42B8BF35 +:10FC20001146CFB2BA423DD9F81EC7B249F0100A08 +:10FC3000514668680DF04DFE68680DF03AFE384494 +:10FC4000431C2868B0F86610026E090951FA82F167 +:10FC500090F85C20DFF800920A44C8464FF0000C90 +:10FC6000E2FB098C4FEA1C116FF0240C01FB0C2104 +:10FC700080F85C1090F85B001A46012100F080F9D2 +:10FC80000190BDF804009DF80610032340EA0140EE +:10FC90000290042202A968680DF0F5FD51466868DB +:10FCA0000DF017FE34B1D5E90010012306225D31B5 +:10FCB0000DF0E9FD28683A46816B68680DF037FE63 +:10FCC0002868A0F85670818F8F420CBF0121002157 +:10FCD00080F8311007F088FD002818BFFFDF8CE0A6 +:10FCE00007E00DE128688078002840F0F98000F0F6 +:10FCF000F5B88DF8000068680178C1F38019D0F874 +:10FD000003100191B0F80700ADF80800694605201E +:10FD1000FFF724FE0028286873D08178002972D06C +:10FD200090F85BA0D5E90104D0F80F10C4F80E10CC +:10FD3000B0F813106182417D2175817D6175B0F845 +:10FD40001710E182B0F819106180B0F81B10A18083 +:10FD5000B0F81D10E18000F11F0104F1080015F05A +:10FD60000EFE686890F8241001F01F01217690F8CB +:10FD70002400400984F86C0184F854A084F855A04C +:10FD8000286890F8651084F8561090F85D0084F8A3 +:10FD900057009DF80010A86800F05BF9022008F0F9 +:10FDA00072FB6868DBF800400DF1040A0780082147 +:10FDB0000DF08CFB002168680DF07FFD214668681E +:10FDC0000DF087FD0623002208F10E0168680DF092 +:10FDD0005AFD2868417B68680DF0BAFB494668689F +:10FDE0000DF0C3FB06230122514668680DF04BFD60 +:10FDF00007F0FAFC002818BFFFDF032029684870CD +:10FE000070E066E0FFE76868AC684FF001080278D0 +:10FE1000617BC2F3401211406173D0F80F10C4F837 +:10FE20000E10B0F813106182417D2175817D6175DE +:10FE3000B0F81710E182B0F819106180B0F81B100B +:10FE4000A180B0F81D10E18008E00000000600204D +:10FE500060000020A85B020053E4B36E00F11F01B4 +:10FE600004F1080015F08BFD686890F8241001F08B +:10FE70001F01217690F82400400984F86C0184F871 +:10FE8000548084F85580286890F8651084F85610DE +:10FE900090F85D0084F857009DF80010A86800F005 +:10FEA000D8F8286880F868A090F86A20B0F86C103C +:10FEB0000120FEF717FA2868477007F085F807F069 +:10FEC00064F806F067FF06F0E5FF012008F0DBFAB2 +:10FED00008E090F82200C0F3001008B1012601E00C +:10FEE000FEF743FE286890F8330018B107F082F857 +:10FEF00006F0DDFA66B100210120FFF798F910E065 +:10FF0000286890F82200C0F300100028E8D0E5E748 +:10FF100028688178012904D190F85B10FF2006F051 +:10FF2000B2FC28684178002919BF4178012903B043 +:10FF3000BDE8F08F4078032818BFFFDF03B0BDE8AD +:10FF4000F08F70B57E4C06460D462068807858B11B +:10FF500006F04FFC21680346304691F85B202946A5 +:10FF6000BDE8704009F042B806F043FC2168034642 +:10FF7000304691F85A202946BDE8704009F036B85D +:10FF800078B50C4600210091082804BF4FF4C870D2 +:10FF900040210DD0042804BF4FF4BF70102107D0BA +:10FFA000022807BF01F11800042101F128000821EF +:10FFB000521D02FB010562489DF80010006890F890 +:10FFC0005C2062F3050141F040068DF8006090F876 +:10FFD0005B00012828D002282DD0082818BFFFDF99 +:10FFE0002FD000BF26F080008DF80000C4EB041075 +:10FFF00000EB80001E2101EB800005FB040451484A +:020000040001F9 +:10000000844228BFFFDF5048A0FB0410BDF8011058 +:10001000000960F30C01ADF80110BDF800009DF877 +:10002000021040EA014078BD9DF8020020F0E00097 +:100030008DF80200D6E79DF8020020F0E0002030A5 +:1000400004E09DF8020020F0E00040308DF802004E +:10005000C8E72DE9F0413A4D04460E46286890F86D +:100060006800002818BFFFDF0027286880F86A7042 +:100070002188A0F86C106188A0F88210A188A0F8EF +:100080008410E188A0F8861094F86C1180F888102C +:1000900090F82F1049B1427B00F10E01012A04D1E2 +:1000A000497901F0C001402934D090F8301041B1B5 +:1000B000427B00F10E01012A04BF497911F0C00F03 +:1000C00028D000F1760015F051FC6868FF2E017809 +:1000D000C1F380116176D0F80310C4F81A10B0F89B +:1000E0000700E08328681DD0C167E18BA0F880106D +:1000F00000F17002511E30460BF0C6FF002808BF09 +:10010000FFDF286890F86F1041F0020180F86F104F +:10011000BDE8F081D0F80E10C0F87610418AA0F842 +:100120007A10D2E7C767A0F88070617E80F86F1000 +:10013000D4F81A100167E18BA0F87410BDE8F081C3 +:1001400060000020C4BF0300898888880178406867 +:1001500029B190F80C1190F8730038B901E001F062 +:10016000A9BD19B1042901D00120704700207047B2 +:1001700070B50C460546062102F006FC606008B129 +:10018000002006E00721284602F0FEFB606018B15F +:1001900001202070002070BD022070BD2DE9FC47B9 +:1001A0000C4606466946FFF7E3FF00287DD19DF81F +:1001B000000050B1FEF727F9B0427CD0214630460E +:1001C0000AF000F9002873D12DE00DF02FFEB042A7 +:1001D00071D02146304612F093FF002868D1019D6E +:1001E00095F8D00022E0012000E00020804695F83C +:1001F00037004FF0010A4FF00009F0B195F83800D0 +:1002000080071AD584F8019084F800A084F804903F +:10021000E68095F839102172698F6181A98FA181DB +:1002200085F8379044E0019D95F80C015835002879 +:10023000DBD1E87E0028D8D0D5E7304602F0E8FCD4 +:10024000070000D1FFDF384601F0F8FE40B184F826 +:1002500001900F212170E680208184F804A027E01E +:10026000304602F0C3FC070000D1FFDFB8F1000FF9 +:1002700021D0384601F039FFB8B19DF8000038B9F7 +:100280000198D0F8F8004188B14201D180F800907F +:10029000304607F07CFB84F801900C21217084F833 +:1002A0000490E680297F217200E004E085F81B902D +:1002B0000120BDE8FC870020FBE71CB56946FFF77D +:1002C00057FF00B1FFDF684601F000FDFB49002049 +:1002D0008968A1F8D2001CBD2DE9FC4104460E46F8 +:1002E000062002F0F9FA0546072002F0F5FA284444 +:1002F000C7B20025A8463E4417E02088401C80B2C3 +:100300002080B04202D34046A4F8008080B2B842B8 +:1003100004D3B04202D20020BDE8FC816946FFF759 +:1003200027FF0028F8D06D1CEDB2AE42E5D84FF69D +:10033000FF7020801220EFE738B54FF6FF70ADF860 +:1003400000000DE00621BDF8000002F02FFB04467E +:100350000721BDF8000002F029FB0CB100B1FFDF5E +:1003600000216846FFF7B8FF0028EBD038BD70B514 +:1003700007F07AFB0BF04FFCD14C4FF6FF760025CF +:100380006683A683CFA0257001680079A4F140029E +:10039000657042F8421FA11C1071601C13F07DF8BB +:1003A00025721B2060814FF4A471A181E08121821C +:1003B0000321A1740422E274A082E082A4F13E0031 +:1003C000218305704680BD480C300570A4F11000F3 +:1003D0000570468070BD70B5B84C16460D4660601D +:1003E000217007F0BBFAFFF7A7FFFFF7C0FF2078E7 +:1003F00010F09BFEB5480EF0C4F92178606812F049 +:100400005EFF20780AF056FE284608F097FBAF48BA +:10041000FEF704F8217860680AF0BAF831462078CF +:1004200013F038FEBDE870400BF0F5BB10B50124A9 +:100430000AB1002010BD21B1012903D000242046BB +:1004400010BD02210DF0B0FAF9E72DE9F0470400E4 +:1004500000D1FFDF9A4802211C308146FFF73CFFA4 +:1004600000B1FFDF964D0620B5F81C8002F034FA8B +:100470000646072002F030FA3044C6B2701CC7B2FC +:10048000A88BB04228D120460DF046FCB0B12078B0 +:1004900018283FD1207901283CD1E088062102F0BC +:1004A00073FA040000D1FFDF208807F070FA20887B +:1004B000062102F07BFA40B3FFDF2BE0287860B31F +:1004C00000266670142020702021201D15F043F9AD +:1004D000022020712E701DE0B84217D12046FDF792 +:1004E00037FFD0B12078172814D1207968B1E0887F +:1004F000072102F049FA40B1008807F048FAE08885 +:10050000072102F053FA00B1FFDF03E02146FFF7B5 +:1005100045FE10B10120BDE8F08702214846FFF7F3 +:10052000DBFE10B9A98B4145AAD12046BDE8F047B2 +:1005300013F0F6BD10B501F064FB08B10C2010BD3E +:100540000BF0BCFB002010BD10B50446007818B1BC +:10055000012801D0122010BD01F064FB20B10BF086 +:100560005DFD08B10C2010BD207801F011FBE21DEB +:1005700004F11703611CBDE810400BF044BC10B53A +:10058000044601F03EFB08B10C2010BD207828B1D4 +:10059000012803D0FF280BD0122010BD01F0F8FA7B +:1005A000611C0BF04BFB08B1002010BD072010BDF3 +:1005B00001200BF07DFBF7E710B50BF032FD08B121 +:1005C000002010BD302010BD10B5044601F02AFBFC +:1005D00008B10C2010BD20460BF01DFD002010BD01 +:1005E00010B501F01FFB20B10BF018FD08B10C2075 +:1005F00010BD0BF06DFC002010BDFF2181704FF687 +:10060000FF7181802D4949680A7882718A88028148 +:100610004988418101214170002070477CB5002547 +:10062000022A19D015DC12F10C0F15D009DC12F1D9 +:10063000280F11D012F1140F0ED012F1100F11D19A +:100640000AE012F1080F07D012F1040F04D04AB9E2 +:1006500002E0D31E052B05D8012806D0022808D0B9 +:1006600003280AD0122528467CBD1046FEF75EFA04 +:10067000F9E710460EF030F8F5E7084614466946EB +:10068000FFF776FD08B10225EDE79DF8000001981F +:10069000002580F85740E6E710B5134601220CF01C +:1006A00061FB002010BD10B5044611F03AFB05288F +:1006B0000ED0204610F028FD002010BD6C00002058 +:1006C000E4070020FFFFFFFF1F000000A40600203A +:1006D0000C20F2E710B5044601F0A4FA08B10C2092 +:1006E000EBE72146002007F0C0F90020E5E710B550 +:1006F000044610F097FD50B108F0A6FC38B1207800 +:1007000008F041FA20780EF0F5FA0020D5E70C2029 +:10071000D3E710B5044601F085FA08B10C20CCE708 +:100720002146012007F0A1F90020C6E738B50446AC +:100730004FF6FF70ADF80000A079E179884216D03D +:100740002079FDF766FD90B16079FDF762FD70B12B +:100750000022A079114614F011F940B90022E07985 +:10076000114614F00BF910B9207A072801D912208C +:1007700038BD08F076FC60B911F0D3FA48B9002111 +:100780006846FFF7A9FD20B1204606F057F8002083 +:1007900038BD0C2038BD2DE9FC41817805461A2969 +:1007A00025D00EDC16292DD2DFE801F02C2C2C2CC4 +:1007B0002C212C2C2C2C2C2C2C2C2C2C2C2C2C218F +:1007C00021212A291ED00BDCA1F11E010C2919D2EE +:1007D000DFE801F018181818181818181818180D4C +:1007E0003A3904290ED2DFE801F00D020D02288803 +:1007F000B0F5706F06D201276946FFF7B9FC18B152 +:10080000022089E5122087E59DF8000001F0C7F974 +:10081000019C08B1F43401E004F5B8749DF80000BF +:1008200001F0BDF9019E08B1F53601E006F271163E +:100830006846FFF78BFC08B1207808B10C206BE507 +:100840002770A8783070684601F040FA002063E510 +:100850007CB50D466946FFF78BFC002618B12E606B +:100860002E7102207CBD9DF8000001F098F9019CDA +:100870009DF80000583401F092F9019884F8406026 +:1008800081682960017B297194F840100029F5D115 +:1008900000207CBD70B5044691F8550091F85630A3 +:1008A0000D4610F00C0F00D100232189A0880CF018 +:1008B000E8FB696A81421DD2401A401CA1884008A9 +:1008C000091A8AB2A2802189081A2081668895F8BF +:1008D000541010460CF07CFB864200D230466080FB +:1008E000E68895F8551020890CF072FB864200D2FC +:1008F0003046E08070BDF0B585B00D46064603A9D0 +:10090000FFF736FC00282DD19DF80C0060B30022C3 +:100910000499FB20B1F84A30FB2B00D30346B1F811 +:100920004C40FB20FB2C00D30446DFF80CCC9CE8A9 +:10093000811000900197CDF808C0ADF80230ADF8F5 +:1009400006406846FFF7A6FF6E80BDF80400E88009 +:10095000BDF808006881BDF80200A880BDF8060057 +:100960002881002005B0F0BD0122D1E72DE9F0413A +:1009700086B0044600886946FFF7FAFB002868D174 +:100980002189E08801F0B1F9002862D1A18860884E +:1009900001F0ABF900285CD12189E08801F0B3F9BE +:1009A000002856D1A188608801F0ADF9070050D128 +:1009B000208802A9FFF79FFF00B1FFDFBDF81010EC +:1009C00062880920914244D3BDF80C10E28891421C +:1009D0003FD3BDF81210BDF80E2023891144A28820 +:1009E0001A44914235D39DF80000019D4FF0000854 +:1009F000012640B185F89B61019890F8DE0105F56C +:100A0000CD7540B914E085F80561019890F828018A +:100A100005F5827508B13A2718E0E088688060889B +:100A2000E8802089A880A08828810122019909E016 +:100A3000E08868806088E8802089A880A088288174 +:100A4000019900222846FFF725FF2E7085F80180C6 +:100A5000384606B0BDE8F08188E710B5044601F0DD +:100A6000E1F820B10BF0DAFA08B10C2025E6207885 +:100A700001F08EF8E279611C0BF051FC08B1002006 +:100A80001BE6022019E610B503780446002B4068E7 +:100A900013460A46014609D05FF001000CF0FAFA4D +:100AA0006168496A884203D9012006E60020F5E71B +:100AB000002002E62DE9F04117468A781E4680465E +:100AC00042B11546C87838B10446690706D52AB13F +:100AD000012104E00725F5E70724F6E70021620776 +:100AE00002D508B1012000E00020014206D0012219 +:100AF00011464046FFF7C7FF98B93BE051B10022CD +:100B000001214046FFF7BFFF58B9600732D50122E7 +:100B100011461FE058B1012200214046FFF7B3FF04 +:100B200008B1092096E7680724D5012206E0680786 +:100B30004FEA44700AD5002813DB00220121404609 +:100B4000FFF7A1FFB0B125F0040513E0002811DA8A +:100B5000012200214046FFF796FF58B124F004041B +:100B600008E0012211464046FFF78DFF10B125F045 +:100B70000405F3E73D70347000206BE710B586B0D4 +:100B80000446008803A9FFF7F3FA002806D1A088DD +:100B900030B1012804D0022802D0122006B08CE522 +:100BA0006B4602AA214603A8FFF784FF0028F5D16F +:100BB0009DF80C3000220121002B049B06D083F805 +:100BC000A511049B93F8F2316BBB24E083F80F115D +:100BD000049B93F834313BB9049B93F80E311BB955 +:100BE000049B93F87D300BB13A2010E0049B83F80E +:100BF0000E11049B9DF8081083F81011049B9DF8BA +:100C0000001083F81111049BA188A3F81211049914 +:100C100081F80F21C2E7049B93F8A4311BB9049B10 +:100C200093F87D300BB13A2010E0049B83F8A411B7 +:100C3000049B9DF8081083F8A611049B9DF80010F2 +:100C400083F8A711049BA188A3F8A811049981F83F +:100C5000A521A3E710B504460020A17801B9012021 +:100C6000E2780AB940F0020001F056F8002803D1FA +:100C70002046BDE8104081E71FE570B51C460D46D3 +:100C800018B1012801D0122070BD1946104601F09C +:100C900053F830B12146284601F058F808B1002039 +:100CA00070BD302070BD70B5044600780E46012836 +:100CB00004D018B1022801D0032841D1607828B1AE +:100CC000012803D0022801D0032839D1E07B10B9D4 +:100CD000A078012834D1A07830F0050130D110F08F +:100CE000050F2DD06289E188E0783346FFF7C5FF14 +:100CF000002826D1A07805281ED16589A2892189DE +:100D000020793346FFF7B9FF00281AD15FF00100C0 +:100D100004EB40014A8915442218D3789278934213 +:100D20000ED1CA8889888A420AD1401CC0B20228E2 +:100D3000EED3E088A84203D3A07B08B1072801D9ED +:100D4000122070BD002070BD10B586B0044600F0C2 +:100D50004BFF08B10C2021E7022104F10A0001F049 +:100D600008F8A0788DF80800A0788DF80000607869 +:100D70008DF8040020788DF80300A07B8DF8050025 +:100D8000E07B00B101208DF80600A078C10717D0E4 +:100D9000E07800F0E5FF8DF80100E088ADF80A008A +:100DA0006089ADF80C00A078400716D5207900F0D6 +:100DB000D7FF8DF802002089ADF80E00A0890AE067 +:100DC00040070AD5E07800F0CBFF8DF80200E088FC +:100DD000ADF80E006089ADF8100002A810F02EFAF0 +:100DE0000028B8D168460DF08AFFD7E610B5044652 +:100DF0000121FFF758FF002803D12046BDE810402D +:100E0000A2E75AE40278012A01D0BAB118E0427888 +:100E10003AB1012A05D0022A12D189B1818879B16B +:100E200000E059B1418849B1808838B101EB8101B6 +:100E3000490000EB8000B1EB002F01D20020704789 +:100E40001220704770B5044600780D46012809D07D +:100E500010F067FF052803D010F001F9002800D03A +:100E60000C2070BD0DF00DFE88B10DF01FFE0DF0D1 +:100E700023FF0028F5D125B160780DF0B4FE0028DD +:100E8000EFD1A1886088BDE8704010F0FDB9122054 +:100E900070BD10B504460121FFF7B4FF002804D14E +:100EA0002046BDE810400121CCE706E42DE9F047DB +:100EB0000746B0F84C50FB2092460E46FB2D00D35F +:100EC0000546DFF87886B8F80A00A84200D2054641 +:100ED00097F85510284600F076FEB8F80C108142BD +:100EE00000D208468146B7F84A40FB20FB2C00D3CD +:100EF0000446B8F80E00A04200D2044697F85410F9 +:100F0000204600F060FEB8F81010814200D208467A +:100F10004FF4A4721B2C01D0904203D11B2D25D07D +:100F2000914523D0F580A6F808907480B080524691 +:100F300039463046FFF7AEFC01203070F0881B3890 +:100F4000E02800D9FFDF70881B38E02800D9FFDFD8 +:100F5000308940F64814A0F5A470A04200D9FFDF04 +:100F6000B088A0F5A470A04200D9FFDFBDE8F087EB +:100F7000F0B5871FDDE9056540F67B44A74213D233 +:100F80008F1FA74210D288420ED8B2F5FA7F0BD23B +:100F9000A3F10A00241FA04206D2521C4A43B2EB1E +:100FA000830F01DAAE4201D90020F0BD0120F0BD6F +:100FB0002DE9FC47477A0446884678077ED0F80832 +:100FC0007CD194F83A0008B9012F77D100252E463C +:100FD000F90788F0010919D0208A494600F0ACFED3 +:100FE000F0B36089494600F0B1FEC8B3208A618938 +:100FF000884263D8A18EE08DCDE90001238D628CFB +:10100000A18BE08AFFF7B4FF50B30125B8070ED5D6 +:1010100004EB4500828EC18DCDE90012038D428C18 +:10102000818BC08AFFF7A4FFD0B16D1C2E467807D4 +:101030001DD504EB45074946388A00F07DFE78B19E +:101040007889494600F082FE50B1388A7989884211 +:1010500057D8B98EF88DCDE900013B8D7A8C00E030 +:1010600009E0B98BF88AFFF783FF20B16D1CB8F156 +:10107000000F03D02AE03020BDE8FC87228A01213E +:101080001FE0B14203D004EB4100008A024404EBAC +:101090004100C38A878ABB4233D1838B478BBB42D3 +:1010A0002FD1438C078CBB422BD1038DC78CBB4205 +:1010B00027D143890089834223D100E021E0491CE4 +:1010C000C9B2A942DDD3608990421AD3207810B109 +:1010D000012816D10DE0A078B8F1000F07D040B17B +:1010E000012806D0022804D003280AD101E00028F4 +:1010F000EED1607838B1012805D0022803D003284A +:1011000001D01220B8E70020B6E7002150E70178AF +:10111000C90702D0406812F0D6BF12F0A3BF2DE974 +:10112000F04788B00D46AFF66422D2E9009201463E +:1011300090462846FFF73CFF06000CD100F054FD16 +:1011400040B9FE4F387828B90CF070FEA0F57F4109 +:10115000FF3902D00C2008B008E7032105F1100088 +:1011600000F007FEF54801AA3E380190F4480290CD +:10117000F24806211038039007A801F0D3FB0400C1 +:1011800035D003210BF04EFBB98AA4F84A10FA8A35 +:10119000A4F84C20FB7C0093BA46BB7C208801F06D +:1011A000AEFC00B1FFDF208806F0F0FB218804F1DF +:1011B0000E0000F041FDE3A004F11207006800906A +:1011C0000321684604F0F2FD002069460A5C3A54A7 +:1011D000401CC0B20328F9D3A88B6080688CA08023 +:1011E000288DE080687A410703D508270AE00920A6 +:1011F000B1E7C10701D0012704E0800701D502272C +:1012000000E000273A46BAF81800114610F0D0F86E +:101210000146A062204610F0D9F817F00C0F09D053 +:1012200001231A46214600200BF034FF616A8842F0 +:1012300000D90926002784F85E7084F85F70A878CA +:1012400000F0A6FC6076D5F80300C4F81A00B5F8E3 +:101250000700E083C4F8089084F80C80012084F82B +:101260000001024604F582712046FFF71FFE8DF84B +:1012700000700121684604F099FD9DF8000000F01F +:101280000701C0F3C1021144C0F3401008448DF8B7 +:101290000000401D2076092801D208302076002168 +:1012A00020460BF0BFFA68780DF0F6FBF6BBA97884 +:1012B0002878EA1C0DF0C3FB48B10DF0F7FBA978C4 +:1012C0002878EA1C0DF069FC060002D052E01226D4 +:1012D00050E0687A00F005010020CA0700D0012024 +:1012E0008A0701D540F00200490701D540F0080007 +:1012F0000DF08EFB06003DD1214603200DF077FC5A +:10130000060037D10DF07DFC060033D1697A01F07B +:1013100005018DF81010697AC90706D06889ADF803 +:101320001200288AADF81400012000E022E0697A5A +:101330008A0700D5401C490707D505EB40004189C5 +:10134000ADF81610008AADF8180004A80FF076FF6B +:10135000064695F83A0000B101200DF06BFB4EB93E +:101360000DF0AAFC060005D1A98F20460FF008FF5A +:10137000060008D0208806F00AFB2088062101F02C +:1013800015FB00B1FFDF3046E5E601460020C6E66A +:1013900038B56A48007878B910F0C3FC052805D044 +:1013A0000CF044FDA0F57F41FF3905D068460FF0F1 +:1013B000AEFF040002D00CE00C2038BD009800887D +:1013C00006F0E5FA00980621008801F0EFFA00B176 +:1013D000FFDF204638BD1CB582894189CDE9001266 +:1013E0000389C28881884088FFF7C2FD08B10020C8 +:1013F0001CBD30201CBD70B50546FFF7ECFF002872 +:101400000ED12888062101F0BFFA040007D000F0B1 +:1014100051FC20B1D4F8F800017831B901E0022084 +:1014200070BDD4F84411097809B13A2070BD052186 +:101430008171D4F8F81000200881D4F8F810A88839 +:101440004881D4F8F810E8888881D4F8F810288901 +:10145000C881D4F8F800028941898A4204D8827987 +:10146000082A01D88A4201D3122070BD2988418000 +:10147000D4F8F81002200870002070BD3EB5044674 +:101480000BF002FCB0B12D480125A0F140024570DF +:10149000236842F8423F2379002113714170694665 +:1014A000062001F0FAF900B1FFDF684601F0D3F938 +:1014B00010B10EE012203EBDBDF80440029880F845 +:1014C0000051684601F0C7F918B9BDF80400A04200 +:1014D000F4D100203EBD70B505460088062101F01C +:1014E00053FA040007D000F0E5FB20B1D4F8F8105F +:1014F000087830B901E0022070BDD4F844010078CA +:1015000008B13A2070BD9620005D10F0010F21D087 +:10151000D5F802004860D5F80600886054F8F80F46 +:10152000698910228181206805F10C010E3014F0C8 +:1015300071F80320216807E0CC5B0200E40700207B +:101540007800002011223300087021682888488024 +:10155000002070BD0C2070BD38B504460078EF281F +:101560004DD86088ADF80000009800F013FC88B3F7 +:101570006188080708D4D4E9012082423FD8202A94 +:101580003DD3B0F5804F3AD8207B18B3072836D822 +:10159000607B28B1012803D0022801D003282ED176 +:1015A0004A0703D4022801D0032805D1A07B08B143 +:1015B000012824D1480707D4607D28B1012803D031 +:1015C000022801D003281AD1C806E07D03D50128DE +:1015D00015D110E013E0012801D003280FD1C8066F +:1015E00009D4607E012803D0022801D0032806D147 +:1015F000A07E0F2803D8E07E18B1012801D0122068 +:1016000038BD002038BDF8B514460D46064607F033 +:1016100028FD08B10C20F8BD3046FFF79DFF0028DB +:10162000F9D1FDF788FA2870B07554B9FF208DF80C +:10163000000069460020FDF76DFA69460020FDF7BD +:101640005DFA3046BDE8F840FDF7B1B90022DAE7AF +:1016500070B50C46054612B11F2907D80CE0FF2CC7 +:1016600004D8FCF71EFF18B11F2C01D9122070BD41 +:101670002846FCF700FF08B1002070BD422070BD75 +:1016800010B50446408810B1FDF71BFA78B12078F8 +:10169000618800F001026078FFF7DAFF002805D1C9 +:1016A000FDF7F7F96288824203D9072010BD1220A6 +:1016B00010BD10466168FDF72DFA002010BD10B571 +:1016C0000446408810B1FCF7DEFE70B120786188D6 +:1016D00000F001026078FFF7BBFF002804D16088AA +:1016E0006168FDF70BFA002010BD122010BD7CB51B +:1016F000044640784225012808D8A078FCF7BBFEB4 +:1017000020B120781225012802D090B128467CBD56 +:10171000FDF71DFA20B1A0880028F7D08028F5D861 +:10172000FDF71CFA60B160780028EFD0207801281E +:1017300008D006F04BFA044607F05DF900287DD08A +:101740000C207CBDFDF74CF810B9FDF7F9F990B30A +:1017500007F087FC0028F3D1FCF755FEA0F57F4188 +:10176000FF39EDD1FDF75EF8A68842F210704643CE +:10177000A079FDF7B7F9FCF78DFEF8B1002207213B +:1017800001A801F0CFF8040043D0F748032184609A +:1017900020460AF052FF2046FDF746FDF34DA88A89 +:1017A000A4F84A00E88AA4F84C00FCF77AFE60B17D +:1017B000288B01210DE0FFE712207CBD314600207F +:1017C00007F0E4F9D8B3FFDF4CE0FDF7C9F90146B3 +:1017D000288B07F086FA0146A0620022204606F018 +:1017E000F8F9FCF75EFEB0B9FDF7BAF910F00C0F8E +:1017F00011D001231A46214618460BF04BFC616AB2 +:10180000884208D90721BDF8040001F0CFF800B1E3 +:10181000FFDF09207CBDE87C0090AB7CEA8AA98AC6 +:10182000208801F06CF900B1FFDF208806F0AEF8E7 +:101830003146204607F0AAF918B101E008E011E0AE +:10184000FFDF002204F5CD712046FFF72FFB09E0F2 +:1018500044B1208806F09BF82088072101F0A6F803 +:1018600000B1FFDF00207CBD002140E770B50D46D0 +:10187000072101F089F8040003D094F8730110B136 +:101880000AE0022070BD94F86500142801D01528E4 +:1018900002D194F8C00108B10C2070BD1022294675 +:1018A00004F5BA7013F0B6FE012084F8730100202D +:1018B00070BD10B5072101F067F818B190F87311E9 +:1018C00011B107E0022010BD90F86510142903D073 +:1018D000152901D00C2010BD022180F873110020C1 +:1018E00010BD2DE9FC410C464BF68032122194428A +:1018F0001DD8E4B16946FEF73BFC002815D19DF8E0 +:10190000000000F04CF9019E9DF80000583600F0F0 +:1019100046F9019DAD1C2F882246394630460AF013 +:1019200082FE2888B842F6D10020BDE8FC81084636 +:10193000FBE77CB5044600886946FEF719FC0028E1 +:1019400010D19DF8000000F02AF9019D9DF80000DB +:10195000583500F024F90198A27890F82C109142A3 +:1019600001D10C207CBD7F212972A9720021E9726E +:10197000E17880F82D10217980F82E10A17880F878 +:101980002C1000207CBD1CB50C466946FEF7F0FB10 +:1019900000280AD19DF8000000F001F9019890F8A4 +:1019A000730000B10120207000201CBD7CB50D46E5 +:1019B00014466946FEF7DCFB002809D19DF80000BB +:1019C00000F0EDF8019890F82C00012801D00C20CF +:1019D0007CBD9DF8000000F0E2F8019890F86010DE +:1019E000297090F86100207000207CBD70B50D4614 +:1019F0001646072100F0C8FF18B381880124C38868 +:101A0000428804EB4104AC4217D842F2107463439D +:101A1000A4106243B3FBF2F2521E94B24FF4FA7276 +:101A2000944200D91446A54200D22C46491C641C9D +:101A3000B4FBF1F24A43521E91B290F8AC211AB9AC +:101A400001E0022070BD01843180002070BD10B51E +:101A50000C46072100F098FF48B180F8DF4024B120 +:101A600090F8DD1009B107F052F9002010BD0220F6 +:101A700010BD017899B1417889B141881B290ED3F5 +:101A800081881B290BD3C188022908D337490268F2 +:101A9000403941F8522F40684860002070471220BA +:101AA000704710B504460FF07FFC204607F0E8F8B9 +:101AB000002010BD10B507F0E6F8002010BD2DE99C +:101AC000F04115460F4606460122114638460FF0F2 +:101AD0006FFC04460121384607F003F9844200D226 +:101AE000044601213046653C00F05EF806460121BF +:101AF000002000F059F8304401219630844206D984 +:101B000000F19601201AB0FBF1F0401C81B229804F +:101B10000020BDE8F08110B5044600F083F808B15C +:101B20000C2010BD601C0AF0D5FB207800F00100ED +:101B3000FCF773FE207800F001000CF0B2FF0020EB +:101B400010BD10B50446072000F0B8FE08B10C2007 +:101B500010BD2078C00715D000226078114612F021 +:101B60000DFF28B1122010BD6C000020E4070020FA +:101B7000A06809F06AF86078D4F8041009F06EF8EB +:101B80000020F0E7002009F060F800210846F5E7A2 +:101B900018B1022801D0012070470020704708B119 +:101BA000002070470120704710B5012904D0022998 +:101BB00005D0FFDF2046D6E7C000503001E08000AE +:101BC0002C3084B2F6E711F00C0F04D04FF474718E +:101BD00001EB801006E0022902D0C000703001E065 +:101BE00080003C3080B2704710B510F09AF804289D +:101BF00005D010F096F8052801D00020B3E70120A9 +:101C0000B1E710B5FFF7F0FF10B10DF019F828B9E2 +:101C100007F027FA20B1FCF7DBFD08B10120A2E7AD +:101C20000020A0E710B5FFF7DFFF18B907F019FA99 +:101C3000002898D0012096E72DE9FE4300250F46A5 +:101C400080460A260421404604F0D9F840460AF0AE +:101C5000BCFF062000F040FE044616E06946062060 +:101C600000F01BFE0BE000BFBDF80400B84206D038 +:101C70000298042241460E3013F0A0FC50B1684691 +:101C800000F0E9FD0500EFD0641E002C06DD002DFC +:101C9000E4D005E040460AF0A1FFF5E705B9FFDF13 +:101CA000D8F800000AF0B5FF761E01D00028C9D090 +:101CB000BDE8FE8390F8D01090F8730020B919B1F8 +:101CC000042901D0012070470020704701780029C5 +:101CD0000AD0416891F8DD20002A05D0002281F861 +:101CE000DD20406807F013B870471B38E12806D2A2 +:101CF000B1F5A47F03D344F29020814201D9122090 +:101D0000704700207047FB2802D8B1F5296F01D930 +:101D1000112070470020704770B514460546012217 +:101D200000F05CF8002806D121462846BDE8704046 +:101D3000002200F053B870BD042803D321B9B0F5D8 +:101D4000804F01D90020704701207047042803D339 +:101D500021B9B0F5804F01D90020704701207047AC +:101D6000012802D018B100207047022070470120DE +:101D7000704710B500224FF4C84408E030F8123024 +:101D8000A34200D9234620F81230521CD2B28A4214 +:101D9000F4D3E8E680B2C1060BD401071CD4810657 +:101DA0004FEAC07101D5B9B900E099B1800713D4E9 +:101DB00010E0410610D481060ED4C1074FEA8071AD +:101DC00004D0002902DB400704D405E0010703D456 +:101DD000400701D401207047002070470AB101225A +:101DE00000E00222024202D1C80802D109B100205B +:101DF000704711207047000030B5058825F4004475 +:101E000021448CB24FF4004194420AD2121B92B288 +:101E10001B339A4201D2A94307E005F40041214354 +:101E200003E0A21A92B2A9431143018030BD0844D5 +:101E3000083050434A31084480B2704770B51D469F +:101E400016460B46044629463046049AFFF7EFFF34 +:101E50000646B34200D2FFDF2821204613F07BFC68 +:101E60004FF6FF70A082283EB0B265776080B0F573 +:101E7000004F00D9FFDF618805F13C00814200D2AC +:101E8000FFDF60880835401B343880B220801B2873 +:101E900000D21B2020800020A07770BD8161886166 +:101EA00070472DE9F05F0D46C188044600F128090E +:101EB000008921F4004620F4004800F062FB10B1D4 +:101EC0000020BDE8F09F4FF0000A4FF0010BB04535 +:101ED0000CD9617FA8EB0600401A0838854219DC4E +:101EE00009EB06000021058041801AE06088617FCF +:101EF000801B471A083F0DD41B2F00DAFFDFBD42BD +:101F000001DC294600E0B9B2681A0204120C04D0C0 +:101F1000424502DD84F817A0D2E709EB06000180F4 +:101F2000428084F817B0CCE770B5044600F128026F +:101F3000C088E37D20F400402BB110440288438820 +:101F400013448B4201D2002070BD00258A4202D387 +:101F50000180458008E0891A0904090C418003D0FA +:101F6000A01D00F01EFB08E0637F008808331844C2 +:101F700081B26288A01DFFF73FFFE575012070BDAB +:101F800070B5034600F12804C588808820F4004617 +:101F90002644A84202D10020188270BD9889358855 +:101FA000A84206D3401B75882D1A2044ADB2C01E2E +:101FB00005E02C1AA5B25C7F20443044401D0C88FB +:101FC000AC4200D90D809C8924B10024147009888A +:101FD000198270BD0124F9E770B5044600F12801AB +:101FE000808820F400404518208A002825D0A18947 +:101FF000084480B2A08129886A881144814200D2B5 +:10200000FFDF2888698800260844A189884212D108 +:10201000A069807F2871698819B1201D00F0C1FA7C +:1020200008E0637F28880833184481B26288201D45 +:10203000FFF7E2FEA6812682012070BD2DE9F04166 +:10204000418987880026044600F12805B94218D046 +:1020500004F10A0821F400402844418819B140469F +:1020600000F09FFA08E0637F00880833184481B2CB +:1020700062884046FFF7C0FE761C6189B6B2B9425D +:10208000E8D13046BDE8F0812DE9F04104460B4629 +:1020900027892830A68827F40041B4F80A80014433 +:1020A0000D46B74201D10020ECE70AB1481D10608F +:1020B00023B1627F691D184613F0ACFA2E88698837 +:1020C00004F1080021B18A1996B200F06AFA06E01C +:1020D000637F62880833991989B2FFF78DFE4745FF +:1020E00001D1208960813046CCE78188C088814257 +:1020F00001D101207047002070470189808881420A +:1021000001D1012070470020704770B58588C388D1 +:1021100000F1280425F4004223F4004114449D42B8 +:102120001AD08389058A5E1925886388EC18A6422F +:1021300014D313B18B4211D30EE0437F08325C19E4 +:102140002244408892B2801A80B22333984201D24E +:1021500011B103E08A4201D1002070BD012070BDA1 +:102160002DE9F0478846C1880446008921F40046DD +:1021700004F1280720F4004507EB060900F001FAF6 +:10218000002178BBB54204D9627FA81B801A0025C4 +:1021900003E06088627F801B801A083823D4E289BC +:1021A00062B1B9F80020B9F802303BB1E81A2177E2 +:1021B000404518DBE0893844801A09E0801A21770D +:1021C00040450ADB607FE1890830304439440844E7 +:1021D000C01EA4F81280BDE8F087454503DB01204E +:1021E0002077E7E7FFE761820020F4E72DE9F74F6A +:1021F000044600F12805C088884620F4004A608A19 +:1022000005EB0A0608B1404502D20020BDE8FE8F6A +:10221000E08978B13788B6F8029007EB0901884267 +:1022200000D0FFDF207F4FF0000B50EA090106D0FD +:1022300088B33BE00027A07FB9463071F2E7E1891F +:1022400059B1607F2944083050440844B4F81F1045 +:1022500020F8031D94F821108170E28907EB080033 +:1022600002EB0801E1813080A6F802B002985F46D7 +:1022700050B1637F30880833184481B26288A01D52 +:10228000FFF7BAFDE78121E0607FE1890830504423 +:10229000294408442DE0FFE7E089B4F81F102844E2 +:1022A000C01B20F8031D94F82110817009EB080071 +:1022B000E28981B202EB0800E081378071800298E8 +:1022C000A0B1A01D00F06DF9A4F80EB0A07F401CD5 +:1022D000A077A07D08B1E088A08284F816B000BF86 +:1022E000A4F812B084F817B001208FE7E0892844E1 +:1022F000C01B30F8031DA4F81F10807884F821005B +:10230000EEE710B5818800F1280321F4004423444E +:10231000848AC288A14212D0914210D0818971B9B9 +:10232000826972B11046FFF7E8FE50B91089283271 +:1023300020F40040104419790079884201D100202E +:1023400010BD184610BD00F12803407F0830084436 +:10235000C01E1060088808B9DB1E13600888498811 +:10236000084480B270472DE9F04100F12806407F13 +:102370001C4608309046431808884D88069ADB1E94 +:10238000A0B1C01C80B2904214D9801AA04200DBD8 +:10239000204687B298183A46414613F00FF90028B4 +:1023A00016D1E01B84B2B844002005E0ED1CADB2AC +:1023B000F61EE8E7101A80B20119A94206D8304487 +:1023C00022464146BDE8F04113F0F8B84FF0FF3027 +:1023D00058E62DE9F04100F12804407F1E46083000 +:1023E00090464318002508884F88069ADB1E90B156 +:1023F000C01C80B2904212D9801AB04200DB304635 +:1024000085B299182A46404613F004F9701B86B22B +:10241000A844002005E0FF1CBFB2E41EEAE7101A42 +:1024200080B28119B94206D821183246404613F0CD +:10243000F1F8A81985B2284624E62DE9F04100F10B +:102440002804407F1E46083090464318002508881F +:102450004F88069ADB1E90B1C01C80B2904212D900 +:10246000801AB04200DB304685B298182A464146B1 +:1024700013F0D0F8701B86B2A844002005E0FF1CC2 +:10248000BFB2E41EEAE7101A80B28119B94206D839 +:1024900020443246414613F0BDF8A81985B22846BB +:1024A000F0E5401D704710B5044600F12801C288D0 +:1024B000808820F400431944904206D0A28922B9B2 +:1024C000228A12B9A28A904201D1002010BD088848 +:1024D000498831B1201D00F064F8002020820120DD +:1024E00010BD637F62880833184481B2201DFFF756 +:1024F00083FCF2E70021C18101774182C1758175BA +:10250000704703881380C28942B1C28822F4004315 +:1025100000F128021A440A60C08970470020704701 +:1025200010B50446808AA0F57F41FF3900D0FFDF57 +:10253000E088A082E08900B10120A07510BD4FF6AF +:10254000FF71818200218175704710B50446808A31 +:10255000A0F57F41FF3900D1FFDFA07D28B9A08819 +:10256000A18A884201D1002010BD012010BD8188C0 +:10257000828A914201D1807D08B1002070470120FC +:10258000704720F4004221F400439A4207D100F43E +:10259000004001F40041884201D001207047002032 +:1025A000704730B5044600880D4620F40040A8422C +:1025B00000D2FFDF21884FF4004088432843208069 +:1025C00030BD70B50C00054609D0082C00D2FFDFE5 +:1025D0001DB1A1B2286800F044F8201D70BD0DB1F6 +:1025E00000202860002070BD0021026803E093886D +:1025F0001268194489B2002AF9D100F032B870B5D6 +:1026000000260D460446082900D2FFDF206808B9DD +:102610001EE0044620688188A94202D00168002992 +:10262000F7D181880646A94201D100680DE005F185 +:10263000080293B20022994209D32844491B026040 +:1026400081802168096821600160206000E0002627 +:10265000304670BD00230B608A8002680A6001600A +:10266000704700234360021D018102607047F0B58E +:102670000F460188408815460C181E46AC4200D310 +:10268000641B3044A84200D9FFDFA019A84200D93A +:10269000FFDF3819F0BD2DE9F04188460646018874 +:1026A000408815460C181F46AC4200D3641B3844C2 +:1026B000A84200D9FFDFE019A84200D9FFDF7088E7 +:1026C0003844708008EB0400BDE8F0812DE9F0414A +:1026D000054600881E461746841B8846BC4200D328 +:1026E0003C442C8068883044B84200D9FFDFA019F0 +:1026F000B84200D9FFDF68883044688008EB0400E6 +:10270000E2E72DE9F04106881D460446701980B2C3 +:10271000174688462080B84201D3C01B20806088BD +:10272000A84200D2FFDF7019B84200D9FFDF6088ED +:10273000401B608008EB0600C6E730B50D460188F7 +:10274000CC18944200D3A41A4088984200D8FFDFE6 +:10275000281930BD2DE9F041C84D04469046A878AF +:102760000E46A04200D8FFDF05EB8607B86A50F896 +:10277000240000B1FFDFB868002816D0304600F012 +:1027800044F90146B868FFF73AFF05000CD0B86A73 +:10279000082E40F8245000D3FFDFB94842462946AE +:1027A00050F82630204698472846BDE8F0812DE9AC +:1027B000F8431E468C1991460F460546FF2C00D95A +:1027C000FFDFB14500D9FFDFE4B200954DB3002033 +:1027D0008046E81C20F00300A84200D0FFDF4946F5 +:1027E000DFF89892684689F8001089F8017089F836 +:1027F000024089F8034089F8044089F8054089F8C7 +:10280000066089F80770414600F008F90021424649 +:102810000F464B460098C01C20F00300009012B1F8 +:102820000EE00120D4E703EB8106B062002005E052 +:10283000D6F828C04CF82070401CC0B2A042F7D394 +:102840000098491C00EB8400C9B200900829E1D32C +:10285000401BBDE8F88310B50446EEF75AFD08B1F9 +:10286000102010BD2078854A618802EB80009278A4 +:102870000EE0836A53F8213043B14A1C6280A18084 +:10288000806A50F82100A060002010BD491C89B268 +:102890008A42EED86180052010BD70B505460C4611 +:1028A0000846EEF736FD08B1102070BD082D01D3A3 +:1028B000072070BD25700020608070BD0EB5694690 +:1028C000FFF7EBFF00B1FFDF6846FFF7C4FF08B179 +:1028D00000200EBD01200EBD10B50446082800D30F +:1028E000FFDF6648005D10BD3EB505460024694621 +:1028F000FFF7D3FF18B1FFDF01E0641CE4B26846C4 +:10290000FFF7A9FF0028F8D02846FFF7E5FF001BD6 +:10291000C0B23EBD59498978814201D9C0B27047E1 +:10292000FF2070472DE9F041544B062903D00729B9 +:102930001CD19D7900E0002500244FF6FF7603EBC3 +:10294000810713F801C00AE06319D7F828E09BB2A9 +:102950005EF823E0BEF1000F04D0641CA4B2A445CD +:10296000F2D8334603801846B34201D100201CE759 +:10297000BDE8F041EEE6A0F57F43FF3B01D008291A +:1029800001D300207047E5E6A0F57F42FF3A0BD067 +:10299000082909D2394A9378834205D902EB81018B +:1029A000896A51F820007047002070472DE9F041F6 +:1029B00004460D46A4F57F4143F20200FF3902D0E0 +:1029C000082D01D30720F0E62C494FF000088A7843 +:1029D000A242F8D901EB8506B26A52F82470002FA2 +:1029E000F1D027483946203050F82520204690471E +:1029F000B16A284641F8248000F007F802463946BB +:102A0000B068FFF727FE0020CFE61D49403131F8BE +:102A100010004FF6FC71C01C084070472DE9F843C8 +:102A2000164E8846054600242868C01C20F0030086 +:102A300028602046FFF7E9FF315D4843B8F1000FF9 +:102A400001D0002200E02A680146009232B100273E +:102A50004FEA0D00FFF7B5FD1FB106E0012700208A +:102A6000F8E706EB8401009A8A602968641C084430 +:102A7000E4B22860082CD7D3EBE60000040800205D +:102A8000D85B020070B50E461D46114600F0D4F822 +:102A900004462946304600F0D8F82044001D70BD99 +:102AA0002DE9F04190460D4604004FF0000610D08D +:102AB0000027E01C20F00300A04200D0FFDFDDB1C2 +:102AC00041460020FFF77DFD0C3000EB850617B175 +:102AD00012E00127EDE7614F04F10C00A9003C6012 +:102AE0002572606000EB85002060606812F033FEA4 +:102AF00041463868FFF765FD3046BDE8F0812DE9B5 +:102B0000FF4F564C804681B020689A46934600B9E4 +:102B1000FFDF2068027A424503D9416851F8280056 +:102B200020B143F2020005B0BDE8F08F5146029893 +:102B300000F082F886B258460E9900F086F885B209 +:102B40007019001D87B22068A14639460068FFF75A +:102B500056FD04001FD0678025802946201D0E9D4C +:102B600007465A4601230095FFF768F92088314649 +:102B700038440123029ACDF800A0FFF75FF92088BE +:102B8000C1193846FFF78AF9D9F8000041680020DA +:102B900041F82840C7E70420C5E770B52F4C05462B +:102BA000206800B9FFDF2068017AA9420ED9426887 +:102BB00052F8251051B1002342F825304A880068A8 +:102BC000FFF748FD216800200A7A08E043F202007E +:102BD00070BD4B6853F8203033B9401CC0B28242FC +:102BE000F7D80868FFF700FD002070BD70B51B4ED8 +:102BF00005460024306800B9FFDF3068017AA94239 +:102C000004D9406850F8250000B1041D204670BD6D +:102C100070B5124E05460024306800B9FFDF3068F9 +:102C2000017AA94206D9406850F8251011B131F84F +:102C3000040B4418204670BD10B50A460121FFF769 +:102C4000F6F8C01C20F0030010BD10B50A460121A3 +:102C5000FFF7EDF8C01C20F0030010BD800000203D +:102C600070B50446C2F11005281912F0D3FC15F016 +:102C7000FF0108D0491EC9B2802060542046BDE83B +:102C8000704012F046BD70BD30B505E05B1EDBB292 +:102C9000CC5CD55C6C40C454002BF7D130BD10B572 +:102CA000002409E00B78521E44EA430300F8013B7C +:102CB00011F8013BD2B2DC09002AF3D110BD2DE995 +:102CC000F04389B01E46DDE9107990460D000446B8 +:102CD00022D002460846F949FDF7DEFC10222146C3 +:102CE0003846FFF7DCFFE07B000606D5F34A39469D +:102CF000102310320846FFF7C7FF10223946484616 +:102D0000FFF7CDFFF87B000606D5EC4A49461023B5 +:102D100010320846FFF7B8FF1021204612F0F9FCE8 +:102D20000DE0103EB6B208EB0601102322466846BD +:102D3000FFF7AAFF224628466946FDF7ADFC102E94 +:102D4000EFD818D0F2B241466846FFF789FF10234A +:102D50004A46694604A8FFF797FF1023224604A9B4 +:102D60006846FFF791FF224628466946FDF794FC26 +:102D700009B0BDE8F08310233A464146EAE770B552 +:102D80009CB01E460546134620980C468DF8080058 +:102D9000202219460DF1090012F03CFC20222146A8 +:102DA0000DF1290012F036FC17A913A8CDE9000196 +:102DB000412302AA31462846FFF781FF1CB070BDAF +:102DC0002DE9FF4F9FB014AEDDE92D5410AFBB4984 +:102DD000CDE90076202320311AA8FFF770FF4FF0CD +:102DE00000088DF808804FF001098DF8099054F81B +:102DF000010FCDF80A00A088ADF80E0014F8010C00 +:102E00001022C0F340008DF8100055F8010FCDF8E6 +:102E10001100A888ADF8150015F8010C2C99C0F325 +:102E200040008DF8170006A8824612F0F3FB0AA8AE +:102E300083461022229912F0EDFBA0483523083872 +:102E400002AA40688DF83C80CDE900760E901AA960 +:102E50001F98FFF734FF8DF808808DF809902068DF +:102E6000CDF80A00A088ADF80E0014F8010C10226D +:102E7000C0F340008DF810002868CDF81100A88834 +:102E8000ADF8150015F8010C2C99C0F340008DF831 +:102E90001700504612F0BEFB58461022229912F03D +:102EA000B9FB86483523083802AA40688DF83C9063 +:102EB000CDE900760E901AA92098FFF700FF23B005 +:102EC000BDE8F08FF0B59BB00C460546DDE9221059 +:102ED0001E461746DDE92032D0F801C0CDF808C003 +:102EE000B0F805C0ADF80CC00078C0F340008DF814 +:102EF0000E00D1F80100CDF80F00B1F80500ADF8D3 +:102F0000130008781946C0F340008DF815001088AA +:102F1000ADF8160090788DF818000DF11900102208 +:102F200012F078FB0DF129001022314612F072FBED +:102F30000DF139001022394612F06CFB17A913A8C5 +:102F4000CDE90001412302AA21462846FFF7B7FE3A +:102F50001BB0F0BDF0B5A3B017460D4604461E46A3 +:102F6000102202A8289912F055FB06A82022394603 +:102F700012F050FB0EA82022294612F04BFB1EA98E +:102F80001AA8CDE90001502302AA314616A8FFF77E +:102F900096FE1698206023B0F0BDF0B589B00446C7 +:102FA000DDE90E070D463978109EC1F340018DF81A +:102FB000001031789446C1F340018DF80110196872 +:102FC000CDF802109988ADF8061099798DF808109F +:102FD0000168CDF809108188ADF80D1080798DF861 +:102FE0000F0010236A46614604A8FFF74DFE2246F3 +:102FF000284604A9FDF750FBD6F801000090B6F86A +:103000000500ADF80400D7F80100CDF80600B7F8C8 +:103010000500ADF80A000020039010236A462146FF +:1030200004A8FFF731FE2246284604A9FDF734FB29 +:1030300009B0F0BD1FB51C6800945B68019313686C +:10304000029352680392024608466946FDF724FB44 +:103050001FBD10B588B004461068049050680590F4 +:1030600000200690079008466A4604A9FDF714FB65 +:10307000BDF80000208008B010BD1FB51288ADF863 +:1030800000201A88ADF802200022019202920392D9 +:10309000024608466946FDF7FFFA1FBD7FB5074B9C +:1030A00014460546083B9A1C6846FFF7E6FF224691 +:1030B00069462846FFF7CDFF7FBD0000305C020067 +:1030C00070B5044600780E46012813D0052802D0BA +:1030D000092813D10EE0A06861690578042003F087 +:1030E0006DF9052D0AD0782300220420616903F0D0 +:1030F000BBF803E00420616903F060F93146204623 +:10310000BDE8704001F084B810B500F12D03C2791C +:103110009C78411D144064F30102C271D2070DD0A6 +:103120004A795C7922404A710A791B791A400A71FE +:103130008278C9788A4200D9817010BD00224A7114 +:10314000F5E74178012900D00C21017070472DE985 +:10315000F04F93B04FF0000B0C690D468DF820B086 +:10316000097801260C2017464FF00D084FF0110A80 +:103170004FF008091B2975D2DFE811F01B00C202CD +:1031800005031D035C036F03A103B603F7031804D3 +:10319000600492049F04EB042905330551055C0586 +:1031A000ED053006330662067E06F8061C07E506C6 +:1031B000EA0614B120781D282AD0D5F808805FEAE5 +:1031C00008004FD001208DF82000686A02220D907F +:1031D0008DF824200A208DF82500A8690A90A88877 +:1031E0000028EED098F8001091B10F2910D27DD2AE +:1031F000DFE801F07C1349DEFCFBFAF9F8F7380848 +:103200009CF6F50002282DD124B120780C2801D09D +:103210000026EEE38DF82020CAE10420696A03F05D +:10322000CDF8A8880728EED1204600F0ECFF022850 +:1032300009D0204600F0E7FF032807D9204600F018 +:10324000E2FF072802D20120207004E0002CB8D051 +:1032500020780128D7D198F80400C11F0A2902D389 +:103260000A2061E0C3E1A070D8F80010E162B8F86C +:103270000410218698F8060084F832000120287096 +:103280000320207044E00728BDD1002C99D020787D +:103290000D28B8D198F8031094F82F20C1F3C0007E +:1032A000C2F3C002104201D0062000E007208907C7 +:1032B00007D198F805100142D2D198F806100142C2 +:1032C000CED194F8312098F8051020EA020211427C +:1032D000C6D194F8322098F8061090430142BFD12D +:1032E00098F80400C11F0A29BAD200E006E2617D05 +:1032F00081427CD8D8F800106160B8F804102181B0 +:1033000098F80600A072012028700E20207003207B +:103310008DF82000686A0D9004F12D000990601D61 +:103320000A900F300B9021E12875FDE3412891D1DF +:10333000204600F068FF042802D1E078C00704D1DD +:10334000204600F060FF0F2884D1A88CD5F80C80AF +:1033500080B24FF0400BE669FFF748FC3246414629 +:103360005B464E46CDF80090FFF733F80B208DF802 +:103370002000686A0D90E0690990002108A8FFF715 +:103380009FFE2078042806D0A07D58B1012809D0DE +:1033900003280AD048E305202070032028708DF808 +:1033A0002060CCE184F800A032E712202070E8E130 +:1033B0001128BCD1204600F026FF042802D1E07875 +:1033C000C00719D0204600F01EFF062805D1E0787E +:1033D000C00711D1A07D02280ED0204608E0CBE026 +:1033E00084E070E14FE122E102E1E8E019E0AEE1C2 +:1033F00000F009FF11289AD1102208F1010104F10F +:103400003C0012F007F9607801286ED0122020707D +:10341000E078C00760D0A07D0028C8D00128C6D0C1 +:103420005AE0112890D1204600F0EDFE082804D083 +:10343000204600F0E8FE132886D104F16C0010222B +:1034400008F10101064612F0E5F8207808280DD0B1 +:1034500014202070E178C8070DD0A07D02280AD082 +:103460006278022A04D00328A1D035E00920F0E7D1 +:1034700008B1012837D1C80713D0A07D02281DD07C +:1034800000200090D4E9062133460EA8FFF777FC10 +:1034900010220EA904F13C0012F090F8C8B10420EB +:1034A00042E7D4E90912201D8DE8070004F12C033E +:1034B00032460EA8616BFFF770FDE9E7606BC1F360 +:1034C0004401491E0068C84000F0010040F080003F +:1034D000D7E72078092806D185F800908DF820904C +:1034E00032E32870EBE30920FBE79CE1112899D136 +:1034F000204600F088FE0A2802D1E078C00704D1F7 +:10350000204600F080FE15288CD104F13C001022EA +:1035100008F10101064612F07DF820780A2816D03D +:1035200016202070D4E90932606B611D8DE80F0010 +:1035300004F15C0304F16C0247310EA8FFF7C2FCF2 +:1035400010220EA9304612F039F818B1F6E20B201D +:10355000207071E22046FFF7D7FDA078216A0A1893 +:10356000C0F11001104612F0D4F823E3394608A840 +:10357000FFF7A6FD06463BE20228B8D1204600F040 +:1035800042FE042804D3204600F03DFE082809D35B +:10359000204600F038FE0E2829D3204600F033FEE6 +:1035A000122824D2A07D0228A1D10E208DF820005F +:1035B000686A0D9098F801008DF82400F0E3022865 +:1035C00095D1204600F01FFE002810D0204600F0C4 +:1035D0001AFE0128F9D0204600F015FE0C28F4D080 +:1035E00004208DF8240098F801008DF825005EE293 +:1035F0001128FCD1002CFAD020781728F7D1617857 +:10360000606A022911D0002101EB4101182606EB66 +:10361000C1011022405808F1010111F0FBFF042004 +:10362000696A00F0E3FD2670F2E50121ECE70B2862 +:10363000DDD1002CDBD020781828D8D16078616AE1 +:1036400002281CD05FF0000000EB4002102000EBCD +:10365000C2000958B8F8010008806078616A022841 +:103660000FD0002000EB4002142000EBC2000958EC +:10367000404650F8032F0A604068486039E0012056 +:10368000E2E70120EEE71128B1D1002CAFD020787D +:103690001928ACD16178606A022912D05FF000016C +:1036A00001EB41011C2202EBC1011022405808F13C +:1036B000010111F0AFFF0420696A00F097FD1A20A4 +:1036C000B6E00121ECE7082891D1002C8FD02078BA +:1036D0001A288CD1606A98F80120017862F34701BA +:1036E0000170616AD8F8022041F8012FB8F806008D +:1036F00088800420696A00F079FD8EE2072013E6D5 +:103700003878012894D1182204F11400796811F056 +:10371000C6FFE079C10894F82F0001EAD001E078F3 +:1037200061F30000E070217D002974D12178032924 +:1037300009D0C00725D0032028708DF82090686A32 +:103740000D90412004E3607DA178884201D90620D4 +:10375000EAE502262671E179204621F0E001E171D7 +:10376000617A21F0F0016172A17A21F0F001A17279 +:10377000FFF7CAFC2E708DF82090686A0D90072024 +:10378000E6E20420ADE6387805289DD18DF82000CA +:10379000686A0D90B8680A900720ADF824000A986E +:1037A0008DF830B06168016021898180A17A8171D2 +:1037B00004202070F4E23978052985D18DF8201095 +:1037C000696A0D91391D09AE0EC986E80E004121C6 +:1037D000ADF824108DF830B01070A88CD7F80C809C +:1037E00080B24026A769FFF713FA41463A463346AE +:1037F000C846CDF80090FEF720FE002108A8FFF78C +:103800005FFCE07820F03E00801CE0702078052806 +:1038100002D00F200CE049E1A07D20B1012802D0A8 +:10382000032802D002E10720C0E584F80080EFE41D +:103830002070EDE4102104F15C0002F0E0FA606B0E +:10384000B0BBA07D18B1012801D00520FDE0062005 +:103850002870F7486063A063BEE23878022894D1EC +:10386000387908B12875B3E3A07D022802D0032877 +:1038700005D022E0B8680028F5D060631CE06078CD +:10388000012806D0A07994F82E10012805D0E84828 +:1038900006E0A17994F82E00F7E7B8680028E2D096 +:1038A0006063E078C00701D0012902D0E04803E05E +:1038B00003E0F8680028D6D0A063062011E68DF852 +:1038C0002090696A0D91E1784846C90709D061786E +:1038D000022903D1A17D29B1012903D0A17D0329AA +:1038E00000D00720287031E138780528BBD1207836 +:1038F00007281ED084F800A005208DF82000686AF3 +:103900000D90B8680A90ADF824A08DF830B003216E +:103910000170E178CA070FD0A27D022A1AD00021D7 +:103920000091D4E9061204F15C03401CFFF727FA6A +:1039300067E384F80090DFE7D4E90923211D8DE8CF +:103940000E0004F12C0304F15C02401C616BFFF7D4 +:1039500024FB56E3626BC1F34401491E1268CA405E +:1039600002F0010141F08001DAE738780528BDD185 +:103970008DF82000686A0D90B8680A90ADF824A010 +:103980008DF830B0042100F8011B102204F15C0115 +:1039900011F040FE002108A8FFF792FB20780928CB +:1039A00001D0132044E70A2020709CE5E078C1078D +:1039B00042D0A17D012902D0022927D038E06178C8 +:1039C00008A8012916D004F16C010091D4E906126F +:1039D00004F15C03001DFFF7BDFA0A2028700326DE +:1039E0008DF82080686A0D90002108A8FFF768FB19 +:1039F000DDE2C3E204F15C010091D4E9062104F1A7 +:103A00006C03001DFFF7A6FA0026E9E7C0F34401A6 +:103A100014290DD24FF0006101EBB0104FEAB060F5 +:103A2000E0706078012801D01020BFE40620FFE696 +:103A3000607801283FF4B8AC0A2052E5E178C90764 +:103A400008D0A17D012903D10B20287004202FE08C +:103A500028702DE00E2028706078616B012817D047 +:103A600004F15C0304F16C020EA8FFF7E3FA2046B0 +:103A7000FFF74AFBA0780EAEC0F11001304411F000 +:103A800048FE06208DF82000686A09960D909AE09D +:103A900004F16C0304F15C020EA8FFF7CBFAE9E72E +:103AA0003978022903D139790029D1D029758FE2DB +:103AB0008DF82000686A0D9058E538780728F6D10F +:103AC000D4E909216078012809D000BF04F16C0015 +:103AD000CDE90002029105D104F16C0304E004F188 +:103AE0005C00F5E704F15C0304F14C007A680646DB +:103AF000216AFFF765F96078012821D1A078216A51 +:103B00000A18C0F11001104611F003FED4E9092390 +:103B1000606B04F12D018DE80F0004F15C0304F1EA +:103B20006C0231460EA800E054E2FFF7CBF91022F8 +:103B30000EA904F13C0011F041FD08B10B20AFE4E7 +:103B400085F800808DF82090686A0D908DF824A08B +:103B50000CE538780528AAD18DF82000686A0D9008 +:103B6000B8680A90ADF824A08DF830B080F80080D5 +:103B7000617801291AD0D4E9093204F12D01A66B2C +:103B800003920096CDE9011304F16C0304F15C0289 +:103B900004F14C01401CFFF795F9002108A8FFF73C +:103BA0008FFA6078012805D0152041E6D4E9092371 +:103BB000611DE4E70E20287006208DF82000686A59 +:103BC000CDF824B00D90A0788DF82800CEE4387898 +:103BD0000328C0D1E079C00770D00F2028700720DB +:103BE00066E7387804286BD11422391D04F11400DB +:103BF00011F055FD616A208CA1F80900616AA07876 +:103C0000C871E179626A01F003011172616A627A36 +:103C10000A73616AA07A81F82400162061E485F8AD +:103C200000A08DF82090696A50460D9190E0000048 +:103C3000305C02003878052842D1B868A861617804 +:103C4000606A022901D0012100E0002101EB41015D +:103C5000142606EBC1014058082102F0D0F8617823 +:103C6000606A022901D0012100E0002101EB41013D +:103C700006EBC101425802A8E169FFF70FFA60782C +:103C8000626A022801D0012000E0002000EB400120 +:103C9000102000EBC1000223105802A90932FEF7E0 +:103CA000F3FF626AFD4B0EA80932A169FFF7E5F93F +:103CB0006178606A022904D0012103E042E18BE0CF +:103CC000BDE0002101EB4101182606EBC101A278FD +:103CD00040580EA911F09EFC6178606A022901D05B +:103CE000012100E0002101EB410106EBC101405838 +:103CF000A1780844C1F1100111F00BFD05208DF8E9 +:103D00002000686A0D90A8690A90ADF824A08DF88B +:103D100030B0062101706278616A022A01D0012266 +:103D200000E0002202EB420206EBC202401C89586E +:103D3000102211F06FFC002108A8FFF7C1F9122032 +:103D4000C5F818B028708DF82090686A0D900B2087 +:103D50008DF824000AE43878052870D18DF8200009 +:103D6000686A0D90B8680A900B20ADF824000A9894 +:103D7000072101706178626A022901D0012100E007 +:103D8000002101EB4103102101EBC30151580988C7 +:103D9000A0F801106178626A022902D0012101E0D5 +:103DA0002FE1002101EB4103142101EBC301515824 +:103DB0000A6840F8032F4968416059E019202870CB +:103DC00001208DF8300077E6162028708DF830B08D +:103DD000002108A8FFF774F9032617E114202870C2 +:103DE000B0E6387805282AD18DF82000686A0D9051 +:103DF000B8680A90ADF824A08DF830B080F8009033 +:103E00006278616A4E46022A01D0012200E0002257 +:103E100002EB42021C2303EBC202401C8958102211 +:103E200011F0F8FB002108A8FFF74AF915202870C7 +:103E30008DF82060686A0D908DF824603CE680E083 +:103E4000387805287DD18DF82000686A0D90B86813 +:103E50000A90ADF824900921017061690978490838 +:103E60004170616951F8012FC0F802208988C18032 +:103E700020781C28A8D1A1E7E078C00702D04FF035 +:103E8000060C01E04FF0070C607802280AD000BF52 +:103E90004FF0000000EB040101F1090105D04FF0E3 +:103EA000010004E04FF00100F4E74FF000000B7850 +:103EB000204413EA0C030B7010F8092F02EA0C02DD +:103EC000027004D14FF01B0C84F800C0D2B394F8F8 +:103ED00001C0BCF1010F00D09BB990F800C0E046D2 +:103EE0005FEACC7C04D028F001060670102606E0BC +:103EF0005FEA887C05D528F00206067013262E702E +:103F0000032694F801C0BCF1020F00D092B991F8D9 +:103F100000C05FEACC7804D02CF001060E701721A7 +:103F200006E05FEA8C7805D52CF002060E701921A8 +:103F3000217000260078D0BBCAB3C3BB1C20207000 +:103F400035E012E002E03878062841D11A2019E461 +:103F5000207801283CD00C283AD02046FFF7F1F811 +:103F600009208DF82000686A0D9031E03878052826 +:103F700005D00620387003261820287046E0052159 +:103F80008DF82010686A0D90B8680A900220ADF88C +:103F9000240001208DF830000A980170297D4170BD +:103FA000394608A8FFF78CF8064618202870012E1D +:103FB0000ED02BE001208DF82000686A0D900320C0 +:103FC0008DF82400287D8DF8250085F814B012E0C6 +:103FD000287D80B11D202070172028708DF820903A +:103FE000686A0D9002208DF82400394608A8FFF772 +:103FF00067F806460AE00CB1FE2020709DF820000C +:1040000020B1002108A8FFF75BF810E413B0304698 +:10401000BDE8F08F2DE9F04387B00C464E690021D2 +:104020008DF8041001202578034602274FF0070978 +:104030004FF0050C85B1012D53D0022D39D1FE2052 +:1040400030708DF80030606A059003208DF8040010 +:10405000207E8DF8050063E02179012925D0022911 +:104060002DD0032928D0042923D1B17D022920D1C4 +:1040700031780D1F042D04D30A3D032D01D31D29D2 +:1040800017D12189022914D38DF804702370208957 +:104090009DF8041088421BD2082001E0285C020031 +:1040A0008DF80000606A059057E070780128EBD029 +:1040B000052007B0BDE8F0831D203070E4E771787B +:1040C0000229F5D131780C29F3D18DF80490DDE780 +:1040D000083402F804CB94E80B0082E80B000320BC +:1040E000E7E71578052DE4D18DF800C0656A0595E0 +:1040F000956802958DF8101094F80480B8F1010FBE +:1041000013D0B8F1020F2DD0B8F1030F1CD0B8F1C5 +:10411000040FCED1ADF804700E202870207E687098 +:1041200000216846FEF7CCFF0CE0ADF804700B20D0 +:104130002870207E002100F01F0068706846FEF79E +:10414000BFFF37700020B4E7ADF804708DF8103071 +:1041500085F800C0207E6870277011466846FEF71B +:10416000AFFFA6E7ADF804902B70207F6870607FEA +:1041700000F00100A870A07F00F01F00E870E27F4F +:104180002A71C0071CD094F8200000F00700687165 +:1041900094F8210000F00700A87100216846FEF79E +:1041A0008FFF2868F062A8883086A87986F83200E8 +:1041B000A069407870752879B0700D203070C1E723 +:1041C000A9716971E9E700B587B004280CD1012015 +:1041D0008DF800008DF80400002005918DF8050091 +:1041E00001466846FEF76CFF07B000BD70B50C468F +:1041F000054602F0E3F821462846BDE870407823E2 +:10420000002202F031B808B1007870470C207047E6 +:1042100070B50C0005784FF000010CD021702146DC +:10422000F1F707F869482178405D884201D1032001 +:1042300070BD022070BDF0F7FCFF002070BD027958 +:10424000012A05D000220A704B78012B02D003E02E +:10425000042070470A758A6102799300521C02712A +:10426000C15003207047F0B587B00F4605460124C2 +:10427000287905EB800050F8046C7078411E022903 +:104280000AD252493A46083901EB8000314650F8CB +:10429000043C2846984704460CB1012C11D12879DA +:1042A000401E10F0FF00287101D00324E0E70A202F +:1042B0008DF80000706A0590002101966846FFF7AE +:1042C000A7FF032CD4D007B02046F0BD70B515462B +:1042D0000A46044629461046FFF7C5FF064674B154 +:1042E0002078FE280BD1207C30B100202870294690 +:1042F00004F10C00FFF7B7FF2046FEF722FF30461F +:1043000070BD704770B50E4604467C2111F023FA4B +:104310000225012E03D0022E04D0052070BD0120FD +:10432000607000E065702046FEF70BFFA575002069 +:1043300070BD28B1027C1AB10A4600F10C01C5E734 +:104340000120704710B5044686B0042002F036F80C +:104350002078FE2806D000208DF80000694620460F +:10436000FFF7E7FF06B010BD7CB50E4600218DF8C3 +:1043700004104178012903D0022903D0002405E06C +:10438000046900E044690CB1217C89B16D460146A5 +:104390002846FFF754FF032809D132462946204614 +:1043A000FFF794FF9DF80410002900D004207CBD85 +:1043B00004F10C05EBE730B40C460146034A2046F5 +:1043C00030BC034B0C3AFEF758BE00006C5C020098 +:1043D000285C020070B50D46040011D085B12101A2 +:1043E000284611F096F910225449284611F012F986 +:1043F000524801210838018044804560002070BD8A +:10440000012070BD70B54D4E00240546083E10E0F9 +:104410007068AA7B00EB0410817B914208D1C17BBC +:10442000EA7B914204D10C22294611F0C7F830B141 +:10443000641C30888442EBDB4FF0FF3070BD2046B7 +:1044400070BD70B50D46060006D02DB1FFF7DAFF3E +:10445000002803DB401C14E0102070BD374C083CE2 +:1044600020886288411C914201D9042070BD616896 +:10447000102201EB0010314611F0CCF82088401CCE +:1044800020802870002070BD2C48083800887047B4 +:104490002A4908390888012802D0401E08800020D7 +:1044A000704770B514460D0018D0BCB10021A17042 +:1044B000022802D0102811D105E0288870B101210E +:1044C000A170108008E02846FFF79CFF002805DB5C +:1044D000401CA070A8892080002070BD012070BD04 +:1044E00070B5054614460E000BD000203070A87839 +:1044F000012808D005D91149A1F108010A88904284 +:104500000AD9012070BD24B1287820702888000ABB +:104510005070022008700FE064B14968102201EB6E +:1045200000112046103911F075F82878207328887A +:10453000000A607310203070002070BD8C000020D5 +:104540002DE9F04190460C4607460025FE48072F0E +:1045500000EB881607D2DFE807F007070707040417 +:104560000400012500E0FFDF06F81470002D13D0D1 +:10457000F548803000EB880191F82700202803D00F +:1045800006EB4000447001E081F8264006EB44024F +:104590002020507081F82740BDE8F081F0B51F461B +:1045A00014460E460546202A00D1FFDFE649E648BC +:1045B000803100EB871C0CEB440001EB8702202EBE +:1045C00007D00CEB460140784B7848701846202104 +:1045D0000AE092F82530407882F82500F6E7014697 +:1045E0000CEB410005704078A142F8D192F82740C9 +:1045F000202C03D00CEB4404637001E082F82630D9 +:104600000CEB41042023637082F82710F0BD30B515 +:104610000D46CE4B44190022181A72EB020100D24B +:10462000FFDFCB48854200DDFFDFC94840428542BD +:1046300000DAFFDFC548401C844207DA002C01DBAA +:10464000204630BDC148401C201830BDBF48C04383 +:10465000FAE710B504460168407ABE4A52F82020B5 +:10466000114450B10220084420F07F40EEF7E5FAF3 +:1046700094F90810BDE81040C9E70420F3E72DE9DC +:10468000F047B14E803696F82D50DFF8BC9206EB1D +:10469000850090F8264034E009EB85174FF00708B5 +:1046A00017F81400012806D004282ED005282ED093 +:1046B000062800D0FFDF01F000F9014607EB4400B7 +:1046C000427806EB850080F8262090F82720A24249 +:1046D00002D1202280F82720084601F0F9F82A4666 +:1046E00021460120FFF72CFF9B48414600EB0410B8 +:1046F00002682046904796F82D5006EB850090F80A +:104700002640202CC8D1BDE8F087022000E003201D +:104710008046D0E710B58C4C2021803484F82510D9 +:1047200084F8261084F82710002084F8280084F8E4 +:104730002D0084F82E10411EA16044F8100B207447 +:10474000607420736073A0738449E07720750870EB +:10475000487000217C4A103C02F81100491CC9B283 +:104760002029F9D30120EEF758F90020EEF755F98A +:10477000012084F82200EEF79BFB7948EEF7ADFBB1 +:10478000764CA41E20707748EEF7A7FB6070BDE85A +:104790001040EEF7CFB810B5EEF7F1F86F4CA41E4D +:1047A0002078EEF7B3FB6078EEF7B0FBBDE8104081 +:1047B00001F0BBB8202070472DE9F34F624C002573 +:1047C000803404EB810A89B09AF82500202821D092 +:1047D000691E02916049009501EB0017391D03AB7A +:1047E00007C983E80700A18BADF81C10A07F8DF8E6 +:1047F0001E009DF81500A046C8B10226554951F883 +:1048000020400399A219114421F07F41019184B104 +:1048100002210FE00120EEF700F90020EEF7FDF88D +:10482000EEF7CBF801F081F884F82F50A7E00426CA +:10483000E4E700218DF81810022801D0012820D1CA +:10484000039801190998081A801C9DF81C1020F083 +:104850007F4001B10221353181420BD203208DF816 +:1048600015000398C4F13201401A20F07F40322431 +:1048700003900CE098F8240018B901F0F0F9002832 +:104880004DD0322C03D214B101F043F801E001F015 +:104890004CF8324A107820B393465278039B121B8F +:1048A00000219DF81840994601281BD0032819D0F3 +:1048B0005FF000008DF81E00002A04DD981A0390B6 +:1048C00001208DF818009DF81C0000B1022103980A +:1048D000254A20F07F40039003AB099801F031F89E +:1048E00010B110E00120E5E79DF81D0018B99BF814 +:1048F0000000032812D08DF81C50CDF80C908DF8D4 +:1049000018408DF81E509DF8180058B103980123E7 +:10491000811900221846EEF7D3F806E000200BB00C +:10492000BDE8F08F0120EEF778F897F90C2001230D +:1049300000200199EEF7C4F8F87BC00701D0EEF72C +:10494000A8F9012112E000004C0A0020FF7F841E1C +:104950000020A1077C5C02004C0800209E00002083 +:10496000176101007F460100FFFF3F0088F82F100C +:104970008AF8285020226946F74810F090FE01205E +:10498000CDE72DE9F05FDFF8D083064608EB86001F +:1049900090F82550202D1FD0A8F180002C4600EB68 +:1049A0008617A0F50079DFF8B4B305E0A24607EB5F +:1049B0004A004478202C0AD0EEF7CDF809EB041316 +:1049C0005A4601211B1D00F0BCFF0028EED0AC426E +:1049D00002D0334652461EE0E14808B1AFF30080F2 +:1049E000EEF7B9F898F82F206AB1D8F80C20411CDE +:1049F000891A0902CA1701EB12610912002902DDA6 +:104A00000020BDE8F09F3146FFF7D6FE08B1012037 +:104A1000F7E733462A4620210420FFF7BFFDEFE7E2 +:104A20002DE9F041CC4C2569EEF795F8401B0002CA +:104A3000C11700EB1160001200D4FFDF94F82200D0 +:104A400000B1FFDF012784F8227094F82E0020289F +:104A500000D1FFDF94F82E60202084F82E0000257E +:104A600084F82F5084F8205084F82150BD482560E8 +:104A70000078022833D0032831D000202077A068A6 +:104A8000401C05D04FF0FF30A0600120EDF7C5FFBE +:104A90000020EDF7C2FFEEF7BEF8EEF7B6F8EDF73F +:104AA0008CFF10F007F8B048056005604FF0E0217A +:104AB0004FF40040B846C1F88002EEF758F994F878 +:104AC0002D703846FFF75DFF0028FAD0A2488038E5 +:104AD00000EB871010F81600022802D006E0012033 +:104AE000CCE73A4631460620FFF72AFD84F82380BA +:104AF00004EB870090F82600202804D09948801EF7 +:104B00004078EEF709FA207F002803D0EEF773F81B +:104B10002577657740E5904910B591F82D20002460 +:104B2000803901EB821100BF11F814302BB1641CE5 +:104B3000E4B2202CF8D3202010BD8C4901EB0411E5 +:104B400008600020C87321460120FFF7F9FC2046C9 +:104B500010BD10B5012801D0032800D171B37E4AE1 +:104B600092F82D307C4C0022803C04EB831300BF74 +:104B700013F812400CB1082010BD521CD2B2202AEA +:104B8000F6D3784A48B1022807D0072916D2DFE8C1 +:104B900001F01506080A0C0E100000210AE01B2186 +:104BA00008E03A2106E0582104E0772102E096214E +:104BB00000E0B52151701070002010BD072010BD1D +:104BC000684810B54078EEF738F880B210BD10B5DF +:104BD000202811D2604991F82D30A1F1800202EB1A +:104BE000831414F810303BB191F82D3002EB83128E +:104BF00012F81020012A01D0002010BD91F82D20BC +:104C000001460020FFF79CFC012010BD10B5EDF718 +:104C1000A2FFBDE81040EEF710B82DE9F0410E46B6 +:104C20004D4F01782025803F0C4607EB831303E0AE +:104C3000254603EB45046478944202D0202CF7D13A +:104C400008E0202C06D0A14206D103EB41014978AF +:104C5000017007E000209FE403EB440003EB4501F3 +:104C600040784870424F7EB127B1002140F2DD30DC +:104C7000AFF300803078A04206D127B100214FF475 +:104C80007870AFF30080357027B1002140F2E53035 +:104C9000AFF3008001207FE410B542680B689A1AD8 +:104CA0001202D41702EB1462121216D4497A91B18F +:104CB000427A82B92F4A006852F8211012681944CA +:104CC0001044001D891C081A0002C11700EB116076 +:104CD0000012322801DB012010BD002010BD2DE99B +:104CE000F04781461C48214E00EB8100984690F821 +:104CF00025402020107006F50070154600EB811746 +:104D00000BE000BF06EB04104946001DFFF7C4FF8F +:104D100028B107EB44002C704478202CF2D129787C +:104D200088F8001013E000BF06EB0415291D484663 +:104D3000FFF7B2FF68B988F80040A97B99F80A002C +:104D4000814201D80020DEE407EB44004478202CA7 +:104D5000EAD10120D7E40000CC0A0020FFFF3F0089 +:104D6000000000009E00002000F500404C080020DC +:104D7000000000007C5C02002DE9FC410E46074665 +:104D80000024FE4D09E000BF9DF8000005EB001077 +:104D90008168384600F0E9FD01246B4601AA3146DE +:104DA0003846FFF79CFF0028EED02046BDE8FC8186 +:104DB00070B50446F2480125A54300EB841100EBD1 +:104DC0008510402210F026FCEE4E26B1002140F264 +:104DD0005F40AFF30080EA48803000EB850100EBD4 +:104DE0008400D0F82500C1F8250026B1002140F24A +:104DF0006340AFF30080284670BD2DE9FC41844636 +:104E0000DF481546089C00EB85170E4617F814007E +:104E1000012803D0022801D00020C7E70B46DA4A58 +:104E20000121604600F08DFDA8B101AB6A4629461C +:104E30003046FFF754FF70B1D1489DF804209DF82B +:104E40000010803000EB85068A4208D02B460520F2 +:104E5000FFF7A4FB0BE02A462146042014E020299A +:104E600003D007EB4100407801E096F8250007EBFE +:104E7000440148709DF80000202809D007EB40004D +:104E800044702A4621460320FFF75AFB01208DE794 +:104E900006F8254F0120F070F3E7B84901EB001048 +:104EA000001DFFF7D6BB7CB51D46134604460E46D3 +:104EB00000F1080221461846EDF7CCFE94F90800EF +:104EC0000F2804DD1F3820722068401C206096B136 +:104ED0000220AE4951F82610461820686946801B0A +:104EE00020F07F40206094F908002844C01C1F284F +:104EF00003DA012009E00420EBE701AAEDF7AAFE9E +:104F00009DF8040010B10098401C009000992068A2 +:104F100031440844C01C20F07F4060607CBD2DE916 +:104F2000FE430C46064609786079907220799846CF +:104F30001546507241B19248803090F82E102029C9 +:104F40000AD00069401D0BE0D4E90223217903B0A7 +:104F50002846BDE8F043A6E78D484178701D084417 +:104F600020F07F47217900222846A368FFF79BFFA6 +:104F70003946284600F0F9FCD4E902322179684626 +:104F8000FFF791FF41462846019CFFF7F5FE2B46AF +:104F900022460021304600F0D4FC002803D13146DF +:104FA000284600F0E2FCBDE8FE832DE9FE4F814675 +:104FB00000F097FC30B1002799F8000020B10020E4 +:104FC000BDE8FE8F0127F7E76D4D6E4C4FF0000AEC +:104FD000803524B1002140F2D640AFF3008095F82F +:104FE0002D8085F823A0002624B1002140F2DB406B +:104FF000AFF300801FB94046FFF7DAFE804624B1C8 +:10500000002140F2E340AFF30080EDF7A4FD4346FA +:105010006A464946FFF783FF24B1002140F2E94088 +:10502000AFF3008095F82E0020280CD02969009855 +:10503000401A0002C21700EB1260001203D5684646 +:1050400000F093FC012624B1002140F2F340AFF3BD +:10505000008095F823000028BBD124B1002140F244 +:10506000F940AFF30080EDF776FD6B46464A00212C +:1050700000F067FC0028A3D027B941466846FFF737 +:105080007BFE064326B16846FFF7E3FAC9F808003D +:1050900024B1002140F20C50AFF3008001208FE7D3 +:1050A0002DE9FF5F8A46814600F01BFC344C8034BA +:1050B00010B39AF80000002710B1012800D0FFDFDC +:1050C000304D25B1002140F28250AFF30080012025 +:1050D000A84600905FEA080604D0002140F28A50FA +:1050E000AFF30080009800F0F3FB94F82D500020FF +:1050F00084F8230067B119E094F82E0001272028D6 +:1051000000D1FFDF9AF800000028D9D0FFDFD7E7F1 +:105110002846FFF74DFE054626B1002140F2945087 +:10512000AFF3008094F823000028D3D126B10021EA +:1051300040F29E50AFF30080EDF70DFD83462B4605 +:1051400001AA5146FFF7EBFE5FEA060804D00021F2 +:1051500040F2A550AFF300803B462A4601A95846CD +:10516000CDF80090FFF749FE064604EB850090F865 +:1051700028B0B8F1000F11D000210BE04C0800203E +:105180004C0A002000000000FFFF3F007C5C020092 +:105190009E00002040F2AC50AFF3008000F08DFB89 +:1051A0000090B8F1000F04D0002140F2B250AFF3EC +:1051B000008094F8230000288CD1B8F1000F04D0AF +:1051C000002140F2BA50AFF30080FE490DF1040C0B +:1051D00001EB09109CE80E0000F1040080E80E00CD +:1051E0004EB35FEA080604D0002140F2C750AFF387 +:1051F00000803BEA070012D094F82E0020280ED140 +:1052000026B1002140F2CC50AFF300802846FFF7D2 +:10521000B8FB20B99AF80000D8B3012849D0B8F1FA +:10522000000F04D0002140F2E950AFF3008028467F +:1052300000F03CFB01265FEA080504D0002140F2A3 +:10524000F250AFF30080009800F042FB25B100213E +:1052500040F2F650AFF300808EB194F82D0004EBCD +:10526000800090F82600202809D025B1002140F2C6 +:10527000FD50AFF30080D4484078EDF74DFE25B1E6 +:10528000002140F20260AFF3008004B03046BDE878 +:10529000F09FFFE7B8F1000F04D0002140F2D45096 +:1052A000AFF3008094F82D2049460420FFF748F919 +:1052B000C0E7002E3FF40EAF002140F2DF50AFF305 +:1052C000008007E72DE9F84FC04D814695F82D0085 +:1052D0004FF00008BE4C4FF0010B474624B10021AF +:1052E0004FF4C260AFF30080584600F0F1FA85F841 +:1052F000237024B1002140F21560AFF3008095F8CF +:105300002D00FFF755FD064695F8230028B1002C27 +:10531000E4D0002140F21B604BE024B1002140F2B8 +:105320001F60AFF30080A948803800EB861111F8A8 +:105330001900032856D1334605EB830A4A469AF8EA +:105340002500904201D1012000E0002000900AF1E8 +:1053500025000021FFF761FC01460098014203D0BF +:1053600001228AF82820AF77E1B324B1002140F26E +:105370002460AFF30080324649460120FFF7E0F891 +:105380009AF828A024B1002140F22F60AFF30080EA +:1053900000F093FA834624B1002140F23460AFF369 +:1053A000008095F8230038B1002C97D000214FF4ED +:1053B000C760AFF3008091E7BAF1000F07D095F80E +:1053C0002E00202803D13046FFF7DBFAE0B124B1EC +:1053D000002140F24C60AFF30080304600F066FAE6 +:1053E0004FF0010824B1002140F25560AFF3008076 +:1053F000584600F06DFA24B1002140F25960AFF335 +:1054000000804046BDE8F88F002CF1D0002140F22A +:105410004760AFF30080E6E70020EDF7D7BA012040 +:10542000EDF7D4BA6848007870472DE9F041674C31 +:1054300094F82E0020281FD194F82D6004EB8607E5 +:1054400097F82550202D00D1FFDF6049803901EB0E +:10545000861000EB4500407807F8250F0120F87012 +:1054600084F82300294684F82E5032460220223444 +:10547000FFF766F8002020700DE42DE9F041514E51 +:10548000524C012538B1012821D0022879D00328B7 +:105490007DD0FFDFF0E700F03CFAFFF7C6FF207E8B +:1054A00000B1FFDF84F821500020EDF7B6FAA168C3 +:1054B000481C04D0012300221846EDF701FB14F824 +:1054C0002E0F217806EB01110A68012154E0FFF745 +:1054D000ACFF0120EDF7A1FA94F8210050B1A068CB +:1054E000401C07D014F82E0F217806EB01110A6832 +:1054F000062141E0207EDFF8D080002708F1020875 +:10550000012803D002281ED0FFDFB5E7A777EDF70B +:1055100072FB98F80000032801D165772577607D3C +:105520002C4951F8200094F8201051B948B1616815 +:105530000123091A00221846EDF7C2FA022020764C +:105540009AE7277698E784F8205000F0E2F9A07FE8 +:1055500050B198F8010061680123091A0022184629 +:10556000EDF7AEFA257600E0277614F82E0F2178B5 +:1055700006EB01110A680021BDE8F041104700E088 +:1055800005E011480078BDE8F041EDF7C5BCFFF734 +:105590004CFF14F82E0F217806EB01110A68052143 +:1055A000EAE710B5094C94F82E00202800D1FFDF5F +:1055B00014F82E0F2178034A02EB01110A68042126 +:1055C0000AE000004C0800209C000020CC0A0020CB +:1055D000000000007C5C0200BDE8104010477CB574 +:1055E000E74C054694F82E00202800D1FFDFA06884 +:1055F000401C00D0FFDF94F82E00E24901AA01EB25 +:105600000010694690F90C002844EDF723FB9DF942 +:1056100004000F2801DD012000E00020009908446B +:105620006168084420F07F41A16094F821000028BF +:1056300007D002B00123BDE8704000221846EDF704 +:105640003FBA7CBD30B5D04A0B1A541CB3EB940F53 +:1056500012D3451AB5EB940F0ED3934203D9101A07 +:1056600043185B1C08E0954204D9511A0844401CB9 +:10567000434201E0FFDF0023184630BD0123002232 +:1056800001460220EDF71CBA0220EDF7C6B9EDF78E +:1056900062BA2DE9FC47BA4C054694F82E00202842 +:1056A00000D1FFDF642D58D3B84A0021521B71EBA3 +:1056B000010052D394F82E20A0462046DFF8C49271 +:1056C00090F82D7009EB0214D8F8000001AA2844C4 +:1056D0006946EDF7BFFA9DF90400002802DD009845 +:1056E000401C0090A068009962684618B21A22F027 +:1056F0007F42B2F5800F30D208EB8702444692F821 +:105700002520202A0AD009EB02125268101A000242 +:10571000C21700EB1260001288421EDBA068401C1A +:1057200010D0EDF718FAA168081A0002C11700EBB3 +:1057300011600012022810DD0120EDF76EF94FF024 +:10574000FF30A06020682844206026F07F40206160 +:10575000012084F82300BDE8FC870020FBE72DE949 +:10576000F047874C074694F82D00A4F1800606EB1D +:10577000801010F8170000B9FFDF94F82D50A046F4 +:10578000834C24B1002140F66D00AFF3008040F659 +:10579000790940F6820A06EB851600BF16F8170055 +:1057A000012818D0042810D005280ED006280CD0C7 +:1057B0001CB100214846AFF3008020BF002CEDD083 +:1057C00000215046AFF30080E8E72A463946012021 +:1057D000FEF7B6FEF2E74FF0010A4FF0000945462A +:1057E00024B1002140F68900AFF30080504600F05C +:1057F0006FF885F8239024B1002140F68E00AFF3B6 +:10580000008095F82D00FFF7D3FA064695F823009F +:1058100028B1002CE4D0002140F694001FE024B110 +:10582000002140F69800AFF3008005EB860000F100 +:10583000270133463A462630FFF7EFF924B100211D +:1058400040F69C00AFF3008000F037F8824695F8F0 +:10585000230038B1002CC3D0002140F6A200AFF3E2 +:105860000080BDE785F82D60012085F823005046B3 +:1058700000F02EF8002C04D0002140F6AF00AFF36A +:105880000080BDE8F08730B504463D480D4690F8ED +:105890002D003B49803901EB801010F8140000B94D +:1058A000FFDF384800EB0410C57330BD344981F880 +:1058B0002D00012081F82300704710B5354808B14C +:1058C000AFF30080EFF3108000F0010072B610BD5E +:1058D00010B5002804D1304808B1AFF3008062B69B +:1058E00010BD2E480068C005C00D10D0103840B261 +:1058F000002804DB00F1E02090F8000405E000F04F +:105900000F0000F1E02090F8140D400970470820C6 +:10591000704710B51A4C94F82400002804D1F6F70B +:105920008DF8012084F8240010BD10B5144C94F8B3 +:105930002400002804D0F6F7AAF8002084F82400F8 +:1059400010BD10B51C685B68241A181A24F07F4437 +:1059500020F07F40A14206D8B4F5800F03D29042D8 +:1059600001D8012010BD002010BDD0E90032D21AAC +:1059700021F07F43114421F07F41C0E9003170479D +:10598000CC0A00204C080020FF7F841EFF1FA107C7 +:1059900000000000000000000000000004ED00E036 +:1059A0002DE9F041044680074FF000054FF0010655 +:1059B0000CD56B48056006600EF0A5FE20B1694865 +:1059C000016841F48061016024F00204E0044FF0BA +:1059D000FF3705D564484660C0F8087324F4805446 +:1059E000600003D56148056024F08044E0050FD5D0 +:1059F0005F48C0F80052C0F808735E490D60091D89 +:105A00000D605C4A04210C321160066124F480743C +:105A1000A00409D558484660C0F80052C0F8087381 +:105A20005648056024F40054C4F38030C4F3C031F8 +:105A3000884200D0FFDF14F4404F14D05048466035 +:105A4000C0F808734F488660C0F80052C0F8087369 +:105A50004D490D600A1D16608660C0F808730D6020 +:105A6000166024F4404420050AD548484660866004 +:105A7000C0F80873C0F848734548056024F4006412 +:105A80000EF0F2FF4348044200D0FFDFBDE8F08192 +:105A9000F0B50022202501234FEA020420FA02F18A +:105AA000C9072DD051B2002910DB00BF4FEA5117B2 +:105AB0004FEA870701F01F0607F1E02703FA06F611 +:105AC000C7F88061BFF34F8FBFF36F8F0CDB00BF50 +:105AD0004FEA51174FEA870701F01F0607F1E02749 +:105AE00003FA06F6C7F8806204DB01F1E02181F8D1 +:105AF000004405E001F00F0101F1E02181F8144DAF +:105B000002F10102AA42C9D3F0BD10B5224C2060B7 +:105B10000846F6F7A8F82068FFF742FF2068FFF76D +:105B2000B7FF0EF087FB00F01AF90EF09DFF0EF0A4 +:105B3000E0FEEDF7BDF9BDE810400EF02BBC10B54E +:105B4000154C2068FFF72CFF2068FFF7A1FF0EF02F +:105B50008BFFF6F77BF90020206010BD0A2070470C +:105B6000FC1F00403C17004000C0004004E501401D +:105B7000008000400485004000D0004004D5004073 +:105B800000E0004000F0004000F5004000B00040A0 +:105B900008B50040FEFF0FFDA000002070B52649AB +:105BA0000A680AB30022154601244B685B1C4B604F +:105BB0000C2B00D34D600E7904FA06F30E681E42DA +:105BC0000FD0EFF3108212F0010272B600D0012262 +:105BD0000C689C430C6002B962B649680160002001 +:105BE00070BD521C0C2AE0D3052070BD4FF0E0219F +:105BF0004FF48000C1F800027047EFF3108111F0FC +:105C0000010F72B64FF0010202FA00F20A4803686F +:105C100042EA0302026000D162B6E7E706480021CB +:105C200001604160704701218140034800680840DD +:105C300000D0012070470000A4000020012081074F +:105C4000086070470121880741600021C0F80011F9 +:105C500018480170704717490120087070474FF0CD +:105C60008040D0F80001012803D0124800780028B5 +:105C700000D00120704710480068C00700D0012004 +:105C800070470D480C300068C00700D001207047F5 +:105C90000948143000687047074910310A68D20378 +:105CA00006D5096801F00301814201D10120704746 +:105CB00000207047AC000020080400400021017063 +:105CC000084670470146002008707047EFF31081C6 +:105CD00001F0010172B60278012A01D0012200E030 +:105CE00000220123037001B962B60AB10020704797 +:105CF0004FF400507047E9E7EFF3108111F0010F06 +:105D000072B64FF00002027000D162B600207047F8 +:105D1000F2E700002DE9F04115460E460446002743 +:105D200000F0E7F8A84215D3002341200FE000BFA0 +:105D300094F84220A25CF25494F84210491CB1FB42 +:105D4000F0F200FB12115B1C84F84210DBB2AB4294 +:105D5000EED3012700F0D9F83846BDE8F08170494C +:105D600010B5802081F800046E49002081F84200BF +:105D700081F84100433181F8420081F8410043310C +:105D800081F8420081F841006748FFF797FF6648B5 +:105D9000401CFFF793FFECF7F9FFBDE8104000F05F +:105DA000B4B8402070475F4800F0A3B80A460146E7 +:105DB0005C48AFE7402070475A48433000F099B83C +:105DC0000A46014657484330A4E7402101700020AD +:105DD000704710B504465348863000F08AF82070AA +:105DE000002010BD0A4601464E4810B58630FFF728 +:105DF00091FF08B1002010BD42F2070010BD70B540 +:105E00000C460546412900D9FFDF48480068103894 +:105E100040B200F050F8C6B20D2000F04CF8C0B20D +:105E2000864203D2FFDF01E0EDF700F82246294663 +:105E30003C48FFF76FFF0028F6D070BD2DE9F04118 +:105E4000394F002506463F1D57F82540204600F0F3 +:105E500041F810B36D1CEDB2032DF5D3314843303A +:105E600000F038F8002825D02E4800F033F800283C +:105E700020D02C48863000F02DF800281AD0ECF7FE +:105E8000ABFF2948FFF722FFB0F5005F00D0FFDF2E +:105E9000BDE8F0412448FFF72FBF94F841004121AD +:105EA000265414F8410F401CB0FBF1F201FB120024 +:105EB0002070D3E751E7002804DB00F1E02090F8E0 +:105EC000000405E000F00F0000F1E02090F8140D50 +:105ED0004009704710F8411F4122491CB1FBF2F301 +:105EE00002FB13114078814201D10120704700204C +:105EF000704710F8411F4078814201D3081A02E030 +:105F0000C0F141000844C0B2704710B50648FFF721 +:105F1000DDFE002803D1BDE81040ECF748BF10BDFE +:105F20000DE000E0FC0A0020B000002004ED00E0DD +:105F300070B5154D2878401CC4B26878844202D0F0 +:105F4000F6F71BF82C7070BD2DE9F0410E4C4FF0A8 +:105F5000E02600BFF6F706F820BF40BF20BF6778F5 +:105F600020786070D6F80052EBF74AFA854305D1E5 +:105F7000D6F8040210B92078B842EBD0F5F7EDFF5F +:105F80000020BDE8F0810000C00000202DE9F041B4 +:105F9000012528034FF0E0210026C1F88001BFF35E +:105FA0004F8FBFF36F8F1F4CC4F800610C2000F0BF +:105FB0002CF81D4801680268C94341F3001142F002 +:105FC00010020260C4F804532560491C00E020BFA1 +:105FD000D4F80021002AFAD019B9016821F0100183 +:105FE0000160124807686560C4F80853C4F800618E +:105FF0000C2000F00AF83846BDE8F08110B50446E0 +:10600000FFF7C4FF2060002010BD002809DB00F06E +:106010001F02012191404009800000F1E020C0F8FA +:106020008012704700C0004010ED00E008C500403D +:106030002DE9F047FF4C0646FF21A06800EB061251 +:1060400011702178FF2910D04FF0080909EB0111D8 +:1060500009EB06174158C05900F0F4F9002807DD94 +:10606000A168207801EB061108702670BDE8F08762 +:1060700094F8008045460DE0A06809EB05114158F1 +:10608000C05900F0DFF9002806DCA068A84600EB44 +:1060900008100578FF2DEFD1A06800EB061100EB8A +:1060A00008100D700670E1E7F0B5E24B04460020E1 +:1060B00001259A680C269B780CE000BF05EB0017C1 +:1060C000D75DA74204D106EB0017D7598F4204D001 +:1060D000401CC0B28342F1D8FF20F0BD70B5FFF77D +:1060E000D6FAD44C08252278A16805EB021289580B +:1060F00000F0A8F9012808DD2178A06805EB01115E +:106100004058BDE87040FFF7B9BAFFF78BF9BDE81A +:106110007040ECF701BF2DE9F041C64C2578FFF740 +:10612000B6FAFF2D6ED04FF00808A26808EB0516EE +:10613000915900F087F90228A06801DD80595DE0DF +:1061400000EB051109782170022101EB0511425C79 +:106150005AB1521E4254815901F5800121F07F410C +:1061600081512846FFF764FF34E00423012203EB4A +:10617000051302EB051250F803C0875CBCF1000F59 +:1061800010D0BCF5007F10D9CCF3080250F806C03F +:106190000CEB423C2CF07F4C40F806C0C3589A1AD6 +:1061A000520A09E0FF2181540AE0825902EB4C3285 +:1061B00022F07F428251002242542846FFF738FFE6 +:1061C0000C21A06801EB05114158E06850F8272028 +:1061D000384690472078FF2814D0FFF758FA2278E5 +:1061E000A16808EB02124546895800F02BF90128F6 +:1061F00093DD2178A06805EB01114058BDE8F0411E +:10620000FFF73CBABDE8F081F0B51D4614460E46D6 +:106210000746FF2B00D3FFDFA00700D0FFDF854834 +:10622000FF210022C0E90247C5700671017042706B +:1062300082701046012204E002EB0013401CE1547E +:10624000C0B2A842F8D3F0BD70B57A4C0646657866 +:106250002079854200D3FFDFE06840F82560607850 +:10626000401C6070284670BD2DE9FF5F1D468B46BF +:106270000746FF24FFF70BFADFF8B891064699F8B6 +:106280000100B84200D8FFDF00214FF001084FF0B5 +:106290000C0A99F80220D9F808000EE008EB011367 +:1062A000C35CFF2B0ED0BB4205D10AEB011350F8A3 +:1062B00003C0DC450CD0491CC9B28A42EED8FF2C81 +:1062C00002D00DE00C46F6E799F803108A4203D19C +:1062D000FF2004B0BDE8F09F1446521C89F802204C +:1062E00008EB04110AEB0412475440F802B00421F1 +:1062F000029B0022012B01EB04110CD040F801207D +:106300004FF4007808234FF0020C454513D9E905F6 +:10631000C90D02D002E04550F2E7414606EB41329A +:1063200003EB041322F07F42C250691A0CEB0412F3 +:10633000490A81540BE005B9012506EB453103EB11 +:10634000041321F07F41C1500CEB0411425499F821 +:1063500000502046FFF76CFE99F80000A84201D0DB +:10636000FFF7BCFE3846B4E770B50C460546FFF7AC +:106370008EF9064621462846FFF796FE0446FF287A +:106380001AD02C4D082101EB0411A8684158304661 +:1063900000F058F800F58050C11700EBD1404013D1 +:1063A0000221AA6801EB0411515C09B100EB412004 +:1063B000002800DC012070BD002070BD2DE9F047F1 +:1063C00088468146FFF770FE0746FF281BD0194D0F +:1063D0002E78A8683146344605E0BC4206D02646F1 +:1063E00000EB06121478FF2CF7D10CE0FF2C0AD03A +:1063F000A6420CD100EB011000782870FF2804D0D1 +:10640000FFF76CFE03E0002030E6FFF73DF9414660 +:106410004846FFF7A9FF0123A968024603EB0413CE +:10642000FF20C854A878401EB84200D1A87001EBE4 +:10643000041001E0C80B002001EB06110078087081 +:10644000104613E6081A0002C11700EB1160001293 +:10645000704700005E48002101704170102181707A +:10646000704770B5054616460C460220ECF730FA28 +:106470005749012008705749F01E086056480560CA +:10648000001F046070BD10B50220ECF721FA5049DE +:106490000120087051480021C0F80011C0F8041113 +:1064A000C0F808114E494FF40000086010BD48487C +:1064B0000178D9B14B4A4FF4000111604749D1F836 +:1064C00000310022002B1CBFD1F80431002B02D078 +:1064D000D1F8081119B142704FF0100104E04FF0EB +:1064E0000101417040490968817002704FF000005D +:1064F000ECF7EEB910B50220ECF7EAF934480122C6 +:10650000002102703548C0F80011C0F80411C0F82D +:106510000811026010BD2E480178002904BF4078A0 +:1065200070472E48D0F80011002904BF02207047A0 +:10653000D0F8001100291CBFD0F80411002905D0A3 +:10654000D0F80801002804BF0120704700207047E0 +:106550001F4800B50278214B4078C821491EC9B2B6 +:1065600082B1D3F800C1BCF1000F10D0D3F8000104 +:1065700000281CBFD3F8040100280BD0D3F8080171 +:1065800050B107E0022802D0012805D002E000291E +:10659000E4D1FFDF002000BD012000BD0C480178E0 +:1065A000002904BF807870470C48D0F800110029FA +:1065B0001CBFD0F80411002902D0D0F8080110B196 +:1065C0004FF01000704708480068C0B270470000E4 +:1065D000C200002010F5004008F5004000F0004027 +:1065E00004F5014008F5014000F400405648002140 +:1065F00001704170704770B5064614460D46012083 +:10660000ECF766F951480660001D0460001D056046 +:106610004F490020C1F850014E49032008604F49FE +:106620004D480860091D4E48086070BD2DE9F041D5 +:10663000054645480C46012606704A4945EA02408F +:1066400040F0807008600EF034F8002804BF46481F +:1066500004600027454CC4F804714649444808606A +:10666000002D02BFC4F800622660BDE8F081012D54 +:1066700018BFFFDFC4F80072266040493E4808603A +:10668000BDE8F0813048017871B13A4A384911606B +:106690003649D1F804210021002A08BF417002D0F8 +:1066A000374A1268427001700020ECF711B9264891 +:1066B0000178002904BF407870472C48D0F80401C5 +:1066C000002808BF70472E480068C0B270470028F5 +:1066D00008BF704730B51C480078002808BFFFDFAE +:1066E0002248D0F80411002918BF30BD0224C0F898 +:1066F0000443DFF890C0DCF80010C1F30015DCF8AB +:10670000001041F01001CCF80010D0F8041100295D +:1067100004BF4FF400414FF0E02206D1C2F88012CE +:1067200020BFD0F80431002BF8D02DB9DCF80010D0 +:1067300021F01001CCF80010C0F8084330BD0B491F +:106740000120886070470000C500002008F5004067 +:10675000001000401CF500405011004098F5014029 +:106760000CF0004004F5004018F5004000F0004037 +:106770000000020308F501400000020204F5014098 +:1067800000F4004010ED00E010B5FF4800240121A6 +:106790004470047044728472C17280F82540C462EF +:1067A000846380F83C4080F83D40FF2180F83E1033 +:1067B00018300FF0DFF8F549601E0860091D086009 +:1067C000091D0C60091D0860091D0C60091D086089 +:1067D000091D0860091D0860091D0860091D086081 +:1067E000091D0860091D0860091D0860091D086071 +:1067F00010BDE748016801F00F01032904BF012023 +:106800007047016801F00F01042904BF022070479E +:10681000016801F00F01052904D0006800F00F00A5 +:10682000062807D1DB48006810F0060F0CBF0820CF +:106830000420704700B5FFDF012000BD10B5D24C29 +:106840000168A1614168E161007A84F82000207E3E +:1068500048B1207FF7F7F3FCA07E011C18BF01218F +:10686000207FF7F7DBFC607E002808BF10BD607F4B +:10687000F7F7E5FCE07E011C18BF0121607FBDE851 +:106880001040F7F7CBBC30B50024054601290AD0EB +:10689000022908BF4FF0807405D0042916BF0829CB +:1068A0004FF0C744FFDF44F4847040F48010BA49CD +:1068B000086045F4403001F1040140F000700860C8 +:1068C00030BD30B50024054601290AD0022908BF91 +:1068D0004FF0807405D0042916BF08294FF0C74433 +:1068E000FFDF44F4847040F48010AB49086045F445 +:1068F000403001F1040140F000700860A748D0F872 +:106900000001002818BFFFDF30BD2DE9F04102274C +:106910004FF0E02801260024C8F88071BFF34F8FA4 +:10692000BFF36F8F9E48046006600DF0ECFE9D4D36 +:1069300018B1286840F4806028600DF0BAFE38B1C4 +:10694000286820F0770040F0880040F00040286080 +:10695000964995480860964940F25B600860091FB7 +:1069600040F203100860081F066089490320086090 +:1069700090480660914A90491160924A904911608E +:10698000121F91491160016821F440710160016892 +:1069900041F480710160C8F8807280491020C1F80C +:1069A0000403794880F83140C462BDE8F081764A3A +:1069B0000368C2F802308088D08011727047724B31 +:1069C00010B51A7A8A4208D101460622981C0EF0A8 +:1069D000F5FD002804BF012010BD002010BD6A484D +:1069E00090F825007047684A517010707047F0B5F4 +:1069F0000546800000F1804000F580508B88C0F88B +:106A000020360B78D1F8011043EA0121C0F80016B6 +:106A100005F10800012707FA00F66C4C002A04BFB4 +:106A20002068B04304D0012A18BFFFDF206830433C +:106A30002060206807FA05F108432060F0BD0EF0E1 +:106A400069B9514890F832007047614AC1781160C5 +:106A500000686049000208607047252808BF0221CD +:106A60000ED0262808BF1A210AD0272808BF502197 +:106A700006D00A2894BF0422062202EB4001C9B2C4 +:106A8000554A11605549086070472DE9F041434E61 +:106A9000804603200D46C6F800025249504808605F +:106AA00028460EF076F9384F0124B8F1000F04BFE4 +:106AB000BC72346026D0B8F1010F23D14A48006877 +:106AC00060B915F00C0F09D0C6F80443012000F09E +:106AD000F0FEF463346487F83C4002E0002000F0EC +:106AE000E8FE28460EF03DFA0220B8720DF0F9FDDE +:106AF00038B90DF008FE20B93C48016841F4C021C6 +:106B0000016074603A48C4643A4800682946BDE8A8 +:106B1000F04100F072BE2DE9F047204E814603207F +:106B20000D46C6F80002DFF8BC802D48C8F800000A +:106B300008460EF02EF928460EF013FA0124124FE3 +:106B4000B9F1000F03D0B9F1010F0AD060E0BC72B7 +:106B5000B86B40F48010B8634FF48010C8F80000A0 +:106B600056E00220B872B86B40F40010B8634FF4DE +:106B70000010C8F800001C480068E8BB15F00C0FB6 +:106B800043D0C6F8044338E0D80B0020000E004084 +:106B9000101500401414004014150040001000406F +:106BA000FC1F00403C1700402C0000897817004073 +:106BB000381500405016004000000C0408F5014054 +:106BC00040800040A4F501401011004040160040F4 +:106BD000241500401C1500400815004054150040C5 +:106BE0000000040404F501408817004068150040C7 +:106BF000008000404C85004007E0012000F059FE75 +:106C0000F463346487F83C4002E0002000F051FE59 +:106C1000ECF73CF82946BDE8F04700F0EEBD2DE961 +:106C2000F84FFA4C8246032088461746C4F8000203 +:106C3000DFF8E093F648C9F8000010460EF0A9F816 +:106C4000DFF8D4B3F54E0125BAF1000F04BFCBF83D +:106C50000040B57204D0BAF1010F18BFFFDF2FD08A +:106C6000EF48C0F80080F049EE480860B06B40F48F +:106C70000020B063D4F800321021C4F808130020BB +:106C8000C4F80002DFF8A4C38A03CCF80020C4F8DB +:106C90000001C4F80C01C4F81001C4F80401C4F8E0 +:106CA0001401C4F81801E24800680090C4F80032EA +:106CB000C9F80020C4F80413BAF1010F09D01BE091 +:106CC00038460EF04EF9DB48CBF800000220B072D7 +:106CD000C6E7D948006860B917F00C0F09D0C4F8AE +:106CE0000453012000F0E5FDE563256486F83C507F +:106CF00002E0002000F0DDFD4FF40020C9F80000A4 +:106D0000CE48C564CE480068404528BFFFDF3946FD +:106D10004046BDE8F84F00F070BD2DE9F041BF4C92 +:106D20000646002594F8310017468846002808BF1B +:106D3000FFDF16B1012E16D021E094F831000128B2 +:106D400008D094F83020394640460EF037F8E16A12 +:106D5000451814E094F830103A4640460EF06CF8AE +:106D6000E16A45180BE094F8310094F830100128DE +:106D70003A46404609D00EF087F8E16A45183A468F +:106D800029463046BDE8F04149E70EF037F8E16AA0 +:106D90004518F4E72DE9F84F9C4CD4F8000220F098 +:106DA0000B09D4F804034FF0100AC0F30018C4F81C +:106DB00008A30026C4F800629C48A2490160974DD0 +:106DC0000127A97A012902D0022903D015E0297EE2 +:106DD00011B912E0697E81B1A97FEA7F07FA01F15A +:106DE00007FA02F21143016095F82000800000F1DB +:106DF000804000F5C040C0F81065FF208DF800000D +:106E0000C4F81061276104E09DF80000401E8DF871 +:106E100000009DF8000018B1D4F810010028F3D04C +:106E20009DF80000002808BFFFDFC4F810610020B3 +:106E300000F03FFD6E72AE72EF72C4F80092B8F1CE +:106E4000000F18BFC4F804A3BDE8F88FFF2008B5F1 +:106E50008DF800006D480021C0F81011012101617A +:106E600005E000BF9DF80010491E8DF800109DF848 +:106E7000001019B1D0F810110029F3D09DF80000CE +:106E8000002808BFFFDF08BD00686F4920F07F4081 +:106E9000086070474FF0E0200221C0F8801100F533 +:106EA000C070BFF34F8FBFF36F8FC0F800117047F2 +:106EB0004FF0E0210220C1F80001704763490870DB +:106EC000704763490860704770B50546EBF7DEFE12 +:106ED000524C2844E16A884298BFFFDF01202074A9 +:106EE000EBF7D4FE554A284400216061C2F84411F2 +:106EF00058490860A06B474940F48000A063D00166 +:106F0000086070BD70B5454C0546534A0220207498 +:106F100010680E4600F00F00032808BF012213D0AE +:106F2000106800F00F00042808BF02220CD010687F +:106F300000F00F0005281BD0106800F00F00062895 +:106F40001CBFFFDF012213D094F8310094F83010F9 +:106F5000012815D028460DF0DEFF38496061002079 +:106F6000C1F844016169E06A08443A49086070BDAB +:106F70003A48006810F0060F0CBF08220422E3E72D +:106F8000334628460DF095FFE7E728494FF4800087 +:106F900008602248816B21F4800181630021017423 +:106FA0007047C20002F1804202F5F8322C4BC2F861 +:106FB0001035C2F8141501218140164801601748A8 +:106FC000826B1143816370471C4801214160C1609D +:106FD0000021C0F844111F4801601048C162704789 +:106FE000204908600948D0F8001241F04001C0F87B +:106FF000001270470548D0F8001221F04001C0F897 +:10700000001218490020086070470000001000407E +:107010000000040404F50140ACF50140D80B002049 +:107020004885004048810040A8F5014008F501402E +:1070300018110040041000408817004000800040F4 +:107040004C85004000000C043C150040C7000020A7 +:107050000415004044850040101500401414004001 +:107060000411004060150040FE48D0F8001221F0E5 +:107070001001C0F80012012181617047FA49FF2018 +:1070800081F83E00F7480021C0F81C11D0F800122A +:1070900041F01001C0F800127047F24981B0D1F8F8 +:1070A0001C21012A0DD0F04991F83E10FF290DBF97 +:1070B00000204942017001B008BF7047012001B0B3 +:1070C0007047EA4A126802F07F02524202700020C2 +:1070D000C1F81C01E64800680090EFE7F0B51746DC +:1070E0000C00064608BFFFDFDF4D14F0010F2F73C1 +:1070F0001CBF012CFFDF002E0CBF01200220687294 +:10710000EC7201281CBF0228FFDFF0BD2DE9F84F0B +:10711000DFF860A39AF80000042828BFFFDFD24CF4 +:10712000DFF85483CF4D94F83C0000260127E0B1EE +:10713000D5F8040110F1000918BF4FF00109D5F886 +:107140001001002818BF012050EA09014FF4002B5C +:1071500017D08021C5F80813C8F800B084F83C6047 +:1071600090F0010F18BFBDE8F88FDFF81093D9F841 +:107170004C0100287DD0A07A01287BD002287AD04B +:10718000A6E0D5F80001DFF8E4A218B3C5F8006165 +:107190006F61FF20009002E0401E009005D0D5F8FE +:1071A0001C0100280098F7D000B9FFDFDAF80000D2 +:1071B00000F07F0ABAF15F0F84BF002000F079FB76 +:1071C00084F83EA0C5F81C61C5F80873A84800689B +:1071D000009002E0B9F1000F03D0B9F1000F27D001 +:1071E00058E0DAF8000000F07F0084F83E00C5F8AF +:1071F0001C6194F83D1039B15F2816D9002000F0C9 +:1072000058FB2F64AF6310E09D4909688AB2090CEE +:107210005F2803D30F2A06D9022904D2012000F0E7 +:1072200048FB2F6401E02F64AF6391480068009031 +:107230008022C5F80423914887649249D1F800C0A0 +:107240000B1F1B6843F69827BC449C4519D20A685B +:1072500042F210731A440A60C0F848618B498A48A8 +:107260000860091F8A4808608A48C0F800B0A06B0F +:1072700002E02DE015E017E040F40020A063BDE837 +:10728000F88F0E60C0F84861C5F80823C8F800B050 +:10729000C0F848618020C5F80803C8F800B0BDE810 +:1072A000F88F207E10B913E0607E88B1A07FE17F67 +:1072B00007FA00F007FA01F10843C8F8000094F853 +:1072C0002000800000F1804000F5C040C0F810654B +:1072D0006948A16B0160A663217C002019B1D9F82F +:1072E0004411012900D00021A27A012A6ED0022A7D +:1072F00074D000BFD5F8101101290CBF1021002156 +:1073000041EA00086448016811F0FF0F03D0D5F886 +:107310001411012900D0002184F83210006810F007 +:10732000FF0F03D0D5F81801012800D0002084F801 +:1073300033005A48006884F83400FFF7ECF801285D +:1073400018BF002084F83500C5F80061C5F80C614D +:10735000C5F81061C5F80461C5F81461C5F8186175 +:107360004F48006800904548C0F844614D480068A7 +:10737000DFF834910090D9F80000A062A9F1040070 +:107380000068E0624948016801F00F01032908BF65 +:10739000012013D0016801F00F01042908BF022069 +:1073A0000CD0016801F00F01052926D0006800F01B +:1073B0000F0006281CBFFFDF01201ED084F830001C +:1073C000A07A84F8310002282CD11EE0D5F80C01F7 +:1073D000012814BF002008208CE7FFE7D5F80C0136 +:1073E000012814BF00200220314A1268012A14BF6C +:1073F00004220022104308437CE72E48006810F066 +:10740000060F0CBF08200420D8E7607850B12A4945 +:10741000096809780840217831EA000008BF84F83B +:10742000247001D084F8246018F0020F0AD0EBF722 +:107430002DFCA16A214A081A9AF80010490852F84E +:107440002110884718F0010F18BF4FF0000B41D0F2 +:10745000EBF71CFCE16A9AF80020081A184951F869 +:1074600022202FE000100040D80B002048150040DB +:107470001C110040C700002008F5014000800040BA +:10748000741500404885004014100040ACF50140E0 +:107490004881004004F501404016004010140040AF +:1074A0001811004044810040448500401015004000 +:1074B000001400401414004004150040945C0200C5 +:1074C000DC5C0200594690479AF8000010F0010F6A +:1074D0002FD10CE018F0020F18BF4FF0010BB7D1FD +:1074E00018F0080F18BF4FF0020BB1D1ECE7DFF82E +:1074F00004B4DBF80000007800F00F00072828BF74 +:1075000084F8256015D2DBF80000062200F109019D +:10751000A01C0EF053F840B9207ADBF8001009786F +:10752000B0EBD11F08BF012001D04FF0000084F85C +:107530002500E17A4FF0000011F0020F1CBF18F097 +:10754000020F18F0040F19D111F0100F1CBF94F89E +:107550003320002A02D094F835207AB111F0080FB8 +:107560001CBF94F82420002A08D111F0040F02D087 +:1075700094F8251011B118F0010F01D04FF001005F +:10758000617A19B168B1FFF705FC10E0DB48DA4910 +:107590000160D5F8000220F00300C5F80002E77290 +:1075A00005E001290DD0022918BFFFDF10D018F027 +:1075B000010F17D0D2489AF8001050F821008047E8 +:1075C00056E06672E772A7729621227B002006E0E1 +:1075D0006672E7720220A072227B96210120FFF7DB +:1075E0009CFBE4E718F0020F2DD018F0040F21D116 +:1075F0000DF077F8F0B90DF086F8D8B9C1480168F8 +:10760000001F0068C0F3006CC0F3425500F00F0388 +:10761000C0F30312C0F30320BCF1000F0AD0002B0B +:107620001CBF002A002805D1002918BF032D38BF30 +:1076300048F0040827EA9800B3499AF8002051F866 +:107640002210884714E018F0080F06D0AF489AF8C7 +:10765000001050F8210080470AE018F0100F08BF12 +:10766000FFDF05D0AA489AF8001050F821008047A3 +:10767000A07A022818BFBDE8F88F207C002808BF38 +:10768000BDE8F88FA349C1F84461022814D001284D +:1076900018BFFFDFE16A6069884298BFFFDF606959 +:1076A000C9F80000A06B4FF4800140F48000A06393 +:1076B00099480160BDE8F88F6169E06A0844EFE726 +:1076C0000021964A81B0002818BFC2F80012C2F803 +:1076D0000011C2F80C11C2F81011C2F80411C2F85E +:1076E0001411C2F818118E480068009001B070475C +:1076F000012804BF28207047022804BF18207047C3 +:10770000042812BF08284FF4A870704700B5FFDFA7 +:10771000282000BD012804BF41F6A470704702284C +:1077200004BF41F288307047042804BF46F21800B5 +:107730007047082804BF47F2A030704700B5FFDF4C +:1077400041F6A47000BD10B502280DD0012804BF79 +:1077500042F6CE3010BD042817BF082843F6A440D7 +:10776000FFDF41F66A0010BD0CF096FF30B90CF057 +:10777000A0FF002808BF41F6583001D041F2643024 +:1077800041F29A01084410BD012812BF02280020CE +:107790007047042812BF08284FF4C870704700B51E +:1077A000FFDF002000BD5D490820C1F800025349F9 +:1077B000514808605C495B480860091D5B480860E7 +:1077C000091D5B480860091D5A48086052494FF47A +:1077D0004020086070475848016803291BBF0068B3 +:1077E0000228012000207047534801680B291BBF65 +:1077F00000680A2801200020704750498A7A012A2F +:1078000049D0022A18BF70474B7E002B08BF704733 +:10781000012A44D0CB7E4A7F13F1000C18BF4FF0F1 +:10782000010C24231844464B18603A4B0020C3F83F +:107830004C0110028CF0010240EA025040F00312A9 +:1078400091F82000830003F1804303F5C043C3F89F +:1078500010253C4A8B7F02EB8000DA0002F1804267 +:1078600002F5F832C2F81405DFF8DCC0C2F810C522 +:10787000C97FCA0002F1804202F5F832C2F814054D +:107880003248C2F81005012000FA03F2884022496C +:107890001043086070470B7E002BB9D170478B7E78 +:1078A0000A7F002B14BF4FF0010C4FF0000C112386 +:1078B000B8E727490968C9B9264A2749136870B14A +:1078C00023F0820343F07D0343F0004313600A6812 +:1078D00022F0100242F0600242F0004205E023F084 +:1078E000004313600A6822F000420A60134981F8DD +:1078F0003D007047041500400000040408F50140F5 +:107900009C5C020054140040AC5C0200BC5C0200B1 +:10791000CC5C02000080004004F5014000100040F3 +:107920001811004000110040A0F501401410004063 +:107930001C1100401010004050150040D80B0020D2 +:107940004C850040006000404C8100401011004018 +:10795000881700403C1700407C17004010B53F4896 +:1079600022210DF0D6FE3D480024017821F01001BF +:107970000170012106F018F839494FF6FF7081F8BF +:107980002240888437490880488010BD70473449B8 +:107990008A8C824218BF7047002081F822004FF67F +:1079A000FF70888470472D49016070472D49088019 +:1079B00070472B498A8CA2F57F43FF3B03D00021FF +:1079C00001600846704791F822202549012A1ABF14 +:1079D0000160012000207047214901F1220091F847 +:1079E0002220012A04BF00207047012202701D4896 +:1079F00000888884104670471A49488070471849A3 +:107A0000184B8A8C5B889A4206D191F82220002A72 +:107A10001EBF016001207047002070471048114AC6 +:107A2000818C5288914209D14FF6FF71818410F800 +:107A3000221F19B1002101700120704700207047FA +:107A40000748084A818C5288914205D190F822005B +:107A500000281CBF00207047012070473E0C00200A +:107A6000180C0020C80000207047574A012340B17D +:107A7000012818BF7047137008689060888890814B +:107A8000704753700868C2F802008888D080704739 +:107A90004D4A10B1012807D00EE0507860B1D2F8FD +:107AA00002000860D08804E0107828B1906808606F +:107AB000908988800120704700207047424910B1AA +:107AC000012803D006E0487810B903E0087808B12F +:107AD000012070470020704730B58DB00C46054638 +:107AE0000D2104A80DF037FEE0788DF81F002079F5 +:107AF0008DF81E0060798DF81D0028680090686878 +:107B00000190A8680290E868039068460CF02CFC8D +:107B100020789DF82F1088420CD160789DF82E10A7 +:107B2000884207D1A0789DF82D10884202BF01201D +:107B30000DB030BD00200DB030BD30B50C4605464F +:107B40008DB04FF0030104F1030012B1FEF738F9D4 +:107B500001E0FEF754F960790D2120F0C00040F0FB +:107B60004000607104A80DF0F6FDE0788DF81F006C +:107B700020798DF81E0060798DF81D00286800902E +:107B800068680190A8680290E868039068460CF065 +:107B9000EBFB9DF82F0020709DF82E0060709DF883 +:107BA0002D00A0700DB030BD10B5002904464FF077 +:107BB000060102D0FEF704F901E0FEF720F9607932 +:107BC00020F0C000607110BDCC000020FE4840686D +:107BD00070472DE9F0410F46064601461446012044 +:107BE00005F0ABFA054696F85500FFF793FD4AF20B +:107BF000B12108444FF47A71B0FBF1F0718840F282 +:107C000071225143C0EB4100001BA0F2653403F028 +:107C10001FF8002818BF1E3CAF4234BF2846384624 +:107C2000A04203D2AF422CBF3C462C467462BDE852 +:107C3000F0812DE9FF4F95B0044690F85500894634 +:107C40001190DDE9171008431390E04800260578ED +:107C50000C2D28BFFFDFDE4F37F8158094F86C51EC +:107C60000C2D28BFFFDFDA4830F8150040441FFA1A +:107C700080F894F865000D280CBF012000200C90BE +:107C80001798002804BF94F80C0103282BD10C98F6 +:107C900048B3B4F88E01484525D1D4F81401C4F88E +:107CA0000001608840F2E2414843C4F80401B4F89E +:107CB0005A01B4F8E6100844C4F80801204602F05E +:107CC000D1FFB4F89201E08294F890016075B4F8A5 +:107CD00094016080B4F89601A080B4F89801E08027 +:107CE000022084F80C01D4F864011090D4F86001EB +:107CF0000F90B4F8E670B4F85801D4F85411089114 +:107D0000179921B194F8201151B100F0DDB804F1B8 +:107D1000E001039174310D9104F5A075091D07E090 +:107D200004F59A710391091D0D9104F59275091DD1 +:107D30000E91B4F85810A9EB0000A9EB01010FFA5D +:107D400080FA0FFA81FBBAF1000F05DAD4F850017E +:107D500008900120DA461390002002909B48007999 +:107D6000E8B3F3F7A5FFD0B3B4F8F800022836D390 +:107D700094F80C01022832D094F8230178BB94F8CF +:107D80006C81B8F10C0F28BFFFDF914830F8180064 +:107D900000F5C8601FFA80F894F80C0101287DD026 +:107DA000618840F2E24041430020B8F1000F05D065 +:107DB000884808FB01F1B1FBF0F0401C07EB0B0118 +:107DC000A1EB0A02D4F8141180B2431A029902FB03 +:107DD00003110291C4F81401012084F8230194F8DE +:107DE0000C01002874D0012800F04682022800F01F +:107DF0009481032818BFFFDF00F078820298311ABF +:107E00000898FCF704FC0D99012640F271220860E5 +:107E10000E98A0F80090002028702E710D98006830 +:107E2000A8606188D4F814015143C0EB4100674950 +:107E3000A0F23530C8618969814287BF0399086023 +:107E4000039801600398616A0068084400F2A51075 +:107E5000E86002F0FDFE10B1E8681E30E8606E7167 +:107E6000B4F8D000A0EB090000B20028C4BF032082 +:107E700068710C980028189800F09A82D8B100BF59 +:107E8000B4F8F81000290CBF0020B4F8FA00A4F8E8 +:107E9000FA0094F8FC20401C504300E019E08842AE +:107EA00009D26879401E002805DD6E71B4F8FA0029 +:107EB000401CA4F8FA001798002800F0A18294F85A +:107EC0002001002800F0988219B00220BDE8F08F50 +:107ED00065E094F86800032857D03B4894F85510A3 +:107EE00090F8300005F0D7FAE18A40F27122514350 +:107EF00000EB41010020D4F80421B8F1000F06D0B6 +:107F0000344808FB02F2B2FBF0F000F10100D4F8B3 +:107F10000031D4F80821A0EB030C029BC4F8000147 +:107F200002FB0C334FF0000007D000BF294808FBCC +:107F300001F1B1FBF0F000F10100D4F81011C4F828 +:107F40001001A0EB01011944608840F2E24300FBFC +:107F500003F34FF0000006D01E4808FB03F3B3FB09 +:107F6000F0F000F1010007EB0B03A3EB0A03A3EB16 +:107F70000202D4F81431A2F10102A0EB030302FBC8 +:107F800003110291C4F8140126E7E18A40F271223C +:107F9000D4F8040101FB02F100EB4101AAE70F98BC +:107FA000002808BFFFDF94F85510074890F830000C +:107FB00005F071FA0790E18A40F271204143079879 +:107FC00000EB4101002007E0600C0020DC000020F5 +:107FD000EC5C020040420F00B8F1000F07D000BF78 +:107FE000FF4808FB01F1B1FBF0F000F10100C4F81B +:107FF0001001618840F2E24001FB00F14FF0000007 +:1080000006D0F74808FB01F1B1FBF0F000F10100E8 +:10801000C4F8140186B221464FF00100D4F828A01C +:1080200005F08BF8074694F85500FFF773FB4AF20A +:10803000B12B58444FF47A78B0FBF8F0618840F2E5 +:1080400071225143C0EB4100801BA0F2653602F063 +:10805000FFFD002818BF1E3EBA4534BF38465046C3 +:10806000B04203D2BA452CBF56463E46666294F8EB +:108070005500FFF789FB00F2E140B0FBF8F10F98E3 +:108080000E1894F85500FFF77FFB074694F855004B +:10809000FFF740FB38444AF2AB310844B0FBF8F13B +:1080A000E28A40F2712042430798D4F8107100EB45 +:1080B0004200401AC01B3044A0F12006617D40F20E +:1080C000E24011FB00FA94F85500009010F00C0FFC +:1080D0000ABF00984EF62830FFF71CFB5844B0FB4F +:1080E000F8F000EB470000EB0A070098FFF700FBF1 +:1080F000384400F16201BB48816194F85500FFF7F4 +:1081000043FB00F2E140B0FBF8F10F980844301A4D +:10811000B0F53D7F98BFFFDF70E6E18A40F2712243 +:10812000D4F80401514300EB41010020B8F1000FE5 +:1081300007D000BFAA4808FB01F1B1FBF0F000F145 +:108140000100C4F81001608840F2E24100FB01F137 +:108150004FF0000006D0A24808FB01F1B1FBF0F09F +:1081600000F10100C4F8140186B221464FF001006D +:10817000D4F828A004F0E1FF804694F85500FFF7FA +:10818000C9FA4AF2B12B00EB0B014FF47A70B1FB44 +:10819000F0F0618840F271225143C0EB4100801B36 +:1081A000A0F2653602F054FD002818BF1E3EC245FD +:1081B00034BF40465046B04203D2C2452CBF56465B +:1081C000464666620FBB1898F8B194F85560304681 +:1081D000FFF7A0FA00EB0B014FF47A70B1FBF0F05F +:1081E000D4F81011E38A084440F27122D4F8041143 +:1081F0005A4301EB42010F1A3046FFF779FA109902 +:10820000081A3844A0F120060AE0E18A40F27122FF +:10821000D4F80401514300EB4100D4F81011461A80 +:10822000D4F80821D4F80011D4F8100101FB020A97 +:10823000607D40F2E24110FB01F894F8557017F0B0 +:108240000C0F0ABF38464EF62830FFF763FA00EBF2 +:108250000B014FF47A70B1FBF0F000EB4A00804460 +:108260003846FFF745FA404400F160015D488161FE +:10827000012084F80C01C1E5618840F2712251436C +:10828000D4F81401D4F80821C0EB410101FB0AF62F +:1082900007EB0B01891AD4F800C1D4F81031491E3C +:1082A0000CFB023201FB002A607D40F2E24110FB30 +:1082B00001F894F8557017F00C0F0ABF38464EF6C7 +:1082C0002830FFF727FA4AF2B12101444FF47A70BF +:1082D000B1FBF0F000EB4A0080443846FFF708FAA3 +:1082E000404400F160013F48816187E5628840F2C7 +:1082F0007121D4F814015143C0EB410000FB0AF690 +:1083000094F8640024281CBF94F8650024280BD13D +:10831000B4F88E01A9EB000000B2002804DB94F849 +:108320009101002818BF1190139800B3FFB910985D +:1083300000281ABF0F980028FFDF94F8550010F0AE +:108340000C0F14BF4EF62830FFF7E4F94AF2B121C2 +:1083500001444FF47A70B1FBF0F0361A94F85500EE +:10836000FFF7C6F91099081A3044A0F12006D4F896 +:10837000141107EB0B0000FB01F7119810F00C0F24 +:108380000ABF11984EF62830FFF7C4F94AF2B1211E +:1083900001444FF47A70B1FBF0F000EB47071198FD +:1083A000FFF7A6F9384400F160010E48816125E528 +:1083B00000287FF465AD94F80C0100283FF47BADF4 +:1083C000618840F27122D4F814015143C0EB41019D +:1083D000284604F0B7FD0004000C3FF46CAD03E048 +:1083E00040420F00DC0000202299002918BF0880BD +:1083F000012019B0BDE8F08F94F85C01FCF762FF32 +:1084000094F85C012946FCF74BFE20B1179880F0E8 +:10841000010084F8210119B00020BDE8F08F70B58B +:10842000FE4C607A00281CBF002070BD94F8340018 +:1084300038B1A16B606A884203D9F7F72AF90020A6 +:1084400070BDA06AE8B1F6F7BCF90546F6F730F85A +:10845000284442F210714618FCF7D8FB054629461D +:10846000E06AFDF7EFF8E562A16A8219914224BF44 +:10847000081AA06205D20120A062F7F70AF90020CD +:1084800070BD012070BDF8B5E44C0246E44F0025F4 +:108490006168606A052A48D2DFE802F0032F3437AA +:1084A0003E00A07A002660B101216846FDF788FCF5 +:1084B0009DF8000042F210710002B0FBF1F201FBE6 +:1084C0001206F6F77EF98119A069FCF7A0F8A06101 +:1084D000257403206075607A38B9207B04F110019F +:1084E000FCF7DEFD002808BFFFDF2584FCF798FAC3 +:1084F0007879BDE8F840EAF70FBDBDE8F840002103 +:1085000000F0B5BDC1F86001F8BDD1F86001BDE86B +:10851000F840012100F0ABBD84F83450FCF780FA3C +:108520007879BDE8F840EAF7F7BCFFDFF8BD2DE940 +:10853000F04FDFF8E892044683B099F800008B46CC +:1085400001270025B64E4FF00208032804BF99F812 +:108550000C00A0427ED1D9F80400706199F80000A7 +:10856000032818BFFFDF0324BBF1080F73D2DFE835 +:108570000BF0040F31312CD1D1C8C9F82450F6F7D3 +:10858000F7FC002818BFFFDFB47003B0BDE8F08F20 +:10859000F5F78EFF0446D9F81C00A04228BFC9F8A1 +:1085A0001C4005D2201AFDF774F8C9F81C4038B1F8 +:1085B000F7F757F8002818BFFFDF03B0BDE8F08FCA +:1085C00003B00020BDE8F04F5DE703B0BDE8F04F19 +:1085D000FEF79CBD89F8144089F8105099F83400D2 +:1085E0004FF0010A42F2107B68B14FF47A71D9F86A +:1085F0001800FCF70CF8C9F81800002109F1100068 +:1086000004F0A0FC1BE001216846FDF7CFFB9DF8BC +:1086100000000002B0FBFBF10BFB110AF6F7D1F8EA +:1086200082445146D9F81800FBF7F1FFC9F8180049 +:10863000514609F1100004F085FC00F1010AB9F877 +:108640002000411C0A293CBF5044A9F82000D9F859 +:10865000040001E062E05DE038B1B9F82000401CA0 +:108660000A2828BF89F8158001D289F8154099F8A1 +:10867000090070BB99F8340040B1D9F83810D9F826 +:108680002400884202D9F7F704F822E0D9F828003C +:1086900058B3F6F796F80446F5F70AFF204400EBC6 +:1086A0000B08FCF7B3FA04462146D9F82C00FCF776 +:1086B000C9FFC9F82C40D9F8281000EB08029142F4 +:1086C00024BF081AC9F828000FD2C9F82870F6F795 +:1086D000E0FF99F80C00FCF77AFA89F800507079FD +:1086E00003B0BDE8F04FEAF717BC99F80C0009F1A8 +:1086F0001001FCF7D5FC002808BFFFDF03B0BDE880 +:10870000F08F99F80C00FCF762FA89F8005003B07A +:10871000BDE8F08FFFDF03B0BDE8F08F202C28BF4D +:10872000FFDFDFF80091072139F81400FAF72CF980 +:108730005FEA000A08BFFFDF202C28BFFFDF39F8FF +:108740001400BAF80010884218BFFFDF5446C6F87C +:1087500014A04FF0200ABBF1080F80F04881DFE839 +:108760000BF0049DA7A7A0F2F1F0C4F86051F580CA +:10877000C4F8645194F8210138B9FCF747FAD4F8E9 +:108780002C11FCF75FFF00281BDCB4F81E11B4F8B5 +:108790005800814206D1B4F8D410081AA4F8D600C3 +:1087A000204605E0081AA4F8D600B4F81E112046A9 +:1087B000A4F85810D4F84811C4F82C11C0F850117E +:1087C0001DE0B4F81C11B4F85800081AA4F8D6003B +:1087D000B4F81C112046A4F85810D4F82C11C4F891 +:1087E0004811C4F85011D4F83411C4F8E010D4F88A +:1087F0003811C4F85411B4F83C11A4F8581102F01F +:108800000EF9FCF7DDF9814694F85500FEF782FF7A +:108810004AF2B12108444FF47A7105E0600C00205F +:10882000DC0000209C0C0020B0FBF1F0D4F8141107 +:1088300040F27122084461885143C0EB4100A0F12D +:10884000300AB9F1B70F98BF4FF0B70921460120A0 +:1088500004F073FC4844AAEB0000A0F21A39A246C7 +:108860002146012004F069FCDAF824109C30814292 +:1088700088BF0D1AC6F80C904D4528BF4D46B5600F +:10888000D4F84C01A0F2A5103061FCF7A8FE84F8E2 +:10889000207186F8028003B0BDE8F08F02F0D3F9B2 +:1088A00001E0FEF733FC84F8207103B0BDE8F08FDF +:1088B000FCF7ACF9D4F8502101461046FCF7C2FE93 +:1088C00048B1628840F27123D4F814115A43C1EBC5 +:1088D0004201B0FBF1F094F865100D290FD0B4F807 +:1088E0005820B4F81E1113189942AEBF481C401C02 +:1088F0001044A4F81E0194F8220178B905E0B4F8F8 +:108900001E01401CA4F81E0108E0B4F81E01B4F8D2 +:10891000D410884204BF401CA4F81E01B4F85A01C8 +:108920000DF1040B401CA4F85A01B4F88000B4F80F +:108930007E10401AB4F85810401E08441FFA80F800 +:1089400012E046E03EE052E000231A462046CDF811 +:1089500000B0FFF76EF9002804BF03B0BDE8F08F48 +:10896000012818BFFFDF25D0B4F81E11A8EB0100C5 +:1089700000B20028E8DA082084F8740084F87370E4 +:10898000204601F00FFE84F80C5194F85C514FF62C +:10899000FF77202D00D3FFDF29F8157094F85C01D4 +:1089A000FCF715F984F85CA1707903B0BDE8F04FCD +:1089B000EAF7B2BAB4F81E01BDF804100844A4F8EE +:1089C0001E01D1E7FEF742FA03B0BDE8F04FFEF713 +:1089D0009DBB94F80C01042818BFFFDF84F80C51EC +:1089E00094F85C514FF6FF77202DD5D3D3E7FFDF06 +:1089F00003B0BDE8F08F10B5F84C207850B10120DD +:108A00006072F6F75EFE2078032805D0207A0028F1 +:108A100008BF10BD0C2010BD207BFCF753FC207B51 +:108A2000FCF79DFE207BFCF7D2F8002808BFFFDF93 +:108A30000020207010BD2DE9F04FE84F83B038784A +:108A400001244FF0000840B17C720120F6F739FE96 +:108A50003878032818BF387A0DD0DFF8849389F866 +:108A6000034069460720F9F718FF002818BFFFDF09 +:108A70004FF6FF7440E0387BFCF724FC387BFCF7B2 +:108A80006EFE387BFCF7A3F8002808BFFFDF87F8ED +:108A90000080E2E7029800281CBF90F80C11002922 +:108AA0002AD00088A0421CBFDFF838A34FF0200B6B +:108AB0003AD00721F9F768FF040008BFFFDF94F8F8 +:108AC0005C01FCF74CFE84F80C8194F85C514FF685 +:108AD000FF76202D28BFFFDF2AF8156094F85C018F +:108AE000FCF775F884F85CB169460720F9F7D5FE04 +:108AF000002818BFFFDF12E06846F9F7ACFE002837 +:108B0000C8D011E0029800281CBF90F80C11002971 +:108B100005D00088A0F57F41FF39CAD104E068463E +:108B2000F9F799FE0028EDD089F8038087F83480A2 +:108B300087F80B8003B00020BDE8F08F70B50446C5 +:108B4000A94890F80004A94D400995F80014490976 +:108B5000884218BFFFDF95F8140D4009A44991F829 +:108B600000144909884218BFFFDF9D4900200122F7 +:108B70004C7188700A7048700A71C8709749087003 +:108B8000BDE8704057E79649087070472DE9F843F3 +:108B9000924C064688462078002860D19548FBF71D +:108BA000BAFF207320285AD003276660277000255B +:108BB00065722572AEB1012106F1FC00FDF71FF9C7 +:108BC0000620F9F789FE81460720F9F785FE96F819 +:108BD000FC104844B1FBF0F200FB1210401C86F878 +:108BE000FC00FBF7EDFF40F2F651884238BF40F23F +:108BF000F65000F59F7086B2F5F75AFCE061F5F784 +:108C0000E0FD4FF0010968B384F80A90FBF7FEFF1E +:108C1000814601216846FDF7C9F89DF8000042F23F +:108C200010710002B0FBF1F201FB120081194846FD +:108C3000FBF7EDFCA061C4E90A8927756775257407 +:108C4000207B04F11001FCF72BFA002808BFFFDF9E +:108C500025840020F6F735FD0020BDE8F8830C20C0 +:108C6000BDE8F883FBF7D2FF3146FBF7D0FCA061EB +:108C7000A57284F83490A8F28B50A562A063DCE75B +:108C80005749487070475649087170472DE9F041BF +:108C9000534C0646E088401CE080D4E902516078DD +:108CA000D6F8607120B13A46284604F076F90546B8 +:108CB000A068854205D02169281A08442061FCF784 +:108CC0008EFCA560AF4209D896F80C01012805D0AA +:108CD000E078002804BF0120BDE8F0810020BDE855 +:108CE000F08110B504460846FEF714FD4AF2B121A2 +:108CF00008444FF47A71B0FBF1F040F2E241614375 +:108D000000F2353081428CBF081A002010BD70B5CA +:108D1000044682B0002084F8200194F8DE00002888 +:108D200007BF94F80C01032802B070BDFBF76EFF7B +:108D3000D4F8502101461046FCF784FC0028DCBF23 +:108D400002B070BD628840F27123D4F814115A4306 +:108D5000C1EB4201B0FBF1F0B4F85810401C0844DC +:108D6000A4F81C01B4F8D400B4F81C21801A00B295 +:108D70000028DCBF02B070BD012084F82201B4F8E5 +:108D80008000B4F87E2001AE801A401E084485B2EF +:108D900012E00096B4F81C11002301222046FEF7D1 +:108DA00048FF002804BF02B070BD01280DD0022882 +:108DB00012BFFFDF02B070BDB4F81C01281A00B268 +:108DC0000028BCBF02B070BDE3E7B4F81C01BDF8D9 +:108DD00004100844A4F81C01EEE70000600C002019 +:108DE000DC0000209C0C002001E000E00BE000E033 +:108DF00019E000E02F850100F8B5042200250629BE +:108E00005BD2DFE801F007260319192A044680F82F +:108E10000C2107E00446BD48C078002818BF84F83C +:108E20000C210AD0FBF7FCFDA4F85A51B4F8580005 +:108E3000A4F81E0184F82251F8BD0095B4F8D410AE +:108E4000012300222046FEF7F4FE002818BFFFDFB2 +:108E5000E8E7032180F80C11F8BD0646876AB0F8F0 +:108E60001401314685B2012004F067F9044696F8F2 +:108E70005500FEF74FFC4AF2B12108444FF47A71D5 +:108E8000B0FBF1F0718840F271225143C0EB410018 +:108E9000401BA0F2653501F0DBFE002818BF1E3D27 +:108EA000A74234BF20463846A84228BF2C4602D2EB +:108EB000A74228BF3C467462F8BDFFDFF8BD2DE92C +:108EC000F05F924EB178022906BFF1880029BDE813 +:108ED000F09F7469C4F8640194F85500FEF708FC2B +:108EE000D4F86411081AB1680144B160F16808440B +:108EF000F060746994F82301002808BFBDE8F09F72 +:108F000094F80C01032818BFBDE8F09F94F8555061 +:108F100036780C2E28BFFFDF7D4F37F8168094F887 +:108F20006C610C2E28BFFFDF37F81600404494F820 +:108F30006C8186B2B8F10C0F28BFFFDF37F818003C +:108F400000F5C8601FFA80F82846FEF7D1FBD4F878 +:108F500064114FF0000A0F1A15F00C0F0ABF2846D3 +:108F60004EF62830FEF7D6FB4FF47A7900F2E73060 +:108F7000B0FBF9F03F1A2846FEF7BAFBD4F8E01030 +:108F800015F00C0FA1EB000B0ABF28464EF6283057 +:108F9000FEF7C0FB4AF2B1210844B0FBF9F0ABEB9D +:108FA0000000A0F160017143B1FBF8F1292202EB4E +:108FB00050006031A0EB510200EB5100BA4201D8E1 +:108FC000B84201D8F2F718FF608840F2E24141430D +:108FD00000202EB106FB01F04E49B0FBF1F0401C21 +:108FE000C4F8140184F823A1BDE8F09F70B50546CC +:108FF000464890F802C0BCF1020F07BF406900F577 +:10900000B074454800F12404002904BF256070BDF8 +:109010004FF47A7601290DD002291CBFFFDF70BD05 +:109020001046FEF790FB00F2E140B0FBF6F0281A84 +:10903000206070BD1846FEF7A7FB00F2E140B0FBD0 +:10904000F6F0281A206070BD3348007800281CBF55 +:109050000020704710B50720F9F730FC80F00100C0 +:1090600010BD2D480078002818BF012070472DE959 +:10907000F843294C0025814684F83450D4F81880F0 +:1090800084F83010E5722570012727722946606840 +:1090900003F0D3FA6168C1F85081267B81F85C61E6 +:1090A000C1F86091C1F85481B1F80080202E28BF2A +:1090B000FFDF1A4820F81680646884F80C510023FA +:1090C000A4F858511A46194620460095FEF7B1FDFE +:1090D000002818BFFFDFC4F80851C4F8005184F815 +:1090E0000C71A4F81E51A4F81C5184F82251B4F854 +:1090F0005800401EA4F85800A4F85A51FBF790FC01 +:1091000002484079BDE8F843E9F706BFDC000020DB +:10911000EC5C020040420F00600C00209C0C002020 +:10912000012804D0022805D0032808D105E0012930 +:1091300007D004E0022904D001E0042901D0002076 +:109140007047012070472DE9F0410E46044604F0B7 +:1091500048FD0546204604F048FD044604F063F847 +:10916000FE4F010015D0386990F854208A4210D083 +:1091700090F8A4311BB190F8A63123421FD02EB92C +:1091800090F85130234201D18A4218D890F8A401B6 +:10919000A8B1284604F047F870B1396991F8552014 +:1091A000824209D091F8A40118B191F8A701284290 +:1091B00005D091F8A40110B10120BDE8F081002094 +:1091C000FBE730B5E54C85B0E06900285DD014219F +:1091D00068460CF0C0FA206990F85500FEF79AFA3C +:1091E0004FF47A7100F5FA70B0FBF1F5206990F850 +:1091F0005500FEF77DFA2844ADF806002069018885 +:10920000ADF80010B0F85810ADF804104188ADF872 +:10921000021090F8860130B1A069C11C039104F0DE +:10922000C1FB8DF81000206990F885018DF80800C9 +:10923000E169684688472069002180F8861180F836 +:1092400085110399002920D090F8841100291CD1A0 +:1092500090F86410272918D09DF81010039A00295F +:1092600013D013780124FF2B11D0072B0DD1022925 +:109270000BD15178FF2908D180F884410399C0F8B7 +:1092800088119DF8101080F8871105B030BD1B299A +:10929000F2D9FAE770B5B14C206990F865001B2847 +:1092A00000D0FFDF2069002580F88D5090F8B801CC +:1092B00000B1FFDF206990F88E1041B180F88E5028 +:1092C0000188A0F8BC1180F8BA510E2108E001888D +:1092D000A0F8BC1180F8BA51012180F8BE110D210F +:1092E00080F8B8110088F9F781FCF9F719F92079AD +:1092F000E9F712FE206980F8655070BD70B5974C93 +:10930000A07980072CD5A078002829D16269204651 +:10931000D37801690D2B01F158005FD00DDCA3F16A +:1093200002034FF001050B2B19D2DFE803F01A18E6 +:1093300044506127182C183A6400152B6FD008DCB4 +:10934000112B4BD0122B5AD0132B62D0142B06D1D9 +:1093500066E0162B71D0172B70D0FF2B6FD0FFDF7C +:1093600070BD91F867200123194603F081FD0028A4 +:10937000F6D12169082081F8670070BD1079BDE839 +:10938000704001F002BD91F86600C00700D1FFDF18 +:1093900001F0BAFC206910F8661F21F0010101708C +:1093A00070BD91F86500102800D0FFDF2069112101 +:1093B00080F88D5008E091F86500142800D0FFDF98 +:1093C0002069152180F88D5080F8651070BD91F8E6 +:1093D0006500152800D0FFDF172005E091F8650033 +:1093E000152800D0FFDF1920216981F8650070BDC4 +:1093F000BDE870404EE7BDE8704001F09ABC91F8BE +:1094000064200123002103F033FD00B9FFDF0E20AB +:109410000FE011F8660F20F0040008701DE00FE067 +:1094200091F864200123002103F022FD00B9FFDF41 +:109430001C20216981F8640070BD12E01BE022E06D +:1094400091F86600C0F30110012800D0FFDF206909 +:1094500010F8661F21F010010170BDE8704001F0A6 +:1094600053BC91F864200123002103F001FD00B9F1 +:10947000FFDF1F20DDE791F86500212801D000B152 +:10948000FFDF2220B0E7BDE8704001F049BC33485F +:10949000016991F86620130702D501218170704798 +:1094A00042F0080281F866208069C07881F8C9001E +:1094B00001F021BC10B5294C21690A88A1F8FC21D2 +:1094C00081F8FA0191F8540001F003FC216981F858 +:1094D000FE0191F8550001F0FCFB216981F8FF01C4 +:1094E000012081F8F801002081F8A4012079BDE86D +:1094F0001040E9F711BDF0B4184C206900F5D6739F +:1095000001881985018E5985818E9985018FB0F862 +:109510004420914200D31146D985828FB0F846107D +:109520008A4200D21146198690F855204FF0010565 +:1095300012F00C0F4FF4296203D0914200D811466B +:10954000198690F8540010F00C0F04D0988D9042BA +:1095500000D902469A8583F8265001E0FC000020DD +:109560002079F0BCE9F7D8BC10B5F84C01230921EB +:10957000206990F86420583003F07AFC38B12169F2 +:10958000002001F87C0F087301F8180C10BD0120B1 +:10959000A07010BD70B5ED4D012329462869896979 +:1095A00090F8642009790E2A01D1122903D00024F1 +:1095B0001C2A03D004E0BDE87040D5E7142902D08E +:1095C000202A08D009E080F8644080F88840BDE88F +:1095D000704001F0FDBB162906D0262A01D11629BC +:1095E00002D0172909D00CE000F8644F80F824401D +:1095F000407821280CD01A2017E090F86520222A04 +:1096000007D0EA69002A03D0FF2901D180F886310A +:1096100012E780F8654001F077FB286980F87D400B +:1096200090F8A4010028F3D00020BDE8704041E785 +:109630002DE9F843C54C206990F86410202909D021 +:109640005FF0000790F86510222905D07FB300F184 +:10965000640503E00127F5E700F1650510F8961FA2 +:1096600041F004010170A06904F0C7FA4FF001084D +:10967000002608B33946A069FFF765FDE0B16A46E8 +:10968000A169206903F0DEFD90B3A06904F0B3FA8C +:109690002169A1F88E01B1F8581001F00EFB40B31A +:1096A0002069282180F8741080F8738058E0FFE763 +:1096B0000220A070BDE8F883206990F8A40110B1E1 +:1096C0001E20FFF7F7FEAFB1A0692169C07881F8CD +:1096D000CA0008FA00F1C1F3006000B9FFDF206999 +:1096E0000A2180F8641090F8880040B9FFDF06E096 +:1096F00009E02AE02E7001F007FBFFF7C8FE2069A1 +:1097000080F87D60D6E7226992F8A40170B1B2F8C2 +:10971000583092F85410B2F8A80102F5C77203F05D +:1097200083FE68B12169252081F86400206900F179 +:10973000650180F87D608D4212D180F865600FE090 +:109740000020FFF7B7FE2E70F0E720699DF80010AB +:1097500080F890119DF8011080F891112420287054 +:10976000206900F165018D4203D1BDE8F84301F0A5 +:10977000CBBA80F888609DE770B5744C01230B214B +:10978000206990F86520583003F072FB202650BB0A +:1097900020690123002190F86520583003F068FB10 +:1097A0000125F0B1206990F8640024281BD0A0693D +:1097B00004F001FAC8B1206990F8961041F0040154 +:1097C00080F89610A1694A7902F0070280F85120CA +:1097D000097901F0070180F8501090F8A5311BBB02 +:1097E00006E0A57028E6A67026E6BDE870404EE6C5 +:1097F00090F8A431C3B900F154035E788E4205D1CC +:109800001978914202D180F87D500DE000F5F97190 +:109810000D7002884A8090F850200A7190F851002B +:1098200048712079E9F778FB2169212081F86500EA +:10983000BDE8704001F05FBA70B54448006990F827 +:109840004E20448EC38E418FB0F84050022A23D060 +:10985000A94200D329460186C18FB0F84220914227 +:1098600000D311468186018FB0F84420914200D385 +:1098700011464186818FB0F84620914200D31146AF +:10988000C186418EA14200D90C464486C18E9942C0 +:1098900000D90B46C386CFE5028E914200D3114614 +:1098A000C68F828E964200D23246A94200D3294604 +:1098B0000186B0F842108A4200D30A46828600210F +:1098C00080F84E10CFE770B5204C206990F8660004 +:1098D00010F0300F04D0A07840F00100A070ABE58C +:1098E000A06904F04DF948B32569A06904F044F972 +:1098F00028872569A06904F03BF968872569A06974 +:1099000004F03CF9A8872569A06904F033F9E887D9 +:10991000A0794FF00102800703D56069C078142850 +:109920000FD0206990F864101C290AD090F84E10CE +:10993000012910D090F89B1169B909E0BDE8704089 +:10994000A5E5206980F84E2005E00000FC0000201D +:1099500090F89A1131B1206910F8661F41F010019A +:10996000017016E090F8661041F0200180F8661052 +:1099700000F5D67103888B86038FCB86438F0B87C8 +:10998000838F4B87C08F888781F832202079E9F751 +:10999000C3FABDE8704001F0AEB970B5FE4C206965 +:1099A00090F86610890707D590F8642001230821F4 +:1099B000583003F05DFAE8B1206990F89000800714 +:1099C00012D4A06904F0B8F8216981F89100A06967 +:1099D00030F8052FA1F892204088A1F8940011F8E2 +:1099E000900F40F002000870206990F89010C907AD +:1099F00003D00FE00120A0701EE590F866008007FC +:109A000000D5FFDF206910F8661F41F002010170E8 +:109A100001F071F92069002590F86410062906D13B +:109A200080F8645080F888502079E9F775FA206949 +:109A300090F88C110429DFD180F88C512079E9F756 +:109A40006BFA206990F864100029D5D180F888500D +:109A5000F2E470B5D04C01230021206990F8652014 +:109A6000583003F005FA012578B9206990F865208F +:109A7000122A0AD001230521583003F0F9F910B158 +:109A80000820A070D8E4A570D6E4206990F88E0074 +:109A900008B901F030F92169A069E83104F02DF826 +:109AA0002169A069C03104F033F8206990F8C00141 +:109AB00000B1FFDF21690888A1F8C20101F5E27158 +:109AC000A06904F008F82169A06901F5E67104F0C5 +:109AD0000AF8206980F8C051142180F865102079B7 +:109AE000BDE87040E9F718BA70B5AB4C012300210E +:109AF000206990F86520583003F0BAF90125A8B123 +:109B0000A06903F0B4FF98B1A0692169B0F80D0015 +:109B1000A1F88E01B1F8581001F0CFF858B12069C2 +:109B2000282180F8741080F8735085E4A57083E4D0 +:109B3000BDE87040ABE4A0692169027981F8902109 +:109B4000B0F80520A1F8922103F084FF2169A1F863 +:109B50009401A06903F081FF2169A1F89601A06931 +:109B600003F082FF2169A1F898010D2081F86500BA +:109B700062E47CB5884CA079C00738D0A069012385 +:109B80000521C578206990F86520583003F070F9F8 +:109B900068B1AD1E0A2D06D2DFE805F009090505FA +:109BA000090905050909A07840F00800A070A0780F +:109BB00000281CD1A06903F023FF00287AD0A069F7 +:109BC0000226C5781DB1012D01D0162D18D12069AE +:109BD00090F8640003F034F990B1206990F86410B3 +:109BE0001F290DD0202903D0162D16D0A6707CBDBC +:109BF000262180F86410162D02D02A20FFF75AFC87 +:109C00000C2D58D00CDC0C2D54D2DFE805F033308D +:109C10001D44A7A7479E57A736392020A0707CBDBA +:109C20000120152D75D008DC112D73D0122D69D0AF +:109C3000132D64D0142D3DD178E0162D7CD0182D35 +:109C40007DD0FF2D36D183E020690123194690F89D +:109C50006720583003F00CF9F8B9A06903F034FF1D +:109C6000216981F87201072081F8670078E001F02E +:109C700036F975E0FFF738FF72E001F010F96FE098 +:109C8000206990F86510112901D0A67068E01221B2 +:109C900080F8651064E0FFF7DCFE61E0206990F871 +:109CA00065001728F1D101F02FF821691B2081F8F8 +:109CB000650055E052E0FFF770FE51E0206990F832 +:109CC0006600C00703D0A07840F001001FE069469D +:109CD000A06903F038FF9DF8000000F0250120691D +:109CE00000F8961F9DF8011001F04901417001F044 +:109CF00002F8206910F8661F41F0010114E0FFF737 +:109D000033FC2DE0216991F86610490705D5A07054 +:109D100026E00EE016E00FE011E000F0ECFF206915 +:109D200010F8661F41F00401017019E0FFF7CBFD48 +:109D300016E001F081F813E0FFF71EFD10E0FFF7D9 +:109D400077FC0DE001F057F80AE0FFF723FC07E08D +:109D5000E16919B1216981F8860101E0FFF797FBFC +:109D60002069F0E92A12491C42F10002C0E9001200 +:109D70007CBD70B5084CA07900074DD5A0780028AF +:109D80004AD1206990F8CB00FE2800D1FFDF20697E +:109D9000FE2180F8CB1001E0FC00002090F8651057 +:109DA0000025192906D180F88D5000F0ADFF2069FB +:109DB00080F86550206990F864101F2902D0272987 +:109DC00021D119E090F8650003F03AF878B12069E4 +:109DD0002621012380F8641090F865200B2158306B +:109DE00003F046F878B92A20FFF764FB0BE02169FD +:109DF000202081F8640006E0012180F8851180F8B8 +:109E0000645080F88850206990F86710082903D1C1 +:109E10000221217080F8CB10E4E4FE49096991F831 +:109E200090210AB991F8542081F8542091F8912199 +:109E30000AB991F8552081F85520002802D0002059 +:109E4000FFF738BB704770B5F24C06460D462069E7 +:109E500090F8CB00FE2800D0FFDF2269002082F8B6 +:109E6000CB6015B1A2F88A00BCE422F8840F01206F +:109E70001071B7E470B5E74C01230021206990F818 +:109E80006420583002F0F4FF00287AD0206990F85E +:109E90009A1111B190F89B1139B190F8A4110029D1 +:109EA0006ED090F8A51111B36AE0B0F89C1120F8BB +:109EB000401FB0F85E114180B0F860118180B0F8A9 +:109EC0006211C180002180F85A1190F826008006A6 +:109ED0000AD501F068F8206910F8661F21F020010A +:109EE00041F01001017051E0002114204CE090F885 +:109EF000652001230B21583002F0BAFF68BB2069AE +:109F000090F8540000F0E5FE0646206990F85500F0 +:109F100000F0DFFE0546206990F8A6113046FFF7F5 +:109F2000FFF8D8B1206990F8A7112846FFF7F8F894 +:109F3000A0B12269B2F8583092F85410B2F8A801D2 +:109F400002F5C77203F070FA20B12169252081F86B +:109F500064001BE00020FFF7ADFA11E02069012347 +:109F6000032190F86520583002F082FF40B9206943 +:109F70000123022190F86520583002F079FF08B1E2 +:109F800000202FE400211620FFF75DFF012029E4C7 +:109F900010B548BB9F4C206990F86610CA0702D0E4 +:109FA0000121092018E08A070AD501210C20FFF7BA +:109FB0004AFF206910F8901F41F0010101702AE06A +:109FC0004A0702D50121132006E00A0707D510F839 +:109FD000C91FC17001210720FFF735FF1BE0C9062B +:109FE00002D590F89B1109B1002010BD90F89A118C +:109FF00079B1B0F89C1120F8401FB0F85E11418093 +:10A00000B0F860118180B0F86211C180002180F841 +:10A010005A1100F0C8FF012010BD70B57D4C2069B9 +:10A0200090F8CB10FE2978D1A178002975D190F84D +:10A03000672001231946583002F01AFF00286CD11E +:10A04000206990F8701149B10021A0F8821090F8B1 +:10A05000711180F8CC10002102205BE090F865209F +:10A0600001230421583002F003FF0546FFF790FF5B +:10A07000002852D1284600F0A1FF00284DD12069C8 +:10A080000123002190F86420583002F0F1FE78B1ED +:10A0900020690123042190F86520583002F0E8FE81 +:10A0A00030B9206990F87C0010B10021122031E015 +:10A0B000206990F864200A2A0DD0002D2DD10123AB +:10A0C0000021583002F0D4FE78B1206990F88C114C +:10A0D00004290AD105E010F8CA1F81700021072069 +:10A0E00018E090F89000800718D0FFF7C3FE002812 +:10A0F00013D120690123002190F86420583002F028 +:10A10000B7FE002809D0206990F88401002804D007 +:10A110000021FF20BDE8704095E609E000210C20F9 +:10A12000FFF791FE206910F8901F41F001010170C6 +:10A1300062E43EB505466846FDF73BFC00B9FFDF2B +:10A14000222100980BF0E5FA0321009803F040FC6F +:10A150000098017821F010010170294603F05DFCA0 +:10A160002C4C0D2D40D00BDCA5F102050B2D19D286 +:10A17000DFE805F01F186519191F18701819240059 +:10A18000152D7BD008DC112D25D0122D0BD0132DD1 +:10A1900009D0142D06D12BE0162D46D0172D6BD0EB +:10A1A000FF2D6AD0FFDFFDF717FC002800D1FFDF8D +:10A1B0003EBD2169009891F8CC1017E0E268009844 +:10A1C0001178017191884171090A81715188C171B9 +:10A1D000090A0172E7E70321009803F028FD062130 +:10A1E000009803F028FDDEE7009806210171DAE708 +:10A1F0002069B0F84410009803F0AAFC2069B0F878 +:10A200004610009803F0A8FC2069B0F840100098B0 +:10A2100002E00000FC00002003F0A2FC2069B0F87E +:10A220004210009803F0A0FCBDE70098D4F810108D +:10A2300091F8A621027191F8A7114171B3E7216944 +:10A240000098F03103F068FC21690098C43103F0F4 +:10A250006DFCA8E7F949D1E90001CDE901012069C8 +:10A2600001A990F8960000F025008DF804000098F0 +:10A2700003F097FC97E701E019E023E02069B0F8CC +:10A280004010009803F06CFC2069B0F84210009870 +:10A2900003F06AFC2069B0F84410009803F058FC01 +:10A2A0002069B0F84610009803F056FC7BE721695E +:10A2B00091F8A40100280098BAD111F8542F027126 +:10A2C0004978BAE7206990F88721D0F8881100987A +:10A2D00003F0B1FB67E7DA4810B5006990F86A103F +:10A2E00041B990F8652001230621583002F0C0FDE5 +:10A2F000002800D0012010BD70B5D14D286990F81C +:10A30000681039B1012905D0022906D0032904D0EB +:10A31000FFDF0AE4B0F8D41037E090F8671008299E +:10A3200036D0B0F87E10B0F8802000248B1C9A4202 +:10A3300006D3511A891E0C04240C01D0641EA4B249 +:10A3400090F87C1039B190F864200123092158302D +:10A3500002F08EFD40B3FFF7BEFF78B129690020FF +:10A36000B1F87820B1F876108B1C9A4203D3501ABA +:10A37000801E00D0401EA04200D284B20CB1641EE8 +:10A38000A4B22869B0F8D4102144A0F8D01043E555 +:10A39000B0F87E100329BDD330F8581F028D114448 +:10A3A000491CA0F8781037E50024EAE770B50C46A0 +:10A3B00005464FF4007120460BF0CDF925802BE5C2 +:10A3C000F8F7EBBB2DE9F0410D4607460721F8F7FA +:10A3D000DBFA041E3CD094F8AC010026A8B16E70E4 +:10A3E000092028700BE0268484F8AC61D4F8AE0113 +:10A3F0006860D4F8B201A860B4F8B601A88194F8F6 +:10A40000AC010028EFD12E71BAE094F8B80190B3F6 +:10A4100094F8B8010D2813D00E2801D0FFDFAFE06B +:10A420002088F8F7E3FB0746F8F78FF878B96E70E5 +:10A430000E20287094F8BA0128712088E88014E072 +:10A440002088F8F7D3FB0746F8F77FF810B1002013 +:10A45000BDE8F0816E700D20287094F8BA01287163 +:10A460002088E88094F8BE01287284F8B8613846E4 +:10A47000F8F765F884E0FFE794F8F00130B16E700A +:10A480001020287084F8F061AF8079E094F8C00162 +:10A4900090B16E700A2028702088A880D4F8C4116A +:10A4A000C5F80610D4F8C811C5F80A10B4F8CC01E4 +:10A4B000E88184F8C06163E094F8CE0140B16E7029 +:10A4C0001A202870B4F8D001A88084F8CE6157E033 +:10A4D00094F8EA0170B16E701B20287005E000BF8F +:10A4E00084F8EA61D4F8EC01686094F8EA01002885 +:10A4F000F6D145E094F8D20190B16E701520287025 +:10A5000004F5EA7707E000BF84F8D2610A223946F1 +:10A51000281D0BF0C4F894F8D2010028F4D12FE0E4 +:10A5200094F8DE0158B16E701D20287084F8DE6149 +:10A530000A2204F5F071281D0BF0B1F820E094F820 +:10A54000F20138B11E20287084F8F261D4F8F401C9 +:10A55000686015E094F8F80100283FF479AF6E7058 +:10A560001620287008E000BF84F8F861D4F8FA01DA +:10A570006860B4F8FE01288194F8F8010028F3D14E +:10A58000012065E72E480021C1610162084670473D +:10A5900030B52B4D0C46E860FFF7F4FF00B1FFDF4C +:10A5A0002C7130BD002180F8641080F8651080F8AF +:10A5B000681090F8DE1009B1022100E00321FEF7D7 +:10A5C0001BBC2DE9F0411E4C0546206909B1002154 +:10A5D00004E0B0F8E610B0F8D6201144A0F8E61078 +:10A5E00090F8701139B990F8672001231946583056 +:10A5F00002F03EFC30B1206930F8821FB0F85420E0 +:10A6000011440180206990F8883033B1B0F884108B +:10A61000B0F8D6201144A0F8841090F98C70002F67 +:10A6200006DDB0F88A10B0F8D6201144A0F88A10E0 +:10A6300001213D2635B180F8746017E0045D020009 +:10A64000FC0000202278022A0AD0012A11D0A27828 +:10A650002AB380F8731012F0140F0DD01E2113E0EE +:10A6600090F8CC20062A3CD016223AE080F87310ED +:10A6700044E090F8722134E0110702D580F874604C +:10A680003CE0910603D5232180F8741036E0900752 +:10A6900000D1FFDF21692A2081F874002AE02BB164 +:10A6A000B0F88420B0F886309A4210D2002F05DD31 +:10A6B000B0F88A20B0F886309A4208D2B0F88230DA +:10A6C000B0F88020934204D390F870310BB122226D +:10A6D00007E090F868303BB1B0F87E30934209D380 +:10A6E000082280F87420C1E7B0F87E20062A01D342 +:10A6F0003E22F6E7206990F8731019B12069BDE891 +:10A70000F0414FE7BDE8F0410021FEF775BB2DE9B0 +:10A71000F047F94C81460D4620690088F8F778FA31 +:10A72000060000D1FFDFA0782843A070A0794FF089 +:10A7300000058006206904D5A0F87E5080F8E4501A +:10A7400003E030F87E1F491C0180FFF7C4FD01279C +:10A7500040B3E088000506D5206990F86A1011B171 +:10A76000A0F876501EE02069B0F87610491C89B236 +:10A77000A0F87610B0F878208A4201D3531A00E08E +:10A780000023B4F808C00CF1050C634501D880F82B +:10A790007C70914206D3A0F8765080F8F071207951 +:10A7A000E8F7BAFBA0794FF0020810F0600F0ED066 +:10A7B000206990F8681011B1032908D102E080F8EF +:10A7C000687001E080F868800121FEF715FB2069C0 +:10A7D00090F86810012904D1E188C90501D580F8F5 +:10A7E0006880B9F1000F70D1E188890502D5A0F821 +:10A7F000F85003E030F8F81F491C018000F09AFB84 +:10A80000FEF7DFFCFFF709FC00F062FF002820697B +:10A8100002D0A0F8D85003E030F8D81F491C0180BE +:10A8200000F059FF38B1216991F8E400022807D8F7 +:10A83000401C81F8E400206990F8E400022804D963 +:10A84000206920F8D85F4580057320690123002125 +:10A8500090F86520583002F00BFB20B9206990F881 +:10A8600065000C2859D120690123002190F864204B +:10A87000583002F0FDFA48B320690123002190F816 +:10A880006720583002F0F4FA00B3206990F868109D +:10A89000022942D190F8E400C0B93046F7F725FC10 +:10A8A000A0B1216991F8CB00FE2836D1B1F8D200D1 +:10A8B000012832D981F8DD70B1F88000B1F87E202E +:10A8C000831E9A4203DB012004E032E025E0801A77 +:10A8D000401E80B2B1F8D82023899A4201D30122C8 +:10A8E00002E09A1A521C92B2904200D910460128F6 +:10A8F00001D181F8DD5091F8682192B1B1F8DA20E8 +:10A90000B1F86A118A4201D3012102E0891A491C77 +:10A9100089B2884205D9084603E02169012081F8FF +:10A92000DD502169B1F858201044A1F8D400FFF798 +:10A93000E3FCE088C0F340214846FFF742FE20696F +:10A9400080F8DE50BDE8F047FDF768B86A49024676 +:10A950008878CB78184312D10846006942B18979CA +:10A96000090703D590F86700082808D00120704730 +:10A97000B0F84810028E914201D8FEF787B9002046 +:10A98000704770B55C4C05460E46E0882843E08071 +:10A99000A80703D5E80700D0FFDF6661EA074FF09C +:10A9A00000014FF001001AD0A661F278062A02D009 +:10A9B0000B2A14D10AE0226992F86530172B0ED1C8 +:10A9C0000023E2E9283302F8370C08E0226992F804 +:10A9D0006530112B03D182F8691082F88E00AA0726 +:10A9E00018D56269D278052A02D00B2A12D10AE062 +:10A9F000216991F86520152A0CD10022E1E92A226B +:10AA000001F83E0C06E0206990F86520102A01D17B +:10AA100080F86A10280601D50820E07079E42DE955 +:10AA2000F84F354C00254FF00108E580A570E57022 +:10AA30004146257061F3070220619246814680F805 +:10AA4000DE800088F8F7E4F8070000D1FFDF206916 +:10AA50000088FCF7ABFF20690088FCF7CDFF206978 +:10AA6000B0F8D21071B190F8CB10FE290FD190F848 +:10AA7000701189B190F8672001231946583002F00F +:10AA8000F7F978B1206990F8CB00FE2804D020694E +:10AA900090F8CB00FFF74DFB206990F8DF1089B1EB +:10AAA000258118E02069A0F8825090F8711180F893 +:10AAB000CC1000210220FFF7C6F9206980F8DD5094 +:10AAC0000220E7E790F8AC1119B9018C8288914215 +:10AAD00000D881882181B0F8D610491E8EB2B0F816 +:10AAE000D8103144A0F8D81090F8DC1031B1A0F89B +:10AAF000DA5080F8DC5006E0FC000020B0F8DA10F4 +:10AB00003144A0F8DA1030F87E1F31440180FFF79D +:10AB1000E2FB20B1206930F8761F314401802069C2 +:10AB2000B0F8D210012902D8491CA0F8D2100EB1F9 +:10AB300080F8E45090F8DD10A1B1B0F8D800218978 +:10AB400088420FD23846F7F7D0FA58B1206990F80A +:10AB5000681139B1B0F8DA10B0F86A01814201D356 +:10AB600000F0BCFD206980F8DD5090F865100B29DD +:10AB700001D00C2916D1B0F85820B0F88E31D21A75 +:10AB800012B2002A0EDBD0F89011816090F8941177 +:10AB90000173022101F051FD206980F8655080F8B1 +:10ABA000988026E0242910D1B0F85810B0F88E21F2 +:10ABB000891A09B2002908DB90F8A401FFF72DF9E2 +:10ABC000206900F8655F057613E090F86410242989 +:10ABD00001D025290DD1B0F85810B0F88E01081A0F +:10ABE00000B2002805DB0120FFF717F9206980F883 +:10ABF000645020690146B0F8D620583001F0EFFECD +:10AC0000206990F8681109B1A0F8DA50FD48009069 +:10AC1000FD4BFE4A4946504600F0BAFC216A11B18C +:10AC20006078FCF7BEF920690123052190F86520C2 +:10AC3000583002F01DF9002803D0BDE8F84F00F0AD +:10AC400042BABDE8F88F00F029BDF149C8617047EC +:10AC5000EF48C069002800D001207047EC4A5070CE +:10AC60001162704710B50446B0F894214388B0F8DB +:10AC70009611B0F898019A4205D1A388994202D161 +:10AC8000E38898420FD02388A4F8B031A4F8B22109 +:10AC9000A4F8B411A4F8B601012084F8AC01DC4892 +:10ACA0000079E8F739F90121204601F0C6FC0020BF +:10ACB00004F8650F0320E07010BD401A00B247F69B +:10ACC000FE71884201DC002801DC01207047002071 +:10ACD000704710B5012808D0022808D0042808D0F1 +:10ACE000082806D0FFDF204610BD0124FBE7022420 +:10ACF000F9E70324F7E7C6480021006920F88A1F16 +:10AD00008178491C81707047C14800B5016911F80C +:10AD10008C0F401E40B20870002800DAFFDF00BD33 +:10AD2000BB482721006980F86410002180F8841155 +:10AD3000704710B5B64C206990F88C11042916D1D3 +:10AD400090F8642001230021583002F091F800B9F6 +:10AD5000FFDF206990F89010890703D4062180F85E +:10AD6000641004E0002180F8881080F88C112069BC +:10AD700090F86600800707D5FFF7C6FF206910F836 +:10AD8000661F21F00201017010BDA14910B50969CB +:10AD900091F864200A2A09D191F8CA20824205D18B +:10ADA000002081F8640081F8880010BD91F86620C9 +:10ADB000130706D522F0080081F86600BDE81040B0 +:10ADC000A2E7FF2801D0FFDF10BDBDE81040A7E7D4 +:10ADD00010B58F4C05212069FEF70EF8206990F818 +:10ADE0004E10012903D0BDE81040FEF784BB0221BC +:10ADF00080F84E1010BD10B5854C206910F8961FD4 +:10AE000041F004010170A06902F013FF162806D179 +:10AE1000206990F86400202802D0262805D010BDB3 +:10AE2000A06902F00AFFFEF745FB2169002081F8C6 +:10AE3000640081F8880010BD70B5754C01230A21AB +:10AE4000206990F86420583002F012F810B3A0691D +:10AE500002F096FEA8B12569A06902F08DFE288750 +:10AE60002569A06902F084FE68872569A06902F05F +:10AE700085FEA8872569A06902F07CFEE887FEF7B9 +:10AE8000DBFC2169002081F8880081F86400BDE8BE +:10AE900070409DE7A07840F00100A070BEE510B5BD +:10AEA0005B4C01230021206990F86520583001F0A7 +:10AEB000DFFF30B1FFF71FFF2169102081F8650027 +:10AEC00010BD20690123052190F86520583001F05C +:10AED000CFFF08B1082000E00120A07010BD70B5C0 +:10AEE0004B4C01230021206990F86520583001F077 +:10AEF000BFFF012588B1A06902F0E3FD2169A1F837 +:10AF00008E01B1F85810FFF7D8FE40B12069282112 +:10AF100080F8741080F8735080E5A5707EE5216993 +:10AF2000A06901F5C87102F0C7FD21690B2081F805 +:10AF3000650073E510B5FEF71CFFFEF71AFE344CF2 +:10AF4000A079400708D5A07830B9206990F867004B +:10AF5000072801D101202070FEF7D0F9A079C006A2 +:10AF600009D5A07838B9206990F865100B2902D16D +:10AF70000C2180F86510E07800070ED520690123C8 +:10AF8000052190F86520583001F072FF30B108209B +:10AF9000A0702169002081F8B80110BDBDE8104003 +:10AFA000002000F09FBB10B5FEF746FCFFF710FF36 +:10AFB0000121BDE810401520FEF745BF10B5144C27 +:10AFC000216991F8652088B3102A06D0142A07D089 +:10AFD000152A22D01B2A35D122E001210B2021E0A5 +:10AFE000FAF7EAFE0C281FD320690821F030FAF79F +:10AFF000E7FE28B120690421C430FAF7E1FE00B968 +:10B00000FFDF07E00FA701004DA9010083A90100A0 +:10B01000FC0000200121042004E000F018F803E007 +:10B0200001210620FEF70FFF012010BDFFE7212AB6 +:10B0300008D191F87D0038B991F8A40110B191F8C8 +:10B04000A50108B10020F0E701211720EAE770B55B +:10B05000174C0025206990F8731101290AD00229A4 +:10B0600025D190F88E10A9B1062180F8CC100121CD +:10B07000022017E090F8B811002918D100F1B003B0 +:10B0800000F1E801002200F5BA7001F06BFE012129 +:10B09000052007E090F89600400701D5112000E058 +:10B0A0000D200121FEF7CFFE206980F87351B5E431 +:10B0B000FC00002030B5FA4C05462078002818BF67 +:10B0C000FFDF257230BDF6490120C87170472DE9B8 +:10B0D000F14FF44E30464068044600F1580990F8AC +:10B0E000551001F097FF94F85510658E80B208292D +:10B0F0006CD001F06DFF854238BF284600F0FF0894 +:10B10000DFF89CA3E848CAF824007768384697F827 +:10B110006AB07D8E97F8551001F07CFF97F85510B6 +:10B1200080B2082956D001F053FF854238BF284627 +:10B13000BBF1000F1CBF001D80B2C0B297F85510C4 +:10B14000FBF7BFFB99F81200002847D009F158011E +:10B15000D54891E80E1000F5027585E80E10D9F873 +:10B160006810C0F82112D9F86C10C0F8251200F54B +:10B170008170FBF7A6FE307800280CBF012000206C +:10B1800080F00101C9480176D9E91412C0E904121E +:10B19000A0F58372DAF82410FBF72DFA94F8550025 +:10B1A000012808BF00220CD0022808BF012208D0C5 +:10B1B000042808BF032204D008281ABFFFDF00229A +:10B1C000022241460120FBF731FA0DE0042101F093 +:10B1D000FFFE90E7042101F0FBFEA6E7DAF8240069 +:10B1E000FBF76FFEFBF74EFA009850B994F8550044 +:10B1F00094F8561010F00C0F08BF00219620FBF7B2 +:10B2000081FE94F8542001210020FBF767FF94F899 +:10B210002C00012808BFFBF731FF02208AF800004C +:10B22000FCF7D9FA002818BFFFDFBDE8F88F2DE939 +:10B23000F04FDFF870A28BB050469AF800204168BA +:10B240001438049091F85D0001F158050C464FF058 +:10B2500008080127AAF13406A0B3012800F00681EE +:10B26000022800F00781032818BFFFDF00F01081DB +:10B27000306A0423017821F008010170AA7908EAF4 +:10B28000C202114321F004010170EA7903EA82024B +:10B29000114321F01001017095F80590F06AF6F75E +:10B2A00034FF8046FCF7CCFBB9F1020F00F00081BF +:10B2B000B9F1010F00F00081B9F1030F00F0008136 +:10B2C00000F003B9FFE72B7B4FF002094FF0000BB2 +:10B2D000242B1CBF95F80DC0BCF1240F07D01F2BE9 +:10B2E00018BF202B2AD0BCF1220F4DD077E091F867 +:10B2F000540092B191F89011002974D0082818BF19 +:10B30000042869D0082918BF042965D0012818BF6E +:10B31000012953D04FF0020065E091F8F2100029A6 +:10B3200061D0082818BF042856D0082918BF04295E +:10B3300052D0012818BF012940D0EBE7BCF1220F01 +:10B3400022D0002A4BD091F8540091F8A61111F0A8 +:10B35000040F18BF41460CD0082818BF04283BD062 +:10B36000082918BF042937D0012818BF012925D082 +:10B37000D0E711F0010F18BF3946EDD111F0020FDF +:10B3800018BF4946E8D12EE04AB391F8540091F82D +:10B39000A62191F8511002EA010111F0040F18BF23 +:10B3A00041460ED0082818BF042815D0082918BF18 +:10B3B000042911D0012818BF0129ABD14FF0010099 +:10B3C00011E011F0010F18BF3946EBD111F0020F57 +:10B3D00018BF4946E6D106E04FF0080003E091F8B7 +:10B3E00054000428F8D001460290204601F01DFECA +:10B3F00080B2029901F0ECFD218E814238BF0846EF +:10B40000ADF80C00A4F848000498FCF7F8FA60B115 +:10B41000B289316A42F48062B28172694FF480600D +:10B42000904703206871EF7022E709AA03A9F06A28 +:10B43000F6F7A6FD306210B195F8351021B10498E9 +:10B44000FCF7B1FA6F7113E79DF8241031B9A0F839 +:10B4500000B080F802B0012102F0BAFABDF80C1079 +:10B46000306A02F0ECFB85F8059001E70498FCF7E0 +:10B470009AFAFDE6B4F84800ADF8080009AA02A956 +:10B48000F06AF6F77DFD3062002808BFFFDFEFE6C7 +:10B490000498FCF7B4FA002808BFFFDFE8E60000D4 +:10B4A0002001002054010020E00C0020E80E0020C4 +:10B4B00030EA080009D106E030EA080005D102E0D0 +:10B4C000B8F1000F01D0012100E00021306A0278BC +:10B4D00042EA01110170697C00291CBF69790129C8 +:10B4E0003DD005F15801FD4891E80E1000F50278B5 +:10B4F00088E80E10A96EC0F82112E96EC0F8251276 +:10B5000000F58170FBF7DDFC9AF8000000280CBF05 +:10B5100001200020F2490876D5E91202C1E90402AF +:10B52000A1F5837101F58370326AFBF764F894F832 +:10B530005400012808BF00220CD0022808BF0122B5 +:10B5400008D0042808BF032204D008281ABFFFDF50 +:10B5500000220222FB210020FBF768F803E0FBF742 +:10B56000B0FCFBF78FF8012194F855200846FBF753 +:10B57000B5FD3771306A018831828078B0743770D8 +:10B58000FCF732F9002818BFFFDF0BB0BDE8F08FE1 +:10B590002DE9F047D34C8146DDF8208020781E4607 +:10B5A00017460D4628B9002F1CBF002EB8F1000F1A +:10B5B00000D1FFDFC4F81C80C4E90D95C4E905760D +:10B5C0004FF00000E071A071E070A0702071607118 +:10B5D000C54EA081E081307805F158072888F7F73B +:10B5E00017FBE0622888F7F701FB2063FBF78DF972 +:10B5F00095F95700FBF723FA05F11200FBF744FC1D +:10B6000005F10E00FBF721FA307800280CBF03206B +:10B610000120FBF753FCB87EFBF71FFAFBF748FC51 +:10B620003078002804BFFF2095F8544019D0BF7C23 +:10B630006C8E95F85510284601F0ECFC95F85510E5 +:10B6400080B208291FD001F0C3FC014620468C427D +:10B6500028BF0846002F1CBF001D80B2C0B295F85D +:10B6600055402146FBF72DF93078214680B1012065 +:10B67000FBF751FA7068D0F8E000FBF725FCBDE855 +:10B68000F047012023E5042101F0A2FC0146DDE79B +:10B690000020FBF740FABDE8F047C8E5924800B546 +:10B6A00001783438007819B1022818BFFFDF00BDD7 +:10B6B000012818BFFFDF00BD8A4810B500780228B6 +:10B6C00018BFFFDFBDE8104000F034BA00F032BA16 +:10B6D0008448007970478348C078704781490120C9 +:10B6E000487170472DE9F04706007F487D4D40685E +:10B6F00000F15804686A90F8019018BF012E03D138 +:10B70000296B09F045FC6870687800274FF0010844 +:10B71000A0B101283CD0022860D003281CBFFFDF65 +:10B72000BDE8F087012E08BFBDE8F087286BF6F76B +:10B73000E1FE287ABDE8F047E7F7EEBB012E14D012 +:10B74000A86A002808BFFFDF6889C21CD5E9091074 +:10B7500009F060FFA86A686201224946286BF6F783 +:10B7600045FD022E08BFBDE8F087D4E91401401C56 +:10B7700041F10001C4E91401E079012801D1E77128 +:10B7800001E084F80780287ABDE8F047E7F7C4BBFA +:10B79000012E14D0A86A002808BFFFDF6889C21CE8 +:10B7A000D5E9091009F036FFA86A68620022494607 +:10B7B000286BF6F71BFD022E08BFBDE8F087D4E921 +:10B7C0001410491C40F10000C4E91410E07901286C +:10B7D0000CBFE77184F80780BDE8F087012E06D022 +:10B7E000286BF6F787FE022E08BFBDE8F087D4E984 +:10B7F0001410491C40F10000C4E91410E07901283C +:10B80000BFD1BCE770B5384E3046A6F1340440686D +:10B8100000F158052078012818BFFFDFA87868B12B +:10B820000021A970A289042042F00402A281626969 +:10B830009047307800281CBF01202871216A03221C +:10B84000087832EA000009D1A28912F4806F05D08D +:10B8500042F00202A2816269022090470121002089 +:10B8600000F087F918B1BDE8704000F063B9BDE899 +:10B87000704000202BE42DE9F14F1B4E002730468D +:10B88000A6F134054068317800F1580A2878B846A6 +:10B89000022818BFFFDFE88940F40070E881716872 +:10B8A0003078FF2091F85410FBF70BF8009800282F +:10B8B0009AF8120000F00681FAF709FFFAF7F7FE8E +:10B8C0004FF00109E0B99AF81200C8B1686A4178EE +:10B8D000B1B10078C0F3C00008E00000E00C002027 +:10B8E000E80E002020010020540100209AF80710E3 +:10B8F000884205D185F80290BDE8F84F00F01AB9EA +:10B90000686A41786981002908BFAF6203D0286B5B +:10B91000F6F726FCA862E88940F02000E881EF7085 +:10B920003078706800F15804834690F82C000128A4 +:10B930001AD1FBF799FB2146584601F054FA98B109 +:10B940003078002870680CBF00F58A7000F5F5703B +:10B95000BBF800104180217A0171617A417180F851 +:10B960000090287AE7F7D8FA686A9AF80610007803 +:10B97000C0F3800088423BD03078706800F15804F2 +:10B9800090F85D0000282FD002284BD067713078E6 +:10B9900000281CBF2079002809D02771AA893946C0 +:10B9A00042F01002AA816A694FF010009047E078D7 +:10B9B000A0B1E770FCF732F8002808BFFFDF0820CD +:10B9C000AA89002142F00802AA816A699047D4E955 +:10B9D0001202411C42F10000C4E91210A0790128B2 +:10B9E0000CBFA77184F80690E88940F48070E88164 +:10B9F000696A9AF807300878C0F3C0029A424ED1BB +:10BA00003278726800F0030002F15804012818BF70 +:10BA100002282DD003281CBFA87940F0040012D0C2 +:10BA2000A8713CE0E86AF6F7D7FA002808BFFFDF04 +:10BA3000D4E91202411C42F10000C4E91210287A34 +:10BA4000E7F76AFAA2E784F80290EA89484642F4E6 +:10BA50000062EA81AA8942F00102AA816A699047DC +:10BA6000E079012801D1E77119E084F8079016E028 +:10BA7000487818B3E98941F40061E981A96A71B194 +:10BA8000FB2884BFA87940F01000C9D8E8790028C5 +:10BA900008BFC84603D080206A6900219047012072 +:10BAA000009900F066F8B0B1B8F1000F1CBF00209B +:10BAB000FFF718FEBDE8F84F00F03CB8E079012828 +:10BAC000D3D1D0E7002818BFFAF739FEE88940F053 +:10BAD0004000E881E3E7B8F1000F1CBF0120FFF749 +:10BAE00001FEFFF7A4FBB8F1000F08BFBDE8F88F17 +:10BAF0000220BDE8F84FF5E570B50D4606463D4815 +:10BB00003C4900784C6850B1FAF773FE034694F84C +:10BB1000542029463046BDE87040FDF767BAFAF771 +:10BB200068FE034694F8542029463046BDE870402C +:10BB300006F0D9B82F4910B54C68FBF745FAFBF76A +:10BB400024FAFBF727F9FBF7A5F9FAF79BFD94F820 +:10BB50002C00012808BFFBF787FA274C00216269F7 +:10BB6000E0899047E269A179A07890470020207091 +:10BB700010BD70B5204C0546002908BF012D06D127 +:10BB8000E07800F10100C0B2E07001282ED8A16970 +:10BB900028468847002829D06179184839B1012DF5 +:10BBA00001BF41780029017811F0100F1ED0A17952 +:10BBB000E1B910490978002908BF012D01D091B1E0 +:10BBC0008DB90F49097811F0100F04BF007810F0FB +:10BBD000100F0BD0A08948B9A06A20B9608910B1B4 +:10BBE00011F0100F02D04FF0000070BD4FF00100B7 +:10BBF00070BD00005401002020010020E00C002056 +:10BC000030010020FE498A78824286BF084490F8BD +:10BC100043010020704710B540F2D311F84809F0F5 +:10BC200078FDFF220821F74809F06BFDF648002156 +:10BC3000417081704FF46171818010BD2DE9F04138 +:10BC40000E46054600F0ADFBED4C102816D004EB77 +:10BC5000C00191F85A0110F0010F1CBF0120BDE88E +:10BC6000F081607808283CBF012081F85A011CD27D +:10BC70006078401C60700120BDE8F0816078082881 +:10BC800013D222780127501C207004EBC2083068C0 +:10BC9000C8F85401B088A8F85801102A28BFFFDF5F +:10BCA00088F8535188F85A71E2E70020BDE8F08126 +:10BCB000D54988707047D4488078704770B4D048B0 +:10BCC00000250178491E4BB2002B46DB00EBC30177 +:10BCD00091F85A1111F0010F3BD04278D9B2521E9F +:10BCE000427000EBC10282F85A5190F802C0002263 +:10BCF000BCF1000F0BD9841894F803618E4202D175 +:10BD0000102A26D103E0521CD2B29445F3D802780F +:10BD1000521ED2B202708A421BD000EBC20200EB6C +:10BD2000C10CD2F85341CCF85341D2F85721CCF88A +:10BD30005721847890F800C00022002C09D9861879 +:10BD400096F8036166450CD1102A1CBF024482F8A4 +:10BD50000311591E4BB2002BB8DAAB48857070BC8A +:10BD60007047521CD2B29442E9D8F2E7A4498A78CB +:10BD7000824286BF01EB0010C01C002070472DE9F5 +:10BD8000F04101261F4690463446002500F009FB8D +:10BD900010282AD09A494FF0000C01EBC00292F80B +:10BDA0005A2102F001058A78002A1ED901EB0C0302 +:10BDB00093F8033183421FD1BCF1100F15D0002F2F +:10BDC00018BF87F800C0887860450ED901EB0C10C9 +:10BDD00010F1030F09D001EB0C0090F84B4190F8E3 +:10BDE0003B0101280CBF0126002648EA050046EA6F +:10BDF00004010840BDE8F0810CF1010303F0FF0CE1 +:10BE00006245D3D8F1E72DE9F05F1F4690460E4614 +:10BE1000814600F0C6FA7A4D044610283CD001460F +:10BE2000AB780020002B0ED92A1892F803218A4201 +:10BE300005D110281CBF1220BDE8F09F03E0401C74 +:10BE4000C0B28342F0D8082B3FD2102C27D0AE7856 +:10BE50001022701CA87005EB061909F10300414679 +:10BE600000F066FF09F183001022394600F060FF00 +:10BE70001021384600F039FF3544102185F8430180 +:10BE8000404600F032FF85F84B0185F80341002061 +:10BE900085F83B01BDE8F09FAB78082B15D22C78D4 +:10BEA000CA46601C287005EBC4093068C9F8540103 +:10BEB000B0884FF0000BA9F85801102C28BFFFDF05 +:10BEC00089F853A189F85AB1C1E70720BDE8F09F6E +:10BED00070B44B488178491E4BB2002BBCBF70BC7C +:10BEE000704700BF817803F0FF0C491ECAB2827010 +:10BEF00050FA83F191F8031194453ED000EB0215FE +:10BF000000EB0C14D5F80360C4F80360D5F80760A3 +:10BF1000C4F80760D5F80B60C4F80B60D5F80F6063 +:10BF2000C4F80F60D5F88360C4F88360D5F88760E3 +:10BF3000C4F88760D5F88B60C4F88B60D5F88F5053 +:10BF4000C4F88F50851800EB0C0402EB420295F800 +:10BF500003610CEB4C0C00EB420284F8036100EB34 +:10BF60004C0CD2F80B61CCF80B61B2F80F21ACF895 +:10BF70000F2195F83B2184F83B2100EBC10292F898 +:10BF80005A2112F0010F33D190F802C00022BCF107 +:10BF9000000F0BD9841894F803518D4202D1102A56 +:10BFA00026D103E0521CD2B29445F3D80278521E37 +:10BFB000D2B202708A421BD000EBC20200EBC10C6D +:10BFC000D2F85341CCF85341D2F85721CCF857213D +:10BFD000847890F800C00022002C09D9851895F8C3 +:10BFE0000351654512D1102A1CBF024482F8031187 +:10BFF000591E4BB2002BBFF675AF70BC70470000E6 +:10C00000100F0020680100205C010020521CD2B2F9 +:10C010009442E3D8ECE7FE4948707047FC4840780A +:10C02000704738B14AF2B811884203D8F84988807D +:10C030000120704700207047F5488088704710B590 +:10C0400000F0AFF9102814D0F24A0146002092F80F +:10C0500002C0BCF1000F0CD9131893F803318B42C6 +:10C0600003D1102818BF10BD03E0401CC0B28445A6 +:10C07000F2D8082010BDE7498A78824286BF01EBDA +:10C080000010833000207047E24B93F802C08445D3 +:10C090009CBF00207047184490F8030103EBC000D8 +:10C0A00090F853310B70D0F854111160B0F858016A +:10C0B000908001207047D74A114491F80321D44958 +:10C0C0000A700268C1F8062080884881704770B500 +:10C0D00016460C460546FAF78DFFFAF7E8F9CC4804 +:10C0E000407868B1CB48817851B12A19002E0CBF35 +:10C0F0008330C01CFAF7B5F9FAF7FCF9012070BDDE +:10C10000002070BD10B5FAF723FA002804BFFF2005 +:10C1100010BDBDE81040FAF741BAFAF719BABD49A7 +:10C120008A7882429CBF00207047084490F803013F +:10C1300001EBC00090F85A0100F0010070472DE9B2 +:10C14000F047B44E00273D46307800288CBFDFF81A +:10C15000C882BDE8F0870024B078002808D93119DA +:10C1600091F80321AA4204D0611CCCB2A042F6D8B7 +:10C170001024A04286BF06EB0410C01C002006EB72 +:10C18000C50999F85A1111F0010F16D050B1102CB1 +:10C1900004D0311991F83B11012903D0102100F08E +:10C1A000A4FD50B108F8074038467B1C99F853218C +:10C1B00009F5AA71DFB2FAF71AFC681CC5B230782B +:10C1C000A842C8D8BDE8F0872DE9F041914C00267F +:10C1D0003546A07800288CBF8F4FBDE8F0816119EB +:10C1E000C0B291F80381A84286BF04EB0510C01CC1 +:10C1F000002091F83B11012903D0102100F075FDBA +:10C2000058B104EBC800BD5590F8532100F5AA7150 +:10C210003046731CDEB2FAF7EAFB681CC5B2A078A0 +:10C22000A842DCD8BDE8F08101447A4810B500EBA3 +:10C2300002100A4601218330FAF713F9BDE81040D5 +:10C24000FAF758B90A46724910B5497841B1714BAD +:10C25000997829B10244D81CFAF703F9012010BDDE +:10C26000002010BD6B4A01EB410102EB4101026865 +:10C27000C1F80B218088A1F80F0170472DE9F0412A +:10C28000644D07460024A878002898BFBDE8F081D7 +:10C29000C0B2A04217D905EB041010F1830612D0EA +:10C2A0001021304600F021FD68B904EB440005EB95 +:10C2B000400808F20B113A463046FBF73EFCB8F84E +:10C2C0000F01A8F80F01601CC4B2A878A042DFD803 +:10C2D000BDE8F08101461022504800F029BD4F48CA +:10C2E00070474C498A78824203D90A1892F8432150 +:10C2F0000AB10020704700EB400001EB400000F263 +:10C300000B10704743498A78824206D9084490F856 +:10C310003B01002804BF01207047002070472DE931 +:10C32000F0410E46074615460621304600F0DDFC7A +:10C33000384C98B1A17871B104F59D7011F0010FDE +:10C3400018BF00F8015FA178490804D0457000F8D3 +:10C35000025F491EFAD10120BDE8F081384631461E +:10C3600000F01FF8102819D0A3780021002B15D950 +:10C37000621892F8032182420BD1102918BF0829B4 +:10C380000CD004EB010080F83B514FF00100BDE8F8 +:10C39000F08101F10101C9B28B42E9D80020BDE86A +:10C3A000F0812DE9F0411B4D0646002428780F4608 +:10C3B000002811D905EBC40090F85311B14206D101 +:10C3C0000622394600F5AA7009F0F8F838B1601C69 +:10C3D000C4B22878A042EDD81020BDE8F0812046F4 +:10C3E000BDE8F0810B4910B44A7801EBC003521E3E +:10C3F0004A70002283F85A2191F802C0BCF1000F64 +:10C4000016D98B1893F8034184420DD1102A07E006 +:10C410005C010020100F002068010020E3100020C4 +:10C420001CBF10BC704703E0521CD2B29445E8D840 +:10C430000A78521ED2B20A7082421BD001EBC202AD +:10C4400001EBC003D2F853C1C3F853C1D2F857214E +:10C45000C3F857218C7891F800C00022002C09D92C +:10C460008B1893F80331634506D1102A1CBF114481 +:10C4700081F8030110BC7047521CD2B29442EFD82D +:10C4800010BC704770B449490D188A78521ED3B257 +:10C490008B7095F8032198423DD001EB001401EB1D +:10C4A000031C00EB4000DCF80360C4F80360DCF818 +:10C4B0000760C4F80760DCF80B60C4F80B60DCF8B8 +:10C4C0000F60C4F80F60DCF88360C4F88360DCF8A8 +:10C4D0008760C4F88760DCF88B60C4F88B60DCF898 +:10C4E0008FC0C4F88FC001EB030C03EB43039CF82F +:10C4F000034101EB430385F8034101EB4000D3F80E +:10C500000B41C0F80B41B3F80F31A0F80F319CF884 +:10C510003B0185F83B0101EBC20090F85A0110F095 +:10C52000010F1CBF70BC704700208C78002C0DD907 +:10C530000B1893F803C1944504D110281CBF70BC9C +:10C54000704703E0401CC0B28442F1D80878401E16 +:10C55000C0B20870904204BF70BC704701EBC203C8 +:10C5600001EBC000D0F853C1C3F853C1D0F8570154 +:10C57000C3F857018C780B780020002C9CBF70BC4E +:10C58000704700BF01EB000C9CF803C19C4506D12D +:10C5900010281CBF084480F8032170BC7047401C61 +:10C5A000C0B28442EED870BC70470000100F00206B +:10C5B00010B50A7B02F01F020A73002202768B1864 +:10C5C00093F808C00CF001034FEA5C0C0CF0010476 +:10C5D00023444FEA5C0C0CF0010423444FEA5C0C4A +:10C5E0000CF001041C444FEA5C0303F0010CA4446A +:10C5F0005B0803F00104A4445B0803F00104A444B5 +:10C600000CEB530300EB020C521C8CF8133090F827 +:10C6100018C0D2B263440376052AD0D3D8B22528F5 +:10C6200088BFFFDF10BD0023C383428401EBC20239 +:10C63000521EB2FBF1F10184704770B5002504462B +:10C6400003290DD04FF4FA4200297BD0012978D07C +:10C65000022918BF70BD0146BDE870405830A7E7F9 +:10C6600004F158067821304609F075F8B571F57176 +:10C6700035737573F573357475717576B5762120DC +:10C6800086F83E00492086F83F00FE2086F87300B9 +:10C6900084F82C502584012084F8540084F8550037 +:10C6A000282184F856101B21218761874FF4A4713B +:10C6B000E187A1871B21218661864FF4A471E18661 +:10C6C000A1861B21A4F84010A4F844104FF4A471D3 +:10C6D000A4F84610A4F842101B21A4F84A10A4F8AC +:10C6E0004C10A4F8481060734FF448606080A4F8C0 +:10C6F000D050A4F8D250A4F8D450A4F8D650A4F83E +:10C70000D850A4F8DA5084F8DD5084F8DF50A4F84B +:10C71000E65084F8E450A4F8F850A4F8FA5084F8ED +:10C720009A5184F89B5184F8A45184F8A55184F857 +:10C73000685184F8705184F8735184F88C5170BD3D +:10C7400000E03FE0A4F8E65084F8DE506188FE483F +:10C750000844B0FBF1F0A4F878004BF68030A4F860 +:10C760007A00E388A4F87E50B4F882C0DB000CFBAA +:10C7700001FCB3FBF1F39CFBF1FC5B1CA4F882C051 +:10C780009BB203FB01FC04F15800A4F88030BCF517 +:10C79000C84FC4BF5B1E0385B2FBF1F2521CC285B9 +:10C7A00001F5802202F5EE32531EB3FBF1F2028452 +:10C7B000C38B03FB01F2B2FBF1F1C1832146BDE85B +:10C7C0007040F5E6B4F89411B4F89831B4F802C0AA +:10C7D00004F15800A4F87E50B4F88240DB0004FB5A +:10C7E0000CF4B3FBF1F394FBF1F45B1C44859BB2B6 +:10C7F00003FB01F40385B4F5C84FC4BF5B1E03857A +:10C80000B2FBF1F2521CC285428C01EBC202521EF5 +:10C81000B2FBF1F20284C28B02FB0CF2B2FBF1F12B +:10C82000C18370BD70B50025044603290DD04FF4B7 +:10C83000FA42002963D001297ED0022918BF70BDB9 +:10C840000146BDE870405830B2E604F15806782140 +:10C85000304608F080FFB571F57135737573F57367 +:10C86000357475717576B576212086F83E004920BD +:10C8700086F83F00FE2086F8730084F82C5025844B +:10C88000012084F8540084F85500282184F85610BB +:10C890001B21218761874FF4A471E187A1871B21A8 +:10C8A000218661864FF4A471E186A1861B21A4F83C +:10C8B0004010A4F844104FF4A471A4F84610A4F852 +:10C8C00042101B21A4F84A10A4F84C10A4F84810F8 +:10C8D0006073A4F8D850202084F8DA0084F8D0508F +:10C8E000C4F8D45084F8045184F8055184F80E51EA +:10C8F00084F80F5184F8F45084F8005170BD6088BA +:10C9000091490144B1FBF0F1A4F878104BF6803165 +:10C91000A4F87A10E388A4F87E50B4F882C0DB0053 +:10C920000CFB00FC9CFBF0FCB3FBF0F304F15801A2 +:10C93000A4F882C05B1C00E021E09BB203FB00FC7A +:10C94000A4F88030BCF5C84FC4BF5B1E0B85B2FB9A +:10C95000F0F2521CCA8500F5802202F5EE32531E19 +:10C96000B3FBF0F20A84CB8B03FB00F2B2FBF0F0D6 +:10C97000C883214604F15800BDE8704018E6D4F899 +:10C98000F830B4F802C004F158005989DB89A4F8E2 +:10C990007E50B4F88240DB0004FB0CF4B3FBF1F3EF +:10C9A00094FBF1F45B1C44859BB203FB01F403850B +:10C9B000B4F5C84FC4BF5B1E0385B2FBF1F2521C35 +:10C9C000C285428C01EBC202521EB2FBF1F202841C +:10C9D000C28B02FB0CF2B2FBF1F1C18370BD2DE9F9 +:10C9E000F003047E0CB1252C03D9BDE8F00312201E +:10C9F0007047002A02BF0020BDE8F003704791F89D +:10CA00000DC01F260123514D4FF00008BCF1000F4F +:10CA100074D0BCF1010F1EBF1F20BDE8F0037047AA +:10CA2000B0F800C00A7C8F7B91F80F907A404F7C61 +:10CA300087EA090742EA072282EA0C0C5FF0000746 +:10CA40000CF0FF094FEA1C2C99FAA9F99CFAACFCEE +:10CA50004FEA19694FEA1C6C49EA0C2C0CEB0C1CD0 +:10CA60007F1C9444FFB21FFA8CFC032FE8D38CEA9E +:10CA7000020C364F0022ECFB057212096FF0240500 +:10CA800002FB05C2D2B201EBD207427602F00705E3 +:10CA90003F7A03FA05F52F4218BF82767ED104FB58 +:10CAA0000CF2120C521CD2B25FF0000400EB040C2A +:10CAB0009CF813C094453CBFA2EB0C02D2B212D337 +:10CAC0000D194FF0000C2D7A03FA0CF73D421CBFF4 +:10CAD000521ED2B2002A71D00CF1010C0CF0FF0CE6 +:10CAE000BCF1080FF0D304F1010C0CF0FF04052C8D +:10CAF000DCD33046BDE8F0037047FFE790F819C07B +:10CB00000C7E474604FB02C2104C4FF0000CE2FBC7 +:10CB1000054C4FEA1C1C6FF024040CFB0422D2B21B +:10CB200001EBD204427602F0070C247A03FA0CFCE3 +:10CB300014EA0C0F1FBF82764046BDE8F003704731 +:10CB400090F818C004E00000FFDB050053E4B36E6A +:10CB5000B2FBFCF40CFB1422521CD2B25FF00004B6 +:10CB600000EB040C9CF813C094453CBFA2EB0C02F4 +:10CB7000D2B212D30D194FF0000C2D7A03FA0CF833 +:10CB800015EA080F1CBF521ED2B27AB10CF1010C8B +:10CB90000CF0FF0CBCF1080FF0D300E011E004F141 +:10CBA000010C0CF0FF04052CDAD3A2E70CEBC40156 +:10CBB00081763846BDE8F0037047FFE70CEBC4010F +:10CBC00081764046BDE8F0037047FD4A016812686F +:10CBD0001140FC4A126811430160704730B4FA49B1 +:10CBE000F74B00244FF0010C0A78521CD2B20A70A5 +:10CBF000202A08BF0C700D781A680CFA05F52A4235 +:10CC0000F2D0097802680CFA01F15140016030BCA1 +:10CC1000704770B46FF01F02010C02EA90251F23C9 +:10CC2000A1F5AA4054381CBFA1F5AA40B0F15500A7 +:10CC300009D0A1F52850AA381EBFA1F52A40B0F1AD +:10CC4000AA00012000D100204FF0000C624664468B +:10CC50008CEA0106F6431643B6F1FF3F11D005F00A +:10CC600001064FEA5C0C4CEAC63C03F00106520890 +:10CC70006D085B08641C42EAC632162CE8D370BC0F +:10CC8000704770BC00207047017931F01F0113BF5D +:10CC9000002000221146704710B4435C491C03F089 +:10CCA000010C5B0803F00104A4445B0803F00104D9 +:10CCB000A4445B0803F00104A4445B0803F00104EE +:10CCC000A4445B0803F001045B08A44403F00104DE +:10CCD000A4440CEB53031A44D2B20529DDDB012A2C +:10CCE0008CBF0120002010BC704730B40022A1F19D +:10CCF000010CBCF1000F11DD431E11F0010F08BF44 +:10CD000013F8012F5C785FEA6C0C07D013F8025F10 +:10CD100022435C782A43BCF1010CF7D1491E5CBF69 +:10CD2000405C0243002A0CBF0120002030BC704749 +:10CD3000002A08BF70471144401E12F0010F03D0B3 +:10CD400011F8013D00F8013F520808BF704700BFCD +:10CD500011F8013C437011F8023D00F8023F521EE9 +:10CD6000F6D1704770B58CB000F110041D46164620 +:10CD70000DF1FF3C5FF0080014F8012C8CF8012045 +:10CD800014F8022D0CF8022F401EF5D101F1100C01 +:10CD90006C460DF10F0108201CF8012C4A701CF89C +:10CDA000022D01F8022F401EF6D1204607F0DCFAD2 +:10CDB0007EB16A1E04F130005FF0080110F8013CFA +:10CDC000537010F8023D02F8023F491EF6D10CB034 +:10CDD00070BD08982860099868600A98A8600B9848 +:10CDE000E8600CB070BD38B505460C466846FAF7E9 +:10CDF00054F9002808BF38BD9DF900202272A07E9A +:10CE0000607294F90A100020511A48BF494295F8FF +:10CE10002D308B42C8BF38BDFF2B08BF38BDE17A2B +:10CE2000491CC9B2E17295F82E30994203D8A17A13 +:10CE30007F2918BF38BDA2720020E072012038BDE2 +:10CE40000C2818BF0B2810D00D2818BF1F280CD095 +:10CE5000202818BF212808D0222818BF232804D052 +:10CE600024281EBF2628002070474FF0010070477D +:10CE70000C2963D2DFE801F006090E13161B323CC1 +:10CE8000415C484E002A5BD058E0072A18BF082AA8 +:10CE900056D053E00C2A18BF0B2A51D04EE00D2A71 +:10CEA0004ED04BE0A2F10F000C2849D946E023B147 +:10CEB000A2F110000B2843D940E0122A18BF112A12 +:10CEC0003ED090F8360020B1122A37D31A2A37D92B +:10CED00034E0162A32D31A2A32D92FE0A2F10F01F8 +:10CEE00003292DD990F8360008B31B2A28D925E04C +:10CEF000002B08BF042A21D122E013B1062A1FD03B +:10CF00001CE0012A1AD11BE01C2A1CBF1D2A1E2A64 +:10CF100016D013E01F2A18BF202A11D0212A18BFCB +:10CF2000222A0DD0232A1CBF242A262A08D005E055 +:10CF300013B10E2A04D001E0052A01D00020704769 +:10CF4000012070472DE9F0410D4604468668F8F748 +:10CF50002CF858B9F7F75AFE40F23471F7F757FB3F +:10CF6000A0602046F8F721F80028F3D095B13046AC +:10CF7000A168F8F767FB00280CDD2844401EB0FBD1 +:10CF8000F5F707FB05F13046F7F741FBA06038469F +:10CF9000BDE8F0810020BDE8F08170B50446904204 +:10CFA00028BF70BD101B642810D325188D4205D8EA +:10CFB000F8F76FFB00281CBF284670BD204670BDE7 +:10CFC0000C5D0200105D0200700100206420ECE79F +:10CFD00011F00C0F13D001F0040100290DBF402205 +:10CFE000102296214FF4167101F5BC71A0EB0103DC +:10CFF00088428CBF93FBF2F0002080B27047022978 +:10D0000019BF6FF00D0101EBD0006FF00E0101EBC5 +:10D010009000F2E7C08E11F00C0F08BF7047B0F51A +:10D02000296F38BF4FF4296070470246808E11F097 +:10D030000C0F08BF704792F85530D18E13F00C0FCB +:10D0400004D0B1F5296F38BF4FF42961538840F2FD +:10D05000E24C03FB0CF3528E4FF4747C0CEB821CFD +:10D060008C459CBF910101F57471591AA1F5967117 +:10D07000884228BF0846B0F5296F38BF4FF42960B1 +:10D080007047084418449830002A14BF0421002136 +:10D0900008447047F0B4002A14BF08220122002B74 +:10D0A00014BF0824012412F00C0F8B8ECA8E25D0D9 +:10D0B00091F85550944615F00C0F04D0BCF5296F2B +:10D0C00038BF4FF4296C4D8840F2E2466E434D8ED6 +:10D0D0004FF4747707EB851767459CBF4FEA851CB3 +:10D0E0000CF5747CA6EB0C0CACF5967C634528BF64 +:10D0F0006346B3F5296F38BF4FF4296314F00C0F62 +:10D1000004D0B2F5296F38BF4FF429621FFA83FCAF +:10D1100000280CBF0123002391F8560014F00C0FD7 +:10D1200008BF00200CEB020108449830002B14BF0C +:10D13000042100210844F0BC70472DE9F00391F868 +:10D1400054200B8E12F00C0F4FF474771CBF07EBBA +:10D1500083139CB256D000BF12F00C0F8B8ECA8E78 +:10D160004D8E91F855C021D016461CF00C0F04D0FE +:10D17000B6F5296F38BF4FF42966B1F8028040F246 +:10D18000E24908FB09F807EB8519B14502D8AE0161 +:10D1900006F57476A8EB0606A6F59676B34228BF88 +:10D1A0003346B3F5296F38BF4FF42963A34228BF34 +:10D1B00023469CB21CF00C0F1CBF07EB85139BB2DF +:10D1C00028D000BF1CF00C0F04D0B2F5296F38BF77 +:10D1D0004FF429629A4228BF1A4600280CBF012347 +:10D1E000002391F856001CF00C0F08BF0020A11876 +:10D1F00008449830002B14BF042100210844BDE8E6 +:10D20000F0037047022A07BF9B003C33DB007033FA +:10D210009CB2A1E7BCF1020F07BFAB003C33EB00AF +:10D2200070339BB2CEE710F0010F1CBF0120704796 +:10D2300010F0020F1CBF0220704710F0040018BF4E +:10D24000082070472DE9F0470446174689464FF0FD +:10D250000108084600F0C5FC0546484600F0C5FC3C +:10D2600010F0010F18BF012625D000BF15F0010FE7 +:10D2700018BF01232AD000BF56EA030108BF4FF0B0 +:10D28000000810F0070F08BF002615F0070F08BFB1 +:10D29000002394F85400B0420CBF00203046387090 +:10D2A00094F85510994208BF00237B70002808BFEE +:10D2B000002B25D115E010F0020F18BF0226D5D1A2 +:10D2C00010F0040F14BF08260026CFE715F0020F58 +:10D2D00018BF0223D0D115F0040F14BF0823002378 +:10D2E000CAE7484600F087FCB4F85810401A00B26C +:10D2F00047F6FE71884201DC002801DC4FF000088F +:10D3000016B1082E0CD018E094F85400012818BF6C +:10D31000022812D004281EBF0828FFDF032D0CD1DD +:10D3200094F8A40148B1B4F8A801012894F8540075 +:10D3300006D0082801D0082038704046BDE8F087A4 +:10D34000042818BF0420F7D1F5E7012814BF0228EC +:10D35000704710F00C0018BF0420704738B4CBB2EF +:10D36000C1F3072CC1B2C0F30724012B07D0022B55 +:10D3700009D0042B08BFBCF1040F2DD006E0BCF18E +:10D38000010F03D128E0BCF1020F25D0012906D0FE +:10D39000022907D0042908BF042C1DD004E0012C69 +:10D3A00002D119E0022C17D001EA0C0161F3070247 +:10D3B00004EA030161F30F22D1B211F0020F18BF8A +:10D3C000022310D0C2F307218DF8003011F0020FB4 +:10D3D00018BF02211BD111E0214003EA0C031940C0 +:10D3E00061F30702E6E711F0010F18BF0123E9D14D +:10D3F00011F0040F14BF08230023E3E711F0010F1D +:10D4000018BF012103D111F0040118BF08218DF8C4 +:10D410000110082B01BF000C012804208DF800002A +:10D42000BDF8000038BC70474FF0000C082902D04E +:10D43000042909D011E001280FD10420907082F84E +:10D4400003C0138001207047012806D00820907087 +:10D4500082F803C013800120704700207047162A0D +:10D4600010D12A220C2818BF0D280FD04FF0230C02 +:10D470001F280DD031B10878012818BF002805D029 +:10D48000162805D000207047012070471A70FBE76E +:10D4900083F800C0F8E7012908D002290BD004293D +:10D4A00012BF082940F6A660704707E0002804BFB5 +:10D4B00040F2E240704740F6C410704700B5FFDF0D +:10D4C00040F2E24000BD00004078704730B50546AC +:10D4D000007801F00F0220F00F0010432870092996 +:10D4E00012D2DFE801F0050705070509050B0F005B +:10D4F00006240BE00C2409E0222407E0012400208C +:10D50000E87003E00E2401E00024FFDF6C7030BD02 +:10D51000007800F00F0070470A68C0F8032089887F +:10D52000A0F807107047D0F803200A60B0F8070091 +:10D53000888070470A68C0F809208988A0F80D1013 +:10D540007047D0F809200A60B0F80D008880704755 +:10D550000278402322F0400203EA81111143017056 +:10D5600070470078C0F3801070470278802322F063 +:10D57000800203EAC1111143017070470078C009AD +:10D58000704770B514460E4605461F2A88BFFFDF58 +:10D590002246314605F1090008F03CF8A01D6870EC +:10D5A00070BD70B544780E460546062C38BFFFDFC7 +:10D5B000A01F84B21F2C88BF1F24224605F1090139 +:10D5C000304608F027F8204670BD70B514460E4668 +:10D5D00005461F2A88BFFFDF2246314605F10900B4 +:10D5E00008F018F8A01D687070BD0968C0F80F1029 +:10D5F00070470A88A0F8132089784175704790F821 +:10D60000242001F01F0122F01F02114380F8241092 +:10D610007047072988BF072190F82420E02322F0D3 +:10D62000E00203EA4111114380F8241070471F30D3 +:10D6300008F0A5B910B5044600F009FB002818BF92 +:10D64000204410BDC17811F03F0F1BBF027912F0CA +:10D65000010F0022012211F03F0F1BBF037913F0CD +:10D66000020F002301231A4402EB4202530011F07F +:10D670003F0F1BBF027912F0080F0022012203EBBB +:10D68000420311F03F0F1BBF027912F0040F00227A +:10D690000122134411F03F0F1BBF027912F0200F3B +:10D6A0000022012202EBC20203EB420311F03F0F02 +:10D6B0001BBF027912F0100F0022012202EB42027E +:10D6C0001A4411F03F0F1BBF007910F0400F0020EB +:10D6D0000120104410F0FF0014BF01210021084474 +:10D6E000C0B2704770B50278417802F00F02082A84 +:10D6F0004DD2DFE802F004080B4C4C4C0F14881F8D +:10D700001F280AD943E00C2907D040E0881F1F28B2 +:10D7100003D93CE0881F1F2839D8012070BD4A1E5C +:10D72000FE2A34D88446C07800258209032A09D00D +:10D7300000F03F04601C884204D86046FFF782FF77 +:10D74000A04201D9284670BD9CF803004FF00106A5 +:10D7500010F03F0F1EBF1CF10400007810F0100FF6 +:10D7600013D064460421604600F071FA002818BF07 +:10D7700014EB0000E6D0017801F03F012529E1D249 +:10D7800080780221B1EB501FDCD3304670BD002001 +:10D7900070BD70B50178012501F00F010024042946 +:10D7A0000AD007290DD008291CBF002070BD407881 +:10D7B0000E2836D0204670BD4078801F1F2830D9F3 +:10D7C000F8E7844640789CF803108A09032AF1D0D0 +:10D7D00001F03F06711C8142ECD86046FFF732FF32 +:10D7E000B042E7D89CF8030010F03F0F1EBF1CF1B9 +:10D7F0000400007810F0100F13D066460421604634 +:10D8000000F025FA002818BF16EB0000D2D00178EE +:10D8100001F03F012529CDD280780221B1EB501FC4 +:10D82000C8D3284670BD10B4017801F00F01032958 +:10D8300020D0052921D14478B0F81910B0F81BC0C8 +:10D84000B0F81730827D222C17D1062915D3B1F5F7 +:10D85000486F98BFBCF5FA7F0FD272B1082A98BF03 +:10D860008A420AD28B429CBFB0F81D00B0F5486FC7 +:10D8700003D805E040780C2802D010BC0020704787 +:10D8800010BC012070472DE9F0411F4614460D00E1 +:10D89000064608BFFFDF2146304600F0D8F90400F5 +:10D8A00008BFFFDF30193A462946BDE8F04107F0CE +:10D8B000B1BEC07800F03F007047C02202EA81117B +:10D8C000C27802F03F021143C1707047C0788009EE +:10D8D0007047C9B201F00102C1F340031A4402EBE0 +:10D8E0004202C1F3800303EB4202C1F3C00302EB27 +:10D8F0004302C1F3001303EB43031A44C1F3401383 +:10D9000003EBC30302EB4302C1F380131A4412F08A +:10D91000FF0202D0521CD2B20171C37802F03F0163 +:10D9200003F0C0031943C170511C417070472DE9C9 +:10D93000F0410546C078164600F03F041019401C1F +:10D940000F46FF2888BFFFDF281932463946001DE1 +:10D9500007F060FEA019401C6870BDE8F081C17836 +:10D96000407801F03F01401A401E80B2704710B568 +:10D9700090F803C00B460CF03F0144780CF03F0CCC +:10D98000A4EB0C0CACF1010C1FFA8CF4944288BF90 +:10D9900014462BB10844011D2246184607F03AFEF2 +:10D9A000204610BD4078704700B5027801F00303AF +:10D9B00022F003021A430270012914BF0229002138 +:10D9C00004D0032916BFFFDF012100BD417000BD57 +:10D9D00000B5027801F0030322F003021A4302703B +:10D9E000012914BF0229002104D0032916BFFFDF3B +:10D9F000012100BD417000BD007800F003007047B8 +:10DA0000417841B1C078192803D2C04A105C8842DD +:10DA100001D1012070470020704730B50124054630 +:10DA2000C17019293CBFB948445C02D3FF2918BF13 +:10DA3000FFDF6C7030BD70B515460E4604461B2ADC +:10DA400088BFFFDF65702A463146E01CBDE87040A4 +:10DA500007F0E0BDB0F807007047B0F80900704764 +:10DA6000C172090A01737047B0F80B00704730B4F7 +:10DA7000B0F80720B0F809C0B0F805300179941F5C +:10DA800040F67A45AC4298BFBCF5FA7F0ED269B138 +:10DA9000082998BF914209D293429FBFB0F80B006A +:10DAA000B0F5486F012030BC98BF7047002030BCF3 +:10DAB0007047001D07F063BF021D0846114607F0BE +:10DAC0005EBFB0F809007047007970470A6842608D +:10DAD00049688160704742680A60806848607047A2 +:10DAE0000988818170478089088070470A68C0F87A +:10DAF0000E204968C0F812107047D0F80E200A6056 +:10DB0000D0F81200486070470968C0F816107047D6 +:10DB1000D0F81600086070470A6842604968816062 +:10DB2000704742680A608068486070470968C16051 +:10DB30007047C06808607047007970470A684260A3 +:10DB400049688160704742680A6080684860704731 +:10DB50000171090A417170478171090AC1717047E9 +:10DB60000172090A417270478172090AC1727047D5 +:10DB700080887047C0887047008970474089704727 +:10DB800001891B2924BF4189B1F5A47F07D381886E +:10DB90001B2921BFC088B0F5A47F01207047002059 +:10DBA00070470A68426049688160704742680A604D +:10DBB000806848607047017911F0070F1BBF4079FA +:10DBC00010F0070F002001207047017911F0070FB6 +:10DBD0001BBF407910F0070F002001207047017132 +:10DBE0007047007970474171704740797047817183 +:10DBF000090AC1717047C088704745A282B0D2E956 +:10DC00000012CDE900120179407901F0070269465E +:10DC10001DF80220012A07D800F00700085C01283F +:10DC20009EBF012002B07047002002B07047017112 +:10DC3000704700797047417170474079704730B53F +:10DC40000C460546FB2988BFFFDF6C7030BDC378EA +:10DC5000024613F03F0008BF70470520127903F019 +:10DC60003F0312F0010F36D0002914BF0B2070477C +:10DC700012F0020F32D0012914BF801D704700BF7F +:10DC800012F0040F2DD0022914BF401C704700BFB2 +:10DC900012F0080F28D0032914BF801C704700BF62 +:10DCA00012F0100F23D0042914BFC01C704700BF0E +:10DCB00012F0200F1ED005291ABF1230C0B27047D3 +:10DCC00012F0400F19D006291ABF401CC0B270478D +:10DCD000072918D114E00029CAD114E00129CFD1B5 +:10DCE00011E00229D4D10EE00329D9D10BE0042997 +:10DCF000DED108E00529E3D105E00629E8D102E0FC +:10DD0000834288BF7047002070470000145D020006 +:10DD100000010102010202032DE9F041FC4E04461C +:10DD2000736893F828000127002528B193F8A00113 +:10DD3000D8B993F84801C0B193F8480198B383F873 +:10DD4000A071D3F84C113C2269B36570201D07F017 +:10DD500061FC052020702771706890F8A0110029DF +:10DD600018BF80F8485107D034E083F8A05103F180 +:10DD70002A014FF48E72E7E71D212A3007F0C9FC13 +:10DD800070687F2180F84510FF2180F8381080F8F6 +:10DD90002B1080F83E10818E21F0600120318186A9 +:10DDA00080F8285016E0FFE793F82200012814D0ED +:10DDB000187801281BD093F8500101281CBF0020BF +:10DDC000BDE8F081657018202070D3F852016060C2 +:10DDD00083F850510120BDE8F08165700720207064 +:10DDE000586A606083F822500120BDE8F0816570B8 +:10DDF000142020702022991C201D07F00BFC257296 +:10DE000071680D7081F85051C24882888284D0F8C0 +:10DE10006421527B80F8262080F82270D1F86401BA +:10DE20000088F4F7E3FEF4F78AFBD3E7B8484068CC +:10DE30000178002914BF80884FF6FF70704770B5D5 +:10DE4000B34C0546606890F8741120460629806836 +:10DE500003D0FFF73BFDB8B127E0FFF737FD10BB5C +:10DE6000A068FFF733FD00BB606890F8A40110F0D4 +:10DE70000C0F1AD0A068C17811F03F0F1CBF0079B9 +:10DE800010F0100F11D00EE0616891F874010828AD +:10DE900009D025B191F83E00FF2806D003E091F8A3 +:10DEA0002B00FF2801D0012070BD002070BDF8B507 +:10DEB000974C07460E46606890F82810002906BF68 +:10DEC00090F848110029F8BD00F1330520787F282B +:10DED00008BFFFDF207828707F202070606890F8EE +:10DEE0009A1100F5D470085C012808BF012508D0FC +:10DEF000022808BF022504D0042816BF08280325DD +:10DF0000FFDF606880F8365090F8971180F846106F +:10DF100090F87411072911D190F8A401012808BFC5 +:10DF2000012508D0022808BF022504D0042816BF06 +:10DF300008280325FFDF606880F83750606890F894 +:10DF400074014FF00005062804D1A068FFF7BEFC5D +:10DF500000283CD0606890F87411082904BF90F83C +:10DF6000A10102280ED04FF00301A068FFF762FB69 +:10DF700040B141780A09616881F838200088C0F30F +:10DF80000B0048870095A068FFF7C2FA6168BDF8EA +:10DF9000005091F83420520962F34615ADF8005054 +:10DFA000072818BFFFDF1CD0BDF800000090606894 +:10DFB000BDF8001081860421A068FFF73BFB002814 +:10DFC0007DD0B0F80100C004C00C79D0B0E0A068EA +:10DFD000C17811F03F0F1CBF007910F0100FB9D1BC +:10DFE000D0E791F87401062816D0072836D0082803 +:10DFF00073D00A2818BFFFDFD6D145F00A00ADF86C +:10E00000000091F83E10FF2914BF0121002161F3A7 +:10E010008200ADF80000C7E7A068FFF757FC58B1D1 +:10E02000012808BF45F0010046D0022814BFFFDFD9 +:10E0300045F0020040D0B7E7A068C17811F03F0F6B +:10E040001CBF007910F0020FAED00120FFF7F7FEE1 +:10E05000002808BF45F004002ED0A5E7A068FFF710 +:10E0600035FCB0B1012804BF45F00100ADF8000057 +:10E070000FD0022898D145F00200ADF80000A16849 +:10E08000CA7812F03F0F1CBF097911F0020F21D19D +:10E0900018E0A068C17811F03F0F1CBF007910F0A4 +:10E0A000020F05D1606890F83E00FF283FF47CAF76 +:10E0B000BDF8000040F00400ADF8000074E72BE06C +:10E0C0002FE00AE0616891F83E10FF2908BF20F0B8 +:10E0D0000400F1D040F00400EEE791F83E00FF2884 +:10E0E0001CBF45F00400ADF8000091F8A101022822 +:10E0F000BDF800000CBF40F0080020F00800ADF8AB +:10E1000000000CBF40F0020020F00200D4E7000045 +:10E1100074010020F41000206068818E21F06001FD +:10E1200005E06068818E21F0600101F14001818687 +:10E13000606890F8741106290DD190F8A40110F0D0 +:10E140000C0F08D0A068C17811F03F0F1CBF0079F8 +:10E1500010F0100F10D1A068C17811F03F0F0BD054 +:10E16000017911F0400F07D04FF00601FFF762FA76 +:10E170006168007881F84500606890F874010628AD +:10E1800004D00020FFF75BFE18BB04E0022F18BF8D +:10E19000012FF6D1F8BDA068C17811F03F0F33D040 +:10E1A000017911F0010F2FD0616801F12C0791F86E +:10E1B000783101F12B05FF2B0CD03A462946184641 +:10E1C000FDF762FF002808BFFFDF287840F002005B +:10E1D000287019E0FFF7C5F92870A068FFF798F9D3 +:10E1E000072804D23946A068FFF79DF90CE0A06823 +:10E1F000FFF78EF9072807D10021A068FFF71AFA68 +:10E20000016839608088B8800120FFF718FE80BB64 +:10E21000A068C17811F03F0F2BD0017911F0020FE7 +:10E2200027D0616801F13F0591F876216F1E1AB180 +:10E23000022E18BF032E08D0FFF76AF907280AD26A +:10E240002946A068FFF77DF912E0D1F85A0128604D +:10E25000B1F85E010BE0A068FFF75AF9072807D173 +:10E260000121A068FFF7E6F9016829608088A8808D +:10E270003E70606890F87401062808BFF8BD072852 +:10E2800018BF082802D00A2806D0F8BDA068FFF7FA +:10E290001DFB022808BFF8BD606800F14705A068B3 +:10E2A000FFF75DFB626892F83230C3F1FF018842EC +:10E2B00028BF084605D9918E21F0600101F1400187 +:10E2C0009186C2B203EB0501A068FFF750FB6168BD +:10E2D00091F83220104481F83200F8BD2DE9F04762 +:10E2E000FB4D06466C6894F82800002818BFBDE86E +:10E2F000F0871D212A34204607F00BFA01272770EA +:10E30000A868FFF705F920B3012827D002282AD0F2 +:10E31000062818BFFFDF2BD004F11D01A868FFF706 +:10E3200040F92072686804F1020904F1010890F8CC +:10E330007801FF2821D04A464146FDF7A5FE002876 +:10E3400008BFFFDF98F8000040F0020088F80000E6 +:10E3500031E0608940F013006081DDE7608940F0C2 +:10E3600015006081DEE7608940F010006081D3E72E +:10E37000608940F012006081CEE7A868FFF7F1F8ED +:10E3800088F80000A868FFF7C3F8072804D24946B8 +:10E39000A868FFF7C8F80EE0A868FFF7B9F80728E3 +:10E3A00009D10021A868FFF745F90168C9F80010F4 +:10E3B0008088A9F80400287804F109087F2808BF9C +:10E3C000FFDF287888F800004FF07F0985F800907B +:10E3D000277300206073FF20A073A17A11F0040F4F +:10E3E00008BF20752DD0686804F1150804F1140ADF +:10E3F00090F8761119B1022E18BF032E09D0A86823 +:10E40000FFF786F807280BD24146A868FFF799F86E +:10E4100015E0D0F85A11C8F80010B0F85E010CE011 +:10E42000A868FFF775F8072809D10121A868FFF748 +:10E4300001F90168C8F800108088A8F804008AF87B +:10E44000006084F81B90686890F89711217780F835 +:10E450002870BDE8F047062003F0F9BB2DE9F04134 +:10E460009B4C606890F82810FF250027A1B91D215A +:10E470002A3007F04EF960687F2180F8451080F857 +:10E48000385080F82B5080F83E50818E21F060018A +:10E490002031818680F82870606800F5D47290F889 +:10E4A0009A11895C80F8A411002002F0E4FF18B3EF +:10E4B000F8F7FEFC6068874990F879010E5C3046F9 +:10E4C000F8F7CBFA606880F8976190F8A41111F022 +:10E4D0000C0F0CBF25200F20F8F7D5F9606890F8D5 +:10E4E000A4110120F8F7D1FA606890F868110329A7 +:10E4F00018BF022910D103E0BDE8F04101F0A4B833 +:10E5000090F89A1100F5D470085C012804D101221A +:10E5100011460020F8F7E2FDF8F7B0FD606890F8CA +:10E52000A461012E07BF4FF0010803214FF000083E +:10E530000521A068FDF786FE616881F8760150B17B +:10E54000B8F1000F18BF402623D000BFF7F79BFF9C +:10E550003046F8F745FD6068D0F87C01F8F7B4FC68 +:10E56000606890F87811FF291CBF00F29110FDF748 +:10E57000A2FD6068062180F8775180F8785180F814 +:10E58000867180F8857180F8A17180F87411BDE8FA +:10E59000F08116F00C0F14BF55265026D6E770B543 +:10E5A0004B4C0646606800F5BA752046806841B15C +:10E5B000D0F80510C5F81D10B0F80900A5F8210025 +:10E5C00003E005F11D01FEF7AEFFA068FEF7C9FFED +:10E5D00085F82400A0680021032E018002D0052EBA +:10E5E00004D046E00321FEF771FF42E00521FEF76B +:10E5F0006DFF6068D0F8640100F10E01A068FEF7BD +:10E60000F4FF6068D0F8640100F11201A068FEF721 +:10E61000F0FFD4E90110D1F86421527D8275D1F860 +:10E620006421D28AC275120A0276D1F86421528816 +:10E630004276120A8276D1F864219288C276120A52 +:10E640000277D1F86421D2884277120A8277D1F812 +:10E6500064110831FEF7EBFF6068D0F86401017EB9 +:10E66000A068FEF7CCFF606890F8AA11A068FEF7DA +:10E67000D0FF05F11D01A068FEF75CFF95F824109E +:10E68000A068FEF772FF606800F5AD7590F85961FB +:10E6900090F8751191B190F86811032906D190F89E +:10E6A0006111002918BF90F87A0101D190F8770123 +:10E6B000FDF717FE00281CBF012605462946A06865 +:10E6C000FEF72AFF3146A068BDE87040FEF740BF64 +:10E6D00074010020305D0200FE49496881F8730131 +:10E6E000704770B5FB4D686890F8741102291FBF20 +:10E6F00090F8741101290C2070BD00F166014FF0F3 +:10E700000004C0F84C1180F848414FF01D0100F1A1 +:10E710002A0006F0FEFF68687F2180F84510FF217F +:10E7200080F8381080F82B1080F83E10818E21F090 +:10E7300060012031818680F82840047080F82240F2 +:10E7400080F85041012680F8A06190F8760130B140 +:10E75000F8F750FCF7F7ABFE686880F87641686818 +:10E76000072180F8724180F8616180F8684180F883 +:10E77000794180F8734180F8A14180F86011002050 +:10E7800070BDD44910B5886048680021A0F8A51173 +:10E7900080F8A711012180F87411FFF7A2FF00286B +:10E7A00018BFFFDF10BD2DE9F047CA4C0546606871 +:10E7B00090F87401012818BF022804D003281CBF58 +:10E7C0000C20BDE8F087687A022823D0F8F79DF87E +:10E7D0000220F8F773FB606890F97301F8F72FF9DE +:10E7E000A068F8F76EFBBC48F8F74EFBBB48F8F79B +:10E7F0002CF9606890F8591100F5AD70F8F7D7F86A +:10E800000F210720F8F7EFF8606890F8610100B376 +:10E81000FDF7DAFC6068297A00F5D47280F89A1165 +:10E82000297A895C80F8A4116968C0F87C1129688C +:10E83000C0F880116A7A012500266AB1012A23D026 +:10E840000527022A08BF80F8747175D0032A7ED08C +:10E85000BBE0FDF774FCDDE7A14F90F860C100223A +:10E8600090F87911491CA7FB01835B08A3EB830394 +:10E87000194480F879112CFA01F111F0010F03D13C +:10E88000511CCAB2032AEBD380F8A16190F8711130 +:10E89000002904BF90F87501002849D0F6F7B6F9B1 +:10E8A000074660683946D0F86C01F6F7CBFEDFF812 +:10E8B0003482814690FBF8F008FB109041423846C4 +:10E8C000F5F7A5FE6168C1F86C0199FBF8F0D1F885 +:10E8D0009C211044C1F89C01FDF7AEFB0146606825 +:10E8E000D0F89C21914223D8C0F86C71C0F89C618B +:10E8F00090F8750100281CBF0120FDF7BFFC012125 +:10E90000606890F87221002A1CBF90F87121002ADB +:10E910000ED090F8592100F5AD73012A04D15A792F +:10E9200002F0C002402A09D000F5AD70F9F73CF9B9 +:10E930006168042081F8740147E008E0FDF7CFFC2E +:10E9400061682A4601F5AD71F9F7F7F8F0E700299B +:10E9500018BFFFDF606800F2A51690F8A701400914 +:10E9600008BF012507D0012808BF022503D00228CF +:10E9700014BF00250825F8F79BFA307800F03F0611 +:10E980003046F8F76AF86068294680F89761FF20FA +:10E99000F7F779FF29460120F8F7BDF8F8F76EFB85 +:10E9A0000521A068FDF74EFC616881F8760148B149 +:10E9B00015F00C0F0CBF50255525F7F764FD2846C0 +:10E9C000F8F70EFB606880F874710020BDE8F087EE +:10E9D00010B5404C606890F8741104290DD00529D9 +:10E9E0001CBF0C2010BD90F8A10148B100F07EFEC4 +:10E9F0006168082081F8740108E0FFF72FFD05E049 +:10EA000000F074FE6168072081F87401002010BDD9 +:10EA10003049002210F0010F496802D0012281F82C +:10EA2000A82110F0080F03D01144082081F8A80194 +:10EA3000002070472749496881F87001704710B578 +:10EA4000244C636893F85831022B14BF032B002821 +:10EA50000BD100291ABF0229012000201146FDF721 +:10EA6000EEFA08281CBF012010BD606890F858011C +:10EA7000002816BF022800200120BDE81040F9F749 +:10EA80001DB81448406890F85801002816BF0228A5 +:10EA900000200120F9F712B80E49496881F85801A1 +:10EAA00070470C49496881F87201704770B5094C8C +:10EAB000616891F85801002816BF02280020012043 +:10EAC00081F8590101F5AD71F8F7E2FF606890F83F +:10EAD000581109E0740100202D5D0200335D020031 +:10EAE000ABAAAAAA40420F00022916BF032901219E +:10EAF000002180F8751190F8592100F5AD734FF0A1 +:10EB00000005012A04BF5B7913F0C00F0AD000F59D +:10EB1000AD73012A04D15A7902F0C002402A01D013 +:10EB2000002200E0012280F87121002A04BF0029A0 +:10EB300070BDC0F89C51F6F769F86168C1F86C01C6 +:10EB400091F8750100281CBF0020FDF797FB0026F7 +:10EB5000606890F8721100291ABF90F871110029AD +:10EB600070BD90F8592100F5AD71012A04D14979A1 +:10EB700001F0C001402906D02946BDE8704000F5EB +:10EB8000AD70F9F711B8FDF7AAFB61683246BDE830 +:10EB9000704001F5AD71F8F7D0BF70B5FE4D0C4671 +:10EBA00000280CBF01230023696881F8613181F8D6 +:10EBB0006A014FF0080081F87A010CD1002C1ABFCD +:10EBC000022C012000201146FDF739FA6968082857 +:10EBD00081F87A0101D0002070BD022C14BF032CF3 +:10EBE0001220F8D170BD002818BF112070470328EB +:10EBF000E94A526808BFC2F8641182F8680100202F +:10EC0000704710B5E44C606890F8681103291CBF88 +:10EC1000002180F8841101D0002010BD0123D0F81C +:10EC200064111A460020FEF735FA6168D1F86421B4 +:10EC3000526A904294BF0120002081F88401EBE7E2 +:10EC4000D548416891F86801032804D0012818BF0D +:10EC5000022807D004E091F86A01012808BF704734 +:10EC60000020704791F86901012814BF0328012092 +:10EC7000F6D1704770B5F8F7A7F9F8F786F9F8F705 +:10EC800089F8F8F707F9C44C0025606890F8760118 +:10EC900030B1F8F7AFF9F7F70AFC606880F8765101 +:10ECA00060680121A0F8A55180F8A75180F874117F +:10ECB00080F85051002070BDB74810B5406800F58D +:10ECC000C47006F0ECF9002010BDB3480121406883 +:10ECD00090F86821032A03BF80F85211D0F864210C +:10ECE0001288002218BF80F85221A0F8542180F821 +:10ECF00050117047A849496881F8AA017047017806 +:10ED0000002311F0010FA44949680AD04278032A70 +:10ED100008BFC1F8643181F86821012281F8A82177 +:10ED20001346027812F0040F0CD082784FF0000CDA +:10ED3000032A08BFC1F864C181F868210B44082286 +:10ED400083F8A821C27881F858210279002A16BFD9 +:10ED5000022A0123002381F8613181F86921427977 +:10ED600081F86021807981F870014FF000007047D0 +:10ED70008948406800F5D27070472DE9F041864C13 +:10ED800005460E46606890F87401032818BFFFDF3F +:10ED9000022D1EBF032DFFDFBDE8F0814FF00007FD +:10EDA0004FF00105AEB1606890F8371089B1818EDF +:10EDB00021F0600101F14001818690F8282042B9DC +:10EDC00080F8285011F0080F14BF0720062002F029 +:10EDD0003EFF6068A0F8A57180F8A77180F87451B3 +:10EDE000BDE8F08100F030BC2DE9F0476A4C0646E2 +:10EDF000894660684FF00108072E90F8617138BFAE +:10EE0000032533D3082E4FF0000088BFBDE8F087FC +:10EE1000FFF715F8002873D1A068C17811F03F0FF3 +:10EE200012D0027912F0010F0ED061684FF0050583 +:10EE300091F87621002A18BFB9F1000F16D091F889 +:10EE4000A411012909D011E011F03F0F1ABF007978 +:10EE500010F0100F002F53D14CE04FF001024FF093 +:10EE60000501FDF734F9616881F87601A168087839 +:10EE70002944C0F3801030B1487900F0C000402828 +:10EE800008BF012000D00020616891F876110029A8 +:10EE900018BF002807D0FDF735F90146606880F8F3 +:10EEA000771180F88581606890F87711FF292AD062 +:10EEB00080F878110846FDF732F940EA07056068E6 +:10EEC00090F87721FF2A18BF002D10D0072E0ED3FF +:10EED000A068C17811F03F0F09D0017911F0020F3D +:10EEE00005D00B21FDF7A0F9606880F886812846DF +:10EEF000BDE8F087FCF7DFFE002808BFBDE8F0871B +:10EF00000120BDE8F087A36890F8612159191B78AA +:10EF1000C3F3801C00F277136046FCF730FF054610 +:10EF2000CDE72DE9F0411C4C84B0A068FEF7CEFC83 +:10EF30000126002550B1022501287CD002287BD073 +:10EF4000F7F728FF04B00620BDE8F081F7F722FFAD +:10EF5000606890F86801032800F0C780A068C17855 +:10EF600011F03F0F05D0027912F0100F18BF0126E3 +:10EF700000D10026002E14BF0822012211F03F0FFD +:10EF800046D0007932EA000142D110F0020F09D0D8 +:10EF90000120FEF754FF01E074010020002808BFA3 +:10EFA000012000D000208DF800508DF804508DF81D +:10EFB0000850FF27D0B102AA694601A800F007FC5B +:10EFC000606890F859719DF80000002818BF47F05C +:10EFD00002070BD1A068FEF7D1FA80460121A06894 +:10EFE000FEF728FB4146F7F7EAFC90B166B1012035 +:10EFF00000F04DFB002878D039460020FEF757FF7F +:10F00000606880F890516CE03946002000F004FB05 +:10F010006BE0606890F86901032818BF022864D18A +:10F020009DF80400002860D09DF8000000285CD105 +:10F030007EB1012001E011E037E000F028FB00285C +:10F0400053D0FE210020FEF732FF606880F8905117 +:10F0500047E0FE21002000F0DFFA46E0F7F79AFED5 +:10F06000A0681821C27812F03F0F3ED00279914378 +:10F070003BD10421FEF7DEFA616891F86821032A8A +:10F0800001BF8078B5EB501F91F8840100282CD087 +:10F090004FF0010000F0FBFA38B3FF210120FEF72A +:10F0A00006FF606880F890611BE0F7F773FE606808 +:10F0B00090F86801032818D0A0681821C27812F0CF +:10F0C0003F0F12D0007931EA00000ED1012000F08C +:10F0D000DEFA50B1FF210220FEF7E9FE606880F8F9 +:10F0E000905104B00320BDE8F08104B00620BDE8D3 +:10F0F000F081F0B5FC4C074683B060686D4600783F +:10F10000002818BFFFDF002661688E70D1F8640107 +:10F1100002888A8042884A8382888A83C088C8831A +:10F1200081F8206047B10121A068FEF783FA054607 +:10F13000A0680078C10907E06946A068FEF7F3F906 +:10F14000A0680078C0F380116068012790F87521ED +:10F15000002A18BF002904D06A7902F0C002402AB0 +:10F1600026D090F87221002A18BF002903D06979AF +:10F1700011F0C00F1CD000F10E0006F0F7FB616823 +:10F1800091F87801FF2819D001F10802C91DFCF798 +:10F190007BFF002808BFFFDF6068C17941F00201F2 +:10F1A000C171D0F891114161B0F89511018310E05F +:10F1B0002968C0F80E10A9884182E0E7D1F86401FF +:10F1C000427ECA71D0F81A208A60C08B88814E6155 +:10F1D0000E8360680770D0F8642190F8731182F88C +:10F1E0005710D0F864010088F3F700FDF3F798F9A1 +:10F1F00003B0F0BD2DE9F041BB4C05460126606827 +:10F20000002790F86811012918BF022902D00329AC +:10F2100018BFFFDF55B1A068FEF764FA18B9A068FF +:10F22000FEF7B7FA10B100F07FFB2DE0606890F8B0 +:10F2300074017F25801F062828BFBDE8F081DFE824 +:10F2400000F003191930443EA748F7F726FF0028BD +:10F2500008BF2570F7F708FF606890F8760130B1B5 +:10F26000F7F7C8FEF7F723F9606880F87671F7F7CB +:10F2700091FD20E09C48F7F710FF002808BF25709B +:10F28000F7F7F2FE00F033FB102880F0DE80DFE8B5 +:10F2900000F036B6BFC3DCDC12CCD4DCDCDC249C52 +:10F2A00038699148F7F7F9FE002808BF2570F7F78D +:10F2B000DBFEF7F76FFDBDE8F041FFF7CFB88A48F6 +:10F2C000F7F7EBFE30B9257004E08748F7F7E5FE65 +:10F2D0000028F8D0F7F7C8FE9AE0032002F0CBF838 +:10F2E000002871D000210320FFF759F901221146AF +:10F2F0001046F7F7F3FE61680C2081F87401BDE851 +:10F30000F081606800F5BA75042002F0B4F80028B6 +:10F310007ED00E202870012002F099FCA068616860 +:10F320000078C0F3401081F8990100210520FFF713 +:10F3300036F96E49A0684FF0200CD1F864210378AB +:10F34000527B23F020030CEA42121A430270D1F8D8 +:10F35000640195F82530427B1A4042732820D1F889 +:10F3600064112DE0062002F086F8002850D05F4D91 +:10F370000F2085F87401022002F069FC6068012109 +:10F3800090F8A4210846F7F7A9FEA0686168007804 +:10F39000C0F3401081F8990101210520FFF7FFF823 +:10F3A000D5F864014673A068017821F0200101704E +:10F3B000F8F71AFA002818BFFFDF2820D5F86411E3 +:10F3C00081F85600BDE8F08122E0052002F053F8F4 +:10F3D000F0B101210320FFF7E2F8F8F705FA002861 +:10F3E00018BFFFDF6068012190F8A4210846F7F7F5 +:10F3F00075FE61680D2081F87401BDE8F0816068D8 +:10F40000A0F8A57180F8A77180F87461BDE8F0815B +:10F41000BDE8F04100F018B96168032081F874017B +:10F42000BDE8F041082002F012BC00F05FF961680D +:10F43000072081F87401BDE8F08100F057F9616898 +:10F44000082081F87401BDE8F081FFDFBDE8F0819C +:10F4500070B5254C606890F8741100230C2938D0E1 +:10F4600001220D2944D00E2953D00F291CBFFFDFE4 +:10F4700070BD042002F0EBFB606890F8A4110E2030 +:10F48000F7F701FA606890F8A40110F00C0F14BFB0 +:10F49000282100219620F7F735FDF7F7EFFD60688A +:10F4A000052190F8A451A068FCF7CCFE616881F8B2 +:10F4B000760148B115F00C0F0CBF50255525F6F715 +:10F4C000E2FF2846F7F78CFD61680B2081F8740194 +:10F4D00070BDF7F7D3FD00219620F7F713FD6168A3 +:10F4E000092081F8740170BD74010020F41000201F +:10F4F00090F8A40110F00C0F14BF282100219620D1 +:10F50000F7F700FDF7F7BAFD61680A2081F874018A +:10F51000E9E7A0F8A53180F8A73180F87421002030 +:10F52000FFF7E7FDBDE87040032002F090BB70B527 +:10F53000FC4C606890F874117F25891F062928BF4C +:10F5400070BDDFE801F017321D033D11F548F7F7F4 +:10F55000A4FD002808BF2570F7F786FDF7F71AFC11 +:10F56000BDE87040FEF77ABFEE48F7F796FD60BB46 +:10F5700025702AE0EB48F7F790FDD8B9257019E01F +:10F5800090F8371089B1818E012221F0600140315D +:10F59000818690F8283043B980F8282011F0080FB0 +:10F5A00014BF0720062002F052FBDE48F7F775FD76 +:10F5B0000028E3D0F7F758FDBDE8704000F044B8EC +:10F5C000D848F7F76AFD0028D2D0F7F74DFD6068FC +:10F5D000002100F5C47005F013FDBDE8704000F097 +:10F5E00033B870B5CF4C06460D46012908D0606887 +:10F5F00090F8A4213046BDE87040134602F073BB7A +:10F60000F7F7F7F861680346304691F8A4212946D8 +:10F61000BDE8704002F067BB10B5FEF748FCC1487A +:10F62000406890F82810002918BF10BD012280F80A +:10F63000282090F8340010F0080F14BF072006208F +:10F64000BDE8104002F003BB70B5F7F7BDFCF7F75B +:10F650009CFCF7F79FFBF7F71DFCB24C0025606898 +:10F6600090F8760130B1F7F7C5FCF6F720FF606837 +:10F6700080F876516068022180F87411A0F8A551D5 +:10F6800080F8A751BDE87040002002F0E0BA70B5E4 +:10F69000A44D06460421A868FDF7CCFF044668681F +:10F6A00090F82800A0B901F0C9FE217811F0800F70 +:10F6B00014BF4FF496711E21B4F80120C2F30C025E +:10F6C00012FB01F10A1AB2F5877F28BF814201D2ED +:10F6D000002070BD68682188A0F8A511A17880F885 +:10F6E000A7113046BDE8704001F0C5BE2DE9F041DC +:10F6F0008C4C616891F8A701400908BF012607D02A +:10F70000012808BF022603D0022814BF00260826BD +:10F710000027D1F88021002A38D001F2A51800284E +:10F7200008BF012507D0012808BF022503D0022801 +:10F7300014BF00250825F7F7BBFB98F8000000F080 +:10F740003F084046F7F789F96068294680F89781B5 +:10F75000FF20F7F798F860682A46D0F8801101205A +:10F76000F7F75DFAF7F78AFC0521A068FCF76AFD58 +:10F77000616881F8760148B115F00C0F0CBF502577 +:10F780005525F6F780FE2846F7F72AFC6068D0F882 +:10F790007C01F7F799FB606890F86811022906D0A0 +:10F7A000032904BF90F89001012804D008E090F8E4 +:10F7B0009001022804D1324601210020F7F78EFC87 +:10F7C000606880F8A46180F88571BDE8F0812DE95A +:10F7D000F74F544C0025914660688A4690F87501B1 +:10F7E00000280CBF4FF001084FF00008A068017816 +:10F7F000CE090121FDF71EFF36B1407900F0C000AF +:10F80000402808BF012600D00026606890F87611D5 +:10F81000002963D090F868114FF0000B03291ED126 +:10F8200090F86111002918BF90F87A7117D0FF2F56 +:10F8300018BF082F22D03846FCF7E4F9002818BF7B +:10F840004FF00108002E49D0606890F88601D0B1D1 +:10F85000FCF763FC0546606880F886B13EE0A1686D +:10F86000CA7812F03F0F19BF097911F0010F90F813 +:10F870002B10FF2918BF90F87771D8D176B390F884 +:10F88000850170B12AE03846FCF7F5FB05460121F9 +:10F89000A068FDF7CFFE01462846F8F71DF905469A +:10F8A0001CE0A068C17811F03F0F05D0017911F07C +:10F8B000010F18BF0B2101D14FF005014FF00002DD +:10F8C000FCF705FC616881F8760138B1FCF71AFC99 +:10F8D000FF2803D06168012581F877018AF800507C +:10F8E0000098067089F8008003B0BDE8F08F0D48DD +:10F8F00010B5406890F8371089B1818E012221F04F +:10F9000060014031818690F8283043B980F8282082 +:10F9100011F0080F14BF0720062002F098F902200A +:10F9200010BD0000740100202DE9F04FFF4D83B0A1 +:10F930000024686890F874017F27801F26464FF0E6 +:10F940000108062880F03F82DFE800F003080893F2 +:10F95000FDFC00F01BFC044600F036BAF348F7F754 +:10F960009CFB002808BF2F70F7F77EFBA868FDF707 +:10F97000CFFD044607286AD1A868FDF7A7FF69688C +:10F9800091F89021824262D191F87401062804D145 +:10F99000A868FDF79BFF002836D0686890F87411BE +:10F9A000082904BF90F8A101022813D04FF00301E9 +:10F9B000A868FDF73FFE002849D06968437891F8B0 +:10F9C0003820B2EB131F42D10088498FC0F30B00DF +:10F9D00088423CD100212046FFF706FAB0B38DF8EB +:10F9E00000608DF804608DF80860A868FF24C17875 +:10F9F00011F03F0F1CBF007910F0020F1CD0012046 +:10FA0000FEF71DFA50B117E0A868C17811F03F0F5A +:10FA10001CBF007910F0100FBFD1DBE702AA6946C6 +:10FA200001A8FFF7D4FE686890F859419DF80000DE +:10FA3000002818BF44F0020423469DF808209DF8D2 +:10FA400004109DF8000000F011FA02E0FFE7FFF754 +:10FA50004EFF0446686890F87601002800F0B481F3 +:10FA6000F7F7C8FAF6F723FD686880F8766100F0CA +:10FA7000ABB9A868FDF74CFD8146A9686868CA78EB +:10FA800090F891319A4221D10A7990F892319A42B4 +:10FA90001CD14A7990F893319A4217D18A7990F81B +:10FAA00094319A4212D1CA7990F895319A420DD187 +:10FAB0000A7A90F896319A4208D1097890F898011C +:10FAC000C1F38011814208BF012400D00024F7F760 +:10FAD00061F99648F7F7E1FA002808BF2F70F7F7A9 +:10FAE000C3FAB9F1040F75D1002C73D0686890F88F +:10FAF000481100296ED190F8281021B190F83410E7 +:10FB000011F0100F66D0D0F84C411D21204605F0B1 +:10FB100000FE84F80080686804F1020A04F101091B +:10FB200090F87801FF280FD052464946FCF7ACFA0E +:10FB3000002808BFFFDF99F8000040F0020089F8B4 +:10FB400000001FE049E0FFE0A868FDF70AFD89F822 +:10FB50000000A868FDF7DCFC072804D25146A8681D +:10FB6000FDF7E1FC0EE0A868FDF7D2FC072809D1FB +:10FB70000021A868FDF75EFD0168CAF800108088C2 +:10FB8000AAF8040004F11D01A868FDF70AFD20721F +:10FB9000287804F109097F2808BFFFDF287889F851 +:10FBA00000002F706868618990F8A12162F300015C +:10FBB00041F01A01618184F80C806673FF21A17302 +:10FBC0002175E77690F89711217780F84881072012 +:10FBD00002F03DF8062400F0F7B84FF00208534851 +:10FBE000F7F75BFA002808BF2F70F7F73DFAA8680F +:10FBF000FDF78EFC0446A868FDF768FE082C08BFD8 +:10FC000000287DD1A8684FF00301C27812F03F0FA1 +:10FC100076D0007931EA000072D1686800F5BA77D1 +:10FC200090F86101002814BFBE79FE784FF00009FA +:10FC3000B87878B1FCF766FA0446FF280AD0014686 +:10FC4000A868401DFCF737FAB4420CBF4FF0010919 +:10FC50004FF000090021A868FDF7ECFC062207F12F +:10FC60001D0105F0ABFC40B9A868FDF77AFC97F8D8 +:10FC70002410884208BF012000D0002059EA000962 +:10FC800060D0686800F5AD7490F859A1787838B103 +:10FC90003046FCF726FB00281CBF04464FF0010A43 +:10FCA0000027A86801784FEAD11B0121FDF7C2FCAB +:10FCB000BBF1000F07D0407900F0C000402808BF1A +:10FCC0004FF0010B01D04FF0000B0121A868FDF7A8 +:10FCD000B1FC0622214605F071FC30B9A868FDF799 +:10FCE0004DFC504508BF012401D04FF000043BEA11 +:10FCF000040018BFFF2E0FD03046FCF7BCF900E01F +:10FD000020E0060008D00121A868FDF793FC014619 +:10FD10003046F7F7E1FE074644EA070019EA000F0C +:10FD200010D06868012100F5C47001E07401002062 +:10FD300005F066F94FF001084046FFF7DAF90520B3 +:10FD400001F085FF44463FE00224F848F7F7A5F9A3 +:10FD5000002808BF2F70F7F787F9A868FDF7D8FBD0 +:10FD60000646A868FDF7B2FD072E08BF00282BD174 +:10FD7000A8684FF00101C27812F03F0F24D0027939 +:10FD8000914321D1696801F5BA760021FDF752FC53 +:10FD9000062206F11D0105F011FCA8B9A868FDF7BF +:10FDA000E0FB96F8241088420ED16868012100F526 +:10FDB000C47005F025F9FF21022000F009F80028A1 +:10FDC00018BF032400E0FFDF03B02046BDE8F08F3A +:10FDD0002DE9F041D54C02460025606890F8A1312C +:10FDE0000BB3A0684FF000064FF00107C37813F083 +:10FDF0003F0F1CBF007910F0100F1BD00020FEF742 +:10FE000056F8606890F83400C0F3411002281BD007 +:10FE10000220FFF73CFC88B16068012580F8906102 +:10FE2000F6F7B8FF1FE0002A14BF0223012380F871 +:10FE3000A131D6E71046FEF73AF805E06068818EFA +:10FE400021F0600140318186606890F8281051B936 +:10FE500080F8287090F8340010F0080F14BF0720C5 +:10FE6000062001F0F4FE2846BDE8F0812DE9F047B8 +:10FE7000AE4C05461F4690460E46A068FDF726FD8F +:10FE8000002800F0CF80012805D0022800F00C8166 +:10FE9000BDE8F0472BE5A0680921C27812F03F0FBA +:10FEA00000F040810279914340F03C81616891F813 +:10FEB0006811032906D012F0020F08BFFF2119D0E4 +:10FEC00065B116E00021FDF7B5FB61680622D1F8A7 +:10FED00064111A3105F072FB50BB1EE0FDF74EFBBA +:10FEE00005460121A068FDF7A5FB2946F6F767FD49 +:10FEF00018B13946012000F039B9606890F86901FD +:10FF0000032818BF022840F00D81002E1CBFFE21DF +:10FF1000012040F02B8100F005B9A068FDF721FB1E +:10FF20006168D1F86411497E884208BF012600D07B +:10FF30000026A068C17811F03F0F05D0017911F0BB +:10FF4000020F01D05DB338E0616891F86A21012A9F +:10FF500001D0A6B119E0C6B90021FDF76BFB6168BD +:10FF60000268D1F86411C1F81A208088C883A0689B +:10FF7000FDF7F7FA6168D1F86411487605E091F869 +:10FF8000770191F87A1188424BD1606800F5C4700E +:10FF900005F07AF8002844D00F20BDE8F087B8F1CA +:10FFA000000F0CD0FDF7EAFA05460121A068FDF725 +:10FFB00041FB2946F6F703FD08B1012200E00022CB +:10FFC000616891F86A01012807D040B92EB991F80B +:10FFD000773191F87A118B4201D1012100E00021A3 +:10FFE0000A421ED0012808BF002E13D14FF0000195 +:10FFF000A068FDF71FFB61680268D1F86411C1F8C1 +:020000040002F8 +:100000001A208088C883A068FDF7ABFA6168D1F830 +:1000100064114876606800F5C47005F035F8002872 +:10002000BAD17FE06068A8464FF0020990F86801F5 +:1000300003282AD0A068C17811F03F0F1BBF0079B8 +:1000400010F0020F002001204FF0FF05A8B14FF083 +:100050000100FDF7F4FE002804BF3D46B8F1000F93 +:100060000BD1A068FDF78AFA07460121A068FDF7C9 +:10007000E1FA3946F6F7A3FC50B129460020FFF714 +:10008000A7FE002818BF4FF003094846BDE8F087D7 +:10009000606890F86901032818BF0228F5D1002E86 +:1000A00018BFFE25E9D1F0E7626892F86831032BAA +:1000B00038D0A0684FF0090CC17811F03F0F31D053 +:1000C00001793CEA010C2DD1022B01F0020105D08F +:1000D000002908BFFF2148D03DB345E009B135B143 +:1000E00013E002F5C47004F0CFFFA0B91AE0B8F134 +:1000F000000F1DD0FDF742FA05460121A068FDF76B +:1001000099FA2946F6F75BFC90B1606800F5C47077 +:1001100004F0BAFF30B139460220FDF7C8FE0D20C9 +:10012000BDE8F0870220BDE8F08712E074010020EE +:10013000606890F86901032818BF0228F2D1002EE8 +:10014000F0D04FF0FE014FF00200FFF765FA0220F9 +:10015000E9E7FDF713FA05460121A068FDF76AFA01 +:100160002946F6F72CFC20B139460220FFF754FA55 +:10017000D8E7606890F86901032818BF0228D1D138 +:10018000002E1CBFFE210220F0D1CBE72DE9F84F55 +:100190000027D048F6F781FFCE4C002804BF7F200F +:1001A0002070F6F761FFA068FDF7B2F980460121E3 +:1001B000FEF71AFE61684FF0000B91F8A421012AA6 +:1001C00013D0042A1CBF082AFFDF00F07781606883 +:1001D00090F8760130B1F6F70DFFF6F768F9606830 +:1001E00080F876B13846BDE8F88F0125BA4EB8F1EF +:1001F000080F19D2DFE808F024860418181811FD3A +:100200000546F6F7C7FD002D7AD0606890F86801C2 +:10021000012818BF022858D072E028B191F868016F +:10022000022805D0012850D0F6F7B4FD0627CEE706 +:10023000FF20FEF753F860680C2780F8A1B1C6E7ED +:100240000027002800F0208191F86801022834D0AE +:1002500001283AD00328BAD1A068D1F86421C37824 +:1002600092F81AC0634521D1037992F81BC0634507 +:100270001CD1437992F81CC0634517D1837992F859 +:100280001DC0634512D1C37992F81EC063450DD1DC +:10029000037A92F81FC0634508D1037892F819C019 +:1002A000C3F38013634508BF012300D0002391F8F6 +:1002B0006A1101290DD0D3B1E4E0FF20FEF70EF85A +:1002C00060680C2780F8A15181E7FF20FEF706F84F +:1002D00016E0002B71D102F11A01FDF724F9A06894 +:1002E000FDF73FF96168D1F864114876CAE096F8E5 +:1002F0007A0108287CD096F8771181425DD0C3E05E +:10030000062764E7054691F8750100280CBF4FF0F9 +:1003100001094FF000090027A06810F8092BD20945 +:1003200007D0407900F0C000402808BF4FF0010A14 +:1003300001D04FF0000A91F86801032806D191F826 +:100340006101002818BF91F87A0101D191F8770175 +:100350000090FBF790FE5FEA00082AD00098FBF7B8 +:1003600051FC002818BF4FF00109BAF1000F20D04E +:10037000A06800F109014046F7F7AEFB070060688E +:1003800090F8598118BF48F00208606890F8681129 +:10039000032913D0F6F7FEFC002DB1D0F6F71FFBB2 +:1003A00000280CBF002F404672D000BFFDF796FF1B +:1003B000A6E7606890F85981E7E763E0A168D0F8A4 +:1003C0006401CA78837E9A421FD10A79C37E9A4219 +:1003D0001BD14A79037F9A4217D18A79437F9A4287 +:1003E00013D1CA79837F9A420FD10A7AC37F01E081 +:1003F0004AE05BE09A4208D10978407EC1F380115F +:10040000814208BF4FF0010801D04FF0000896F874 +:100410007701082806D096F87A11884208BF4FF075 +:10042000010A01D04FF0000A2FB9B9F1000F04D032 +:10043000F6F7D5FA08B1012000E000204DB196F89A +:100440006A11012903D021B958EA0A0101D001211A +:1004500000E00021084217D0606890F86A11012975 +:1004600008BFB8F1000F0DD1D0F8640100F11A01F6 +:10047000A068FDF758F8A068FDF773F86168D1F837 +:10048000641148760E27A2E6F6F784FC38E7FFE70A +:10049000606890F86901032818BF02287FF430AF24 +:1004A000BAF1000F18BFFE2080D129E791F8701132 +:1004B000002918BF00283FF4B7AE06E0B8F1070FD7 +:1004C0007FF4B2AE00283FF4AFAEFEF72AFD074638 +:1004D0007DE6000074010020F4100020D0F8E01048 +:1004E00049B1D0E939231A448B691A448A61D0E9A9 +:1004F0003712D16003E0F74AD0F8DC101162D0E97E +:10050000371009B1086170470028FCD000218161D3 +:1005100070472DE9FF4F06460C46488883B040F2ED +:10052000E24148430190E08A002500FB01FA94F87B +:10053000640090460D2822D00C2820D024281ED0FC +:1005400094F8650024281AD000208346069818B134 +:100550000121204602F0B7FE94F8541094F855009B +:10056000009094F8D0200F464FF47A794AB1012ACE +:1005700061D0022A44D0032A5DD0FFDFB5E001201C +:10058000E3E7B8F1000F00D1FFDFD24814F8541FA1 +:10059000243090F83800FCF77EFF01902078F7F7C0 +:1005A000D2F84D4600F2E730B0FBF5F1DFF82493C6 +:1005B000D9F80C0001EB00082078F7F7C4F80146E1 +:1005C00014F85409022816D0012816D040F6340039 +:1005D00008444AF2EF010844B0FBF5F10198D9F85C +:1005E0001C20411A514402EB08000D18012084F828 +:1005F000D0002D1D78E02846EAE74FF4C860E7E711 +:10060000DFF8D092A8F10100D9F80810014300D119 +:10061000FFDFB148B8F1000F016801EB0A0506D011 +:10062000D9F8080000F22330A84200D9FFDF0320E8 +:1006300084F8D00058E094F86420019D242A05D065 +:1006400094F86530242B01D0252A3AD1B4F85820EB +:10065000B4F8F030D21A521C12B2002A31DB94F8EE +:10066000F22072B3174694F8F32002B110460090BE +:10067000022916D0012916D040F6340049F6085256 +:100680008118022F12D0012F12D040F634001044EE +:10069000814210D9081A00F5FA70B0FBF9F0054450 +:1006A0000FE04846EAE74FF4C860E7E74846EEE760 +:1006B0004FF4C860EBE7401A00F5FA70B0FBF9F0B0 +:1006C0002D1AB8F1000F0FD0DFF80882D8F8080013 +:1006D00018B9B8F8020000B1FFDFD8F8080000F23E +:1006E0002330A84200D9FFDF05B9FFDF2946D4F83F +:1006F000D400F3F78CFFC4F8D400B0600020307051 +:100700004FF0010886F80480204602F0CAFEABF1E3 +:100710000101084202D186F8058005E094F8D00076 +:1007200001282FD003207071606A3946009A01F0C9 +:1007300022FBF060069830EA0B0020D029463046B4 +:10074000FCF700FC87B2204602F0ABFEB8420FD89F +:10075000074686F8058005FB07F1D4F8D400F3F7C7 +:1007600056FFB06029463046FCF7ECFB384487B2B0 +:100770003946204602F0A7FDB068C4F8D40007B09F +:10078000BDE8F08F0220CEE72DE9F04106460C4689 +:10079000012001F0D2FAC5B20B2001F0CEFAC0B2AE +:1007A000854200D0FFDF0025082C7DD2DFE804F071 +:1007B0000461696965C98E96304601F0D2FA062156 +:1007C000F2F7E2F8040000D1FFDF304601F0C9FA89 +:1007D0002188884200D0FFDF94F8D00000B9FFDF05 +:1007E000204602F075FA3B4E21460020B560758028 +:1007F000F561FCF7A2FC00F19807606AB84217D9CE +:1008000094F85500F6F786FF014694F854004FF42B +:100810007A72022828D0012828D040F634000844F3 +:100820004AF247310844B0FBF2F1606A0844C51B44 +:10083000214600203561FCF780FC618840F2E242ED +:1008400051439830081AA0F22330706194F8552073 +:1008500094F85410606A01F08EFAA0F29310B0611F +:10086000BDE8F041F4F7BBBE1046D8E74FF4C860CE +:10087000D5E7BDE8F04102F002BCBDE8F041F6F773 +:1008800045BC6FF0040001F058FAC4B2192001F021 +:1008900054FAC0B2844200D0FFDF304601F061FA62 +:1008A0000621F2F771F800E04BE0040000D1FFDF11 +:1008B000304601F056FA2188884200D0FFDF2046FA +:1008C000BDE8F0410122002101F072BAF6F7BEFA4C +:1008D000D3E70000A012002084010020304601F080 +:1008E00040FA0621F2F750F8040000D1FFDF30464D +:1008F00001F037FA2188884200D0FFDF94F8D00059 +:10090000042800D0FFDF84F8D05094F8DA504FF676 +:10091000FF76202D00D3FFDFFB4820F8156094F808 +:10092000DA00F4F754F900B9FFDF202084F8DA0088 +:100930002046FFF7D3FDF5480078BDE8F041E2F727 +:10094000EBBAFFDFBDE8F08170B5EF4C0025483C05 +:1009500084F82C50E07868B1E570FEF7B6F920789D +:10096000042803D0A06AFFF7B9FDA562E748007824 +:10097000E2F7D2FABDE8704001F02BBA70B5E24C54 +:100980000146483C206AF4F75DFE6568A27890FB5A +:10099000F5F172B140F27122B5FBF2F292B2E36B63 +:1009A00001FB02F6B34202D901FB123200E0002241 +:1009B000E2634D43002800DAFFDF2946206AF3F79F +:1009C00026FE206270BD2DE9F05FFEF7D1F9824668 +:1009D000CD486C3800F1240881684646D8F81C00E0 +:1009E000F3F715FE0146306AF4F72CFE4FF00009CC +:1009F000074686F839903C464FF423754E461CE076 +:100A00000AEB06000079F6F785FE4AF2B1210144AF +:100A10004FF47A70B1FBF0F108EB86024046926821 +:100A200011448C4207D3641A90F83910A4F523744A +:100A3000491C88F83910761CF6B298F83A00B04292 +:100A4000DED8002C0FDD98F83910404608EB810104 +:100A50008968A14207D24168C91BA94200D90D4645 +:100A60006C4288F8399098F83960C3460AEB06085A +:100A700098F80400F6F74EFE01464AF2B120014410 +:100A80004FF47A7AB1FBFAF298F80410082909D0E9 +:100A9000042909D00020131804290AD0082908D0F5 +:100AA000252007E0082000E0022000EB400028306D +:100AB000F1E70F20401D4FF4A872082913D0042934 +:100AC00014D0022915D04FF0080C282210FB0C205E +:100AD000184462190BEB860302449868D846824298 +:100AE0000BD8791925E04FF0400CEFE74FF0100CD0 +:100AF000ECE74FF0040C1822E8E798F8392098F852 +:100B00003A604046B24210D2521C88F839203C1B51 +:100B10009868621984180846F6F7FCFD4AF2B1217C +:100B20000144B1FBFAF0011903E080F83990D8F8DC +:100B30000410D8F82000BDE8F05FF3F768BD2DE998 +:100B4000FE4F14460546FEF713F9DFF8BCB10290DC +:100B5000ABF1480B58469BF839604FF0000A0BEB9D +:100B600086018968CBF84010ECB304460078002772 +:100B7000042827D0052840D0FFDFA0463946A069C9 +:100B8000F3F745FD0746F4F741F881463946D8F8B2 +:100B90000440F4F757FD401E90FBF4F0C14361435D +:100BA0003846F3F734FD0146C8F820004846F4F70C +:100BB00049FD002800DDFFDF012088F8140088F8D7 +:100BC00013008FE0D4F81890D4F8048001F06BF98A +:100BD000070010D0387800B9FFDF796978684A4695 +:100BE0000844414600E00EE001F045F90746404563 +:100BF000C3D9FFDFC1E75746BFE7A06A01F0F6F8A7 +:100C000040F6B837B9E7016A0BEB46000191C08D99 +:100C100008B35C46DBF81800FFF7B0FE6168206A95 +:100C2000F3F7F5FC074684F839A0019CD846204626 +:100C3000DBF81810F4F706FD814639462046F4F734 +:100C400001FDD8F80420B9FBF2F3B0FBF2F08342C7 +:100C500043D0012142E0F3F7D9FFFFF78FFEFFF702 +:100C6000B2FE9BF83910DBF804900BEB81010746CC +:100C7000896800913946DBF82000F4F7E3FC002492 +:100C80008046484504DB98FBF9F404FB09F41BE0BB +:100C9000002059469BF8392008E000BF01EB800393 +:100CA00004F523749B68401C1C44C0B28242F5D8F2 +:100CB00052B10120F6F72EFD4AF2B12101444FF462 +:100CC0007A70B1FBF0F004440099A8EB04000C1A10 +:100CD00000D5FFDFCBF84040A7E7002188F81410CB +:100CE00088F813A09BF802005C46B8B13946206A28 +:100CF000F4F7A8FC0146E26B40F2712042438A42BD +:100D000006D2C4F840A009E00C13002080010020A6 +:100D1000206C511A884200D308462064AF6085F8E1 +:100D200000A001202871029F94F839003F1DC05D8A +:100D3000F6F7F0FC4AF23B5101444FF47A70B1FBF4 +:100D4000F0F0216CFB300844E8602078042808D1DA +:100D500094F8390004EB4000C08D0A2801D203202A +:100D600000E00220687104EB4600C08DC0B1284647 +:100D70006168FCF7E7F882B20020761C0CE000BF47 +:100D800004EB4003B042D98D114489B2D98501D317 +:100D9000491CD985401CC0B294F83A108142EFD268 +:100DA000A868A061E06194F8390004EB4000C18DAF +:100DB000491CC18594F83900C05D082803D0042877 +:100DC00003D000210BE0082100E0022101EB4101EA +:100DD00028314FF4A872082804D0042802D0022831 +:100DE00007D028220A44042805D0082803D025214A +:100DF00002E01822F6E70F21491D08280CD004282C +:100E00000CD002280CD0082011FB0020216C884255 +:100E100008D20120BDE8FE8F4020F5E71020F3E75F +:100E20000420F1E70020F5E770B5FB4C061D14F82F +:100E3000392F905DF6F76EFC4FF47A7100F2E730CF +:100E4000B0FBF1F0D4F8071045182078805DF6F774 +:100E50004FFC2178895D082903D0042903D00022A2 +:100E60000BE0082200E0022202EB420228324FF49B +:100E7000A873082904D0042902D0022907D0282306 +:100E80001344042905D0082903D0252202E01823A1 +:100E9000F6E70F22521D08290AD004290AD0022998 +:100EA0000AD0082112FB0131081A281A293070BD16 +:100EB0004021F7E71021F5E70421F3E7FEB50446EA +:100EC0000F46012000F039FFC5B20B2000F035FFBE +:100ED000C0B2854200D0FFDF01260025CE48082F92 +:100EE00050D2DFE807F004304747434F4F4C0446E9 +:100EF000467406744078002819D1FDF739FF009533 +:100F000094F839108DF808104188C90410D0606C2D +:100F1000019003208DF80900BF4824388560C56121 +:100F200025746846FDF73FFC002800D0FFDFFEBDBA +:100F3000FFF77AFF0190207D10B18DF80950EBE7A3 +:100F40008DF80960E8E70446407840B1207C08B994 +:100F5000FDF790FE6574BDE8FE40F3F761BDA67431 +:100F6000FDF736FD0028E2D0FFDFFEBDBDE8FE4004 +:100F7000F6F7CCB82046BDE8FE4000F09DBFBDE8C6 +:100F8000FE40E1E4FFDFFEBDA34950B101228A70BB +:100F90004A6840F27123B2FBF3F202EB0010C8631F +:100FA00070470020887070472DE9F05F894640F255 +:100FB0007121994E484300250446706090462F46A3 +:100FC000D0074AF2B12A4FF47A7B0FD0B9F800006B +:100FD0004843B0600120F6F79DFB00EB0A01B1FB2E +:100FE000FBF0241AB7680125A4F523745FEA0870A2 +:100FF00016D539F8151040F27120414306EB8508EB +:101000000820C8F80810F6F785FB00EB0A01B1FBD1 +:10101000FBF0241AD8F80800A4F5237407446D1CCB +:10102000A7421AD9002D18D0391BB1FBF5F0B268D0 +:10103000101AB1FBF5F205FB1212801AB060012004 +:1010400009E000BFB1FBF5F306EB80029468E31AF8 +:10105000401CC0B29360A842F4D3BDE8F09F2DE9D4 +:10106000F0416D4C00262078042804D02078052813 +:1010700001D00C2066E401206070607C002538B14E +:10108000EFF3108010F0010F72B610D001270FE0BF +:10109000FDF76EFE074694F82400F4F713F97888FC +:1010A000C00411D000210320FDF767FE0CE00027EB +:1010B000607C38B1A07C28B1FDF7DCFD6574A574B7 +:1010C000F3F7AEFC07B962B694F82400F4F747FBD7 +:1010D00094F82C0030B184F82C502078052800D0EA +:1010E000FFDF0C26657000F074FE30462AE44A48A3 +:1010F00010B5007808B1FFF7B2FF00F00DFF4649C8 +:1011000000202439086210BD10B5444C58B10128A4 +:1011100007D0FFDFA06841F66A01884200D3FFDFF5 +:1011200010BD40F6C410A060F4E73C4908B5087053 +:10113000394900200870487081F82C00C870087484 +:10114000487488742022886281F8242024394870E9 +:101150004FF6FF7211F16C0121F81020401CC0B253 +:101160002028F9D30020FFF7CFFFFFF7C0FF1020A2 +:10117000ADF80000012269460420FFF715FF08BD05 +:101180007FB5254C05460E46207810B10C2004B0E2 +:1011900070BD95F8552095F85410686A00F0FEFE71 +:1011A000C5F8E400A56295F8D00000B1FFDF1A4948 +:1011B00000202439C86105212170607084F82C005A +:1011C000014604E004EB4102491CD085C9B294F801 +:1011D0003A208A42F6D284F839003046FFF7D4FE2E +:1011E0000F48F3F798FC84F82400202800D1FFDF93 +:1011F000F3F70CFDA06194F8241001226846FFF774 +:101200009EFC00B9FFDF94F824006946F3F748FF1D +:1012100000B9FFDF0020BAE7C412002080010020DF +:10122000BD0E0200F84810B5007808B1002010BDCE +:101230000620F1F743FB80F0010010BDF8B5F24D38 +:101240000446287800B1FFDF002000902378024692 +:10125000DE0701466B4605D06088A188ADF8001016 +:10126000012211462678760706D5E088248923F8DE +:10127000114042F00802491C491E85F83A101946EF +:10128000FFF792FE0020F8BD1FB511B1112004B088 +:1012900010BDDD4C217809B10C20F8E70022627006 +:1012A00004212170114604E004EB4103491CDA8556 +:1012B000C9B294F83A308B42F6D284F83920FFF75D +:1012C00063FED248F3F727FC84F82400202800D1DD +:1012D000FFDF00F0E8FD10B1F3F798FC05E0F3F74D +:1012E00095FC40F6B831F3F792F9A06194F8241018 +:1012F00001226846FFF723FC00B9FFDF94F82400C1 +:101300006946F3F7CDFE00B9FFDF0020BFE770B5F7 +:10131000BD4CA16A0160FFF7A2FE050002D1A06AE0 +:10132000FFF7DCF80020A062284670BD7FB5B64C00 +:101330002178052901D00C2029E7B3492439C86058 +:10134000A06A00B9FFDFA06A90F8D00000B1FFDF0B +:10135000A06A90F8DA00202800D0FFDFAC48F3F74D +:10136000DAFBA16A0546202881F8DA000E8800D34E +:10137000FFDFA548483020F81560A06A90F8DA0031 +:10138000202800D1FFDF002301226846A16AFFF771 +:10139000C0F8A06A694690F8DA00F3F781FE00B958 +:1013A000FFDF0020A062F2E69749243948707047B9 +:1013B00010B540F2E24300FB03F4002000F0EEFD24 +:1013C000844201D9201A10BD002010BD70B50D4611 +:1013D000064601460020FBF7B0FE044696F855008D +:1013E000F6F798F9014696F854004FF47A720228FD +:1013F00015D0012815D040F6340008444AF2473190 +:101400000844B0FBF2F1708840F271225043C1EB06 +:101410004000A0F22330A54206D2214605E0104646 +:10142000EBE74FF4C860E8E72946814204D2A542C1 +:1014300001D2204600E02846706270BD70B5F5F715 +:10144000D8F90446F6F754F901466F482438826803 +:101450004068101A0E18204600F066FC054620462B +:10146000F6F758F9281A4FF47A7100F2E730B0FB1A +:10147000F1F0304470BD70B50546FDF779FC624966 +:10148000007824398C689834072D30D2DFE805F0D5 +:10149000043434252C34340014214FF4A873042868 +:1014A00010D00822082809D02A2102280FD011FBC9 +:1014B000024000222823D118441819E0402211FBD1 +:1014C0000240F8E7102211FB02402E22F3E704222B +:1014D00011FB024000221823EDE7282100F03CFC1C +:1014E000044404F5317403E004F5B07400E0FFDF58 +:1014F0004548006CA04201D9012070BD002070BD9C +:1015000070B5414C243C607870B1D4E90451284650 +:10151000A268FBF742FD2061A84205D0A169401BEB +:101520000844A061F4F75BF82169A068884201D8FB +:10153000207808B1002070BD012070BD2DE9F04F6A +:10154000074685B016460D461C461846F6F7D0F8F5 +:1015500007EB45014718204600F0E6FB4AF2C5714B +:101560004FF47A7908444D46B0FBF5F0384400F169 +:101570006008254824388068304404902046F6F7F7 +:10158000B7F8A8EB0007204600F0CEFB0646204641 +:10159000F6F7C0F8301AB0FBF5F03A1A18252820F3 +:1015A0004FF4C8764FF4BF774FF0020B082C34D0BD +:1015B000042C2FD00021022C32D0082311F1280155 +:1015C00003EB830301EB83010A444FF0000A082C6C +:1015D0002ED0042C27D00021022C2ED00546082026 +:1015E00001F5B07100EB00102844814231D2082C83 +:1015F00029D0042C24D00020022C27D00821283008 +:1016000001EB011132E00000C4120020BD0E020007 +:101610008907020039461023D2E731464023CFE73D +:1016200004231831CCE73D4640F2EE311020D9E7D3 +:1016300035464FF435614020D4E70420B431D1E77A +:1016400038461021DCE730464021D9E70421183024 +:10165000D6E7082C4ED0042C49D00020022C4CD0C8 +:1016600008212830C1EBC10303EB411108441518D0 +:101670002821204600F070FB05EB4000082C42D0EA +:10168000042C3DD00026022C3FD0082116F128065C +:1016900001EB811106EB810146180120FB4D8DF80D +:1016A00004008DF800A08DF805B0E86906F2272641 +:1016B0000499F2F7ACFFCDE902062046F6F72AF8C6 +:1016C0004AF23B510144B1FBF9F0301AFB3828646F +:1016D0000298C5F84480E86195F824006946F3F75C +:1016E000DFFC002800D1FFDF05B0BDE8F08F3846F1 +:1016F0001021B7E730464021B4E704211830B1E7A4 +:101700003E461021C4E74021C2E704211836BFE756 +:101710002DE9FE4F04461D46174688464FF0010A44 +:101720001846F5F7E5FFD94E0146243E07EB48027F +:10173000B068204410440F18284600F0F5FA4FF422 +:101740007A7BD84600F6FB00B0FBF8F0384400F195 +:1017500020092846F5F7CCFFB2680146A9EB020044 +:10176000001B471A284600F0DFFA06462846F5F720 +:10177000D1FF311AB1FBF8F03A1A182628204FF49D +:10178000C8774FF4BF78082D2BD0042D26D0002128 +:10179000022D29D00823283103EB830301EB8301B9 +:1017A0000A44082D28D0042D21D00021022D28D054 +:1017B0000646082001F5B07100EB0010304481426C +:1017C0002BD2082D23D0042D1ED00020022D21D095 +:1017D0000821283001EB011108442CE04146102378 +:1017E000DAE739464023D7E704231831D4E74646E1 +:1017F00040F2EE311020DFE73E464FF435614020E5 +:10180000DAE70420B431D7E740461021E2E7384652 +:101810004021DFE704211830DCE7082D4CD0042DEF +:1018200047D00021022D4AD008202831C0EBC00348 +:1018300003EB4010084416182821284600F08CFAC3 +:1018400006EB4000082D40D0042D3BD00027022D90 +:101850003DD0082117F1280701EB811107EB810129 +:10186000451805F596750C98F5F754FF4AF23B516B +:101870000144B1FBFBF0854EFB30A6F12407316C2F +:1018800004F1FB020844B9684B191A44824228D972 +:10189000621911440D1AFB35E1F7F8F9B9680844EB +:1018A00061190844B0F1807F36D2642D12D26420D1 +:1018B00011E041461020B9E739464020B6E7042040 +:1018C0001831B3E747461021C6E74021C4E7042199 +:1018D0001837C1E72846F3F7DCFEE8B1306C28443E +:1018E0003064E1F7D3F9B968293821440844CDE9D7 +:1018F000000996F839008DF8080002208DF80900DB +:101900006846FCF750FF00B1FFDFFDF761F800B15A +:10191000FFDF5046BDE8FE8F4FF0000AF9E71FB524 +:1019200000F042FB594C607880B994F824100022F2 +:101930006846FFF704F938B194F824006946F3F7D4 +:10194000AFFB18B9FFDF01E00120E070F3F768F8A2 +:1019500000206074A0741FBD2DE9F84FFDF708FA50 +:101960000646451CC07840090CD001280CD002283E +:101970000CD000202978824608064FF4967407D4CC +:101980001E2006E00120F5E70220F3E70820F1E73A +:101990002046B5F80120C2F30C0212FB00F7C8097B +:1019A00001D010B103E01E2401E0FFDF0024FFF7A7 +:1019B00045FDA7EB00092878B77909EB0408C0F3C7 +:1019C000801010B120B1322504E04FF4FA7501E027 +:1019D000FFDF00250C2F00D3FFDF2D482D4A30F804 +:1019E0001700291801FB0821501CB1FBF0F5F4F792 +:1019F00000FFF5F78FFE4FF47A7100F27160B0FBD3 +:101A0000F1F1A9EB0100471BA7F15900103FB0F518 +:101A1000237F11D31D4E717829B9024653462946BA +:101A20002046FFF78BFD00F0BFFAF2F7F9FF002028 +:101A30007074B074BDE8F88F307800905346224639 +:101A400029463846FFF764FE0028F3D10121022021 +:101A5000FDF793F9BDE8F84F61E710B50446012999 +:101A600003D10A482438007830B1042084F8D0002B +:101A7000BDE81040F2F7D4BF00220121204600F05B +:101A800097F934F8580F401C2080F1E7C412002069 +:101A9000385D02003F420F002DE9F0410746FDF797 +:101AA00067F9050000D1FFDF29783846FBF7F3FC22 +:101AB000F84C0146A4F12406E069B268024467B319 +:101AC0002878082803D0042803D000270BE0082337 +:101AD00000E0022303EB430728374FF4A8730828DC +:101AE00004D0042802D002280FD028233B44082821 +:101AF0000DD004280DD002280DD00820C0EBC0075F +:101B000007EB40101844983009E01823EEE7402016 +:101B1000F4E71020F2E70420F0E74FF4FC701044E3 +:101B2000471828783F1DF5F7F5FD024628784FF451 +:101B30007A7102281DD001281DD040F634001044CF +:101B40004AF2EF021044B0FBF1F03A1AA06A40F2F8 +:101B5000E241B0464788D0304F43316A81420DD0D0 +:101B60003946606B00F087F90646B84207D9FFDFB7 +:101B700005E00846E3E74FF4C860E0E70026C64802 +:101B80008068864207D2A16A40F2712248884243A7 +:101B900006EB420604E040F2E240B6FBF0F0A16A38 +:101BA000C882A06A297880F85410297880F85510E6 +:101BB00005214175C08A6FF41C71484306EB400053 +:101BC00040F63541C8F81C00B0EB410F00D3FFDFF1 +:101BD000BDE8F08110B5052937D2DFE801F005092D +:101BE000030D3100002100E00121BDE8104034E781 +:101BF000032180F8D01010BD0446408840F2E24135 +:101C00004843A549091D0860D4F8F8000089E0821E +:101C1000D4F8F80080796075D4F8F80040896080C5 +:101C2000D4F8F8008089A080D4F8F800C089E0805A +:101C30002046A16AFFF7CAFB022084F8D00010BD3D +:101C4000816ABDE81040FFF7C1BBFFDF10BD70B572 +:101C5000904C243C0928A1683FD2DFE800F0050B36 +:101C60000B15131538380800BDE8704057E6BDE87D +:101C7000704071E6022803D00020BDE870400BE7F9 +:101C80000120FAE7E16070BD032802D005281CD0CE +:101C900000E0E1605FF0000600F086F97D4D012074 +:101CA00085F82C0085F83860A86AE9690026C0F834 +:101CB000D41080F8D060E068FFF738FB00B1FFDF98 +:101CC000F2F7AEFE6E74AE7470BD0126E4E77248A2 +:101CD0000078BDE87040E1F71FB9FFDF70BD6D49C6 +:101CE00024394860704770B56A4D0446243DB1B14F +:101CF0004FF47A76012903D0022905D0FFDF70BDA9 +:101D00001846F5F741FD05E06888401C68801046DC +:101D1000F5F719FD00F2E730B0FBF6F0201AA860E5 +:101D200070BD5C4800787047082803D0042801D0B3 +:101D3000F5F7F0BC4EF628307047002804DB00F1C0 +:101D4000E02090F8000405E000F00F0000F1E02032 +:101D500090F8140D4009704710F00C0000D00846B0 +:101D6000704710B50446202800D3FFDF49484830AB +:101D700030F8140010BD70B505460C461046F5F756 +:101D8000C9FC4FF47A71022C0DD0012C0DD040F615 +:101D9000340210444AF247321044B0FBF1F02844B8 +:101DA00000F2931070BD0A46F3E74FF4C862F0E703 +:101DB0001FB513460A46044601466846FEF7A9FBCE +:101DC00094F8DA006946F3F76BF9002800D1FFDFD9 +:101DD0001FBD70B52F4C0025257094F82400F2F734 +:101DE000F6FE00B9FFDF84F8245070BD2DE9F04104 +:101DF000050000D1FFDF274A0024243AD5F8E4602B +:101E00002046631E116A08E08869B04203D39842F5 +:101E100001D203460C460846C9680029F4D104B92A +:101E200004460021C5F8E040D035C4B1E068E56063 +:101E3000E86000B105612E698846A96156B1B069B4 +:101E400030B16F69B84200D2FFDFB069C01BA86132 +:101E5000C6F818800F4D5CB1207820B902E0E96027 +:101E60001562E8E7FFDF6169606808446863AFE610 +:101E7000C5F83480ACE610B50C4601461046F3F7C1 +:101E8000E1FB00280ADA211A491EB1FBF4F101FB3B +:101E9000040010BDC41200208001002090FBF4F16A +:101EA00001FB1400F5E74648016A002001E00846FE +:101EB000C9680029FBD170477FB504466FF0040064 +:101EC000FFF73BFFC5B21920FFF737FFC0B28542CD +:101ED00000D0FFDFFCF74CFF4088C00407D0012191 +:101EE0000320FCF74AFF37480078E1F715F8002295 +:101EF00021466846FEF723FE38B169462046F3F7CF +:101F0000CFF8002800D1FFDF7FBD2D49012024310B +:101F1000C870FEF719FD7FBD2DE9FE43284D012055 +:101F2000287000264FF6FF7420E00621F0F72CFD04 +:101F3000070000D1FFDF97F8DA00D037F3F70FFC86 +:101F400007F80A6BA14617F8DA89B8F1200F00D319 +:101F5000FFDF1B4A6C3222F8189097F8DA00F2F78C +:101F600036FE00B9FFDF202087F8DA006946062038 +:101F7000F0F793FC50B1FFDF08E0029830B190F821 +:101F8000D01019B10088A042CFD104E06846F0F724 +:101F900062FC0028F1D02E70BDE8FE8310B5FFF77B +:101FA000EAFE00F5C87074E705480021243090F877 +:101FB000392000EB4200C18502480078E0F7ACBF51 +:101FC000A012002080010020FA490C28896881F8BD +:101FD000CB001ABF1328182870474FF000021128B1 +:101FE00010D0072808BF704715280BD001281ABF4A +:101FF000002802287047A1F884204FF0010081F8E2 +:1020000088007047A1F88A20704770B5E94CA16834 +:102010000A88A1F83E2181F83C0191F8540001287A +:1020200008BF012508D0022808BF022504D00428D3 +:1020300016BF08280325FFDFA06880F8405190F8FC +:102040005500012808BF012508D0022808BF022535 +:1020500004D0042816BF08280325FFDFA0684FF02E +:10206000010180F8415180F83A114FF0000180F8E9 +:102070000E11E078BDE87040E0F74EBFCD4A01296F +:1020800092681BD0002302290FD0032922D030B33D +:1020900001282FD0032818BF704792F86400132836 +:1020A0001CBF1628182805D1704792F8CB000028CD +:1020B00008BF7047D2F8F8000370704792F8CB0061 +:1020C000012808BF704700BFD2F8FC000178491E04 +:1020D0000170704792F8CB000328EBD17047D2F81B +:1020E000F800B2F858108288891A09B20029A8BFEE +:1020F00003707047B2F85800B2F80211401A00B2EB +:102100000028E1DA70472DE9F041AA4C00260327A8 +:10211000D4F808C0012590B12069C0788CF8CA00B5 +:1021200005FA00F010F4000F08BFFFDFA06880F888 +:102130006470A0F8846080F88850BDE8F0810023C6 +:102140009CF8652019460CF15800FAF791FE00281A +:1021500004BF6570BDE8F0816078002818BFBDE855 +:10216000F0812069C178A06880F8C91080F8657096 +:10217000A0F88A6080F88C50BDE8F08170B58D4C75 +:1021800084B0207910F0010F04BF04B070BD206945 +:1021900000230521C578A06890F864205830FAF72C +:1021A00067FE002818BF062D09D026DC022D1CBFB3 +:1021B000042D052D03D0607840F008006070607831 +:1021C00000281CBF04B070BD2069FBF719FC002873 +:1021D00000F01B832069C078801E162880F01583CC +:1021E000DFE800F011F18CB0DF2FF1F0F17FEFDCD0 +:1021F000F1F1F1CFEEEDECEBEAE70B2D1CBF0D2D6D +:10220000112DD8D1DBE7A0684FF000034FF001019A +:1022100090F8672000F15800FAF72AFE002840F0F5 +:1022200067832069FBF750FCA16881F8F60007205E +:1022300081F86700002081F88C0081F8880000F0A8 +:1022400057BBA0680921002390F864205830FAF7A2 +:102250000FFE18B120690079122812D0A0680A2157 +:10226000002390F864205830FAF702FE18B1206974 +:10227000007914281DD020690079162840F0388391 +:1022800021E0A0680125002390F86420092158303E +:10229000FAF7EEFD002808BF657000F0298360782A +:1022A000002840F02583A16881F87C0081F888002F +:1022B00044E0A168002081F86400A1F8840081F85E +:1022C000880000F045BAA06890F864101F2940F01B +:1022D0000F83002180F8641080F888101A2000F025 +:1022E00005BBA06890F864100F295FD161780029C0 +:1022F00040F0FE8280F8691012213EE0A06890F85C +:102300006410132952D16178002940F0F182D0F88D +:10231000F81000884988814218BFFFDFA068D0F814 +:10232000F80000F126012069FBF7FBFBA06800F133 +:10233000C4012069FBF7FDFBA168162081F8640049 +:1023400000F0D6BAA26892F8640016282ED1607800 +:10235000002840F0CD82D2F8F80002F1B00300F17D +:102360001E0100220E30FAF7FDFCA0680021C0E932 +:102370002811012180F86910182180F8641000F0FC +:10238000B7BA2069FBF755FC032840F0B1822069F9 +:10239000FBF753FC01F02DFC00F0AABA206900798C +:1023A000F8E7A06890F864101A290DD0022000F018 +:1023B000D6B95AE28C010020D3E19FE140E10EE161 +:1023C00023E14DE0BEE0C6E16178002940F0908253 +:1023D000002580F88D5080F88850D0F8F8100088DB +:1023E0004988814218BFFFDFA068D0F8F8100D704F +:1023F000D0F844110A78002A18BFFFDF2BD190F8DB +:102400008E207AB180F88E500288CA80D0F84411AC +:102410000D71D0F844210E211170D0F844210188AB +:10242000518010E00288CA80D0F844110D71D0F8B4 +:10243000442101211172D0F844210D211170D0F8EE +:102440004421018851800088F0F7D0FBF0F768F84C +:10245000E078E0F761FDA06880F8645000F048BAC9 +:10246000A0680023194690F865205830FAF700FD5F +:1024700048B9A0680023082190F864205830FAF782 +:10248000F7FC00287ED06078002840F03182A068F8 +:1024900090F8900010F0020F14D12069FBF74CFB6C +:1024A000A16881F891002069B0F80520A1F8922078 +:1024B000B0F80700A1F8940091F8900040F00200F5 +:1024C00081F89000A06890F8901011F0010F12D1DF +:1024D00090F86520002319465830FAF7C9FC002807 +:1024E00008BFFFDF0121A06880F8651080F88C101C +:1024F0000021A0F88A10A06890F86410012907D183 +:10250000002180F8641080F88810E078E0F704FD7E +:10251000A168D1F8F800098842888A4204BF01788E +:10252000042940F0E5814FF000050570E078E0F700 +:10253000F3FCA06890F86410002908BF80F8885068 +:1025400000F0D6B9A0680023072190F86420583025 +:10255000FAF78EFCB0B16078002840F0C98102A97A +:102560002069FBF723FB9DF80800002500F02501FA +:10257000A06880F896109DF8091001F0490180F8D4 +:10258000971000E04EE080F88850D0F8F8100088EE +:102590004988814218BFFFDFA068D0F8F8100D709D +:1025A000D0F844110A78002A18BFFFDF7FF453AF38 +:1025B0000288CA80D0F844110D71D0F84411029AF3 +:1025C0008A60039ACA60D0F84421082111700188FA +:1025D000D0F844014180E078E0F79EFC3BE7A0683A +:1025E0000023092190F864205830FAF741FCC8B163 +:1025F0006078002840F07C81A16881F87C0081F837 +:10260000880081F8640000F073B9A06800231946BF +:1026100090F865205830FAF72BFC18B1607818B1A3 +:1026200000F066B901209AE0A0680021A0F88A10A5 +:10263000012180F88C10022180F8651000F058B953 +:10264000A0680023194690F865205830FAF710FC6E +:1026500088B32069FBF794FA00287CD0A56820692C +:10266000FBF78AFA2887A5682069FBF781FA688753 +:10267000A5682069FBF782FAA887A5682069FBF79F +:1026800079FAE887A06890F864101C2913BF90F8C5 +:102690004E10012180F84E10012907D090F8051145 +:1026A000002904BF90F80411002905D04FF01E0145 +:1026B00080F865101AE04FE04FF01D0180F86510BA +:1026C0000288A0F82A21028FA0F82C21428FA0F8BE +:1026D0002E21828F00F58A71A0F83021C08FC88327 +:1026E0004FF001000875E078E0F716FCA0680021C3 +:1026F000A0F88A10012180F88C10F9E0A06800236E +:102700000A2190F864205830FAF7B2FB20B3206910 +:10271000FBF736FAA8B1A5682069FBF72DFA2887E0 +:10272000A5682069FBF724FA6887A5682069FBF78C +:1027300025FAA887A5682069FBF71CFAE88700F04E +:102740002FFFA068002180F8881080F8641000BF77 +:1027500000F0DFFECCE058E0607840F001006070EF +:10276000C6E0A0680023194690F865205830FAF7B3 +:102770007FFB00283FF456AFA06890F86400232840 +:1027800012BF2428607840F02000E8D06846F5F7B2 +:1027900036F9002808BF002104D0009802A9C078AB +:1027A0008DF80800A06801AB162290F86400FAF7D3 +:1027B00056FE88B1A0689DF80420162180F8EC2010 +:1027C00080F8ED10192180F86510012180F88C1037 +:1027D0000021A0F88A108BE02069FBF7ECF9A0B18A +:1027E0002169087900F00702A06880F85020497933 +:1027F00001F0070180F8511090F80F31002B04BF51 +:1028000090F80E31002B05D024E04FF00000FFF7C8 +:102810007AFC6DE090F855C000F15403944501BF77 +:102820001A788A42012180F87D1013D00288A0F81E +:10283000362190F8502000F58A7180F8382190F800 +:10284000510081F825004FF0010081F82000E07868 +:10285000E0F762FBA068212180F86510012180F873 +:102860008C100021A0F88A1042E0A06890F8640063 +:102870001F287FF471AF2069FBF7A7F988B320699F +:10288000A2680179407901F0070161F30705294643 +:1028900000F0070060F30F21012082F88800002576 +:1028A000A2F88450232082F86400566DD2F81001FB +:1028B000FAF754FDF2B2C1B28A4207BFA16881F8AB +:1028C000F250A26882F8F210C6F30721C0F3072085 +:1028D000814219BFA16881F8F300A06880F8F35025 +:1028E00006E0FFE70120FFF70EFC1E20FFF78DFB3F +:1028F000A068D0E92A12491C42F10002C0E92A125C +:1029000004B070BD2DE9F047FE4D04464FF00007BE +:10291000687808436870287910F0200F284680688E +:1029200018BFA0F87E7004D1B0F87E10491CA0F842 +:102930007E1090F86A10012639B990F864200023BF +:1029400006215830FAF794FA58B3A88810F4006FAB +:1029500007D0A86890F86A10002918BFA0F8767010 +:102960001FD1A868B0F87610491C89B2A0F876107B +:10297000B0F878208A422CBF511A00218288521D5B +:102980008A4228BF80F87C60B0F87610B0F87820D2 +:10299000914206D3A0F8767080F81A61E878E0F7E3 +:1029A000BBFA287910F0600F08D0A86890F868107A +:1029B00021B980F868600121FFF70CF94FF0080891 +:1029C000002C56D16878002851D1287910F0040FD6 +:1029D0000DD0A86890F86400032808BFFFDFA8683E +:1029E00090F86710072904BF2E7080F8677001F017 +:1029F00051F9287910F0080F19D06878B8B9A8688B +:102A0000002190F8CB00FFF739FBA86890F8CB00C5 +:102A1000FE2808BFFFDFFE21A86880F8CB1090F8E1 +:102A20006710082903D10221297080F86770FFF729 +:102A3000A5FBA87810F0080F16D0A8680023052180 +:102A400090F864205830FAF713FA50B185F80180F5 +:102A5000A868D0F8441108780D2808BF0020087035 +:102A600002E00020F8F73EFEA86801F04BF800F005 +:102A7000E1FDA868A14600F1580490F8F40030B9CF +:102A8000E27B002301212046FAF7F2F910B1608DB4 +:102A9000401C60853D21B9F1000F18D1287802282B +:102AA00008BF16200ED0012804BFA86890F8F600D1 +:102AB00008D06878E8B110F0140F1CBF1E202077F2 +:102AC00002D005E0207703E010F0080F02D0217754 +:102AD000E67641E010F0030F03D02A202077E67657 +:102AE0003AE010F0200F08BFFFDF23202077E676C2 +:102AF00032E094F8300028B1A08D411CA185E18D11 +:102B0000884213D294F8340028B1608E411C61864B +:102B1000E18D88420AD2618D208D814203D3AA685B +:102B200092F8F42012B9E28D914203D3222020774B +:102B3000E67611E0217C31B1E18C814228BF84F836 +:102B40001C80C5D206E0E08C062803D33E20207707 +:102B5000E67601E0E07EA0B1277367732774022157 +:102B6000A868FFF737F8A86890F8CB10012904D1BE +:102B7000D0F8FC000178491E0170E878E0F7CCF944 +:102B800003E00021A868FFF725F8BDE8F047F4F757 +:102B900045BF5C4A51789378194314D111460128F6 +:102BA000896809D0107910F0040F03D091F86700FC +:102BB000072808D001207047B1F84800098E8842E4 +:102BC00001D8FEF79DBC0020704770B54D4C0646FD +:102BD0000D46A0883043A08016F0020F04D016F0F6 +:102BE000010F18BFFFDFE56016F0010F18BF256168 +:102BF00016F0020F4FF000024FF0010117D0E878F5 +:102C0000062802D00B280BD011E0A06890F86420B1 +:102C1000182A0CD10022C0E92A2280F86A1006E0A6 +:102C2000A06890F86410122908BF80F86A2016F096 +:102C3000800F1CBF0820A07016F4806F08BF70BD05 +:102C4000A268B2F8580091880844801DE97880B2E3 +:102C5000012908BFA2F802011FD0002904BFD2F841 +:102C6000F810888019D0182917D192F8F21000298D +:102C700004BF92F8F330002B0BD011F00C0F1EBFE5 +:102C800092F8543013F00C0F994204D092F8F310DC +:102C900009B94FF00000A2F8F000E97828460129B0 +:102CA00009D071B1182918BF70BDB2F8F010BDE895 +:102CB0007040FAF79CBFB2F802114172090AA9727A +:102CC00070BDD2F8F81089884173090AA97370BDE4 +:102CD000F0B50C4C85B00026A060A6806670A6708A +:102CE000054626700088F4F761FEA0680088F4F7B6 +:102CF00083FEB5F8D800A168401C82B201F15800EB +:102D000002E000008C010020F9F769FE002818BFDE +:102D1000FFDF95F8650024280AD1B5F85810B5F8FA +:102D2000F000081A00B20028A4BF6078002806D07E +:102D300095F86400242818BF25283BD119E0A06825 +:102D400090F8F210002908BF90F8541080F8541041 +:102D500090F8F310002908BF90F8551080F855102E +:102D60000020FFF752F985F86560A16881F87D6061 +:102D700020E0B5F85810B5F8F000081A00B20028A5 +:102D8000A4BF6078002815D1A06890F8F21000293F +:102D900008BF90F8541080F8541090F8F3100029F0 +:102DA00008BF90F8551080F855100020FFF72DF956 +:102DB00085F86460A5F8D860A06890F8881039B1EB +:102DC000B0F88410B0F88620914224BF05B0F0BD61 +:102DD00090F88C1039B1B0F88A10B0F88620914282 +:102DE00024BF05B0F0BDB0F88220B0F880108A4250 +:102DF00024BF05B0F0BD90F8682092B3B0F87E20F3 +:102E00008A4224BF05B0F0BD90F8CB70FE2F00F0D1 +:102E10001D816846F4F7CDFD002808BFFFDF2221A1 +:102E2000009802F076FC03210098FAF7D1FD009893 +:102E3000017821F0100101703946FAF7EEFD192FE3 +:102E400080F0E280DFE807F0271F1445E0E0E11999 +:102E500070E0E1E163E0E0E0E0D3E1E17A93ACE04F +:102E6000B500B0F87E10062924BF05B0F0BDCBE751 +:102E7000A168009891F8F51003E0A168009891F816 +:102E8000CC100171C1E0A068D0F8FC00411C009892 +:102E9000FAF70FFEB9E0A1680098D1F8F82092790E +:102EA0000271D1F8F82012894271120A8271D1F8A8 +:102EB000F8205289C271120A0272D1F8F820928960 +:102EC0004272120A8272D1F8F810C989FAF7C8FD65 +:102ED0009BE0A068D0F8F800011D0098FAF7F6FD15 +:102EE000A068D0F8F80000F10C010098FAF7F8FD9E +:102EF000A068D0F8F80000F11E010098FAF7F6FD7E +:102F0000A06800F1C0010098FAF7FEFD7DE062695B +:102F100000981178017191884171090A8171518875 +:102F2000C171090A017270E0FE49D1E90001CDE9E1 +:102F3000020102A90098FAF701FE66E0A068B0F865 +:102F400044100098FAF704FEA068B0F84610009804 +:102F5000FAF702FEA068B0F840100098FAF700FEF9 +:102F6000A068B0F842100098FAF7FEFD4DE0A068A6 +:102F7000B0F840100098FAF7F3FDA068B0F84210DE +:102F80000098FAF7F1FDA068B0F844100098FAF73D +:102F9000DFFDA068B0F846100098FAF7DDFD34E0D8 +:102FA000A168009891F81021027191F811114171F6 +:102FB0002BE0A06890F8F300FAF7C7F901460098F3 +:102FC000FAF711FEA16891F8F20010F00C0F1CBF87 +:102FD00091F8541011F00C0F02D0884218BF002055 +:102FE000FAF7B3F901460098FAF7F9FD0DE0A06889 +:102FF00090F8ED100098FAF71AFEA06890F8EC101F +:103000000098FAF718FE00E0FFDFF4F7E5FC00286F +:1030100008BFFFDF0098C178012903D049B1182902 +:103020000FD013E0A168B1F802114172090A817250 +:103030000CE0A168D1F8F81089884173090A8173FE +:1030400004E0A168B1F8F010FAF7D1FDB64800909D +:10305000B64BB74A29463046F8F79AFAA0680023DB +:10306000052190F864205830F9F702FF002804BFCA +:1030700005B0F0BD05B0BDE8F040F8F724B8AD48A4 +:10308000806890F8881029B1B0F88410B0F88620D4 +:10309000914219D290F88C1029B1B0F88A10B0F88A +:1030A0008620914210D2B0F88220B0F880108A4277 +:1030B0000AD290F86820B0F87E001AB1884203D294 +:1030C000F8F7ECBA0628FBD3002001461AE470B5E5 +:1030D0000C46064615464FF4A471204602F03BFB11 +:1030E0002680002D08BFFFDF2868C4F8F800686854 +:1030F000C4F8FC00A868C4F8440170BDEFF74DBDEA +:103100002DE9F0410D4607460621EFF73DFC041E70 +:1031100008BFBDE8F081D4F844110026087858B102 +:103120004A8821888A4207D1092810D00E281DD04C +:103130000D2832D008284CD094F81A01002857D016 +:103140006E701020287084F81A61AF803EE06E70B7 +:1031500009202870D4F84401416869608168A96039 +:103160008089A881D4F8440106702FE00846EFF763 +:103170003DFD0746EFF7E9F9B0B96E700E202870F3 +:10318000D4F8440140686860D4F8440106703846B9 +:10319000EFF7D5F90120BDE8F0810846EFF726FDED +:1031A0000746EFF7D2F910B10020BDE8F0816E704C +:1031B0000D202870D4F84401416869600089288195 +:1031C000D4F8440106703846EFF7B9F90120BDE89C +:1031D000F0816E7008202870D4F84401416882683C +:1031E000C0686960AA60E860D4F844010670EDE741 +:1031F00094F81C01B0B16E701520287094F81C0171 +:103200000028E3D084F81C61D4F81E016860D4F86B +:103210002201A860B4F82601A88194F81C010028B6 +:10322000F0D1D3E794F8280170B16E701D2028709A +:1032300084F82861D4F82A016860D4F82E01A860C7 +:10324000B4F83201A881C1E794F8340140B16E703E +:103250001E20287084F83461D4F836016860B5E720 +:1032600094F8140180B16E701B20287094F814013A +:103270000028ABD084F81461D4F81601686094F883 +:1032800014010028F6D1A1E794F83A01002808BFFC +:10329000BDE8F0816E701620287094F83A0100287D +:1032A00094D000BF84F83A61D4F83C016860B4F867 +:1032B0004001288194F83A010028F3D186E71D4A9D +:1032C0005061D17070472DE9F0470446481E85B221 +:1032D00038BFBDE8F08704F108080126DFF85490F4 +:1032E0004FF0090A5FF00007B4F8D800401CA4F8BA +:1032F000D800B4F87E00401CA4F87E0094F86A0060 +:1033000040B994F864200023062104F15800F9F72D +:10331000AFFD38B3B4F87600401C80B2A4F8760054 +:103320000AE00000505D020005290200932B020014 +:10333000CB2B02008C010020B4F8781081422CBF06 +:103340000A1A0022A3885B1D934228BF84F87C6080 +:10335000884207D3A4F8767084F81A6199F80300BC +:10336000DFF7DAFD94F8880020B1B4F88400401C3F +:10337000A4F8840094F88C0020B1B4F88A00401CB2 +:10338000A4F88A0094F8F40040B994F86720002368 +:10339000012104F15800F9F76BFD20B1B4F8820067 +:1033A000401CA4F8820094F864000C2802D00D2878 +:1033B00020D067E0B4F85800411CB4F80201814203 +:1033C00060D1D4F8FC00411C404602F0D8FA02213A +:1033D0002046F9F727FAD4F8FC000078002808BF47 +:1033E000FFDF0121FE20FEF749FE84F8647084F8B7 +:1033F000986047E0B4F85800411CD4F8F800808881 +:1034000081423FD1D4F844010178002918BFFFDF81 +:1034100022D12188C180D4F8F8004189D4F8440130 +:103420000181D4F8F8008189D4F844014181D4F8AD +:10343000F800C189D4F844018181D4F844010771AE +:10344000D4F8440180F800A0D4F8440121884180D8 +:1034500099F80300DFF760FD01212046F9F7E2F952 +:1034600003212046FEF7B6FBD9F80800D0F8F80093 +:103470000078022818BFFFDF0221FE20FEF7FEFDC4 +:1034800084F86470B4F85800401C691EA4F8580011 +:103490008DB2BFF429AFBDE8F087FC4AC2E906014E +:1034A000704770B50446B0F87E0094F868100029A3 +:1034B00008BFC0F1020503D0B4F88010081A051F38 +:1034C00094F87C0040B194F864200023092104F1B1 +:1034D0005800F9F7CDFCA0B1B4F8766094F86A0012 +:1034E00058B994F864200023062104F15800F9F734 +:1034F000BFFC002808BF284603D0B4F87800801B22 +:10350000001FA842D8BF0546002DD4BF0020A8B296 +:1035100070BD042110B5DD4CA068FEF75BFBA06810 +:1035200090F84E10012902BF022180F84E1010BD04 +:1035300000F58A720188A0F81E11018EA0F82011F2 +:10354000818EA0F82211038FB0F844108B4238BF4F +:1035500019461182838FB0F846108B4238BF194646 +:10356000518290F8553013F00C0F4FF0010305D045 +:10357000B1F5296F98BF4FF42961518290F854003A +:1035800010F00C0F06D0D089B0F5296F98BF4FF41A +:103590002960D0811372E078BDE81040DFF7BCBC31 +:1035A000BA4830B4806890F84E30B0F832C0C48E5B +:1035B000B0F84010428F022B25D08A4238BF114606 +:1035C0000186C28FB0F842108A4238BF1146818608 +:1035D000028FB0F844108A4238BF11464186828F6C +:1035E000B0F846108A4238BF1146C186418E614507 +:1035F00088BF8C46A0F832C0C18EA14288BF0C465D +:10360000C48630BC7047038E9A4228BF1A46C58FC5 +:10361000838E9D4238BF2B468A4238BF11460186B1 +:10362000B0F842108B4228BF0B468386002180F8F9 +:103630004E10CDE770B5954CA06890F8CB10FE29E0 +:1036400006BF6178002970BD90F867204FF0000335 +:103650004FF0010100F15800F9F70AFC002818BFEB +:1036600070BDA06890F8F41021B1BDE87040022050 +:10367000FEF7AABC90F86420002319465830F9F7E9 +:10368000F7FB40B1A06890F87C0020B1BDE8704025 +:103690001220FEF799BCA068002590F86420122A39 +:1036A0001FD004DC032A3FD0112A1FD003E0182AC0 +:1036B00035D0232A43D0002304215830F9F7D8FB12 +:1036C000002818BF70BDD4F808C09CF86500192800 +:1036D0007CD03BDC01286BD0022879D003285DD058 +:1036E00038E0BDE870400B20FEF76EBCF2F764FBDB +:1036F0000C2838BF70BDA0680821D0F8F8001E3033 +:10370000F2F75EFB28B1A0680421C030F2F758FB45 +:1037100000B9FFDFBDE870400320FEF755BCBDE8EF +:1037200070400620FEF750BC90F8CA1080F8CC100C +:103730000720FEF749FCA06880F8645070BD18208F +:10374000FEF742FCA068A0F8845070BD1E2847D048 +:1037500021286BD0DCF8F80001260178002973D00D +:103760004088BCF8001088426ED100239CF8642089 +:1037700019460CF15800F9F77BFB002864D0A068CB +:10378000D0F8F810097802297ED003297DD00429C9 +:103790007ED0052908BF08207BD0C7E09CF8C9006F +:1037A0008CF8CC000720FEF70FFCA06800F079B978 +:1037B0000C20FEF709FCA068A0F88A5090F8901041 +:1037C00041F0010180F8901000F06BB96FE0FFE765 +:1037D0001320FEF7F9FBA068A0F88A5000F061B949 +:1037E0009CF80501002818BF70BD9CF8040188B141 +:1037F000BCF80601ACF84000BCF80801ACF8420087 +:10380000BCF80A01ACF84400BCF80C01ACF8460066 +:103810008CF80451FFF7C4FEFFF77BFE1520FEF77E +:10382000D3FBA068A0F88A5000F03BB99CF87D005B +:1038300058B18CF8F2508CF8F3501820FEF7C4FB06 +:10384000A068A0F88A5070BD70E09CF80F010028B5 +:1038500018BF70BD9CF80E01002808BF70BDDCE9E0 +:103860001416DCF81001F9F779FDF2B2C1B28A4200 +:1038700007BFA16881F8F250A26882F8F210C6F37F +:103880000721C0F3072005E016E01BE08C010020B3 +:1038900039E020E0814219BFA16881F8F300A068F7 +:1038A00080F8F3501820BDE87040FEF78DBB112062 +:1038B000FEF78AFBA068F4E090F86500F9F7C0FA1B +:1038C000A0BB08E090F8691041B190F86A000028A8 +:1038D00008BFFFDF0A20FEF777FB27E0F2F76CFA5C +:1038E0000C2823D3A0680821D0F8F8001E30F2F786 +:1038F00067FA28B1A0680421C030F2F761FA00B974 +:10390000FFDF0320E7E790F8900010F0030F0DD1E0 +:103910000C20FEF759FBA168A1F8845081F888605B +:1039200091F8900040F0010081F89000A06890F8B4 +:10393000CB10FE2918BF70BD90F8642000231946F3 +:103940005830F9F795FA002808BF70BDA06890F8C4 +:103950000011E9B3A1690978D1BB90F86500F9F7C6 +:103960006FFAA8BBA068B0F858100A2931D900F145 +:1039700008010522E06901F021FE0028A06804BFCB +:1039800080F8005170BDD0F8FC00017861B1411C95 +:103990000522E06901F012FE002818BF70BDA06882 +:1039A000D0F8FC00007830B9A068E169D0F8FC00DC +:1039B000401C01F0E4FFA068D0F8FC000178491C2D +:1039C00001700120FEF700FBA06880F8005170BD77 +:1039D000FFE7A06890F8041111B190F80511E1B368 +:1039E00090F80E11002908BF70BD90F80F11002942 +:1039F00018BF70BD90F86500F9F722FA002818BFCB +:103A000070BDA06890F85400012808BF012508D0B7 +:103A1000022808BF022504D0042816BF0828032561 +:103A2000FFDFA06890F85500012808BF012608D0E4 +:103A3000022808BF022604D0042816BF082803263F +:103A4000FFDFA268012D92F810012DD0022D2ED09B +:103A5000032D08BF04282CD03BE0FFE7B0F8061187 +:103A6000A0F84010B0F80811A0F84210B0F80A1100 +:103A7000A0F84410B0F80C11A0F8461080F80451DA +:103A800090F865001D2804D0BDE870401420FEF7B2 +:103A90009BBAFFF785FDFFF73CFD1520FEF794FA72 +:103AA000A06880F8655070BD012812D101E002289D +:103AB0000FD192F81101012E06D0022E07D0032E4D +:103AC00008BF04280AD004E0012802D106E0022839 +:103AD00004D0BDE870401620FEF776BAB2F8583030 +:103AE00092F85410B2F81201F032F9F79DFC20B1AF +:103AF000A168252081F8640070BDBDE870400020F9 +:103B0000FEF783BA70B5044690F8640000250C28CF +:103B100014D00D2818BF70BDB4F85800D4F8F810B0 +:103B2000401C8988884218BF70BDD4F84401FF4EFC +:103B30000178002918BFFFDF45D122E0B4F8580012 +:103B4000B4F80211401C884218BF70BDD4F8FC00C4 +:103B5000411C04F1080001F012FF02212046F8F791 +:103B600061FED4F8FC000078002808BFFFDF0121C7 +:103B7000FE20FEF783FA84F86450012084F8980050 +:103B800070BD2188C180D4F8F800D4F84411408970 +:103B90000881D4F8F800D4F8441180894881D4F819 +:103BA000F800D4F84411C0898881D4F84401057123 +:103BB000D4F8441109200870D4F8441120884880B2 +:103BC000F078DFF7A9F901212046F8F72BFE032151 +:103BD0002046FDF7FFFFB068D0F8F8000078022813 +:103BE00018BFFFDF0221FE20FEF748FA84F8645078 +:103BF00070BD70B5CD4CA16891F86420162A11BF34 +:103C0000132A91F88E20002A62781BBF0220607070 +:103C1000002A70BD81F8C8004FF0000581F88D5072 +:103C200081F88850D1F8F80009884088884218BF88 +:103C3000FFDFA068D0F8F8000078032818BFFFDF86 +:103C40000321FE20FEF71AFAA068D0F844110A7882 +:103C5000002A18BFFFDF19D10288CA80D0F844219A +:103C600090F8C8101171D0F844110D72D0F84421A9 +:103C70000D211170D0F84421018851800088EEF7A1 +:103C8000B5FFEEF74DFCE078DFF746F9A06880F865 +:103C9000645070BD10B5A54C207910F0020F08BF1C +:103CA00010BD6078002818BF10BDE068C0781928E2 +:103CB00080F06C81DFE800F05F4F0D8FFAFAA622EA +:103CC0003FFA6F83B1FAFAFAFAF9E5E2FBF7F6FA8E +:103CD000F500A0680023012190F867205830F9F71B +:103CE000C7F8002818BF10BD0821A06880F8671029 +:103CF000002180F8881080F88C1010BDA068002387 +:103D0000194690F865205830F9F7B2F818B1A16853 +:103D1000002081F88C00A0680023194690F86420E8 +:103D20005830F9F7A5F8002808BF10BD0020A16899 +:103D300081F8880010BDA0680023194690F864201F +:103D40005830F9F795F8002808BFFFDF0420A16874 +:103D500081F8640010BDA0680023194690F8642023 +:103D60005830F9F785F8002808BFFFDF0C20A1685C +:103D700081F8640010BDA0680023194690F8642003 +:103D80005830F9F775F8002808BFFFDF0D20A1684B +:103D900081F8640010BDA0680023194690F86420E3 +:103DA0005830F9F765F8002808BFFFDF0121A06847 +:103DB00080F88D105FF00F0180F8641010BDA068CE +:103DC00090F86400122818BFFFDF0121A06880F876 +:103DD0008E101121F0E7A0680023194690F86420A6 +:103DE0005830F9F745F828B9A06890F88E000028F7 +:103DF00008BFFFDF0121A06880F88D10132180F833 +:103E0000641010BDA06890F86400182818BFFFDF88 +:103E10001A20A16881F8640010BDA068D0F8F810DD +:103E200003884A889A4204BF097804291BD190F874 +:103E300064204FF00003194600F15800F9F718F814 +:103E4000002808BFFFDFA06890F8901011F0020F63 +:103E500004BF012180F8641005D0002180F888108B +:103E6000D0F8F8000170A0680023194690F865208A +:103E70005830F8F7FDFF002808BF10BD0020A168EA +:103E800081E0A0680023194690F864205830F8F7C4 +:103E9000EFFF002808BFFFDF0520A16881F864005C +:103EA00010BD30E01FE012E001E068E06EE0A068C5 +:103EB0000023194690F864205830F8F7D9FF0028FD +:103EC00008BFFFDF1C20A16881F86400E8E7A06854 +:103ED0000023194690F865205830F8F7C9FF0028EC +:103EE00008BFFFDFCAE7A0680023194690F86420E6 +:103EF0005830F8F7BDFF002808BFFFDF1F20A1687A +:103F000081F86400CCE7A06890F8651021291DD0E5 +:103F100090F86410232918BFFFDFC1D190F8F21088 +:103F2000002904BF90F8F310002901E08C01002063 +:103F30001CBF242180F864107FF4F8AE4FF000011C +:103F400080F864100846FEF760F8EFE690F8F2108B +:103F5000002907BF90F8F3100029242180F865108C +:103F60008CD14FF0000180F8651080F87D1090F83A +:103F70000E0100281CBF0020FEF747F87EE7A1686D +:103F8000002081F8650081F88C0089E7FFDF87E772 +:103F900070B58D4C0829207A62D2DFE801F004194F +:103FA00059592561615978B1F2F7AFFC01210846F2 +:103FB000F2F7B1FDF3F7F7FB0020A072F2F74DFD29 +:103FC000BDE87040F2F774BFBDE87040F0F728BD5F +:103FD000D4E90001F0F71BFB2060A07A401CC0B2BE +:103FE000A07228281CD370BDA07A0025401EC6B23E +:103FF000E0683044F3F751F810B9E1687F20885544 +:10400000A07A272828BF01252846F3F759FBA07A74 +:10401000282809D2401CC0B2A072282828BF70BD31 +:10402000BDE87040F2F719BD207A00281CBF0120BE +:1040300000F085F8F2F7AEFEF2F72CFF0120E072F7 +:1040400062480078DEF768FFBDE87040F0F7E8BC32 +:10405000002808BF70BD0020BDE8704000F06FB8B8 +:10406000FFDF70BD10B5584C207A002804BF0C202B +:1040700010BD00202072E072607AF1F723F9607AB7 +:10408000F1F76DFB607AF0F7A2FD00280CBF1F204E +:10409000002010BD002270B54B4C06460D46207A1C +:1040A00068B12272E272607AF1F70CF9607AF1F786 +:1040B00056FB607AF0F78BFD002808BFFFDF43480E +:1040C000E560067070BD70B5050007D0A5F5E85035 +:1040D0003F494C3881429CBF122070BD3A4CE06889 +:1040E000002804BF092070BD207A00281CBF0C20C6 +:1040F00070BD3848F0F70FFD6072202804BF1F2004 +:1041000070BDF0F783FD2060002D1CBF28442060A7 +:10411000012065602072002000F011F8002070BDC1 +:104120002949CA7A002A04BF002070471F22027062 +:1041300000224270CB684360CA72012070472DE9AB +:10414000F04184B00746F0F761FD1F4D80464146BF +:1041500068682C6800EB800046002046F1F772FA90 +:10416000B04206DB6868811B4046F0F750FA04460F +:10417000286040F2347621464046F1F763FAB042B7 +:1041800004DA31464046F0F742FA044600208DF842 +:1041900000004FF4DD60039004208DF80500002F2F +:1041A00014BF012003208DF8040068460294F0F744 +:1041B000FCFE687A6946F0F773FF002808BFFFDF4E +:1041C00004B0BDE8F08100004C130020AC010020D9 +:1041D000B5EB3C00913F02002DE9F0410C4612493D +:1041E0000D68114A114908321160A0F120013129EE +:1041F00001D301200CE0412810D040CC0C4F94E8B2 +:104200000E0007EB8000241F50F8807C3046B84732 +:1042100020600548001D0560BDE8F0812046DCF700 +:10422000F7FFF5E706207047100502400100000186 +:10423000585D020010B55348F1F740FD00B1FFDFB3 +:104240005048401CF1F73AFD002800D0FFDF10BDB8 +:104250002DE9F14F4C4ED6F800B001274948F1F74F +:1042600035FDDFF8208128B95FF0000708F1010073 +:10427000F1F742FD454C00254FF003090120606035 +:10428000C4F80051C4F80451009931602060DFF88F +:1042900000A118E0DAF80000C00614D50E2000F0E6 +:1042A00064F8EFF3108010F0010072B600D0012026 +:1042B000C4F80493D4F8001119B9D4F8041101B961 +:1042C00020BF00B962B6D4F8000118B9D4F80401CF +:1042D0000028DFD0D4F804010028CFD137B1C6F8C8 +:1042E00000B008F10100F1F7F1FC11E008F1010064 +:1042F000F1F7ECFC0028B9D1C4F80893C4F80451D4 +:10430000C4F800510E2000F030F81E48F1F7F4FC1C +:104310000020BDE8F88F2DE9F0438DB00D4606462C +:1043200000240DF110090DF1200817E004EB4407FB +:10433000102255F82710684601F06CF905EB870745 +:1043400010224846796801F065F96846FFF780FF5A +:1043500010224146B86801F05DF9641CB442E5DB07 +:104360000DB00020BDE8F08372E7002809DB00F003 +:104370001F02012191404009800000F1E020C0F8B7 +:1043800080127047AD01002004E5004000E00040CD +:1043900010ED00E0B14900200870704770B5B04DD5 +:1043A00001232B60AF4B1C68002CFCD0002407E0DD +:1043B0000E6806601E68002EFCD0001D091D641CDE +:1043C0009442F5D30020286018680028FCD070BD06 +:1043D00070B5A24E0446A44D3078022800D0FFDF0D +:1043E000AC4200D3FFDF7169A048012903D847F22E +:1043F0003052944201DD03224271491C7161291B34 +:10440000C1609A497078F0F74BFE002800D1FFDFB9 +:1044100070BD70B5914C0D466178884200D0FFDFC9 +:10442000914E082D4BD2DFE805F04A041E2D4A4A72 +:104430004A382078022800D0FFDF03202070A078BF +:10444000012801D020B108E0A06800F039FE04E0A6 +:1044500004F1080007C8FFF7A1FF05202070BDE8A0 +:104460007040F0F7DDBAF0F7D1FB01466068F1F774 +:10447000E9F8B04202D2616902290BD30320F1F7B7 +:10448000BCFB12E0F0F7C2FB01466068F1F7DAF816 +:10449000B042F3D2BDE870409AE7207802280AD0F3 +:1044A000052806D0FFDF04202070BDE8704000F032 +:1044B000CAB8022000E00320F1F79FFBF3E7FFDF1B +:1044C00070BD70B50546F0F7A1FB644C60602078C4 +:1044D000012800D0FFDF6549012008700020087125 +:1044E00004208D6048716048C860022020706078A8 +:1044F000F0F7D6FD002800D1FFDF70BD10B5574C96 +:10450000207838B90220F1F78EFB18B90320F1F7B3 +:104510008AFB08B1112010BD5548F0F7FCFA607015 +:10452000202804D0012020700020606110BD0320ED +:1045300010BD2DE9F0471446054600EB84000E46F9 +:10454000A0F1040800F0CFFD07464FF0805001694C +:104550004F4306EB8401091FB14201D2012100E063 +:10456000002189461CB10069B4EB900F02D90920E3 +:10457000BDE8F0872846DCF79FFE90B9A84510D328 +:10458000BD4205D2B84503D245EA0600800701D0F6 +:104590001020EDE73046DCF78FFE10B9B9F1000FBF +:1045A00001D00F20E4E7334833490068884205D042 +:1045B000224631462846FFF7F1FE14E0FFF79EFF42 +:1045C0000028D5D1254800218560C0E903648170A9 +:1045D00000F06FF810B14FF4A97000E0292060439B +:1045E0001830FFF76EFF0020C2E770B505464FF0A8 +:1045F000805004696C432046DCF75EFE08B10F2052 +:1046000070BD00F070FDA84201D8102070BD19489F +:1046100019490068884203D0204600F051FD10E09F +:10462000FFF76CFF0028F1D10C48012184608170F4 +:1046300000F03FF808B1114800E011481830FFF7CA +:1046400040FF002070BD10B5044C6078F0F7BFFA51 +:1046500000B9FFDF0020207010BD0000B001002075 +:1046600004E5014000E40140105C0C005C130020F4 +:104670001344020054000020BEBAFECA645E01006A +:10468000084C01004FF08050D0F830010A2801D0CA +:10469000002070470120704700B5FFF7F3FF20B1FD +:1046A0004FF08050D0F8340108B1002000BD012047 +:1046B00000BD4FF08050D0F83011062905D0D0F859 +:1046C0003001401C01D000207047012070474FF09E +:1046D0008050D0F83001082801D000207047012018 +:1046E000704700B5FFF7E5FF48B14FF08050D0F8B4 +:1046F0003411062905D3D0F83401401C01D0002024 +:1047000000BD012000BD00B5FFF7D3FF58B14FF049 +:104710008050D0F83411062905D3D0F83401401C5C +:1047200001D0012000BD002000BD00007B490968C8 +:10473000016000207047794908600020704701211E +:104740008A0720B1012804D042F204007047916723 +:1047500000E0D1670020704771490120086042F2F3 +:104760000600704708B504236D4A1907103230B1AE +:10477000C1F80433106840F0010010600BE01068CD +:1047800020F001001060C1F808330020C1F80801D2 +:10479000644800680090002008BD011F0B2909D85B +:1047A0005F4910310A6822F01E0242EA40000860A8 +:1047B0000020704742F2050070470F2809D8584979 +:1047C00010310A6822F4706242EA0020086000207A +:1047D000704742F205007047000100F18040C0F8C8 +:1047E000041900207047000100F18040C0F808194A +:1047F00000207047000100F18040D0F800090860F7 +:1048000000207047012801D907207047464A52F816 +:10481000200002680A43026000207047012801D985 +:1048200007207047404A52F8200002688A4302601D +:1048300000207047012801D9072070473A4A52F8F2 +:1048400020000068086000207047020037494FF0E0 +:10485000000003D0012A01D0072070470A6070478A +:10486000020033494FF0000003D0012A01D0072095 +:1048700070470A60704708B54FF40072510510B1D7 +:10488000C1F8042308E0C1F808230020C1F824017E +:1048900024481C3000680090002008BD08B5802224 +:1048A000D10510B1C1F8042308E0C1F808230020A5 +:1048B000C1F81C011B48143000680090002008BD9E +:1048C00008B54FF48072910510B1C1F8042308E0D7 +:1048D000C1F808230020C1F82001124818300068F0 +:1048E0000090002008BD0D493831096801600020A2 +:1048F00070474FF080410020C1F80801C1F8240141 +:10490000C1F81C01C1F820014FF0E020802180F89F +:1049100000140121C0F8001170470000000400409D +:1049200000050040080100401C5E020078050040C0 +:10493000800500406249634B0A6863499A420968EE +:1049400001D1C1F310010160002070475C495D4B4B +:104950000A685D49091D9A4201D1C0F31000086040 +:10496000002070475649574B0A68574908319A4208 +:1049700001D1C0F3100008600020704730B5504BE3 +:10498000504D1C6842F20803AC4202D0142802D2F7 +:1049900003E0112801D3184630BDC3004B4818442A +:1049A000C0F81015C0F81425002030BD4449454B0F +:1049B0000A6842F209019A4202D0062802D203E0B4 +:1049C000042801D308467047404A012142F83010BC +:1049D000002070473A493B4B0A6842F209019A426B +:1049E00002D0062802D203E0042801D3084670470B +:1049F000364A012102EBC00041600020704770B5CB +:104A00002F4A304E314C156842F2090304EB800204 +:104A1000B54204D0062804D2C2F8001807E00428E2 +:104A200001D3184670BDC1F31000C2F80008002081 +:104A300070BD70B5224A234E244C156842F209031A +:104A400004EB8002B54204D0062804D2D2F8000854 +:104A500007E0042801D3184670BDD2F80008C0F35F +:104A600010000860002070BD174910B508311848C3 +:104A700008601120154A002102EBC003C3F810158D +:104A8000C3F81415401C1428F6D3002006E00428AF +:104A900004D302EB8003C3F8001807E002EB8003A5 +:104AA000D3F80048C4F31004C3F80048401C06289B +:104AB000EDD310BD04490648083108607047000076 +:104AC00054000020BEBAFECA00F5014000F00140CB +:104AD0000000FEFF834B1B6803B19847BFF34F8F65 +:104AE00081480168814A01F4E06111430160BFF32C +:104AF0004F8F00BFFDE710B5EFF3108010F0010FEE +:104B000072B601D0012400E0002400F0E1F850B1B9 +:104B1000DCF772FCEFF73FFEF1F711F8E7F700FA68 +:104B200073490020086004B962B6002010BD2DE969 +:104B3000F0410C460546EFF3108010F0010F72B6FD +:104B400001D0012600E0002600F0C2F820B106B92D +:104B500062B60820BDE8F081DCF742FBDCF750FCD0 +:104B60000246002001234709BF0007F1E02700F0BB +:104B70001F01D7F80071CF40F9071BD0202803D2BE +:104B800022FA00F1C90727D141B2002904DB01F163 +:104B9000E02191F8001405E001F00F0101F1E0219E +:104BA00091F8141D4909082916D203FA01F717F0E4 +:104BB000EC0F11D0401C6428D5D3E7F78FF94D4A8C +:104BC0004D490020E7F7D2F949494C480860204692 +:104BD000DCF779FB60B904E006B962B641F2010086 +:104BE000B8E7404804602DB12846DCF7B9FB18B19E +:104BF00010242CE0424D19E02878022802D94FF405 +:104C0000805424E007240028687801D0F8B908E02F +:104C1000E8B120281BD8A878212818D8012816D058 +:104C200001E0A87898B9E8780B2810D83549802099 +:104C300081F8140DDCF7E4FB2946F0F766FFEFF787 +:104C400069FD00F083FA2846DCF7A8FB044606B9A4 +:104C500062B61CB1FFF74FFF20467BE7002079E7E3 +:104C600010B5044600F034F800B101202070002097 +:104C700010BD254908600020704770B50C462349D7 +:104C80000D682249224E08310E60102807D01128E5 +:104C90000CD012280FD0132811D0012013E0D4E932 +:104CA0000001FFF744FF354620600DE0FFF723FFCA +:104CB0000025206008E02068FFF7D2FF03E01249DA +:104CC00020680860002020601048001D056070BD4D +:104CD00007480A490068884201D101207047002036 +:104CE00070470000C80100200CED00E00400FA0548 +:104CF00054000020F813002000000020BEBAFECAB5 +:104D0000245E02000BE000E00400002010050240D9 +:104D10000100000100B59B4902282ED021DC10F1D2 +:104D20000C0F08BFF42028D00FDC10F1280F08BFAB +:104D3000D82022D010F1140F08BFEC201DD010F1A4 +:104D4000100F08BFF02018D021E010F1080F08BFA5 +:104D5000F82012D010F1040F0CBFFC2000280CD05A +:104D600015E0A0F10300062811D2DFE800F00E0CD8 +:104D70000A080503082000E00720086000BD06209F +:104D8000FBE70520F9E70420F7E70320F5E7FFDF5D +:104D900000BD00B57C49012808BF03200CD00228C3 +:104DA00008BF042008D0042808BF062004D0082823 +:104DB00016BFFFDF052000BD086000BD70B50546C9 +:104DC0000C4616461046F2F7A5FC022C08BF4FF41D +:104DD0007A7105D0012C0CBF4FF4C86140F6340144 +:104DE00044183046F2F7D0FC204449F67971084463 +:104DF0004FF47A71B0FBF1F0281A70BD70B505461A +:104E00000C460846F2F79FFC022C08BF40F24C41CA +:104E100005D0012C0CBF40F634014FF4AF5149F6D8 +:104E2000CA62511A08444FF47A7100F2E140B0FBB3 +:104E3000F1F0281A801E70BD70B5064615460C4666 +:104E40000846F2F780FC022D08BF4FF47A7105D0B6 +:104E5000012D0CBF4FF4C86140F63401022C08BF8D +:104E600040F24C4205D0012C0CBF40F634024FF406 +:104E7000AF52891A084449F6FC6108444FF47A712C +:104E8000B0FBF1F0301A70BD70B504460E4608460E +:104E9000F2F740FC05463046F2F776FC28444AF229 +:104EA000AB3108444FF47A71B0FBF1F0201A801E48 +:104EB00070BD2DE9F04107461E460D4614461046CA +:104EC000082A16BF04284EF62830F2F723FC07EB19 +:104ED0004701C1EBC71100EBC100022D08BF40F232 +:104EE0004C4105D0012D0CBF40F634014FF4AF51B9 +:104EF00047182846F2F727FC381A4FF47A7100F663 +:104F0000B730B0FBF1F52046F2F7F2FB284430440D +:104F1000401DBDE8F08170B5054614460E460846B2 +:104F2000F2F7F8FB05EB4502C2EBC512C0EBC20578 +:104F30003046F2F729FC2D1A2046082C16BF04280B +:104F40004EF62830F2F7E6FB28444FF47A7100F66B +:104F5000B730B0FBF1F52046F2F7CAFB2844401DFC +:104F600070BD0A49082818BF0428086803BF20F448 +:104F70006C5040F4444040F0004020F00040086095 +:104F8000704700000C15004010150040401700400D +:104F90002DE9FE430C468046F8F72EFD074698F8AB +:104FA0000160204601A96A46EDF7ABFA05000DD075 +:104FB000012F02D00320BDE8FE83204602AA0199FA +:104FC000EDF7C1F90298B0F803000AE0022F14D1FE +:104FD000042E12D3B8F80300BDF80020011D914241 +:104FE00004D8001D80B2A919814202D14FF00000FF +:104FF000E1E702D24FF00100DDE74FF00200DAE70F +:10500000C2790D2341B342BB8188012904D94908E3 +:10501000818004BF012282800168012918BF002914 +:1050200030D001686FEA0101C1EBC10202EB01124D +:1050300081796FEA010101EB8103C3EB8111114416 +:105040004FEA914201608188B2FBF1F301FB132129 +:1050500081714FF0010102E01AB14FF00001C171FE +:1050600070478188FF2908D24FF6FF7202EA41019A +:105070008180FF2984BFFF2282800168012918BF37 +:105080000029CED10360CCE7817931B1491E11F0FE +:10509000FF0181711CBF002070470120704710B5CF +:1050A0000121C1718171818004460421F0F788FEDD +:1050B000002818BF10BD2068401C206010BD0000F3 +:1050C0000B4A022111600B490B68002BFCD0084BE6 +:1050D0001B1D186008680028FCD0002010600868BC +:1050E0000028FCD070474FF08050406970470000A6 +:1050F00004E5014000E4014002000B464FF00000CF +:10510000014620D0012A04D0022A04D0032A0DD15E +:1051100003E0012002E0022015E00320072B05D266 +:10512000DFE803F00406080A0C0E100007207047A1 +:10513000012108E0022106E0032104E0042102E04D +:10514000052100E00621EFF704BD0000F948052124 +:1051500081700021017041707047F7490A78012A77 +:1051600005D0CA681044C8604038F0F738BA8A6879 +:1051700010448860F8E7002819D00378EF49F04A16 +:1051800013B1012B0ED011E00379012B00D06BB9C4 +:1051900043790BB1012B09D18368643B8B4205D263 +:1051A000C0680EE00379012B02D00BB100207047DC +:1051B00043790BB1012BF9D1C368643B8B42F5D223 +:1051C00080689042F2D801207047DB4910B5012277 +:1051D0000A700279A2B100220A71427992B10422C6 +:1051E0004A718268D34C52328A60C0681434C860F5 +:1051F0006060EFF70BFDCF4920600220887010BD82 +:105200000322E9E70322EBE770B5CB4D044600200B +:105210002870207988B100202871607978B1042045 +:10522000C44E6871A168F068EFF7F1F9A860E06812 +:105230005230E8600320B07070BD0120ECE703201D +:10524000EEE72DE9F04105460226F0F7E8F80068A0 +:1052500000B1FFDFB74C01273DB12878B0B101287C +:1052600005D0022810D0032813D027710CE06868FD +:10527000C82807D3F0F70DFA20B16868FFF76DFF73 +:10528000012603E0002601E000F05EF93046BDE8AB +:10529000F08120780028F7D16868FFF76CFF0028BC +:1052A000E3D06868017879B1A078042800D0FFDFE6 +:1052B00001216868FFF7A8FF9F49E078EFF7F0FE4B +:1052C0000028E1D1FFDFDFE7FFF77FFF6770DBE753 +:1052D0002DE9F047974C8846E178884200D0FFDFFF +:1052E000DFF8509200250127934E09F11409B8F117 +:1052F000080F75D2DFE808F0040C28527A808D95EB +:10530000A078032802D0022800D0FFDFBDE8F08794 +:10531000A078032802D0022800D0FFDF0420A0706C +:1053200025712078002878D1FFF717FF3078012801 +:1053300006D0B068E06000F027F92061002060E04E +:10534000E078EFF7AAFDF5E7A078032802D002285D +:1053500000D0FFDF207800286DD1A078032816D078 +:10536000EFF754FC01464F46D9F80000F0F76AF910 +:1053700000280EDB796881420BDB081AF0606E4969 +:10538000E078EFF78DFE0028C0D1FFDFBEE70420F4 +:1053900028E00420F0F731FCA570B7E7A0780328D7 +:1053A00002D0022800D0FFDF207888BBA078032835 +:1053B00017D0EFF72BFC01464F46D9F80000F0F765 +:1053C00041F90028E5DB79688142E2DB081AF060E8 +:1053D0005949E078EFF764FE002897D1FFDF95E7A1 +:1053E00040E00520F0F709FCA7708FE7A0780428BB +:1053F00000D0FFDF022004E0A078042800D0FFDF07 +:105400000120A1688847FFF71CFF054630E004E053 +:1054100011E0A078042800D0FFDFBDE8F04700F0DD +:1054200093B8A078042804D0617809B1022800D08C +:10543000FFDF207818B1BDE8F04700F08EB8207982 +:1054400020B10620F0F7D9FB2571CDE7607838B19F +:105450003949E078EFF724FE00B9FFDF657055E7C2 +:105460000720BFE7FFDF51E73DB1012D03D0FFDF8C +:10547000022DF9D14AE70420C3E70320C1E770B544 +:10548000050004D02B4CA078052806D101E010209F +:1054900070BD0820F0F7C7FB08B1112070BD294886 +:1054A000EFF739FBE070202806D00121F0F7EBF987 +:1054B0000020A560A07070BD032070BD1D4810B510 +:1054C000017809B1112010BD8178052906D0012984 +:1054D00006D029B101210170002010BD0F2010BDA0 +:1054E00000F03BF8F8E770B5124C0546A07808B11B +:1054F000012809D155B12846FFF73DFE40B1287873 +:1055000040B1A078012809D00F2070BD102070BDD7 +:10551000072070BD2846FFF758FE03E0002128460B +:10552000FFF772FE0449E078EFF7BAFD00B9FFDF3C +:10553000002070BDCC0100206C1300203D860100CE +:10554000FF1FA107D15202000A4810B5006900F000 +:1055500013F8BDE81040EFF763BA064810B5C078FD +:10556000EFF735FB00B9FFDF0820F0F746FBBDE899 +:105570001040EBE5CC0100200C490A6848F2021308 +:105580009A4302430A607047084A116848F20213BE +:1055900001EA03009943116070470246044B102052 +:1055A0001344FC2B01D8116000207047C80602404C +:1055B0000018FEBF704770477047704740EA01030C +:1055C00010B59B070FD1042A0DD310C808C9121FAC +:1055D0009C42F8D020BA19BA884201D9012010BDE6 +:1055E0004FF0FF3010BD1AB1D30703D0521C07E0B3 +:1055F000002010BD10F8013B11F8014B1B1B07D117 +:1056000010F8013B11F8014B1B1B01D1921EF1D187 +:10561000184610BD032A40F2308010F0030C00F051 +:10562000158011F8013BBCF1020F624498BF11F8DC +:1056300001CB00F8013B38BF11F8013BA2F1040295 +:1056400098BF00F801CB38BF00F8013B11F003030D +:1056500000F02580083AC0F0088051F8043B083A71 +:1056600051F804CBA0E80810F5E7121D5CBF51F813 +:10567000043B40F8043BAFF30080D20724BF11F88D +:10568000013B11F801CB48BF11F8012B24BF00F8F2 +:10569000013B00F801CB48BF00F8012B704710B563 +:1056A000203AC0F00B80B1E81850203AA0E818501A +:1056B000B1E81850A0E81850BFF4F5AF5FEA027CDB +:1056C00024BFB1E81850A0E8185044BF18C918C04A +:1056D000BDE810405FEA827C24BF51F8043B40F8EB +:1056E000043B08BF7047D20728BF31F8023B48BFD0 +:1056F00011F8012B28BF20F8023B48BF00F8012B0E +:10570000704702F0FF0343EA032242EA024200F03C +:1057100002B84FF000020429C0F0128010F0030C10 +:1057200000F01B80CCF1040CBCF1020F18BF00F894 +:10573000012BA8BF20F8022BA1EB0C0100F00DB843 +:105740005FEAC17C24BF00F8012B00F8012B48BFA1 +:1057500000F8012B70474FF0000200B51346944645 +:105760009646203922BFA0E80C50A0E80C50B1F1B9 +:105770002001BFF4F7AF090728BFA0E80C5048BFCD +:105780000CC05DF804EB890028BF40F8042B08BF6B +:10579000704748BF20F8022B11F0804F18BF00F867 +:1057A000012B70477047704770477047FEDF1849FC +:1057B0000978F9B90420714608421BD10699154AA7 +:1057C000914217DC0699022914DB02394878DF2858 +:1057D00010D10878FE2807D0FF280BD14FF0010028 +:1057E0004FF000020C4B184741F201000099019A5A +:1057F000094B1847094B002B02D01B68DB68184780 +:105800004FF0FF3071464FF00002034B1847000085 +:1058100028ED00E000600200D54A020004000020EC +:10582000174818497047FFF7FBFFDBF7C7FC00BDBF +:10583000154816490968884203D1154A13605B6808 +:10584000184700BD20BFFDE70F481049096888428E +:1058500010D1104B18684FF0FF318842F2D080F31E +:1058600008884FF02021884204DD0B48026803219C +:105870000A4302600948804709488047FFDF00006B +:105880008013002080130020001000000000002082 +:10589000040000200060020014090040C52F000031 +:1058A0003158020004207146084202D0EFF309810A +:1058B00001E0EFF30881886902380078102813DBD3 +:1058C00020280FDB2C280BDB0A4A12680A4B9A426D +:1058D00003D1602804DB094A1047022008607047A2 +:1058E000074A1047074A1047074A12682C321268C5 +:1058F0001047000054000020BEBAFECA0514000084 +:10590000D94102007B4C0200040000200D4B0E49DF +:1059100008470E4B0C4908470D4B0B4908470D4BE8 +:10592000094908470C4B084908470C4B06490847EA +:105930000B4B054908470B4B034908470A4B0249E3 +:1059400008470000BDBC000039C00000552D000014 +:10595000CF2B00005D2B0000F72D0000211400006C +:105960001B2900004D2F0000C9110000002101601B +:1059700081807047002101604160017270470A68B0 +:1059800002600B79037170476D960000CB970000A1 +:105990002D99000091990000CB990000FF9900001B +:1059A000319A0000699A0000D79A00001B97000006 +:1059B00051990000A7120000C14300000D440000EF +:1059C00073440000FF44000023460000E546000049 +:1059D00017470000EF47000087480000DB48000041 +:1059E000C1490000E1490000C3160000E7160000AD +:1059F000171600006B16000019170000AD17000005 +:105A000037600000E7610000AD650000C56600007A +:105A10004F670000CD670000316800005169000049 +:105A2000216A00008D6A0000034A0000094A000054 +:105A3000134A00007B4A0000A74A0000534C0000B4 +:105A40007D4C0000B54C00001F4D0000034E0000CF +:105A5000214E000031440000A7120000A7120000F0 +:105A6000A7120000A7120000A7120000A712000052 +:105A7000A7120000A32500002926000045260000EB +:105A800061260000EF2700008B260000952600000D +:105A9000D7260000F9260000D527000017280000AF +:105AA000A7120000A7120000BB830000DB830000E8 +:105AB000E58300001F8400004D8400003D85000048 +:105AC000CB850000DF8500002D86000043870000A5 +:105AD000E9880000118A00003F730000298A000055 +:105AE000A7120000A7120000B5B500001FB7000004 +:105AF00073B70000DFB700008FB80000010000009E +:105B000000000000100110013A0200001A02000417 +:105B100005060000FFFFFFFF0000FFFFA9AD00002A +:105B2000233D00004921000089730000018F00001F +:105B300000000000AD910000899100009B910000E1 +:105B40000000020000000000000200000000000051 +:105B50000001000000000000678100004781000094 +:105B6000B581000025250000E7240000072500007E +:105B700013A900003FA9000047AB00003159000005 +:105B8000D5810000000000000582000073250000A0 +:105B900000000000000000000000000029AA000032 +:105BA00000000000C55900000300000001555555D4 +:105BB000D6BE898E00006306630C631200000703E3 +:105BC000AB054F08000053044308330C00000000ED +:105BD000900A0000900A0000B3560000B35600007F +:105BE0009D43000055AC00000B7600005B200000D8 +:105BF000CF300200ADA30100F1560000F1560000C5 +:105C0000BF430000B7AC00008F760000CD2000003D +:105C1000FD300200C1A30100700170014000380096 +:105C20005C0024004801000200000300656C7462FF +:105C30000000000000000000000000000000000064 +:105C400087000000000000000000000000000000CD +:105C5000BE83605ADB0B376038A5F5AA9183886C48 +:105C6000010000004F31010015400100000000015B +:105C70000206030405000000070000000000000009 +:105C8000060000000A00000032000000730000005F +:105C9000B4000000BF8E0100DF1C0200F3F800001A +:105CA000B9B601002FF50100B9B6010091FA000064 +:105CB00077B80100F5F1010077B80100CDF60000DA +:105CC00005B8010051F4010005B80100EFF800002B +:105CD000CDB60100E5ED0100CDB6010043FF0000A7 +:105CE000F9BA0100E3F50100F9BA0100F401FA0084 +:105CF000960064004B0032001E0014000A000500EC +:105D0000020001000049000000000000AAAED7AB6D +:105D1000154120100C0802170D01010209090101AB +:105D20000602091818030101090903030555555511 +:105D3000252627D6BE898E00F401FA00960064005D +:105D40004B0032001E0014000A0005000200010092 +:105D50002549000000000000354902004D490200BD +:105D6000654902007D490200AD490200D5490200A3 +:105D7000FF490200334A0200EB45020033450200AE +:105D8000254202009B550200BD5C0100CD5C010074 +:105D9000F95C0100CB5D0100D35D0100E55D010010 +:105DA0003F470200594702002D47020037470200D3 +:105DB000654702009B470200BB470200D94702002B +:105DC000E7470200F5470200054802001D480200AF +:105DD000354802004B480200614802000000000004 +:105DE00063BA0000B9BA0000CFBA0000F95002004F +:105DF00051420200174302007F540200BD540200CA +:105E0000E75402009D5B0100FD5F0100774802003E +:105E10009D480200C1480200E74802001C050040FE +:105E20002005004000100200485E0200080000202B +:105E3000E0010000441100007C5E0200E801002047 +:105E400098110000A0110000011413F81302412062 +:105E50000A2006441A0102228C2720FB349B5F8013 +:105E60001280021E10133F0B1420FC0A1B20820814 +:0C5E7000019C0916C7327F0B6CF410BCBB +:00000001FF diff --git a/ports/nrf/boards/adafruit_nrf52840_s140_v6.ld b/ports/nrf/boards/adafruit_nrf52840_s140_v6.ld new file mode 100644 index 00000000000..2587a19e343 --- /dev/null +++ b/ports/nrf/boards/adafruit_nrf52840_s140_v6.ld @@ -0,0 +1,45 @@ +/* + GNU linker script for NRF52840 w/S140 6.x.x SoftDevice + + MEMORY MAP + ------------------------------------------------------------------------ + START ADDR END ADDR SIZE DESCRIPTION + ---------- ---------- ------- ----------------------------------------- + 0x000FF000..0x000FFFFF ( 4KB) Bootloader Settings + 0x000FE000..0x000FEFFF ( 4KB) Master Boot Record Params + 0x000F4000..0x000FDFFF ( 40KB) Bootloader (UF2 + CDC + OTA) + + 0x000ED000..0x000F3FFF (28KB ) Private Config Data (Bonding, Keys, etc.) + 0x000AD000..0x000ECFFF (256KB) User Filesystem + 0x00026000..0x000ACFFF (540KB) Application Code (including ISR vector) + 0x00001000..0x00025FFF (148KB) SoftDevice + 0x00000000..0x00000FFF (4KB) Master Boot Record +*/ + +/* Specify the memory areas (S140 6.x.x) */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000 + + FLASH_ISR (rx) : ORIGIN = 0x00026000, LENGTH = 0x001000 + FLASH_TEXT (rx) : ORIGIN = 0x00027000, LENGTH = 0x086000 + FLASH_FATFS (r) : ORIGIN = 0x000AD000, LENGTH = 0x040000 + + /* 0x2000000 - RAM:ORIGIN is reserved for Softdevice */ + RAM (xrw) : ORIGIN = 0x20004000, LENGTH = 0x20040000 - 0x20004000 +} + +/* produce a link error if there is not this amount of RAM for these sections */ +_minimum_stack_size = 2K; +_minimum_heap_size = 0; + +/* top end of the stack */ + +/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/ +_estack = ORIGIN(RAM) + LENGTH(RAM); + +/* RAM extents for the garbage collector */ +_ram_end = ORIGIN(RAM) + LENGTH(RAM); +_heap_end = 0x20020000; /* tunable */ + +INCLUDE "boards/common.ld" diff --git a/ports/nrf/boards/board.h b/ports/nrf/boards/board.h new file mode 100644 index 00000000000..ec98f04fbe0 --- /dev/null +++ b/ports/nrf/boards/board.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +// This file defines board specific functions. + +#ifndef MICROPY_INCLUDED_NRF_BOARDS_BOARD_H +#define MICROPY_INCLUDED_NRF_BOARDS_BOARD_H + +#include + +// Initializes board related state once on start up. +void board_init(void); + +// Returns true if the user initiates safe mode in a board specific way. +// Also add BOARD_USER_SAFE_MODE in mpconfigboard.h to explain the board specific +// way. +bool board_requests_safe_mode(void); + +// Reset the state of off MCU components such as neopixels. +void reset_board(void); + +#endif // MICROPY_INCLUDED_NRF_BOARDS_BOARD_H diff --git a/ports/nrf/boards/circuitplayground_bluefruit/board.c b/ports/nrf/boards/circuitplayground_bluefruit/board.c new file mode 100644 index 00000000000..4421970eefe --- /dev/null +++ b/ports/nrf/boards/circuitplayground_bluefruit/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.h b/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.h new file mode 100644 index 00000000000..1e55cd02609 --- /dev/null +++ b/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.h @@ -0,0 +1,72 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "nrfx/hal/nrf_gpio.h" + +#define MICROPY_HW_BOARD_NAME "Adafruit Circuit Playground Bluefruit" +#define MICROPY_HW_MCU_NAME "nRF52840" +#define MICROPY_PY_SYS_PLATFORM "CircuitPlaygroundBluefruit" + +#define FLASH_SIZE (0x100000) +#define FLASH_PAGE_SIZE (4096) + +#define MICROPY_HW_LED_STATUS (&pin_P1_14) + +// Unusually, board does not have a 32 kHz xtal. Nearly all boards do. +#define BOARD_HAS_32KHZ_XTAL (0) + +#if QSPI_FLASH_FILESYSTEM +#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 21) +#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 23) +#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(1, 00) +#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 22) +#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19) +#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 15) +#endif + +#if SPI_FLASH_FILESYSTEM +#define SPI_FLASH_MOSI_PIN &pin_P0_21 +#define SPI_FLASH_MISO_PIN &pin_P0_23 +#define SPI_FLASH_SCK_PIN &pin_P0_19 +#define SPI_FLASH_CS_PIN &pin_P0_15 +#endif + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 + +#define CIRCUITPY_INTERNAL_NVM_SIZE (4096) + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_P0_04) +#define DEFAULT_I2C_BUS_SDA (&pin_P0_05) + +#define DEFAULT_SPI_BUS_SCK (&pin_P0_05) +#define DEFAULT_SPI_BUS_MOSI (&pin_P1_03) +#define DEFAULT_SPI_BUS_MISO (&pin_P0_29) + +#define DEFAULT_UART_BUS_RX (&pin_P0_30) +#define DEFAULT_UART_BUS_TX (&pin_P0_14) diff --git a/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.mk b/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.mk new file mode 100644 index 00000000000..dbb32629c65 --- /dev/null +++ b/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.mk @@ -0,0 +1,26 @@ +USB_VID = 0x239A +USB_PID = 0x8046 +USB_PRODUCT = "Circuit Playground Bluefruit" +USB_MANUFACTURER = "Adafruit Industries LLC" + +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +MCU_CHIP = nrf52840 +SD ?= s140 +SOFTDEV_VERSION ?= 6.1.0 + +BOOT_SETTING_ADDR = 0xFF000 + +ifeq ($(SD),) + LD_FILE = boards/nrf52840_1M_256k.ld +else + LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld + CIRCUITPY_BLEIO = 1 +endif + +NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "GD25Q16C" diff --git a/ports/nrf/boards/circuitplayground_bluefruit/pins.c b/ports/nrf/boards/circuitplayground_bluefruit/pins.c new file mode 100644 index 00000000000..55665167950 --- /dev/null +++ b/ports/nrf/boards/circuitplayground_bluefruit/pins.c @@ -0,0 +1,71 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_AUDIO), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_P0_26) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_05) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_29) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_03) }, + + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_04) }, + + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_05) }, + + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_30) }, + + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_14) }, + + { MP_ROM_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_P0_28) }, + + { MP_ROM_QSTR(MP_QSTR_TEMPERATURE), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON_A), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_P1_02) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON_B), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_15) }, + + { MP_ROM_QSTR(MP_QSTR_SLIDE_SWITCH), MP_ROM_PTR(&pin_P1_06) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P1_06) }, + + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P1_14) }, + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P1_14) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P0_13) }, + + { MP_ROM_QSTR(MP_QSTR_MICROPHONE_CLOCK), MP_ROM_PTR(&pin_P0_17) }, + { MP_ROM_QSTR(MP_QSTR_MICROPHONE_DATA), MP_ROM_PTR(&pin_P0_16) }, + + { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_SDA), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_SCL), MP_ROM_PTR(&pin_P1_12) }, + + { MP_ROM_QSTR(MP_QSTR_SPEAKER_ENABLE), MP_ROM_PTR(&pin_P1_04) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/common.ld b/ports/nrf/boards/common.ld new file mode 100644 index 00000000000..df81aae5833 --- /dev/null +++ b/ports/nrf/boards/common.ld @@ -0,0 +1,108 @@ +/* Flash region for File System */ +__fatfs_flash_start_addr = ORIGIN(FLASH_FATFS); +__fatfs_flash_length = LENGTH(FLASH_FATFS); + +/* 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 */ + } >FLASH_TEXT + + /* + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } >FLASH + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + */ + + /* used by the startup to initialize data */ + _sidata = .; + + /* 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 and GC */ + } >RAM + + /* this is to define the start of the heap, and make sure we have a minimum size */ + .heap : + { + . = ALIGN(4); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + _heap_start = .; /* define a global symbol at heap start */ + . = . + _minimum_heap_size; + } >RAM + + /* this just checks there is enough RAM for the stack */ + .stack : + { + . = ALIGN(4); + . = . + _minimum_stack_size; + . = ALIGN(4); + } >RAM + + /* Remove information from the standard libraries */ + /* + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + */ + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + diff --git a/ports/nrf/boards/electronut_labs_blip/README.md b/ports/nrf/boards/electronut_labs_blip/README.md new file mode 100644 index 00000000000..c34ef16f8dd --- /dev/null +++ b/ports/nrf/boards/electronut_labs_blip/README.md @@ -0,0 +1,67 @@ +# Setup + +The `Electronut Labs Blip` board is a development board based on the `nRF52840` SoC from +Nordic Semiconductors. It has a Black Magic Probe compatible programmer and debugger +built in, along with temperature/humidity sensor, ambient light intensity sensor, and +a 3-axis accelerometer. It can be used to prototype very low power devices. It also has +provision for an SD card slot, which makes it a complete and versatile development board. + +Schematic, datasheet, pin mapping etc. can be found over [here](https://docs.electronut.in/blip/). + +Features: + +* Raytac MDBT50Q-1M module based on Nordic Semiconductor's nRF52840 +* LIS2DDH12 High-performance 3-axis "femto" accelerometer +* Optical Sensor LTR-329ALS-01 +* Si7006-A20 I2C humidity and temperature sensor +* On board STM32F103CBT6 as Black magic probe debugger +* NFC Antenna +* MicroSD slot +* Power Supply: USB, JST connector for Li-ion/Li-po +* BQ24079 battery charging and power management IC + +## Installing CircuitPython submodules + +Before you can build, you will need to run the following commands once, which +will install the submodules that are part of the CircuitPython ecosystem, and +build the `mpy-cross` tool: + +``` +$ cd circuitpython +$ git submodule update --init +$ make -C mpy-cross +``` + +## Building and Flashing CircuitPython + +No special notes for this, follow `ports/nrf` generic `README.md`. + +### Flashing CircuitPython with GDB using on board Black magic probe debugger + +``` +$ cd ports/nrf +$ make V=1 SD=s140 SERIAL=/dev/ttyACM0 BOARD=electronut_labs_blip all +... +... +LINK build-electronut_labs_blip-s140/firmware.elf + +778588 bytes free in flash out of 1048576 bytes ( 1024.0 kb ). +228320 bytes free in ram for stack out of 245760 bytes ( 240.0 kb ). + +Create build-electronut_labs_blip-s140/firmware.bin +Create build-electronut_labs_blip-s140/firmware.hex +Create build-electronut_labs_blip-s140/firmware.uf2 +python3 ../../tools/uf2/utils/uf2conv.py -f 0xADA52840 -c -o "build-electronut_labs_blip-s140/firmware.uf2" build-electronut_labs_blip-s140/firmware.hex +Converting to uf2, output size: 540160, start address: 0x26000 +Wrote 540160 bytes to build-electronut_labs_blip-s140/firmware.uf2. +``` + +Now you can use either `.hex` or `.elf` from the generated files inside +`build-electronut_labs_blip-s140` directory. Now you can use `arm-none-eabi-gdb` +to flash circuitpython on Blip. + +### Other tips + +Once circuitpython is running on your board, it will come up as a mass storage +device named `CIRCUITPY`, where you can drop in your python code. The file names +it looks for are `main.py`, `main.txt`, `code.py` or `code.txt`. diff --git a/ports/nrf/boards/electronut_labs_blip/board.c b/ports/nrf/boards/electronut_labs_blip/board.c new file mode 100644 index 00000000000..4421970eefe --- /dev/null +++ b/ports/nrf/boards/electronut_labs_blip/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/electronut_labs_blip/mpconfigboard.h b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.h new file mode 100644 index 00000000000..21e8c3ef61c --- /dev/null +++ b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.h @@ -0,0 +1,53 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * Copyright (c) 2019 tavish@electronut.in + * + * 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 "nrfx/hal/nrf_gpio.h" + +#define ELECTRONUT_LABS_PAPYR + +#define MICROPY_HW_BOARD_NAME "Electronut Labs Blip" +#define MICROPY_HW_MCU_NAME "nRF52840" +#define MICROPY_PY_SYS_PLATFORM "ElectronutLabsPapyr" + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 + +// TODO #define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_P0_11) +#define DEFAULT_I2C_BUS_SDA (&pin_P0_12) + +#define DEFAULT_SPI_BUS_SCK (&pin_P0_25) +#define DEFAULT_SPI_BUS_MOSI (&pin_P1_02) +#define DEFAULT_SPI_BUS_MISO (&pin_P0_24) + +#define DEFAULT_UART_BUS_RX (&pin_P0_08) +#define DEFAULT_UART_BUS_TX (&pin_P0_06) diff --git a/ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk new file mode 100644 index 00000000000..9cddd96eebb --- /dev/null +++ b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk @@ -0,0 +1,30 @@ +USB_VID = 0x239A +USB_PID = 0x803C +USB_PRODUCT = "Blip" +USB_MANUFACTURER = "Electronut Labs" + +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +MCU_CHIP = nrf52840 +SD ?= s140 +SOFTDEV_VERSION ?= 6.1.0 + +BOOT_SETTING_ADDR = 0xFF000 + +ifeq ($(SD),) + LD_FILE = boards/nrf52840_1M_256k.ld +else + LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld + CIRCUITPY_BLEIO = 1 +endif + +NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 + +QSPI_FLASH_FILESYSTEM = 0 +INTERNAL_FLASH_FILESYSTEM = 1 +CIRCUITPY_AUDIOIO = 0 +CIRCUITPY_DISPLAYIO = 1 +CIRCUITPY_GAMEPAD = 1 +CIRCUITPY_STAGE = 1 + diff --git a/ports/nrf/boards/electronut_labs_blip/pins.c b/ports/nrf/boards/electronut_labs_blip/pins.c new file mode 100644 index 00000000000..a8f9af1cd74 --- /dev/null +++ b/ports/nrf/boards/electronut_labs_blip/pins.c @@ -0,0 +1,72 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, + + // odd row + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_P0_19) }, + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_P0_21) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_D29), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_D31), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_P1_01) }, + { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_P1_06) }, + + // even row + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_P0_16) }, + { MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_P0_20) }, + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_P0_22) }, + { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_P0_23) }, + { MP_ROM_QSTR(MP_QSTR_D28), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_D30), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_P1_00) }, + { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_P1_03) }, + { MP_ROM_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_P1_05) }, + { MP_ROM_QSTR(MP_QSTR_D40), MP_ROM_PTR(&pin_P1_08) }, + + // SCL SDA as pins also + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_12) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_P0_17) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_08) }, + + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P0_14) }, + + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_GREEN_LED), MP_ROM_PTR(&pin_P0_13) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_P1_07) }, + { MP_ROM_QSTR(MP_QSTR_RESET), MP_ROM_PTR(&pin_P0_18) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/electronut_labs_papyr/README.md b/ports/nrf/boards/electronut_labs_papyr/README.md new file mode 100644 index 00000000000..fda39019382 --- /dev/null +++ b/ports/nrf/boards/electronut_labs_papyr/README.md @@ -0,0 +1,58 @@ +# Setup + +The `Electronut Labs Papyr` board is based on the `nRF52840` SoC from +Nordic Semiconductors. It has an e-ink display on it, along with a CR2477 +battery holder. + +Papyr can be programmed with the [`Adafruit nRF52 bootloader`](https://github.com/adafruit/Adafruit_nRF52_Bootloader) to + +Schematic, datasheet default pin mapping etc. can be found over [here](https://docs.electronut.in/papyr/). The default pin mapping can be found in the board directory. + +## Installing CircuitPython submodules + +Before you can build, you will need to run the following commands once, which +will install the submodules that are part of the CircuitPython ecosystem, and +build the `mpy-cross` tool: + +``` +$ cd circuitpython +$ git submodule update --init +$ make -C mpy-cross +``` + +## Installing the Bootloader + +If the `Adafruit nRF52 bootloader` is installed on the board, then the +bootloader allows you to update the core CircuitPython firmware and internal +file system contents using serial, or USB CDC, or USB mass storage. + +On empty devices, the bootloader will need to be flashed once using a +HW debugger such as a Segger J-Link, or Blackmagicprobe +(or [Electronut labs Bumpy](https://docs.electronut.in/bumpy/)). + + +## Building and Flashing CircuitPython + +No special notes for this, follow `ports/nrf` generic `README.md`. + +### Flashing CircuitPython with MSC UF2 + +`uf2` file is generated last by `all` target. + +``` +$ cd ports/nrf +$ make V=1 SD=s140 SERIAL=/dev/ttyACM0 BOARD=electronut_labs_papyr all +... +... +python3 ../../tools/uf2/utils/uf2conv.py -f 0xADA52840 -c -o "build-electronut_labs_papyr-s140/firmware.uf2" build-electronut_labs_papyr-s140/firmware.hex +Converting to uf2, output size: 536576, start address: 0x26000 +Wrote 536576 bytes to build-electronut_labs_papyr-s140/firmware.uf2 +``` + +Simply drag and drop firmware.uf2 to the MSC, the nrf52840 will blink fast and reset after done. + +### Other tips + +Once circuitpython is running on your board, it will come up as a mass storage +device named `CIRCUITPY`, where you can drop in your python code. The file names +it looks for are `main.py`, `main.txt`, `code.py` or `code.txt`. diff --git a/ports/nrf/boards/electronut_labs_papyr/board.c b/ports/nrf/boards/electronut_labs_papyr/board.c new file mode 100644 index 00000000000..4421970eefe --- /dev/null +++ b/ports/nrf/boards/electronut_labs_papyr/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/electronut_labs_papyr/mpconfigboard.h b/ports/nrf/boards/electronut_labs_papyr/mpconfigboard.h new file mode 100644 index 00000000000..7f5021fdca4 --- /dev/null +++ b/ports/nrf/boards/electronut_labs_papyr/mpconfigboard.h @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "nrfx/hal/nrf_gpio.h" + +#define ELECTRONUT_LABS_PAPYR + +#define MICROPY_HW_BOARD_NAME "Electronut Labs Papyr" +#define MICROPY_HW_MCU_NAME "nRF52840" +#define MICROPY_PY_SYS_PLATFORM "ElectronutLabsPapyr" + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 + +// TODO #define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_P0_06) +#define DEFAULT_I2C_BUS_SDA (&pin_P0_05) + +#define DEFAULT_SPI_BUS_SCK (&pin_P0_31) +#define DEFAULT_SPI_BUS_MOSI (&pin_P0_29) +#define DEFAULT_SPI_BUS_MISO (&pin_P1_01) + +#define DEFAULT_UART_BUS_RX (&pin_P0_07) +#define DEFAULT_UART_BUS_TX (&pin_P0_08) diff --git a/ports/nrf/boards/electronut_labs_papyr/mpconfigboard.mk b/ports/nrf/boards/electronut_labs_papyr/mpconfigboard.mk new file mode 100644 index 00000000000..5aee244f11f --- /dev/null +++ b/ports/nrf/boards/electronut_labs_papyr/mpconfigboard.mk @@ -0,0 +1,22 @@ +USB_VID = 0x239A +USB_PID = 0x803C +USB_PRODUCT = "Papyr" +USB_MANUFACTURER = "Electronut Labs" + +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +MCU_CHIP = nrf52840 +SD ?= s140 +SOFTDEV_VERSION ?= 6.1.0 + +BOOT_SETTING_ADDR = 0xFF000 + +ifeq ($(SD),) + LD_FILE = boards/nrf52840_1M_256k.ld +else + LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld + CIRCUITPY_BLEIO = 1 +endif + +NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 \ No newline at end of file diff --git a/ports/nrf/boards/electronut_labs_papyr/pins.c b/ports/nrf/boards/electronut_labs_papyr/pins.c new file mode 100644 index 00000000000..ef0178e9b11 --- /dev/null +++ b/ports/nrf/boards/electronut_labs_papyr/pins.c @@ -0,0 +1,44 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_P0_06) }, + + { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_P0_15) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P1_01) }, + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_BUSY), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_DC), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_RES), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_EINK_EN), MP_ROM_PTR(&pin_P0_11) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_07) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_05) }, + + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P0_14) }, + + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_GREEN_LED), MP_ROM_PTR(&pin_P0_13) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/feather_nrf52840_express/README.md b/ports/nrf/boards/feather_nrf52840_express/README.md new file mode 100644 index 00000000000..8d515010f9c --- /dev/null +++ b/ports/nrf/boards/feather_nrf52840_express/README.md @@ -0,0 +1,201 @@ +# Setup + +The `feather52840` board is currently based on the `PCA10056` development +board from Nordic Semiconductors, since commercial modules are not yet +available for the nRF52840. + +The difference between the `pca10056` and `feather52840` board support +packages is that no bootloader is present on the `pca10056` (a HW debugger +like a Segger J-Link is required to flash firmware images), whereas the +`feather52840` package uses a serial bootloader, with a slightly different +flash layout to account for the bootloader's presence. + +Both targets run on the same hardware and assume the same pinouts. + +The `feather52840` board support package will be updated at a later date +to reflect any pin changes in the final Feather form-factor HW. + +## Installing CircuitPython submodules + +Before you can build, you will need to run the following commands once, which +will install the submodules that are part of the CircuitPython ecosystem, and +build the `mpy-cross` tool: + +``` +$ cd circuitpython +$ git submodule update --init +$ make -C mpy-cross +``` + +You then need to download the SD and Nordic SDK files via: + +> This script relies on `wget`, which must be available from the command line. + +``` +$ cd ports/nrf +$ ./bluetooth/download_ble_stack.sh +``` + +## Installing the Serial Bootloader + +The Adafruit nRF52840 Feather uses a serial bootloader that allows you to +update the core CircuitPython firmware and internal file system contents +using only a serial connection. + +On empty devices, the serial bootloader will need to be flashed once using a +HW debugger such as a Segger J-Link before the serial updater (`adafruit-nrfutil`) can +be used. + +### Install `nrfjprog` + +Before you can install the bootloader, you will first need to install the +`nrfjprog` tool from Nordic Semiconductors for your operating system. The +binary files can be downloaded via the following links: + +- [nRF5x toolset tar for Linux 32-bit v9.7.2](http://www.nordicsemi.com/eng/nordic/Products/nRF52832/nRF5x-Command-Line-Tools-Linux32/52619) +- [nRF5x toolset tar for Linux 64-bit v9.7.2](http://www.nordicsemi.com/eng/nordic/Products/nRF52832/nRF5x-Command-Line-Tools-Linux64/51388) +- [nRF5x toolset tar for OSX v9.7.2](http://www.nordicsemi.com/eng/nordic/Products/nRF52832/nRF5x-Command-Line-Tools-OSX/53406) +- [nRF5x toolset installer for Windows v9.7.2](http://www.nordicsemi.com/eng/nordic/Products/nRF52832/nRF5x-Command-Line-Tools-Win32/48768) + +You will then need to add the `nrfjprog` folder to your system `PATH` variable +so that it is available from the command line. The exact process for this is +OS specific, but on a POSIX type system like OS X or Linux, you can +temporarily add the location to your `PATH` environment variables as follows: + +``` +$ export PATH=$PATH:YOURPATHHERE/nRF5x-Command-Line-Tools_9_7_2_OSX/nrfjprog/ +``` + +You can test this by running the following command: + +``` +$ nrfjprog --version +nrfjprog version: 9.7.2 +JLinkARM.dll version: 6.20f +``` + +### Flash the USB CDC Bootloader with 'nrfjprog' + +> This operation only needs to be done once, and only on boards that don't + already have the serial bootloader installed. + +Firstly clone the [Adafruit_nRF52_Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader.git) and enter its directory + +``` +$ git clone https://github.com/adafruit/Adafruit_nRF52_Bootloader.git +$ cd Adafruit_nRF52_Bootloader +``` + +Once `nrfjprog` is installed and available in `PATH` you can flash your +board with the serial bootloader via the following command: + +``` +make BOARD=feather_nrf52840_express VERSION=latest flash +``` + +This should give you the following (or very similar) output, and you will see +a DFU blinky pattern on one of the board LEDs: + +``` +$ make BOARD=pca10056 VERSION=latest flash +Flashing: bin/pca10056/6.0.0r0/pca10056_bootloader_s140_6.0.0r0.hex +nrfjprog --program bin/pca10056/6.0.0r0/pca10056_bootloader_s140_6.0.0r0.hex --chiperase -f nrf52 --reset +Parsing hex file. +Erasing user available code and UICR flash areas. +Applying system reset. +Checking that the area to write is not protected. +Programing device. +Applying system reset. +Run. +``` + +From this point onward, you can now use a simple serial port for firmware +updates. + +Note: You can specify other version that are available in the directory `Adafruit_nRF52_Bootloader/bin/feather_nrf52840_express/` . The `VERSION=latest` will use the latest bootloader available. + +### IMPORTANT: Disable Mass Storage on PCA10056 J-Link + +The J-Link firmware on the PCA10056 implement USB Mass Storage, but this +causes a known conflict with reliable USB CDC serial port communication. In +order to use the serial bootloader, **you must disable MSD support on the +Segger J-Link**! + +To disable mass storage support, run the `JLinkExe` (or equivalent) command, +and send `MSDDisable`. (You can re-enable MSD support via `MSDEnable`): + +``` +$ JLinkExe +SEGGER J-Link Commander V6.20f (Compiled Oct 13 2017 17:20:01) +DLL version V6.20f, compiled Oct 13 2017 17:19:52 + +Connecting to J-Link via USB...O.K. +Firmware: J-Link OB-SAM3U128-V2-NordicSemi compiled Jul 24 2017 17:30:12 +Hardware version: V1.00 +S/N: 683947110 +VTref = 3.300V + + +Type "connect" to establish a target connection, '?' for help +J-Link>MSDDisable +Probe configured successfully. +J-Link>exit +``` + +## Building and Flashing CircuitPython + +### Installing `adafruit-nrfutil` + +run follow command to install [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil) from PyPi + +``` +$ pip3 install adafruit-nrfutil --user +``` + +### Flashing CircuitPython with USB CDC + +With the serial bootloader present on your board, you first need to force your +board into DFU mode by holding down BUTTON1 and RESETTING the board (with +BUTTON1 still pressed as you come out of reset). + +This will give you a **fast blinky DFU pattern** to indicate you are in DFU +mode. + +You can **build and flash** a CircuitPython binary via the following command: + +``` +$ make V=1 SD=s140 SERIAL=/dev/tty.usbmodem1411 BOARD=feather52840 all dfu-gen dfu-flash +``` + +This should give you the following results: + +``` +$make V=1 BOARD=feather52840 SD=s140 SERIAL=/dev/tty.usbmodem1411 dfu-gen dfu-flash +nrfutil dfu genpkg --sd-req 0xFFFE --dev-type 0x0052 --application build-feather52840-s140/firmware.hex build-feather52840-s140/dfu-package.zip +Zip created at build-feather52840-s140/dfu-package.zip +nrfutil --verbose dfu serial --package build-feather52840-s140/dfu-package.zip -p /dev/ttyACM1 -b 115200 --singlebank +Upgrading target on /dev/ttyACM1 with DFU package /home/hathach/Dropbox/adafruit/circuitpython/ada_cp/ports/nrf/build-feather52840-s140/dfu-package.zip. Flow control is disabled, Single bank mode +Starting DFU upgrade of type 4, SoftDevice size: 0, bootloader size: 0, application size: 199840 +Sending DFU start packet +Sending DFU init packet +Sending firmware file +######################################################################################################################################################################################################################################################################################################################################################################################################### +Activating new firmware + +DFU upgrade took 8.50606513023s +Device programmed. +``` + +### Flashing CircuitPython with MSC UF2 + +uf2 file is generated last by `all` target + +``` +$ make V=1 SD=s140 SERIAL=/dev/tty.usbmodem1411 BOARD=feather52840 all +Create firmware.uf2 +../../tools/uf2/utils/uf2conv.py -f 0xADA52840 -c -o "build-feather52840-s140/firmware.uf2" "build-feather52840-s140/firmware.hex" +Converting to uf2, output size: 392192, start address: 0x26000 +Wrote 392192 bytes to build-feather52840-s140/firmware.uf2. +``` + +Simply drag and drop firmware.uf2 to the MSC, the nrf52840 will blink fast and reset after done. diff --git a/ports/nrf/boards/feather_nrf52840_express/board.c b/ports/nrf/boards/feather_nrf52840_express/board.c new file mode 100644 index 00000000000..4421970eefe --- /dev/null +++ b/ports/nrf/boards/feather_nrf52840_express/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h new file mode 100644 index 00000000000..70ccffc3f31 --- /dev/null +++ b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h @@ -0,0 +1,73 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "nrfx/hal/nrf_gpio.h" + +#define MICROPY_HW_BOARD_NAME "Adafruit Feather nRF52840 Express" +#define MICROPY_HW_MCU_NAME "nRF52840" +#define MICROPY_PY_SYS_PLATFORM "Feather52840Express" + +#define FLASH_SIZE (0x100000) +#define FLASH_PAGE_SIZE (4096) + +#define MICROPY_HW_NEOPIXEL (&pin_P0_16) + +#define MICROPY_HW_LED_STATUS (&pin_P1_15) + +#if QSPI_FLASH_FILESYSTEM +#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 17) +#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 22) +#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 23) +#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 21) +#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19) +#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 20) +#endif + +#if SPI_FLASH_FILESYSTEM +#define SPI_FLASH_MOSI_PIN &pin_P0_17 +#define SPI_FLASH_MISO_PIN &pin_P0_22 +#define SPI_FLASH_SCK_PIN &pin_P0_19 +#define SPI_FLASH_CS_PIN &pin_P0_20 +#endif + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 + +#define CIRCUITPY_INTERNAL_NVM_SIZE (4096) + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_P0_11) +#define DEFAULT_I2C_BUS_SDA (&pin_P0_12) + +#define DEFAULT_SPI_BUS_SCK (&pin_P0_14) +#define DEFAULT_SPI_BUS_MOSI (&pin_P0_13) +#define DEFAULT_SPI_BUS_MISO (&pin_P0_15) + +#define DEFAULT_UART_BUS_RX (&pin_P0_24) +#define DEFAULT_UART_BUS_TX (&pin_P0_25) diff --git a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk new file mode 100644 index 00000000000..0fef54ef791 --- /dev/null +++ b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.mk @@ -0,0 +1,26 @@ +USB_VID = 0x239A +USB_PID = 0x802A +USB_PRODUCT = "Feather nRF52840 Express" +USB_MANUFACTURER = "Adafruit Industries LLC" + +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +MCU_CHIP = nrf52840 +SD ?= s140 +SOFTDEV_VERSION ?= 6.1.0 + +BOOT_SETTING_ADDR = 0xFF000 + +ifeq ($(SD),) + LD_FILE = boards/nrf52840_1M_256k.ld +else + LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld + CIRCUITPY_BLEIO = 1 +endif + +NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "GD25Q16C" diff --git a/ports/nrf/boards/feather_nrf52840_express/pins.c b/ports/nrf/boards/feather_nrf52840_express/pins.c new file mode 100644 index 00000000000..ec2689ab457 --- /dev/null +++ b/ports/nrf/boards/feather_nrf52840_express/pins.c @@ -0,0 +1,53 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_03) }, + + { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_P0_29) }, + + { MP_ROM_QSTR(MP_QSTR_SWITCH), MP_ROM_PTR(&pin_P1_02) }, + + { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_08) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P1_09) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_P0_16) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_15) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_24) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_12) }, + + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_15) }, + + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_10) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/README.md b/ports/nrf/boards/makerdiary_nrf52840_mdk/README.md new file mode 100644 index 00000000000..f1ba8151ac7 --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/README.md @@ -0,0 +1,102 @@ +# MakerDiary NRF52840 MDK + +Refer to https://github.com/makerdiary/nrf52840-mdk or +https://wiki.makerdiary.com/nrf52840-mdk/ for more details about the device. + +Notably, CircuitPython does not currently support QSPI external flash on NRF +devices, so neither does this port - the 64Mb flash device is not used for +anything. Also, don't confuse this with the 64MiB drive that shows up on your +computer - it's actually part of the MSC driver provided by the DAPLink +debugger, and is inaccessible at all from Python land (this drive is where you +can copy `firmware.hex` if you'd prefer to flash that way as opposed to with +`pyocd`. You'll still have access to 256KB of the onboard flash, however, for +storing your Python files, cat pictures, or whatever. + +It's also interesting to note that all three LEDs and the "user button" on this +device are wired through sinks, not sources, so flip your boolean expectations +when dealing with `digitalio.DigitalInOut` on this device - `my_led.value = +True` turns the LED off! Likewise, the user button will read `False` when +pressed. + +## Installing CircuitPython submodules + +Before you can build, you will need to run the following commands once, which +will install the submodules that are part of the CircuitPython ecosystem, and +build the `mpy-cross` tool: + +``` +$ cd circuitpython +$ git submodule update --init +$ make -C mpy-cross +``` + +You then need to download the SD and Nordic SDK files via: + +> This script relies on `wget`, which must be available from the command line. + +``` +$ cd ports/nrf +$ ./drivers/bluetooth/download_ble_stack.sh +``` + +## Note about bootloaders + +While most Adafruit devices come with (or can easily be flashed with) an +Adafruit-provided bootloader (supporting niceties like UF2 flashing), this +board comes with DAPLink which (apparently?) handles everything from debugging +to programming the device, as well as the boot sequence. What's particularly +awesome about this board is that there is no physical interaction with the board +required to flash new code (read: CircuitPython builds) - the device is _always_ +listening for new firmware uploads (via `pyocd-flashtool`), even if userspace +code is running. + +## Building and Flashing CircuitPython + +You'll need to have [pyocd](https://github.com/mbedmicro/pyOCD) installed as +appropriate for your system. + +```sh +make BOARD=makerdiary_nrf52840_mdk FLASHER=pyocd SD=s140 flash +``` + +This should give you the following (or very similar) output, and you will see +a DFU blinky pattern on one of the board LEDs: + +``` +$ make BOARD=makerdiary_nrf52840_mdk FLASHER=pyocd SD=s140 flash +Use make V=1, make V=2 or set BUILD_VERBOSE similarly in your environment to increase build verbosity. +pyocd-flashtool -t nrf52 build-makerdiary_nrf52840_mdk-s140/firmware.hex --sector_erase +INFO:root:DAP SWD MODE initialised +INFO:root:ROM table #0 @ 0xe00ff000 cidr=b105100d pidr=2002c4008 +INFO:root:[0] +WARNING:root:Invalid coresight component, cidr=0x0 +INFO:root:[1] +INFO:root:[2] +WARNING:root:Invalid coresight component, cidr=0x1010101 +INFO:root:[3] +WARNING:root:Invalid coresight component, cidr=0x0 +INFO:root:[4] +INFO:root:[5] +INFO:root:CPU core is Cortex-M4 +INFO:root:FPU present +INFO:root:6 hardware breakpoints, 4 literal comparators +INFO:root:4 hardware watchpoints +[====================] 100% +INFO:root:Programmed 237568 bytes (58 pages) at 14.28 kB/s +#pyocd-tool -t nrf52 erase 0xFF000 +pyocd-tool -t nrf52 write32 0xFF000 0x00000001 +WARNING:root:Invalid coresight component, cidr=0x0 +WARNING:root:Invalid coresight component, cidr=0x1010101 +WARNING:root:Invalid coresight component, cidr=0x0 +pyocd-tool -t nrf52 reset +WARNING:root:Invalid coresight component, cidr=0x0 +WARNING:root:Invalid coresight component, cidr=0x1010101 +WARNING:root:Invalid coresight component, cidr=0x0 +Resetting target +``` + +Alternatively (and untested by me), it's apparently possible to copy +`firmware.hex` to the MSC device provided by DAPLink and flash that way. Refer +to [the upstream +documentation](https://wiki.makerdiary.com/nrf52840-mdk/getting-started/#drag-n-drop-programming) +for details. diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c b/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c new file mode 100644 index 00000000000..4421970eefe --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h new file mode 100644 index 00000000000..ed48364942d --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.h @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "nrfx/hal/nrf_gpio.h" + +#define MAKERDIARYNRF52840MDK + +#define MICROPY_HW_BOARD_NAME "MakerDiary nRF52840 MDK" +#define MICROPY_HW_MCU_NAME "nRF52840" +#define MICROPY_PY_SYS_PLATFORM "MakerDiary52840MDK" + +#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(1, 5) +#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(1, 4) +#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(1, 2) +#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(1, 1) +#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(1, 3) +#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(1, 8) + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 + +// TODO #define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 0 + +#define DEFAULT_UART_BUS_RX (&pin_P0_19) +#define DEFAULT_UART_BUS_TX (&pin_P0_20) diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk new file mode 100644 index 00000000000..abb0f4946c4 --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk @@ -0,0 +1,26 @@ +USB_VID = 0x239A +USB_PID = 0x802A +USB_PRODUCT = "nRF52840-MDK" +USB_MANUFACTURER = "makerdiary" + +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +MCU_CHIP = nrf52840 +SD ?= s140 +SOFTDEV_VERSION ?= 6.1.0 + +BOOT_SETTING_ADDR = 0xFF000 + +ifeq ($(SD),) + LD_FILE = boards/nrf52840_1M_256k.ld +else + LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld + CIRCUITPY_BLEIO = 1 +endif + +NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "MX25R6435F" diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/pins.c b/ports/nrf/boards/makerdiary_nrf52840_mdk/pins.c new file mode 100644 index 00000000000..5284c248425 --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/pins.c @@ -0,0 +1,61 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_AIN0), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_AIN1), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_AIN2), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_AIN3), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_AIN4), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_AIN5), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_AIN6), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_AIN7), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_VDIV), MP_ROM_PTR(&pin_P0_05) }, + + { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, + + { MP_ROM_QSTR(MP_QSTR_P2), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_P3), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_P4), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_P5), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_P6), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_P7), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_P8), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_P9), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_P10), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_P11), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_P12), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_P13), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_P14), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_P15), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_P16), MP_ROM_PTR(&pin_P0_16) }, + { MP_ROM_QSTR(MP_QSTR_P17), MP_ROM_PTR(&pin_P0_17) }, + { MP_ROM_QSTR(MP_QSTR_P21), MP_ROM_PTR(&pin_P0_21) }, + { MP_ROM_QSTR(MP_QSTR_P25), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_P26), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_P27), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_P28), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_P29), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_P30), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_P31), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P1_03) }, + { MP_ROM_QSTR(MP_QSTR_CSN), MP_ROM_PTR(&pin_P1_06) }, + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_P1_05) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_P1_01) }, + + { MP_ROM_QSTR(MP_QSTR_TXD), MP_ROM_PTR(&pin_P0_20) }, + { MP_ROM_QSTR(MP_QSTR_RXD), MP_ROM_PTR(&pin_P0_19) }, + + { MP_ROM_QSTR(MP_QSTR_LED_RED), MP_ROM_PTR(&pin_P0_23) }, + { MP_ROM_QSTR(MP_QSTR_LED_GREEN), MP_ROM_PTR(&pin_P0_22) }, + { MP_ROM_QSTR(MP_QSTR_LED_BLUE), MP_ROM_PTR(&pin_P0_24) }, + + { MP_ROM_QSTR(MP_QSTR_USR_BTN), MP_ROM_PTR(&pin_P1_00) }, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/README.md b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/README.md new file mode 100644 index 00000000000..e3e50f905dc --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/README.md @@ -0,0 +1,96 @@ +# MakerDiary NRF52840 MDK USB Dongle + +Refer to [The makerdiary Github repo](https://github.com/makerdiary/nrf52840-mdk-usb-dongle) +or [The nrf52840-mdk-usb-dongle wiki](https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle/) +for more details about the device. + +This is pretty much just the nRF52840 with a useful number of pins exposed for +your pleasure along with one RGB LED and an onboard antenna in a USB stick form +factor with room for headers on the sides. + +Note that all three LEDs on this device are wired through sinks, not sources, +so flip your boolean expectations when dealing with `DigitalInOut` or `PWMOut` +on this device -- +`led.value = True` or `led.duty_cycle = 0xffff` turns the LED off! + +The onboard button is hard wired to the Reset pin so you cannot use it yourself. + +## Installing CircuitPython submodules + +Before you can build, you will need to run the following commands once, which +will install the submodules that are part of the CircuitPython ecosystem, and +build the `mpy-cross` tool: + +``` +$ cd circuitpython +$ git submodule update --init +$ make -C mpy-cross +``` + +## Note about bootloaders + +While most Adafruit devices come with (or can easily be flashed with) an +Adafruit-provided bootloader (supporting niceties like UF2 flashing), this +board comes with one that supports DFU via nrfutil. If you ever need to +restore the DFU bootloader via a SWD debugger, use +[the nRF52 open bootloader hex file](https://github.com/makerdiary/nrf52840-mdk-usb-dongle/tree/master/firmware/open_bootloader). + +## Building and Flashing CircuitPython + +``` +$ cd ports/nrf +``` + +### Build CircuitPython for the MDK USB Dongle + +``` +make BOARD=makerdiary_nrf52840_mdk_usb_dongle SD=s140 V=1 -j4 hex +``` + +This should produce a `build-makerdiary_nrf52840_mdk_usb_dongle-s140/firmware.hex` file. + +### Install nrfutil + +You'll need to have [nrfutil](https://pypi.org/project/nrfutil/) installed as +appropriate for your system. +As of 2019-01, _nrfutil still requires Python 2.7_... ugh! + +### Flash the nRF52 Radio Soft Device + +Build a DFU package from the softdevice hex file and flash it: + +```sh +nrfutil pkg generate --hw-version 52 --sd-req 0x00 --sd-id 0xAE --softdevice bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_softdevice.hex dfu_sd140-6.1.0.zip +nrfutil dfu usb-serial -pkg dfu_sd140-6.1.0.zip -p /dev/tty.usbmodemABRACADBRA # likely /dev/ttyACM0 on Linux +``` + +Note that the `--sd=id 0xAE` comes from the Nordic nRF52 manual for SoftDevice +6.1.0. When the SoftDevice is changed, read the Nordic manual to find the +correct value and use it on all of the `nrfutil pkg generate` commands. + +`/dev/tty.usbmodem*` is a macOS name. On Linux it'll likely be `/dev/ttyACM*`. On Windows probably a COM port. + +### Flash CircuitPython + +Build a DFU package from the hex application file and flash it: + +``` +nrfutil pkg generate --sd-req 0xAE --application build-makerdiary_nrf52840_mdk_usb_dongle-s140/firmware.hex --hw-version 52 --application-version 1 dfu_circuitpython.zip +nrfutil dfu usb-serial -pkg dfu_circuitpython.zip -p /dev/tty.usbmodemABRACADBRA +``` + +I'm not sure if `--application-version 1` is actually meaningful or required. + +After this, your device should be up and running CircuitPython. When it +resets, you'll see the CIRCUITPY USB filesystem and a new console usb modem +serial port show up. + +``` +Adafruit CircuitPython 4.0.0-alpha.5-139-g10ceb6716 on 2019-01-14; MakerDiary nRF52840 MDK USB Dongle with nRF52840 +>>> +``` + +### TODO items + +* Update the Makefile to do the above DFU .zip building and nrfutil flashing. +* Create a UF2 bootloader for this. It is already a USB stick form factor, it deserves to behave like one. diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/board.c b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/board.c new file mode 100644 index 00000000000..4421970eefe --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.h b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.h new file mode 100644 index 00000000000..d4096503d7d --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "nrfx/hal/nrf_gpio.h" + +#define MAKERDIARY_NRF52840_MDK_DONGLE + +#define MICROPY_HW_BOARD_NAME "MakerDiary nRF52840 MDK USB Dongle" +#define MICROPY_HW_MCU_NAME "nRF52840" +#define MICROPY_PY_SYS_PLATFORM "MakerDiary52840MDKDongle" + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 + +// TODO #define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 // according to the schematic we do diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.mk b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.mk new file mode 100644 index 00000000000..82bbc3bd8cf --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.mk @@ -0,0 +1,23 @@ +USB_VID = 0x239A +USB_PID = 0x802A +USB_PRODUCT = "nRF52840-MDK-Dongle" +USB_MANUFACTURER = "makerdiary" + +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +MCU_CHIP = nrf52840 +SD ?= s140 +SOFTDEV_VERSION ?= 6.1.0 + +BOOT_SETTING_ADDR = 0xFF000 +BOOT_FILE = boards/$(BOARD)/bootloader/$(SOFTDEV_VERSION)/$(BOARD)_bootloader_$(SOFTDEV_VERSION)_s140 + +ifeq ($(SD),) + LD_FILE = boards/nrf52840_1M_256k.ld +else + LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld + CIRCUITPY_BLEIO = 1 +endif + +NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/pins.c b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/pins.c new file mode 100644 index 00000000000..006b2476880 --- /dev/null +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/pins.c @@ -0,0 +1,39 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_AIN0), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_AIN1), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_AIN2), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_AIN3), MP_ROM_PTR(&pin_P0_05) }, + + { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_P0_04) }, // User must connect manually. + { MP_ROM_QSTR(MP_QSTR_VDIV), MP_ROM_PTR(&pin_P0_05) }, // User must connect manually. + +// Not defining the NFC names until CircuitPython supports NFC. +// { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, +// { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, + + { MP_ROM_QSTR(MP_QSTR_P2), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_P3), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_P4), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_P5), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_P6), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_P7), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_P8), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_P9), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_P10), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_P18), MP_ROM_PTR(&pin_P0_18) }, // !Reset button. + { MP_ROM_QSTR(MP_QSTR_P19), MP_ROM_PTR(&pin_P0_19) }, + { MP_ROM_QSTR(MP_QSTR_P22), MP_ROM_PTR(&pin_P0_22) }, // green led, low is on. + { MP_ROM_QSTR(MP_QSTR_P23), MP_ROM_PTR(&pin_P0_23) }, // red led, low is on. + { MP_ROM_QSTR(MP_QSTR_P24), MP_ROM_PTR(&pin_P0_24) }, // blue led, low is on. + + { MP_ROM_QSTR(MP_QSTR_LED_RED), MP_ROM_PTR(&pin_P0_23) }, // Low is on. + { MP_ROM_QSTR(MP_QSTR_LED_GREEN), MP_ROM_PTR(&pin_P0_22) }, // Low is on. + { MP_ROM_QSTR(MP_QSTR_LED_BLUE), MP_ROM_PTR(&pin_P0_24) }, // Low is on. + + // BUT this is the RESET pin so we can't really use it. + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_P0_18) }, // Low is pressed. +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/metro_nrf52840_express/board.c b/ports/nrf/boards/metro_nrf52840_express/board.c new file mode 100644 index 00000000000..4421970eefe --- /dev/null +++ b/ports/nrf/boards/metro_nrf52840_express/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.h b/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.h new file mode 100644 index 00000000000..520eef90d97 --- /dev/null +++ b/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.h @@ -0,0 +1,73 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "nrfx/hal/nrf_gpio.h" + +#define MICROPY_HW_BOARD_NAME "Adafruit Metro nRF52840 Express" +#define MICROPY_HW_MCU_NAME "nRF52840" +#define MICROPY_PY_SYS_PLATFORM "Metro52840Express" + +#define FLASH_SIZE (0x100000) +#define FLASH_PAGE_SIZE (4096) + +#define MICROPY_HW_NEOPIXEL (&pin_P0_13) + +#define MICROPY_HW_LED_STATUS (&pin_P1_13) + +#if QSPI_FLASH_FILESYSTEM +#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 17) +#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 23) +#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 22) +#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 21) +#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19) +#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 20) +#endif + +#if SPI_FLASH_FILESYSTEM +#define SPI_FLASH_MOSI_PIN &pin_P0_17 +#define SPI_FLASH_MISO_PIN &pin_P0_23 +#define SPI_FLASH_SCK_PIN &pin_P0_19 +#define SPI_FLASH_CS_PIN &pin_P0_20 +#endif + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 + +#define CIRCUITPY_INTERNAL_NVM_SIZE (4096) + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_P0_16) +#define DEFAULT_I2C_BUS_SDA (&pin_P0_15) + +#define DEFAULT_SPI_BUS_SCK (&pin_P0_07) +#define DEFAULT_SPI_BUS_MOSI (&pin_P1_08) +#define DEFAULT_SPI_BUS_MISO (&pin_P0_11) + +#define DEFAULT_UART_BUS_RX (&pin_P0_24) +#define DEFAULT_UART_BUS_TX (&pin_P0_25) diff --git a/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk b/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk new file mode 100644 index 00000000000..4c1c93c10af --- /dev/null +++ b/ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk @@ -0,0 +1,26 @@ +USB_VID = 0x239A +USB_PID = 0x8040 +USB_PRODUCT = "Metro nRF52840 Express" +USB_MANUFACTURER = "Adafruit Industries LLC" + +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +MCU_CHIP = nrf52840 +SD ?= s140 +SOFTDEV_VERSION ?= 6.1.0 + +BOOT_SETTING_ADDR = 0xFF000 + +ifeq ($(SD),) + LD_FILE = boards/nrf52840_1M_256k.ld +else + LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld + CIRCUITPY_BLEIO = 1 +endif + +NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "GD25Q16C" diff --git a/ports/nrf/boards/metro_nrf52840_express/pins.c b/ports/nrf/boards/metro_nrf52840_express/pins.c new file mode 100644 index 00000000000..452e31202be --- /dev/null +++ b/ports/nrf/boards/metro_nrf52840_express/pins.c @@ -0,0 +1,56 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_03) }, + + { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_SWITCH), MP_ROM_PTR(&pin_P1_02) }, + + { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, + + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_24) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_25) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_P1_11) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_12) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P1_14) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P1_09) }, + { MP_ROM_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_P0_14) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_16) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_P0_13) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P1_08) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_11) }, + + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P1_13) }, + + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_15) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/nrf52840_1M_256k.ld b/ports/nrf/boards/nrf52840_1M_256k.ld new file mode 100644 index 00000000000..eb8a18aef6c --- /dev/null +++ b/ports/nrf/boards/nrf52840_1M_256k.ld @@ -0,0 +1,28 @@ +/* + GNU linker script for NRF52840 blank w/ no SoftDevice +*/ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000 /* entire flash, 1 MiB */ + FLASH_ISR (rx) : ORIGIN = 0x00000000, LENGTH = 0x001000 /* sector 0, 4 KiB */ + FLASH_TEXT (rx) : ORIGIN = 0x00001000, LENGTH = 0x0E6000 /* 920 KiB */ + FLASH_FATFS (r) : ORIGIN = 0x000E7000, LENGTH = 0x019000 /* File system 100 KiB */ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x040000 /* 256 KiB */ +} + +/* produce a link error if there is not this amount of RAM for these sections */ +_minimum_stack_size = 40K; +_minimum_heap_size = 0; + +/* top end of the stack */ + +/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/ +_estack = ORIGIN(RAM) + LENGTH(RAM); + +/* RAM extents for the garbage collector */ +_ram_end = ORIGIN(RAM) + LENGTH(RAM); +_heap_end = 0x20020000; /* tunable */ + +INCLUDE "boards/common.ld" diff --git a/ports/nrf/boards/nrf52840_1M_256k_s140_6.0.0.ld b/ports/nrf/boards/nrf52840_1M_256k_s140_6.0.0.ld new file mode 100644 index 00000000000..90d6c402d0d --- /dev/null +++ b/ports/nrf/boards/nrf52840_1M_256k_s140_6.0.0.ld @@ -0,0 +1,28 @@ +/* + GNU linker script for NRF52840 w/ s140 6.0.0 SoftDevice +*/ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000 /* entire flash, 1 MiB */ + FLASH_ISR (rx) : ORIGIN = 0x00026000, LENGTH = 0x001000 /* sector 0, 4 KiB */ + FLASH_TEXT (rx) : ORIGIN = 0x00027000, LENGTH = 0x099000 /* 612 KiB */ + FLASH_FATFS (r) : ORIGIN = 0x000C0000, LENGTH = 0x040000 /* File system 256 KiB */ + RAM (xrw) : ORIGIN = 0x20004000, LENGTH = 0x03C000 /* 240 KiB */ +} + +/* produce a link error if there is not this amount of RAM for these sections */ +_minimum_stack_size = 40K; +_minimum_heap_size = 0; + +/* top end of the stack */ + +/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/ +_estack = ORIGIN(RAM) + LENGTH(RAM); + +/* RAM extents for the garbage collector */ +_ram_end = ORIGIN(RAM) + LENGTH(RAM); +_heap_end = 0x20020000; /* tunable */ + +INCLUDE "boards/common.ld" diff --git a/ports/nrf/boards/nrf52_prefix.c b/ports/nrf/boards/nrf52_prefix.c new file mode 100644 index 00000000000..0c96eb61ef5 --- /dev/null +++ b/ports/nrf/boards/nrf52_prefix.c @@ -0,0 +1,16 @@ +// nrf52_prefix.c becomes the initial portion of the generated pins file. + +#include + +#include "py/obj.h" +#include "py/mphal.h" +#include "nrf_pin.h" + +#define PIN(p_name, p_port, p_pin, p_adc_channel) \ +{ \ + { &mcu_pin_type }, \ + .name = MP_QSTR_ ## p_name, \ + .port = (p_port), \ + .pin = (p_pin), \ + .adc_channel = (p_adc_channel), \ +} diff --git a/ports/nrf/boards/particle_argon/board.c b/ports/nrf/boards/particle_argon/board.c new file mode 100644 index 00000000000..f891f54a13d --- /dev/null +++ b/ports/nrf/boards/particle_argon/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/particle_argon/mpconfigboard.h b/ports/nrf/boards/particle_argon/mpconfigboard.h new file mode 100644 index 00000000000..a4ecb2bb435 --- /dev/null +++ b/ports/nrf/boards/particle_argon/mpconfigboard.h @@ -0,0 +1,72 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "nrfx/hal/nrf_gpio.h" + +#define MICROPY_HW_BOARD_NAME "Particle Argon" +#define MICROPY_HW_MCU_NAME "nRF52840" +#define MICROPY_PY_SYS_PLATFORM "Particle Argon" + +#define MICROPY_HW_LED_STATUS (&pin_P1_12) + +#define MICROPY_HW_RGB_LED_RED (&pin_P0_13) +#define MICROPY_HW_RGB_LED_GREEN (&pin_P0_14) +#define MICROPY_HW_RGB_LED_BLUE (&pin_P0_15) + +#if QSPI_FLASH_FILESYSTEM +#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 20) +#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 21) +#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 22) +#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 23) +#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19) +#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 17) +#endif + +#if SPI_FLASH_FILESYSTEM +#define SPI_FLASH_MOSI_PIN &pin_P0_20 +#define SPI_FLASH_MISO_PIN &pin_P0_21 +#define SPI_FLASH_SCK_PIN &pin_P0_19 +#define SPI_FLASH_CS_PIN &pin_P0_17 +#endif + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 + +// TODO #define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_P0_27) +#define DEFAULT_I2C_BUS_SDA (&pin_P0_26) + +#define DEFAULT_SPI_BUS_SCK (&pin_P1_15) +#define DEFAULT_SPI_BUS_MOSI (&pin_P1_13) +#define DEFAULT_SPI_BUS_MISO (&pin_P1_14) + +#define DEFAULT_UART_BUS_RX (&pin_P0_08) +#define DEFAULT_UART_BUS_TX (&pin_P0_06) diff --git a/ports/nrf/boards/particle_argon/mpconfigboard.mk b/ports/nrf/boards/particle_argon/mpconfigboard.mk new file mode 100644 index 00000000000..8d3bb2a289b --- /dev/null +++ b/ports/nrf/boards/particle_argon/mpconfigboard.mk @@ -0,0 +1,26 @@ +USB_VID = 0x2b04 +USB_PID = 0xc00c +USB_PRODUCT = "Argon" +USB_MANUFACTURER = "Particle" + +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +MCU_CHIP = nrf52840 +SD ?= s140 +SOFTDEV_VERSION ?= 6.1.0 + +BOOT_SETTING_ADDR = 0xFF000 + +ifeq ($(SD),) + LD_FILE = boards/nrf52840_1M_256k.ld +else + LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld + CIRCUITPY_BLEIO = 1 +endif + +NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "MX25L3233F" diff --git a/ports/nrf/boards/particle_argon/pins.c b/ports/nrf/boards/particle_argon/pins.c new file mode 100644 index 00000000000..9fab9e6b6ad --- /dev/null +++ b/ports/nrf/boards/particle_argon/pins.c @@ -0,0 +1,70 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_MODE), MP_ROM_PTR(&pin_P0_11) }, + + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_P0_05) }, + + { MP_ROM_QSTR(MP_QSTR_CHARGE_STATUS), MP_ROM_PTR(&pin_P1_09) }, + + { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P1_01) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_P1_08) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P1_11) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P1_12) }, + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_12) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P1_03) }, + + { MP_ROM_QSTR(MP_QSTR_RGB_LED_RED), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_RGB_LED_GREEN), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_RGB_LED_BLUE), MP_ROM_PTR(&pin_P0_15) }, + + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P1_14) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P1_14) }, + + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_08) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_26) }, + + { MP_ROM_QSTR(MP_QSTR_ANTENNA_EXTERNAL), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_ANTENNA_PCB), MP_ROM_PTR(&pin_P0_02) }, + + + { MP_ROM_QSTR(MP_QSTR_ESP_TX), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_ESP_RX), MP_ROM_PTR(&pin_P1_05) }, + { MP_ROM_QSTR(MP_QSTR_ESP_CTS), MP_ROM_PTR(&pin_P1_07) }, + { MP_ROM_QSTR(MP_QSTR_ESP_RTS), MP_ROM_PTR(&pin_P1_06) }, + { MP_ROM_QSTR(MP_QSTR_ESP_BOOT_MODE), MP_ROM_PTR(&pin_P0_16) }, + { MP_ROM_QSTR(MP_QSTR_ESP_WIFI_EN), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_ESP_HOST_WK), MP_ROM_PTR(&pin_P0_07) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/particle_boron/board.c b/ports/nrf/boards/particle_boron/board.c new file mode 100644 index 00000000000..f891f54a13d --- /dev/null +++ b/ports/nrf/boards/particle_boron/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/particle_boron/mpconfigboard.h b/ports/nrf/boards/particle_boron/mpconfigboard.h new file mode 100644 index 00000000000..5e817311f9b --- /dev/null +++ b/ports/nrf/boards/particle_boron/mpconfigboard.h @@ -0,0 +1,72 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "nrfx/hal/nrf_gpio.h" + +#define MICROPY_HW_BOARD_NAME "Particle Boron" +#define MICROPY_HW_MCU_NAME "nRF52840" +#define MICROPY_PY_SYS_PLATFORM "Particle Boron" + +#define MICROPY_HW_LED_STATUS (&pin_P1_12) + +#define MICROPY_HW_RGB_LED_RED (&pin_P0_13) +#define MICROPY_HW_RGB_LED_GREEN (&pin_P0_14) +#define MICROPY_HW_RGB_LED_BLUE (&pin_P0_15) + +#if QSPI_FLASH_FILESYSTEM +#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 20) +#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 21) +#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 22) +#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 23) +#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19) +#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 17) +#endif + +#if SPI_FLASH_FILESYSTEM +#define SPI_FLASH_MOSI_PIN &pin_P0_20 +#define SPI_FLASH_MISO_PIN &pin_P0_21 +#define SPI_FLASH_SCK_PIN &pin_P0_19 +#define SPI_FLASH_CS_PIN &pin_P0_17 +#endif + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 + +// TODO #define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_P0_27) +#define DEFAULT_I2C_BUS_SDA (&pin_P0_26) + +#define DEFAULT_SPI_BUS_SCK (&pin_P1_15) +#define DEFAULT_SPI_BUS_MOSI (&pin_P1_13) +#define DEFAULT_SPI_BUS_MISO (&pin_P1_14) + +#define DEFAULT_UART_BUS_RX (&pin_P0_08) +#define DEFAULT_UART_BUS_TX (&pin_P0_06) diff --git a/ports/nrf/boards/particle_boron/mpconfigboard.mk b/ports/nrf/boards/particle_boron/mpconfigboard.mk new file mode 100644 index 00000000000..801b9613f7c --- /dev/null +++ b/ports/nrf/boards/particle_boron/mpconfigboard.mk @@ -0,0 +1,26 @@ +USB_VID = 0x2b04 +USB_PID = 0xc00d +USB_PRODUCT = "Boron" +USB_MANUFACTURER = "Particle" + +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +MCU_CHIP = nrf52840 +SD ?= s140 +SOFTDEV_VERSION ?= 6.1.0 + +BOOT_SETTING_ADDR = 0xFF000 + +ifeq ($(SD),) + LD_FILE = boards/nrf52840_1M_256k.ld +else + LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld + CIRCUITPY_BLEIO = 1 +endif + +NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "MX25L3233F" diff --git a/ports/nrf/boards/particle_boron/pins.c b/ports/nrf/boards/particle_boron/pins.c new file mode 100644 index 00000000000..4d6f3e7de22 --- /dev/null +++ b/ports/nrf/boards/particle_boron/pins.c @@ -0,0 +1,70 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_MODE), MP_ROM_PTR(&pin_P0_11) }, + + { MP_ROM_QSTR(MP_QSTR_POWER_I2C_SDA), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_POWER_I2C_SCL), MP_ROM_PTR(&pin_P1_09) }, + { MP_ROM_QSTR(MP_QSTR_POWER_INTERRUPT), MP_ROM_PTR(&pin_P0_05) }, + + { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P1_01) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_P1_08) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P1_11) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P1_12) }, + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_12) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P1_03) }, + + { MP_ROM_QSTR(MP_QSTR_RGB_LED_RED), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_RGB_LED_GREEN), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_RGB_LED_BLUE), MP_ROM_PTR(&pin_P0_15) }, + + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P1_14) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P1_14) }, + + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_08) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_26) }, + + { MP_ROM_QSTR(MP_QSTR_ANTENNA_SWITCH), MP_ROM_PTR(&pin_P0_07) }, + + { MP_ROM_QSTR(MP_QSTR_UBLOX_TX), MP_ROM_PTR(&pin_P1_05) }, + { MP_ROM_QSTR(MP_QSTR_UBLOX_RX), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_UBLOX_CTS), MP_ROM_PTR(&pin_P1_06) }, + { MP_ROM_QSTR(MP_QSTR_UBLOX_RTS), MP_ROM_PTR(&pin_P1_07) }, + { MP_ROM_QSTR(MP_QSTR_UBLOX_POWER_ENABLE), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_UBLOX_POWER_MONITOR), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_UBLOX_RESET), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_UBLOX_POWER_ON), MP_ROM_PTR(&pin_P0_16) }, + + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + + +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/particle_xenon/board.c b/ports/nrf/boards/particle_xenon/board.c new file mode 100644 index 00000000000..f891f54a13d --- /dev/null +++ b/ports/nrf/boards/particle_xenon/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/particle_xenon/mpconfigboard.h b/ports/nrf/boards/particle_xenon/mpconfigboard.h new file mode 100644 index 00000000000..6c8cc7cef2d --- /dev/null +++ b/ports/nrf/boards/particle_xenon/mpconfigboard.h @@ -0,0 +1,72 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "nrfx/hal/nrf_gpio.h" + +#define MICROPY_HW_BOARD_NAME "Particle Xenon" +#define MICROPY_HW_MCU_NAME "nRF52840" +#define MICROPY_PY_SYS_PLATFORM "Particle Xenon" + +#define MICROPY_HW_LED_STATUS (&pin_P1_12) + +#define CP_RGB_STATUS_R (&pin_P0_13) +#define CP_RGB_STATUS_G (&pin_P0_14) +#define CP_RGB_STATUS_B (&pin_P0_15) + +#if QSPI_FLASH_FILESYSTEM +#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 20) +#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 21) +#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 22) +#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 23) +#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19) +#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 17) +#endif + +#if SPI_FLASH_FILESYSTEM +#define SPI_FLASH_MOSI_PIN &pin_P0_20 +#define SPI_FLASH_MISO_PIN &pin_P0_21 +#define SPI_FLASH_SCK_PIN &pin_P0_19 +#define SPI_FLASH_CS_PIN &pin_P0_17 +#endif + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 + +// TODO #define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_P0_27) +#define DEFAULT_I2C_BUS_SDA (&pin_P0_26) + +#define DEFAULT_SPI_BUS_SCK (&pin_P1_15) +#define DEFAULT_SPI_BUS_MOSI (&pin_P1_13) +#define DEFAULT_SPI_BUS_MISO (&pin_P1_14) + +#define DEFAULT_UART_BUS_RX (&pin_P0_08) +#define DEFAULT_UART_BUS_TX (&pin_P0_06) diff --git a/ports/nrf/boards/particle_xenon/mpconfigboard.mk b/ports/nrf/boards/particle_xenon/mpconfigboard.mk new file mode 100644 index 00000000000..5cebc423a0d --- /dev/null +++ b/ports/nrf/boards/particle_xenon/mpconfigboard.mk @@ -0,0 +1,26 @@ +USB_VID = 0x2b04 +USB_PID = 0xc00e # argon is 0xc00c +USB_PRODUCT = "Xenon" +USB_MANUFACTURER = "Particle" + +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +MCU_CHIP = nrf52840 +SD ?= s140 +SOFTDEV_VERSION ?= 6.1.0 + +BOOT_SETTING_ADDR = 0xFF000 + +ifeq ($(SD),) + LD_FILE = boards/nrf52840_1M_256k.ld +else + LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld + CIRCUITPY_BLEIO = 1 +endif + +NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "MX25L3233F" diff --git a/ports/nrf/boards/particle_xenon/pins.c b/ports/nrf/boards/particle_xenon/pins.c new file mode 100644 index 00000000000..a50c8b6418d --- /dev/null +++ b/ports/nrf/boards/particle_xenon/pins.c @@ -0,0 +1,63 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_MODE), MP_ROM_PTR(&pin_P0_11) }, + + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_P0_05) }, + + { MP_ROM_QSTR(MP_QSTR_CHARGE_STATUS), MP_ROM_PTR(&pin_P1_09) }, + + { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P1_01) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_P1_08) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P1_11) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P1_12) }, + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_12) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P1_03) }, + + { MP_ROM_QSTR(MP_QSTR_RGB_LED_RED), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_RGB_LED_GREEN), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_RGB_LED_BLUE), MP_ROM_PTR(&pin_P0_15) }, + + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P1_14) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P1_14) }, + + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_08) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_26) }, + + { MP_ROM_QSTR(MP_QSTR_ANTENNA_EXTERNAL), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_ANTENNA_PCB), MP_ROM_PTR(&pin_P0_24) }, + + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + + +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/pca10056/board.c b/ports/nrf/boards/pca10056/board.c new file mode 100644 index 00000000000..4421970eefe --- /dev/null +++ b/ports/nrf/boards/pca10056/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/pca10056/examples/buttons.py b/ports/nrf/boards/pca10056/examples/buttons.py new file mode 100644 index 00000000000..1a0c5aabbca --- /dev/null +++ b/ports/nrf/boards/pca10056/examples/buttons.py @@ -0,0 +1,26 @@ +import board +import digitalio +import gamepad +import time + +pad = gamepad.GamePad( + digitalio.DigitalInOut(board.P0_11), + digitalio.DigitalInOut(board.P0_12), + digitalio.DigitalInOut(board.P0_24), + digitalio.DigitalInOut(board.P0_25), +) + +prev_buttons = 0 + +while True: + buttons = pad.get_pressed() + + if buttons != prev_buttons: + for i in range(0, 4): + bit = (1 << i) + if (buttons & bit) != (prev_buttons & bit): + print('Button %d %s' % (i + 1, 'pressed' if buttons & bit else 'released')) + + prev_buttons = buttons + + time.sleep(0.1) diff --git a/ports/nrf/boards/pca10056/mpconfigboard.h b/ports/nrf/boards/pca10056/mpconfigboard.h new file mode 100644 index 00000000000..48ef7f1c390 --- /dev/null +++ b/ports/nrf/boards/pca10056/mpconfigboard.h @@ -0,0 +1,66 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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 "nrfx/hal/nrf_gpio.h" + +#define MICROPY_HW_BOARD_NAME "PCA10056 nRF52840-DK" +#define MICROPY_HW_MCU_NAME "nRF52840" +#define MICROPY_PY_SYS_PLATFORM "nRF52840-DK" + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 + +#define MICROPY_HW_LED_STATUS (&pin_P0_13) + +#define DEFAULT_I2C_BUS_SCL (&pin_P0_27) +#define DEFAULT_I2C_BUS_SDA (&pin_P0_26) + +#define DEFAULT_SPI_BUS_SCK (&pin_P1_15) +#define DEFAULT_SPI_BUS_MOSI (&pin_P1_13) +#define DEFAULT_SPI_BUS_MISO (&pin_P1_14) + +#define DEFAULT_UART_BUS_RX (&pin_P1_01) +#define DEFAULT_UART_BUS_TX (&pin_P1_02) + +// Flash operation mode is determined by MICROPY_QSPI_DATAn pin configuration. +// A pin config is valid if it is defined and its value is not 0xFF. +// Quad mode: If all DATA0 --> DATA3 are valid +// Dual mode: If DATA0 and DATA1 are valid while either DATA2 and/or DATA3 are invalid +// Single mode: If only DATA0 is valid +#if QSPI_FLASH_FILESYSTEM +#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 20) +#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 21) +#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 22) +#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 23) +#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19) +#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 17) +#endif + +#if SPI_FLASH_FILESYSTEM +#define SPI_FLASH_MOSI_PIN &pin_P0_20 +#define SPI_FLASH_MISO_PIN &pin_P0_21 +#define SPI_FLASH_SCK_PIN &pin_P0_19 +#define SPI_FLASH_CS_PIN &pin_P0_17 +#endif diff --git a/ports/nrf/boards/pca10056/mpconfigboard.mk b/ports/nrf/boards/pca10056/mpconfigboard.mk new file mode 100644 index 00000000000..723e7976e1a --- /dev/null +++ b/ports/nrf/boards/pca10056/mpconfigboard.mk @@ -0,0 +1,26 @@ +USB_VID = 0x239A +USB_PID = 0x802A +USB_PRODUCT = "PCA10056" +USB_MANUFACTURER = "Nordic Semiconductor" + +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +MCU_CHIP = nrf52840 +SD ?= s140 +SOFTDEV_VERSION ?= 6.1.0 + +BOOT_SETTING_ADDR = 0xFF000 + +ifeq ($(SD),) + LD_FILE = boards/nrf52840_1M_256k.ld +else + LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld + CIRCUITPY_BLEIO = 1 +endif + +NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = "MX25R6435F" diff --git a/ports/nrf/boards/pca10056/pins.c b/ports/nrf/boards/pca10056/pins.c new file mode 100644 index 00000000000..e00bc8a11e6 --- /dev/null +++ b/ports/nrf/boards/pca10056/pins.c @@ -0,0 +1,129 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_P0_00), MP_ROM_PTR(&pin_P0_00) }, + { MP_ROM_QSTR(MP_QSTR_P0_01), MP_ROM_PTR(&pin_P0_01) }, + { MP_ROM_QSTR(MP_QSTR_P0_02), MP_ROM_PTR(&pin_P0_02) }, + + { MP_ROM_QSTR(MP_QSTR_P0_03), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_03) }, + + { MP_ROM_QSTR(MP_QSTR_P0_04), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_04) }, + + { MP_ROM_QSTR(MP_QSTR_P0_05), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_P0_06), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_P0_07), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_P0_08), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_P0_09), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_P0_10), MP_ROM_PTR(&pin_P0_10) }, + + { MP_ROM_QSTR(MP_QSTR_P0_11), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON1), MP_ROM_PTR(&pin_P0_11) }, + + { MP_ROM_QSTR(MP_QSTR_P0_12), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON2), MP_ROM_PTR(&pin_P0_12) }, + + { MP_ROM_QSTR(MP_QSTR_P0_13), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_P0_13) }, + + { MP_ROM_QSTR(MP_QSTR_P0_14), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_P0_14) }, + + { MP_ROM_QSTR(MP_QSTR_P0_15), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_LED3), MP_ROM_PTR(&pin_P0_15) }, + + { MP_ROM_QSTR(MP_QSTR_P0_16), MP_ROM_PTR(&pin_P0_16) }, + { MP_ROM_QSTR(MP_QSTR_LED4), MP_ROM_PTR(&pin_P0_16) }, + + { MP_ROM_QSTR(MP_QSTR_P0_17), MP_ROM_PTR(&pin_P0_17) }, + + // RESET { MP_ROM_QSTR(MP_QSTR_P0_18), MP_ROM_PTR(&pin_P0_18) }, + + { MP_ROM_QSTR(MP_QSTR_P0_19), MP_ROM_PTR(&pin_P0_19) }, + { MP_ROM_QSTR(MP_QSTR_P0_20), MP_ROM_PTR(&pin_P0_20) }, + { MP_ROM_QSTR(MP_QSTR_P0_21), MP_ROM_PTR(&pin_P0_21) }, + { MP_ROM_QSTR(MP_QSTR_P0_22), MP_ROM_PTR(&pin_P0_22) }, + { MP_ROM_QSTR(MP_QSTR_P0_23), MP_ROM_PTR(&pin_P0_23) }, + + { MP_ROM_QSTR(MP_QSTR_P0_24), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON3), MP_ROM_PTR(&pin_P0_24) }, + + { MP_ROM_QSTR(MP_QSTR_P0_25), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON4), MP_ROM_PTR(&pin_P0_25) }, + + { MP_ROM_QSTR(MP_QSTR_P0_26), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_26) }, + + { MP_ROM_QSTR(MP_QSTR_P0_27), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_27) }, + + { MP_ROM_QSTR(MP_QSTR_P0_28), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_28) }, + + { MP_ROM_QSTR(MP_QSTR_P0_29), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_29) }, + + { MP_ROM_QSTR(MP_QSTR_P0_30), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_30) }, + + { MP_ROM_QSTR(MP_QSTR_P0_31), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_P1_00), MP_ROM_PTR(&pin_P1_00) }, + + { MP_ROM_QSTR(MP_QSTR_P1_01), MP_ROM_PTR(&pin_P1_01) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P1_01) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P1_01) }, + + { MP_ROM_QSTR(MP_QSTR_P1_02), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P1_02) }, + + { MP_ROM_QSTR(MP_QSTR_P1_03), MP_ROM_PTR(&pin_P1_03) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P1_03) }, + + { MP_ROM_QSTR(MP_QSTR_P1_04), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_04) }, + + { MP_ROM_QSTR(MP_QSTR_P1_05), MP_ROM_PTR(&pin_P1_05) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_P1_05) }, + + { MP_ROM_QSTR(MP_QSTR_P1_06), MP_ROM_PTR(&pin_P1_06) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_06) }, + + { MP_ROM_QSTR(MP_QSTR_P1_07), MP_ROM_PTR(&pin_P1_07) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P1_07) }, + + { MP_ROM_QSTR(MP_QSTR_P1_08), MP_ROM_PTR(&pin_P1_08) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P1_08) }, + + { MP_ROM_QSTR(MP_QSTR_P1_09), MP_ROM_PTR(&pin_P1_09) }, + + { MP_ROM_QSTR(MP_QSTR_P1_10), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P1_10) }, + + { MP_ROM_QSTR(MP_QSTR_P1_11), MP_ROM_PTR(&pin_P1_11) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P1_11) }, + + { MP_ROM_QSTR(MP_QSTR_P1_12), MP_ROM_PTR(&pin_P1_12) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P1_12) }, + + { MP_ROM_QSTR(MP_QSTR_P1_13), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P1_13) }, + + { MP_ROM_QSTR(MP_QSTR_P1_14), MP_ROM_PTR(&pin_P1_14) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P1_14) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P1_14) }, + + // Note that there is no LED on D13. + { MP_ROM_QSTR(MP_QSTR_P1_15), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P1_15) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/pca10059/board.c b/ports/nrf/boards/pca10059/board.c new file mode 100644 index 00000000000..4421970eefe --- /dev/null +++ b/ports/nrf/boards/pca10059/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/pca10059/bootloader/6.0.0/pca10056_bootloader_6.0.0_s140.zip b/ports/nrf/boards/pca10059/bootloader/6.0.0/pca10056_bootloader_6.0.0_s140.zip new file mode 100644 index 00000000000..691f4a1ab3c Binary files /dev/null and b/ports/nrf/boards/pca10059/bootloader/6.0.0/pca10056_bootloader_6.0.0_s140.zip differ diff --git a/ports/nrf/boards/pca10059/mpconfigboard.h b/ports/nrf/boards/pca10059/mpconfigboard.h new file mode 100644 index 00000000000..d5ce212292e --- /dev/null +++ b/ports/nrf/boards/pca10059/mpconfigboard.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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 MICROPY_HW_BOARD_NAME "PCA10059 nRF52840 Dongle" +#define MICROPY_HW_MCU_NAME "nRF52840" +#define MICROPY_PY_SYS_PLATFORM "nRF52840-DK" + +#define MICROPY_HW_LED_STATUS (&pin_P0_06) + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 diff --git a/ports/nrf/boards/pca10059/mpconfigboard.mk b/ports/nrf/boards/pca10059/mpconfigboard.mk new file mode 100644 index 00000000000..db9d8066856 --- /dev/null +++ b/ports/nrf/boards/pca10059/mpconfigboard.mk @@ -0,0 +1,23 @@ +USB_VID = 0x239A +USB_PID = 0x802A +USB_PRODUCT = "PCA10059" +USB_MANUFACTURER = "Nordic Semiconductor" + +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +MCU_CHIP = nrf52840 +SD ?= s140 +SOFTDEV_VERSION ?= 6.1.0 + +BOOT_SETTING_ADDR = 0xFF000 +BOOT_FILE = boards/$(BOARD)/bootloader/$(SOFTDEV_VERSION)/$(BOARD)_bootloader_$(SOFTDEV_VERSION)_s140 + +ifeq ($(SD),) + LD_FILE = boards/nrf52840_1M_256k.ld +else + LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld + CIRCUITPY_BLEIO = 1 +endif + +NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 diff --git a/ports/nrf/boards/pca10059/pins.c b/ports/nrf/boards/pca10059/pins.c new file mode 100644 index 00000000000..932b925d17f --- /dev/null +++ b/ports/nrf/boards/pca10059/pins.c @@ -0,0 +1,40 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_P0_02), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_P0_04), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_P0_05), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_P0_09), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_P0_10), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_P0_11), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_P0_13), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_P0_14), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_P0_15), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_P0_17), MP_ROM_PTR(&pin_P0_17) }, + { MP_ROM_QSTR(MP_QSTR_P0_20), MP_ROM_PTR(&pin_P0_20) }, + { MP_ROM_QSTR(MP_QSTR_P0_22), MP_ROM_PTR(&pin_P0_22) }, + { MP_ROM_QSTR(MP_QSTR_P0_24), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_P0_26), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_P0_29), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_P0_31), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_P1_00), MP_ROM_PTR(&pin_P1_00) }, + { MP_ROM_QSTR(MP_QSTR_P1_01), MP_ROM_PTR(&pin_P1_01) }, + { MP_ROM_QSTR(MP_QSTR_P1_02), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_P1_04), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_P1_07), MP_ROM_PTR(&pin_P1_07) }, + { MP_ROM_QSTR(MP_QSTR_P1_10), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_P1_11), MP_ROM_PTR(&pin_P1_11) }, + { MP_ROM_QSTR(MP_QSTR_P1_13), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_P1_15), MP_ROM_PTR(&pin_P1_15) }, + + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_P0_06) }, + + { MP_ROM_QSTR(MP_QSTR_LED2_R), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_LED2_G), MP_ROM_PTR(&pin_P1_09) }, + { MP_ROM_QSTR(MP_QSTR_LED2_B), MP_ROM_PTR(&pin_P0_12) }, + + { MP_ROM_QSTR(MP_QSTR_SW1), MP_ROM_PTR(&pin_P1_06) }, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/sparkfun_nrf52840_mini/README.md b/ports/nrf/boards/sparkfun_nrf52840_mini/README.md new file mode 100644 index 00000000000..f80f1c27ca6 --- /dev/null +++ b/ports/nrf/boards/sparkfun_nrf52840_mini/README.md @@ -0,0 +1,48 @@ +# SparkFun Pro nRF52840 Mini Breakout + +The [SparkFun Pro nRF52840 Mini](https://www.sparkfun.com/products/15025) small breakout board for Raytac's MDBT50Q-P1M module, which features an nRF52840. It breaks out as many pins as it can in an Arduino Pro Mini footprint. Also included on the board are a qwiic (I2C) connector, LiPo battery charger, and on/off switch. + +Note: the SparkFun Pro nRF52840 Mini Breakout does not include a QSPI external flash. Any Python code will need to be stored on the internal flash filesystem. + +## CircuitPython Pin Defs + +CircuitPython pin definitions try to follow those of the [Arduino Pro Mini](https://www.sparkfun.com/products/11113), which the footprint is based on. + +This can be somewhat confusing, especially around the analog pins. Here's a quick pin-map: + + + + + + + + + + + + + + + + + + + + + + +
Board pin labelDigital Pin ReferenceAdditional Pin CapabilitiesPin/Port Reference
17D1TXP0_17
15D0RXP0_15
8SDAP0_08
11SCLP0_11
19D3P0_19
20D4P0_20
21D5P0_21
22D6P0_22
23D7P0_23
9D8P0_09
10D9P0_10
2D10A0P0_02
3D11MOSI, A1P0_03
31D12MISO, A7P0_31
30D13SCK, A6P0_31
29A5P0_29
28A4P0_28
5A3P0_05
4A2P0_04
+ +If a pin isn't defined as D0, D1, etc., standard port/pin references should work -- e.g. `P0_17` is pin 17, `P0_02` is pin 2, etc. + +## Bootloader Notes + +The nRF52840 Mini ships with a slightly modified (i.e pin defs and USB defs) version of the Adafruit nRF52 bootloader, which supports UF2 and CDC bootloading. + +## Hardware Reference + +The nRF52840 Mini hardware layout is open source: + +* [Schematic](https://cdn.sparkfun.com/assets/learn_tutorials/8/2/0/nrf52840-breakout-mdbt50q-v10.pdf) +* [Eagle Files](https://cdn.sparkfun.com/assets/learn_tutorials/8/2/0/nrf52840-breakout-mdbt50q-v10.zip) +* [Hookup Guide](https://learn.sparkfun.com/tutorials/sparkfun-pro-nrf52840-mini-hookup-guide) \ No newline at end of file diff --git a/ports/nrf/boards/sparkfun_nrf52840_mini/board.c b/ports/nrf/boards/sparkfun_nrf52840_mini/board.c new file mode 100644 index 00000000000..4421970eefe --- /dev/null +++ b/ports/nrf/boards/sparkfun_nrf52840_mini/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.h b/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.h new file mode 100644 index 00000000000..a5ed69b2bd9 --- /dev/null +++ b/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.h @@ -0,0 +1,66 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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 "nrfx/hal/nrf_gpio.h" + +#define MICROPY_HW_BOARD_NAME "SparkFun Pro nRF52840 Mini" +#define MICROPY_HW_MCU_NAME "nRF52840" +#define MICROPY_PY_SYS_PLATFORM "SFE_NRF52840_Mini" + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 + +#define DEFAULT_I2C_BUS_SCL (&pin_P0_11) +#define DEFAULT_I2C_BUS_SDA (&pin_P0_08) + +#define DEFAULT_SPI_BUS_SCK (&pin_P0_30) +#define DEFAULT_SPI_BUS_MOSI (&pin_P0_03) +#define DEFAULT_SPI_BUS_MISO (&pin_P0_31) + +#define DEFAULT_UART_BUS_RX (&pin_P0_15) +#define DEFAULT_UART_BUS_TX (&pin_P0_17) + +/* Note: Flash chip is not provided on SparkFun nRF52840 Mini. + * Leaving this as a reminder for future/similar versions of the board. */ +// Flash operation mode is determined by MICROPY_QSPI_DATAn pin configuration. +// A pin config is valid if it is defined and its value is not 0xFF. +// Quad mode: If all DATA0 --> DATA3 are valid +// Dual mode: If DATA0 and DATA1 are valid while either DATA2 and/or DATA3 are invalid +// Single mode: If only DATA0 is valid +/*#if QSPI_FLASH_FILESYSTEM +#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 20) +#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 21) +#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 22) +#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 23) +#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19) +#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 17) +#endif + +#if SPI_FLASH_FILESYSTEM +#define SPI_FLASH_MOSI_PIN &pin_P0_20 +#define SPI_FLASH_MISO_PIN &pin_P0_21 +#define SPI_FLASH_SCK_PIN &pin_P0_19 +#define SPI_FLASH_CS_PIN &pin_P0_17 +#endif*/ diff --git a/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.mk b/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.mk new file mode 100644 index 00000000000..212a85d57ce --- /dev/null +++ b/ports/nrf/boards/sparkfun_nrf52840_mini/mpconfigboard.mk @@ -0,0 +1,24 @@ +USB_VID = 0x1B4F +USB_PID = 0x5289 +USB_PRODUCT = "SFE_nRF52840_Mini" +USB_MANUFACTURER = "SparkFun Electronics" + +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +MCU_CHIP = nrf52840 +SD ?= s140 +SOFTDEV_VERSION ?= 6.1.0 + +BOOT_SETTING_ADDR = 0xFF000 + +ifeq ($(SD),) + LD_FILE = boards/nrf52840_1M_256k.ld +else + LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld + CIRCUITPY_BLEIO = 1 +endif + +NRF_DEFINES += -DNRF52840_XXAA -DNRF52840 + +INTERNAL_FLASH_FILESYSTEM = 1 diff --git a/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c b/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c new file mode 100644 index 00000000000..e7b61db584e --- /dev/null +++ b/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c @@ -0,0 +1,53 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P1_15) }, // D1/TX + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_P0_17) }, // D0/RX + // D2 on qwiic gap + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P0_19) }, // D3 + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_P0_20) }, // D4 + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P0_21) }, // D5 + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_22) }, // D6 + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P0_23) }, // D7 + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P0_09) }, // D8 + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_10) }, // D9 + + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_02) }, // D10 + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_03) }, // D11 + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_31) }, // D12 + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P0_30) }, // D13 + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_P0_29) }, // D14 + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_P0_28) }, // D15 + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_P0_05) }, // D16 + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_P0_04) }, // D17 + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_02) }, // A0 + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_03) }, // A1 + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_04) }, // A2 + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_05) }, // A3 + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_28) }, // A4 + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_29) }, // A5 + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_P0_30) }, // A6 + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_P0_31) }, // A7 + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_08) }, // 8 - SDA + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, // 11 - SCL + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_31) }, // 31 - MISO + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_03) }, // 3 - MOSI + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_30) }, // 30 - SCK + + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_P0_07) }, // 7 - Blue LED + + { MP_ROM_QSTR(MP_QSTR_BUTTON1), MP_ROM_PTR(&pin_P0_13) }, // 13 - Button + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_15) }, // 15 - UART RX + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_17) }, // 17 - UART TX + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_QWIIC), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/common-hal/_bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c new file mode 100644 index 00000000000..a8e1f190594 --- /dev/null +++ b/ports/nrf/common-hal/_bleio/Adapter.c @@ -0,0 +1,204 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * 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 +#include + +#include "ble.h" +#include "ble_drv.h" +#include "nrfx_power.h" +#include "nrf_nvic.h" +#include "nrf_sdm.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "supervisor/usb.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/Address.h" + +#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) +#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) +#define BLE_SLAVE_LATENCY 0 +#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) + +STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) { + mp_raise_msg_varg(&mp_type_AssertionError, + translate("Soft device assert, id: 0x%08lX, pc: 0x%08lX"), id, pc); +} + +STATIC uint32_t ble_stack_enable(void) { + nrf_clock_lf_cfg_t clock_config = { +#if BOARD_HAS_32KHZ_XTAL + .source = NRF_CLOCK_LF_SRC_XTAL, + .rc_ctiv = 0, + .rc_temp_ctiv = 0, + .accuracy = NRF_CLOCK_LF_ACCURACY_20_PPM, +#else + .source = NRF_CLOCK_LF_SRC_RC, + .rc_ctiv = 16, + .rc_temp_ctiv = 2, + .accuracy = NRF_CLOCK_LF_ACCURACY_250_PPM, +#endif + }; + + uint32_t err_code = sd_softdevice_enable(&clock_config, softdevice_assert_handler); + if (err_code != NRF_SUCCESS) { + return err_code; + } + + err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn); + if (err_code != NRF_SUCCESS) { + return err_code; + } + + // Start with no event handlers, etc. + ble_drv_reset(); + + uint32_t app_ram_start; + app_ram_start = 0x20004000; + + ble_cfg_t ble_conf; + ble_conf.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_TAG_CUSTOM; + ble_conf.conn_cfg.params.gap_conn_cfg.conn_count = BLE_GAP_CONN_COUNT_DEFAULT; + ble_conf.conn_cfg.params.gap_conn_cfg.event_length = BLE_GAP_EVENT_LENGTH_DEFAULT; + err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_conf, app_ram_start); + if (err_code != NRF_SUCCESS) + return err_code; + + memset(&ble_conf, 0, sizeof(ble_conf)); + ble_conf.gap_cfg.role_count_cfg.periph_role_count = 1; + ble_conf.gap_cfg.role_count_cfg.central_role_count = 1; + err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_conf, app_ram_start); + if (err_code != NRF_SUCCESS) + return err_code; + + memset(&ble_conf, 0, sizeof(ble_conf)); + ble_conf.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_TAG_CUSTOM; + ble_conf.conn_cfg.params.gatts_conn_cfg.hvn_tx_queue_size = MAX_TX_IN_PROGRESS; + err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATTS, &ble_conf, app_ram_start); + if (err_code != NRF_SUCCESS) + return err_code; + + err_code = sd_ble_enable(&app_ram_start); + if (err_code != NRF_SUCCESS) + return err_code; + + ble_gap_conn_params_t gap_conn_params = { + .min_conn_interval = BLE_MIN_CONN_INTERVAL, + .max_conn_interval = BLE_MAX_CONN_INTERVAL, + .slave_latency = BLE_SLAVE_LATENCY, + .conn_sup_timeout = BLE_CONN_SUP_TIMEOUT, + }; + err_code = sd_ble_gap_ppcp_set(&gap_conn_params); + if (err_code != NRF_SUCCESS) { + return err_code; + } + + err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_UNKNOWN); + return err_code; +} + +void common_hal_bleio_adapter_set_enabled(bool enabled) { + const bool is_enabled = common_hal_bleio_adapter_get_enabled(); + + // Don't enable or disable twice + if ((is_enabled && enabled) || (!is_enabled && !enabled)) { + return; + } + + uint32_t err_code; + if (enabled) { + // The SD takes over the POWER module and will fail if the module is already in use. + // Occurs when USB is initialized previously + nrfx_power_uninit(); + + err_code = ble_stack_enable(); + + // Re-init USB hardware + init_usb_hardware(); + } else { + err_code = sd_softdevice_disable(); + + // Re-init USB hardware + init_usb_hardware(); + } + + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg(translate("Failed to change softdevice state")); + } +} + +bool common_hal_bleio_adapter_get_enabled(void) { + uint8_t is_enabled; + + const uint32_t err_code = sd_softdevice_is_enabled(&is_enabled); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg(translate("Failed to get softdevice state")); + } + + return is_enabled; +} + +void get_address(ble_gap_addr_t *address) { + uint32_t err_code; + + common_hal_bleio_adapter_set_enabled(true); + err_code = sd_ble_gap_addr_get(address); + + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg(translate("Failed to get local address")); + } +} + +bleio_address_obj_t *common_hal_bleio_adapter_get_address(void) { + common_hal_bleio_adapter_set_enabled(true); + + ble_gap_addr_t local_address; + get_address(&local_address); + + bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t); + address->base.type = &bleio_address_type; + + common_hal_bleio_address_construct(address, local_address.addr, local_address.addr_type); + return address; +} + +mp_obj_t common_hal_bleio_adapter_get_default_name(void) { + common_hal_bleio_adapter_set_enabled(true); + + ble_gap_addr_t local_address; + get_address(&local_address); + + char name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0, 0 }; + + name[sizeof(name) - 4] = nibble_to_hex_lower[local_address.addr[1] >> 4 & 0xf]; + name[sizeof(name) - 3] = nibble_to_hex_lower[local_address.addr[1] & 0xf]; + name[sizeof(name) - 2] = nibble_to_hex_lower[local_address.addr[0] >> 4 & 0xf]; + name[sizeof(name) - 1] = nibble_to_hex_lower[local_address.addr[0] & 0xf]; + + return mp_obj_new_str(name, sizeof(name)); +} diff --git a/ports/nrf/common-hal/_bleio/Adapter.h b/ports/nrf/common-hal/_bleio/Adapter.h new file mode 100644 index 00000000000..5dcc625406c --- /dev/null +++ b/ports/nrf/common-hal/_bleio/Adapter.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ADAPTER_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ADAPTER_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} super_adapter_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ADAPTER_H diff --git a/ports/nrf/common-hal/_bleio/Attribute.c b/ports/nrf/common-hal/_bleio/Attribute.c new file mode 100644 index 00000000000..c55914b10d6 --- /dev/null +++ b/ports/nrf/common-hal/_bleio/Attribute.c @@ -0,0 +1,60 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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 "shared-bindings/_bleio/Attribute.h" + +// Convert a _bleio security mode to a ble_gap_conn_sec_mode_t setting. +void bleio_attribute_gatts_set_security_mode(ble_gap_conn_sec_mode_t *perm, bleio_attribute_security_mode_t security_mode) { + switch (security_mode) { + case SECURITY_MODE_NO_ACCESS: + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(perm); + break; + + case SECURITY_MODE_OPEN: + BLE_GAP_CONN_SEC_MODE_SET_OPEN(perm); + break; + + case SECURITY_MODE_ENC_NO_MITM: + BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(perm); + break; + + case SECURITY_MODE_ENC_WITH_MITM: + BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(perm); + break; + + case SECURITY_MODE_LESC_ENC_WITH_MITM: + BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(perm); + break; + + case SECURITY_MODE_SIGNED_NO_MITM: + BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(perm); + break; + + case SECURITY_MODE_SIGNED_WITH_MITM: + BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(perm); + break; + } +} diff --git a/ports/nrf/common-hal/_bleio/Attribute.h b/ports/nrf/common-hal/_bleio/Attribute.h new file mode 100644 index 00000000000..8cc361046ed --- /dev/null +++ b/ports/nrf/common-hal/_bleio/Attribute.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ATTRIBUTE_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ATTRIBUTE_H + +#include "shared-module/_bleio/Attribute.h" + +extern void bleio_attribute_gatts_set_security_mode(ble_gap_conn_sec_mode_t *perm, bleio_attribute_security_mode_t security_mode); + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ATTRIBUTE_H diff --git a/ports/nrf/common-hal/_bleio/Central.c b/ports/nrf/common-hal/_bleio/Central.c new file mode 100644 index 00000000000..db67b763c61 --- /dev/null +++ b/ports/nrf/common-hal/_bleio/Central.c @@ -0,0 +1,145 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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 +#include + +#include "ble.h" +#include "ble_drv.h" +#include "ble_hci.h" +#include "nrf_soc.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/Central.h" + +STATIC void central_on_ble_evt(ble_evt_t *ble_evt, void *central_in) { + bleio_central_obj_t *central = (bleio_central_obj_t*)central_in; + + switch (ble_evt->header.evt_id) { + case BLE_GAP_EVT_CONNECTED: + central->conn_handle = ble_evt->evt.gap_evt.conn_handle; + central->waiting_to_connect = false; + break; + + case BLE_GAP_EVT_TIMEOUT: + // Handle will be invalid. + central->waiting_to_connect = false; + break; + + case BLE_GAP_EVT_DISCONNECTED: + central->conn_handle = BLE_CONN_HANDLE_INVALID; + break; + + case BLE_GAP_EVT_SEC_PARAMS_REQUEST: + sd_ble_gap_sec_params_reply(central->conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); + break; + + case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: { + ble_gap_evt_conn_param_update_request_t *request = + &ble_evt->evt.gap_evt.params.conn_param_update_request; + sd_ble_gap_conn_param_update(central->conn_handle, &request->conn_params); + break; + } + default: + // For debugging. + // mp_printf(&mp_plat_print, "Unhandled central event: 0x%04x\n", ble_evt->header.evt_id); + break; + } +} + +void common_hal_bleio_central_construct(bleio_central_obj_t *self) { + common_hal_bleio_adapter_set_enabled(true); + + self->remote_service_list = mp_obj_new_list(0, NULL); + self->conn_handle = BLE_CONN_HANDLE_INVALID; +} + +void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout) { + common_hal_bleio_adapter_set_enabled(true); + ble_drv_add_event_handler(central_on_ble_evt, self); + + ble_gap_addr_t addr; + + addr.addr_type = address->type; + mp_buffer_info_t address_buf_info; + mp_get_buffer_raise(address->bytes, &address_buf_info, MP_BUFFER_READ); + memcpy(addr.addr, (uint8_t *) address_buf_info.buf, NUM_BLEIO_ADDRESS_BYTES); + + ble_gap_scan_params_t scan_params = { + .interval = MSEC_TO_UNITS(100, UNIT_0_625_MS), + .window = MSEC_TO_UNITS(100, UNIT_0_625_MS), + .scan_phys = BLE_GAP_PHY_1MBPS, + // timeout of 0 means no timeout + .timeout = SEC_TO_UNITS(timeout, UNIT_10_MS), + }; + + ble_gap_conn_params_t conn_params = { + .conn_sup_timeout = MSEC_TO_UNITS(4000, UNIT_10_MS), + .min_conn_interval = MSEC_TO_UNITS(15, UNIT_1_25_MS), + .max_conn_interval = MSEC_TO_UNITS(300, UNIT_1_25_MS), + .slave_latency = 0, // number of conn events + }; + + self->waiting_to_connect = true; + + uint32_t err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_CUSTOM); + + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to start connecting, error 0x%04x"), err_code); + } + + while (self->waiting_to_connect) { + RUN_BACKGROUND_TASKS; + } + + if (self->conn_handle == BLE_CONN_HANDLE_INVALID) { + mp_raise_OSError_msg(translate("Failed to connect: timeout")); + } +} + +void common_hal_bleio_central_disconnect(bleio_central_obj_t *self) { + sd_ble_gap_disconnect(self->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); +} + +bool common_hal_bleio_central_get_connected(bleio_central_obj_t *self) { + return self->conn_handle != BLE_CONN_HANDLE_INVALID; +} + +mp_obj_tuple_t *common_hal_bleio_central_discover_remote_services(bleio_central_obj_t *self, mp_obj_t service_uuids_whitelist) { + common_hal_bleio_device_discover_remote_services(MP_OBJ_FROM_PTR(self), service_uuids_whitelist); + // Convert to a tuple and then clear the list so the callee will take ownership. + mp_obj_tuple_t *services_tuple = mp_obj_new_tuple(self->remote_service_list->len, + self->remote_service_list->items); + mp_obj_list_clear(self->remote_service_list); + return services_tuple; +} + +mp_obj_list_t *common_hal_bleio_central_get_remote_services(bleio_central_obj_t *self) { + return self->remote_service_list; +} diff --git a/ports/nrf/common-hal/_bleio/Central.h b/ports/nrf/common-hal/_bleio/Central.h new file mode 100644 index 00000000000..01f7faca74d --- /dev/null +++ b/ports/nrf/common-hal/_bleio/Central.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CENTRAL_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CENTRAL_H + +#include + +#include "py/objlist.h" +#include "shared-module/_bleio/Address.h" + +typedef struct { + mp_obj_base_t base; + volatile bool waiting_to_connect; + volatile uint16_t conn_handle; + // Services discovered after connecting to a remote peripheral. + mp_obj_list_t *remote_service_list; +} bleio_central_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CENTRAL_H diff --git a/ports/nrf/common-hal/_bleio/Characteristic.c b/ports/nrf/common-hal/_bleio/Characteristic.c new file mode 100644 index 00000000000..e8454d528cf --- /dev/null +++ b/ports/nrf/common-hal/_bleio/Characteristic.c @@ -0,0 +1,299 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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 "py/runtime.h" + +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/Service.h" + +static volatile bleio_characteristic_obj_t *m_read_characteristic; + +STATIC uint16_t characteristic_get_cccd(uint16_t cccd_handle, uint16_t conn_handle) { + uint16_t cccd; + ble_gatts_value_t value = { + .p_value = (uint8_t*) &cccd, + .len = 2, + }; + + const uint32_t err_code = sd_ble_gatts_value_get(conn_handle, cccd_handle, &value); + + if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING) { + // CCCD is not set, so say that neither Notify nor Indicate is enabled. + cccd = 0; + } else if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to read CCCD value, err 0x%04x"), err_code); + } + + return cccd; +} + +STATIC void characteristic_on_gattc_read_rsp_evt(ble_evt_t *ble_evt, void *param) { + switch (ble_evt->header.evt_id) { + + // More events may be handled later, so keep this as a switch. + + case BLE_GATTC_EVT_READ_RSP: { + ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp; + if (m_read_characteristic) { + m_read_characteristic->value = mp_obj_new_bytearray(response->len, response->data); + } + // Indicate to busy-wait loop that we've read the attribute value. + m_read_characteristic = NULL; + break; + } + + default: + // For debugging. + // mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id); + break; + } +} + +STATIC void characteristic_gatts_notify_indicate(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, uint16_t hvx_type) { + uint16_t hvx_len = bufinfo->len; + + ble_gatts_hvx_params_t hvx_params = { + .handle = handle, + .type = hvx_type, + .offset = 0, + .p_len = &hvx_len, + .p_data = bufinfo->buf, + }; + + while (1) { + const uint32_t err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params); + if (err_code == NRF_SUCCESS) { + break; + } + // TX buffer is full + // We could wait for an event indicating the write is complete, but just retrying is easier. + if (err_code == NRF_ERROR_RESOURCES) { + RUN_BACKGROUND_TASKS; + continue; + } + + // Some real error has occurred. + mp_raise_OSError_msg_varg(translate("Failed to notify or indicate attribute value, err 0x%04x"), err_code); + } +} + +STATIC void characteristic_gattc_read(bleio_characteristic_obj_t *characteristic) { + const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device); + common_hal_bleio_check_connected(conn_handle); + + // Set to NULL in event loop after event. + m_read_characteristic = characteristic; + + ble_drv_add_event_handler(characteristic_on_gattc_read_rsp_evt, characteristic); + + const uint32_t err_code = sd_ble_gattc_read(conn_handle, characteristic->handle, 0); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to read attribute value, err 0x%04x"), err_code); + } + + while (m_read_characteristic != NULL) { + RUN_BACKGROUND_TASKS; + } + + ble_drv_remove_event_handler(characteristic_on_gattc_read_rsp_evt, characteristic); +} + +void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo) { + self->service = service; + self->uuid = uuid; + self->handle = BLE_GATT_HANDLE_INVALID; + self->props = props; + self->read_perm = read_perm; + self->write_perm = write_perm; + self->descriptor_list = mp_obj_new_list(0, NULL); + + const mp_int_t max_length_max = fixed_length ? BLE_GATTS_FIX_ATTR_LEN_MAX : BLE_GATTS_VAR_ATTR_LEN_MAX; + if (max_length < 0 || max_length > max_length_max) { + mp_raise_ValueError_varg(translate("max_length must be 0-%d when fixed_length is %s"), + max_length_max, fixed_length ? "True" : "False"); + } + self->max_length = max_length; + self->fixed_length = fixed_length; + + common_hal_bleio_characteristic_set_value(self, initial_value_bufinfo); +} + +mp_obj_list_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self) { + return self->descriptor_list; +} + +bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_characteristic_obj_t *self) { + return self->service; +} + +mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self) { + // Do GATT operations only if this characteristic has been added to a registered service. + if (self->handle != BLE_GATT_HANDLE_INVALID) { + uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device); + if (common_hal_bleio_service_get_is_remote(self->service)) { + // self->value is set by evt handler. + characteristic_gattc_read(self); + } else { + self->value = common_hal_bleio_gatts_read(self->handle, conn_handle); + } + } + + return self->value; +} + +void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { + if (self->fixed_length && bufinfo->len != self->max_length) { + mp_raise_ValueError(translate("Value length != required fixed length")); + } + if (bufinfo->len > self->max_length) { + mp_raise_ValueError(translate("Value length > max_length")); + } + + self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len); + + // Do GATT operations only if this characteristic has been added to a registered service. + if (self->handle != BLE_GATT_HANDLE_INVALID) { + uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device); + + if (common_hal_bleio_service_get_is_remote(self->service)) { + // Last argument is true if write-no-reponse desired. + common_hal_bleio_gattc_write(self->handle, conn_handle, bufinfo, + (self->props & CHAR_PROP_WRITE_NO_RESPONSE)); + } else { + + bool sent = false; + uint16_t cccd = 0; + + const bool notify = self->props & CHAR_PROP_NOTIFY; + const bool indicate = self->props & CHAR_PROP_INDICATE; + if (notify | indicate) { + cccd = characteristic_get_cccd(self->cccd_handle, conn_handle); + } + + // It's possible that both notify and indicate are set. + if (notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) { + characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_NOTIFICATION); + sent = true; + } + if (indicate && (cccd & BLE_GATT_HVX_INDICATION)) { + characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_INDICATION); + sent = true; + } + + if (!sent) { + common_hal_bleio_gatts_write(self->handle, conn_handle, bufinfo); + } + } + } +} + +bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self) { + return self->uuid; +} + +bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties(bleio_characteristic_obj_t *self) { + return self->props; +} + +void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *self, bleio_descriptor_obj_t *descriptor) { + ble_uuid_t desc_uuid; + bleio_uuid_convert_to_nrf_ble_uuid(descriptor->uuid, &desc_uuid); + + ble_gatts_attr_md_t desc_attr_md = { + // Data passed is not in a permanent location and should be copied. + .vloc = BLE_GATTS_VLOC_STACK, + .vlen = !descriptor->fixed_length, + }; + + bleio_attribute_gatts_set_security_mode(&desc_attr_md.read_perm, descriptor->read_perm); + bleio_attribute_gatts_set_security_mode(&desc_attr_md.write_perm, descriptor->write_perm); + + mp_buffer_info_t desc_value_bufinfo; + mp_get_buffer_raise(descriptor->value, &desc_value_bufinfo, MP_BUFFER_READ); + + ble_gatts_attr_t desc_attr = { + .p_uuid = &desc_uuid, + .p_attr_md = &desc_attr_md, + .init_len = desc_value_bufinfo.len, + .p_value = desc_value_bufinfo.buf, + .init_offs = 0, + .max_len = descriptor->max_length, + }; + + uint32_t err_code = sd_ble_gatts_descriptor_add(self->handle, &desc_attr, &descriptor->handle); + + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to add descriptor, err 0x%04x"), err_code); + } + + mp_obj_list_append(self->descriptor_list, MP_OBJ_FROM_PTR(descriptor)); +} + +void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate) { + if (self->cccd_handle == BLE_GATT_HANDLE_INVALID) { + mp_raise_ValueError(translate("No CCCD for this Characteristic")); + } + + if (!common_hal_bleio_service_get_is_remote(self->service)) { + mp_raise_ValueError(translate("Can't set CCCD on local Characteristic")); + } + + const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device); + common_hal_bleio_check_connected(conn_handle); + + uint16_t cccd_value = + (notify ? BLE_GATT_HVX_NOTIFICATION : 0) | + (indicate ? BLE_GATT_HVX_INDICATION : 0); + + ble_gattc_write_params_t write_params = { + .write_op = BLE_GATT_OP_WRITE_REQ, + .handle = self->cccd_handle, + .p_value = (uint8_t *) &cccd_value, + .len = 2, + }; + + while (1) { + uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params); + if (err_code == NRF_SUCCESS) { + break; + } + + // Write with response will return NRF_ERROR_BUSY if the response has not been received. + // Write without reponse will return NRF_ERROR_RESOURCES if too many writes are pending. + if (err_code == NRF_ERROR_BUSY || err_code == NRF_ERROR_RESOURCES) { + // We could wait for an event indicating the write is complete, but just retrying is easier. + RUN_BACKGROUND_TASKS; + continue; + } + + // Some real error occurred. + mp_raise_OSError_msg_varg(translate("Failed to write CCCD, err 0x%04x"), err_code); + } + +} diff --git a/ports/nrf/common-hal/_bleio/Characteristic.h b/ports/nrf/common-hal/_bleio/Characteristic.h new file mode 100644 index 00000000000..3a7691d07f7 --- /dev/null +++ b/ports/nrf/common-hal/_bleio/Characteristic.h @@ -0,0 +1,54 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTIC_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTIC_H + +#include "shared-bindings/_bleio/Attribute.h" +#include "shared-module/_bleio/Characteristic.h" +#include "common-hal/_bleio/Service.h" +#include "common-hal/_bleio/UUID.h" + +typedef struct { + mp_obj_base_t base; + // Will be MP_OBJ_NULL before being assigned to a Service. + bleio_service_obj_t *service; + bleio_uuid_obj_t *uuid; + mp_obj_t value; + uint16_t max_length; + bool fixed_length; + uint16_t handle; + bleio_characteristic_properties_t props; + bleio_attribute_security_mode_t read_perm; + bleio_attribute_security_mode_t write_perm; + mp_obj_list_t *descriptor_list; + uint16_t user_desc_handle; + uint16_t cccd_handle; + uint16_t sccd_handle; +} bleio_characteristic_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTIC_H diff --git a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c new file mode 100644 index 00000000000..95794feec00 --- /dev/null +++ b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c @@ -0,0 +1,155 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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 +#include + +#include "ble_drv.h" +#include "ble_gatts.h" +#include "nrf_nvic.h" + +#include "lib/utils/interrupt_char.h" +#include "py/runtime.h" +#include "py/stream.h" + +#include "tick.h" + +#include "shared-bindings/_bleio/__init__.h" +#include "common-hal/_bleio/CharacteristicBuffer.h" + +STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *data, uint16_t len) { + // Push all the data onto the ring buffer. + uint8_t is_nested_critical_region; + sd_nvic_critical_region_enter(&is_nested_critical_region); + for (size_t i = 0; i < len; i++) { + ringbuf_put(&self->ringbuf, data[i]); + } + sd_nvic_critical_region_exit(is_nested_critical_region); +} + +STATIC void characteristic_buffer_on_ble_evt(ble_evt_t *ble_evt, void *param) { + bleio_characteristic_buffer_obj_t *self = (bleio_characteristic_buffer_obj_t *) param; + switch (ble_evt->header.evt_id) { + case BLE_GATTS_EVT_WRITE: { + // A client wrote to this server characteristic. + + ble_gatts_evt_write_t *evt_write = &ble_evt->evt.gatts_evt.params.write; + // Event handle must match the handle for my characteristic. + if (evt_write->handle == self->characteristic->handle) { + write_to_ringbuf(self, evt_write->data, evt_write->len); + } + break; + } + + case BLE_GATTC_EVT_HVX: { + // A remote service wrote to this characteristic. + + ble_gattc_evt_hvx_t* evt_hvx = &ble_evt->evt.gattc_evt.params.hvx; + // Must be a notification, and event handle must match the handle for my characteristic. + if (evt_hvx->type == BLE_GATT_HVX_NOTIFICATION && + evt_hvx->handle == self->characteristic->handle) { + write_to_ringbuf(self, evt_hvx->data, evt_hvx->len); + } + break; + } + } +} + +// Assumes that timeout and buffer_size have been validated before call. +void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffer_obj_t *self, + bleio_characteristic_obj_t *characteristic, + mp_float_t timeout, + size_t buffer_size) { + + self->characteristic = characteristic; + self->timeout_ms = timeout * 1000; + // This is a macro. + // true means long-lived, so it won't be moved. + ringbuf_alloc(&self->ringbuf, buffer_size, true); + + ble_drv_add_event_handler(characteristic_buffer_on_ble_evt, self); + +} + +int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode) { + uint64_t start_ticks = ticks_ms; + + // Wait for all bytes received or timeout + while ( (ringbuf_count(&self->ringbuf) < len) && (ticks_ms - start_ticks < self->timeout_ms) ) { + RUN_BACKGROUND_TASKS; + // Allow user to break out of a timeout with a KeyboardInterrupt. + if ( mp_hal_is_interrupted() ) { + return 0; + } + } + + // Copy received data. Lock out write interrupt handler while copying. + uint8_t is_nested_critical_region; + sd_nvic_critical_region_enter(&is_nested_critical_region); + + size_t rx_bytes = MIN(ringbuf_count(&self->ringbuf), len); + for ( size_t i = 0; i < rx_bytes; i++ ) { + data[i] = ringbuf_get(&self->ringbuf); + } + + // Writes now OK. + sd_nvic_critical_region_exit(is_nested_critical_region); + + return rx_bytes; +} + +uint32_t common_hal_bleio_characteristic_buffer_rx_characters_available(bleio_characteristic_buffer_obj_t *self) { + uint8_t is_nested_critical_region; + sd_nvic_critical_region_enter(&is_nested_critical_region); + uint16_t count = ringbuf_count(&self->ringbuf); + sd_nvic_critical_region_exit(is_nested_critical_region); + return count; +} + +void common_hal_bleio_characteristic_buffer_clear_rx_buffer(bleio_characteristic_buffer_obj_t *self) { + // prevent conflict with uart irq + uint8_t is_nested_critical_region; + sd_nvic_critical_region_enter(&is_nested_critical_region); + ringbuf_clear(&self->ringbuf); + sd_nvic_critical_region_exit(is_nested_critical_region); +} + +bool common_hal_bleio_characteristic_buffer_deinited(bleio_characteristic_buffer_obj_t *self) { + return self->characteristic == NULL; +} + +void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_obj_t *self) { + if (!common_hal_bleio_characteristic_buffer_deinited(self)) { + ble_drv_remove_event_handler(characteristic_buffer_on_ble_evt, self); + } +} + +bool common_hal_bleio_characteristic_buffer_connected(bleio_characteristic_buffer_obj_t *self) { + return self->characteristic != NULL && + self->characteristic->service != NULL && + self->characteristic->service->device != NULL && + common_hal_bleio_device_get_conn_handle(self->characteristic->service->device) != BLE_CONN_HANDLE_INVALID; +} diff --git a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.h b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.h new file mode 100644 index 00000000000..f0949251cd2 --- /dev/null +++ b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.h @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H + +#include "nrf_soc.h" + +#include "py/ringbuf.h" +#include "shared-bindings/_bleio/Characteristic.h" + +typedef struct { + mp_obj_base_t base; + bleio_characteristic_obj_t *characteristic; + uint32_t timeout_ms; + // Ring buffer storing consecutive incoming values. + ringbuf_t ringbuf; +} bleio_characteristic_buffer_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H diff --git a/ports/nrf/common-hal/_bleio/Descriptor.c b/ports/nrf/common-hal/_bleio/Descriptor.c new file mode 100644 index 00000000000..137f004babd --- /dev/null +++ b/ports/nrf/common-hal/_bleio/Descriptor.c @@ -0,0 +1,143 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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 "py/runtime.h" + +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/UUID.h" + +static volatile bleio_descriptor_obj_t *m_read_descriptor; + +void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_characteristic_obj_t *characteristic, bleio_uuid_obj_t *uuid, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo) { + self->characteristic = characteristic; + self->uuid = uuid; + self->handle = BLE_GATT_HANDLE_INVALID; + self->read_perm = read_perm; + self->write_perm = write_perm; + + const mp_int_t max_length_max = fixed_length ? BLE_GATTS_FIX_ATTR_LEN_MAX : BLE_GATTS_VAR_ATTR_LEN_MAX; + if (max_length < 0 || max_length > max_length_max) { + mp_raise_ValueError_varg(translate("max_length must be 0-%d when fixed_length is %s"), + max_length_max, fixed_length ? "True" : "False"); + } + self->max_length = max_length; + self->fixed_length = fixed_length; + + common_hal_bleio_descriptor_set_value(self, initial_value_bufinfo); +} + +bleio_uuid_obj_t *common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) { + return self->uuid; +} + +bleio_characteristic_obj_t *common_hal_bleio_descriptor_get_characteristic(bleio_descriptor_obj_t *self) { + return self->characteristic; +} + +STATIC void descriptor_on_gattc_read_rsp_evt(ble_evt_t *ble_evt, void *param) { + switch (ble_evt->header.evt_id) { + + // More events may be handled later, so keep this as a switch. + + case BLE_GATTC_EVT_READ_RSP: { + ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp; + if (m_read_descriptor) { + m_read_descriptor->value = mp_obj_new_bytearray(response->len, response->data); + } + // Indicate to busy-wait loop that we've read the attribute value. + m_read_descriptor = NULL; + break; + } + + default: + // For debugging. + // mp_printf(&mp_plat_print, "Unhandled descriptor event: 0x%04x\n", ble_evt->header.evt_id); + break; + } +} + +STATIC void descriptor_gattc_read(bleio_descriptor_obj_t *descriptor) { + const uint16_t conn_handle = + common_hal_bleio_device_get_conn_handle(descriptor->characteristic->service->device); + common_hal_bleio_check_connected(conn_handle); + + // Set to NULL in event loop after event. + m_read_descriptor = descriptor; + + ble_drv_add_event_handler(descriptor_on_gattc_read_rsp_evt, descriptor); + + const uint32_t err_code = sd_ble_gattc_read(conn_handle, descriptor->handle, 0); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to read attribute value, err 0x%04x"), err_code); + } + + while (m_read_descriptor != NULL) { + MICROPY_VM_HOOK_LOOP; + } + + ble_drv_remove_event_handler(descriptor_on_gattc_read_rsp_evt, descriptor); +} + +mp_obj_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self) { + // Do GATT operations only if this descriptor has been registered + if (self->handle != BLE_GATT_HANDLE_INVALID) { + if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) { + descriptor_gattc_read(self); + } else { + self->value = common_hal_bleio_gatts_read( + self->handle, common_hal_bleio_device_get_conn_handle(self->characteristic->service->device)); + } + } + + return self->value; +} + +void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buffer_info_t *bufinfo) { + if (self->fixed_length && bufinfo->len != self->max_length) { + mp_raise_ValueError(translate("Value length != required fixed length")); + } + if (bufinfo->len > self->max_length) { + mp_raise_ValueError(translate("Value length > max_length")); + } + + self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len); + + // Do GATT operations only if this descriptor has been registered. + if (self->handle != BLE_GATT_HANDLE_INVALID) { + uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->characteristic->service->device); + if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) { + // false means WRITE_REQ, not write-no-response + common_hal_bleio_gattc_write(self->handle, conn_handle, bufinfo, false); + } else { + common_hal_bleio_gatts_write(self->handle, conn_handle, bufinfo); + } + } + +} diff --git a/ports/nrf/common-hal/_bleio/Descriptor.h b/ports/nrf/common-hal/_bleio/Descriptor.h new file mode 100644 index 00000000000..3adb0df1849 --- /dev/null +++ b/ports/nrf/common-hal/_bleio/Descriptor.h @@ -0,0 +1,50 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_DESCRIPTOR_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_DESCRIPTOR_H + +#include "py/obj.h" + +#include "common-hal/_bleio/Characteristic.h" +#include "common-hal/_bleio/UUID.h" + +typedef struct { + mp_obj_base_t base; + // Will be MP_OBJ_NULL before being assigned to a Characteristic. + bleio_characteristic_obj_t *characteristic; + bleio_uuid_obj_t *uuid; + mp_obj_t value; + uint16_t max_length; + bool fixed_length; + uint16_t handle; + bleio_attribute_security_mode_t read_perm; + bleio_attribute_security_mode_t write_perm; +} bleio_descriptor_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_DESCRIPTOR_H diff --git a/ports/nrf/common-hal/_bleio/Peripheral.c b/ports/nrf/common-hal/_bleio/Peripheral.c new file mode 100644 index 00000000000..9b0f96d48f2 --- /dev/null +++ b/ports/nrf/common-hal/_bleio/Peripheral.c @@ -0,0 +1,361 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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 +#include + +#include "ble.h" +#include "ble_drv.h" +#include "ble_hci.h" +#include "nrf_soc.h" +#include "py/gc.h" +#include "py/objlist.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/Attribute.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Peripheral.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/UUID.h" + +#define BLE_ADV_LENGTH_FIELD_SIZE 1 +#define BLE_ADV_AD_TYPE_FIELD_SIZE 1 +#define BLE_AD_TYPE_FLAGS_DATA_SIZE 1 + +static const ble_gap_sec_params_t pairing_sec_params = { + .bond = 1, + .mitm = 0, + .lesc = 0, + .keypress = 0, + .oob = 0, + .io_caps = BLE_GAP_IO_CAPS_NONE, + .min_key_size = 7, + .max_key_size = 16, + .kdist_own = { .enc = 1, .id = 1}, + .kdist_peer = { .enc = 1, .id = 1}, +}; + +STATIC void check_data_fit(size_t data_len) { + if (data_len > BLE_GAP_ADV_SET_DATA_SIZE_MAX) { + mp_raise_ValueError(translate("Data too large for advertisement packet")); + } +} + +STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { + bleio_peripheral_obj_t *self = (bleio_peripheral_obj_t*)self_in; + + // For debugging. + // mp_printf(&mp_plat_print, "Peripheral event: 0x%04x\n", ble_evt->header.evt_id); + + switch (ble_evt->header.evt_id) { + case BLE_GAP_EVT_CONNECTED: { + // Central has connected. + ble_gap_evt_connected_t* connected = &ble_evt->evt.gap_evt.params.connected; + + self->conn_handle = ble_evt->evt.gap_evt.conn_handle; + + // See if connection interval set by Central is out of range. + // If so, negotiate our preferred range. + ble_gap_conn_params_t conn_params; + sd_ble_gap_ppcp_get(&conn_params); + if (conn_params.min_conn_interval < connected->conn_params.min_conn_interval || + conn_params.min_conn_interval > connected->conn_params.max_conn_interval) { + sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params); + } + break; + } + + case BLE_GAP_EVT_DISCONNECTED: + // Central has disconnected. + self->conn_handle = BLE_CONN_HANDLE_INVALID; + break; + + case BLE_GAP_EVT_PHY_UPDATE_REQUEST: { + ble_gap_phys_t const phys = { + .rx_phys = BLE_GAP_PHY_AUTO, + .tx_phys = BLE_GAP_PHY_AUTO, + }; + sd_ble_gap_phy_update(ble_evt->evt.gap_evt.conn_handle, &phys); + break; + } + + case BLE_GAP_EVT_ADV_SET_TERMINATED: + // TODO: Someday may handle timeouts or limit reached. + break; + + case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: + // SoftDevice will respond to a length update request. + sd_ble_gap_data_length_update(self->conn_handle, NULL, NULL); + break; + + case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: { + // We only handle MTU of size BLE_GATT_ATT_MTU_DEFAULT. + sd_ble_gatts_exchange_mtu_reply(self->conn_handle, BLE_GATT_ATT_MTU_DEFAULT); + break; + } + + case BLE_GATTS_EVT_SYS_ATTR_MISSING: + sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0); + break; + + case BLE_GAP_EVT_SEC_PARAMS_REQUEST: { + ble_gap_sec_keyset_t keyset = { + .keys_own = { + .p_enc_key = &self->bonding_keys.own_enc, + .p_id_key = NULL, + .p_sign_key = NULL, + .p_pk = NULL + }, + + .keys_peer = { + .p_enc_key = &self->bonding_keys.peer_enc, + .p_id_key = &self->bonding_keys.peer_id, + .p_sign_key = NULL, + .p_pk = NULL + } + }; + + sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, + &pairing_sec_params, &keyset); + break; + } + + case BLE_GAP_EVT_LESC_DHKEY_REQUEST: + // TODO for LESC pairing: + // sd_ble_gap_lesc_dhkey_reply(...); + break; + + case BLE_GAP_EVT_AUTH_STATUS: { + // Pairing process completed + ble_gap_evt_auth_status_t* status = &ble_evt->evt.gap_evt.params.auth_status; + if (BLE_GAP_SEC_STATUS_SUCCESS == status->auth_status) { + // TODO _ediv = bonding_keys->own_enc.master_id.ediv; + self->pair_status = PAIR_PAIRED; + } else { + self->pair_status = PAIR_NOT_PAIRED; + } + break; + } + + case BLE_GAP_EVT_SEC_INFO_REQUEST: { + // Peer asks for the stored keys. + // - load key and return if bonded previously. + // - Else return NULL --> Initiate key exchange + ble_gap_evt_sec_info_request_t* sec_info_request = &ble_evt->evt.gap_evt.params.sec_info_request; + (void) sec_info_request; + //if ( bond_load_keys(_role, sec_req->master_id.ediv, &bkeys) ) { + //sd_ble_gap_sec_info_reply(_conn_hdl, &bkeys.own_enc.enc_info, &bkeys.peer_id.id_info, NULL); + // + //_ediv = bkeys.own_enc.master_id.ediv; + // } else { + sd_ble_gap_sec_info_reply(self->conn_handle, NULL, NULL, NULL); + // } + break; + } + + case BLE_GAP_EVT_CONN_SEC_UPDATE: { + ble_gap_conn_sec_t* conn_sec = &ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec; + if (conn_sec->sec_mode.sm <= 1 && conn_sec->sec_mode.lv <= 1) { + // Security setup did not succeed: + // mode 0, level 0 means no access + // mode 1, level 1 means open link + // mode >=1 and/or level >=1 means encryption is set up + self->pair_status = PAIR_NOT_PAIRED; + } else { + //if ( !bond_load_cccd(_role, _conn_hdl, _ediv) ) { + if (true) { // TODO: no bonding yet + // Initialize system attributes fresh. + sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0); + } + // Not quite paired yet: wait for BLE_GAP_EVT_AUTH_STATUS SUCCESS. + self->ediv = self->bonding_keys.own_enc.master_id.ediv; + } + break; + } + + + default: + // For debugging. + // mp_printf(&mp_plat_print, "Unhandled peripheral event: 0x%04x\n", ble_evt->header.evt_id); + break; + } +} + +void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_t name) { + common_hal_bleio_adapter_set_enabled(true); + + self->service_list = mp_obj_new_list(0, NULL); + // Used only for discovery when acting as a client. + self->remote_service_list = mp_obj_new_list(0, NULL); + self->name = name; + + self->conn_handle = BLE_CONN_HANDLE_INVALID; + self->adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; + self->pair_status = PAIR_NOT_PAIRED; + + memset(&self->bonding_keys, 0, sizeof(self->bonding_keys)); +} + +void common_hal_bleio_peripheral_add_service(bleio_peripheral_obj_t *self, bleio_service_obj_t *service) { + ble_uuid_t uuid; + bleio_uuid_convert_to_nrf_ble_uuid(service->uuid, &uuid); + + uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY; + if (common_hal_bleio_service_get_is_secondary(service)) { + service_type = BLE_GATTS_SRVC_TYPE_SECONDARY; + } + + const uint32_t err_code = sd_ble_gatts_service_add(service_type, &uuid, &service->handle); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to add service, err 0x%04x"), err_code); + } + + mp_obj_list_append(self->service_list, MP_OBJ_FROM_PTR(service)); +} + +mp_obj_list_t *common_hal_bleio_peripheral_get_services(bleio_peripheral_obj_t *self) { + return self->service_list; +} + +bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self) { + return self->conn_handle != BLE_CONN_HANDLE_INVALID; +} + +mp_obj_t common_hal_bleio_peripheral_get_name(bleio_peripheral_obj_t *self) { + return self->name; +} + +void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *self, bool connectable, mp_float_t interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo) { + + // interval value has already been validated. + + if (connectable) { + ble_drv_add_event_handler(peripheral_on_ble_evt, self); + } + + common_hal_bleio_adapter_set_enabled(true); + + uint32_t err_code; + + GET_STR_DATA_LEN(self->name, name_data, name_len); + if (name_len > 0) { + // Set device name, and make it available to anyone. + ble_gap_conn_sec_mode_t sec_mode; + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); + err_code = sd_ble_gap_device_name_set(&sec_mode, name_data, name_len); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to set device name, err 0x%04x"), err_code); + + } + } + + check_data_fit(advertising_data_bufinfo->len); + // The advertising data buffers must not move, because the SoftDevice depends on them. + // So make them long-lived. + self->advertising_data = (uint8_t *) gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_MAX * sizeof(uint8_t), false, true); + memcpy(self->advertising_data, advertising_data_bufinfo->buf, advertising_data_bufinfo->len); + + check_data_fit(scan_response_data_bufinfo->len); + self->scan_response_data = (uint8_t *) gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_MAX * sizeof(uint8_t), false, true); + memcpy(self->scan_response_data, scan_response_data_bufinfo->buf, scan_response_data_bufinfo->len); + + + ble_gap_adv_params_t adv_params = { + .interval = SEC_TO_UNITS(interval, UNIT_0_625_MS), + .properties.type = connectable ? BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED + : BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED, + .duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED, + .filter_policy = BLE_GAP_ADV_FP_ANY, + .primary_phy = BLE_GAP_PHY_1MBPS, + }; + + common_hal_bleio_peripheral_stop_advertising(self); + + const ble_gap_adv_data_t ble_gap_adv_data = { + .adv_data.p_data = self->advertising_data, + .adv_data.len = advertising_data_bufinfo->len, + .scan_rsp_data.p_data = scan_response_data_bufinfo-> len > 0 ? self->scan_response_data : NULL, + .scan_rsp_data.len = scan_response_data_bufinfo->len, + }; + + err_code = sd_ble_gap_adv_set_configure(&self->adv_handle, &ble_gap_adv_data, &adv_params); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to configure advertising, err 0x%04x"), err_code); + } + + err_code = sd_ble_gap_adv_start(self->adv_handle, BLE_CONN_CFG_TAG_CUSTOM); + + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to start advertising, err 0x%04x"), err_code); + } +} + +void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *self) { + if (self->adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET) + return; + + const uint32_t err_code = sd_ble_gap_adv_stop(self->adv_handle); + + if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) { + mp_raise_OSError_msg_varg(translate("Failed to stop advertising, err 0x%04x"), err_code); + } +} + +void common_hal_bleio_peripheral_disconnect(bleio_peripheral_obj_t *self) { + sd_ble_gap_disconnect(self->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); +} + +mp_obj_tuple_t *common_hal_bleio_peripheral_discover_remote_services(bleio_peripheral_obj_t *self, mp_obj_t service_uuids_whitelist) { + common_hal_bleio_device_discover_remote_services(MP_OBJ_FROM_PTR(self), service_uuids_whitelist); + // Convert to a tuple and then clear the list so the callee will take ownership. + mp_obj_tuple_t *services_tuple = mp_obj_new_tuple(self->remote_service_list->len, + self->remote_service_list->items); + mp_obj_list_clear(self->remote_service_list); + return services_tuple; +} + +void common_hal_bleio_peripheral_pair(bleio_peripheral_obj_t *self) { + self->pair_status = PAIR_WAITING; + + uint32_t err_code = sd_ble_gap_authenticate(self->conn_handle, &pairing_sec_params); + + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to start pairing, error 0x%04x"), err_code); + } + + while (self->pair_status == PAIR_WAITING) { + RUN_BACKGROUND_TASKS; + } + + if (self->pair_status == PAIR_NOT_PAIRED) { + mp_raise_OSError_msg(translate("Failed to pair")); + } + + +} diff --git a/ports/nrf/common-hal/_bleio/Peripheral.h b/ports/nrf/common-hal/_bleio/Peripheral.h new file mode 100644 index 00000000000..a4f62d288a3 --- /dev/null +++ b/ports/nrf/common-hal/_bleio/Peripheral.h @@ -0,0 +1,67 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PERIPHERAL_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PERIPHERAL_H + +#include + +#include "ble.h" + +#include "py/obj.h" +#include "py/objlist.h" + +#include "common-hal/_bleio/__init__.h" +#include "shared-module/_bleio/Address.h" + +typedef enum { + PAIR_NOT_PAIRED, + PAIR_WAITING, + PAIR_PAIRED, +} pair_status_t; + +typedef struct { + mp_obj_base_t base; + mp_obj_t name; + volatile uint16_t conn_handle; + // Services provided by this peripheral. + mp_obj_list_t *service_list; + // Remote services discovered when this peripheral is acting as a client. + mp_obj_list_t *remote_service_list; + // The advertising data and scan response buffers are held by us, not by the SD, so we must + // maintain them and not change it. If we need to change the contents during advertising, + // there are tricks to get the SD to notice (see DevZone - TBS). + // EDIV: Encrypted Diversifier: Identifies LTK during legacy pairing. + bonding_keys_t bonding_keys; + uint16_t ediv; + uint8_t* advertising_data; + uint8_t* scan_response_data; + uint8_t adv_handle; + pair_status_t pair_status; +} bleio_peripheral_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PERIPHERAL_H diff --git a/ports/nrf/common-hal/_bleio/Scanner.c b/ports/nrf/common-hal/_bleio/Scanner.c new file mode 100644 index 00000000000..ec73f7eb8fd --- /dev/null +++ b/ports/nrf/common-hal/_bleio/Scanner.c @@ -0,0 +1,105 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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 + +#include "ble_drv.h" +#include "ble_gap.h" +#include "py/mphal.h" +#include "py/objlist.h" +#include "py/runtime.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/ScanEntry.h" +#include "shared-bindings/_bleio/Scanner.h" +#include "shared-module/_bleio/ScanEntry.h" + +static uint8_t m_scan_buffer_data[BLE_GAP_SCAN_BUFFER_MIN]; + +static ble_data_t m_scan_buffer = { + m_scan_buffer_data, + BLE_GAP_SCAN_BUFFER_MIN +}; + +STATIC void scanner_on_ble_evt(ble_evt_t *ble_evt, void *scanner_in) { + bleio_scanner_obj_t *scanner = (bleio_scanner_obj_t*)scanner_in; + ble_gap_evt_adv_report_t *report = &ble_evt->evt.gap_evt.params.adv_report; + + if (ble_evt->header.evt_id != BLE_GAP_EVT_ADV_REPORT) { + return; + } + + bleio_scanentry_obj_t *entry = m_new_obj(bleio_scanentry_obj_t); + entry->base.type = &bleio_scanentry_type; + entry->rssi = report->rssi; + + bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t); + address->base.type = &bleio_address_type; + common_hal_bleio_address_construct(MP_OBJ_TO_PTR(address), + report->peer_addr.addr, report->peer_addr.addr_type); + entry->address = address; + + entry->data = mp_obj_new_bytes(report->data.p_data, report->data.len); + + mp_obj_list_append(scanner->scan_entries, MP_OBJ_FROM_PTR(entry)); + + const uint32_t err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to continue scanning, err 0x%04x"), err_code); + } +} + +void common_hal_bleio_scanner_construct(bleio_scanner_obj_t *self) { +} + +mp_obj_t common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_float_t timeout, mp_float_t interval, mp_float_t window) { + common_hal_bleio_adapter_set_enabled(true); + ble_drv_add_event_handler(scanner_on_ble_evt, self); + + ble_gap_scan_params_t scan_params = { + .interval = SEC_TO_UNITS(interval, UNIT_0_625_MS), + .window = SEC_TO_UNITS(window, UNIT_0_625_MS), + .scan_phys = BLE_GAP_PHY_1MBPS, + }; + + self->scan_entries = mp_obj_new_list(0, NULL); + + uint32_t err_code; + err_code = sd_ble_gap_scan_start(&scan_params, &m_scan_buffer); + + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to start scanning, err 0x%04x"), err_code); + } + + mp_hal_delay_ms(timeout * 1000); + sd_ble_gap_scan_stop(); + + // Return list, and don't hang on to it, so it can be GC'd. + mp_obj_t entries = self->scan_entries; + self->scan_entries = MP_OBJ_NULL; + return entries; +} diff --git a/ports/nrf/common-hal/_bleio/Scanner.h b/ports/nrf/common-hal/_bleio/Scanner.h new file mode 100644 index 00000000000..3768a52cb8c --- /dev/null +++ b/ports/nrf/common-hal/_bleio/Scanner.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SCANNER_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SCANNER_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + mp_obj_t scan_entries; + uint16_t interval; + uint16_t window; +} bleio_scanner_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SCANNER_H diff --git a/ports/nrf/common-hal/_bleio/Service.c b/ports/nrf/common-hal/_bleio/Service.c new file mode 100644 index 00000000000..650cdc4ec90 --- /dev/null +++ b/ports/nrf/common-hal/_bleio/Service.c @@ -0,0 +1,122 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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 "ble_drv.h" +#include "ble.h" +#include "py/runtime.h" +#include "common-hal/_bleio/__init__.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/Peripheral.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/Adapter.h" + +void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_peripheral_obj_t *peripheral, bleio_uuid_obj_t *uuid, bool is_secondary) { + self->device = MP_OBJ_FROM_PTR(peripheral); + self->handle = 0xFFFF; + self->uuid = uuid; + self->characteristic_list = mp_obj_new_list(0, NULL); + self->is_remote = false; + self->is_secondary = is_secondary; +} + +bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self) { + return self->uuid; +} + +mp_obj_list_t *common_hal_bleio_service_get_characteristic_list(bleio_service_obj_t *self) { + return self->characteristic_list; +} + +bool common_hal_bleio_service_get_is_remote(bleio_service_obj_t *self) { + return self->is_remote; +} + +bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self) { + return self->is_secondary; +} + +void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic) { + ble_gatts_char_md_t char_md = { + .char_props.broadcast = (characteristic->props & CHAR_PROP_BROADCAST) ? 1 : 0, + .char_props.read = (characteristic->props & CHAR_PROP_READ) ? 1 : 0, + .char_props.write_wo_resp = (characteristic->props & CHAR_PROP_WRITE_NO_RESPONSE) ? 1 : 0, + .char_props.write = (characteristic->props & CHAR_PROP_WRITE) ? 1 : 0, + .char_props.notify = (characteristic->props & CHAR_PROP_NOTIFY) ? 1 : 0, + .char_props.indicate = (characteristic->props & CHAR_PROP_INDICATE) ? 1 : 0, + }; + + ble_gatts_attr_md_t cccd_md = { + .vloc = BLE_GATTS_VLOC_STACK, + }; + + ble_uuid_t char_uuid; + bleio_uuid_convert_to_nrf_ble_uuid(characteristic->uuid, &char_uuid); + + ble_gatts_attr_md_t char_attr_md = { + .vloc = BLE_GATTS_VLOC_STACK, + .vlen = !characteristic->fixed_length, + }; + + if (char_md.char_props.notify || char_md.char_props.indicate) { + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + // Make CCCD write permission match characteristic read permission. + bleio_attribute_gatts_set_security_mode(&cccd_md.write_perm, characteristic->read_perm); + + char_md.p_cccd_md = &cccd_md; + } + + bleio_attribute_gatts_set_security_mode(&char_attr_md.read_perm, characteristic->read_perm); + bleio_attribute_gatts_set_security_mode(&char_attr_md.write_perm, characteristic->write_perm); + + mp_buffer_info_t char_value_bufinfo; + mp_get_buffer_raise(characteristic->value, &char_value_bufinfo, MP_BUFFER_READ); + + ble_gatts_attr_t char_attr = { + .p_uuid = &char_uuid, + .p_attr_md = &char_attr_md, + .init_len = char_value_bufinfo.len, + .p_value = char_value_bufinfo.buf, + .init_offs = 0, + .max_len = characteristic->max_length, + }; + + ble_gatts_char_handles_t char_handles; + + uint32_t err_code; + err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &char_attr, &char_handles); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to add characteristic, err 0x%04x"), err_code); + } + + characteristic->user_desc_handle = char_handles.user_desc_handle; + characteristic->cccd_handle = char_handles.cccd_handle; + characteristic->sccd_handle = char_handles.sccd_handle; + characteristic->handle = char_handles.value_handle; + + mp_obj_list_append(self->characteristic_list, MP_OBJ_FROM_PTR(characteristic)); +} diff --git a/ports/nrf/common-hal/_bleio/Service.h b/ports/nrf/common-hal/_bleio/Service.h new file mode 100644 index 00000000000..a4614b9f51d --- /dev/null +++ b/ports/nrf/common-hal/_bleio/Service.h @@ -0,0 +1,50 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SERVICE_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SERVICE_H + +#include "py/objlist.h" +#include "common-hal/_bleio/UUID.h" + +typedef struct { + mp_obj_base_t base; + // Handle for this service. + uint16_t handle; + // True if created during discovery. + bool is_remote; + bool is_secondary; + bleio_uuid_obj_t *uuid; + // May be a Peripheral, Central, etc. + mp_obj_t device; + mp_obj_list_t *characteristic_list; + // Range of attribute handles of this service. + uint16_t start_handle; + uint16_t end_handle; +} bleio_service_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SERVICE_H diff --git a/ports/nrf/common-hal/_bleio/UUID.c b/ports/nrf/common-hal/_bleio/UUID.c new file mode 100644 index 00000000000..0e65b7d58d6 --- /dev/null +++ b/ports/nrf/common-hal/_bleio/UUID.c @@ -0,0 +1,99 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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 + +#include "py/runtime.h" +#include "common-hal/_bleio/UUID.h" +#include "shared-bindings/_bleio/Adapter.h" + +#include "ble.h" +#include "ble_drv.h" +#include "nrf_error.h" + +// If uuid128 is NULL, this is a Bluetooth SIG 16-bit UUID. +// If uuid128 is not NULL, it's a 128-bit (16-byte) UUID, with bytes 12 and 13 zero'd out, where +// the 16-bit part goes. Those 16 bits are passed in uuid16. +void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, uint8_t uuid128[]) { + common_hal_bleio_adapter_set_enabled(true); + + self->nrf_ble_uuid.uuid = uuid16; + if (uuid128 == NULL) { + self->nrf_ble_uuid.type = BLE_UUID_TYPE_BLE; + } else { + ble_uuid128_t vs_uuid; + memcpy(vs_uuid.uuid128, uuid128, sizeof(vs_uuid.uuid128)); + + // Register this vendor-specific UUID. Bytes 12 and 13 will be zero. + const uint32_t err_code = sd_ble_uuid_vs_add(&vs_uuid, &self->nrf_ble_uuid.type); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to register Vendor-Specific UUID, err 0x%04x"), err_code); + } + } +} + +uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self) { + return self->nrf_ble_uuid.type == BLE_UUID_TYPE_BLE ? 16 : 128; +} + +uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self) { + return self->nrf_ble_uuid.uuid; +} + +// True if uuid128 has been successfully filled in. +bool common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]) { + uint8_t length; + const uint32_t err_code = sd_ble_uuid_encode(&self->nrf_ble_uuid, &length, uuid128); + + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Could not decode ble_uuid, err 0x%04x"), err_code); + } + // If not 16 bytes, this is not a 128-bit UUID, so return. + return length == 16; +} + +// Returns 0 if this is a 16-bit UUID, otherwise returns a non-zero index +// into the 128-bit uuid registration table. +uint32_t common_hal_bleio_uuid_get_uuid128_reference(bleio_uuid_obj_t *self) { + return self->nrf_ble_uuid.type == BLE_UUID_TYPE_BLE ? 0 : self->nrf_ble_uuid.type; +} + + +void bleio_uuid_construct_from_nrf_ble_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_ble_uuid) { + if (nrf_ble_uuid->type == BLE_UUID_TYPE_UNKNOWN) { + mp_raise_RuntimeError(translate("Unexpected nrfx uuid type")); + } + self->nrf_ble_uuid.uuid = nrf_ble_uuid->uuid; + self->nrf_ble_uuid.type = nrf_ble_uuid->type; +} + +// Fill in a ble_uuid_t from my values. +void bleio_uuid_convert_to_nrf_ble_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_ble_uuid) { + nrf_ble_uuid->uuid = self->nrf_ble_uuid.uuid; + nrf_ble_uuid->type = self->nrf_ble_uuid.type; +} diff --git a/ports/nrf/common-hal/_bleio/UUID.h b/ports/nrf/common-hal/_bleio/UUID.h new file mode 100644 index 00000000000..7d3a6204ecd --- /dev/null +++ b/ports/nrf/common-hal/_bleio/UUID.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H + +#include "py/obj.h" + +#include "ble.h" + +typedef struct { + mp_obj_base_t base; + // Use the native way of storing UUID's: + // - ble_uuid_t.uuid is a 16-bit uuid. + // - ble_uuid_t.type is BLE_UUID_TYPE_BLE if it's a 16-bit Bluetooth SIG UUID. + // or is BLE_UUID_TYPE_VENDOR_BEGIN and higher, which indexes into a table of registered + // 128-bit UUIDs. + ble_uuid_t nrf_ble_uuid; +} bleio_uuid_obj_t; + +void bleio_uuid_construct_from_nrf_ble_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid); +void bleio_uuid_convert_to_nrf_ble_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_uuid); + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H diff --git a/ports/nrf/common-hal/_bleio/__init__.c b/ports/nrf/common-hal/_bleio/__init__.c new file mode 100644 index 00000000000..5530441909e --- /dev/null +++ b/ports/nrf/common-hal/_bleio/__init__.c @@ -0,0 +1,502 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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 "py/runtime.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/Central.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/Peripheral.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/UUID.h" + +#include "common-hal/_bleio/__init__.h" + +static volatile bool m_discovery_in_process; +static volatile bool m_discovery_successful; + +static bleio_service_obj_t *m_char_discovery_service; +static bleio_characteristic_obj_t *m_desc_discovery_characteristic; + +// Turn off BLE on a reset or reload. +void bleio_reset() { + if (common_hal_bleio_adapter_get_enabled()) { + common_hal_bleio_adapter_set_enabled(false); + } +} + +// The singleton _bleio.Adapter object, bound to _bleio.adapter +// It currently only has properties and no state +const super_adapter_obj_t common_hal_bleio_adapter_obj = { + .base = { + .type = &bleio_adapter_type, + }, +}; + +void common_hal_bleio_check_connected(uint16_t conn_handle) { + if (conn_handle == BLE_CONN_HANDLE_INVALID) { + mp_raise_OSError_msg(translate("Not connected")); + } +} + +uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device) { + if (MP_OBJ_IS_TYPE(device, &bleio_peripheral_type)) { + return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle; + } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) { + return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle; + } else { + return BLE_CONN_HANDLE_INVALID; + } +} + +mp_obj_list_t *common_hal_bleio_device_get_remote_service_list(mp_obj_t device) { + if (MP_OBJ_IS_TYPE(device, &bleio_peripheral_type)) { + return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->remote_service_list; + } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) { + return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->remote_service_list; + } else { + return NULL; + } +} + +// service_uuid may be NULL, to discover all services. +STATIC bool discover_next_services(mp_obj_t device, uint16_t start_handle, ble_uuid_t *service_uuid) { + m_discovery_successful = false; + m_discovery_in_process = true; + + uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(device); + uint32_t err_code = sd_ble_gattc_primary_services_discover(conn_handle, start_handle, service_uuid); + + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg(translate("Failed to discover services")); + } + + // Wait for a discovery event. + while (m_discovery_in_process) { + MICROPY_VM_HOOK_LOOP; + } + return m_discovery_successful; +} + +STATIC bool discover_next_characteristics(mp_obj_t device, bleio_service_obj_t *service, uint16_t start_handle) { + m_char_discovery_service = service; + + ble_gattc_handle_range_t handle_range; + handle_range.start_handle = start_handle; + handle_range.end_handle = service->end_handle; + + m_discovery_successful = false; + m_discovery_in_process = true; + + uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(device); + uint32_t err_code = sd_ble_gattc_characteristics_discover(conn_handle, &handle_range); + if (err_code != NRF_SUCCESS) { + return false; + } + + // Wait for a discovery event. + while (m_discovery_in_process) { + MICROPY_VM_HOOK_LOOP; + } + return m_discovery_successful; +} + +STATIC bool discover_next_descriptors(mp_obj_t device, bleio_characteristic_obj_t *characteristic, uint16_t start_handle, uint16_t end_handle) { + m_desc_discovery_characteristic = characteristic; + + ble_gattc_handle_range_t handle_range; + handle_range.start_handle = start_handle; + handle_range.end_handle = end_handle; + + m_discovery_successful = false; + m_discovery_in_process = true; + + uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(device); + uint32_t err_code = sd_ble_gattc_descriptors_discover(conn_handle, &handle_range); + if (err_code != NRF_SUCCESS) { + return false; + } + + // Wait for a discovery event. + while (m_discovery_in_process) { + MICROPY_VM_HOOK_LOOP; + } + return m_discovery_successful; +} + +STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response, mp_obj_t device) { + for (size_t i = 0; i < response->count; ++i) { + ble_gattc_service_t *gattc_service = &response->services[i]; + + bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t); + service->base.type = &bleio_service_type; + + // Initialize several fields at once. + common_hal_bleio_service_construct(service, device, NULL, false); + + service->is_remote = true; + service->start_handle = gattc_service->handle_range.start_handle; + service->end_handle = gattc_service->handle_range.end_handle; + service->handle = gattc_service->handle_range.start_handle; + + if (gattc_service->uuid.type != BLE_UUID_TYPE_UNKNOWN) { + // Known service UUID. + bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); + uuid->base.type = &bleio_uuid_type; + bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid); + service->uuid = uuid; + } else { + // The discovery response contained a 128-bit UUID that has not yet been registered with the + // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it. + // For now, just set the UUID to NULL. + service->uuid = NULL; + } + + mp_obj_list_append(common_hal_bleio_device_get_remote_service_list(device), service); + } + + if (response->count > 0) { + m_discovery_successful = true; + } + m_discovery_in_process = false; +} + +STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, mp_obj_t device) { + for (size_t i = 0; i < response->count; ++i) { + ble_gattc_char_t *gattc_char = &response->chars[i]; + + bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t); + characteristic->base.type = &bleio_characteristic_type; + + bleio_uuid_obj_t *uuid = NULL; + + if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) { + // Known characteristic UUID. + uuid = m_new_obj(bleio_uuid_obj_t); + uuid->base.type = &bleio_uuid_type; + bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid); + } else { + // The discovery response contained a 128-bit UUID that has not yet been registered with the + // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it. + // For now, just leave the UUID as NULL. + } + + bleio_characteristic_properties_t props = + (gattc_char->char_props.broadcast ? CHAR_PROP_BROADCAST : 0) | + (gattc_char->char_props.indicate ? CHAR_PROP_INDICATE : 0) | + (gattc_char->char_props.notify ? CHAR_PROP_NOTIFY : 0) | + (gattc_char->char_props.read ? CHAR_PROP_READ : 0) | + (gattc_char->char_props.write ? CHAR_PROP_WRITE : 0) | + (gattc_char->char_props.write_wo_resp ? CHAR_PROP_WRITE_NO_RESPONSE : 0); + + // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler. + common_hal_bleio_characteristic_construct( + characteristic, m_char_discovery_service, uuid, props, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, + GATT_MAX_DATA_LENGTH, false, // max_length, fixed_length: values may not matter for gattc + mp_obj_new_list(0, NULL)); + characteristic->handle = gattc_char->handle_value; + + mp_obj_list_append(m_char_discovery_service->characteristic_list, MP_OBJ_FROM_PTR(characteristic)); + } + + if (response->count > 0) { + m_discovery_successful = true; + } + m_discovery_in_process = false; +} + +STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, mp_obj_t device) { + for (size_t i = 0; i < response->count; ++i) { + ble_gattc_desc_t *gattc_desc = &response->descs[i]; + + // Remember handles for certain well-known descriptors. + switch (gattc_desc->uuid.uuid) { + case BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG: + m_desc_discovery_characteristic->cccd_handle = gattc_desc->handle; + break; + + case BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG: + m_desc_discovery_characteristic->sccd_handle = gattc_desc->handle; + break; + + case BLE_UUID_DESCRIPTOR_CHAR_USER_DESC: + m_desc_discovery_characteristic->user_desc_handle = gattc_desc->handle; + break; + + default: + // TODO: sd_ble_gattc_descriptors_discover() can return things that are not descriptors, + // so ignore those. + // https://devzone.nordicsemi.com/f/nordic-q-a/49500/sd_ble_gattc_descriptors_discover-is-returning-attributes-that-are-not-descriptors + break; + } + + bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t); + descriptor->base.type = &bleio_descriptor_type; + + bleio_uuid_obj_t *uuid = NULL; + + if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) { + // Known descriptor UUID. + uuid = m_new_obj(bleio_uuid_obj_t); + uuid->base.type = &bleio_uuid_type; + bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid); + } else { + // The discovery response contained a 128-bit UUID that has not yet been registered with the + // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it. + // For now, just leave the UUID as NULL. + } + + common_hal_bleio_descriptor_construct( + descriptor, m_desc_discovery_characteristic, uuid, + SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, + GATT_MAX_DATA_LENGTH, false, mp_const_empty_bytes); + descriptor->handle = gattc_desc->handle; + + mp_obj_list_append(m_desc_discovery_characteristic->descriptor_list, MP_OBJ_FROM_PTR(descriptor)); + } + + if (response->count > 0) { + m_discovery_successful = true; + } + m_discovery_in_process = false; +} + +STATIC void discovery_on_ble_evt(ble_evt_t *ble_evt, mp_obj_t device) { + switch (ble_evt->header.evt_id) { + case BLE_GAP_EVT_DISCONNECTED: + m_discovery_successful = false; + m_discovery_in_process = false; + break; + + case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: + on_primary_srv_discovery_rsp(&ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp, device); + break; + + case BLE_GATTC_EVT_CHAR_DISC_RSP: + on_char_discovery_rsp(&ble_evt->evt.gattc_evt.params.char_disc_rsp, device); + break; + + case BLE_GATTC_EVT_DESC_DISC_RSP: + on_desc_discovery_rsp(&ble_evt->evt.gattc_evt.params.desc_disc_rsp, device); + break; + + default: + // For debugging. + // mp_printf(&mp_plat_print, "Unhandled discovery event: 0x%04x\n", ble_evt->header.evt_id); + break; + } +} + + +void common_hal_bleio_device_discover_remote_services(mp_obj_t device, mp_obj_t service_uuids_whitelist) { + mp_obj_list_t *remote_services_list = common_hal_bleio_device_get_remote_service_list(device); + + ble_drv_add_event_handler(discovery_on_ble_evt, device); + + // Start over with an empty list. + mp_obj_list_clear(MP_OBJ_FROM_PTR(common_hal_bleio_device_get_remote_service_list(device))); + + if (service_uuids_whitelist == mp_const_none) { + // List of service UUID's not given, so discover all available services. + + uint16_t next_service_start_handle = BLE_GATT_HANDLE_START; + + while (discover_next_services(device, next_service_start_handle, MP_OBJ_NULL)) { + // discover_next_services() appends to remote_services_list. + + // Get the most recently discovered service, and then ask for services + // whose handles start after the last attribute handle inside that service. + const bleio_service_obj_t *service = + MP_OBJ_TO_PTR(remote_services_list->items[remote_services_list->len - 1]); + next_service_start_handle = service->end_handle + 1; + } + } else { + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(service_uuids_whitelist, &iter_buf); + mp_obj_t uuid_obj; + while ((uuid_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) { + mp_raise_ValueError(translate("non-UUID found in service_uuids_whitelist")); + } + bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj); + + ble_uuid_t nrf_uuid; + bleio_uuid_convert_to_nrf_ble_uuid(uuid, &nrf_uuid); + + // Service might or might not be discovered; that's ok. Caller has to check + // Central.remote_services to find out. + // We only need to call this once for each service to discover. + discover_next_services(device, BLE_GATT_HANDLE_START, &nrf_uuid); + } + } + + + for (size_t service_idx = 0; service_idx < remote_services_list->len; ++service_idx) { + bleio_service_obj_t *service = MP_OBJ_TO_PTR(remote_services_list->items[service_idx]); + + // Skip the service if it had an unknown (unregistered) UUID. + if (service->uuid == NULL) { + continue; + } + + uint16_t next_char_start_handle = service->start_handle; + + // Stop when we go past the end of the range of handles for this service or + // discovery call returns nothing. + // discover_next_characteristics() appends to the characteristic_list. + while (next_char_start_handle <= service->end_handle && + discover_next_characteristics(device, service, next_char_start_handle)) { + + + // Get the most recently discovered characteristic, and then ask for characteristics + // whose handles start after the last attribute handle inside that characteristic. + const bleio_characteristic_obj_t *characteristic = + MP_OBJ_TO_PTR(service->characteristic_list->items[service->characteristic_list->len - 1]); + next_char_start_handle = characteristic->handle + 1; + } + + // Got characteristics for this service. Now discover descriptors for each characteristic. + size_t char_list_len = service->characteristic_list->len; + for (size_t char_idx = 0; char_idx < char_list_len; ++char_idx) { + bleio_characteristic_obj_t *characteristic = + MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx]); + const bool last_characteristic = char_idx == char_list_len - 1; + bleio_characteristic_obj_t *next_characteristic = last_characteristic + ? NULL + : MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx + 1]); + + // Skip the characteristic if it had an unknown (unregistered) UUID. + if (characteristic->uuid == NULL) { + continue; + } + + uint16_t next_desc_start_handle = characteristic->handle + 1; + + // Don't run past the end of this service or the beginning of the next characteristic. + uint16_t next_desc_end_handle = next_characteristic == NULL + ? service->end_handle + : next_characteristic->handle - 1; + + // Stop when we go past the end of the range of handles for this service or + // discovery call returns nothing. + // discover_next_descriptors() appends to the descriptor_list. + while (next_desc_start_handle <= service->end_handle && + next_desc_start_handle < next_desc_end_handle && + discover_next_descriptors(device, characteristic, + next_desc_start_handle, next_desc_end_handle)) { + + // Get the most recently discovered descriptor, and then ask for descriptors + // whose handles start after that descriptor's handle. + const bleio_descriptor_obj_t *descriptor = + MP_OBJ_TO_PTR(characteristic->descriptor_list->items[characteristic->descriptor_list->len - 1]); + next_desc_start_handle = descriptor->handle + 1; + } + } + } + + // This event handler is no longer needed. + ble_drv_remove_event_handler(discovery_on_ble_evt, device); + +} + +// GATTS read of a Characteristic or Descriptor. +mp_obj_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle) { + // conn_handle might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because + // we can still read and write the local value. + + mp_buffer_info_t bufinfo; + ble_gatts_value_t gatts_value = { + .p_value = NULL, + .len = 0, + }; + + // Read once to find out what size buffer we need, then read again to fill buffer. + + mp_obj_t value = mp_const_none; + uint32_t err_code = sd_ble_gatts_value_get(conn_handle, handle, &gatts_value); + if (err_code == NRF_SUCCESS) { + value = mp_obj_new_bytearray_of_zeros(gatts_value.len); + mp_get_buffer_raise(value, &bufinfo, MP_BUFFER_WRITE); + gatts_value.p_value = bufinfo.buf; + + // Read again, with the correct size of buffer. + err_code = sd_ble_gatts_value_get(conn_handle, handle, &gatts_value); + } + + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to read gatts value, err 0x%04x"), err_code); + } + + return value; +} + +void common_hal_bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo) { + // conn_handle might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because + // we can still read and write the local value. + + ble_gatts_value_t gatts_value = { + .p_value = bufinfo->buf, + .len = bufinfo->len, + }; + + const uint32_t err_code = sd_ble_gatts_value_set(conn_handle, handle, &gatts_value); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to write gatts value, err 0x%04x"), err_code); + } +} + +void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, bool write_no_response) { + common_hal_bleio_check_connected(conn_handle); + + ble_gattc_write_params_t write_params = { + .write_op = write_no_response ? BLE_GATT_OP_WRITE_CMD: BLE_GATT_OP_WRITE_REQ, + .handle = handle, + .p_value = bufinfo->buf, + .len = bufinfo->len, + }; + + while (1) { + uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params); + if (err_code == NRF_SUCCESS) { + break; + } + + // Write with response will return NRF_ERROR_BUSY if the response has not been received. + // Write without reponse will return NRF_ERROR_RESOURCES if too many writes are pending. + if (err_code == NRF_ERROR_BUSY || err_code == NRF_ERROR_RESOURCES) { + // We could wait for an event indicating the write is complete, but just retrying is easier. + MICROPY_VM_HOOK_LOOP; + continue; + } + + // Some real error occurred. + mp_raise_OSError_msg_varg(translate("Failed to write attribute value, err 0x%04x"), err_code); + } + +} diff --git a/ports/nrf/common-hal/_bleio/__init__.h b/ports/nrf/common-hal/_bleio/__init__.h new file mode 100644 index 00000000000..cf1a06945d1 --- /dev/null +++ b/ports/nrf/common-hal/_bleio/__init__.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H + +void bleio_reset(void); + +typedef struct { + ble_gap_enc_key_t own_enc; + ble_gap_enc_key_t peer_enc; + ble_gap_id_key_t peer_id; +} bonding_keys_t; + +// We assume variable length data. +// 20 bytes max (23 - 3). +#define GATT_MAX_DATA_LENGTH (BLE_GATT_ATT_MTU_DEFAULT - 3) + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H diff --git a/ports/nrf/common-hal/analogio/AnalogIn.c b/ports/nrf/common-hal/analogio/AnalogIn.c new file mode 100644 index 00000000000..f20802ac989 --- /dev/null +++ b/ports/nrf/common-hal/analogio/AnalogIn.c @@ -0,0 +1,112 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "common-hal/analogio/AnalogIn.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +#include "nrfx_saadc.h" +#include "nrf_gpio.h" + +#define CHANNEL_NO 0 + +void common_hal_analogio_analogin_construct(analogio_analogin_obj_t *self, const mcu_pin_obj_t *pin) { + if (pin->adc_channel == 0) + mp_raise_ValueError(translate("Pin does not have ADC capabilities")); + + nrf_gpio_cfg_default(pin->number); + + claim_pin(pin); + self->pin = pin; +} + +bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t *self) { + return self->pin == mp_const_none; +} + +void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { + if (common_hal_analogio_analogin_deinited(self)) + return; + + nrf_gpio_cfg_default(self->pin->number); + + reset_pin_number(self->pin->number); + self->pin = mp_const_none; +} + +uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { + // Something else might have used the ADC in a different way, + // so we completely re-initialize it. + + nrf_saadc_value_t value; + + const nrf_saadc_channel_config_t config = { + .resistor_p = NRF_SAADC_RESISTOR_DISABLED, + .resistor_n = NRF_SAADC_RESISTOR_DISABLED, + .gain = NRF_SAADC_GAIN1_6, + .reference = NRF_SAADC_REFERENCE_INTERNAL, + .acq_time = NRF_SAADC_ACQTIME_3US, + .mode = NRF_SAADC_MODE_SINGLE_ENDED, + .burst = NRF_SAADC_BURST_DISABLED, + .pin_p = self->pin->adc_channel, + .pin_n = self->pin->adc_channel, + }; + + nrf_saadc_resolution_set(NRF_SAADC_RESOLUTION_14BIT); + nrf_saadc_oversample_set(NRF_SAADC_OVERSAMPLE_DISABLED); + nrf_saadc_enable(); + + for (uint32_t i = 0; i < NRF_SAADC_CHANNEL_COUNT; i++) + nrf_saadc_channel_input_set(i, NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED); + + nrf_saadc_channel_init(CHANNEL_NO, &config); + nrf_saadc_buffer_init(&value, 1); + + nrf_saadc_task_trigger(NRF_SAADC_TASK_START); + while (nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED) == 0); + nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED); + + nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE); + while (nrf_saadc_event_check(NRF_SAADC_EVENT_END) == 0); + nrf_saadc_event_clear(NRF_SAADC_EVENT_END); + + nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP); + while (nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED) == 0); + nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED); + + nrf_saadc_disable(); + + if (value < 0) + value = 0; + + // Map value to from 14 to 16 bits + return (value << 2); +} + +float common_hal_analogio_analogin_get_reference_voltage(analogio_analogin_obj_t *self) { + return 3.3f; +} diff --git a/ports/nrf/common-hal/analogio/AnalogIn.h b/ports/nrf/common-hal/analogio/AnalogIn.h new file mode 100644 index 00000000000..e0e95bad4c2 --- /dev/null +++ b/ports/nrf/common-hal/analogio/AnalogIn.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_ANALOGIO_ANALOGIN_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_ANALOGIO_ANALOGIN_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t * pin; +} analogio_analogin_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_ANALOGIO_ANALOGIN_H diff --git a/ports/nrf/common-hal/analogio/AnalogOut.c b/ports/nrf/common-hal/analogio/AnalogOut.c new file mode 100644 index 00000000000..adafa15d5c9 --- /dev/null +++ b/ports/nrf/common-hal/analogio/AnalogOut.c @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "shared-bindings/analogio/AnalogOut.h" + +#include +#include + +#include "py/mperrno.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self, const mcu_pin_obj_t *pin) { + mp_raise_RuntimeError(translate("AnalogOut functionality not supported")); +} + +bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self) { + return true; +} + +void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self) { +} + +void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, uint16_t value) { +} diff --git a/ports/nrf/common-hal/analogio/AnalogOut.h b/ports/nrf/common-hal/analogio/AnalogOut.h new file mode 100644 index 00000000000..3244ee33b82 --- /dev/null +++ b/ports/nrf/common-hal/analogio/AnalogOut.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_ANALOGIO_ANALOGOUT_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_ANALOGIO_ANALOGOUT_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} analogio_analogout_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_ANALOGIO_ANALOGOUT_H diff --git a/ports/nrf/common-hal/analogio/__init__.c b/ports/nrf/common-hal/analogio/__init__.c new file mode 100644 index 00000000000..eea58c77d63 --- /dev/null +++ b/ports/nrf/common-hal/analogio/__init__.c @@ -0,0 +1 @@ +// No analogio module functions. diff --git a/ports/nrf/common-hal/audiobusio/I2SOut.c b/ports/nrf/common-hal/audiobusio/I2SOut.c new file mode 100644 index 00000000000..8be1fb2f8ca --- /dev/null +++ b/ports/nrf/common-hal/audiobusio/I2SOut.c @@ -0,0 +1,70 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Jeff Epler for Adafruit Industries + * + * 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 "common-hal/microcontroller/Pin.h" +#include "common-hal/audiobusio/I2SOut.h" + +#include "py/obj.h" +#include "py/runtime.h" + +void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t* self, + const mcu_pin_obj_t* bit_clock, const mcu_pin_obj_t* word_select, + const mcu_pin_obj_t* data, bool left_justified) { + mp_raise_NotImplementedError(NULL); +} + +bool common_hal_audiobusio_i2sout_deinited(audiobusio_i2sout_obj_t* self) { + mp_raise_NotImplementedError(NULL); +} + +void common_hal_audiobusio_i2sout_deinit(audiobusio_i2sout_obj_t* self) { + mp_raise_NotImplementedError(NULL); +} + +void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t* self, + mp_obj_t sample, bool loop) { + mp_raise_NotImplementedError(NULL); +} + +void common_hal_audiobusio_i2sout_pause(audiobusio_i2sout_obj_t* self) { + mp_raise_NotImplementedError(NULL); +} + +void common_hal_audiobusio_i2sout_resume(audiobusio_i2sout_obj_t* self) { + mp_raise_NotImplementedError(NULL); +} + +bool common_hal_audiobusio_i2sout_get_paused(audiobusio_i2sout_obj_t* self) { + mp_raise_NotImplementedError(NULL); +} + +void common_hal_audiobusio_i2sout_stop(audiobusio_i2sout_obj_t* self) { + mp_raise_NotImplementedError(NULL); +} + +bool common_hal_audiobusio_i2sout_get_playing(audiobusio_i2sout_obj_t* self) { + mp_raise_NotImplementedError(NULL); +} diff --git a/ports/nrf/common-hal/audiobusio/I2SOut.h b/ports/nrf/common-hal/audiobusio/I2SOut.h new file mode 100644 index 00000000000..01c944e7218 --- /dev/null +++ b/ports/nrf/common-hal/audiobusio/I2SOut.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_AUDIOBUSIO_I2SOUT_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_AUDIOBUSIO_I2SOUT_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} audiobusio_i2sout_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_AUDIOBUSIO_I2SOUT_H diff --git a/ports/nrf/common-hal/audiobusio/PDMIn.c b/ports/nrf/common-hal/audiobusio/PDMIn.c new file mode 100644 index 00000000000..a7f9c9d7477 --- /dev/null +++ b/ports/nrf/common-hal/audiobusio/PDMIn.c @@ -0,0 +1,130 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Jeff Epler for Adafruit Industries + * + * 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 "common-hal/audiobusio/PDMIn.h" +#include "shared-bindings/microcontroller/Pin.h" + +#include "py/runtime.h" + +__attribute__((used)) +NRF_PDM_Type *nrf_pdm = NRF_PDM; + +static uint32_t dummy_buffer[4]; + +void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t* self, + const mcu_pin_obj_t* clock_pin, + const mcu_pin_obj_t* data_pin, + uint32_t sample_rate, + uint8_t bit_depth, + bool mono, + uint8_t oversample) { + assert_pin_free(clock_pin); + assert_pin_free(data_pin); + claim_pin(clock_pin); + claim_pin(data_pin); + + self->mono = mono; + self->clock_pin_number = clock_pin->number; + self->data_pin_number = data_pin->number; + + if (sample_rate != 16000) { + mp_raise_ValueError(translate("only sample_rate=16000 is supported")); + } + if (bit_depth != 16) { + mp_raise_ValueError(translate("only bit_depth=16 is supported")); + } + nrf_pdm->PSEL.CLK = self->clock_pin_number; + nrf_pdm->PSEL.DIN = self->data_pin_number; + nrf_pdm->PDMCLKCTRL = PDM_PDMCLKCTRL_FREQ_Default; // For Ratio64 + nrf_pdm->RATIO = PDM_RATIO_RATIO_Ratio64; + nrf_pdm->GAINL = PDM_GAINL_GAINL_DefaultGain; + nrf_pdm->GAINR = PDM_GAINR_GAINR_DefaultGain; + nrf_pdm->ENABLE = 1; + + nrf_pdm->SAMPLE.PTR = (uintptr_t)&dummy_buffer; + nrf_pdm->SAMPLE.MAXCNT = 1; + nrf_pdm->TASKS_START = 1; +} + +bool common_hal_audiobusio_pdmin_deinited(audiobusio_pdmin_obj_t* self) { + return !self->clock_pin_number; +} + +void common_hal_audiobusio_pdmin_deinit(audiobusio_pdmin_obj_t* self) { + nrf_pdm->ENABLE = 0; + + reset_pin_number(self->clock_pin_number); + self->clock_pin_number = 0; + reset_pin_number(self->data_pin_number); + self->data_pin_number = 0; +} + +uint8_t common_hal_audiobusio_pdmin_get_bit_depth(audiobusio_pdmin_obj_t* self) { + return 16; +} + +uint32_t common_hal_audiobusio_pdmin_get_sample_rate(audiobusio_pdmin_obj_t* self) { + return 16000; +} + +uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* self, + uint16_t* output_buffer, uint32_t output_buffer_length) { + // Note: Adafruit's module has SELECT pulled to GND, which makes the DATA + // valid when the CLK is low, therefore it must be sampled on the rising edge. + if (self->mono) { + nrf_pdm->MODE = PDM_MODE_OPERATION_Stereo | PDM_MODE_EDGE_LeftRising; + } else { + nrf_pdm->MODE = PDM_MODE_OPERATION_Mono | PDM_MODE_EDGE_LeftRising; + } + + // step 1. Redirect to real buffer + nrf_pdm->SAMPLE.PTR = (uintptr_t)output_buffer; + nrf_pdm->SAMPLE.MAXCNT = output_buffer_length; + + // a delay is the safest simple way to ensure that the above requested sample has started + mp_hal_delay_us(200); + nrf_pdm->EVENTS_END = 0; + + // step 2. Registers are double buffered, so pre-redirect back to dummy buffer + nrf_pdm->SAMPLE.PTR = (uintptr_t)&dummy_buffer; + nrf_pdm->SAMPLE.MAXCNT = 1; + + // Step 3. wait for PDM to end + while (!nrf_pdm->EVENTS_END) { + MICROPY_VM_HOOK_LOOP; + } + + // Step 4. They want unsigned + for (uint32_t i=0; imono) { + return (output_buffer_length / 2) * 2; + } else { + return (output_buffer_length / 4) * 4; + } +} diff --git a/ports/nrf/common-hal/audiobusio/PDMIn.h b/ports/nrf/common-hal/audiobusio/PDMIn.h new file mode 100644 index 00000000000..d921e42ff38 --- /dev/null +++ b/ports/nrf/common-hal/audiobusio/PDMIn.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_AUDIOBUSIO_AUDIOOUT_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_AUDIOBUSIO_AUDIOOUT_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint8_t clock_pin_number, data_pin_number; + bool mono; +} audiobusio_pdmin_obj_t; + +#endif diff --git a/ports/nrf/common-hal/audiobusio/__init__.c b/ports/nrf/common-hal/audiobusio/__init__.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/nrf/common-hal/audiopwmio/PWMAudioOut.c b/ports/nrf/common-hal/audiopwmio/PWMAudioOut.c new file mode 100644 index 00000000000..0321b751ca0 --- /dev/null +++ b/ports/nrf/common-hal/audiopwmio/PWMAudioOut.c @@ -0,0 +1,316 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Jeff Epler for Adafruit Industries + * + * 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 +#include + +#include "extmod/vfs_fat.h" +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "common-hal/audiopwmio/PWMAudioOut.h" +#include "common-hal/pulseio/PWMOut.h" +#include "shared-bindings/audiopwmio/PWMAudioOut.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "supervisor/shared/translate.h" + +// TODO: This should be the same size as PWMOut.c:pwms[], but there's no trivial way to accomplish that +STATIC audiopwmio_pwmaudioout_obj_t* active_audio[4]; + +#define F_TARGET (62500) +#define F_PWM (16000000) +// return the REFRESH value, store the TOP value in an out-parameter +// Tested for key values (worst relative error = 0.224% = 3.84 cents) +// 8000: top = 250 refresh = 7 [ 8000.0] +// 22050: top = 242 refresh = 2 [22038.5] +// 24000: top = 222 refresh = 2 [24024.0] +// 44100: top = 181 refresh = 1 [44198.8] +// 48000: top = 167 refresh = 1 [47904.1] +STATIC uint32_t calculate_pwm_parameters(uint32_t sample_rate, uint32_t *top_out) { + // the desired frequency is the closest integer multiple of sample_rate not less than F_TARGET + uint32_t desired_frequency = (F_TARGET + sample_rate - 1) / sample_rate * sample_rate; + // The top value is the PWM frequency divided by the desired frequency (round to nearest) + uint32_t top = (F_PWM + desired_frequency/2) / desired_frequency; + // The actual frequency is the PWM frequency divided by the top value (round to nearest) + uint32_t actual_frequency = (F_PWM + top/2) / top; + // The multiplier is the actual frequency divided by the sample rate (round to nearest) + uint32_t multiplier = (actual_frequency + sample_rate/2) / sample_rate; + *top_out = top; + return multiplier - 1; +} + +STATIC void activate_audiopwmout_obj(audiopwmio_pwmaudioout_obj_t *self) { + for(size_t i=0; i < MP_ARRAY_SIZE(active_audio); i++) { + if(!active_audio[i]) { + active_audio[i] = self; + break; + } + } +} +STATIC void deactivate_audiopwmout_obj(audiopwmio_pwmaudioout_obj_t *self) { + for(size_t i=0; i < MP_ARRAY_SIZE(active_audio); i++) { + if(active_audio[i] == self) + active_audio[i] = NULL; + } +} + +void audiopwmout_reset() { + for(size_t i=0; i < MP_ARRAY_SIZE(active_audio); i++) + active_audio[i] = NULL; +} + +STATIC void fill_buffers(audiopwmio_pwmaudioout_obj_t *self, int buf) { + self->pwm->EVENTS_SEQSTARTED[1-buf] = 0; + uint16_t *dev_buffer = self->buffers[buf]; + uint8_t *buffer; + uint32_t buffer_length; + audioio_get_buffer_result_t get_buffer_result = + audiosample_get_buffer(self->sample, false, 0, + &buffer, &buffer_length); + if (get_buffer_result == GET_BUFFER_ERROR) { + common_hal_audiopwmio_pwmaudioout_stop(self); + return; + } + uint32_t num_samples = buffer_length / self->bytes_per_sample / self->spacing; + + if(self->bytes_per_sample == 1) { + uint8_t offset = self->signed_to_unsigned ? 0x80 : 0; + uint16_t scale = self->scale; + for(uint32_t i=0; ispacing; i++) { + uint8_t rawval = (*buffer++ + offset); + uint16_t val = (uint16_t)(((uint32_t)rawval * (uint32_t)scale) >> 8); + *dev_buffer++ = val; + if(self->spacing == 1) + *dev_buffer++ = val; + } + } else { + uint16_t offset = self->signed_to_unsigned ? 0x8000 : 0; + uint16_t scale = self->scale; + uint16_t *buffer16 = (uint16_t*)buffer; + for(uint32_t i=0; ispacing; i++) { + uint16_t rawval = (*buffer16++ + offset); + uint16_t val = (uint16_t)((rawval * (uint32_t)scale) >> 16); + *dev_buffer++ = val; + if(self->spacing == 1) + *dev_buffer++ = val; + } + } + self->pwm->SEQ[buf].PTR = (intptr_t)self->buffers[buf]; + self->pwm->SEQ[buf].CNT = num_samples*2; + + if (self->loop && get_buffer_result == GET_BUFFER_DONE) { + audiosample_reset_buffer(self->sample, false, 0); + } else if(get_buffer_result == GET_BUFFER_DONE) { + self->pwm->SHORTS = NRF_PWM_SHORT_SEQEND0_STOP_MASK | NRF_PWM_SHORT_SEQEND1_STOP_MASK; + self->stopping = true; + } +} + +STATIC void audiopwmout_background_obj(audiopwmio_pwmaudioout_obj_t *self) { + if(!common_hal_audiopwmio_pwmaudioout_get_playing(self)) + return; + if(self->stopping) { + bool stopped = + (self->pwm->EVENTS_SEQEND[0] || !self->pwm->EVENTS_SEQSTARTED[0]) && + (self->pwm->EVENTS_SEQEND[1] || !self->pwm->EVENTS_SEQSTARTED[1]); + if(stopped) + self->pwm->TASKS_STOP = 1; + } else if(!self->paused && !self->single_buffer) { + if(self->pwm->EVENTS_SEQSTARTED[0]) fill_buffers(self, 1); + if(self->pwm->EVENTS_SEQSTARTED[1]) fill_buffers(self, 0); + } +} + +void audiopwmout_background() { + for(size_t i=0; i < MP_ARRAY_SIZE(active_audio); i++) { + if(!active_audio[i]) continue; + audiopwmout_background_obj(active_audio[i]); + } +} + +void common_hal_audiopwmio_pwmaudioout_construct(audiopwmio_pwmaudioout_obj_t* self, + const mcu_pin_obj_t* left_channel, const mcu_pin_obj_t* right_channel, uint16_t quiescent_value) { + assert_pin_free(left_channel); + assert_pin_free(right_channel); + self->pwm = pwmout_allocate(256, PWM_PRESCALER_PRESCALER_DIV_1, true, NULL, NULL); + if(!self->pwm) { + mp_raise_RuntimeError(translate("All timers in use")); + } + + self->pwm->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_1; + // two uint16_t values per sample when Grouped + // n.b. SEQ[#].CNT "counts" are 2 per sample (left and right channels) + self->pwm->DECODER = PWM_DECODER_LOAD_Grouped; + + // we use channels 0 and 2 because these are GROUPED; it lets us save half + // the space for sample data (no additional optimization is possible for + // single channel) + self->pwm->PSEL.OUT[0] = self->left_channel_number = left_channel->number; + claim_pin(left_channel); + + if(right_channel) + { + self->pwm->PSEL.OUT[2] = self->right_channel_number = right_channel->number; + claim_pin(right_channel); + } + + self->quiescent_value = quiescent_value >> 8; + + self->pwm->ENABLE = 1; + // TODO: Ramp from 0 to quiescent value +} + +bool common_hal_audiopwmio_pwmaudioout_deinited(audiopwmio_pwmaudioout_obj_t* self) { + return !self->pwm; +} + +void common_hal_audiopwmio_pwmaudioout_deinit(audiopwmio_pwmaudioout_obj_t* self) { + if (common_hal_audiopwmio_pwmaudioout_deinited(self)) { + return; + } + // TODO: ramp the pwm down from quiescent value to 0 + self->pwm->ENABLE = 0; + + if(self->left_channel_number) + reset_pin_number(self->left_channel_number); + if(self->right_channel_number) + reset_pin_number(self->right_channel_number); + + pwmout_free_channel(self->pwm, 0); + pwmout_free_channel(self->pwm, 2); + + self->pwm = NULL; + + m_free(self->buffers[0]); + self->buffers[0] = NULL; + + m_free(self->buffers[1]); + self->buffers[1] = NULL; +} + +void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t* self, mp_obj_t sample, bool loop) { + if (common_hal_audiopwmio_pwmaudioout_get_playing(self)) { + common_hal_audiopwmio_pwmaudioout_stop(self); + } + self->sample = sample; + self->loop = loop; + + uint32_t sample_rate = audiosample_sample_rate(sample); + uint32_t max_sample_rate = 62500; + if (sample_rate > max_sample_rate) { + mp_raise_ValueError_varg(translate("Sample rate too high. It must be less than %d"), max_sample_rate); + } + self->bytes_per_sample = audiosample_bits_per_sample(sample) / 8; + + uint32_t max_buffer_length; + audiosample_get_buffer_structure(sample, /* single channel */ false, + &self->single_buffer, &self->signed_to_unsigned, &max_buffer_length, + &self->spacing); + if(max_buffer_length > UINT16_MAX) { + mp_raise_ValueError_varg(translate("Buffer length %d too big. It must be less than %d"), max_buffer_length, UINT16_MAX); + } + self->buffer_length = (uint16_t)max_buffer_length; + self->buffers[0] = m_malloc(self->buffer_length * 2 * sizeof(uint16_t), false); + if(!self->single_buffer) + self->buffers[1] = m_malloc(self->buffer_length * 2 * sizeof(uint16_t), false); + + + uint32_t top; + self->pwm->SEQ[0].REFRESH = self->pwm->SEQ[1].REFRESH = calculate_pwm_parameters(sample_rate, &top); + self->scale = top-1; + self->pwm->COUNTERTOP = top; + + self->pwm->LOOP = 1; + audiosample_reset_buffer(self->sample, false, 0); + activate_audiopwmout_obj(self); + fill_buffers(self, 0); + self->pwm->SEQ[1].PTR = self->pwm->SEQ[0].PTR; + self->pwm->SEQ[1].CNT = self->pwm->SEQ[0].CNT; + self->pwm->EVENTS_SEQSTARTED[0] = 0; + self->pwm->EVENTS_SEQSTARTED[1] = 0; + self->pwm->EVENTS_STOPPED = 0; + self->pwm->SHORTS = NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK; + self->pwm->TASKS_SEQSTART[0] = 1; + self->playing = true; + self->stopping = false; + self->paused = false; +} + +void common_hal_audiopwmio_pwmaudioout_stop(audiopwmio_pwmaudioout_obj_t* self) { + deactivate_audiopwmout_obj(self); + self->pwm->TASKS_STOP = 1; + self->stopping = false; + self->paused = false; + + m_free(self->buffers[0]); + self->buffers[0] = NULL; + + m_free(self->buffers[1]); + self->buffers[1] = NULL; +} + +bool common_hal_audiopwmio_pwmaudioout_get_playing(audiopwmio_pwmaudioout_obj_t* self) { + if(!self->paused && self->pwm->EVENTS_STOPPED) { + self->playing = false; + self->pwm->EVENTS_STOPPED = 0; + } + return self->playing; +} + +/* pause/resume present difficulties for the NRF PWM audio module. + * + * A PWM sequence can be stopped in its tracks by sending a TASKS_STOP event, + * but there's no way to pick up the sequence where it was stopped; you could + * start at the start of one of the two sequences, but especially for "single buffer" + * sample, this seems undesirable. + * + * Or, you can stop at the end of a sequence so that you don't duplicate anything + * when restarting, but again this is unsatisfactory for a "single buffer" sample. + * + * For now, I've taken the coward's way and left these methods unimplemented. + * Perhaps the way forward is to divide even "single buffer" samples into tasks of + * only a few ms long, so that they can be stopped/restarted quickly enough that it + * feels instant. (This also saves on memory, for long in-memory "single buffer" + * samples, since we have to locally take a resampled copy!) + */ +void common_hal_audiopwmio_pwmaudioout_pause(audiopwmio_pwmaudioout_obj_t* self) { + self->paused = true; + self->pwm->SHORTS = NRF_PWM_SHORT_SEQEND1_STOP_MASK; +} + +void common_hal_audiopwmio_pwmaudioout_resume(audiopwmio_pwmaudioout_obj_t* self) { + self->paused = false; + self->pwm->SHORTS = NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK; + if (self->pwm->EVENTS_STOPPED) { + self->pwm->EVENTS_STOPPED = 0; + self->pwm->TASKS_SEQSTART[0] = 1; + } +} + +bool common_hal_audiopwmio_pwmaudioout_get_paused(audiopwmio_pwmaudioout_obj_t* self) { + return self->paused; +} diff --git a/ports/nrf/common-hal/audiopwmio/PWMAudioOut.h b/ports/nrf/common-hal/audiopwmio/PWMAudioOut.h new file mode 100644 index 00000000000..8deff5d3409 --- /dev/null +++ b/ports/nrf/common-hal/audiopwmio/PWMAudioOut.h @@ -0,0 +1,59 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_AUDIOPWM_AUDIOOUT_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_AUDIOPWM_AUDIOOUT_H + +#include "common-hal/microcontroller/Pin.h" + +typedef struct { + mp_obj_base_t base; + mp_obj_t *sample; + NRF_PWM_Type *pwm; + uint16_t *buffers[2]; + + uint16_t buffer_length; + uint16_t quiescent_value; + uint16_t scale; + + uint8_t left_channel_number; + uint8_t right_channel_number; + uint8_t spacing; + uint8_t bytes_per_sample; + + bool playing; + bool stopping; + bool paused; + bool loop; + bool signed_to_unsigned; + bool single_buffer; +} audiopwmio_pwmaudioout_obj_t; + +void audiopwmout_reset(void); + +void audiopwmout_background(void); + +#endif diff --git a/ports/nrf/common-hal/audiopwmio/__init__.c b/ports/nrf/common-hal/audiopwmio/__init__.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/nrf/common-hal/board/__init__.c b/ports/nrf/common-hal/board/__init__.c new file mode 100644 index 00000000000..880033ed679 --- /dev/null +++ b/ports/nrf/common-hal/board/__init__.c @@ -0,0 +1,25 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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. + */ diff --git a/ports/nrf/common-hal/busio/I2C.c b/ports/nrf/common-hal/busio/I2C.c new file mode 100644 index 00000000000..71835d16ad1 --- /dev/null +++ b/ports/nrf/common-hal/busio/I2C.c @@ -0,0 +1,270 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 hathach + * Copyright (c) 2016 Sandeep Mistry All right reserved. + * + * 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 "shared-bindings/busio/I2C.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +#include "nrfx_twim.h" +#include "nrf_gpio.h" + +#include "nrfx_spim.h" +#include "nrf_gpio.h" + +// all TWI instances have the same max size +// 16 bits for 840, 10 bits for 810, 8 bits for 832 +#define I2C_MAX_XFER_LEN ((1UL << TWIM0_EASYDMA_MAXCNT_SIZE) - 1) + +STATIC twim_peripheral_t twim_peripherals[] = { +#if NRFX_CHECK(NRFX_TWIM0_ENABLED) + // SPIM0 and TWIM0 share an address. + { .twim = NRFX_TWIM_INSTANCE(0), + .in_use = false + }, +#endif +#if NRFX_CHECK(NRFX_TWIM1_ENABLED) + // SPIM1 and TWIM1 share an address. + { .twim = NRFX_TWIM_INSTANCE(1), + .in_use = false + }, +#endif +}; + +STATIC bool never_reset[MP_ARRAY_SIZE(twim_peripherals)]; + +void i2c_reset(void) { + for (size_t i = 0 ; i < MP_ARRAY_SIZE(twim_peripherals); i++) { + if (never_reset[i]) { + continue; + } + nrf_twim_disable(twim_peripherals[i].twim.p_twim); + twim_peripherals[i].in_use = false; + } +} + +void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { + for (size_t i = 0 ; i < MP_ARRAY_SIZE(twim_peripherals); i++) { + if (self->twim_peripheral == &twim_peripherals[i]) { + never_reset[i] = true; + + never_reset_pin_number(self->scl_pin_number); + never_reset_pin_number(self->sda_pin_number); + break; + } + } +} + +static uint8_t twi_error_to_mp(const nrfx_err_t err) { + switch (err) { + case NRFX_ERROR_DRV_TWI_ERR_ANACK: + return MP_ENODEV; + case NRFX_ERROR_BUSY: + return MP_EBUSY; + case NRFX_ERROR_DRV_TWI_ERR_DNACK: + case NRFX_ERROR_INVALID_ADDR: + return MP_EIO; + default: + break; + } + + return 0; +} + +void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) { + if (scl->number == sda->number) { + mp_raise_ValueError(translate("Invalid pins")); + } + + // Find a free instance. + self->twim_peripheral = NULL; + for (size_t i = 0 ; i < MP_ARRAY_SIZE(twim_peripherals); i++) { + if (!twim_peripherals[i].in_use) { + self->twim_peripheral = &twim_peripherals[i]; + self->twim_peripheral->in_use = true; + break; + } + } + + if (self->twim_peripheral == NULL) { + mp_raise_ValueError(translate("All I2C peripherals are in use")); + } + + nrfx_twim_config_t config = NRFX_TWIM_DEFAULT_CONFIG; + config.scl = scl->number; + config.sda = sda->number; + + // change freq. only if it's less than the default 400K + if (frequency < 100000) { + config.frequency = NRF_TWIM_FREQ_100K; + } else if (frequency < 250000) { + config.frequency = NRF_TWIM_FREQ_250K; + } + + self->scl_pin_number = scl->number; + self->sda_pin_number = sda->number; + claim_pin(sda); + claim_pin(scl); + + nrfx_err_t err = nrfx_twim_init(&self->twim_peripheral->twim, &config, NULL, NULL); + + // A soft reset doesn't uninit the driver so we might end up with a invalid state + if (err == NRFX_ERROR_INVALID_STATE) { + nrfx_twim_uninit(&self->twim_peripheral->twim); + err = nrfx_twim_init(&self->twim_peripheral->twim, &config, NULL, NULL); + } + + if (err != NRFX_SUCCESS) { + common_hal_busio_i2c_deinit(self); + mp_raise_OSError(MP_EIO); + } + +} + +bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { + return self->sda_pin_number == NO_PIN; +} + +void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { + if (common_hal_busio_i2c_deinited(self)) + return; + + nrfx_twim_uninit(&self->twim_peripheral->twim); + + reset_pin_number(self->sda_pin_number); + reset_pin_number(self->scl_pin_number); + self->sda_pin_number = NO_PIN; + self->scl_pin_number = NO_PIN; + + self->twim_peripheral->in_use = false; +} + +// nrfx_twim_tx doesn't support 0-length data so we fall back to the hal API +bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { + NRF_TWIM_Type *reg = self->twim_peripheral->twim.p_twim; + bool found = true; + + nrfx_twim_enable(&self->twim_peripheral->twim); + + nrf_twim_address_set(reg, addr); + nrf_twim_tx_buffer_set(reg, NULL, 0); + + nrf_twim_task_trigger(reg, NRF_TWIM_TASK_RESUME); + + nrf_twim_task_trigger(reg, NRF_TWIM_TASK_STARTTX); + while (nrf_twim_event_check(reg, NRF_TWIM_EVENT_TXSTARTED) == 0 && + nrf_twim_event_check(reg, NRF_TWIM_EVENT_ERROR) == 0); + nrf_twim_event_clear(reg, NRF_TWIM_EVENT_TXSTARTED); + + nrf_twim_task_trigger(reg, NRF_TWIM_TASK_STOP); + while (nrf_twim_event_check(reg, NRF_TWIM_EVENT_STOPPED) == 0); + nrf_twim_event_clear(reg, NRF_TWIM_EVENT_STOPPED); + + if (nrf_twim_event_check(reg, NRF_TWIM_EVENT_ERROR)) { + nrf_twim_event_clear(reg, NRF_TWIM_EVENT_ERROR); + + nrf_twim_errorsrc_get_and_clear(reg); + found = false; + } + + nrfx_twim_disable(&self->twim_peripheral->twim); + + return found; +} + +bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) { + bool grabbed_lock = false; + // NRFX_CRITICAL_SECTION_ENTER(); + if (!self->has_lock) { + grabbed_lock = true; + self->has_lock = true; + } + // NRFX_CRITICAL_SECTION_EXIT(); + return grabbed_lock; +} + +bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self) { + return self->has_lock; +} + +void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { + self->has_lock = false; +} + +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool stopBit) { + if(len == 0) { + return common_hal_busio_i2c_probe(self, addr) ? 0 : MP_ENODEV; + } + + nrfx_err_t err = NRFX_SUCCESS; + + nrfx_twim_enable(&self->twim_peripheral->twim); + + // break into MAX_XFER_LEN transaction + while ( len ) { + const size_t xact_len = MIN(len, I2C_MAX_XFER_LEN); + + if ( NRFX_SUCCESS != (err = nrfx_twim_tx(&self->twim_peripheral->twim, addr, data, xact_len, !stopBit)) ) { + break; + } + + len -= xact_len; + data += xact_len; + } + + nrfx_twim_disable(&self->twim_peripheral->twim); + + return twi_error_to_mp(err); +} + +uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { + if(len == 0) { + return 0; + } + + nrfx_err_t err = NRFX_SUCCESS; + + nrfx_twim_enable(&self->twim_peripheral->twim); + + // break into MAX_XFER_LEN transaction + while ( len ) { + const size_t xact_len = MIN(len, I2C_MAX_XFER_LEN); + + if ( NRFX_SUCCESS != (err = nrfx_twim_rx(&self->twim_peripheral->twim, addr, data, xact_len)) ) { + break; + } + + len -= xact_len; + data += xact_len; + } + + nrfx_twim_disable(&self->twim_peripheral->twim); + + return twi_error_to_mp(err); +} diff --git a/ports/nrf/common-hal/busio/I2C.h b/ports/nrf/common-hal/busio/I2C.h new file mode 100644 index 00000000000..b75d15f00fd --- /dev/null +++ b/ports/nrf/common-hal/busio/I2C.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_I2C_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_I2C_H + +#include "nrfx_twim.h" + +#include "py/obj.h" + +typedef struct { + nrfx_twim_t twim; + bool in_use; +} twim_peripheral_t; + +typedef struct { + mp_obj_base_t base; + twim_peripheral_t* twim_peripheral; + bool has_lock; + uint8_t scl_pin_number; + uint8_t sda_pin_number; +} busio_i2c_obj_t; + +void i2c_reset(void); + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_I2C_H diff --git a/ports/nrf/common-hal/busio/OneWire.h b/ports/nrf/common-hal/busio/OneWire.h new file mode 100644 index 00000000000..821cc64c1ed --- /dev/null +++ b/ports/nrf/common-hal/busio/OneWire.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_ONEWIRE_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_ONEWIRE_H + +// Use bitbangio. +#include "shared-module/busio/OneWire.h" + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_ONEWIRE_H diff --git a/ports/nrf/common-hal/busio/SPI.c b/ports/nrf/common-hal/busio/SPI.c new file mode 100644 index 00000000000..5f1aac1934d --- /dev/null +++ b/ports/nrf/common-hal/busio/SPI.c @@ -0,0 +1,339 @@ +/* + * SPI Master library for nRF5x. + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 hathach + * Copyright (c) 2016 Sandeep Mistry All right reserved. + * Copyright (c) 2015 Arduino LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "shared-bindings/busio/SPI.h" +#include "py/mperrno.h" +#include "py/runtime.h" + +#include "nrfx_spim.h" +#include "nrf_gpio.h" + +STATIC spim_peripheral_t spim_peripherals[] = { +#if NRFX_CHECK(NRFX_SPIM3_ENABLED) + // SPIM3 exists only on nRF52840 and supports 32MHz max. All other SPIM's are only 8MHz max. + // Allocate SPIM3 first. + { .spim = NRFX_SPIM_INSTANCE(3), + .max_frequency_MHz = 32, + .max_xfer_size = SPIM3_EASYDMA_MAXCNT_SIZE, + }, +#endif +#if NRFX_CHECK(NRFX_SPIM2_ENABLED) + // SPIM2 is not shared with a TWIM, so allocate before the shared ones. + { .spim = NRFX_SPIM_INSTANCE(2), + .max_frequency_MHz = 8, + .max_xfer_size = SPIM2_EASYDMA_MAXCNT_SIZE, + }, +#endif +#if NRFX_CHECK(NRFX_SPIM1_ENABLED) + // SPIM1 and TWIM1 share an address. + { .spim = NRFX_SPIM_INSTANCE(1), + .max_frequency_MHz = 8, + .max_xfer_size = SPIM1_EASYDMA_MAXCNT_SIZE, + }, +#endif +#if NRFX_CHECK(NRFX_SPIM0_ENABLED) + // SPIM0 and TWIM0 share an address. + { .spim = NRFX_SPIM_INSTANCE(0), + .max_frequency_MHz = 8, + .max_xfer_size = SPIM0_EASYDMA_MAXCNT_SIZE, + }, +#endif +}; + +STATIC bool never_reset[MP_ARRAY_SIZE(spim_peripherals)]; + +void spi_reset(void) { + for (size_t i = 0 ; i < MP_ARRAY_SIZE(spim_peripherals); i++) { + if (never_reset[i]) { + continue; + } + nrf_spim_disable(spim_peripherals[i].spim.p_reg); + } +} + +void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { + for (size_t i = 0 ; i < MP_ARRAY_SIZE(spim_peripherals); i++) { + if (self->spim_peripheral == &spim_peripherals[i]) { + never_reset[i] = true; + + never_reset_pin_number(self->clock_pin_number); + never_reset_pin_number(self->MOSI_pin_number); + never_reset_pin_number(self->MISO_pin_number); + break; + } + } +} + +// Convert frequency to clock-speed-dependent value. Choose the next lower baudrate if in between +// available baudrates. +static nrf_spim_frequency_t baudrate_to_spim_frequency(const uint32_t baudrate) { + + static const struct { + const uint32_t boundary; + nrf_spim_frequency_t spim_frequency; + } baudrate_map[] = { +#ifdef SPIM_FREQUENCY_FREQUENCY_M32 + { 32000000, NRF_SPIM_FREQ_32M }, +#endif +#ifdef SPIM_FREQUENCY_FREQUENCY_M16 + { 16000000, NRF_SPIM_FREQ_16M }, +#endif + { 8000000, NRF_SPIM_FREQ_8M }, + { 4000000, NRF_SPIM_FREQ_4M }, + { 2000000, NRF_SPIM_FREQ_2M }, + { 1000000, NRF_SPIM_FREQ_1M }, + { 500000, NRF_SPIM_FREQ_500K }, + { 250000, NRF_SPIM_FREQ_250K }, + { 0, NRF_SPIM_FREQ_125K }, + }; + + size_t i = 0; + uint32_t boundary; + do { + boundary = baudrate_map[i].boundary; + if (baudrate >= boundary) { + return baudrate_map[i].spim_frequency; + } + i++; + } while (boundary != 0); + // Should not get here. + return 0; +} + +void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, const mcu_pin_obj_t * miso) { + // Find a free instance. + self->spim_peripheral = NULL; + for (size_t i = 0 ; i < MP_ARRAY_SIZE(spim_peripherals); i++) { + if ((spim_peripherals[i].spim.p_reg->ENABLE & SPIM_ENABLE_ENABLE_Msk) == 0) { + self->spim_peripheral = &spim_peripherals[i]; + break; + } + } + + if (self->spim_peripheral == NULL) { + mp_raise_ValueError(translate("All SPI peripherals are in use")); + } + + nrfx_spim_config_t config = NRFX_SPIM_DEFAULT_CONFIG; + config.frequency = NRF_SPIM_FREQ_8M; + + config.sck_pin = clock->number; + self->clock_pin_number = clock->number; + claim_pin(clock); + + if (mosi != (mcu_pin_obj_t*)&mp_const_none_obj) { + config.mosi_pin = mosi->number; + self->MOSI_pin_number = mosi->number; + claim_pin(mosi); + } else { + self->MOSI_pin_number = NO_PIN; + } + + if (miso != (mcu_pin_obj_t*)&mp_const_none_obj) { + config.miso_pin = miso->number; + self->MISO_pin_number = mosi->number; + claim_pin(miso); + } else { + self->MISO_pin_number = NO_PIN; + } + + nrfx_err_t err = nrfx_spim_init(&self->spim_peripheral->spim, &config, NULL, NULL); + + // A soft reset doesn't uninit the driver so we might end up with a invalid state + if (err == NRFX_ERROR_INVALID_STATE) { + nrfx_spim_uninit(&self->spim_peripheral->spim); + err = nrfx_spim_init(&self->spim_peripheral->spim, &config, NULL, NULL); + } + + if (err != NRFX_SUCCESS) { + common_hal_busio_spi_deinit(self); + mp_raise_OSError(MP_EIO); + } +} + +bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { + return self->clock_pin_number == NO_PIN; +} + +void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { + if (common_hal_busio_spi_deinited(self)) + return; + + nrfx_spim_uninit(&self->spim_peripheral->spim); + + reset_pin_number(self->clock_pin_number); + reset_pin_number(self->MOSI_pin_number); + reset_pin_number(self->MISO_pin_number); +} + +bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { + // nrf52 does not support 16 bit + if (bits != 8) { + return false; + } + + // Set desired frequency, rounding down, and don't go above available frequency for this SPIM. + nrf_spim_frequency_set(self->spim_peripheral->spim.p_reg, + baudrate_to_spim_frequency(MIN(baudrate, + self->spim_peripheral->max_frequency_MHz * 1000000))); + + nrf_spim_mode_t mode = NRF_SPIM_MODE_0; + if (polarity) { + mode = (phase) ? NRF_SPIM_MODE_3 : NRF_SPIM_MODE_2; + } else { + mode = (phase) ? NRF_SPIM_MODE_1 : NRF_SPIM_MODE_0; + } + + nrf_spim_configure(self->spim_peripheral->spim.p_reg, mode, NRF_SPIM_BIT_ORDER_MSB_FIRST); + + return true; +} + +bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { + bool grabbed_lock = false; + // NRFX_CRITICAL_SECTION_ENTER(); + if (!self->has_lock) { + grabbed_lock = true; + self->has_lock = true; + } + // NRFX_CRITICAL_SECTION_EXIT(); + return grabbed_lock; +} + +bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self) { + return self->has_lock; +} + +void common_hal_busio_spi_unlock(busio_spi_obj_t *self) { + self->has_lock = false; +} + +bool common_hal_busio_spi_write(busio_spi_obj_t *self, const uint8_t *data, size_t len) { + if (len == 0) + return true; + + const uint32_t max_xfer_size = self->spim_peripheral->max_xfer_size; + const uint32_t parts = len / max_xfer_size; + const uint32_t remainder = len % max_xfer_size; + + for (uint32_t i = 0; i < parts; ++i) { + const nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_XFER_TX(data + i * max_xfer_size, max_xfer_size); + if (nrfx_spim_xfer(&self->spim_peripheral->spim, &xfer, 0) != NRFX_SUCCESS) + return false; + } + + if (remainder > 0) { + const nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_XFER_TX(data + parts * max_xfer_size, remainder); + if (nrfx_spim_xfer(&self->spim_peripheral->spim, &xfer, 0) != NRFX_SUCCESS) + return false; + } + + return true; +} + +bool common_hal_busio_spi_read(busio_spi_obj_t *self, uint8_t *data, size_t len, uint8_t write_value) { + if (len == 0) + return true; + + const uint32_t max_xfer_size = self->spim_peripheral->max_xfer_size; + const uint32_t parts = len / max_xfer_size; + const uint32_t remainder = len % max_xfer_size; + + for (uint32_t i = 0; i < parts; ++i) { + const nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_XFER_RX(data + i * max_xfer_size, max_xfer_size); + if (nrfx_spim_xfer(&self->spim_peripheral->spim, &xfer, 0) != NRFX_SUCCESS) + return false; + } + + if (remainder > 0) { + const nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_XFER_RX(data + parts * max_xfer_size, remainder); + if (nrfx_spim_xfer(&self->spim_peripheral->spim, &xfer, 0) != NRFX_SUCCESS) + return false; + } + + return true; +} + +bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_out, uint8_t *data_in, size_t len) { + if (len == 0) + return true; + + + const uint32_t max_xfer_size = self->spim_peripheral->max_xfer_size; + const uint32_t parts = len / max_xfer_size; + const uint32_t remainder = len % max_xfer_size; + + for (uint32_t i = 0; i < parts; ++i) { + const nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_SINGLE_XFER(data_out + i * max_xfer_size, max_xfer_size, + data_in + i * max_xfer_size, max_xfer_size); + if (nrfx_spim_xfer(&self->spim_peripheral->spim, &xfer, 0) != NRFX_SUCCESS) + return false; + } + + if (remainder > 0) { + const nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_SINGLE_XFER(data_out + parts * max_xfer_size, remainder, + data_in + parts * max_xfer_size, remainder); + if (nrfx_spim_xfer(&self->spim_peripheral->spim, &xfer, 0) != NRFX_SUCCESS) + return false; + } + + return true; +} + +uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t* self) { + switch (self->spim_peripheral->spim.p_reg->FREQUENCY) { + case NRF_SPIM_FREQ_125K: + return 125000; + case NRF_SPIM_FREQ_250K: + return 250000; + case NRF_SPIM_FREQ_500K: + return 500000; + case NRF_SPIM_FREQ_1M: + return 1000000; + case NRF_SPIM_FREQ_2M: + return 2000000; + case NRF_SPIM_FREQ_4M: + return 4000000; + case NRF_SPIM_FREQ_8M: + return 8000000; +#ifdef SPIM_FREQUENCY_FREQUENCY_M16 + case NRF_SPIM_FREQ_16M: + return 16000000; +#endif +#ifdef SPIM_FREQUENCY_FREQUENCY_M32 + case NRF_SPIM_FREQ_32M: + return 32000000; +#endif + default: + return 0; + } +} + +uint8_t common_hal_busio_spi_get_phase(busio_spi_obj_t* self) { + return 0; +} + +uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t* self) { + return 0; +} diff --git a/ports/nrf/common-hal/busio/SPI.h b/ports/nrf/common-hal/busio/SPI.h new file mode 100644 index 00000000000..1b0de8acfd7 --- /dev/null +++ b/ports/nrf/common-hal/busio/SPI.h @@ -0,0 +1,50 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_SPI_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_SPI_H + +#include "nrfx_spim.h" +#include "py/obj.h" + +typedef struct { + nrfx_spim_t spim; + uint8_t max_frequency_MHz; + uint8_t max_xfer_size; +} spim_peripheral_t; + +typedef struct { + mp_obj_base_t base; + spim_peripheral_t* spim_peripheral; + bool has_lock; + uint8_t clock_pin_number; + uint8_t MOSI_pin_number; + uint8_t MISO_pin_number; +} busio_spi_obj_t; + +void spi_reset(void); + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_SPI_H diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c new file mode 100644 index 00000000000..54a66ddbe77 --- /dev/null +++ b/ports/nrf/common-hal/busio/UART.c @@ -0,0 +1,326 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Ha Thach for Adafruit Industries + * + * 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 "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/busio/UART.h" + +#include "lib/utils/interrupt_char.h" +#include "py/mpconfig.h" +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "supervisor/shared/translate.h" + +#include "tick.h" +#include "nrfx_uarte.h" +#include + +// expression to examine, and return value in case of failing +#define _VERIFY_ERR(_exp) \ + do {\ + uint32_t _err = (_exp);\ + if (NRFX_SUCCESS != _err ) {\ + mp_raise_msg_varg(&mp_type_RuntimeError, translate("error = 0x%08lX"), _err);\ + }\ + }while(0) + +static nrfx_uarte_t nrfx_uartes[] = { +#if NRFX_CHECK(NRFX_UARTE0_ENABLED) + NRFX_UARTE_INSTANCE(0), +#endif +#if NRFX_CHECK(NRFX_UARTE1_ENABLED) + NRFX_UARTE_INSTANCE(1), +#endif +}; + +static uint32_t get_nrf_baud (uint32_t baudrate) { + + static const struct { + const uint32_t boundary; + nrf_uarte_baudrate_t uarte_baudraute; + } baudrate_map[] = { + { 1200, NRF_UARTE_BAUDRATE_1200 }, + { 2400, NRF_UARTE_BAUDRATE_2400 }, + { 4800, NRF_UARTE_BAUDRATE_4800 }, + { 9600, NRF_UARTE_BAUDRATE_9600 }, + { 14400, NRF_UARTE_BAUDRATE_14400 }, + { 19200, NRF_UARTE_BAUDRATE_19200 }, + { 28800, NRF_UARTE_BAUDRATE_28800 }, + { 38400, NRF_UARTE_BAUDRATE_38400 }, + { 57600, NRF_UARTE_BAUDRATE_57600 }, + { 76800, NRF_UARTE_BAUDRATE_76800 }, + { 115200, NRF_UARTE_BAUDRATE_115200 }, + { 230400, NRF_UARTE_BAUDRATE_230400 }, + { 250000, NRF_UARTE_BAUDRATE_250000 }, + { 460800, NRF_UARTE_BAUDRATE_460800 }, + { 921600, NRF_UARTE_BAUDRATE_921600 }, + { 0, NRF_UARTE_BAUDRATE_1000000 }, + }; + + size_t i = 0; + uint32_t boundary; + do { + boundary = baudrate_map[i].boundary; + if (baudrate <= boundary || boundary == 0) { + return baudrate_map[i].uarte_baudraute; + } + i++; + } while (true); +} + +static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context) { + busio_uart_obj_t* self = (busio_uart_obj_t*) context; + + switch ( event->type ) { + case NRFX_UARTE_EVT_RX_DONE: + ringbuf_put_n(&self->rbuf, event->data.rxtx.p_data, event->data.rxtx.bytes); + + // keep receiving + (void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1); + break; + + case NRFX_UARTE_EVT_TX_DONE: + // nothing to do + break; + + case NRFX_UARTE_EVT_ERROR: + // Possible Error source is Overrun, Parity, Framing, Break + // uint32_t errsrc = event->data.error.error_mask; + + ringbuf_put_n(&self->rbuf, event->data.error.rxtx.p_data, event->data.error.rxtx.bytes); + + // Keep receiving + (void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1); + break; + + default: + break; + } +} + +void uart_reset(void) { + for (size_t i = 0 ; i < MP_ARRAY_SIZE(nrfx_uartes); i++) { + nrf_uarte_disable(nrfx_uartes[i].p_reg); + } +} + +void common_hal_busio_uart_construct (busio_uart_obj_t *self, + const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, + uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout, + uint16_t receiver_buffer_size) { + // Find a free UART peripheral. + self->uarte = NULL; + for (size_t i = 0 ; i < MP_ARRAY_SIZE(nrfx_uartes); i++) { + if ((nrfx_uartes[i].p_reg->ENABLE & UARTE_ENABLE_ENABLE_Msk) == 0) { + self->uarte = &nrfx_uartes[i]; + break; + } + } + + if (self->uarte == NULL) { + mp_raise_ValueError(translate("All UART peripherals are in use")); + } + + if ( (tx == mp_const_none) && (rx == mp_const_none) ) { + mp_raise_ValueError(translate("tx and rx cannot both be None")); + } + + if ( receiver_buffer_size == 0 ) { + mp_raise_ValueError(translate("Invalid buffer size")); + } + + if ( parity == PARITY_ODD ) { + mp_raise_ValueError(translate("Odd parity is not supported")); + } + + nrfx_uarte_config_t config = { + .pseltxd = (tx == mp_const_none) ? NRF_UARTE_PSEL_DISCONNECTED : tx->number, + .pselrxd = (rx == mp_const_none) ? NRF_UARTE_PSEL_DISCONNECTED : rx->number, + .pselcts = NRF_UARTE_PSEL_DISCONNECTED, + .pselrts = NRF_UARTE_PSEL_DISCONNECTED, + .p_context = self, + .hwfc = NRF_UARTE_HWFC_DISABLED, + .parity = (parity == PARITY_NONE) ? NRF_UARTE_PARITY_EXCLUDED : NRF_UARTE_PARITY_INCLUDED, + .baudrate = get_nrf_baud(baudrate), + .interrupt_priority = 7 + }; + + nrfx_uarte_uninit(self->uarte); + _VERIFY_ERR(nrfx_uarte_init(self->uarte, &config, uart_callback_irq)); + + // Init buffer for rx + if ( rx != mp_const_none ) { + // Initially allocate the UART's buffer in the long-lived part of the + // heap. UARTs are generally long-lived objects, but the "make long- + // lived" machinery is incapable of moving internal pointers like + // self->buffer, so do it manually. (However, as long as internal + // pointers like this are NOT moved, allocating the buffer + // in the long-lived pool is not strictly necessary) + // (This is a macro.) + ringbuf_alloc(&self->rbuf, receiver_buffer_size, true); + + if ( !self->rbuf.buf ) { + nrfx_uarte_uninit(self->uarte); + mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer")); + } + + self->rx_pin_number = rx->number; + claim_pin(rx); + } + + if ( tx != mp_const_none ) { + self->tx_pin_number = tx->number; + claim_pin(tx); + } else { + self->tx_pin_number = NO_PIN; + } + + self->baudrate = baudrate; + self->timeout_ms = timeout * 1000; + + // Initial wait for incoming byte + _VERIFY_ERR(nrfx_uarte_rx(self->uarte, &self->rx_char, 1)); +} + +bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { + return self->rx_pin_number == NO_PIN; +} + +void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { + if ( !common_hal_busio_uart_deinited(self) ) { + nrfx_uarte_uninit(self->uarte); + reset_pin_number(self->tx_pin_number); + reset_pin_number(self->rx_pin_number); + self->tx_pin_number = NO_PIN; + self->rx_pin_number = NO_PIN; + + gc_free(self->rbuf.buf); + self->rbuf.size = 0; + self->rbuf.iput = self->rbuf.iget = 0; + } +} + +// Read characters. +size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { + if ( nrf_uarte_rx_pin_get(self->uarte->p_reg) == NRF_UARTE_PSEL_DISCONNECTED ) { + mp_raise_ValueError(translate("No RX pin")); + } + + size_t rx_bytes = 0; + uint64_t start_ticks = ticks_ms; + + // Wait for all bytes received or timeout + while ( (ringbuf_count(&self->rbuf) < len) && (ticks_ms - start_ticks < self->timeout_ms) ) { + RUN_BACKGROUND_TASKS; + // Allow user to break out of a timeout with a KeyboardInterrupt. + if ( mp_hal_is_interrupted() ) { + return 0; + } + } + + // prevent conflict with uart irq + NVIC_DisableIRQ(nrfx_get_irq_number(self->uarte->p_reg)); + + // copy received data + rx_bytes = ringbuf_count(&self->rbuf); + rx_bytes = MIN(rx_bytes, len); + for ( uint16_t i = 0; i < rx_bytes; i++ ) { + data[i] = ringbuf_get(&self->rbuf); + } + + NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte->p_reg)); + + return rx_bytes; +} + +// Write characters. +size_t common_hal_busio_uart_write (busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { + if ( nrf_uarte_tx_pin_get(self->uarte->p_reg) == NRF_UARTE_PSEL_DISCONNECTED ) { + mp_raise_ValueError(translate("No TX pin")); + } + + if ( len == 0 ) return 0; + + uint64_t start_ticks = ticks_ms; + + // Wait for on-going transfer to complete + while ( nrfx_uarte_tx_in_progress(self->uarte) && (ticks_ms - start_ticks < self->timeout_ms) ) { + RUN_BACKGROUND_TASKS; + } + + // Time up + if ( !(ticks_ms - start_ticks < self->timeout_ms) ) { + *errcode = MP_EAGAIN; + return MP_STREAM_ERROR; + } + + // EasyDMA can only access SRAM + uint8_t * tx_buf = (uint8_t*) data; + if ( !nrfx_is_in_ram(data) ) { + // TODO: If this is not too big, we could allocate it on the stack. + tx_buf = (uint8_t *) gc_alloc(len, false, false); + memcpy(tx_buf, data, len); + } + + (*errcode) = nrfx_uarte_tx(self->uarte, tx_buf, len); + _VERIFY_ERR(*errcode); + (*errcode) = 0; + + while ( nrfx_uarte_tx_in_progress(self->uarte) && (ticks_ms - start_ticks < self->timeout_ms) ) { + RUN_BACKGROUND_TASKS; + } + + if ( !nrfx_is_in_ram(data) ) { + gc_free(tx_buf); + } + + return len; +} + +uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) { + return self->baudrate; +} + +void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) { + self->baudrate = baudrate; + nrf_uarte_baudrate_set(self->uarte->p_reg, get_nrf_baud(baudrate)); +} + +uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { + return ringbuf_count(&self->rbuf); +} + +void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) { + // prevent conflict with uart irq + NVIC_DisableIRQ(nrfx_get_irq_number(self->uarte->p_reg)); + ringbuf_clear(&self->rbuf); + NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte->p_reg)); +} + +bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { + return !nrfx_uarte_tx_in_progress(self->uarte); +} diff --git a/ports/nrf/common-hal/busio/UART.h b/ports/nrf/common-hal/busio/UART.h new file mode 100644 index 00000000000..58432001cd7 --- /dev/null +++ b/ports/nrf/common-hal/busio/UART.h @@ -0,0 +1,53 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_UART_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_UART_H + +#include "common-hal/microcontroller/Pin.h" +#include "nrfx_uarte.h" + +#include "py/obj.h" +#include "py/ringbuf.h" + +typedef struct { + mp_obj_base_t base; + + nrfx_uarte_t *uarte; + + uint32_t baudrate; + uint32_t timeout_ms; + + ringbuf_t rbuf; + uint8_t rx_char; // EasyDMA buf + + uint8_t tx_pin_number; + uint8_t rx_pin_number; +} busio_uart_obj_t; + +void uart_reset(void); + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_UART_H diff --git a/ports/nrf/common-hal/busio/__init__.c b/ports/nrf/common-hal/busio/__init__.c new file mode 100644 index 00000000000..41761b6743a --- /dev/null +++ b/ports/nrf/common-hal/busio/__init__.c @@ -0,0 +1 @@ +// No busio module functions. diff --git a/ports/nrf/common-hal/digitalio/DigitalInOut.c b/ports/nrf/common-hal/digitalio/DigitalInOut.c new file mode 100644 index 00000000000..0836962c631 --- /dev/null +++ b/ports/nrf/common-hal/digitalio/DigitalInOut.c @@ -0,0 +1,158 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/digitalio/DigitalInOut.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +#include "nrf_gpio.h" + +void common_hal_digitalio_digitalinout_never_reset( + digitalio_digitalinout_obj_t *self) { + never_reset_pin_number(self->pin->number); +} + +digitalinout_result_t common_hal_digitalio_digitalinout_construct( + digitalio_digitalinout_obj_t *self, const mcu_pin_obj_t *pin) { + claim_pin(pin); + self->pin = pin; + + nrf_gpio_cfg_input(pin->number, NRF_GPIO_PIN_NOPULL); + + return DIGITALINOUT_OK; +} + +bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t *self) { + return self->pin == mp_const_none; +} + +void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self) { + if (common_hal_digitalio_digitalinout_deinited(self)) { + return; + } + nrf_gpio_cfg_default(self->pin->number); + + reset_pin_number(self->pin->number); + self->pin = mp_const_none; +} + +void common_hal_digitalio_digitalinout_switch_to_input( + digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { + nrf_gpio_cfg_input(self->pin->number, NRF_GPIO_PIN_NOPULL); + common_hal_digitalio_digitalinout_set_pull(self, pull); +} + +void common_hal_digitalio_digitalinout_switch_to_output( + digitalio_digitalinout_obj_t *self, bool value, + digitalio_drive_mode_t drive_mode) { + + common_hal_digitalio_digitalinout_set_drive_mode(self, drive_mode); + common_hal_digitalio_digitalinout_set_value(self, value); +} + +digitalio_direction_t common_hal_digitalio_digitalinout_get_direction( + digitalio_digitalinout_obj_t *self) { + + return (nrf_gpio_pin_dir_get(self->pin->number) == NRF_GPIO_PIN_DIR_INPUT) + ? DIRECTION_INPUT : DIRECTION_OUTPUT; +} + +void common_hal_digitalio_digitalinout_set_value( + digitalio_digitalinout_obj_t *self, bool value) { + nrf_gpio_pin_write(self->pin->number, value); +} + +bool common_hal_digitalio_digitalinout_get_value( + digitalio_digitalinout_obj_t *self) { + return (nrf_gpio_pin_dir_get(self->pin->number) == NRF_GPIO_PIN_DIR_INPUT) + ? nrf_gpio_pin_read(self->pin->number) + : nrf_gpio_pin_out_read(self->pin->number); +} + +void common_hal_digitalio_digitalinout_set_drive_mode( + digitalio_digitalinout_obj_t *self, + digitalio_drive_mode_t drive_mode) { + nrf_gpio_cfg(self->pin->number, + NRF_GPIO_PIN_DIR_OUTPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_NOPULL, + drive_mode == DRIVE_MODE_OPEN_DRAIN ? NRF_GPIO_PIN_H0D1 : NRF_GPIO_PIN_H0H1, + NRF_GPIO_PIN_NOSENSE); +} + +digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( + digitalio_digitalinout_obj_t *self) { + uint32_t pin = self->pin->number; + // Changes pin to be a relative pin number in port. + NRF_GPIO_Type *reg = nrf_gpio_pin_port_decode(&pin); + + switch ((reg->PIN_CNF[pin] & GPIO_PIN_CNF_DRIVE_Msk) >> GPIO_PIN_CNF_DRIVE_Pos) { + case NRF_GPIO_PIN_S0D1: + case NRF_GPIO_PIN_H0D1: + return DRIVE_MODE_OPEN_DRAIN; + default: + return DRIVE_MODE_PUSH_PULL; + } +} + +void common_hal_digitalio_digitalinout_set_pull( + digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { + nrf_gpio_pin_pull_t hal_pull = NRF_GPIO_PIN_NOPULL; + + switch (pull) { + case PULL_UP: + hal_pull = NRF_GPIO_PIN_PULLUP; + break; + case PULL_DOWN: + hal_pull = NRF_GPIO_PIN_PULLDOWN; + break; + case PULL_NONE: + default: + break; + } + + nrf_gpio_cfg_input(self->pin->number, hal_pull); +} + +digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( + digitalio_digitalinout_obj_t *self) { + uint32_t pin = self->pin->number; + // Changes pin to be a relative pin number in port. + NRF_GPIO_Type *reg = nrf_gpio_pin_port_decode(&pin); + + if (nrf_gpio_pin_dir_get(self->pin->number) == NRF_GPIO_PIN_DIR_OUTPUT) { + mp_raise_AttributeError(translate("Cannot get pull while in output mode")); + } + + switch ((reg->PIN_CNF[pin] & GPIO_PIN_CNF_PULL_Msk) >> GPIO_PIN_CNF_PULL_Pos) { + case NRF_GPIO_PIN_PULLUP: + return PULL_UP; + case NRF_GPIO_PIN_PULLDOWN: + return PULL_DOWN; + default: + return PULL_NONE; + } +} diff --git a/ports/nrf/common-hal/digitalio/DigitalInOut.h b/ports/nrf/common-hal/digitalio/DigitalInOut.h new file mode 100644 index 00000000000..9122ba4a13f --- /dev/null +++ b/ports/nrf/common-hal/digitalio/DigitalInOut.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_DIGITALIO_DIGITALINOUT_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_DIGITALIO_DIGITALINOUT_H + +#include "common-hal/microcontroller/Pin.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t *pin; +} digitalio_digitalinout_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_DIGITALIO_DIGITALINOUT_H diff --git a/ports/nrf/common-hal/digitalio/__init__.c b/ports/nrf/common-hal/digitalio/__init__.c new file mode 100644 index 00000000000..20fad459593 --- /dev/null +++ b/ports/nrf/common-hal/digitalio/__init__.c @@ -0,0 +1 @@ +// No digitalio module functions. diff --git a/ports/nrf/common-hal/displayio/ParallelBus.c b/ports/nrf/common-hal/displayio/ParallelBus.c new file mode 100644 index 00000000000..be4b28a6e6b --- /dev/null +++ b/ports/nrf/common-hal/displayio/ParallelBus.c @@ -0,0 +1,162 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/ParallelBus.h" + +#include + +#include "common-hal/microcontroller/Pin.h" +#include "py/runtime.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/microcontroller/__init__.h" + +#include "tick.h" + +void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self, + const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select, + const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset) { + + uint8_t data_pin = data0->number; + if (data_pin % 8 != 0) { + mp_raise_ValueError(translate("Data 0 pin must be byte aligned")); + } + for (uint8_t i = 0; i < 8; i++) { + if (!pin_number_is_free(data_pin + i)) { + mp_raise_ValueError_varg(translate("Bus pin %d is already in use"), i); + } + } + NRF_GPIO_Type *g; + uint8_t num_pins_in_port; + if (data0->number < P0_PIN_NUM) { + g = NRF_P0; + num_pins_in_port = P0_PIN_NUM; + } else { + g = NRF_P1; + num_pins_in_port = P1_PIN_NUM; + } + g->DIRSET = 0xff << (data_pin % num_pins_in_port); + for (uint8_t i = 0; i < 8; i++) { + g->PIN_CNF[data_pin + i] |= NRF_GPIO_PIN_S0S1 << GPIO_PIN_CNF_DRIVE_Pos; + } + self->bus = ((uint8_t*) &g->OUT) + (data0->number % num_pins_in_port / 8); + + self->command.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->command, command); + common_hal_digitalio_digitalinout_switch_to_output(&self->command, true, DRIVE_MODE_PUSH_PULL); + + self->chip_select.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); + common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL); + + self->write.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->write, write); + common_hal_digitalio_digitalinout_switch_to_output(&self->write, true, DRIVE_MODE_PUSH_PULL); + + self->read.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->read, read); + common_hal_digitalio_digitalinout_switch_to_output(&self->read, true, DRIVE_MODE_PUSH_PULL); + + self->data0_pin = data_pin; + uint8_t num_pins_in_write_port; + if (data0->number < P0_PIN_NUM) { + self->write_group = NRF_P0; + num_pins_in_write_port = P0_PIN_NUM; + } else { + self->write_group = NRF_P1; + num_pins_in_write_port = P1_PIN_NUM; + } + self->write_mask = 1 << (write->number % num_pins_in_write_port); + + self->reset.base.type = &mp_type_NoneType; + if (reset != NULL) { + self->reset.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->reset, reset); + common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); + never_reset_pin_number(reset->number); + common_hal_displayio_parallelbus_reset(self); + } + + never_reset_pin_number(command->number); + never_reset_pin_number(chip_select->number); + never_reset_pin_number(write->number); + never_reset_pin_number(read->number); + for (uint8_t i = 0; i < 8; i++) { + never_reset_pin_number(data_pin + i); + } +} + +void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self) { + for (uint8_t i = 0; i < 8; i++) { + reset_pin_number(self->data0_pin + i); + } + + reset_pin_number(self->command.pin->number); + reset_pin_number(self->chip_select.pin->number); + reset_pin_number(self->write.pin->number); + reset_pin_number(self->read.pin->number); + reset_pin_number(self->reset.pin->number); +} + +bool common_hal_displayio_parallelbus_reset(mp_obj_t obj) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + if (self->reset.base.type == &mp_type_NoneType) { + return false; + } + + common_hal_digitalio_digitalinout_set_value(&self->reset, false); + common_hal_mcu_delay_us(4); + common_hal_digitalio_digitalinout_set_value(&self->reset, true); + return true; +} + +bool common_hal_displayio_parallelbus_bus_free(mp_obj_t obj) { + return true; +} + +bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); + return true; +} + +// This ignores chip_select behaviour because data is clocked in by the write line toggling. +void common_hal_displayio_parallelbus_send(mp_obj_t obj, display_byte_type_t byte_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->command, byte_type == DISPLAY_DATA); + uint32_t* clear_write = (uint32_t*) &self->write_group->OUTCLR; + uint32_t* set_write = (uint32_t*) &self->write_group->OUTSET; + uint32_t mask = self->write_mask; + for (uint32_t i = 0; i < data_length; i++) { + *clear_write = mask; + *self->bus = data[i]; + *set_write = mask; + } +} + +void common_hal_displayio_parallelbus_end_transaction(mp_obj_t obj) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); +} diff --git a/ports/nrf/common-hal/displayio/ParallelBus.h b/ports/nrf/common-hal/displayio/ParallelBus.h new file mode 100644 index 00000000000..5c10d3d42a9 --- /dev/null +++ b/ports/nrf/common-hal/displayio/ParallelBus.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_DISPLAYIO_PARALLELBUS_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_DISPLAYIO_PARALLELBUS_H + +#include "common-hal/digitalio/DigitalInOut.h" + +typedef struct { + mp_obj_base_t base; + uint8_t* bus; + digitalio_digitalinout_obj_t command; + digitalio_digitalinout_obj_t chip_select; + digitalio_digitalinout_obj_t reset; + digitalio_digitalinout_obj_t write; + digitalio_digitalinout_obj_t read; + uint8_t data0_pin; + NRF_GPIO_Type* write_group; + uint32_t write_mask; +} displayio_parallelbus_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_DISPLAYIO_PARALLELBUS_H diff --git a/ports/nrf/common-hal/microcontroller/Pin.c b/ports/nrf/common-hal/microcontroller/Pin.c new file mode 100644 index 00000000000..3cee784b63a --- /dev/null +++ b/ports/nrf/common-hal/microcontroller/Pin.c @@ -0,0 +1,182 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/microcontroller/Pin.h" + +#include "nrf_gpio.h" +#include "py/mphal.h" + +#include "nrf/pins.h" +#include "supervisor/shared/rgb_led_status.h" + +#ifdef MICROPY_HW_NEOPIXEL +bool neopixel_in_use; +#endif +#ifdef MICROPY_HW_APA102_MOSI +bool apa102_sck_in_use; +bool apa102_mosi_in_use; +#endif +#ifdef SPEAKER_ENABLE_PIN +bool speaker_enable_in_use; +#endif + +// Bit mask of claimed pins on each of up to two ports. nrf52832 has one port; nrf52840 has two. +STATIC uint32_t claimed_pins[GPIO_COUNT]; +STATIC uint32_t never_reset_pins[GPIO_COUNT]; + +void reset_all_pins(void) { + for (size_t i = 0; i < GPIO_COUNT; i++) { + claimed_pins[i] = never_reset_pins[i]; + } + + for (uint32_t pin = 0; pin < NUMBER_OF_PINS; ++pin) { + if ((never_reset_pins[nrf_pin_port(pin)] & (1 << nrf_relative_pin_number(pin))) != 0) { + continue; + } + nrf_gpio_cfg_default(pin); + } + + #ifdef MICROPY_HW_NEOPIXEL + neopixel_in_use = false; + #endif + #ifdef MICROPY_HW_APA102_MOSI + apa102_sck_in_use = false; + apa102_mosi_in_use = false; + #endif + + // After configuring SWD because it may be shared. + #ifdef SPEAKER_ENABLE_PIN + speaker_enable_in_use = false; + // TODO set pin to out and turn off. + #endif +} + +// Mark pin as free and return it to a quiescent state. +void reset_pin_number(uint8_t pin_number) { + if (pin_number == NO_PIN) { + return; + } + + // Clear claimed bit. + claimed_pins[nrf_pin_port(pin_number)] &= ~(1 << nrf_relative_pin_number(pin_number)); + + #ifdef MICROPY_HW_NEOPIXEL + if (pin_number == MICROPY_HW_NEOPIXEL->number) { + neopixel_in_use = false; + rgb_led_status_init(); + return; + } + #endif + #ifdef MICROPY_HW_APA102_MOSI + if (pin == MICROPY_HW_APA102_MOSI->number || + pin == MICROPY_HW_APA102_SCK->number) { + apa102_mosi_in_use = apa102_mosi_in_use && pin_number != MICROPY_HW_APA102_MOSI->number; + apa102_sck_in_use = apa102_sck_in_use && pin_number != MICROPY_HW_APA102_SCK->number; + if (!apa102_sck_in_use && !apa102_mosi_in_use) { + rgb_led_status_init(); + } + return; + } + #endif + + #ifdef SPEAKER_ENABLE_PIN + if (pin_number == SPEAKER_ENABLE_PIN->number) { + speaker_enable_in_use = false; + common_hal_digitalio_digitalinout_switch_to_output(SPEAKER_ENABLE_PIN, true, DRIVE_MODE_PUSH_PULL); + nrf_gpio_pin_dir_set(pin_number, NRF_GPIO_PIN_DIR_OUTPUT); + nrf_gpio_pin_write(pin_number, false); + } + #endif +} + + +void never_reset_pin_number(uint8_t pin_number) { + never_reset_pins[nrf_pin_port(pin_number)] |= 1 << nrf_relative_pin_number(pin_number); +} + +void claim_pin(const mcu_pin_obj_t* pin) { + // Set bit in claimed_pins bitmask. + claimed_pins[nrf_pin_port(pin->number)] |= 1 << nrf_relative_pin_number(pin->number); + + #ifdef MICROPY_HW_NEOPIXEL + if (pin == MICROPY_HW_NEOPIXEL) { + neopixel_in_use = true; + } + #endif + #ifdef MICROPY_HW_APA102_MOSI + if (pin == MICROPY_HW_APA102_MOSI) { + apa102_mosi_in_use = true; + } + if (pin == MICROPY_HW_APA102_SCK) { + apa102_sck_in_use = true; + } + #endif + + #ifdef SPEAKER_ENABLE_PIN + if (pin == SPEAKER_ENABLE_PIN) { + speaker_enable_in_use = true; + } + #endif +} + + +bool pin_number_is_free(uint8_t pin_number) { + return !(claimed_pins[nrf_pin_port(pin_number)] & (1 << nrf_relative_pin_number(pin_number))); +} + +bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) { + #ifdef MICROPY_HW_NEOPIXEL + if (pin == MICROPY_HW_NEOPIXEL) { + return !neopixel_in_use; + } + #endif + #ifdef MICROPY_HW_APA102_MOSI + if (pin == MICROPY_HW_APA102_MOSI) { + return !apa102_mosi_in_use; + } + if (pin == MICROPY_HW_APA102_SCK) { + return !apa102_sck_in_use; + } + #endif + + #ifdef SPEAKER_ENABLE_PIN + if (pin == SPEAKER_ENABLE_PIN) { + return !speaker_enable_in_use; + } + #endif + + #ifdef NRF52840 + // If NFC pins are enabled for NFC, don't allow them to be used for GPIO. + if (((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == + (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)) && + (pin->number == 9 || pin->number == 10)) { + return false; + } + #endif + + return pin_number_is_free(pin->number); + +} diff --git a/ports/nrf/common-hal/microcontroller/Pin.h b/ports/nrf/common-hal/microcontroller/Pin.h new file mode 100644 index 00000000000..735ed90ccaf --- /dev/null +++ b/ports/nrf/common-hal/microcontroller/Pin.h @@ -0,0 +1,61 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_MICROCONTROLLER_PIN_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_MICROCONTROLLER_PIN_H + +#include "py/mphal.h" + +#include "peripherals/nrf/pins.h" + +#ifdef MICROPY_HW_NEOPIXEL +extern bool neopixel_in_use; +#endif +#ifdef MICROPY_HW_APA102_MOSI +extern bool apa102_sck_in_use; +extern bool apa102_mosi_in_use; +#endif + +void reset_all_pins(void); +// reset_pin_number takes the pin number instead of the pointer so that objects don't +// need to store a full pointer. +void reset_pin_number(uint8_t pin); +void claim_pin(const mcu_pin_obj_t* pin); +bool pin_number_is_free(uint8_t pin_number); +void never_reset_pin_number(uint8_t pin_number); + +// Lower 5 bits of a pin number are the pin number in a port. +// upper bits (just one bit for current chips) is port number. + +static inline uint8_t nrf_pin_port(uint8_t absolute_pin) { + return absolute_pin >> 5; +} + +static inline uint8_t nrf_relative_pin_number(uint8_t absolute_pin) { + return absolute_pin & 0x1f; +} + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_MICROCONTROLLER_PIN_H diff --git a/ports/nrf/common-hal/microcontroller/Processor.c b/ports/nrf/common-hal/microcontroller/Processor.c new file mode 100644 index 00000000000..836020d1590 --- /dev/null +++ b/ports/nrf/common-hal/microcontroller/Processor.c @@ -0,0 +1,75 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert for Adafruit Industries + * + * 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 "common-hal/microcontroller/Processor.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +#ifdef BLUETOOTH_SD +#include "nrf_sdm.h" +#endif + +#include "nrf.h" + +float common_hal_mcu_processor_get_temperature(void) { + int32_t temp = 0; + +#ifdef BLUETOOTH_SD + uint8_t sd_en = 0; + + (void) sd_softdevice_is_enabled(&sd_en); + + if (sd_en) { + uint32_t err_code = sd_temp_get(&temp); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg(translate("Cannot get temperature")); + } + } +#endif + + NRF_TEMP->TASKS_START = 1; + + while (NRF_TEMP->EVENTS_DATARDY == 0) + ; + + NRF_TEMP->EVENTS_DATARDY = 0; + + temp = NRF_TEMP->TEMP; + + NRF_TEMP->TASKS_STOP = 1; + + return temp / 4.0f; +} + +uint32_t common_hal_mcu_processor_get_frequency(void) { + return 64000000ul; +} + +void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { + for (int i=0; i<2; i++) { + ((uint32_t*) raw_id)[i] = NRF_FICR->DEVICEID[i]; + } +} diff --git a/ports/nrf/common-hal/microcontroller/Processor.h b/ports/nrf/common-hal/microcontroller/Processor.h new file mode 100644 index 00000000000..4049c165fb7 --- /dev/null +++ b/ports/nrf/common-hal/microcontroller/Processor.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H + +#define COMMON_HAL_MCU_PROCESSOR_UID_LENGTH 8 + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + // Stores no state currently. +} mcu_processor_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H diff --git a/ports/nrf/common-hal/microcontroller/__init__.c b/ports/nrf/common-hal/microcontroller/__init__.c new file mode 100644 index 00000000000..a6b1c4ba3b1 --- /dev/null +++ b/ports/nrf/common-hal/microcontroller/__init__.c @@ -0,0 +1,139 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "py/mphal.h" +#include "py/obj.h" +#include "py/runtime.h" + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/microcontroller/Processor.h" + +#include "shared-bindings/nvm/ByteArray.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/Processor.h" + +#include "supervisor/filesystem.h" +#include "supervisor/shared/safe_mode.h" +#include "nrfx_glue.h" + +// This routine should work even when interrupts are disabled. Used by OneWire +// for precise timing. +void common_hal_mcu_delay_us(uint32_t delay) { + NRFX_DELAY_US(delay); +} + +void common_hal_mcu_disable_interrupts() { +} + +void common_hal_mcu_enable_interrupts() { +} + +void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { + enum { DFU_MAGIC_UF2_RESET = 0x57 }; + if(runmode == RUNMODE_BOOTLOADER) + NRF_POWER->GPREGRET = DFU_MAGIC_UF2_RESET; + else + NRF_POWER->GPREGRET = 0; + if(runmode == RUNMODE_SAFE_MODE) + safe_mode_on_next_reset(PROGRAMMATIC_SAFE_MODE); +} + +void common_hal_mcu_reset(void) { + filesystem_flush(); + NVIC_SystemReset(); +} + +// The singleton microcontroller.Processor object, bound to microcontroller.cpu +// It currently only has properties, and no state. +const mcu_processor_obj_t common_hal_mcu_processor_obj = { + .base = { + .type = &mcu_processor_type, + }, +}; + +#if CIRCUITPY_INTERNAL_NVM_SIZE > 0 +// The singleton nvm.ByteArray object. +const nvm_bytearray_obj_t common_hal_mcu_nvm_obj = { + .base = { + .type = &nvm_bytearray_type, + }, +}; +#endif + +STATIC const mp_rom_map_elem_t mcu_pin_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_P0_00), MP_ROM_PTR(&pin_P0_00) }, + { MP_ROM_QSTR(MP_QSTR_P0_01), MP_ROM_PTR(&pin_P0_01) }, + { MP_ROM_QSTR(MP_QSTR_P0_02), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_P0_03), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_P0_04), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_P0_05), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_P0_06), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_P0_07), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_P0_08), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_P0_09), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_P0_10), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_P0_11), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_P0_12), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_P0_13), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_P0_14), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_P0_15), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_P0_16), MP_ROM_PTR(&pin_P0_16) }, + { MP_ROM_QSTR(MP_QSTR_P0_17), MP_ROM_PTR(&pin_P0_17) }, + { MP_ROM_QSTR(MP_QSTR_P0_18), MP_ROM_PTR(&pin_P0_18) }, + { MP_ROM_QSTR(MP_QSTR_P0_19), MP_ROM_PTR(&pin_P0_19) }, + { MP_ROM_QSTR(MP_QSTR_P0_20), MP_ROM_PTR(&pin_P0_20) }, + { MP_ROM_QSTR(MP_QSTR_P0_21), MP_ROM_PTR(&pin_P0_21) }, + { MP_ROM_QSTR(MP_QSTR_P0_22), MP_ROM_PTR(&pin_P0_22) }, + { MP_ROM_QSTR(MP_QSTR_P0_23), MP_ROM_PTR(&pin_P0_23) }, + { MP_ROM_QSTR(MP_QSTR_P0_24), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_P0_25), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_P0_26), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_P0_27), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_P0_28), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_P0_29), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_P0_30), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_P0_31), MP_ROM_PTR(&pin_P0_31) }, +#ifdef NRF52840 + { MP_ROM_QSTR(MP_QSTR_P1_00), MP_ROM_PTR(&pin_P1_00) }, + { MP_ROM_QSTR(MP_QSTR_P1_01), MP_ROM_PTR(&pin_P1_01) }, + { MP_ROM_QSTR(MP_QSTR_P1_02), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_P1_03), MP_ROM_PTR(&pin_P1_03) }, + { MP_ROM_QSTR(MP_QSTR_P1_04), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_P1_05), MP_ROM_PTR(&pin_P1_05) }, + { MP_ROM_QSTR(MP_QSTR_P1_06), MP_ROM_PTR(&pin_P1_06) }, + { MP_ROM_QSTR(MP_QSTR_P1_07), MP_ROM_PTR(&pin_P1_07) }, + { MP_ROM_QSTR(MP_QSTR_P1_08), MP_ROM_PTR(&pin_P1_08) }, + { MP_ROM_QSTR(MP_QSTR_P1_09), MP_ROM_PTR(&pin_P1_09) }, + { MP_ROM_QSTR(MP_QSTR_P1_10), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_P1_11), MP_ROM_PTR(&pin_P1_11) }, + { MP_ROM_QSTR(MP_QSTR_P1_12), MP_ROM_PTR(&pin_P1_12) }, + { MP_ROM_QSTR(MP_QSTR_P1_13), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_P1_14), MP_ROM_PTR(&pin_P1_14) }, + { MP_ROM_QSTR(MP_QSTR_P1_15), MP_ROM_PTR(&pin_P1_15) }, +#endif +}; +MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_globals_table); diff --git a/ports/nrf/common-hal/neopixel_write/__init__.c b/ports/nrf/common-hal/neopixel_write/__init__.c new file mode 100644 index 00000000000..3b67778a622 --- /dev/null +++ b/ports/nrf/common-hal/neopixel_write/__init__.c @@ -0,0 +1,297 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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 "py/mphal.h" +#include "shared-bindings/neopixel_write/__init__.h" +#include "nrf_pwm.h" + +#include "tick.h" + +// https://github.com/adafruit/Adafruit_NeoPixel/blob/master/Adafruit_NeoPixel.cpp +// [[[Begin of the Neopixel NRF52 EasyDMA implementation +// by the Hackerspace San Salvador]]] +// This technique uses the PWM peripheral on the NRF52. The PWM uses the +// EasyDMA feature included on the chip. This technique loads the duty +// cycle configuration for each cycle when the PWM is enabled. For this +// to work we need to store a 16 bit configuration for each bit of the +// RGB(W) values in the pixel buffer. +// Comparator values for the PWM were hand picked and are guaranteed to +// be 100% organic to preserve freshness and high accuracy. Current +// parameters are: +// * PWM Clock: 16Mhz +// * Minimum step time: 62.5ns +// * Time for zero in high (T0H): 0.31ms +// * Time for one in high (T1H): 0.75ms +// * Cycle time: 1.25us +// * Frequency: 800Khz +// For 400Khz we just double the calculated times. +// ---------- BEGIN Constants for the EasyDMA implementation ----------- +// The PWM starts the duty cycle in LOW. To start with HIGH we +// need to set the 15th bit on each register. + +// WS2812 (rev A) timing is 0.35 and 0.7us +//#define MAGIC_T0H 5UL | (0x8000) // 0.3125us +//#define MAGIC_T1H 12UL | (0x8000) // 0.75us + +// WS2812B (rev B) timing is 0.4 and 0.8 us +#define MAGIC_T0H 6UL | (0x8000) // 0.375us +#define MAGIC_T1H 13UL | (0x8000) // 0.8125us +#define CTOPVAL 20UL // 1.25us + +// ---------- END Constants for the EasyDMA implementation ------------- +// +// If there is no device available an alternative cycle-counter +// implementation is tried. +// The nRF52840 runs with a fixed clock of 64Mhz. The alternative +// implementation is the same as the one used for the Teensy 3.0/1/2 but +// with the Nordic SDK HAL & registers syntax. +// The number of cycles was hand picked and is guaranteed to be 100% +// organic to preserve freshness and high accuracy. +// ---------- BEGIN Constants for cycle counter implementation --------- +#define CYCLES_800_T0H 18 // ~0.36 uS +#define CYCLES_800_T1H 41 // ~0.76 uS +#define CYCLES_800 71 // ~1.25 uS + +// ---------- END of Constants for cycle counter implementation -------- + +// find a free PWM device, which is not enabled and has no connected pins +static NRF_PWM_Type* find_free_pwm (void) { + NRF_PWM_Type* PWM[] = { + NRF_PWM0, NRF_PWM1, NRF_PWM2 +#ifdef NRF_PWM3 + , NRF_PWM3 +#endif + }; + + for ( size_t device = 0; device < ARRAY_SIZE(PWM); device++ ) { + if ( (PWM[device]->ENABLE == 0) && + (PWM[device]->PSEL.OUT[0] & PWM_PSEL_OUT_CONNECT_Msk) && (PWM[device]->PSEL.OUT[1] & PWM_PSEL_OUT_CONNECT_Msk) && + (PWM[device]->PSEL.OUT[2] & PWM_PSEL_OUT_CONNECT_Msk) && (PWM[device]->PSEL.OUT[3] & PWM_PSEL_OUT_CONNECT_Msk) ) { + return PWM[device]; + } + } + + return NULL; +} + +uint64_t next_start_tick_ms = 0; +uint32_t next_start_tick_us = 1000; + +void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout, uint8_t *pixels, uint32_t numBytes) { + // To support both the SoftDevice + Neopixels we use the EasyDMA + // feature from the NRF25. However this technique implies to + // generate a pattern and store it on the memory. The actual + // memory used in bytes corresponds to the following formula: + // totalMem = numBytes*8*2+(2*2) + // The two additional bytes at the end are needed to reset the + // sequence. + // + // If there is not enough memory, we will fall back to cycle counter + // using DWT + +#define PATTERN_SIZE(numBytes) (numBytes * 8 * sizeof(uint16_t) + 2 * sizeof(uint16_t)) + + uint32_t pattern_size = PATTERN_SIZE(numBytes); + uint16_t* pixels_pattern = NULL; + bool pattern_on_heap = false; + + // Use the stack to store 1 pixels worth of PWM data for the status led. uint32_t to ensure alignment. + // Make it at least as big as PATTERN_SIZE(3), for one pixel of RGB data. + // PATTERN_SIZE is a multiple of 4, so we don't need round up to make sure one_pixel is large enough. + uint32_t one_pixel[PATTERN_SIZE(3)/sizeof(uint32_t)]; + + NRF_PWM_Type* pwm = find_free_pwm(); + + // only malloc if there is PWM device available + if ( pwm != NULL ) { + if (pattern_size <= sizeof(one_pixel)) { + pixels_pattern = (uint16_t *) one_pixel; + } else { + pixels_pattern = (uint16_t *) m_malloc_maybe(pattern_size, false); + pattern_on_heap = true; + } + } + + // Wait to make sure we don't append onto the last transmission. + wait_until(next_start_tick_ms, next_start_tick_us); + + // Use the identified device to choose the implementation + // If a PWM device is available use DMA + if ( (pixels_pattern != NULL) && (pwm != NULL) ) { + uint16_t pos = 0; // bit position + + for ( uint16_t n = 0; n < numBytes; n++ ) { + uint8_t pix = pixels[n]; + + for ( uint8_t mask = 0x80; mask > 0; mask >>= 1 ) { + pixels_pattern[pos] = (pix & mask) ? MAGIC_T1H : MAGIC_T0H; + pos++; + } + } + + // Zero padding to indicate the end of sequence + pixels_pattern[pos++] = 0 | (0x8000); // Seq end + pixels_pattern[pos++] = 0 | (0x8000); // Seq end + + // Set the wave mode to count UP + // Set the PWM to use the 16MHz clock + // Setting of the maximum count + // but keeping it on 16Mhz allows for more granularity just + // in case someone wants to do more fine-tuning of the timing. + nrf_pwm_configure(pwm, NRF_PWM_CLK_16MHz, NRF_PWM_MODE_UP, CTOPVAL); + + // Disable loops, we want the sequence to repeat only once + nrf_pwm_loop_set(pwm, 0); + + // On the "Common" setting the PWM uses the same pattern for the + // for supported sequences. The pattern is stored on half-word of 16bits + nrf_pwm_decoder_set(pwm, PWM_DECODER_LOAD_Common, PWM_DECODER_MODE_RefreshCount); + + // Pointer to the memory storing the pattern + nrf_pwm_seq_ptr_set(pwm, 0, pixels_pattern); + + // Calculation of the number of steps loaded from memory. + nrf_pwm_seq_cnt_set(pwm, 0, pattern_size / sizeof(uint16_t)); + + // The following settings are ignored with the current config. + nrf_pwm_seq_refresh_set(pwm, 0, 0); + nrf_pwm_seq_end_delay_set(pwm, 0, 0); + + // The Neopixel implementation is a blocking algorithm. DMA + // allows for non-blocking operation. To "simulate" a blocking + // operation we enable the interruption for the end of sequence + // and block the execution thread until the event flag is set by + // the peripheral. + // pwm->INTEN |= (PWM_INTEN_SEQEND0_Enabled<pin->number, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL} ); + + // Enable the PWM + nrf_pwm_enable(pwm); + + // After all of this and many hours of reading the documentation + // we are ready to start the sequence... + nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQEND0); + nrf_pwm_task_trigger(pwm, NRF_PWM_TASK_SEQSTART0); + + // But we have to wait for the flag to be set. + while ( !nrf_pwm_event_check(pwm, NRF_PWM_EVENT_SEQEND0) ) { + RUN_BACKGROUND_TASKS; + } + + // Before leave we clear the flag for the event. + nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQEND0); + + // We need to disable the device and disconnect + // all the outputs before leave or the device will not + // be selected on the next call. + // TODO: Check if disabling the device causes performance issues. + nrf_pwm_disable(pwm); + nrf_pwm_pins_set(pwm, (uint32_t[]) {0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL} ); + + if (pattern_on_heap) { + m_free(pixels_pattern); + } + + } // End of DMA implementation + // --------------------------------------------------------------------- + else { + // Fall back to DWT + // If you are using the Bluetooth SoftDevice we advise you to not disable + // the interrupts. Disabling the interrupts even for short periods of time + // causes the SoftDevice to stop working. + // Disable the interrupts only in cases where you need high performance for + // the LEDs and if you are not using the EasyDMA feature. + __disable_irq(); + + uint32_t decoded_pin = digitalinout->pin->number; + NRF_GPIO_Type* port = nrf_gpio_pin_port_decode(&decoded_pin); + + uint32_t pinMask = ( 1UL << decoded_pin ); + + uint32_t CYCLES_X00 = CYCLES_800; + uint32_t CYCLES_X00_T1H = CYCLES_800_T1H; + uint32_t CYCLES_X00_T0H = CYCLES_800_T0H; + + // Enable DWT in debug core + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; + + // Tries to re-send the frame if is interrupted by the SoftDevice. + while ( 1 ) { + uint8_t *p = pixels; + + uint32_t cycStart = DWT->CYCCNT; + uint32_t cyc = 0; + + for ( uint16_t n = 0; n < numBytes; n++ ) { + uint8_t pix = *p++; + + for ( uint8_t mask = 0x80; mask; mask >>= 1 ) { + while ( DWT->CYCCNT - cyc < CYCLES_X00 ) + ; + cyc = DWT->CYCCNT; + + port->OUTSET |= pinMask; + + if ( pix & mask ) { + while ( DWT->CYCCNT - cyc < CYCLES_X00_T1H ) + ; + } else { + while ( DWT->CYCCNT - cyc < CYCLES_X00_T0H ) + ; + } + + port->OUTCLR |= pinMask; + } + } + while ( DWT->CYCCNT - cyc < CYCLES_X00 ) + ; + + // If total time longer than 25%, resend the whole data. + // Since we are likely to be interrupted by SoftDevice + if ( (DWT->CYCCNT - cycStart) < (8 * numBytes * ((CYCLES_X00 * 5) / 4)) ) { + break; + } + + // re-send need 300us delay + mp_hal_delay_us(300); + } + + // Enable interrupts again + __enable_irq(); + } + + // Update the next start. + current_tick(&next_start_tick_ms, &next_start_tick_us); + if (next_start_tick_us < 100) { + next_start_tick_ms += 1; + next_start_tick_us = 100 - next_start_tick_us; + } else { + next_start_tick_us -= 100; + } +} diff --git a/ports/nrf/common-hal/nvm/ByteArray.c b/ports/nrf/common-hal/nvm/ByteArray.c new file mode 100644 index 00000000000..ee270f79bb1 --- /dev/null +++ b/ports/nrf/common-hal/nvm/ByteArray.c @@ -0,0 +1,80 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Nick Moore for Adafruit Industries + * + * 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 "common-hal/nvm/ByteArray.h" + +#include +#include + +#include "peripherals/nrf/nvm.h" + +// defined in linker +extern uint32_t __fatfs_flash_start_addr[]; +extern uint32_t __fatfs_flash_length[]; + +#define NVM_START_ADDR ((uint32_t)__fatfs_flash_start_addr + \ + (uint32_t)__fatfs_flash_length - CIRCUITPY_INTERNAL_NVM_SIZE) + +uint32_t common_hal_nvm_bytearray_get_length(nvm_bytearray_obj_t *self) { + return CIRCUITPY_INTERNAL_NVM_SIZE; +} + +static void write_page(uint32_t page_addr, uint32_t offset, uint32_t len, uint8_t *bytes) { + // Write a whole page to flash, buffering it first and then erasing and rewriting + // it since we can only clear a whole page at a time. + + if (offset == 0 && len == FLASH_PAGE_SIZE) { + nrf_nvm_safe_flash_page_write(page_addr, bytes); + } else { + uint8_t buffer[FLASH_PAGE_SIZE]; + memcpy(buffer, (uint8_t *)page_addr, FLASH_PAGE_SIZE); + memcpy(buffer + offset, bytes, len); + nrf_nvm_safe_flash_page_write(page_addr, buffer); + } +} + +bool common_hal_nvm_bytearray_set_bytes(nvm_bytearray_obj_t *self, + uint32_t start_index, uint8_t* values, uint32_t len) { + + uint32_t address = NVM_START_ADDR + start_index; + uint32_t offset = address % FLASH_PAGE_SIZE; + uint32_t page_addr = address - offset; + + while (len) { + uint32_t write_len = MIN(len, FLASH_PAGE_SIZE - offset); + write_page(page_addr, offset, write_len, values); + len -= write_len; + values += write_len; + page_addr += FLASH_PAGE_SIZE; + offset = 0; + } + return true; +} + +void common_hal_nvm_bytearray_get_bytes(nvm_bytearray_obj_t *self, + uint32_t start_index, uint32_t len, uint8_t* values) { + memcpy(values, (uint8_t *)(NVM_START_ADDR + start_index), len); +} diff --git a/ports/nrf/common-hal/nvm/ByteArray.h b/ports/nrf/common-hal/nvm/ByteArray.h new file mode 100644 index 00000000000..a8d09dd43a8 --- /dev/null +++ b/ports/nrf/common-hal/nvm/ByteArray.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Nick Moore for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_NVM_BYTEARRAY_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_NVM_BYTEARRAY_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} nvm_bytearray_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_NVM_BYTEARRAY_H diff --git a/ports/nrf/common-hal/nvm/__init__.c b/ports/nrf/common-hal/nvm/__init__.c new file mode 100644 index 00000000000..3cdc9d3a4c0 --- /dev/null +++ b/ports/nrf/common-hal/nvm/__init__.c @@ -0,0 +1,27 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Nick Moore for Adafruit Industries + * + * 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. + */ + +// No nvm module functions. diff --git a/ports/nrf/common-hal/os/__init__.c b/ports/nrf/common-hal/os/__init__.c new file mode 100644 index 00000000000..7671cc2a51f --- /dev/null +++ b/ports/nrf/common-hal/os/__init__.c @@ -0,0 +1,86 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "genhdr/mpversion.h" +#include "py/mpconfig.h" +#include "py/objstr.h" +#include "py/objtuple.h" + +#ifdef BLUETOOTH_SD +#include "nrf_sdm.h" +#endif + +#include "nrf_rng.h" + +STATIC const qstr os_uname_info_fields[] = { + MP_QSTR_sysname, MP_QSTR_nodename, + MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine +}; +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, "nrf52"); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, "nrf52"); + +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); + +STATIC MP_DEFINE_ATTRTUPLE( + os_uname_info_obj, + os_uname_info_fields, + 5, + (mp_obj_t)&os_uname_info_sysname_obj, + (mp_obj_t)&os_uname_info_nodename_obj, + (mp_obj_t)&os_uname_info_release_obj, + (mp_obj_t)&os_uname_info_version_obj, + (mp_obj_t)&os_uname_info_machine_obj +); + +mp_obj_t common_hal_os_uname(void) { + return (mp_obj_t)&os_uname_info_obj; +} + +bool common_hal_os_urandom(uint8_t *buffer, uint32_t length) { +#ifdef BLUETOOTH_SD + uint8_t sd_en = 0; + (void) sd_softdevice_is_enabled(&sd_en); + + if (sd_en) + return NRF_SUCCESS == sd_rand_application_vector_get(buffer, length); +#endif + + nrf_rng_event_clear(NRF_RNG_EVENT_VALRDY); + nrf_rng_task_trigger(NRF_RNG_TASK_START); + + for (uint32_t i = 0; i < length; i++) { + while (nrf_rng_event_get(NRF_RNG_EVENT_VALRDY) == 0); + nrf_rng_event_clear(NRF_RNG_EVENT_VALRDY); + + buffer[i] = nrf_rng_random_value_get(); + } + + nrf_rng_task_trigger(NRF_RNG_TASK_STOP); + + return true; +} diff --git a/ports/nrf/common-hal/pulseio/PWMOut.c b/ports/nrf/common-hal/pulseio/PWMOut.c new file mode 100644 index 00000000000..b827470d3db --- /dev/null +++ b/ports/nrf/common-hal/pulseio/PWMOut.c @@ -0,0 +1,295 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 +#include "nrf.h" + +#include "py/runtime.h" +#include "common-hal/pulseio/PWMOut.h" +#include "shared-bindings/pulseio/PWMOut.h" +#include "supervisor/shared/translate.h" + +#include "nrf_gpio.h" + +#define PWM_MAX_FREQ (16000000) + +STATIC NRF_PWM_Type* pwms[] = { +#if NRFX_CHECK(NRFX_PWM0_ENABLED) + NRF_PWM0, +#endif +#if NRFX_CHECK(NRFX_PWM1_ENABLED) + NRF_PWM1, +#endif +#if NRFX_CHECK(NRFX_PWM2_ENABLED) + NRF_PWM2, +#endif +#if NRFX_CHECK(NRFX_PWM3_ENABLED) + NRF_PWM3, +#endif +}; + +#define CHANNELS_PER_PWM 4 + +STATIC uint16_t pwm_seq[MP_ARRAY_SIZE(pwms)][CHANNELS_PER_PWM]; + +static uint8_t never_reset_pwm[MP_ARRAY_SIZE(pwms)]; + +STATIC int pwm_idx(NRF_PWM_Type *pwm) { + for(size_t i=0; i < MP_ARRAY_SIZE(pwms); i++) + if(pwms[i] == pwm) return i; + return -1; +} + +void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) { + for(size_t i=0; i < MP_ARRAY_SIZE(pwms); i++) { + NRF_PWM_Type* pwm = pwms[i]; + if (pwm == self->pwm) { + never_reset_pwm[i] += 1; + } + } + + never_reset_pin_number(self->pin_number); +} + +void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self) { + for(size_t i=0; i < MP_ARRAY_SIZE(pwms); i++) { + NRF_PWM_Type* pwm = pwms[i]; + if (pwm == self->pwm) { + never_reset_pwm[i] -= 1; + } + } +} + +void reset_single_pwmout(uint8_t i) { + NRF_PWM_Type* pwm = pwms[i]; + + pwm->ENABLE = 0; + pwm->MODE = PWM_MODE_UPDOWN_Up; + pwm->DECODER = PWM_DECODER_LOAD_Individual; + pwm->LOOP = 0; + pwm->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_1; // default is 500 hz + pwm->COUNTERTOP = (PWM_MAX_FREQ/500); // default is 500 hz + + pwm->SEQ[0].PTR = (uint32_t) pwm_seq[i]; + pwm->SEQ[0].CNT = CHANNELS_PER_PWM; // default mode is Individual --> count must be 4 + pwm->SEQ[0].REFRESH = 0; + pwm->SEQ[0].ENDDELAY = 0; + + pwm->SEQ[1].PTR = 0; + pwm->SEQ[1].CNT = 0; + pwm->SEQ[1].REFRESH = 0; + pwm->SEQ[1].ENDDELAY = 0; + + for(int ch =0; ch < CHANNELS_PER_PWM; ch++) { + pwm_seq[i][ch] = (1 << 15); // polarity = 0 + } +} + +void pwmout_reset(void) { + for(size_t i=0; i < MP_ARRAY_SIZE(pwms); i++) { + if (never_reset_pwm[i] > 0) { + continue; + } + reset_single_pwmout(i); + } +} + +// Find the smallest prescaler value that will allow the divisor to be in range. +// This allows the most accuracy. +bool convert_frequency(uint32_t frequency, uint16_t *countertop, nrf_pwm_clk_t *base_clock) { + uint32_t divisor = 1; + // Use a 32-bit number so we don't overflow the uint16_t; + uint32_t tentative_countertop; + for (*base_clock = PWM_PRESCALER_PRESCALER_DIV_1; + *base_clock <= PWM_PRESCALER_PRESCALER_DIV_128; + (*base_clock)++) { + tentative_countertop = PWM_MAX_FREQ / divisor / frequency; + // COUNTERTOP must be 3..32767, according to datasheet, but 3 doesn't work. 4 does. + if (tentative_countertop <= 32767 && tentative_countertop >= 4) { + // In range, OK to return. + *countertop = tentative_countertop; + return true; + } + divisor *= 2; + } + + return false; +} + +NRF_PWM_Type *pwmout_allocate(uint16_t countertop, nrf_pwm_clk_t base_clock, + bool variable_frequency, int8_t *channel_out, bool *pwm_already_in_use_out) { + for (size_t pwm_index = 0; pwm_index < MP_ARRAY_SIZE(pwms); pwm_index++) { + NRF_PWM_Type *pwm = pwms[pwm_index]; + bool pwm_already_in_use = pwm->ENABLE & SPIM_ENABLE_ENABLE_Msk; + if (pwm_already_in_use) { + if (variable_frequency) { + // Variable frequency requires exclusive use of a PWM, so try the next one. + continue; + } + + // PWM is in use, but see if it's set to the same frequency we need. If so, + // look for a free channel. + if (pwm->COUNTERTOP == countertop && pwm->PRESCALER == base_clock) { + for (size_t chan = 0; chan < CHANNELS_PER_PWM; chan++) { + if (pwm->PSEL.OUT[chan] == 0xFFFFFFFF) { + // Channel is free. + if(channel_out) + *channel_out = chan; + if(pwm_already_in_use_out) + *pwm_already_in_use_out = pwm_already_in_use; + return pwm; + } + } + } + } else { + // PWM not yet in use, so we can start to use it. Use channel 0. + if(channel_out) + *channel_out = 0; + if(pwm_already_in_use_out) + *pwm_already_in_use_out = pwm_already_in_use; + return pwm; + } + } + return NULL; +} + +void pwmout_free_channel(NRF_PWM_Type *pwm, int8_t channel) { + // Disconnect pin from channel. + pwm->PSEL.OUT[channel] = 0xFFFFFFFF; + + for(int i=0; i < CHANNELS_PER_PWM; i++) { + if (pwm->PSEL.OUT[i] != 0xFFFFFFFF) { + // Some channel is still being used, so don't disable. + return; + } + } + + nrf_pwm_disable(pwm); +} + +pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, + const mcu_pin_obj_t* pin, + uint16_t duty, + uint32_t frequency, + bool variable_frequency) { + + // We don't use the nrfx driver here because we want to dynamically allocate channels + // as needed in an already-enabled PWM. + + uint16_t countertop; + nrf_pwm_clk_t base_clock; + if (frequency == 0 || !convert_frequency(frequency, &countertop, &base_clock)) { + return PWMOUT_INVALID_FREQUENCY; + } + + int8_t channel; + bool pwm_already_in_use; + self->pwm = pwmout_allocate(countertop, base_clock, variable_frequency, + &channel, &pwm_already_in_use); + + if (self->pwm == NULL) { + return PWMOUT_ALL_TIMERS_IN_USE; + } + + self->channel = channel; + self->pin_number = pin->number; + claim_pin(pin); + + self->frequency = frequency; + self->variable_frequency = variable_frequency; + + // Note this is standard, not strong drive. + nrf_gpio_cfg_output(self->pin_number); + + // disable before mapping pin channel + nrf_pwm_disable(self->pwm); + + if (!pwm_already_in_use) { + reset_single_pwmout(pwm_idx(self->pwm)); + nrf_pwm_configure(self->pwm, base_clock, NRF_PWM_MODE_UP, countertop); + } + + // Connect channel to pin, without disturbing other channels. + self->pwm->PSEL.OUT[self->channel] = pin->number; + + nrf_pwm_enable(self->pwm); + + common_hal_pulseio_pwmout_set_duty_cycle(self, duty); + return PWMOUT_OK; +} + +bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) { + return self->pwm == NULL; +} + +void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { + if (common_hal_pulseio_pwmout_deinited(self)) { + return; + } + + nrf_gpio_cfg_default(self->pin_number); + + NRF_PWM_Type* pwm = self->pwm; + self->pwm = NULL; + + pwmout_free_channel(pwm, self->channel); +} + +void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty_cycle) { + self->duty_cycle = duty_cycle; + + uint16_t* p_value = ((uint16_t*)self->pwm->SEQ[0].PTR) + self->channel; + *p_value = ((duty_cycle * self->pwm->COUNTERTOP) / 0xFFFF) | (1 << 15); + + self->pwm->TASKS_SEQSTART[0] = 1; +} + +uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) { + return self->duty_cycle; +} + +void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_t frequency) { + // COUNTERTOP is 3..32767, so highest available frequency is PWM_MAX_FREQ / 3. + uint16_t countertop; + nrf_pwm_clk_t base_clock; + if (frequency == 0 || !convert_frequency(frequency, &countertop, &base_clock)) { + mp_raise_ValueError(translate("Invalid PWM frequency")); + } + self->frequency = frequency; + + nrf_pwm_configure(self->pwm, base_clock, NRF_PWM_MODE_UP, countertop); + // Set the duty cycle again, because it depends on COUNTERTOP, which probably changed. + // Setting the duty cycle will also do a SEQSTART. + common_hal_pulseio_pwmout_set_duty_cycle(self, self->duty_cycle); +} + +uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self) { + return self->frequency; +} + +bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self) { + return self->variable_frequency; +} diff --git a/ports/nrf/common-hal/pulseio/PWMOut.h b/ports/nrf/common-hal/pulseio/PWMOut.h new file mode 100644 index 00000000000..b6798cb6859 --- /dev/null +++ b/ports/nrf/common-hal/pulseio/PWMOut.h @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_PULSEIO_PWMOUT_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_PULSEIO_PWMOUT_H + +#include "nrfx_pwm.h" +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + NRF_PWM_Type* pwm; + uint8_t pin_number; + uint8_t channel: 7; + bool variable_frequency: 1; + uint16_t duty_cycle; + uint32_t frequency; +} pulseio_pwmout_obj_t; + +void pwmout_reset(void); +NRF_PWM_Type *pwmout_allocate(uint16_t countertop, nrf_pwm_clk_t base_clock, + bool variable_frequency, int8_t *channel_out, bool *pwm_already_in_use_out); +void pwmout_free_channel(NRF_PWM_Type *pwm, int8_t channel); + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_PULSEIO_PWMOUT_H diff --git a/ports/nrf/common-hal/pulseio/PulseIn.c b/ports/nrf/common-hal/pulseio/PulseIn.c new file mode 100644 index 00000000000..3839668314b --- /dev/null +++ b/ports/nrf/common-hal/pulseio/PulseIn.c @@ -0,0 +1,282 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "common-hal/pulseio/PulseIn.h" + +#include +#include + +#include "py/mpconfig.h" +#include "py/gc.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/pulseio/PulseIn.h" + +#include "tick.h" +#include "nrfx_gpiote.h" + +// obj array to map pin -> self since nrfx hide the mapping +static pulseio_pulsein_obj_t* _objs[GPIOTE_CH_NUM]; + +// return index of the object in array +static int _find_pulsein_obj(pulseio_pulsein_obj_t* obj) { + for(size_t i = 0; i < NRFX_ARRAY_SIZE(_objs); i++ ) { + if ( _objs[i] == obj) { + return i; + } + } + + return -1; +} + +static void _pulsein_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { + // Grab the current time first. + uint32_t current_us; + uint64_t current_ms; + current_tick(¤t_ms, ¤t_us); + + // current_tick gives us the remaining us until the next tick but we want the number since the last ms. + current_us = 1000 - current_us; + + pulseio_pulsein_obj_t* self = NULL; + for(size_t i = 0; i < NRFX_ARRAY_SIZE(_objs); i++ ) { + if ( _objs[i] && _objs[i]->pin == pin ) { + self = _objs[i]; + break; + } + } + if ( !self ) return; + + if (self->first_edge) { + // first pulse is opposite state from idle + bool state = nrf_gpio_pin_read(self->pin); + if ( self->idle_state != state ) { + self->first_edge = false; + } + }else { + uint32_t ms_diff = current_ms - self->last_ms; + uint16_t us_diff = current_us - self->last_us; + uint32_t total_diff = us_diff; + + if (self->last_us > current_us) { + total_diff = 1000 + current_us - self->last_us; + if (ms_diff > 1) { + total_diff += (ms_diff - 1) * 1000; + } + } else { + total_diff += ms_diff * 1000; + } + uint16_t duration = 0xffff; + if (total_diff < duration) { + duration = total_diff; + } + + uint16_t i = (self->start + self->len) % self->maxlen; + self->buffer[i] = duration; + if (self->len < self->maxlen) { + self->len++; + } else { + self->start++; + } + } + + self->last_ms = current_ms; + self->last_us = current_us; +} + +void pulsein_reset(void) { + if ( nrfx_gpiote_is_init() ) { + nrfx_gpiote_uninit(); + } + nrfx_gpiote_init(); + + memset(_objs, 0, sizeof(_objs)); +} + +void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) { + int idx = _find_pulsein_obj(NULL); + if ( idx < 0 ) { + mp_raise_NotImplementedError(NULL); + } + _objs[idx] = self; + + self->buffer = (uint16_t *) m_malloc(maxlen * sizeof(uint16_t), false); + if (self->buffer == NULL) { + mp_raise_msg_varg(&mp_type_MemoryError, translate("Failed to allocate RX buffer of %d bytes"), maxlen * sizeof(uint16_t)); + } + + self->pin = pin->number; + self->maxlen = maxlen; + self->idle_state = idle_state; + self->start = 0; + self->len = 0; + self->first_edge = true; + self->paused = false; + self->last_us = 0; + self->last_ms = 0; + + claim_pin(pin); + + nrfx_gpiote_in_config_t cfg = { + .sense = NRF_GPIOTE_POLARITY_TOGGLE, + .pull = NRF_GPIO_PIN_NOPULL, // idle_state ? NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_PULLUP, + .is_watcher = false, // nrf_gpio_cfg_watcher vs nrf_gpio_cfg_input + .hi_accuracy = true, + .skip_gpio_setup = false + }; + nrfx_gpiote_in_init(self->pin, &cfg, _pulsein_handler); + nrfx_gpiote_in_event_enable(self->pin, true); +} + +bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self) { + return self->pin == NO_PIN; +} + +void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) { + if (common_hal_pulseio_pulsein_deinited(self)) { + return; + } + + nrfx_gpiote_in_event_disable(self->pin); + nrfx_gpiote_in_uninit(self->pin); + + // mark local array as invalid + int idx = _find_pulsein_obj(self); + if ( idx < 0 ) { + mp_raise_NotImplementedError(NULL); + } + _objs[idx] = NULL; + + reset_pin_number(self->pin); + self->pin = NO_PIN; +} + +void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) { + nrfx_gpiote_in_event_disable(self->pin); + self->paused = true; +} + +void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, uint16_t trigger_duration) { + // Make sure we're paused. + if ( !self->paused ) { + common_hal_pulseio_pulsein_pause(self); + } + + // Send the trigger pulse. + if (trigger_duration > 0) { + nrfx_gpiote_in_uninit(self->pin); + + nrf_gpio_cfg_output(self->pin); + nrf_gpio_pin_write(self->pin, !self->idle_state); + common_hal_mcu_delay_us((uint32_t)trigger_duration); + nrf_gpio_pin_write(self->pin, self->idle_state); + + nrfx_gpiote_in_config_t cfg = { + .sense = NRF_GPIOTE_POLARITY_TOGGLE, + .pull = NRF_GPIO_PIN_NOPULL, // idle_state ? NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_PULLUP, + .is_watcher = false, // nrf_gpio_cfg_watcher vs nrf_gpio_cfg_input + .hi_accuracy = true, + .skip_gpio_setup = false + }; + nrfx_gpiote_in_init(self->pin, &cfg, _pulsein_handler); + } + + self->first_edge = true; + self->paused = false; + self->last_ms = 0; + self->last_us = 0; + + nrfx_gpiote_in_event_enable(self->pin, true); +} + +void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self) { + if ( !self->paused ) { + nrfx_gpiote_in_event_disable(self->pin); + } + + self->start = 0; + self->len = 0; + + if ( !self->paused ) { + nrfx_gpiote_in_event_enable(self->pin, true); + } +} + +uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_t index) { + if ( !self->paused ) { + nrfx_gpiote_in_event_disable(self->pin); + } + + if (index < 0) { + index += self->len; + } + if (index < 0 || index >= self->len) { + if ( !self->paused ) { + nrfx_gpiote_in_event_enable(self->pin, true); + } + mp_raise_IndexError(translate("index out of range")); + } + uint16_t value = self->buffer[(self->start + index) % self->maxlen]; + + if ( !self->paused ) { + nrfx_gpiote_in_event_enable(self->pin, true); + } + + return value; +} + +uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) { + if (self->len == 0) { + mp_raise_IndexError(translate("pop from an empty PulseIn")); + } + + if ( !self->paused ) { + nrfx_gpiote_in_event_disable(self->pin); + } + + uint16_t value = self->buffer[self->start]; + self->start = (self->start + 1) % self->maxlen; + self->len--; + + if ( !self->paused ) { + nrfx_gpiote_in_event_enable(self->pin, true); + } + + return value; +} + +uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self) { + return self->maxlen; +} + +bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self) { + return self->paused; +} + +uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) { + return self->len; +} diff --git a/ports/nrf/common-hal/pulseio/PulseIn.h b/ports/nrf/common-hal/pulseio/PulseIn.h new file mode 100644 index 00000000000..4b2c6eee3f6 --- /dev/null +++ b/ports/nrf/common-hal/pulseio/PulseIn.h @@ -0,0 +1,53 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_PULSEIO_PULSEIN_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_PULSEIO_PULSEIN_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + + uint8_t pin; + bool idle_state; + bool paused; + volatile bool first_edge; + + uint16_t* buffer; + uint16_t maxlen; + + volatile uint16_t start; + volatile uint16_t len; + volatile uint16_t last_us; + volatile uint64_t last_ms; +} pulseio_pulsein_obj_t; + +void pulsein_reset(void); + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_PULSEIO_PULSEIN_H diff --git a/ports/nrf/common-hal/pulseio/PulseOut.c b/ports/nrf/common-hal/pulseio/PulseOut.c new file mode 100644 index 00000000000..d0433247acf --- /dev/null +++ b/ports/nrf/common-hal/pulseio/PulseOut.c @@ -0,0 +1,162 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "common-hal/pulseio/PulseOut.h" + +#include + +#include "py/mpconfig.h" +#include "nrf/pins.h" +#include "nrf/timers.h" +#include "py/gc.h" +#include "py/runtime.h" +#include "shared-bindings/pulseio/PulseOut.h" +#include "shared-bindings/pulseio/PWMOut.h" +#include "supervisor/shared/translate.h" + +// A single timer is shared amongst all PulseOut objects under the assumption that +// the code is single threaded. +static uint8_t refcount = 0; + +static nrfx_timer_t *timer = NULL; + +static uint16_t *pulse_array = NULL; +static volatile uint16_t pulse_array_index = 0; +static uint16_t pulse_array_length; + +static void turn_on(pulseio_pulseout_obj_t *pulseout) { + pulseout->pwmout->pwm->PSEL.OUT[0] = pulseout->pwmout->pin_number; +} + +static void turn_off(pulseio_pulseout_obj_t *pulseout) { + // Disconnect pin from PWM. + pulseout->pwmout->pwm->PSEL.OUT[0] = 0xffffffff; + // Make sure pin is low. + nrf_gpio_pin_clear(pulseout->pwmout->pin_number); +} + +static void start_timer(void) { + nrfx_timer_clear(timer); + // true enables interrupt. + nrfx_timer_compare(timer, NRF_TIMER_CC_CHANNEL0, pulse_array[pulse_array_index], true); + nrfx_timer_resume(timer); +} + +static void pulseout_event_handler(nrf_timer_event_t event_type, void *p_context) { + pulseio_pulseout_obj_t *pulseout = (pulseio_pulseout_obj_t*) p_context; + if (event_type != NRF_TIMER_EVENT_COMPARE0) { + // Spurious event. + return; + } + nrfx_timer_pause(timer); + + pulse_array_index++; + + // No more pulses. Turn off output and don't restart. + if (pulse_array_index >= pulse_array_length) { + turn_off(pulseout); + return; + } + + // Alternate on and off, starting with on. + if (pulse_array_index % 2 == 0) { + turn_on(pulseout); + } else { + turn_off(pulseout); + } + + // Count up to the next given value. + start_timer(); +} + +void pulseout_reset() { + if (timer != NULL) { + nrf_peripherals_free_timer(timer); + } + refcount = 0; +} + +void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self, + const pulseio_pwmout_obj_t* carrier) { + if (refcount == 0) { + timer = nrf_peripherals_allocate_timer(); + if (timer == NULL) { + mp_raise_RuntimeError(translate("All timers in use")); + } + } + refcount++; + + nrfx_timer_config_t timer_config = { + // PulseOut durations are in microseconds, so this is convenient. + .frequency = NRF_TIMER_FREQ_1MHz, + .mode = NRF_TIMER_MODE_TIMER, + .bit_width = NRF_TIMER_BIT_WIDTH_32, + .interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY, + .p_context = self, + }; + + self->pwmout = carrier; + + nrfx_timer_init(timer, &timer_config, &pulseout_event_handler); + turn_off(self); +} + +bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self) { + return self->pwmout == NULL; +} + +void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) { + if (common_hal_pulseio_pulseout_deinited(self)) { + return; + } + turn_on(self); + self->pwmout = NULL; + + refcount--; + if (refcount == 0) { + nrf_peripherals_free_timer(timer); + } +} + +void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pulses, uint16_t length) { + pulse_array = pulses; + pulse_array_index = 0; + pulse_array_length = length; + + nrfx_timer_enable(timer); + + turn_on(self); + // Count up to the next given value. + start_timer(); + + while(pulse_array_index < length) { + // Do other things while we wait. The interrupts will handle sending the + // signal. + RUN_BACKGROUND_TASKS; + } + + nrfx_timer_disable(timer); +} diff --git a/ports/nrf/common-hal/pulseio/PulseOut.h b/ports/nrf/common-hal/pulseio/PulseOut.h new file mode 100644 index 00000000000..42ec52e30e1 --- /dev/null +++ b/ports/nrf/common-hal/pulseio/PulseOut.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_PULSEIO_PULSEOUT_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_PULSEIO_PULSEOUT_H + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/pulseio/PWMOut.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + const pulseio_pwmout_obj_t *pwmout; +} pulseio_pulseout_obj_t; + +void pulseout_reset(void); + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_PULSEIO_PULSEOUT_H diff --git a/ports/nrf/common-hal/pulseio/__init__.c b/ports/nrf/common-hal/pulseio/__init__.c new file mode 100644 index 00000000000..2bee925bc77 --- /dev/null +++ b/ports/nrf/common-hal/pulseio/__init__.c @@ -0,0 +1 @@ +// No pulseio module functions. diff --git a/ports/nrf/common-hal/rotaryio/IncrementalEncoder.c b/ports/nrf/common-hal/rotaryio/IncrementalEncoder.c new file mode 100644 index 00000000000..a0cfd48d563 --- /dev/null +++ b/ports/nrf/common-hal/rotaryio/IncrementalEncoder.c @@ -0,0 +1,116 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Nick Moore for Adafruit Industries + * + * 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 "common-hal/rotaryio/IncrementalEncoder.h" +#include "nrfx_gpiote.h" + +#include "py/runtime.h" + +#include + +// obj array to map pin number -> self since nrfx hide the mapping +static rotaryio_incrementalencoder_obj_t *_objs[NUMBER_OF_PINS]; + +static void _intr_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { + rotaryio_incrementalencoder_obj_t *self = _objs[pin]; + if (!self) return; + + // reads a state 0 .. 3 *in order*. + uint8_t new_state = nrf_gpio_pin_read(self->pin_a); + new_state = (new_state << 1) + (new_state ^ nrf_gpio_pin_read(self->pin_b)); + + uint8_t change = (new_state - self->state) & 0x03; + if (change == 1) self->quarter++; + else if (change == 3) self->quarter--; + // ignore other state transitions + + self->state = new_state; + + // logic from the atmel-samd port: provides some damping and scales movement + // down by 4:1. + if (self->quarter >= 4) { + self->position++; + self->quarter = 0; + } else if (self->quarter <= -4) { + self->position--; + self->quarter = 0; + } +} + +void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t* self, + const mcu_pin_obj_t* pin_a, const mcu_pin_obj_t* pin_b) { + + self->pin_a = pin_a->number; + self->pin_b = pin_b->number; + + _objs[self->pin_a] = self; + _objs[self->pin_b] = self; + + nrfx_gpiote_in_config_t cfg = { + .sense = NRF_GPIOTE_POLARITY_TOGGLE, + .pull = NRF_GPIO_PIN_PULLUP, + .is_watcher = false, + .hi_accuracy = true, + .skip_gpio_setup = false + }; + nrfx_gpiote_in_init(self->pin_a, &cfg, _intr_handler); + nrfx_gpiote_in_init(self->pin_b, &cfg, _intr_handler); + nrfx_gpiote_in_event_enable(self->pin_a, true); + nrfx_gpiote_in_event_enable(self->pin_b, true); + + claim_pin(pin_a); + claim_pin(pin_b); +} + +bool common_hal_rotaryio_incrementalencoder_deinited(rotaryio_incrementalencoder_obj_t* self) { + return self->pin_a == NO_PIN; +} + +void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_obj_t* self) { + if (common_hal_rotaryio_incrementalencoder_deinited(self)) { + return; + } + _objs[self->pin_a] = NULL; + _objs[self->pin_b] = NULL; + + nrfx_gpiote_in_event_disable(self->pin_a); + nrfx_gpiote_in_event_disable(self->pin_b); + nrfx_gpiote_in_uninit(self->pin_a); + nrfx_gpiote_in_uninit(self->pin_b); + reset_pin_number(self->pin_a); + reset_pin_number(self->pin_b); + self->pin_a = NO_PIN; + self->pin_b = NO_PIN; +} + +mp_int_t common_hal_rotaryio_incrementalencoder_get_position(rotaryio_incrementalencoder_obj_t* self) { + return self->position; +} + +void common_hal_rotaryio_incrementalencoder_set_position(rotaryio_incrementalencoder_obj_t* self, + mp_int_t new_position) { + self->position = new_position; +} diff --git a/ports/nrf/common-hal/rotaryio/IncrementalEncoder.h b/ports/nrf/common-hal/rotaryio/IncrementalEncoder.h new file mode 100644 index 00000000000..1d0fe41839d --- /dev/null +++ b/ports/nrf/common-hal/rotaryio/IncrementalEncoder.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_ROTARYIO_INCREMENTALENCODER_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_ROTARYIO_INCREMENTALENCODER_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint8_t pin_a; + uint8_t pin_b; + uint8_t state; + int8_t quarter; + mp_int_t position; +} rotaryio_incrementalencoder_obj_t; + + +void incrementalencoder_interrupt_handler(uint8_t channel); + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_ROTARYIO_INCREMENTALENCODER_H diff --git a/ports/nrf/common-hal/rotaryio/__init__.c b/ports/nrf/common-hal/rotaryio/__init__.c new file mode 100644 index 00000000000..0aae79c26a1 --- /dev/null +++ b/ports/nrf/common-hal/rotaryio/__init__.c @@ -0,0 +1 @@ +// No rotaryio module functions. diff --git a/ports/nrf/common-hal/rtc/RTC.c b/ports/nrf/common-hal/rtc/RTC.c new file mode 100644 index 00000000000..57138350c9e --- /dev/null +++ b/ports/nrf/common-hal/rtc/RTC.c @@ -0,0 +1,90 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Nick Moore for Adafruit Industries + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" +#include "lib/timeutils/timeutils.h" +#include "shared-bindings/rtc/__init__.h" +#include "supervisor/shared/translate.h" + +#include "nrfx_rtc.h" +#include "nrf_clock.h" + +// We clock the RTC very slowly (8Hz) so that it won't overflow often. +// But the counter is only 24 bits, so overflow is about every 24 days ... +// For testing, set this to 32768 and it'll overflow every few minutes + +#define RTC_CLOCK_HZ (8) + +volatile static uint32_t rtc_offset = 0; + +const nrfx_rtc_t rtc_instance = NRFX_RTC_INSTANCE(2); + +const nrfx_rtc_config_t rtc_config = { + .prescaler = RTC_FREQ_TO_PRESCALER(RTC_CLOCK_HZ), + .reliable = 0, + .tick_latency = 0, + .interrupt_priority = 6 +}; + +void rtc_handler(nrfx_rtc_int_type_t int_type) { + if (int_type == NRFX_RTC_INT_OVERFLOW) { + rtc_offset += (1L<<24) / RTC_CLOCK_HZ; + } +} + +void rtc_init(void) { + if (!nrf_clock_lf_is_running()) { + nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART); + } + nrfx_rtc_counter_clear(&rtc_instance); + nrfx_rtc_init(&rtc_instance, &rtc_config, rtc_handler); + nrfx_rtc_enable(&rtc_instance); + nrfx_rtc_overflow_enable(&rtc_instance, 1); +} + +void common_hal_rtc_get_time(timeutils_struct_time_t *tm) { + uint32_t t = rtc_offset + (nrfx_rtc_counter_get(&rtc_instance) / RTC_CLOCK_HZ ); + timeutils_seconds_since_2000_to_struct_time(t, tm); +} + +void common_hal_rtc_set_time(timeutils_struct_time_t *tm) { + rtc_offset = timeutils_seconds_since_2000( + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec + ); + nrfx_rtc_counter_clear(&rtc_instance); +} + +int common_hal_rtc_get_calibration(void) { + return 0; +} + +void common_hal_rtc_set_calibration(int calibration) { + mp_raise_NotImplementedError(translate("RTC calibration is not supported on this board")); +} + diff --git a/ports/nrf/common-hal/rtc/RTC.h b/ports/nrf/common-hal/rtc/RTC.h new file mode 100644 index 00000000000..0207c8338c6 --- /dev/null +++ b/ports/nrf/common-hal/rtc/RTC.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_RTC_RTC_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_RTC_RTC_H + +extern void rtc_init(void); +extern void rtc_reset(void); + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_RTC_RTC_H diff --git a/ports/nrf/common-hal/rtc/__init__.c b/ports/nrf/common-hal/rtc/__init__.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/nrf/common-hal/supervisor/Runtime.c b/ports/nrf/common-hal/supervisor/Runtime.c new file mode 100755 index 00000000000..feab6987d8b --- /dev/null +++ b/ports/nrf/common-hal/supervisor/Runtime.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Michael Schroeder + * + * 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 +#include "shared-bindings/supervisor/Runtime.h" +#include "supervisor/serial.h" + +bool common_hal_get_serial_connected(void) { + return (bool) serial_connected(); +} + +bool common_hal_get_serial_bytes_available(void) { + return (bool) serial_bytes_available(); +} + diff --git a/ports/nrf/common-hal/supervisor/Runtime.h b/ports/nrf/common-hal/supervisor/Runtime.h new file mode 100755 index 00000000000..dbff22e4c92 --- /dev/null +++ b/ports/nrf/common-hal/supervisor/Runtime.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Michael Schroeder + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_SUPERVISOR_RUNTIME_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_SUPERVISOR_RUNTIME_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + // Stores no state currently. +} super_runtime_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_SUPERVISOR_RUNTIME_H diff --git a/ports/nrf/common-hal/supervisor/__init__.c b/ports/nrf/common-hal/supervisor/__init__.c new file mode 100755 index 00000000000..ac88556b45d --- /dev/null +++ b/ports/nrf/common-hal/supervisor/__init__.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Michael Schroeder + * + * 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 "py/obj.h" + +#include "shared-bindings/supervisor/__init__.h" +#include "shared-bindings/supervisor/Runtime.h" + + +// The singleton supervisor.Runtime object, bound to supervisor.runtime +// It currently only has properties, and no state. +const super_runtime_obj_t common_hal_supervisor_runtime_obj = { + .base = { + .type = &supervisor_runtime_type, + }, +}; \ No newline at end of file diff --git a/ports/nrf/common-hal/time/__init__.c b/ports/nrf/common-hal/time/__init__.c new file mode 100644 index 00000000000..e3cb481ef42 --- /dev/null +++ b/ports/nrf/common-hal/time/__init__.c @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "py/mphal.h" + +#include "tick.h" + +uint64_t common_hal_time_monotonic(void) { + return ticks_ms; +} + +void common_hal_time_delay_ms(uint32_t delay) { + mp_hal_delay_ms(delay); +} diff --git a/ports/nrf/device/nrf52/startup_nrf52.c b/ports/nrf/device/nrf52/startup_nrf52.c new file mode 100644 index 00000000000..614b8c2d322 --- /dev/null +++ b/ports/nrf/device/nrf52/startup_nrf52.c @@ -0,0 +1,169 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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 + +extern uint32_t _estack; +extern uint32_t _sidata; +extern uint32_t _sdata; +extern uint32_t _edata; +extern uint32_t _sbss; +extern uint32_t _ebss; + +typedef void (*func)(void); + +#define _start main + +extern void _start(void) __attribute__((noreturn)); +extern void SystemInit(void); + +void Default_Handler(void) { + while (1); +} + +void Reset_Handler(void) { + uint32_t * p_src = &_sidata; + uint32_t * p_dest = &_sdata; + + while (p_dest < &_edata) { + *p_dest++ = *p_src++; + } + + uint32_t * p_bss = &_sbss; + uint32_t * p_bss_end = &_ebss; + while (p_bss < p_bss_end) { + *p_bss++ = 0ul; + } + + SystemInit(); + _start(); +} + +void NMI_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void HardFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void MemoryManagement_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void BusFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void UsageFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void DebugMon_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); + +void POWER_CLOCK_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void RADIO_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void UARTE0_UART0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void NFCT_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void GPIOTE_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SAADC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void TIMER0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void TIMER1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void TIMER2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void RTC0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void TEMP_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void RNG_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void ECB_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void CCM_AAR_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void WDT_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void RTC1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void QDEC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void COMP_LPCOMP_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SWI0_EGU0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SWI1_EGU1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SWI2_EGU2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SWI3_EGU3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SWI4_EGU4_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SWI5_EGU5_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void TIMER3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void TIMER4_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void PWM0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void PDM_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void MWU_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void PWM1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void PWM2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SPIM2_SPIS2_SPI2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void RTC2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void I2S_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); + +const func __Vectors[] __attribute__ ((section(".isr_vector"))) = { + (func)&_estack, + Reset_Handler, + NMI_Handler, + HardFault_Handler, + MemoryManagement_Handler, + BusFault_Handler, + UsageFault_Handler, + 0, + 0, + 0, + 0, + SVC_Handler, + DebugMon_Handler, + 0, + PendSV_Handler, + SysTick_Handler, + + /* External Interrupts */ + POWER_CLOCK_IRQHandler, + RADIO_IRQHandler, + UARTE0_UART0_IRQHandler, + SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler, + SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler, + NFCT_IRQHandler, + GPIOTE_IRQHandler, + SAADC_IRQHandler, + TIMER0_IRQHandler, + TIMER1_IRQHandler, + TIMER2_IRQHandler, + RTC0_IRQHandler, + TEMP_IRQHandler, + RNG_IRQHandler, + ECB_IRQHandler, + CCM_AAR_IRQHandler, + WDT_IRQHandler, + RTC1_IRQHandler, + QDEC_IRQHandler, + COMP_LPCOMP_IRQHandler, + SWI0_EGU0_IRQHandler, + SWI1_EGU1_IRQHandler, + SWI2_EGU2_IRQHandler, + SWI3_EGU3_IRQHandler, + SWI4_EGU4_IRQHandler, + SWI5_EGU5_IRQHandler, + TIMER3_IRQHandler, + TIMER4_IRQHandler, + PWM0_IRQHandler, + PDM_IRQHandler, + 0, + 0, + MWU_IRQHandler, + PWM1_IRQHandler, + PWM2_IRQHandler, + SPIM2_SPIS2_SPI2_IRQHandler, + RTC2_IRQHandler, + I2S_IRQHandler +}; diff --git a/ports/nrf/device/nrf52/startup_nrf52840.c b/ports/nrf/device/nrf52/startup_nrf52840.c new file mode 100644 index 00000000000..8e1c3601288 --- /dev/null +++ b/ports/nrf/device/nrf52/startup_nrf52840.c @@ -0,0 +1,184 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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 + +extern uint32_t _estack; +extern uint32_t _sidata; +extern uint32_t _sdata; +extern uint32_t _edata; +extern uint32_t _sbss; +extern uint32_t _ebss; + +typedef void (*func)(void); + +#define _start main + +extern void _start(void) __attribute__((noreturn)); +extern void SystemInit(void); + +void Default_Handler(void) { + while (1); +} + +void Reset_Handler(void) { + uint32_t * p_src = &_sidata; + uint32_t * p_dest = &_sdata; + + while (p_dest < &_edata) { + *p_dest++ = *p_src++; + } + + uint32_t * p_bss = &_sbss; + uint32_t * p_bss_end = &_ebss; + while (p_bss < p_bss_end) { + *p_bss++ = 0ul; + } + + SystemInit(); + _start(); +} + +void NMI_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void HardFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void MemoryManagement_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void BusFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void UsageFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void DebugMon_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); + +void POWER_CLOCK_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void RADIO_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void UARTE0_UART0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void NFCT_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void GPIOTE_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SAADC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void TIMER0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void TIMER1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void TIMER2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void RTC0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void TEMP_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void RNG_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void ECB_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void CCM_AAR_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void WDT_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void RTC1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void QDEC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void COMP_LPCOMP_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SWI0_EGU0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SWI1_EGU1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SWI2_EGU2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SWI3_EGU3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SWI4_EGU4_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SWI5_EGU5_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void TIMER3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void TIMER4_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void PWM0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void PDM_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void MWU_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void PWM1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void PWM2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SPIM2_SPIS2_SPI2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void RTC2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void I2S_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void FPU_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void USBD_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void UARTE1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void QSPI_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void CRYPTOCELL_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SPIM3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); +void PWM3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler"))); + +const func __Vectors[] __attribute__ ((used, section(".isr_vector"))) = { + (func)&_estack, + Reset_Handler, + NMI_Handler, + HardFault_Handler, + MemoryManagement_Handler, + BusFault_Handler, + UsageFault_Handler, + 0, + 0, + 0, + 0, + SVC_Handler, + DebugMon_Handler, + 0, + PendSV_Handler, + SysTick_Handler, + + /* External Interrupts */ + POWER_CLOCK_IRQHandler, + RADIO_IRQHandler, + UARTE0_UART0_IRQHandler, + SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler, + SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler, + NFCT_IRQHandler, + GPIOTE_IRQHandler, + SAADC_IRQHandler, + TIMER0_IRQHandler, + TIMER1_IRQHandler, + TIMER2_IRQHandler, + RTC0_IRQHandler, + TEMP_IRQHandler, + RNG_IRQHandler, + ECB_IRQHandler, + CCM_AAR_IRQHandler, + WDT_IRQHandler, + RTC1_IRQHandler, + QDEC_IRQHandler, + COMP_LPCOMP_IRQHandler, + SWI0_EGU0_IRQHandler, + SWI1_EGU1_IRQHandler, + SWI2_EGU2_IRQHandler, + SWI3_EGU3_IRQHandler, + SWI4_EGU4_IRQHandler, + SWI5_EGU5_IRQHandler, + TIMER3_IRQHandler, + TIMER4_IRQHandler, + PWM0_IRQHandler, + PDM_IRQHandler, + 0, + 0, + MWU_IRQHandler, + PWM1_IRQHandler, + PWM2_IRQHandler, + SPIM2_SPIS2_SPI2_IRQHandler, + RTC2_IRQHandler, + I2S_IRQHandler, + FPU_IRQHandler, + USBD_IRQHandler, + UARTE1_IRQHandler, + QSPI_IRQHandler, + CRYPTOCELL_IRQHandler, + SPIM3_IRQHandler, + 0, + PWM3_IRQHandler, +}; diff --git a/ports/nrf/examples/ubluepy_eddystone.py b/ports/nrf/examples/ubluepy_eddystone.py new file mode 100644 index 00000000000..baf25ba4b47 --- /dev/null +++ b/ports/nrf/examples/ubluepy_eddystone.py @@ -0,0 +1,58 @@ +from ubluepy import Peripheral, constants + +BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE = const(0x02) +BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED = const(0x04) + +BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE = const(BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) + +EDDYSTONE_FRAME_TYPE_URL = const(0x10) +EDDYSTONE_URL_PREFIX_HTTP_WWW = const(0x00) # "http://www". +EDDYSTONE_URL_SUFFIX_DOT_COM = const(0x01) # ".com" + +def string_to_binarray(text): + b = bytearray([]) + for c in text: + b.append(ord(c)) + return b + +def gen_ad_type_content(ad_type, data): + b = bytearray(1) + b.append(ad_type) + b.extend(data) + b[0] = len(b) - 1 + return b + +def generate_eddystone_adv_packet(url): + # flags + disc_mode = bytearray([BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE]) + packet_flags = gen_ad_type_content(constants.ad_types.AD_TYPE_FLAGS, disc_mode) + + # 16-bit uuid + uuid = bytearray([0xAA, 0xFE]) + packet_uuid16 = gen_ad_type_content(constants.ad_types.AD_TYPE_16BIT_SERVICE_UUID_COMPLETE, uuid) + + # eddystone data + rssi = 0xEE # -18 dB, approx signal strength at 0m. + eddystone_data = bytearray([]) + eddystone_data.append(EDDYSTONE_FRAME_TYPE_URL) + eddystone_data.append(rssi) + eddystone_data.append(EDDYSTONE_URL_PREFIX_HTTP_WWW) + eddystone_data.extend(string_to_binarray(url)) + eddystone_data.append(EDDYSTONE_URL_SUFFIX_DOT_COM) + + # service data + service_data = uuid + eddystone_data + packet_service_data = gen_ad_type_content(constants.ad_types.AD_TYPE_SERVICE_DATA, service_data) + + # generate advertisement packet + packet = bytearray([]) + packet.extend(packet_flags) + packet.extend(packet_uuid16) + packet.extend(packet_service_data) + + return packet + +def start(): + adv_packet = generate_eddystone_adv_packet("micropython") + p = Peripheral() + p.advertise(data=adv_packet, connectable=False) \ No newline at end of file diff --git a/ports/nrf/examples/ubluepy_scan.py b/ports/nrf/examples/ubluepy_scan.py new file mode 100644 index 00000000000..ab11661ccaa --- /dev/null +++ b/ports/nrf/examples/ubluepy_scan.py @@ -0,0 +1,38 @@ +from ubluepy import Scanner, constants + +def bytes_to_str(bytes): + string = "" + for b in bytes: + string += chr(b) + return string + +def get_device_names(scan_entries): + dev_names = [] + for e in scan_entries: + scan = e.getScanData() + if scan: + for s in scan: + if s[0] == constants.ad_types.AD_TYPE_COMPLETE_LOCAL_NAME: + dev_names.append((e, bytes_to_str(s[2]))) + return dev_names + +def find_device_by_name(name): + s = Scanner() + scan_res = s.scan(100) + + device_names = get_device_names(scan_res) + for dev in device_names: + if name == dev[1]: + return dev[0] + +# >>> res = find_device_by_name("micr") +# >>> if res: +# ... print("address:", res.addr()) +# ... print("address type:", res.addr_type()) +# ... print("rssi:", res.rssi()) +# ... +# ... +# ... +# address: c2:73:61:89:24:45 +# address type: 1 +# rssi: -26 diff --git a/ports/nrf/examples/ubluepy_temp.py b/ports/nrf/examples/ubluepy_temp.py new file mode 100644 index 00000000000..e5c157dbbd4 --- /dev/null +++ b/ports/nrf/examples/ubluepy_temp.py @@ -0,0 +1,92 @@ +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# Copyright (c) 2017 Glenn Ruben Bakke +# +# 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 + +from pyb import LED +from machine import RTC, Temp +from ubluepy import Service, Characteristic, UUID, Peripheral, constants + +def event_handler(id, handle, data): + global rtc + global periph + global serv_env_sense + global notif_enabled + + if id == constants.EVT_GAP_CONNECTED: + # indicated 'connected' + LED(1).on() + + elif id == constants.EVT_GAP_DISCONNECTED: + # stop low power timer + rtc.stop() + # indicate 'disconnected' + LED(1).off() + # restart advertisement + periph.advertise(device_name="micr_temp", services=[serv_env_sense]) + + elif id == constants.EVT_GATTS_WRITE: + # write to this Characteristic is to CCCD + if int(data[0]) == 1: + notif_enabled = True + # start low power timer + rtc.start() + else: + notif_enabled = False + # stop low power timer + rtc.stop() + +def send_temp(timer_id): + global notif_enabled + global char_temp + + if notif_enabled: + # measure chip temperature + temp = Temp.read() + temp = temp * 100 + char_temp.write(bytearray([temp & 0xFF, temp >> 8])) + +# start off with LED(1) off +LED(1).off() + +# use RTC1 as RTC0 is used by bluetooth stack +# set up RTC callback every 5 second +rtc = RTC(1, period=5, mode=RTC.PERIODIC, callback=send_temp) + +notif_enabled = False + +uuid_env_sense = UUID("0x181A") # Environmental Sensing service +uuid_temp = UUID("0x2A6E") # Temperature characteristic + +serv_env_sense = Service(uuid_env_sense) + +temp_props = Characteristic.PROP_NOTIFY | Characteristic.PROP_READ +temp_attrs = Characteristic.ATTR_CCCD +char_temp = Characteristic(uuid_temp, props = temp_props, attrs = temp_attrs) + +serv_env_sense.addCharacteristic(char_temp) + +periph = Peripheral() +periph.addService(serv_env_sense) +periph.setConnectionHandler(event_handler) +periph.advertise(device_name="micr_temp", services=[serv_env_sense]) + diff --git a/ports/nrf/fatfs_port.c b/ports/nrf/fatfs_port.c new file mode 100644 index 00000000000..13ac21fb1bc --- /dev/null +++ b/ports/nrf/fatfs_port.c @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython 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 "py/runtime.h" +#include "lib/oofatfs/ff.h" + +DWORD get_fattime(void) { + // TODO: Implement this function. For now, fake it. + return ((2016 - 1980) << 25) | ((12) << 21) | ((4) << 16) | ((00) << 11) | ((18) << 5) | (23 / 2); +} diff --git a/ports/nrf/freeze/test.py b/ports/nrf/freeze/test.py new file mode 100644 index 00000000000..e64bbc9f52c --- /dev/null +++ b/ports/nrf/freeze/test.py @@ -0,0 +1,4 @@ +import sys + +def hello(): + print("Hello %s!" % sys.platform) diff --git a/ports/nrf/gccollect.c b/ports/nrf/gccollect.c new file mode 100644 index 00000000000..b7aa57a55a2 --- /dev/null +++ b/ports/nrf/gccollect.c @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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 +#include + +#include "py/obj.h" +#include "py/gc.h" +#include "gccollect.h" + +static inline uint32_t get_msp(void) +{ + register uint32_t result; + __asm volatile ("MRS %0, msp\n" : "=r" (result) ); + return(result); +} + +void gc_collect(void) { + // start the GC + gc_collect_start(); + + mp_uint_t sp = get_msp(); // Get stack pointer + + // trace the stack, including the registers (since they live on the stack in this function) + gc_collect_root((void**)sp, ((uint32_t)&_ram_end - sp) / sizeof(uint32_t)); + + // end the GC + gc_collect_end(); +} diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h new file mode 100644 index 00000000000..0b755a156b7 --- /dev/null +++ b/ports/nrf/mpconfigport.h @@ -0,0 +1,65 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2015 Glenn Ruben Bakke + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef NRF5_MPCONFIGPORT_H__ +#define NRF5_MPCONFIGPORT_H__ + +#include "ble_drv.h" + +#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1) +#define MICROPY_PY_FUNCTION_ATTRS (1) +#define MICROPY_PY_IO (1) +#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) +#define MICROPY_PY_SYS_STDIO_BUFFER (1) +#define MICROPY_PY_UBINASCII (1) +#define MICROPY_PY_UJSON (1) + +// TODO this is old BLE stuff +#if BLUETOOTH_SD + #define MICROPY_PY_BLEIO (1) + #define MICROPY_PY_BLE_NUS (0) +#else + #ifndef MICROPY_PY_BLEIO + #define MICROPY_PY_BLEIO (0) + #endif +#endif + +// 24kiB stack +#define CIRCUITPY_DEFAULT_STACK_SIZE 0x6000 + +#include "py/circuitpy_mpconfig.h" + +#ifndef BOARD_HAS_32KHZ_XTAL +// Assume crystal is present, which is the most common case. +#define BOARD_HAS_32KHZ_XTAL (1) +#endif + +#define MICROPY_PORT_ROOT_POINTERS \ + CIRCUITPY_COMMON_ROOT_POINTERS \ + ble_drv_evt_handler_entry_t* ble_drv_evt_handler_entries; \ + +#endif // NRF5_MPCONFIGPORT_H__ diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk new file mode 100644 index 00000000000..55920b3f4a8 --- /dev/null +++ b/ports/nrf/mpconfigport.mk @@ -0,0 +1,34 @@ +# Define an equivalent for MICROPY_LONGINT_IMPL, to pass to $(MPY-TOOL) in py/mkrules.mk +# $(MPY-TOOL) needs to know what kind of longint to use (if any) to freeze long integers. +# This should correspond to the MICROPY_LONGINT_IMPL definition in mpconfigport.h. +MPY_TOOL_LONGINT_IMPL = -mlongint-impl=mpz + +INTERNAL_LIBM = 1 + +USB_SERIAL_NUMBER_LENGTH = 16 + +# All nRF ports have longints. +LONGINT_IMPL = MPZ + +# Audio via PWM +CIRCUITPY_AUDIOCORE = 1 +CIRCUITPY_AUDIOIO = 0 +CIRCUITPY_AUDIOPWMIO = 1 +CIRCUITPY_AUDIOBUSIO = 1 + +# No I2CSlave implementation +CIRCUITPY_I2CSLAVE = 0 + +# enable NVM +CIRCUITPY_NVM = 1 + +# enable RTC +CIRCUITPY_RTC = 1 + +# frequencyio not yet implemented +CIRCUITPY_FREQUENCYIO = 0 + +# CircuitPython doesn't yet support NFC so force the NFC antenna pins to be GPIO. +# See https://github.com/adafruit/circuitpython/issues/1300 +# Defined here because system_nrf52840.c doesn't #include any of our own include files. +CFLAGS += -DCONFIG_NFCT_PINS_AS_GPIOS diff --git a/ports/nrf/mphalport.c b/ports/nrf/mphalport.c new file mode 100644 index 00000000000..bcd9fb11451 --- /dev/null +++ b/ports/nrf/mphalport.c @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2015 Glenn Ruben Bakke + * + * 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 + +#include "py/mphal.h" +#include "py/mpstate.h" +#include "py/gc.h" + +/*------------------------------------------------------------------*/ +/* delay + *------------------------------------------------------------------*/ +void mp_hal_delay_ms(mp_uint_t delay) { + uint64_t start_tick = ticks_ms; + uint64_t duration = 0; + while (duration < delay) { + RUN_BACKGROUND_TASKS; + // Check to see if we've been CTRL-Ced by autoreload or the user. + if(MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) || + MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { + break; + } + duration = (ticks_ms - start_tick); + // TODO(tannewt): Go to sleep for a little while while we wait. + } +} diff --git a/ports/nrf/mphalport.h b/ports/nrf/mphalport.h new file mode 100644 index 00000000000..a1929a4ace6 --- /dev/null +++ b/ports/nrf/mphalport.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2015 Glenn Ruben Bakke + * + * 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. + */ + +#ifndef __NRF52_HAL +#define __NRF52_HAL + +#include +#include + +#include "lib/utils/interrupt_char.h" +#include "nrfx_uarte.h" +#include "py/mpconfig.h" + +extern nrfx_uarte_t serial_instance; + +extern volatile uint64_t ticks_ms; + +#define mp_hal_ticks_ms() ((mp_uint_t) ticks_ms) +#define mp_hal_delay_us(us) NRFX_DELAY_US((uint32_t) (us)) + +bool mp_hal_stdin_any(void); + +#endif diff --git a/ports/nrf/nrfx b/ports/nrf/nrfx new file mode 160000 index 00000000000..3d268263be2 --- /dev/null +++ b/ports/nrf/nrfx @@ -0,0 +1 @@ +Subproject commit 3d268263be2390ab760f75a3da72689ef13031a4 diff --git a/ports/nrf/nrfx_config.h b/ports/nrf/nrfx_config.h new file mode 100644 index 00000000000..8fa6721e2c4 --- /dev/null +++ b/ports/nrf/nrfx_config.h @@ -0,0 +1,104 @@ +#ifndef NRFX_CONFIG_H__ +#define NRFX_CONFIG_H__ + +// Power +#define NRFX_POWER_ENABLED 1 +#define NRFX_POWER_CONFIG_IRQ_PRIORITY 7 + +// Turn on nrfx supported workarounds for errata in Rev1/Rev2 of nRF52832 +#ifdef NRF52832_XXAA + #define NRFX_SPIS_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 +#endif + +// NOTE: THIS WORKAROUND CAUSES BLE CODE TO CRASH; tested on 2019-03-11. +// Turn on nrfx supported workarounds for errata in Rev1 of nRF52840 +#ifdef NRF52840_XXAA +// #define NRFX_SPIM3_NRF52840_ANOMALY_198_WORKAROUND_ENABLED 1 +#endif + +// SPI +#define NRFX_SPIM_ENABLED 1 + +// TWIM0 and TWIM1 are the same peripherals as SPIM0 and SPIM1. +// The IRQ handlers for these peripherals are set up at compile time, +// so out of the box TWIM0/SPIM0 and TWIM1/SPIM1 cannot be shared +// between common-hal/busio/I2C.c and SPI.c. +// We could write an interrupt handler that checks whether it's +// being used for SPI or I2C, but perhaps two I2C's and 1-2 SPI's are good enough for now. + +// Enable SPIM1, SPIM2 and SPIM3 (if available) +// No conflict with TWIM0. +#define NRFX_SPIM1_ENABLED 1 +#define NRFX_SPIM2_ENABLED 1 +// DON'T ENABLE SPIM3 DUE TO ANOMALY WORKAROUND FAILURE (SEE ABOVE). +// #ifdef NRF52840_XXAA +// #define NRFX_SPIM_EXTENDED_ENABLED 1 +// #define NRFX_SPIM3_ENABLED 1 +// #else +// #define NRFX_SPIM3_ENABLED 0 +// #endif + + +#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY 7 +#define NRFX_SPIM_MISO_PULL_CFG 1 + +// QSPI +#define NRFX_QSPI_ENABLED 1 + +// TWI aka. I2C; enable a single bus: TWIM0 (no conflict with SPIM1 and SPIM2) +#define NRFX_TWIM_ENABLED 1 +#define NRFX_TWIM0_ENABLED 1 +//#define NRFX_TWIM1_ENABLED 1 + +#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY 7 +#define NRFX_TWIM_DEFAULT_CONFIG_FREQUENCY NRF_TWIM_FREQ_400K +#define NRFX_TWIM_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0 + +// UART +#define NRFX_UARTE_ENABLED 1 +#define NRFX_UARTE0_ENABLED 1 +#define NRFX_UARTE1_ENABLED 1 + +// PWM +#define NRFX_PWM0_ENABLED 1 +#define NRFX_PWM1_ENABLED 1 +#define NRFX_PWM2_ENABLED 1 + +#ifdef NRF_PWM3 +#define NRFX_PWM3_ENABLED 1 +#else +#define NRFX_PWM3_ENABLED 0 +#endif + +#define NRFX_RTC_ENABLED 1 +#define NRFX_RTC0_ENABLED 1 +#define NRFX_RTC1_ENABLED 1 +#define NRFX_RTC2_ENABLED 1 + +// TIMERS +#define NRFX_TIMER_ENABLED 1 +// Don't enable TIMER0: it's used by the SoftDevice. +#define NRFX_TIMER0_ENABLED 0 +#define NRFX_TIMER1_ENABLED 1 +#define NRFX_TIMER2_ENABLED 1 + +#ifdef NRF_TIMER3 +#define NRFX_TIMER3_ENABLED 1 +#else +#define NRFX_TIMER3_ENABLED 0 +#endif + +#ifdef NRF_TIMER4 +#define NRFX_TIMER4_ENABLED 1 +#else +#define NRFX_TIMER4_ENABLED 0 +#endif + +#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 7 + +// GPIO interrupt +#define NRFX_GPIOTE_ENABLED 1 +#define NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 1 +#define NRFX_GPIOTE_CONFIG_IRQ_PRIORITY 7 + +#endif // NRFX_CONFIG_H__ diff --git a/ports/nrf/nrfx_glue.h b/ports/nrf/nrfx_glue.h new file mode 100644 index 00000000000..345de387045 --- /dev/null +++ b/ports/nrf/nrfx_glue.h @@ -0,0 +1,247 @@ +/** + * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef NRFX_GLUE_H__ +#define NRFX_GLUE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * @defgroup nrfx_glue nrfx_glue.h + * @{ + * @ingroup nrfx + * + * @brief This file contains macros that should be implemented according to + * the needs of the host environment into which @em nrfx is integrated. + */ + +#include + +void __assert_func(const char *file, int line, const char *func, const char *expr); + +//------------------------------------------------------------------------------ + +/** + * @brief Macro for placing a runtime assertion. + * + * @param expression Expression to evaluate. + */ + +#ifndef NDEBUG +#define NRFX_ASSERT(expr) ((expr) ? (void)0 : __assert_func(__FILE__, __LINE__, __FUNCTION__, #expr)) +#else +#define NRFX_ASSERT(expr) +#endif +/** + * @brief Macro for placing a compile time assertion. + * + * @param expression Expression to evaluate. + */ +#define NRFX_STATIC_ASSERT(expression) + + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif + +//------------------------------------------------------------------------------ + +#ifdef SOFTDEVICE_PRESENT +#define INTERRUPT_PRIORITY_IS_VALID(pri) ((((pri) > 1) && ((pri) < 4)) || \ + (((pri) > 4) && ((pri) < 8))) +#else +#define INTERRUPT_PRIORITY_IS_VALID(pri) ((pri) < 8) +#endif //SOFTDEVICE_PRESENT + +/** + * @brief Macro for setting the priority of a specific IRQ. + * + * @param irq_number IRQ number. + * @param priority Priority to set. + */ +#define NRFX_IRQ_PRIORITY_SET(irq_number, priority) \ + _NRFX_IRQ_PRIORITY_SET(irq_number, priority) +static inline void _NRFX_IRQ_PRIORITY_SET(IRQn_Type irq_number, + uint8_t priority) +{ + //ASSERT(INTERRUPT_PRIORITY_IS_VALID(priority)); + NVIC_SetPriority(irq_number, priority); +} + +/** + * @brief Macro for enabling a specific IRQ. + * + * @param irq_number IRQ number. + */ +#define NRFX_IRQ_ENABLE(irq_number) _NRFX_IRQ_ENABLE(irq_number) +static inline void _NRFX_IRQ_ENABLE(IRQn_Type irq_number) +{ + NVIC_ClearPendingIRQ(irq_number); + NVIC_EnableIRQ(irq_number); +} + +/** + * @brief Macro for checking if a specific IRQ is enabled. + * + * @param irq_number IRQ number. + * + * @retval true If the IRQ is enabled. + * @retval false Otherwise. + */ +#define NRFX_IRQ_IS_ENABLED(irq_number) _NRFX_IRQ_IS_ENABLED(irq_number) +static inline bool _NRFX_IRQ_IS_ENABLED(IRQn_Type irq_number) +{ + return 0 != (NVIC->ISER[irq_number / 32] & (1UL << (irq_number % 32))); +} + +/** + * @brief Macro for disabling a specific IRQ. + * + * @param irq_number IRQ number. + */ +#define NRFX_IRQ_DISABLE(irq_number) _NRFX_IRQ_DISABLE(irq_number) +static inline void _NRFX_IRQ_DISABLE(IRQn_Type irq_number) +{ + NVIC_DisableIRQ(irq_number); +} + +/** + * @brief Macro for setting a specific IRQ as pending. + * + * @param irq_number IRQ number. + */ +#define NRFX_IRQ_PENDING_SET(irq_number) _NRFX_IRQ_PENDING_SET(irq_number) +static inline void _NRFX_IRQ_PENDING_SET(IRQn_Type irq_number) +{ + NVIC_SetPendingIRQ(irq_number); +} + +/** + * @brief Macro for clearing the pending status of a specific IRQ. + * + * @param irq_number IRQ number. + */ +#define NRFX_IRQ_PENDING_CLEAR(irq_number) _NRFX_IRQ_PENDING_CLEAR(irq_number) +static inline void _NRFX_IRQ_PENDING_CLEAR(IRQn_Type irq_number) +{ + NVIC_ClearPendingIRQ(irq_number); +} + +/** + * @brief Macro for checking the pending status of a specific IRQ. + * + * @retval true If the IRQ is pending. + * @retval false Otherwise. + */ +#define NRFX_IRQ_IS_PENDING(irq_number) _NRFX_IRQ_IS_PENDING(irq_number) +static inline bool _NRFX_IRQ_IS_PENDING(IRQn_Type irq_number) +{ + return (NVIC_GetPendingIRQ(irq_number) == 1); +} + +//#include +//#include +/** + * @brief Macro for entering into a critical section. + */ +#define NRFX_CRITICAL_SECTION_ENTER() CRITICAL_REGION_ENTER() + +/** + * @brief Macro for exiting from a critical section. + */ +#define NRFX_CRITICAL_SECTION_EXIT() CRITICAL_REGION_EXIT() + +//------------------------------------------------------------------------------ + +/** + * @brief When set to a non-zero value, this macro specifies that + * @ref nrfx_coredep_delay_us uses a precise DWT-based solution. + * A compilation error is generated if the DWT unit is not present + * in the SoC used. + */ +#define NRFX_DELAY_DWT_BASED 0 + +#include + +#define NRFX_DELAY_US(us_time) nrfx_coredep_delay_us(us_time) + +//------------------------------------------------------------------------------ + +/** + * @brief When set to a non-zero value, this macro specifies that the + * @ref nrfx_error_codes and the @ref ret_code_t type itself are defined + * in a customized way and the default definitions from @c + * should not be used. + */ +#define NRFX_CUSTOM_ERROR_CODES 0 + +//------------------------------------------------------------------------------ + +/** + * @brief Bitmask defining PPI channels reserved to be used outside of nrfx. + */ +#define NRFX_PPI_CHANNELS_USED NRF_PPI_CHANNELS_USED + +/** + * @brief Bitmask defining PPI groups reserved to be used outside of nrfx. + */ +#define NRFX_PPI_GROUPS_USED NRF_PPI_GROUPS_USED + +/** + * @brief Bitmask defining SWI instances reserved to be used outside of nrfx. + */ +#define NRFX_SWI_USED NRF_SWI_USED + +/** + * @brief Bitmask defining TIMER instances reserved to be used outside of nrfx. + */ +#define NRFX_TIMERS_USED NRF_TIMERS_USED + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NRFX_GLUE_H__ diff --git a/ports/nrf/nrfx_log.h b/ports/nrf/nrfx_log.h new file mode 100644 index 00000000000..886eb75f866 --- /dev/null +++ b/ports/nrf/nrfx_log.h @@ -0,0 +1,138 @@ +/** + * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef NRFX_LOG_H__ +#define NRFX_LOG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrfx_log nrfx_log.h + * @{ + * @ingroup nrfx + * + * @brief This file contains macros that should be implemented according to + * the needs of the host environment into which @em nrfx is integrated. + */ + +/** + * @brief Macro for logging a message with the severity level ERROR. + * + * @param format printf-style format string, optionally followed by arguments + * to be formatted and inserted in the resulting string. + */ +#define NRFX_LOG_ERROR(format, ...) + +/** + * @brief Macro for logging a message with the severity level WARNING. + * + * @param format printf-style format string, optionally followed by arguments + * to be formatted and inserted in the resulting string. + */ +#define NRFX_LOG_WARNING(format, ...) + +/** + * @brief Macro for logging a message with the severity level INFO. + * + * @param format printf-style format string, optionally followed by arguments + * to be formatted and inserted in the resulting string. + */ +#define NRFX_LOG_INFO(format, ...) + +/** + * @brief Macro for logging a message with the severity level DEBUG. + * + * @param format printf-style format string, optionally followed by arguments + * to be formatted and inserted in the resulting string. + */ +#define NRFX_LOG_DEBUG(format, ...) + + +/** + * @brief Macro for logging a memory dump with the severity level ERROR. + * + * @param[in] p_memory Pointer to the memory region to be dumped. + * @param[in] length Length of the memory region in bytes. + */ +#define NRFX_LOG_HEXDUMP_ERROR(p_memory, length) + +/** + * @brief Macro for logging a memory dump with the severity level WARNING. + * + * @param[in] p_memory Pointer to the memory region to be dumped. + * @param[in] length Length of the memory region in bytes. + */ +#define NRFX_LOG_HEXDUMP_WARNING(p_memory, length) + +/** + * @brief Macro for logging a memory dump with the severity level INFO. + * + * @param[in] p_memory Pointer to the memory region to be dumped. + * @param[in] length Length of the memory region in bytes. + */ +#define NRFX_LOG_HEXDUMP_INFO(p_memory, length) + +/** + * @brief Macro for logging a memory dump with the severity level DEBUG. + * + * @param[in] p_memory Pointer to the memory region to be dumped. + * @param[in] length Length of the memory region in bytes. + */ +#define NRFX_LOG_HEXDUMP_DEBUG(p_memory, length) + + +/** + * @brief Macro for getting the textual representation of a given error code. + * + * @param[in] error_code Error code. + * + * @return String containing the textual representation of the error code. + */ +#define NRFX_LOG_ERROR_STRING_GET(error_code) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NRFX_LOG_H__ diff --git a/ports/nrf/peripherals/nrf/cache.c b/ports/nrf/peripherals/nrf/cache.c new file mode 100644 index 00000000000..02e11c4613a --- /dev/null +++ b/ports/nrf/peripherals/nrf/cache.c @@ -0,0 +1,38 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "nrfx.h" + +// Turn off cache and invalidate all data in it. +void nrf_peripherals_disable_and_clear_cache(void) { + // Disabling cache also invalidates all cache entries. + NRF_NVMC->ICACHECNF &= ~(1 << NVMC_ICACHECNF_CACHEEN_Pos); +} + +// Enable cache +void nrf_peripherals_enable_cache(void) { + NRF_NVMC->ICACHECNF |= 1 << NVMC_ICACHECNF_CACHEEN_Pos; +} diff --git a/ports/nrf/peripherals/nrf/cache.h b/ports/nrf/peripherals/nrf/cache.h new file mode 100644 index 00000000000..d9ba63f3db6 --- /dev/null +++ b/ports/nrf/peripherals/nrf/cache.h @@ -0,0 +1,28 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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. + */ + +void nrf_peripherals_disable_and_clear_cache(void); +void nrf_peripherals_enable_cache(void); diff --git a/ports/nrf/peripherals/nrf/clocks.c b/ports/nrf/peripherals/nrf/clocks.c new file mode 100644 index 00000000000..269365cc94f --- /dev/null +++ b/ports/nrf/peripherals/nrf/clocks.c @@ -0,0 +1,42 @@ + +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "nrfx.h" +#include "mpconfigport.h" + +void nrf_peripherals_clocks_init(void) { + +#if BOARD_HAS_32KHZ_XTAL + NRF_CLOCK->LFCLKSRC = (uint32_t)((CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk); +#else + NRF_CLOCK->LFCLKSRC = (uint32_t)((CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk); +#endif + NRF_CLOCK->TASKS_LFCLKSTART = 1UL; + + // Wait for clocks to start. + while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {} +} diff --git a/ports/nrf/peripherals/nrf/clocks.h b/ports/nrf/peripherals/nrf/clocks.h new file mode 100644 index 00000000000..e815d849ff5 --- /dev/null +++ b/ports/nrf/peripherals/nrf/clocks.h @@ -0,0 +1,27 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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. + */ + +void nrf_peripherals_clocks_init(void); diff --git a/ports/nrf/peripherals/nrf/nrf52840/pins.c b/ports/nrf/peripherals/nrf/nrf52840/pins.c new file mode 100644 index 00000000000..b7dc8e65e05 --- /dev/null +++ b/ports/nrf/peripherals/nrf/nrf52840/pins.c @@ -0,0 +1,78 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "py/obj.h" +#include "py/mphal.h" +#include "nrf/pins.h" + +const mcu_pin_obj_t pin_P0_00 = PIN(P0_00, 0, 0, 0); +const mcu_pin_obj_t pin_P0_01 = PIN(P0_01, 0, 1, 0); +const mcu_pin_obj_t pin_P0_02 = PIN(P0_02, 0, 2, SAADC_CH_PSELP_PSELP_AnalogInput0); +const mcu_pin_obj_t pin_P0_03 = PIN(P0_03, 0, 3, SAADC_CH_PSELP_PSELP_AnalogInput1); +const mcu_pin_obj_t pin_P0_04 = PIN(P0_04, 0, 4, SAADC_CH_PSELP_PSELP_AnalogInput2); +const mcu_pin_obj_t pin_P0_05 = PIN(P0_05, 0, 5, SAADC_CH_PSELP_PSELP_AnalogInput3); +const mcu_pin_obj_t pin_P0_06 = PIN(P0_06, 0, 6, 0); +const mcu_pin_obj_t pin_P0_07 = PIN(P0_07, 0, 7, 0); +const mcu_pin_obj_t pin_P0_08 = PIN(P0_08, 0, 8, 0); +const mcu_pin_obj_t pin_P0_09 = PIN(P0_09, 0, 9, 0); +const mcu_pin_obj_t pin_P0_10 = PIN(P0_10, 0, 10, 0); +const mcu_pin_obj_t pin_P0_11 = PIN(P0_11, 0, 11, 0); +const mcu_pin_obj_t pin_P0_12 = PIN(P0_12, 0, 12, 0); +const mcu_pin_obj_t pin_P0_13 = PIN(P0_13, 0, 13, 0); +const mcu_pin_obj_t pin_P0_14 = PIN(P0_14, 0, 14, 0); +const mcu_pin_obj_t pin_P0_15 = PIN(P0_15, 0, 15, 0); +const mcu_pin_obj_t pin_P0_16 = PIN(P0_16, 0, 16, 0); +const mcu_pin_obj_t pin_P0_17 = PIN(P0_17, 0, 17, 0); +const mcu_pin_obj_t pin_P0_18 = PIN(P0_18, 0, 18, 0); +const mcu_pin_obj_t pin_P0_19 = PIN(P0_19, 0, 19, 0); +const mcu_pin_obj_t pin_P0_20 = PIN(P0_20, 0, 20, 0); +const mcu_pin_obj_t pin_P0_21 = PIN(P0_21, 0, 21, 0); +const mcu_pin_obj_t pin_P0_22 = PIN(P0_22, 0, 22, 0); +const mcu_pin_obj_t pin_P0_23 = PIN(P0_23, 0, 23, 0); +const mcu_pin_obj_t pin_P0_24 = PIN(P0_24, 0, 24, 0); +const mcu_pin_obj_t pin_P0_25 = PIN(P0_25, 0, 25, 0); +const mcu_pin_obj_t pin_P0_26 = PIN(P0_26, 0, 26, 0); +const mcu_pin_obj_t pin_P0_27 = PIN(P0_27, 0, 27, 0); +const mcu_pin_obj_t pin_P0_28 = PIN(P0_28, 0, 28, SAADC_CH_PSELP_PSELP_AnalogInput4); +const mcu_pin_obj_t pin_P0_29 = PIN(P0_29, 0, 29, SAADC_CH_PSELP_PSELP_AnalogInput5); +const mcu_pin_obj_t pin_P0_30 = PIN(P0_30, 0, 30, SAADC_CH_PSELP_PSELP_AnalogInput6); +const mcu_pin_obj_t pin_P0_31 = PIN(P0_31, 0, 31, SAADC_CH_PSELP_PSELP_AnalogInput7); +const mcu_pin_obj_t pin_P1_00 = PIN(P1_00, 1, 0, 0); +const mcu_pin_obj_t pin_P1_01 = PIN(P1_01, 1, 1, 0); +const mcu_pin_obj_t pin_P1_02 = PIN(P1_02, 1, 2, 0); +const mcu_pin_obj_t pin_P1_03 = PIN(P1_03, 1, 3, 0); +const mcu_pin_obj_t pin_P1_04 = PIN(P1_04, 1, 4, 0); +const mcu_pin_obj_t pin_P1_05 = PIN(P1_05, 1, 5, 0); +const mcu_pin_obj_t pin_P1_06 = PIN(P1_06, 1, 6, 0); +const mcu_pin_obj_t pin_P1_07 = PIN(P1_07, 1, 7, 0); +const mcu_pin_obj_t pin_P1_08 = PIN(P1_08, 1, 8, 0); +const mcu_pin_obj_t pin_P1_09 = PIN(P1_09, 1, 9, 0); +const mcu_pin_obj_t pin_P1_10 = PIN(P1_10, 1, 10, 0); +const mcu_pin_obj_t pin_P1_11 = PIN(P1_11, 1, 11, 0); +const mcu_pin_obj_t pin_P1_12 = PIN(P1_12, 1, 12, 0); +const mcu_pin_obj_t pin_P1_13 = PIN(P1_13, 1, 13, 0); +const mcu_pin_obj_t pin_P1_14 = PIN(P1_14, 1, 14, 0); +const mcu_pin_obj_t pin_P1_15 = PIN(P1_15, 1, 15, 0); diff --git a/ports/nrf/peripherals/nrf/nrf52840/pins.h b/ports/nrf/peripherals/nrf/nrf52840/pins.h new file mode 100644 index 00000000000..3ad72ff6327 --- /dev/null +++ b/ports/nrf/peripherals/nrf/nrf52840/pins.h @@ -0,0 +1,79 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 by Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_PERIPHERALS_NRF52840_PINS_H +#define MICROPY_INCLUDED_NRF_PERIPHERALS_NRF52840_PINS_H + +extern const mcu_pin_obj_t pin_P0_00; +extern const mcu_pin_obj_t pin_P0_01; +extern const mcu_pin_obj_t pin_P0_02; +extern const mcu_pin_obj_t pin_P0_03; +extern const mcu_pin_obj_t pin_P0_04; +extern const mcu_pin_obj_t pin_P0_05; +extern const mcu_pin_obj_t pin_P0_06; +extern const mcu_pin_obj_t pin_P0_07; +extern const mcu_pin_obj_t pin_P0_08; +extern const mcu_pin_obj_t pin_P0_09; +extern const mcu_pin_obj_t pin_P0_10; +extern const mcu_pin_obj_t pin_P0_11; +extern const mcu_pin_obj_t pin_P0_12; +extern const mcu_pin_obj_t pin_P0_13; +extern const mcu_pin_obj_t pin_P0_14; +extern const mcu_pin_obj_t pin_P0_15; +extern const mcu_pin_obj_t pin_P0_16; +extern const mcu_pin_obj_t pin_P0_17; +extern const mcu_pin_obj_t pin_P0_18; +extern const mcu_pin_obj_t pin_P0_19; +extern const mcu_pin_obj_t pin_P0_20; +extern const mcu_pin_obj_t pin_P0_21; +extern const mcu_pin_obj_t pin_P0_22; +extern const mcu_pin_obj_t pin_P0_23; +extern const mcu_pin_obj_t pin_P0_24; +extern const mcu_pin_obj_t pin_P0_25; +extern const mcu_pin_obj_t pin_P0_26; +extern const mcu_pin_obj_t pin_P0_27; +extern const mcu_pin_obj_t pin_P0_28; +extern const mcu_pin_obj_t pin_P0_29; +extern const mcu_pin_obj_t pin_P0_30; +extern const mcu_pin_obj_t pin_P0_31; +extern const mcu_pin_obj_t pin_P1_00; +extern const mcu_pin_obj_t pin_P1_01; +extern const mcu_pin_obj_t pin_P1_02; +extern const mcu_pin_obj_t pin_P1_03; +extern const mcu_pin_obj_t pin_P1_04; +extern const mcu_pin_obj_t pin_P1_05; +extern const mcu_pin_obj_t pin_P1_06; +extern const mcu_pin_obj_t pin_P1_07; +extern const mcu_pin_obj_t pin_P1_08; +extern const mcu_pin_obj_t pin_P1_09; +extern const mcu_pin_obj_t pin_P1_10; +extern const mcu_pin_obj_t pin_P1_11; +extern const mcu_pin_obj_t pin_P1_12; +extern const mcu_pin_obj_t pin_P1_13; +extern const mcu_pin_obj_t pin_P1_14; +extern const mcu_pin_obj_t pin_P1_15; + +#endif // MICROPY_INCLUDED_NRF_PERIPHERALS_NRF52840_PINS_H diff --git a/ports/nrf/peripherals/nrf/nrf52840/power.c b/ports/nrf/peripherals/nrf/nrf52840/power.c new file mode 100644 index 00000000000..9f7a9fa17ae --- /dev/null +++ b/ports/nrf/peripherals/nrf/nrf52840/power.c @@ -0,0 +1,40 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "nrfx.h" +#include "nrf_nvmc.h" + +void nrf_peripherals_power_init(void) { + // Set GPIO reference voltage to 3.3V if it isn't already. REGOUT0 will get reset to 0xfffffff + // if flash is erased, which sets the default to 1.8V + // This matters only when "high voltage mode" is enabled, which is true on the PCA10059, + // and might be true on other boards. + if (NRF_UICR->REGOUT0 == 0xffffffff) { + nrf_nvmc_write_word((uint32_t) &NRF_UICR->REGOUT0, UICR_REGOUT0_VOUT_3V3 << UICR_REGOUT0_VOUT_Pos); + // Must reset to make enable change. + NVIC_SystemReset(); + } +} diff --git a/ports/nrf/peripherals/nrf/nvm.c b/ports/nrf/peripherals/nrf/nvm.c new file mode 100644 index 00000000000..d8fddc4dcf6 --- /dev/null +++ b/ports/nrf/peripherals/nrf/nvm.c @@ -0,0 +1,95 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2019 Nick Moore for Adafruit Industries + * + * 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 "py/runtime.h" + +#include +#include + +#include "nrf_nvmc.h" + +#define FLASH_PAGE_SIZE (4096) + +#ifdef BLUETOOTH_SD +#include "ble_drv.h" +#include "nrf_sdm.h" + +STATIC void sd_flash_operation_start(void) { + sd_flash_operation_status = SD_FLASH_OPERATION_IN_PROGRESS; +} + +STATIC sd_flash_operation_status_t sd_flash_operation_wait_until_done(void) { + while (sd_flash_operation_status == SD_FLASH_OPERATION_IN_PROGRESS) { + sd_app_evt_wait(); + } + return sd_flash_operation_status; +} +#endif + +void nrf_nvm_safe_flash_page_write(uint32_t page_addr, uint8_t *data) { + #ifdef BLUETOOTH_SD + uint8_t sd_en = 0; + (void) sd_softdevice_is_enabled(&sd_en); + if (sd_en) { + uint32_t err_code; + sd_flash_operation_status_t status; + + sd_flash_operation_start(); + err_code = sd_flash_page_erase(page_addr / FLASH_PAGE_SIZE); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Flash erase failed to start, err 0x%04x"), err_code); + } + status = sd_flash_operation_wait_until_done(); + if (status == SD_FLASH_OPERATION_ERROR) { + mp_raise_OSError_msg(translate("Flash erase failed")); + } + + // Divide a full page into parts, because writing a full page causes an assertion failure. + // See https://devzone.nordicsemi.com/f/nordic-q-a/40088/sd_flash_write-cause-nrf_fault_id_sd_assert/ + const size_t BLOCK_PARTS = 2; + size_t words_to_write = FLASH_PAGE_SIZE / sizeof(uint32_t) / BLOCK_PARTS; + for (size_t i = 0; i < BLOCK_PARTS; i++) { + sd_flash_operation_start(); + err_code = sd_flash_write(((uint32_t *)page_addr) + i * words_to_write, + (uint32_t *)data + i * words_to_write, + words_to_write); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Flash write failed to start, err 0x%04x"), err_code); + } + status = sd_flash_operation_wait_until_done(); + if (status == SD_FLASH_OPERATION_ERROR) { + mp_raise_OSError_msg(translate("Flash write failed")); + } + } + + return; + } + #endif + + nrf_nvmc_page_erase(page_addr); + nrf_nvmc_write_bytes(page_addr, data, FLASH_PAGE_SIZE); +} diff --git a/ports/nrf/peripherals/nrf/nvm.h b/ports/nrf/peripherals/nrf/nvm.h new file mode 100644 index 00000000000..4eac3d7283b --- /dev/null +++ b/ports/nrf/peripherals/nrf/nvm.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2019 Nick Moore for Adafruit Industries + * + * 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 FLASH_PAGE_SIZE (4096) + +#ifndef CIRCUITPY_INTERNAL_NVM_SIZE +#define CIRCUITPY_INTERNAL_NVM_SIZE (0) +#endif + +void nrf_nvm_safe_flash_page_write(uint32_t page_addr, uint8_t *data); diff --git a/ports/nrf/peripherals/nrf/pins.h b/ports/nrf/peripherals/nrf/pins.h new file mode 100644 index 00000000000..3a4c995790b --- /dev/null +++ b/ports/nrf/peripherals/nrf/pins.h @@ -0,0 +1,64 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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. + */ + +// DO NOT include this file directly. Use shared-bindings/microcontroller/Pin.h instead to ensure +// that all necessary includes are already included. + +#ifndef __MICROPY_INCLUDED_NRF_PERIPHERALS_PINS_H__ +#define __MICROPY_INCLUDED_NRF_PERIPHERALS_PINS_H__ + +#include +#include + +#include "nrf_gpio.h" + +typedef struct { + mp_obj_base_t base; + // These could be squeezed to fewer bits if more fields are needed. + uint8_t number; // port << 5 | pin number in port (0-31): 6 bits needed + uint8_t adc_channel; // 0 is no ADC, ADC channel from 1 to 8: + // 4 bits needed here; 5 bits used in periph registers +} mcu_pin_obj_t; + +extern const mp_obj_type_t mcu_pin_type; + +// Used in device-specific pins.c +#define PIN(p_name, p_port, p_pin, p_adc_channel) \ +{ \ + { &mcu_pin_type }, \ + .number = NRF_GPIO_PIN_MAP(p_port, p_pin), \ + .adc_channel = (p_adc_channel), \ +} + +// Use illegal pin value to mark unassigned pins. +#define NO_PIN 0xff + +// Choose based on chip, but not specifically revision (e.g., not NRF52840_XXAA) +#ifdef NRF52840 +#include "nrf52840/pins.h" +#endif + +#endif // __MICROPY_INCLUDED_NRF_PERIPHERALS_PINS_H__ diff --git a/ports/nrf/peripherals/nrf/power.h b/ports/nrf/peripherals/nrf/power.h new file mode 100644 index 00000000000..c3744618cac --- /dev/null +++ b/ports/nrf/peripherals/nrf/power.h @@ -0,0 +1,27 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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. + */ + +void nrf_peripherals_power_init(void); diff --git a/ports/nrf/peripherals/nrf/timers.c b/ports/nrf/peripherals/nrf/timers.c new file mode 100644 index 00000000000..88f3dd4681b --- /dev/null +++ b/ports/nrf/peripherals/nrf/timers.c @@ -0,0 +1,88 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "common-hal/pulseio/PulseOut.h" + +#include + +#include "nrfx.h" +#include "nrfx_timer.h" + +#include "py/mpconfig.h" +#include "py/runtime.h" + +STATIC nrfx_timer_t nrfx_timers[] = { +#if NRFX_CHECK(NRFX_TIMER0_ENABLED) + #error NRFX_TIMER0_ENABLED should not be on: TIMER0 is used by the SoftDevice + NRFX_TIMER_INSTANCE(0), +#endif +#if NRFX_CHECK(NRFX_TIMER1_ENABLED) + NRFX_TIMER_INSTANCE(1), +#endif +#if NRFX_CHECK(NRFX_TIMER2_ENABLED) + NRFX_TIMER_INSTANCE(2), +#endif +#if NRFX_CHECK(NRFX_TIMER3_ENABLED) + NRFX_TIMER_INSTANCE(3), +#endif +#if NRFX_CHECK(NRFX_TIMER4_ENABLED) + NRFX_TIMER_INSTANCE(4), +#endif +}; + +static bool nrfx_timer_allocated[ARRAY_SIZE(nrfx_timers)]; + +void timers_reset(void) { + for (size_t i = 0; i < ARRAY_SIZE(nrfx_timers); i ++) { + nrfx_timer_uninit(&nrfx_timers[i]); + nrfx_timer_allocated[i] = false; + } +} + +// Returns a free nrfx_timer instance, and marks it as allocated. +// The caller should init as with the desired config. +// Returns NULL if no timer is available. +nrfx_timer_t* nrf_peripherals_allocate_timer(void) { + for (size_t i = 0; i < ARRAY_SIZE(nrfx_timers); i ++) { + if (!nrfx_timer_allocated[i]) { + nrfx_timer_allocated[i] = true; + return &nrfx_timers[i]; + } + } + return NULL; +} + +// Free a timer, which may or may not have been initialized. +void nrf_peripherals_free_timer(nrfx_timer_t* timer) { + for (size_t i = 0; i < ARRAY_SIZE(nrfx_timers); i ++) { + if (timer == &nrfx_timers[i]) { + nrfx_timer_allocated[i] = false; + // Safe to call even if not initialized. + nrfx_timer_uninit(timer); + return; + } + } +} diff --git a/ports/nrf/peripherals/nrf/timers.h b/ports/nrf/peripherals/nrf/timers.h new file mode 100644 index 00000000000..7d3815579af --- /dev/null +++ b/ports/nrf/peripherals/nrf/timers.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "nrfx.h" +#include "nrfx_timer.h" + +void timers_reset(void); +nrfx_timer_t* nrf_peripherals_allocate_timer(void); +void nrf_peripherals_free_timer(nrfx_timer_t* timer); diff --git a/ports/nrf/qstrdefsport.h b/ports/nrf/qstrdefsport.h new file mode 100644 index 00000000000..3ba897069bf --- /dev/null +++ b/ports/nrf/qstrdefsport.h @@ -0,0 +1 @@ +// qstrs specific to this port diff --git a/ports/nrf/sd_mutex.c b/ports/nrf/sd_mutex.c new file mode 100644 index 00000000000..b3162e6af92 --- /dev/null +++ b/ports/nrf/sd_mutex.c @@ -0,0 +1,54 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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 "py/mpconfig.h" +#include "py/runtime.h" +#include "nrf_soc.h" + +void sd_mutex_acquire_check(nrf_mutex_t* p_mutex) { + uint32_t err_code = sd_mutex_acquire(p_mutex); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to acquire mutex, err 0x%04x"), err_code); + } +} + +void sd_mutex_acquire_wait(nrf_mutex_t* p_mutex) { + while (sd_mutex_acquire(p_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { + RUN_BACKGROUND_TASKS; + } +} + +void sd_mutex_acquire_wait_no_vm(nrf_mutex_t* p_mutex) { + while (sd_mutex_acquire(p_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { + } +} + +void sd_mutex_release_check(nrf_mutex_t* p_mutex) { + uint32_t err_code = sd_mutex_release(p_mutex); + if (err_code != NRF_SUCCESS) { + mp_raise_OSError_msg_varg(translate("Failed to release mutex, err 0x%04x"), err_code); + } +} diff --git a/ports/nrf/sd_mutex.h b/ports/nrf/sd_mutex.h new file mode 100644 index 00000000000..ca46917205b --- /dev/null +++ b/ports/nrf/sd_mutex.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_NRF_SD_MUTEX_H +#define MICROPY_INCLUDED_NRF_SD_MUTEX_H + +#include "nrf_soc.h" + +// Helpers for common usage of nrf_mutex. + +// Try to acquire a mutex right now. Raise exception if we can't get it. +void sd_mutex_acquire_check(nrf_mutex_t* p_mutex); + +// Wait for a mutex to become available. Run VM background tasks while waiting. +void sd_mutex_acquire_wait(nrf_mutex_t* p_mutex); + +// Wait for a mutex to become available.. Block VM while waiting. +void sd_mutex_acquire_wait_no_vm(nrf_mutex_t* p_mutex); + +// Release a mutex, and raise exception on error. +void sd_mutex_release_check(nrf_mutex_t* p_mutex); + +#endif // MICROPY_INCLUDED_NRF_SD_MUTEX_H diff --git a/ports/nrf/supervisor/cpu.s b/ports/nrf/supervisor/cpu.s new file mode 100755 index 00000000000..9e6807a5e2e --- /dev/null +++ b/ports/nrf/supervisor/cpu.s @@ -0,0 +1,27 @@ +.syntax unified +.cpu cortex-m4 +.thumb +.text +.align 2 + +@ uint cpu_get_regs_and_sp(r0=uint regs[10]) +.global cpu_get_regs_and_sp +.thumb +.thumb_func +.type cpu_get_regs_and_sp, %function +cpu_get_regs_and_sp: +@ store registers into given array +str r4, [r0], #4 +str r5, [r0], #4 +str r6, [r0], #4 +str r7, [r0], #4 +str r8, [r0], #4 +str r9, [r0], #4 +str r10, [r0], #4 +str r11, [r0], #4 +str r12, [r0], #4 +str r13, [r0], #4 + +@ return the sp +mov r0, sp +bx lr diff --git a/ports/nrf/supervisor/internal_flash.c b/ports/nrf/supervisor/internal_flash.c new file mode 100644 index 00000000000..dcacd4d27f4 --- /dev/null +++ b/ports/nrf/supervisor/internal_flash.c @@ -0,0 +1,123 @@ +/* + * This file is part of the MicroPython 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 "supervisor/flash.h" + +#include +#include + +#include "extmod/vfs.h" +#include "extmod/vfs_fat.h" +#include "py/mphal.h" +#include "py/obj.h" +#include "py/runtime.h" +#include "lib/oofatfs/ff.h" + +#include "peripherals/nrf/nvm.h" + +#ifdef BLUETOOTH_SD +#include "ble_drv.h" +#include "nrf_sdm.h" +#endif + +// defined in linker +extern uint32_t __fatfs_flash_start_addr[]; +extern uint32_t __fatfs_flash_length[]; + +#define NO_CACHE 0xffffffff + +uint8_t _flash_cache[FLASH_PAGE_SIZE] __attribute__((aligned(4))); +uint32_t _flash_page_addr = NO_CACHE; + + +/*------------------------------------------------------------------*/ +/* Internal Flash API + *------------------------------------------------------------------*/ +static inline uint32_t lba2addr(uint32_t block) { + return ((uint32_t)__fatfs_flash_start_addr) + block * FILESYSTEM_BLOCK_SIZE; +} + +void supervisor_flash_init(void) { +} + +uint32_t supervisor_flash_get_block_size(void) { + return FILESYSTEM_BLOCK_SIZE; +} + +uint32_t supervisor_flash_get_block_count(void) { + return ((uint32_t) __fatfs_flash_length - CIRCUITPY_INTERNAL_NVM_SIZE) / FILESYSTEM_BLOCK_SIZE ; +} + +void supervisor_flash_flush(void) { + if (_flash_page_addr == NO_CACHE) return; + + // Skip if data is the same + if (memcmp(_flash_cache, (void *)_flash_page_addr, FLASH_PAGE_SIZE) != 0) { + nrf_nvm_safe_flash_page_write(_flash_page_addr, _flash_cache); + } +} + +mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { + // Must write out anything in cache before trying to read. + supervisor_flash_flush(); + + uint32_t src = lba2addr(block); + memcpy(dest, (uint8_t*) src, FILESYSTEM_BLOCK_SIZE*num_blocks); + return 0; // success +} + +mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks) { + while (num_blocks) { + uint32_t const addr = lba2addr(lba); + uint32_t const page_addr = addr & ~(FLASH_PAGE_SIZE - 1); + + uint32_t count = 8 - (lba % 8); // up to page boundary + count = MIN(num_blocks, count); + + if (page_addr != _flash_page_addr) { + // Write out anything in cache before overwriting it. + supervisor_flash_flush(); + + _flash_page_addr = page_addr; + + // Copy the current contents of the entire page into the cache. + memcpy(_flash_cache, (void *)page_addr, FLASH_PAGE_SIZE); + } + + // Overwrite part or all of the page cache with the src data. + memcpy(_flash_cache + (addr & (FLASH_PAGE_SIZE - 1)), src, count * FILESYSTEM_BLOCK_SIZE); + + // adjust for next run + lba += count; + src += count * FILESYSTEM_BLOCK_SIZE; + num_blocks -= count; + } + + return 0; // success +} + +void supervisor_flash_release_cache(void) { +} + diff --git a/ports/nrf/supervisor/internal_flash.h b/ports/nrf/supervisor/internal_flash.h new file mode 100644 index 00000000000..024a53ebba0 --- /dev/null +++ b/ports/nrf/supervisor/internal_flash.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython 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. + */ +#ifndef MICROPY_INCLUDED_NRF_INTERNAL_FLASH_H +#define MICROPY_INCLUDED_NRF_INTERNAL_FLASH_H + +#include +#include + +#include "py/mpconfig.h" + +#define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms +#define INTERNAL_FLASH_IDLE_TICK(tick) (((tick) & INTERNAL_FLASH_SYSTICK_MASK) == 2) + +#endif // MICROPY_INCLUDED_NRF_INTERNAL_FLASH_H diff --git a/ports/nrf/supervisor/internal_flash_root_pointers.h b/ports/nrf/supervisor/internal_flash_root_pointers.h new file mode 100644 index 00000000000..cc6074585ed --- /dev/null +++ b/ports/nrf/supervisor/internal_flash_root_pointers.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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. + */ +#ifndef MICROPY_INCLUDED_NRF_INTERNAL_FLASH_ROOT_POINTERS_H +#define MICROPY_INCLUDED_NRF_INTERNAL_FLASH_ROOT_POINTERS_H + +#define FLASH_ROOT_POINTERS + +#endif // MICROPY_INCLUDED_NRF_INTERNAL_FLASH_ROOT_POINTERS_H diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c new file mode 100644 index 00000000000..8e558358165 --- /dev/null +++ b/ports/nrf/supervisor/port.c @@ -0,0 +1,150 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 +#include "supervisor/port.h" +#include "boards/board.h" + +#include "nrfx/hal/nrf_power.h" +#include "nrfx/drivers/include/nrfx_power.h" + +#include "nrf/cache.h" +#include "nrf/clocks.h" +#include "nrf/power.h" +#include "nrf/timers.h" + +#include "shared-module/gamepad/__init__.h" +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/_bleio/__init__.h" +#include "common-hal/busio/I2C.h" +#include "common-hal/busio/SPI.h" +#include "common-hal/busio/UART.h" +#include "common-hal/pulseio/PWMOut.h" +#include "common-hal/pulseio/PulseOut.h" +#include "common-hal/pulseio/PulseIn.h" +#include "common-hal/rtc/RTC.h" +#include "tick.h" + +#include "shared-bindings/rtc/__init__.h" + +#ifdef CIRCUITPY_AUDIOPWMIO +#include "common-hal/audiopwmio/PWMAudioOut.h" +#endif + +static void power_warning_handler(void) { + reset_into_safe_mode(BROWNOUT); +} + +safe_mode_t port_init(void) { + nrf_peripherals_clocks_init(); + + // If GPIO voltage is set wrong in UICR, this will fix it, and + // will also do a reset to make the change take effect. + nrf_peripherals_power_init(); + + nrfx_power_pofwarn_config_t power_failure_config; + power_failure_config.handler = power_warning_handler; + power_failure_config.thr = NRF_POWER_POFTHR_V27; + #if NRF_POWER_HAS_VDDH + power_failure_config.thrvddh = NRF_POWER_POFTHRVDDH_V27; + #endif + nrfx_power_pof_init(&power_failure_config); + nrfx_power_pof_enable(&power_failure_config); + + nrf_peripherals_enable_cache(); + + // Configure millisecond timer initialization. + tick_init(); + + #if CIRCUITPY_RTC + rtc_init(); + #endif + + // Will do usb_init() if chip supports USB. + board_init(); + + return NO_SAFE_MODE; +} + +void reset_port(void) { +#ifdef CIRCUITPY_GAMEPAD_TICKS + gamepad_reset(); +#endif + + i2c_reset(); + spi_reset(); + uart_reset(); + +#ifdef CIRCUITPY_AUDIOPWMIO + audiopwmout_reset(); +#endif + +#if CIRCUITPY_PULSEIO + pwmout_reset(); + pulseout_reset(); + pulsein_reset(); +#endif + + timers_reset(); + +#if CIRCUITPY_RTC + rtc_reset(); +#endif + +#if CIRCUITPY_BLEIO + bleio_reset(); +#endif + + reset_all_pins(); +} + +void reset_to_bootloader(void) { + enum { DFU_MAGIC_SERIAL = 0x4e }; + + NRF_POWER->GPREGRET = DFU_MAGIC_SERIAL; + reset_cpu(); +} + +void reset_cpu(void) { + NVIC_SystemReset(); +} + +extern uint32_t _ebss; +// Place the word to save just after our BSS section that gets blanked. +void port_set_saved_word(uint32_t value) { + _ebss = value; +} + +uint32_t port_get_saved_word(void) { + return _ebss; +} + +void HardFault_Handler(void) { + reset_into_safe_mode(HARD_CRASH); + while (true) { + asm("nop;"); + } +} diff --git a/ports/nrf/supervisor/qspi_flash.c b/ports/nrf/supervisor/qspi_flash.c new file mode 100644 index 00000000000..bb449d881cb --- /dev/null +++ b/ports/nrf/supervisor/qspi_flash.c @@ -0,0 +1,157 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/spi_flash_api.h" + +#include +#include + +#include "py/mpconfig.h" // for EXTERNAL_FLASH_QSPI_DUAL +#include "nrfx_qspi.h" + +#include "shared-bindings/microcontroller/__init__.h" + +#include "supervisor/shared/external_flash/common_commands.h" +#include "supervisor/shared/external_flash/qspi_flash.h" + +bool spi_flash_command(uint8_t command) { + nrf_qspi_cinstr_conf_t cinstr_cfg = { + .opcode = command, + .length = 1, + .io2_level = true, + .io3_level = true, + .wipwait = false, + .wren = false + }; + return nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL) == NRFX_SUCCESS; +} + +bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length) { + nrf_qspi_cinstr_conf_t cinstr_cfg = { + .opcode = command, + .length = length + 1, + .io2_level = true, + .io3_level = true, + .wipwait = false, + .wren = false + }; + return nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, response) == NRFX_SUCCESS; + +} + +bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) { + nrf_qspi_cinstr_conf_t cinstr_cfg = { + .opcode = command, + .length = length + 1, + .io2_level = true, + .io3_level = true, + .wipwait = false, + .wren = false // We do this manually. + }; + return nrfx_qspi_cinstr_xfer(&cinstr_cfg, data, NULL) == NRFX_SUCCESS; +} + +bool spi_flash_sector_command(uint8_t command, uint32_t address) { + if (command != CMD_SECTOR_ERASE) { + return false; + } + return nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, address) == NRFX_SUCCESS; +} + +bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) { + return nrfx_qspi_write(data, length, address) == NRFX_SUCCESS; +} + +bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t length) { + return nrfx_qspi_read(data, length, address) == NRFX_SUCCESS; +} + +void spi_flash_init(void) { + // Init QSPI flash + nrfx_qspi_config_t qspi_cfg = { + .xip_offset = 0, + .pins = { + .sck_pin = MICROPY_QSPI_SCK, + .csn_pin = MICROPY_QSPI_CS, + .io0_pin = MICROPY_QSPI_DATA0, + .io1_pin = NRF_QSPI_PIN_NOT_CONNECTED, + .io2_pin = NRF_QSPI_PIN_NOT_CONNECTED, + .io3_pin = NRF_QSPI_PIN_NOT_CONNECTED, + + }, + .prot_if = { + .readoc = NRF_QSPI_READOC_FASTREAD, + .writeoc = NRF_QSPI_WRITEOC_PP, + .addrmode = NRF_QSPI_ADDRMODE_24BIT, + .dpmconfig = false + }, + .phy_if = { + .sck_freq = NRF_QSPI_FREQ_32MDIV16, // Start at a slow 2MHz and speed up once we know what we're talking to. + .sck_delay = 10, // min time CS must stay high before going low again. in unit of 62.5 ns + .spi_mode = NRF_QSPI_MODE_0, + .dpmen = false + }, + .irq_priority = 7, + }; + +#if EXTERNAL_FLASH_QSPI_DUAL + qspi_cfg.pins.io1_pin = MICROPY_QSPI_DATA1; + qspi_cfg.prot_if.readoc = NRF_QSPI_READOC_READ2O; + qspi_cfg.prot_if.writeoc = NRF_QSPI_WRITEOC_PP2O; +#else + qspi_cfg.pins.io1_pin = MICROPY_QSPI_DATA1; + qspi_cfg.pins.io2_pin = MICROPY_QSPI_DATA2; + qspi_cfg.pins.io3_pin = MICROPY_QSPI_DATA3; + qspi_cfg.prot_if.readoc = NRF_QSPI_READOC_READ4IO; + qspi_cfg.prot_if.writeoc = NRF_QSPI_WRITEOC_PP4O; +#endif + + // No callback for blocking API + nrfx_qspi_init(&qspi_cfg, NULL, NULL); +} + +void spi_flash_init_device(const external_flash_device* device) { + check_quad_enable(device); + + // Switch to single output line if the device doesn't support quad programs. + if (!device->supports_qspi_writes) { + NRF_QSPI->IFCONFIG0 &= ~QSPI_IFCONFIG0_WRITEOC_Msk; + NRF_QSPI->IFCONFIG0 |= QSPI_IFCONFIG0_WRITEOC_PP << QSPI_IFCONFIG0_WRITEOC_Pos; + } + + // Speed up as much as we can. + // Start at 16 MHz and go down. + // At 32 MHz GD25Q16C doesn't work reliably on Feather 52840, even though it should work up to 104 MHz. + // sckfreq = 0 is 32 Mhz + // sckfreq = 1 is 16 MHz, etc. + uint8_t sckfreq = 1; + while (32000000 / (sckfreq + 1) > device->max_clock_speed_mhz * 1000000 && sckfreq < 16) { + sckfreq += 1; + } + NRF_QSPI->IFCONFIG1 &= ~QSPI_IFCONFIG1_SCKFREQ_Msk; + NRF_QSPI->IFCONFIG1 |= sckfreq << QSPI_IFCONFIG1_SCKFREQ_Pos; +} diff --git a/ports/nrf/supervisor/serial.c b/ports/nrf/supervisor/serial.c new file mode 100644 index 00000000000..6fd89eb3ea3 --- /dev/null +++ b/ports/nrf/supervisor/serial.c @@ -0,0 +1,127 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "py/mphal.h" + +#include "supervisor/serial.h" + +#if (MICROPY_PY_BLE_NUS == 1) +#include "ble_uart.h" +#else +#include +#include "nrf_gpio.h" +#include "nrfx_uarte.h" +#endif + +#if (MICROPY_PY_BLE_NUS == 1) + +void serial_init(void) { + ble_uart_init(); +} + +bool serial_connected(void) { + return ble_uart_connected(); +} + +char serial_read(void) { + return (char) ble_uart_rx_chr(); +} + +bool serial_bytes_available(void) { + return ble_uart_stdin_any(); +} + +void serial_write(const char *text) { + ble_uart_stdout_tx_str(text); +} + +#elif !defined(NRF52840_XXAA) + +uint8_t serial_received_char; +nrfx_uarte_t serial_instance = NRFX_UARTE_INSTANCE(0); + +void serial_init(void) { + nrfx_uarte_config_t config = { + .pseltxd = MICROPY_HW_UART_TX, + .pselrxd = MICROPY_HW_UART_RX, + .pselcts = NRF_UARTE_PSEL_DISCONNECTED, + .pselrts = NRF_UARTE_PSEL_DISCONNECTED, + .p_context = NULL, + .hwfc = NRF_UARTE_HWFC_DISABLED, + .parity = NRF_UARTE_PARITY_EXCLUDED, + .baudrate = NRF_UARTE_BAUDRATE_115200, + .interrupt_priority = 7 + }; + + nrfx_uarte_uninit(&serial_instance); + const nrfx_err_t err = nrfx_uarte_init(&serial_instance, &config, NULL); // no callback for blocking mode + + if (err != NRFX_SUCCESS) { + NRFX_ASSERT(err); + } + + // enabled receiving + nrf_uarte_task_trigger(serial_instance.p_reg, NRF_UARTE_TASK_STARTRX); +} + +bool serial_connected(void) { + return true; +} + +char serial_read(void) { + uint8_t data; + nrfx_uarte_rx(&serial_instance, &data, 1); + return data; +} + +bool serial_bytes_available(void) { + return nrf_uarte_event_check(serial_instance.p_reg, NRF_UARTE_EVENT_RXDRDY); +} + +void serial_write(const char* text) { + serial_write_substring(text, strlen(text)); +} + +void serial_write_substring(const char *text, uint32_t len) { + if (len == 0) { + return; + } + + // EasyDMA can only access SRAM + uint8_t * tx_buf = (uint8_t*) text; + if ( !nrfx_is_in_ram(text) ) { + tx_buf = (uint8_t *) m_malloc(len, false); + memcpy(tx_buf, text, len); + } + + nrfx_uarte_tx(&serial_instance, tx_buf, len); + + if ( !nrfx_is_in_ram(text) ) { + m_free(tx_buf); + } +} + +#endif diff --git a/ports/nrf/supervisor/usb.c b/ports/nrf/supervisor/usb.c new file mode 100644 index 00000000000..bb9d78101cb --- /dev/null +++ b/ports/nrf/supervisor/usb.c @@ -0,0 +1,89 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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 "nrfx.h" +#include "nrfx_power.h" +#include "tick.h" +#include "supervisor/usb.h" +#include "lib/utils/interrupt_char.h" +#include "lib/mp-readline/readline.h" + +#ifdef SOFTDEVICE_PRESENT +#include "nrf_sdm.h" +#include "nrf_soc.h" +#endif + +// tinyusb function that handles power event (detected, ready, removed) +// We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled. +extern void tusb_hal_nrf_power_event(uint32_t event); + +void init_usb_hardware(void) { + + // 2 is max priority (0, 1 are reserved for SD) + NVIC_SetPriority(USBD_IRQn, 2); + + // USB power may already be ready at this time -> no event generated + // We need to invoke the handler based on the status initially for the first call + static bool first_call = true; + uint32_t usb_reg; + +#ifdef SOFTDEVICE_PRESENT + uint8_t sd_en = false; + (void) sd_softdevice_is_enabled(&sd_en); + + if ( sd_en ) { + sd_power_usbdetected_enable(true); + sd_power_usbpwrrdy_enable(true); + sd_power_usbremoved_enable(true); + + sd_power_usbregstatus_get(&usb_reg); + }else +#endif + { + // Power module init + const nrfx_power_config_t pwr_cfg = { 0 }; + nrfx_power_init(&pwr_cfg); + + // Register tusb function as USB power handler + const nrfx_power_usbevt_config_t config = { .handler = (nrfx_power_usb_event_handler_t) tusb_hal_nrf_power_event }; + nrfx_power_usbevt_init(&config); + + nrfx_power_usbevt_enable(); + + usb_reg = NRF_POWER->USBREGSTATUS; + } + + if ( first_call ) { + first_call = false; + if ( usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk ) { + tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED); + } + + if ( usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk ) { + tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY); + } + } +} diff --git a/ports/nrf/tick.c b/ports/nrf/tick.c new file mode 100644 index 00000000000..6d8fd13e0a8 --- /dev/null +++ b/ports/nrf/tick.c @@ -0,0 +1,84 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "tick.h" + +#include "supervisor/shared/autoreload.h" +#include "supervisor/filesystem.h" +#include "shared-module/gamepad/__init__.h" +#include "shared-bindings/microcontroller/Processor.h" +#include "nrf.h" + +// Global millisecond tick count +volatile uint64_t ticks_ms = 0; + +void SysTick_Handler(void) { + // SysTick interrupt handler called when the SysTick timer reaches zero + // (every millisecond). + ticks_ms += 1; + +#if CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS > 0 + filesystem_tick(); +#endif +#ifdef CIRCUITPY_AUTORELOAD_DELAY_MS + autoreload_tick(); +#endif +#ifdef CIRCUITPY_GAMEPAD_TICKS + if (!(ticks_ms & CIRCUITPY_GAMEPAD_TICKS)) { + gamepad_tick(); + } +#endif +} + +void tick_init() { + uint32_t ticks_per_ms = common_hal_mcu_processor_get_frequency() / 1000; + SysTick_Config(ticks_per_ms); // interrupt is enabled +} + +void tick_delay(uint32_t us) { + uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000; + uint32_t us_between_ticks = SysTick->VAL / ticks_per_us; + uint64_t start_ms = ticks_ms; + while (us > 1000) { + while (ticks_ms == start_ms) {} + us -= us_between_ticks; + start_ms = ticks_ms; + us_between_ticks = 1000; + } + while (SysTick->VAL > ((us_between_ticks - us) * ticks_per_us)) {} +} + +// us counts down! +void current_tick(uint64_t* ms, uint32_t* us_until_ms) { + uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000; + *ms = ticks_ms; + *us_until_ms = SysTick->VAL / ticks_per_us; +} + +void wait_until(uint64_t ms, uint32_t us_until_ms) { + uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000; + while(ticks_ms <= ms && SysTick->VAL / ticks_per_us >= us_until_ms) {} +} diff --git a/ports/nrf/tick.h b/ports/nrf/tick.h new file mode 100644 index 00000000000..838e9fbea84 --- /dev/null +++ b/ports/nrf/tick.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ +#ifndef MICROPY_INCLUDED_NRF_TICK_H +#define MICROPY_INCLUDED_NRF_TICK_H + +#include "py/mpconfig.h" + +#include + +extern volatile uint64_t ticks_ms; + +extern struct timer_descriptor ms_timer; + +void tick_init(void); + +void tick_delay(uint32_t us); + +void current_tick(uint64_t* ms, uint32_t* us_until_ms); +// Do not call this with interrupts disabled because it may be waiting for +// ticks_ms to increment. +void wait_until(uint64_t ms, uint32_t us_until_ms); + +#endif // MICROPY_INCLUDED_NRF_TICK_H diff --git a/ports/qemu-arm/Makefile b/ports/qemu-arm/Makefile index 95f349beba1..6c4a74620ba 100644 --- a/ports/qemu-arm/Makefile +++ b/ports/qemu-arm/Makefile @@ -91,9 +91,27 @@ all: run run: $(BUILD)/firmware.elf qemu-system-arm -machine integratorcp -cpu cortex-m3 -nographic -monitor null -serial null -semihosting -kernel $(BUILD)/firmware.elf +test: $(BUILD)/firmware-test.elf + qemu-system-arm -machine integratorcp -cpu cortex-m3 -nographic -monitor null -serial null -semihosting -kernel $(BUILD)/firmware-test.elf > $(BUILD)/console.out + $(Q)tail -n2 $(BUILD)/console.out + $(Q)tail -n1 $(BUILD)/console.out | grep -q "status: 0" + +.PHONY: $(BUILD)/genhdr/tests.h + +$(BUILD)/test_main.o: $(BUILD)/genhdr/tests.h +$(BUILD)/genhdr/tests.h: + $(Q)echo "Generating $@";(cd $(TOP)/tests; ../tools/tinytest-codegen.py) > $@ + +$(BUILD)/tinytest.o: + $(Q)$(CC) $(CFLAGS) -DNO_FORKING -o $@ -c $(TOP)/tools/tinytest/tinytest.c + ## `$(LD)` doesn't seem to like `--specs` for some reason, but we can just use `$(CC)` here. $(BUILD)/firmware.elf: $(OBJ_COMMON) $(OBJ_RUN) $(Q)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) $(Q)$(SIZE) $@ +$(BUILD)/firmware-test.elf: $(OBJ_COMMON) $(OBJ_TEST) + $(Q)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) + $(Q)$(SIZE) $@ + include $(TOP)/py/mkrules.mk diff --git a/ports/qemu-arm/mpconfigport.h b/ports/qemu-arm/mpconfigport.h index 5d861919889..dbfc395af23 100644 --- a/ports/qemu-arm/mpconfigport.h +++ b/ports/qemu-arm/mpconfigport.h @@ -23,6 +23,7 @@ #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) #define MICROPY_PY_BUILTINS_FROZENSET (1) #define MICROPY_PY_BUILTINS_MEMORYVIEW (1) +#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) #define MICROPY_PY_BUILTINS_POW3 (1) #define MICROPY_PY_IO (1) #define MICROPY_PY_SYS_EXIT (1) diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 3ee0d1934b9..bedfa70091e 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -106,6 +106,7 @@ SRC_LIB = $(addprefix lib/,\ libc/string0.c \ oofatfs/ff.c \ oofatfs/option/unicode.c \ + mp-readline/builtin_input.c \ mp-readline/readline.c \ netutils/netutils.c \ timeutils/timeutils.c \ diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c index 1622c505c13..5d3076ccde7 100644 --- a/ports/stm32/uart.c +++ b/ports/stm32/uart.c @@ -28,6 +28,8 @@ #include #include +//#include "py/ioctl.h" +//#include "py/nlr.h" #include "py/runtime.h" #include "py/stream.h" #include "py/mperrno.h" diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index 23c490d3759..c6fc86e05d7 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -34,6 +34,7 @@ #include "usbd_msc_storage.h" #include "usbd_hid_interface.h" +#include "py/ioctl.h" #include "py/objstr.h" #include "py/runtime.h" #include "py/stream.h" diff --git a/ports/stm32f4/.gitignore b/ports/stm32f4/.gitignore new file mode 100644 index 00000000000..3080ece14da --- /dev/null +++ b/ports/stm32f4/.gitignore @@ -0,0 +1,9 @@ +# Build files +##################### +build-*/ + +# Reference files +##################### +ref/ + +.gdb_history \ No newline at end of file diff --git a/ports/stm32f4/Makefile b/ports/stm32f4/Makefile new file mode 100755 index 00000000000..c75a6c7ee49 --- /dev/null +++ b/ports/stm32f4/Makefile @@ -0,0 +1,272 @@ +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# Copyright (c) 2019 Dan Halbert for Adafruit Industries +# +# 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. +DEBUG = 1 + +# Select the board to build for. +ifeq ($(BOARD),) + $(error You must provide a BOARD parameter) +else + ifeq ($(wildcard boards/$(BOARD)/.),) + $(error Invalid BOARD specified) + endif +endif + +# If the build directory is not given, make it reflect the board name. +BUILD ?= build-$(BOARD) + +include ../../py/mkenv.mk +# Board-specific +include boards/$(BOARD)/mpconfigboard.mk +# Port-specific +include mpconfigport.mk + +# CircuitPython-specific +include $(TOP)/py/circuitpy_mpconfig.mk + +# qstr definitions (must come before including py.mk) +QSTR_DEFS = qstrdefsport.h + +# include py core make definitions +include $(TOP)/py/py.mk + +include $(TOP)/supervisor/supervisor.mk + +# Include make rules and variables common across CircuitPython builds. +include $(TOP)/py/circuitpy_defns.mk + +CROSS_COMPILE = arm-none-eabi- + +####################################### +# CFLAGS +####################################### + +INC += -I. +INC += -I../.. +INC += -I$(BUILD) +INC += -I$(BUILD)/genhdr +INC += -I./stm32f4/STM32F4xx_HAL_Driver/Inc +INC += -I./stm32f4/STM32F4xx_HAL_Driver/Inc/Legacy +INC += -I./stm32f4/CMSIS/Device/ST/STM32F4xx/Include +INC += -I./stm32f4/CMSIS/Include +INC += -I./boards +INC += -I./boards/$(BOARD) +INC += -I./peripherals +INC += -I../../lib/mp-readline +INC += -I../../lib/tinyusb/src +INC += -I../../supervisor/shared/usb + + +#Debugging/Optimization +ifeq ($(DEBUG), 1) + CFLAGS += -ggdb + # You may want to enable these flags to make setting breakpoints easier. + CFLAGS += -fno-inline -fno-ipa-sra +else + CFLAGS += -Os -DNDEBUG + # TODO: Test with -flto + ### CFLAGS += -flto +endif + +# C defines and other board specifics +ifeq ($(MCU_SUB_VARIANT), stm32f412zx) +C_DEFS = \ + -DUSE_FULL_LL_DRIVER \ + -DUSE_HAL_DRIVER \ + -DSTM32F412Zx +endif + +ifeq ($(MCU_SUB_VARIANT), stm32f411xe) +C_DEFS = \ + -DUSE_HAL_DRIVER \ + -DSTM32F411xE +endif + +#TODO: Add ASM Flags? -Werror +CFLAGS += $(INC) -Wall -std=gnu11 -nostdlib $(BASE_CFLAGS) $(C_DEFS) $(CFLAGS_MOD) $(COPT) + +# Undo some warnings. +# STM32 apparently also uses undefined preprocessor variables quite casually, +# so we can't do warning checks for these. +CFLAGS += -Wno-undef +# STM32 might do casts that increase alignment requirements. +CFLAGS += -Wno-cast-align + +CFLAGS += \ + -mthumb \ + -mabi=aapcs-linux \ + -mfloat-abi=hard \ + -mcpu=cortex-m4 \ + -mfpu=fpv4-sp-d16 + +# TODO: check this +CFLAGS += -D__START=main + +LDFLAGS = $(CFLAGS) -fshort-enums -Wl,-nostdlib -Wl,-T,$(LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections -specs=nano.specs +LIBS := -lgcc -lc + +LDFLAGS += -mthumb -mcpu=cortex-m4 + +# Use toolchain libm if we're not using our own. +ifndef INTERNAL_LIBM +LIBS += -lm +endif + +# TinyUSB defines +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_STM32F4 -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_CDC_TX_BUFSIZE=1024 -DCFG_TUD_MSC_BUFSIZE=4096 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_MIDI_TX_BUFSIZE=128 + + +###################################### +# source +###################################### + +SRC_STM32 = \ + boards/$(BOARD)/stm32f4xx_hal_msp.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_gpio.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_i2c.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_dma.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s_ex.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_qspi.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usart.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_rcc.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_utils.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_exti.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c \ + stm32f4/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c \ + system_stm32f4xx.c + +SRC_C += \ + background.c \ + fatfs_port.c \ + mphalport.c \ + tick.c \ + boards/$(BOARD)/board.c \ + peripherals/stm32f4/$(MCU_SUB_VARIANT)/clocks.c \ + peripherals/stm32f4/$(MCU_SUB_VARIANT)/gpio.c \ + lib/libc/string0.c \ + lib/mp-readline/readline.c \ + lib/oofatfs/ff.c \ + lib/oofatfs/option/ccsbcs.c \ + lib/timeutils/timeutils.c \ + lib/utils/buffer_helper.c \ + lib/utils/context_manager_helpers.c \ + lib/utils/interrupt_char.c \ + lib/utils/pyexec.c \ + lib/utils/stdout_helpers.c \ + lib/utils/sys_stdio_mphal.c \ + supervisor/shared/memory.c + +ifneq ($(USB),FALSE) +SRC_C += lib/tinyusb/src/portable/st/stm32f4/dcd_stm32f4.c +endif + +ifeq ($(MCU_SUB_VARIANT), stm32f412zx) +SRC_C += peripherals/stm32f4/stm32f412zx/pins.c +SRC_C += boards/$(BOARD)/pins.c +endif + +SRC_S = \ + supervisor/cpu.s \ + boards/startup_$(MCU_SUB_VARIANT).s + +SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ + $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ + $(addprefix common-hal/, $(SRC_COMMON_HAL)) + +SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ + $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ + $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) + + + +FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py') +FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy)) + +OBJ += $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_STM32:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_EXPANDED:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o)) +ifeq ($(INTERNAL_LIBM),1) +OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) +endif +OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) + +$(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os +$(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os + +# List of sources for qstr extraction +SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_MOD) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) +# Sources that only hold QSTRs after pre-processing. +SRC_QSTR_PREPROCESSOR += + + +all: $(BUILD)/firmware.bin $(BUILD)/firmware.uf2 + +$(BUILD)/firmware.elf: $(OBJ) + $(STEPECHO) "LINK $@" + $(Q)$(CC) -o $@ $(LDFLAGS) $^ -Wl,--start-group $(LIBS) -Wl,--end-group + $(Q)$(SIZE) $@ | $(PYTHON3) $(TOP)/tools/build_memory_info.py $(LD_FILE) + +$(BUILD)/firmware.bin: $(BUILD)/firmware.elf + $(STEPECHO) "Create $@" + $(Q)$(OBJCOPY) -O binary $^ $@ +# $(Q)$(OBJCOPY) -O binary -j .vectors -j .text -j .data $^ $@ + +$(BUILD)/firmware.hex: $(BUILD)/firmware.elf + $(STEPECHO) "Create $@" + $(Q)$(OBJCOPY) -O ihex $^ $@ +# $(Q)$(OBJCOPY) -O ihex -j .vectors -j .text -j .data $^ $@ + +$(BUILD)/firmware.uf2: $(BUILD)/firmware.hex + $(ECHO) "Create $@" + $(PYTHON3) $(TOP)/tools/uf2/utils/uf2conv.py -f 0xADA52840 -c -o "$(BUILD)/firmware.uf2" $^ + +include $(TOP)/py/mkrules.mk + +# Print out the value of a make variable. +# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile +print-%: + @echo $* = $($*) diff --git a/ports/stm32f4/README.md b/ports/stm32f4/README.md new file mode 100644 index 00000000000..a860c01ce45 --- /dev/null +++ b/ports/stm32f4/README.md @@ -0,0 +1,3 @@ +# CircuitPython Port To The ST Microelectronics STM32F4 Series + +This is a port of CircuitPython to the STM32F4 series of chips. diff --git a/ports/stm32f4/background.c b/ports/stm32f4/background.c new file mode 100644 index 00000000000..b91c3793ee5 --- /dev/null +++ b/ports/stm32f4/background.c @@ -0,0 +1,57 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "py/runtime.h" +#include "supervisor/filesystem.h" +#include "supervisor/usb.h" +#include "supervisor/shared/stack.h" + +#if CIRCUITPY_DISPLAYIO +#include "shared-module/displayio/__init__.h" +#endif + +static bool running_background_tasks = false; + +void background_tasks_reset(void) { + running_background_tasks = false; +} + +void run_background_tasks(void) { + // Don't call ourselves recursively. + if (running_background_tasks) { + return; + } + running_background_tasks = true; + filesystem_background(); + //usb_background(); + + #if CIRCUITPY_DISPLAYIO + displayio_background(); + #endif + running_background_tasks = false; + + assert_heap_ok(); +} diff --git a/ports/stm32f4/background.h b/ports/stm32f4/background.h new file mode 100644 index 00000000000..05a4f894a6c --- /dev/null +++ b/ports/stm32f4/background.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_STM32F4_BACKGROUND_H +#define MICROPY_INCLUDED_STM32F4_BACKGROUND_H + +#include + +void background_tasks_reset(void); +void run_background_tasks(void); + +#endif // MICROPY_INCLUDED_STM32F4_BACKGROUND_H diff --git a/ports/stm32f4/boards/STM32F411VETx_FLASH.ld b/ports/stm32f4/boards/STM32F411VETx_FLASH.ld new file mode 100644 index 00000000000..a3c3594a941 --- /dev/null +++ b/ports/stm32f4/boards/STM32F411VETx_FLASH.ld @@ -0,0 +1,189 @@ +/* +****************************************************************************** +** + +** File : LinkerScript.ld +** +** Author : Auto-generated by Ac6 System Workbench +** +** Abstract : Linker script for STM32F411VETx series +** 512Kbytes FLASH and 128Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed “as is,†without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© COPYRIGHT(c) 2014 Ac6

+** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** 1. Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** 3. Neither the name of Ac6 nor the names of its contributors +** may be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20020000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/ports/stm32f4/boards/STM32F412ZGTx_FLASH.ld b/ports/stm32f4/boards/STM32F412ZGTx_FLASH.ld new file mode 100644 index 00000000000..da1efdeccef --- /dev/null +++ b/ports/stm32f4/boards/STM32F412ZGTx_FLASH.ld @@ -0,0 +1,189 @@ +/* +****************************************************************************** +** + +** File : LinkerScript.ld +** +** Author : Auto-generated by Ac6 System Workbench +** +** Abstract : Linker script for STM32F412ZGTx series +** 1024Kbytes FLASH and 256Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed “as is,†without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© COPYRIGHT(c) 2014 Ac6

+** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** 1. Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** 3. Neither the name of Ac6 nor the names of its contributors +** may be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20040000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/ports/stm32f4/boards/board.h b/ports/stm32f4/boards/board.h new file mode 100644 index 00000000000..22d9e99be09 --- /dev/null +++ b/ports/stm32f4/boards/board.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +// This file defines board specific functions. + +#ifndef MICROPY_INCLUDED_STM32F4_BOARDS_BOARD_H +#define MICROPY_INCLUDED_STM32F4_BOARDS_BOARD_H + +#include + +// Initializes board related state once on start up. +void board_init(void); + +// Returns true if the user initiates safe mode in a board specific way. +// Also add BOARD_USER_SAFE_MODE in mpconfigboard.h to explain the board specific +// way. +bool board_requests_safe_mode(void); + +// Reset the state of off MCU components such as neopixels. +void reset_board(void); + +#endif // MICROPY_INCLUDED_STM32F4_BOARDS_BOARD_H diff --git a/ports/stm32f4/boards/startup_stm32f411xe.s b/ports/stm32f4/boards/startup_stm32f411xe.s new file mode 100644 index 00000000000..3aac640cb2f --- /dev/null +++ b/ports/stm32f4/boards/startup_stm32f411xe.s @@ -0,0 +1,452 @@ +/** + ****************************************************************************** + * @file startup_stm32f411xe.s + * @author MCD Application Team + * @brief STM32F411xExx Devices vector table for GCC based toolchains. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M4 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m4 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss +/* stack used for SystemInit_ExtMemCtl; always internal RAM used */ + +/** + * @brief This is the code that gets called when the processor first + * starts execution following a reset event. Only the absolutely + * necessary set is performed, after which the application + * supplied main() routine is called. + * @param None + * @retval : None +*/ + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr sp, =_estack /* set stack pointer */ + +/* Copy the data segment initializers from flash to SRAM */ + movs r1, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r3, =_sidata + ldr r3, [r3, r1] + str r3, [r0, r1] + adds r1, r1, #4 + +LoopCopyDataInit: + ldr r0, =_sdata + ldr r3, =_edata + adds r2, r0, r1 + cmp r2, r3 + bcc CopyDataInit + ldr r2, =_sbss + b LoopFillZerobss +/* Zero fill the bss segment. */ +FillZerobss: + movs r3, #0 + str r3, [r2], #4 + +LoopFillZerobss: + ldr r3, = _ebss + cmp r2, r3 + bcc FillZerobss + +/* Call the clock system intitialization function.*/ + bl SystemInit +/* Call static constructors */ +/* bl __libc_init_array */ +/* Call the application's entry point.*/ + bl main + bx lr +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * @param None + * @retval None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex M3. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +*******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + + /* External Interrupts */ + .word WWDG_IRQHandler /* Window WatchDog */ + .word PVD_IRQHandler /* PVD through EXTI Line detection */ + .word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */ + .word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */ + .word FLASH_IRQHandler /* FLASH */ + .word RCC_IRQHandler /* RCC */ + .word EXTI0_IRQHandler /* EXTI Line0 */ + .word EXTI1_IRQHandler /* EXTI Line1 */ + .word EXTI2_IRQHandler /* EXTI Line2 */ + .word EXTI3_IRQHandler /* EXTI Line3 */ + .word EXTI4_IRQHandler /* EXTI Line4 */ + .word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */ + .word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */ + .word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */ + .word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */ + .word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */ + .word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */ + .word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */ + .word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word EXTI9_5_IRQHandler /* External Line[9:5]s */ + .word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */ + .word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */ + .word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */ + .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */ + .word TIM2_IRQHandler /* TIM2 */ + .word TIM3_IRQHandler /* TIM3 */ + .word TIM4_IRQHandler /* TIM4 */ + .word I2C1_EV_IRQHandler /* I2C1 Event */ + .word I2C1_ER_IRQHandler /* I2C1 Error */ + .word I2C2_EV_IRQHandler /* I2C2 Event */ + .word I2C2_ER_IRQHandler /* I2C2 Error */ + .word SPI1_IRQHandler /* SPI1 */ + .word SPI2_IRQHandler /* SPI2 */ + .word USART1_IRQHandler /* USART1 */ + .word USART2_IRQHandler /* USART2 */ + .word 0 /* Reserved */ + .word EXTI15_10_IRQHandler /* External Line[15:10]s */ + .word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */ + .word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */ + .word 0 /* Reserved */ + .word SDIO_IRQHandler /* SDIO */ + .word TIM5_IRQHandler /* TIM5 */ + .word SPI3_IRQHandler /* SPI3 */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */ + .word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */ + .word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */ + .word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */ + .word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word OTG_FS_IRQHandler /* USB OTG FS */ + .word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */ + .word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */ + .word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */ + .word USART6_IRQHandler /* USART6 */ + .word I2C3_EV_IRQHandler /* I2C3 event */ + .word I2C3_ER_IRQHandler /* I2C3 error */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word FPU_IRQHandler /* FPU */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word SPI4_IRQHandler /* SPI4 */ + .word SPI5_IRQHandler /* SPI5 */ + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak PVD_IRQHandler + .thumb_set PVD_IRQHandler,Default_Handler + + .weak TAMP_STAMP_IRQHandler + .thumb_set TAMP_STAMP_IRQHandler,Default_Handler + + .weak RTC_WKUP_IRQHandler + .thumb_set RTC_WKUP_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak EXTI0_IRQHandler + .thumb_set EXTI0_IRQHandler,Default_Handler + + .weak EXTI1_IRQHandler + .thumb_set EXTI1_IRQHandler,Default_Handler + + .weak EXTI2_IRQHandler + .thumb_set EXTI2_IRQHandler,Default_Handler + + .weak EXTI3_IRQHandler + .thumb_set EXTI3_IRQHandler,Default_Handler + + .weak EXTI4_IRQHandler + .thumb_set EXTI4_IRQHandler,Default_Handler + + .weak DMA1_Stream0_IRQHandler + .thumb_set DMA1_Stream0_IRQHandler,Default_Handler + + .weak DMA1_Stream1_IRQHandler + .thumb_set DMA1_Stream1_IRQHandler,Default_Handler + + .weak DMA1_Stream2_IRQHandler + .thumb_set DMA1_Stream2_IRQHandler,Default_Handler + + .weak DMA1_Stream3_IRQHandler + .thumb_set DMA1_Stream3_IRQHandler,Default_Handler + + .weak DMA1_Stream4_IRQHandler + .thumb_set DMA1_Stream4_IRQHandler,Default_Handler + + .weak DMA1_Stream5_IRQHandler + .thumb_set DMA1_Stream5_IRQHandler,Default_Handler + + .weak DMA1_Stream6_IRQHandler + .thumb_set DMA1_Stream6_IRQHandler,Default_Handler + + .weak ADC_IRQHandler + .thumb_set ADC_IRQHandler,Default_Handler + + .weak EXTI9_5_IRQHandler + .thumb_set EXTI9_5_IRQHandler,Default_Handler + + .weak TIM1_BRK_TIM9_IRQHandler + .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler + + .weak TIM1_UP_TIM10_IRQHandler + .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler + + .weak TIM1_TRG_COM_TIM11_IRQHandler + .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler + + .weak TIM1_CC_IRQHandler + .thumb_set TIM1_CC_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak TIM3_IRQHandler + .thumb_set TIM3_IRQHandler,Default_Handler + + .weak TIM4_IRQHandler + .thumb_set TIM4_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C2_EV_IRQHandler + .thumb_set I2C2_EV_IRQHandler,Default_Handler + + .weak I2C2_ER_IRQHandler + .thumb_set I2C2_ER_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak USART2_IRQHandler + .thumb_set USART2_IRQHandler,Default_Handler + + .weak EXTI15_10_IRQHandler + .thumb_set EXTI15_10_IRQHandler,Default_Handler + + .weak RTC_Alarm_IRQHandler + .thumb_set RTC_Alarm_IRQHandler,Default_Handler + + .weak OTG_FS_WKUP_IRQHandler + .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler + + .weak DMA1_Stream7_IRQHandler + .thumb_set DMA1_Stream7_IRQHandler,Default_Handler + + .weak SDIO_IRQHandler + .thumb_set SDIO_IRQHandler,Default_Handler + + .weak TIM5_IRQHandler + .thumb_set TIM5_IRQHandler,Default_Handler + + .weak SPI3_IRQHandler + .thumb_set SPI3_IRQHandler,Default_Handler + + .weak DMA2_Stream0_IRQHandler + .thumb_set DMA2_Stream0_IRQHandler,Default_Handler + + .weak DMA2_Stream1_IRQHandler + .thumb_set DMA2_Stream1_IRQHandler,Default_Handler + + .weak DMA2_Stream2_IRQHandler + .thumb_set DMA2_Stream2_IRQHandler,Default_Handler + + .weak DMA2_Stream3_IRQHandler + .thumb_set DMA2_Stream3_IRQHandler,Default_Handler + + .weak DMA2_Stream4_IRQHandler + .thumb_set DMA2_Stream4_IRQHandler,Default_Handler + + .weak OTG_FS_IRQHandler + .thumb_set OTG_FS_IRQHandler,Default_Handler + + .weak DMA2_Stream5_IRQHandler + .thumb_set DMA2_Stream5_IRQHandler,Default_Handler + + .weak DMA2_Stream6_IRQHandler + .thumb_set DMA2_Stream6_IRQHandler,Default_Handler + + .weak DMA2_Stream7_IRQHandler + .thumb_set DMA2_Stream7_IRQHandler,Default_Handler + + .weak USART6_IRQHandler + .thumb_set USART6_IRQHandler,Default_Handler + + .weak I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak SPI4_IRQHandler + .thumb_set SPI4_IRQHandler,Default_Handler + + .weak SPI5_IRQHandler + .thumb_set SPI5_IRQHandler,Default_Handler + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/ports/stm32f4/boards/startup_stm32f412zx.s b/ports/stm32f4/boards/startup_stm32f412zx.s new file mode 100644 index 00000000000..8012207957f --- /dev/null +++ b/ports/stm32f4/boards/startup_stm32f412zx.s @@ -0,0 +1,524 @@ +/** + ****************************************************************************** + * @file startup_stm32f412zx.s + * @author MCD Application Team + * @brief STM32F412Zx Devices vector table for GCC based toolchains. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M4 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m4 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss +/* stack used for SystemInit_ExtMemCtl; always internal RAM used */ + +/** + * @brief This is the code that gets called when the processor first + * starts execution following a reset event. Only the absolutely + * necessary set is performed, after which the application + * supplied main() routine is called. + * @param None + * @retval : None +*/ + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr sp, =_estack /* set stack pointer */ + +/* Copy the data segment initializers from flash to SRAM */ + movs r1, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r3, =_sidata + ldr r3, [r3, r1] + str r3, [r0, r1] + adds r1, r1, #4 + +LoopCopyDataInit: + ldr r0, =_sdata + ldr r3, =_edata + adds r2, r0, r1 + cmp r2, r3 + bcc CopyDataInit + ldr r2, =_sbss + b LoopFillZerobss +/* Zero fill the bss segment. */ +FillZerobss: + movs r3, #0 + str r3, [r2], #4 + +LoopFillZerobss: + ldr r3, = _ebss + cmp r2, r3 + bcc FillZerobss + +/* Call the clock system intitialization function.*/ + bl SystemInit +/* Call static constructors */ +/* bl __libc_init_array */ +/* Call the application's entry point.*/ + bl main + bx lr +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * @param None + * @retval None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex M3. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +*******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + + /* External Interrupts */ + .word WWDG_IRQHandler /* Window WatchDog */ + .word PVD_IRQHandler /* PVD through EXTI Line detection */ + .word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */ + .word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */ + .word FLASH_IRQHandler /* FLASH */ + .word RCC_IRQHandler /* RCC */ + .word EXTI0_IRQHandler /* EXTI Line0 */ + .word EXTI1_IRQHandler /* EXTI Line1 */ + .word EXTI2_IRQHandler /* EXTI Line2 */ + .word EXTI3_IRQHandler /* EXTI Line3 */ + .word EXTI4_IRQHandler /* EXTI Line4 */ + .word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */ + .word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */ + .word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */ + .word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */ + .word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */ + .word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */ + .word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */ + .word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */ + .word CAN1_TX_IRQHandler /* CAN1 TX */ + .word CAN1_RX0_IRQHandler /* CAN1 RX0 */ + .word CAN1_RX1_IRQHandler /* CAN1 RX1 */ + .word CAN1_SCE_IRQHandler /* CAN1 SCE */ + .word EXTI9_5_IRQHandler /* External Line[9:5]s */ + .word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */ + .word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */ + .word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */ + .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */ + .word TIM2_IRQHandler /* TIM2 */ + .word TIM3_IRQHandler /* TIM3 */ + .word TIM4_IRQHandler /* TIM4 */ + .word I2C1_EV_IRQHandler /* I2C1 Event */ + .word I2C1_ER_IRQHandler /* I2C1 Error */ + .word I2C2_EV_IRQHandler /* I2C2 Event */ + .word I2C2_ER_IRQHandler /* I2C2 Error */ + .word SPI1_IRQHandler /* SPI1 */ + .word SPI2_IRQHandler /* SPI2 */ + .word USART1_IRQHandler /* USART1 */ + .word USART2_IRQHandler /* USART2 */ + .word USART3_IRQHandler /* USART3 */ + .word EXTI15_10_IRQHandler /* External Line[15:10]s */ + .word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */ + .word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */ + .word TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */ + .word TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */ + .word TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */ + .word TIM8_CC_IRQHandler /* TIM8 Capture Compare */ + .word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */ + .word 0 /* Reserved */ + .word SDIO_IRQHandler /* SDIO */ + .word TIM5_IRQHandler /* TIM5 */ + .word SPI3_IRQHandler /* SPI3 */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word TIM6_IRQHandler /* TIM6 */ + .word TIM7_IRQHandler /* TIM7 */ + .word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */ + .word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */ + .word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */ + .word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */ + .word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */ + .word DFSDM1_FLT0_IRQHandler /* DFSDM1 Filter0 */ + .word DFSDM1_FLT1_IRQHandler /* DFSDM1 Filter1 */ + .word CAN2_TX_IRQHandler /* CAN2 TX */ + .word CAN2_RX0_IRQHandler /* CAN2 RX0 */ + .word CAN2_RX1_IRQHandler /* CAN2 RX1 */ + .word CAN2_SCE_IRQHandler /* CAN2 SCE */ + .word OTG_FS_IRQHandler /* USB OTG FS */ + .word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */ + .word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */ + .word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */ + .word USART6_IRQHandler /* USART6 */ + .word I2C3_EV_IRQHandler /* I2C3 event */ + .word I2C3_ER_IRQHandler /* I2C3 error */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word RNG_IRQHandler /* RNG */ + .word FPU_IRQHandler /* FPU */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word SPI4_IRQHandler /* SPI4 */ + .word SPI5_IRQHandler /* SPI5 */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word QUADSPI_IRQHandler /* QuadSPI */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word FMPI2C1_EV_IRQHandler /* FMPI2C1 Event */ + .word FMPI2C1_ER_IRQHandler /* FMPI2C1 Error */ + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak PVD_IRQHandler + .thumb_set PVD_IRQHandler,Default_Handler + + .weak TAMP_STAMP_IRQHandler + .thumb_set TAMP_STAMP_IRQHandler,Default_Handler + + .weak RTC_WKUP_IRQHandler + .thumb_set RTC_WKUP_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak EXTI0_IRQHandler + .thumb_set EXTI0_IRQHandler,Default_Handler + + .weak EXTI1_IRQHandler + .thumb_set EXTI1_IRQHandler,Default_Handler + + .weak EXTI2_IRQHandler + .thumb_set EXTI2_IRQHandler,Default_Handler + + .weak EXTI3_IRQHandler + .thumb_set EXTI3_IRQHandler,Default_Handler + + .weak EXTI4_IRQHandler + .thumb_set EXTI4_IRQHandler,Default_Handler + + .weak DMA1_Stream0_IRQHandler + .thumb_set DMA1_Stream0_IRQHandler,Default_Handler + + .weak DMA1_Stream1_IRQHandler + .thumb_set DMA1_Stream1_IRQHandler,Default_Handler + + .weak DMA1_Stream2_IRQHandler + .thumb_set DMA1_Stream2_IRQHandler,Default_Handler + + .weak DMA1_Stream3_IRQHandler + .thumb_set DMA1_Stream3_IRQHandler,Default_Handler + + .weak DMA1_Stream4_IRQHandler + .thumb_set DMA1_Stream4_IRQHandler,Default_Handler + + .weak DMA1_Stream5_IRQHandler + .thumb_set DMA1_Stream5_IRQHandler,Default_Handler + + .weak DMA1_Stream6_IRQHandler + .thumb_set DMA1_Stream6_IRQHandler,Default_Handler + + .weak ADC_IRQHandler + .thumb_set ADC_IRQHandler,Default_Handler + + .weak CAN1_TX_IRQHandler + .thumb_set CAN1_TX_IRQHandler,Default_Handler + + .weak CAN1_RX0_IRQHandler + .thumb_set CAN1_RX0_IRQHandler,Default_Handler + + .weak CAN1_RX1_IRQHandler + .thumb_set CAN1_RX1_IRQHandler,Default_Handler + + .weak CAN1_SCE_IRQHandler + .thumb_set CAN1_SCE_IRQHandler,Default_Handler + + .weak EXTI9_5_IRQHandler + .thumb_set EXTI9_5_IRQHandler,Default_Handler + + .weak TIM1_BRK_TIM9_IRQHandler + .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler + + .weak TIM1_UP_TIM10_IRQHandler + .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler + + .weak TIM1_TRG_COM_TIM11_IRQHandler + .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler + + .weak TIM1_CC_IRQHandler + .thumb_set TIM1_CC_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak TIM3_IRQHandler + .thumb_set TIM3_IRQHandler,Default_Handler + + .weak TIM4_IRQHandler + .thumb_set TIM4_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C2_EV_IRQHandler + .thumb_set I2C2_EV_IRQHandler,Default_Handler + + .weak I2C2_ER_IRQHandler + .thumb_set I2C2_ER_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak USART2_IRQHandler + .thumb_set USART2_IRQHandler,Default_Handler + + .weak USART3_IRQHandler + .thumb_set USART3_IRQHandler,Default_Handler + + .weak EXTI15_10_IRQHandler + .thumb_set EXTI15_10_IRQHandler,Default_Handler + + .weak RTC_Alarm_IRQHandler + .thumb_set RTC_Alarm_IRQHandler,Default_Handler + + .weak OTG_FS_WKUP_IRQHandler + .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler + + .weak TIM8_BRK_TIM12_IRQHandler + .thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler + + .weak TIM8_UP_TIM13_IRQHandler + .thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler + + .weak TIM8_TRG_COM_TIM14_IRQHandler + .thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler + + .weak TIM8_CC_IRQHandler + .thumb_set TIM8_CC_IRQHandler,Default_Handler + + .weak DMA1_Stream7_IRQHandler + .thumb_set DMA1_Stream7_IRQHandler,Default_Handler + + .weak SDIO_IRQHandler + .thumb_set SDIO_IRQHandler,Default_Handler + + .weak TIM5_IRQHandler + .thumb_set TIM5_IRQHandler,Default_Handler + + .weak SPI3_IRQHandler + .thumb_set SPI3_IRQHandler,Default_Handler + + .weak TIM6_IRQHandler + .thumb_set TIM6_IRQHandler,Default_Handler + + .weak TIM7_IRQHandler + .thumb_set TIM7_IRQHandler,Default_Handler + + .weak DMA2_Stream0_IRQHandler + .thumb_set DMA2_Stream0_IRQHandler,Default_Handler + + .weak DMA2_Stream1_IRQHandler + .thumb_set DMA2_Stream1_IRQHandler,Default_Handler + + .weak DMA2_Stream2_IRQHandler + .thumb_set DMA2_Stream2_IRQHandler,Default_Handler + + .weak DMA2_Stream3_IRQHandler + .thumb_set DMA2_Stream3_IRQHandler,Default_Handler + + .weak DMA2_Stream4_IRQHandler + .thumb_set DMA2_Stream4_IRQHandler,Default_Handler + + .weak DFSDM1_FLT0_IRQHandler + .thumb_set DFSDM1_FLT0_IRQHandler,Default_Handler + + .weak DFSDM1_FLT1_IRQHandler + .thumb_set DFSDM1_FLT1_IRQHandler,Default_Handler + + .weak CAN2_TX_IRQHandler + .thumb_set CAN2_TX_IRQHandler,Default_Handler + + .weak CAN2_RX0_IRQHandler + .thumb_set CAN2_RX0_IRQHandler,Default_Handler + + .weak CAN2_RX1_IRQHandler + .thumb_set CAN2_RX1_IRQHandler,Default_Handler + + .weak CAN2_SCE_IRQHandler + .thumb_set CAN2_SCE_IRQHandler,Default_Handler + + .weak OTG_FS_IRQHandler + .thumb_set OTG_FS_IRQHandler,Default_Handler + + .weak DMA2_Stream5_IRQHandler + .thumb_set DMA2_Stream5_IRQHandler,Default_Handler + + .weak DMA2_Stream6_IRQHandler + .thumb_set DMA2_Stream6_IRQHandler,Default_Handler + + .weak DMA2_Stream7_IRQHandler + .thumb_set DMA2_Stream7_IRQHandler,Default_Handler + + .weak USART6_IRQHandler + .thumb_set USART6_IRQHandler,Default_Handler + + .weak I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_IRQHandler,Default_Handler + + .weak RNG_IRQHandler + .thumb_set RNG_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak SPI4_IRQHandler + .thumb_set SPI4_IRQHandler,Default_Handler + + .weak SPI5_IRQHandler + .thumb_set SPI5_IRQHandler,Default_Handler + + .weak QUADSPI_IRQHandler + .thumb_set QUADSPI_IRQHandler,Default_Handler + + .weak FMPI2C1_EV_IRQHandler + .thumb_set FMPI2C1_EV_IRQHandler,Default_Handler + + .weak FMPI2C1_ER_IRQHandler + .thumb_set FMPI2C1_ER_IRQHandler,Default_Handler +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/ports/stm32f4/boards/stm32f411.ld b/ports/stm32f4/boards/stm32f411.ld new file mode 100644 index 00000000000..f0d4804f939 --- /dev/null +++ b/ports/stm32f4/boards/stm32f411.ld @@ -0,0 +1,189 @@ +/* +****************************************************************************** +** + +** File : LinkerScript.ld +** +** Author : Auto-generated by Ac6 System Workbench +** +** Abstract : Linker script for STM32F411RETx series +** 512Kbytes FLASH and 128Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed “as is,†without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© COPYRIGHT(c) 2014 Ac6

+** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** 1. Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** 3. Neither the name of Ac6 nor the names of its contributors +** may be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20020000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + + diff --git a/ports/stm32f4/boards/stm32f411re_discovery/board.c b/ports/stm32f4/boards/stm32f411re_discovery/board.c new file mode 100644 index 00000000000..4421970eefe --- /dev/null +++ b/ports/stm32f4/boards/stm32f411re_discovery/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.h b/ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.h new file mode 100644 index 00000000000..67544328234 --- /dev/null +++ b/ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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. + */ + +//Micropython setup + +#define MICROPY_HW_BOARD_NAME "STM32F411E_DISCO" +#define MICROPY_HW_MCU_NAME "STM32F411xE" + +#define FLASH_SIZE (0x7D000) +#define FLASH_PAGE_SIZE (0x4000) + +#define CIRCUITPY_INTERNAL_NVM_SIZE (4096) +#define AUTORESET_DELAY_MS 500 +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) \ No newline at end of file diff --git a/ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.mk b/ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.mk new file mode 100644 index 00000000000..7b865b57e02 --- /dev/null +++ b/ports/stm32f4/boards/stm32f411re_discovery/mpconfigboard.mk @@ -0,0 +1,13 @@ +USB_VID = 0x239A +USB_PID = 0x802A +USB_PRODUCT = "STM32F411RE Discovery Board - CPy" +USB_MANUFACTURER = "Adafruit Industries LLC" + +MCU_SERIES = m4 +MCU_VARIANT = stm32f4 +MCU_SUB_VARIANT = stm32f411xe +CMSIS_MCU = STM32F411xE +LD_FILE = boards/STM32F411VETx_FLASH.ld +TEXT0_ADDR = 0x08000000 +TEXT1_ADDR = 0x08020000 + diff --git a/ports/stm32f4/boards/stm32f411re_discovery/pins.c b/ports/stm32f4/boards/stm32f411re_discovery/pins.c new file mode 100644 index 00000000000..e3a4b5ed60d --- /dev/null +++ b/ports/stm32f4/boards/stm32f411re_discovery/pins.c @@ -0,0 +1,90 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_PE02), MP_ROM_PTR(&pin_PE02) }, + { MP_ROM_QSTR(MP_QSTR_PE03), MP_ROM_PTR(&pin_PE03) }, + { MP_ROM_QSTR(MP_QSTR_PE04), MP_ROM_PTR(&pin_PE04) }, + { MP_ROM_QSTR(MP_QSTR_PE05), MP_ROM_PTR(&pin_PE05) }, + { MP_ROM_QSTR(MP_QSTR_PE06), MP_ROM_PTR(&pin_PE06) }, + { MP_ROM_QSTR(MP_QSTR_PC13), MP_ROM_PTR(&pin_PC13) }, + { MP_ROM_QSTR(MP_QSTR_PF02), MP_ROM_PTR(&pin_PF02) }, + { MP_ROM_QSTR(MP_QSTR_PF03), MP_ROM_PTR(&pin_PF03) }, + { MP_ROM_QSTR(MP_QSTR_PF10), MP_ROM_PTR(&pin_PF10) }, + { MP_ROM_QSTR(MP_QSTR_PC00), MP_ROM_PTR(&pin_PC00) }, + { MP_ROM_QSTR(MP_QSTR_PC01), MP_ROM_PTR(&pin_PC01) }, + { MP_ROM_QSTR(MP_QSTR_PC02), MP_ROM_PTR(&pin_PC02) }, + { MP_ROM_QSTR(MP_QSTR_PC03), MP_ROM_PTR(&pin_PC03) }, + { MP_ROM_QSTR(MP_QSTR_PA01), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_PA02), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_PA03), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_PA04), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_PA05), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_PA06), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_PA07), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_PC04), MP_ROM_PTR(&pin_PC04) }, + { MP_ROM_QSTR(MP_QSTR_PC05), MP_ROM_PTR(&pin_PC05) }, + { MP_ROM_QSTR(MP_QSTR_PB00), MP_ROM_PTR(&pin_PB00) }, + { MP_ROM_QSTR(MP_QSTR_PB01), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_PF11), MP_ROM_PTR(&pin_PF11) }, + { MP_ROM_QSTR(MP_QSTR_PF13), MP_ROM_PTR(&pin_PF13) }, + { MP_ROM_QSTR(MP_QSTR_PB10), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_PB11), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_PB12), MP_ROM_PTR(&pin_PB12) }, + { MP_ROM_QSTR(MP_QSTR_PB13), MP_ROM_PTR(&pin_PB13) }, + { MP_ROM_QSTR(MP_QSTR_PB14), MP_ROM_PTR(&pin_PB14) }, + { MP_ROM_QSTR(MP_QSTR_PB15), MP_ROM_PTR(&pin_PB15) }, + { MP_ROM_QSTR(MP_QSTR_PD12), MP_ROM_PTR(&pin_PD12) }, + { MP_ROM_QSTR(MP_QSTR_PD13), MP_ROM_PTR(&pin_PD13) }, + { MP_ROM_QSTR(MP_QSTR_PG02), MP_ROM_PTR(&pin_PG02) }, + { MP_ROM_QSTR(MP_QSTR_PC06), MP_ROM_PTR(&pin_PC06) }, + { MP_ROM_QSTR(MP_QSTR_PC07), MP_ROM_PTR(&pin_PC07) }, + { MP_ROM_QSTR(MP_QSTR_PC09), MP_ROM_PTR(&pin_PC09) }, + { MP_ROM_QSTR(MP_QSTR_PA08), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_PA10), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_PA13), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_PA14), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_PA15), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_PD06), MP_ROM_PTR(&pin_PD06) }, + { MP_ROM_QSTR(MP_QSTR_PG09), MP_ROM_PTR(&pin_PG09) }, + { MP_ROM_QSTR(MP_QSTR_PG10), MP_ROM_PTR(&pin_PG10) }, + { MP_ROM_QSTR(MP_QSTR_PG11), MP_ROM_PTR(&pin_PG11) }, + { MP_ROM_QSTR(MP_QSTR_PG12), MP_ROM_PTR(&pin_PG12) }, + { MP_ROM_QSTR(MP_QSTR_PG13), MP_ROM_PTR(&pin_PG13) }, + { MP_ROM_QSTR(MP_QSTR_PG14), MP_ROM_PTR(&pin_PG14) }, + { MP_ROM_QSTR(MP_QSTR_PB03), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_PB04), MP_ROM_PTR(&pin_PB04) }, + { MP_ROM_QSTR(MP_QSTR_PB05), MP_ROM_PTR(&pin_PB05) }, + { MP_ROM_QSTR(MP_QSTR_PB06), MP_ROM_PTR(&pin_PB06) }, + { MP_ROM_QSTR(MP_QSTR_PB07), MP_ROM_PTR(&pin_PB07) }, + { MP_ROM_QSTR(MP_QSTR_PB08), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_PB09), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_PE00), MP_ROM_PTR(&pin_PE00) }, + { MP_ROM_QSTR(MP_QSTR_PE01), MP_ROM_PTR(&pin_PE01) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PG10) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PG11) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PF03) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PF10) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PG12) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PF04) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PG13) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PG14) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PG09) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PC01) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PC03) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PC04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PC05) }, //alt PB09, see F401ZG-DISCO manual + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB00) }, //alt PB10, see F401ZG-DISCO manual + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_PE00) }, + { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_PE01) }, + { MP_ROM_QSTR(MP_QSTR_LED3), MP_ROM_PTR(&pin_PE02) }, + { MP_ROM_QSTR(MP_QSTR_LED4), MP_ROM_PTR(&pin_PE03) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/stm32f4/boards/stm32f411re_discovery/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/stm32f411re_discovery/stm32f4xx_hal_conf.h new file mode 100644 index 00000000000..548c501dce3 --- /dev/null +++ b/ports/stm32f4/boards/stm32f411re_discovery/stm32f4xx_hal_conf.h @@ -0,0 +1,439 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf_template.h + * @author MCD Application Team + * @brief HAL configuration template file. + * This file should be copied to the application folder and renamed + * to stm32f4xx_hal_conf.h. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_CONF_H +#define __STM32F4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED + + /* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCCARD_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_I2C_MODULE_ENABLED +#define HAL_I2S_MODULE_ENABLED +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +/* #define HAL_MMC_MODULE_ENABLED */ +#define HAL_SPI_MODULE_ENABLED +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_PCD_MODULE_ENABLED +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +/* #define HAL_QSPI_MODULE_ENABLED */ +/* #define HAL_QSPI_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_FMPI2C_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_EXTI_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the External audio frequency in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848_PHY_ADDRESS Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY ((uint32_t)0x000000FFU) +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU) + +#define PHY_READ_TO ((uint32_t)0x0000FFFFU) +#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU) + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ +#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */ + +#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f4xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f4xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32f4xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f4xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_FMPI2C_MODULE_ENABLED + #include "stm32f4xx_hal_fmpi2c.h" +#endif /* HAL_FMPI2C_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f4xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/ports/stm32f4/boards/stm32f411re_discovery/stm32f4xx_hal_msp.c b/ports/stm32f4/boards/stm32f411re_discovery/stm32f4xx_hal_msp.c new file mode 100644 index 00000000000..4989f9889b9 --- /dev/null +++ b/ports/stm32f4/boards/stm32f411re_discovery/stm32f4xx_hal_msp.c @@ -0,0 +1,427 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : stm32f4xx_hal_msp.c + * Description : This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include "stm32f4xx_hal.h" +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN Define */ +#define DATA_Ready_Pin GPIO_PIN_2 +#define DATA_Ready_GPIO_Port GPIOE +#define CS_I2C_SPI_Pin GPIO_PIN_3 +#define CS_I2C_SPI_GPIO_Port GPIOE +#define INT1_Pin GPIO_PIN_4 +#define INT1_GPIO_Port GPIOE +#define INT2_Pin GPIO_PIN_5 +#define INT2_GPIO_Port GPIOE +#define PC14_OSC32_IN_Pin GPIO_PIN_14 +#define PC14_OSC32_IN_GPIO_Port GPIOC +#define PC15_OSC32_OUT_Pin GPIO_PIN_15 +#define PC15_OSC32_OUT_GPIO_Port GPIOC +#define PH0_OSC_IN_Pin GPIO_PIN_0 +#define PH0_OSC_IN_GPIO_Port GPIOH +#define PH1_OSC_OUT_Pin GPIO_PIN_1 +#define PH1_OSC_OUT_GPIO_Port GPIOH +#define OTG_FS_PowerSwitchOn_Pin GPIO_PIN_0 +#define OTG_FS_PowerSwitchOn_GPIO_Port GPIOC +#define PDM_OUT_Pin GPIO_PIN_3 +#define PDM_OUT_GPIO_Port GPIOC +#define I2S3_WS_Pin GPIO_PIN_4 +#define I2S3_WS_GPIO_Port GPIOA +#define SPI1_SCK_Pin GPIO_PIN_5 +#define SPI1_SCK_GPIO_Port GPIOA +#define SPI1_MISO_Pin GPIO_PIN_6 +#define SPI1_MISO_GPIO_Port GPIOA +#define SPI1_MOSI_Pin GPIO_PIN_7 +#define SPI1_MOSI_GPIO_Port GPIOA +#define CLK_IN_Pin GPIO_PIN_10 +#define CLK_IN_GPIO_Port GPIOB +#define LD4_Pin GPIO_PIN_12 +#define LD4_GPIO_Port GPIOD +#define LD3_Pin GPIO_PIN_13 +#define LD3_GPIO_Port GPIOD +#define LD5_Pin GPIO_PIN_14 +#define LD5_GPIO_Port GPIOD +#define LD6_Pin GPIO_PIN_15 +#define LD6_GPIO_Port GPIOD +#define I2S3_MCK_Pin GPIO_PIN_7 +#define I2S3_MCK_GPIO_Port GPIOC +#define VBUS_FS_Pin GPIO_PIN_9 +#define VBUS_FS_GPIO_Port GPIOA +#define OTG_FS_ID_Pin GPIO_PIN_10 +#define OTG_FS_ID_GPIO_Port GPIOA +#define OTG_FS_DM_Pin GPIO_PIN_11 +#define OTG_FS_DM_GPIO_Port GPIOA +#define OTG_FS_DP_Pin GPIO_PIN_12 +#define OTG_FS_DP_GPIO_Port GPIOA +#define SWDIO_Pin GPIO_PIN_13 +#define SWDIO_GPIO_Port GPIOA +#define SWCLK_Pin GPIO_PIN_14 +#define SWCLK_GPIO_Port GPIOA +#define I2S3_SCK_Pin GPIO_PIN_10 +#define I2S3_SCK_GPIO_Port GPIOC +#define I2S3_SD_Pin GPIO_PIN_12 +#define I2S3_SD_GPIO_Port GPIOC +#define Audio_RST_Pin GPIO_PIN_4 +#define Audio_RST_GPIO_Port GPIOD +#define OTG_FS_OverCurrent_Pin GPIO_PIN_5 +#define OTG_FS_OverCurrent_GPIO_Port GPIOD +#define SWO_Pin GPIO_PIN_3 +#define SWO_GPIO_Port GPIOB +#define Audio_SCL_Pin GPIO_PIN_6 +#define Audio_SCL_GPIO_Port GPIOB +#define Audio_SDA_Pin GPIO_PIN_9 +#define Audio_SDA_GPIO_Port GPIOB +#define MEMS_INT2_Pin GPIO_PIN_1 +#define MEMS_INT2_GPIO_Port GPIOE + +/* USER CODE END Define */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN Macro */ + +/* USER CODE END Macro */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* External functions --------------------------------------------------------*/ +/* USER CODE BEGIN ExternalFunctions */ + +/* USER CODE END ExternalFunctions */ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + __HAL_RCC_PWR_CLK_ENABLE(); + + HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0); + + /* System interrupt init*/ + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + +/** +* @brief I2C MSP Initialization +* This function configures the hardware resources used in this example +* @param hi2c: I2C handle pointer +* @retval None +*/ +void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hi2c->Instance==I2C1) + { + /* USER CODE BEGIN I2C1_MspInit 0 */ + + /* USER CODE END I2C1_MspInit 0 */ + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**I2C1 GPIO Configuration + PB6 ------> I2C1_SCL + PB9 ------> I2C1_SDA + */ + GPIO_InitStruct.Pin = Audio_SCL_Pin|Audio_SDA_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* Peripheral clock enable */ + __HAL_RCC_I2C1_CLK_ENABLE(); + /* USER CODE BEGIN I2C1_MspInit 1 */ + + /* USER CODE END I2C1_MspInit 1 */ + } + +} + +/** +* @brief I2C MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hi2c: I2C handle pointer +* @retval None +*/ +void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c) +{ + if(hi2c->Instance==I2C1) + { + /* USER CODE BEGIN I2C1_MspDeInit 0 */ + + /* USER CODE END I2C1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_I2C1_CLK_DISABLE(); + + /**I2C1 GPIO Configuration + PB6 ------> I2C1_SCL + PB9 ------> I2C1_SDA + */ + HAL_GPIO_DeInit(GPIOB, Audio_SCL_Pin|Audio_SDA_Pin); + + /* USER CODE BEGIN I2C1_MspDeInit 1 */ + + /* USER CODE END I2C1_MspDeInit 1 */ + } + +} + +/** +* @brief I2S MSP Initialization +* This function configures the hardware resources used in this example +* @param hi2s: I2S handle pointer +* @retval None +*/ +void HAL_I2S_MspInit(I2S_HandleTypeDef* hi2s) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hi2s->Instance==SPI2) + { + /* USER CODE BEGIN SPI2_MspInit 0 */ + + /* USER CODE END SPI2_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_SPI2_CLK_ENABLE(); + + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**I2S2 GPIO Configuration + PC2 ------> I2S2_ext_SD + PC3 ------> I2S2_SD + PB10 ------> I2S2_CK + PB12 ------> I2S2_WS + */ + GPIO_InitStruct.Pin = GPIO_PIN_2; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF6_I2S2ext; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = PDM_OUT_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; + HAL_GPIO_Init(PDM_OUT_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = CLK_IN_Pin|GPIO_PIN_12; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN SPI2_MspInit 1 */ + + /* USER CODE END SPI2_MspInit 1 */ + } + else if(hi2s->Instance==SPI3) + { + /* USER CODE BEGIN SPI3_MspInit 0 */ + + /* USER CODE END SPI3_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_SPI3_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + /**I2S3 GPIO Configuration + PA4 ------> I2S3_WS + PC7 ------> I2S3_MCK + PC10 ------> I2S3_CK + PC12 ------> I2S3_SD + */ + GPIO_InitStruct.Pin = I2S3_WS_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF6_SPI3; + HAL_GPIO_Init(I2S3_WS_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = I2S3_MCK_Pin|I2S3_SCK_Pin|I2S3_SD_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF6_SPI3; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /* USER CODE BEGIN SPI3_MspInit 1 */ + + /* USER CODE END SPI3_MspInit 1 */ + } + +} + +/** +* @brief I2S MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hi2s: I2S handle pointer +* @retval None +*/ +void HAL_I2S_MspDeInit(I2S_HandleTypeDef* hi2s) +{ + if(hi2s->Instance==SPI2) + { + /* USER CODE BEGIN SPI2_MspDeInit 0 */ + + /* USER CODE END SPI2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SPI2_CLK_DISABLE(); + + /**I2S2 GPIO Configuration + PC2 ------> I2S2_ext_SD + PC3 ------> I2S2_SD + PB10 ------> I2S2_CK + PB12 ------> I2S2_WS + */ + HAL_GPIO_DeInit(GPIOC, GPIO_PIN_2|PDM_OUT_Pin); + + HAL_GPIO_DeInit(GPIOB, CLK_IN_Pin|GPIO_PIN_12); + + /* USER CODE BEGIN SPI2_MspDeInit 1 */ + + /* USER CODE END SPI2_MspDeInit 1 */ + } + else if(hi2s->Instance==SPI3) + { + /* USER CODE BEGIN SPI3_MspDeInit 0 */ + + /* USER CODE END SPI3_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SPI3_CLK_DISABLE(); + + /**I2S3 GPIO Configuration + PA4 ------> I2S3_WS + PC7 ------> I2S3_MCK + PC10 ------> I2S3_CK + PC12 ------> I2S3_SD + */ + HAL_GPIO_DeInit(I2S3_WS_GPIO_Port, I2S3_WS_Pin); + + HAL_GPIO_DeInit(GPIOC, I2S3_MCK_Pin|I2S3_SCK_Pin|I2S3_SD_Pin); + + /* USER CODE BEGIN SPI3_MspDeInit 1 */ + + /* USER CODE END SPI3_MspDeInit 1 */ + } + +} + +/** +* @brief SPI MSP Initialization +* This function configures the hardware resources used in this example +* @param hspi: SPI handle pointer +* @retval None +*/ +void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hspi->Instance==SPI1) + { + /* USER CODE BEGIN SPI1_MspInit 0 */ + + /* USER CODE END SPI1_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_SPI1_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**SPI1 GPIO Configuration + PA5 ------> SPI1_SCK + PA6 ------> SPI1_MISO + PA7 ------> SPI1_MOSI + */ + GPIO_InitStruct.Pin = SPI1_SCK_Pin|SPI1_MISO_Pin|SPI1_MOSI_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN SPI1_MspInit 1 */ + + /* USER CODE END SPI1_MspInit 1 */ + } + +} + +/** +* @brief SPI MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hspi: SPI handle pointer +* @retval None +*/ +void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) +{ + if(hspi->Instance==SPI1) + { + /* USER CODE BEGIN SPI1_MspDeInit 0 */ + + /* USER CODE END SPI1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SPI1_CLK_DISABLE(); + + /**SPI1 GPIO Configuration + PA5 ------> SPI1_SCK + PA6 ------> SPI1_MISO + PA7 ------> SPI1_MOSI + */ + HAL_GPIO_DeInit(GPIOA, SPI1_SCK_Pin|SPI1_MISO_Pin|SPI1_MOSI_Pin); + + /* USER CODE BEGIN SPI1_MspDeInit 1 */ + + /* USER CODE END SPI1_MspDeInit 1 */ + } + +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/board.c b/ports/stm32f4/boards/stm32f412zg_discovery/board.c new file mode 100644 index 00000000000..4421970eefe --- /dev/null +++ b/ports/stm32f4/boards/stm32f412zg_discovery/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.h b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.h new file mode 100644 index 00000000000..416944257b8 --- /dev/null +++ b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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. + */ + +//Micropython setup + +#define MICROPY_HW_BOARD_NAME "STM32F412G_DISCO" +#define MICROPY_HW_MCU_NAME "STM32F412xGS" + +#define FLASH_SIZE (0x100000) +#define FLASH_PAGE_SIZE (0x4000) + +#define CIRCUITPY_INTERNAL_NVM_SIZE (4096) +#define AUTORESET_DELAY_MS 500 +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) \ No newline at end of file diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk new file mode 100644 index 00000000000..444795874bb --- /dev/null +++ b/ports/stm32f4/boards/stm32f412zg_discovery/mpconfigboard.mk @@ -0,0 +1,13 @@ +USB_VID = 0x483 +USB_PID = 0x572B +USB_PRODUCT = "STM32F412ZG Discovery Board - CPy" +USB_MANUFACTURER = "STMicroelectronics" + +MCU_SERIES = m4 +MCU_VARIANT = stm32f4 +MCU_SUB_VARIANT = stm32f412zx +CMSIS_MCU = STM32F412xG +LD_FILE = boards/STM32F412ZGTx_FLASH.ld +TEXT0_ADDR = 0x08000000 +TEXT1_ADDR = 0x08020000 + diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/pins.c b/ports/stm32f4/boards/stm32f412zg_discovery/pins.c new file mode 100644 index 00000000000..e3a4b5ed60d --- /dev/null +++ b/ports/stm32f4/boards/stm32f412zg_discovery/pins.c @@ -0,0 +1,90 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_PE02), MP_ROM_PTR(&pin_PE02) }, + { MP_ROM_QSTR(MP_QSTR_PE03), MP_ROM_PTR(&pin_PE03) }, + { MP_ROM_QSTR(MP_QSTR_PE04), MP_ROM_PTR(&pin_PE04) }, + { MP_ROM_QSTR(MP_QSTR_PE05), MP_ROM_PTR(&pin_PE05) }, + { MP_ROM_QSTR(MP_QSTR_PE06), MP_ROM_PTR(&pin_PE06) }, + { MP_ROM_QSTR(MP_QSTR_PC13), MP_ROM_PTR(&pin_PC13) }, + { MP_ROM_QSTR(MP_QSTR_PF02), MP_ROM_PTR(&pin_PF02) }, + { MP_ROM_QSTR(MP_QSTR_PF03), MP_ROM_PTR(&pin_PF03) }, + { MP_ROM_QSTR(MP_QSTR_PF10), MP_ROM_PTR(&pin_PF10) }, + { MP_ROM_QSTR(MP_QSTR_PC00), MP_ROM_PTR(&pin_PC00) }, + { MP_ROM_QSTR(MP_QSTR_PC01), MP_ROM_PTR(&pin_PC01) }, + { MP_ROM_QSTR(MP_QSTR_PC02), MP_ROM_PTR(&pin_PC02) }, + { MP_ROM_QSTR(MP_QSTR_PC03), MP_ROM_PTR(&pin_PC03) }, + { MP_ROM_QSTR(MP_QSTR_PA01), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_PA02), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_PA03), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_PA04), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_PA05), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_PA06), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_PA07), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_PC04), MP_ROM_PTR(&pin_PC04) }, + { MP_ROM_QSTR(MP_QSTR_PC05), MP_ROM_PTR(&pin_PC05) }, + { MP_ROM_QSTR(MP_QSTR_PB00), MP_ROM_PTR(&pin_PB00) }, + { MP_ROM_QSTR(MP_QSTR_PB01), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_PF11), MP_ROM_PTR(&pin_PF11) }, + { MP_ROM_QSTR(MP_QSTR_PF13), MP_ROM_PTR(&pin_PF13) }, + { MP_ROM_QSTR(MP_QSTR_PB10), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_PB11), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_PB12), MP_ROM_PTR(&pin_PB12) }, + { MP_ROM_QSTR(MP_QSTR_PB13), MP_ROM_PTR(&pin_PB13) }, + { MP_ROM_QSTR(MP_QSTR_PB14), MP_ROM_PTR(&pin_PB14) }, + { MP_ROM_QSTR(MP_QSTR_PB15), MP_ROM_PTR(&pin_PB15) }, + { MP_ROM_QSTR(MP_QSTR_PD12), MP_ROM_PTR(&pin_PD12) }, + { MP_ROM_QSTR(MP_QSTR_PD13), MP_ROM_PTR(&pin_PD13) }, + { MP_ROM_QSTR(MP_QSTR_PG02), MP_ROM_PTR(&pin_PG02) }, + { MP_ROM_QSTR(MP_QSTR_PC06), MP_ROM_PTR(&pin_PC06) }, + { MP_ROM_QSTR(MP_QSTR_PC07), MP_ROM_PTR(&pin_PC07) }, + { MP_ROM_QSTR(MP_QSTR_PC09), MP_ROM_PTR(&pin_PC09) }, + { MP_ROM_QSTR(MP_QSTR_PA08), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_PA10), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_PA13), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_PA14), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_PA15), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_PD06), MP_ROM_PTR(&pin_PD06) }, + { MP_ROM_QSTR(MP_QSTR_PG09), MP_ROM_PTR(&pin_PG09) }, + { MP_ROM_QSTR(MP_QSTR_PG10), MP_ROM_PTR(&pin_PG10) }, + { MP_ROM_QSTR(MP_QSTR_PG11), MP_ROM_PTR(&pin_PG11) }, + { MP_ROM_QSTR(MP_QSTR_PG12), MP_ROM_PTR(&pin_PG12) }, + { MP_ROM_QSTR(MP_QSTR_PG13), MP_ROM_PTR(&pin_PG13) }, + { MP_ROM_QSTR(MP_QSTR_PG14), MP_ROM_PTR(&pin_PG14) }, + { MP_ROM_QSTR(MP_QSTR_PB03), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_PB04), MP_ROM_PTR(&pin_PB04) }, + { MP_ROM_QSTR(MP_QSTR_PB05), MP_ROM_PTR(&pin_PB05) }, + { MP_ROM_QSTR(MP_QSTR_PB06), MP_ROM_PTR(&pin_PB06) }, + { MP_ROM_QSTR(MP_QSTR_PB07), MP_ROM_PTR(&pin_PB07) }, + { MP_ROM_QSTR(MP_QSTR_PB08), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_PB09), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_PE00), MP_ROM_PTR(&pin_PE00) }, + { MP_ROM_QSTR(MP_QSTR_PE01), MP_ROM_PTR(&pin_PE01) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PG10) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PG11) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PF03) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PF10) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PG12) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PF04) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PG13) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PG14) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PG09) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PC01) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PC03) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PC04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PC05) }, //alt PB09, see F401ZG-DISCO manual + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB00) }, //alt PB10, see F401ZG-DISCO manual + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_PE00) }, + { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_PE01) }, + { MP_ROM_QSTR(MP_QSTR_LED3), MP_ROM_PTR(&pin_PE02) }, + { MP_ROM_QSTR(MP_QSTR_LED4), MP_ROM_PTR(&pin_PE03) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h new file mode 100644 index 00000000000..5d329c14f5d --- /dev/null +++ b/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h @@ -0,0 +1,439 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf_template.h + * @author MCD Application Team + * @brief HAL configuration template file. + * This file should be copied to the application folder and renamed + * to stm32f4xx_hal_conf.h. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_CONF_H +#define __STM32F4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED + + /* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCCARD_MODULE_ENABLED */ +#define HAL_SRAM_MODULE_ENABLED +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_I2C_MODULE_ENABLED +#define HAL_I2S_MODULE_ENABLED +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +#define HAL_SD_MODULE_ENABLED +/* #define HAL_MMC_MODULE_ENABLED */ +/* #define HAL_SPI_MODULE_ENABLED */ +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_PCD_MODULE_ENABLED +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_QSPI_MODULE_ENABLED +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_FMPI2C_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_EXTI_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the External audio frequency in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848_PHY_ADDRESS Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY ((uint32_t)0x000000FFU) +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU) + +#define PHY_READ_TO ((uint32_t)0x0000FFFFU) +#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU) + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ +#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */ + +#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f4xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f4xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32f4xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f4xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_FMPI2C_MODULE_ENABLED + #include "stm32f4xx_hal_fmpi2c.h" +#endif /* HAL_FMPI2C_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f4xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_msp.c b/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_msp.c new file mode 100644 index 00000000000..9d29f360797 --- /dev/null +++ b/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_msp.c @@ -0,0 +1,832 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : stm32f4xx_hal_msp.c + * Description : This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN Define */ +#define LED3_Pin GPIO_PIN_2 +#define LED3_GPIO_Port GPIOE +#define LED4_Pin GPIO_PIN_3 +#define LED4_GPIO_Port GPIOE +#define DFSDM_DATIN3_Pin GPIO_PIN_4 +#define DFSDM_DATIN3_GPIO_Port GPIOE +#define A0_Pin GPIO_PIN_0 +#define A0_GPIO_Port GPIOF +#define LCD_BLCTRL_Pin GPIO_PIN_5 +#define LCD_BLCTRL_GPIO_Port GPIOF +#define QSPI_BK1_IO3_Pin GPIO_PIN_6 +#define QSPI_BK1_IO3_GPIO_Port GPIOF +#define QSPI_BK1_IO2_Pin GPIO_PIN_7 +#define QSPI_BK1_IO2_GPIO_Port GPIOF +#define QSPI_BK1_IO0_Pin GPIO_PIN_8 +#define QSPI_BK1_IO0_GPIO_Port GPIOF +#define QSPI_BK1_IO1_Pin GPIO_PIN_9 +#define QSPI_BK1_IO1_GPIO_Port GPIOF +#define STLK_MCO_Pin GPIO_PIN_0 +#define STLK_MCO_GPIO_Port GPIOH +#define DFSDM_CKOUT_Pin GPIO_PIN_2 +#define DFSDM_CKOUT_GPIO_Port GPIOC +#define JOY_SEL_Pin GPIO_PIN_0 +#define JOY_SEL_GPIO_Port GPIOA +#define STLINK_RX_Pin GPIO_PIN_2 +#define STLINK_RX_GPIO_Port GPIOA +#define STLINK_TX_Pin GPIO_PIN_3 +#define STLINK_TX_GPIO_Port GPIOA +#define CODEC_I2S3_WS_Pin GPIO_PIN_4 +#define CODEC_I2S3_WS_GPIO_Port GPIOA +#define DFSDM_DATIN0_Pin GPIO_PIN_1 +#define DFSDM_DATIN0_GPIO_Port GPIOB +#define QSPI_CLK_Pin GPIO_PIN_2 +#define QSPI_CLK_GPIO_Port GPIOB +#define EXT_RESET_Pin GPIO_PIN_11 +#define EXT_RESET_GPIO_Port GPIOF +#define CTP_RST_Pin GPIO_PIN_12 +#define CTP_RST_GPIO_Port GPIOF +#define JOY_RIGHT_Pin GPIO_PIN_14 +#define JOY_RIGHT_GPIO_Port GPIOF +#define JOY_LEFT_Pin GPIO_PIN_15 +#define JOY_LEFT_GPIO_Port GPIOF +#define JOY_UP_Pin GPIO_PIN_0 +#define JOY_UP_GPIO_Port GPIOG +#define JOY_DOWN_Pin GPIO_PIN_1 +#define JOY_DOWN_GPIO_Port GPIOG +#define D4_Pin GPIO_PIN_7 +#define D4_GPIO_Port GPIOE +#define D5_Pin GPIO_PIN_8 +#define D5_GPIO_Port GPIOE +#define D6_Pin GPIO_PIN_9 +#define D6_GPIO_Port GPIOE +#define D7_Pin GPIO_PIN_10 +#define D7_GPIO_Port GPIOE +#define D8_Pin GPIO_PIN_11 +#define D8_GPIO_Port GPIOE +#define D9_Pin GPIO_PIN_12 +#define D9_GPIO_Port GPIOE +#define D10_Pin GPIO_PIN_13 +#define D10_GPIO_Port GPIOE +#define D11_Pin GPIO_PIN_14 +#define D11_GPIO_Port GPIOE +#define D12_Pin GPIO_PIN_15 +#define D12_GPIO_Port GPIOE +#define I2C2_SCL_Pin GPIO_PIN_10 +#define I2C2_SCL_GPIO_Port GPIOB +#define M2_CKIN_Pin GPIO_PIN_11 +#define M2_CKIN_GPIO_Port GPIOB +#define CODEC_I2S3_SCK_Pin GPIO_PIN_12 +#define CODEC_I2S3_SCK_GPIO_Port GPIOB +#define D13_Pin GPIO_PIN_8 +#define D13_GPIO_Port GPIOD +#define D14_Pin GPIO_PIN_9 +#define D14_GPIO_Port GPIOD +#define D15_Pin GPIO_PIN_10 +#define D15_GPIO_Port GPIOD +#define LCD_RESET_Pin GPIO_PIN_11 +#define LCD_RESET_GPIO_Port GPIOD +#define D0_Pin GPIO_PIN_14 +#define D0_GPIO_Port GPIOD +#define D1_Pin GPIO_PIN_15 +#define D1_GPIO_Port GPIOD +#define CODEC_INT_Pin GPIO_PIN_2 +#define CODEC_INT_GPIO_Port GPIOG +#define LCD_TE_Pin GPIO_PIN_4 +#define LCD_TE_GPIO_Port GPIOG +#define CTP_INT_Pin GPIO_PIN_5 +#define CTP_INT_GPIO_Port GPIOG +#define QSPI_BK1_NCS_Pin GPIO_PIN_6 +#define QSPI_BK1_NCS_GPIO_Port GPIOG +#define USB_OTGFS_OVRCR_Pin GPIO_PIN_7 +#define USB_OTGFS_OVRCR_GPIO_Port GPIOG +#define USB_OTGFS_PPWR_EN_Pin GPIO_PIN_8 +#define USB_OTGFS_PPWR_EN_GPIO_Port GPIOG +#define CODEC_I2S3_MCK_Pin GPIO_PIN_7 +#define CODEC_I2S3_MCK_GPIO_Port GPIOC +#define uSD_D0_Pin GPIO_PIN_8 +#define uSD_D0_GPIO_Port GPIOC +#define uSD_D1_Pin GPIO_PIN_9 +#define uSD_D1_GPIO_Port GPIOC +#define M2_CKINA8_Pin GPIO_PIN_8 +#define M2_CKINA8_GPIO_Port GPIOA +#define USB_OTGFS_VBUS_Pin GPIO_PIN_9 +#define USB_OTGFS_VBUS_GPIO_Port GPIOA +#define USB_OTGFS_ID_Pin GPIO_PIN_10 +#define USB_OTGFS_ID_GPIO_Port GPIOA +#define USB_OTGFS_DM_Pin GPIO_PIN_11 +#define USB_OTGFS_DM_GPIO_Port GPIOA +#define USB_OTGFS_DP_Pin GPIO_PIN_12 +#define USB_OTGFS_DP_GPIO_Port GPIOA +#define SWDIO_Pin GPIO_PIN_13 +#define SWDIO_GPIO_Port GPIOA +#define SWCLK_Pin GPIO_PIN_14 +#define SWCLK_GPIO_Port GPIOA +#define uSD_D2_Pin GPIO_PIN_10 +#define uSD_D2_GPIO_Port GPIOC +#define uSD_D3_Pin GPIO_PIN_11 +#define uSD_D3_GPIO_Port GPIOC +#define uSD_CLK_Pin GPIO_PIN_12 +#define uSD_CLK_GPIO_Port GPIOC +#define D2_Pin GPIO_PIN_0 +#define D2_GPIO_Port GPIOD +#define D3_Pin GPIO_PIN_1 +#define D3_GPIO_Port GPIOD +#define uSD_CMD_Pin GPIO_PIN_2 +#define uSD_CMD_GPIO_Port GPIOD +#define uSD_DETECT_Pin GPIO_PIN_3 +#define uSD_DETECT_GPIO_Port GPIOD +#define FMC_NOE_Pin GPIO_PIN_4 +#define FMC_NOE_GPIO_Port GPIOD +#define FMC_NWE_Pin GPIO_PIN_5 +#define FMC_NWE_GPIO_Port GPIOD +#define FMC_NE1_Pin GPIO_PIN_7 +#define FMC_NE1_GPIO_Port GPIOD +#define SWO_Pin GPIO_PIN_3 +#define SWO_GPIO_Port GPIOB +#define CODEC_I2S3ext_SD_Pin GPIO_PIN_4 +#define CODEC_I2S3ext_SD_GPIO_Port GPIOB +#define CODEC_I2S3_SD_Pin GPIO_PIN_5 +#define CODEC_I2S3_SD_GPIO_Port GPIOB +#define I2C1_SCL_Pin GPIO_PIN_6 +#define I2C1_SCL_GPIO_Port GPIOB +#define I2C1_SDA_Pin GPIO_PIN_7 +#define I2C1_SDA_GPIO_Port GPIOB +#define I2C2_SDA_Pin GPIO_PIN_9 +#define I2C2_SDA_GPIO_Port GPIOB +#define LED1_Pin GPIO_PIN_0 +#define LED1_GPIO_Port GPIOE +#define LED2_Pin GPIO_PIN_1 +#define LED2_GPIO_Port GPIOE + +/* USER CODE END Define */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN Macro */ + +/* USER CODE END Macro */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* External functions --------------------------------------------------------*/ +/* USER CODE BEGIN ExternalFunctions */ + +/* USER CODE END ExternalFunctions */ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + __HAL_RCC_PWR_CLK_ENABLE(); + + /* System interrupt init*/ + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + +/** +* @brief I2C MSP Initialization +* This function configures the hardware resources used in this example +* @param hi2c: I2C handle pointer +* @retval None +*/ +void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hi2c->Instance==I2C1) + { + /* USER CODE BEGIN I2C1_MspInit 0 */ + + /* USER CODE END I2C1_MspInit 0 */ + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**I2C1 GPIO Configuration + PB6 ------> I2C1_SCL + PB7 ------> I2C1_SDA + */ + GPIO_InitStruct.Pin = I2C1_SCL_Pin|I2C1_SDA_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* Peripheral clock enable */ + __HAL_RCC_I2C1_CLK_ENABLE(); + /* USER CODE BEGIN I2C1_MspInit 1 */ + + /* USER CODE END I2C1_MspInit 1 */ + } + else if(hi2c->Instance==I2C2) + { + /* USER CODE BEGIN I2C2_MspInit 0 */ + + /* USER CODE END I2C2_MspInit 0 */ + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**I2C2 GPIO Configuration + PB10 ------> I2C2_SCL + PB9 ------> I2C2_SDA + */ + GPIO_InitStruct.Pin = I2C2_SCL_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF4_I2C2; + HAL_GPIO_Init(I2C2_SCL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = I2C2_SDA_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF9_I2C2; + HAL_GPIO_Init(I2C2_SDA_GPIO_Port, &GPIO_InitStruct); + + /* Peripheral clock enable */ + __HAL_RCC_I2C2_CLK_ENABLE(); + /* USER CODE BEGIN I2C2_MspInit 1 */ + + /* USER CODE END I2C2_MspInit 1 */ + } + +} + +/** +* @brief I2C MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hi2c: I2C handle pointer +* @retval None +*/ +void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c) +{ + if(hi2c->Instance==I2C1) + { + /* USER CODE BEGIN I2C1_MspDeInit 0 */ + + /* USER CODE END I2C1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_I2C1_CLK_DISABLE(); + + /**I2C1 GPIO Configuration + PB6 ------> I2C1_SCL + PB7 ------> I2C1_SDA + */ + HAL_GPIO_DeInit(GPIOB, I2C1_SCL_Pin|I2C1_SDA_Pin); + + /* USER CODE BEGIN I2C1_MspDeInit 1 */ + + /* USER CODE END I2C1_MspDeInit 1 */ + } + else if(hi2c->Instance==I2C2) + { + /* USER CODE BEGIN I2C2_MspDeInit 0 */ + + /* USER CODE END I2C2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_I2C2_CLK_DISABLE(); + + /**I2C2 GPIO Configuration + PB10 ------> I2C2_SCL + PB9 ------> I2C2_SDA + */ + HAL_GPIO_DeInit(GPIOB, I2C2_SCL_Pin|I2C2_SDA_Pin); + + /* USER CODE BEGIN I2C2_MspDeInit 1 */ + + /* USER CODE END I2C2_MspDeInit 1 */ + } + +} + +/** +* @brief I2S MSP Initialization +* This function configures the hardware resources used in this example +* @param hi2s: I2S handle pointer +* @retval None +*/ +void HAL_I2S_MspInit(I2S_HandleTypeDef* hi2s) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hi2s->Instance==SPI3) + { + /* USER CODE BEGIN SPI3_MspInit 0 */ + + /* USER CODE END SPI3_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_SPI3_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + /**I2S3 GPIO Configuration + PA4 ------> I2S3_WS + PB12 ------> I2S3_CK + PC7 ------> I2S3_MCK + PB4 ------> I2S3_ext_SD + PB5 ------> I2S3_SD + */ + GPIO_InitStruct.Pin = CODEC_I2S3_WS_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF6_SPI3; + HAL_GPIO_Init(CODEC_I2S3_WS_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = CODEC_I2S3_SCK_Pin|CODEC_I2S3ext_SD_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF7_SPI3; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = CODEC_I2S3_MCK_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF6_SPI3; + HAL_GPIO_Init(CODEC_I2S3_MCK_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = CODEC_I2S3_SD_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF6_SPI3; + HAL_GPIO_Init(CODEC_I2S3_SD_GPIO_Port, &GPIO_InitStruct); + + /* USER CODE BEGIN SPI3_MspInit 1 */ + + /* USER CODE END SPI3_MspInit 1 */ + } + +} + +/** +* @brief I2S MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hi2s: I2S handle pointer +* @retval None +*/ +void HAL_I2S_MspDeInit(I2S_HandleTypeDef* hi2s) +{ + if(hi2s->Instance==SPI3) + { + /* USER CODE BEGIN SPI3_MspDeInit 0 */ + + /* USER CODE END SPI3_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SPI3_CLK_DISABLE(); + + /**I2S3 GPIO Configuration + PA4 ------> I2S3_WS + PB12 ------> I2S3_CK + PC7 ------> I2S3_MCK + PB4 ------> I2S3_ext_SD + PB5 ------> I2S3_SD + */ + HAL_GPIO_DeInit(CODEC_I2S3_WS_GPIO_Port, CODEC_I2S3_WS_Pin); + + HAL_GPIO_DeInit(GPIOB, CODEC_I2S3_SCK_Pin|CODEC_I2S3ext_SD_Pin|CODEC_I2S3_SD_Pin); + + HAL_GPIO_DeInit(CODEC_I2S3_MCK_GPIO_Port, CODEC_I2S3_MCK_Pin); + + /* USER CODE BEGIN SPI3_MspDeInit 1 */ + + /* USER CODE END SPI3_MspDeInit 1 */ + } + +} + +/** +* @brief QSPI MSP Initialization +* This function configures the hardware resources used in this example +* @param hqspi: QSPI handle pointer +* @retval None +*/ +void HAL_QSPI_MspInit(QSPI_HandleTypeDef* hqspi) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hqspi->Instance==QUADSPI) + { + /* USER CODE BEGIN QUADSPI_MspInit 0 */ + + /* USER CODE END QUADSPI_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_QSPI_CLK_ENABLE(); + + __HAL_RCC_GPIOF_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + /**QUADSPI GPIO Configuration + PF6 ------> QUADSPI_BK1_IO3 + PF7 ------> QUADSPI_BK1_IO2 + PF8 ------> QUADSPI_BK1_IO0 + PF9 ------> QUADSPI_BK1_IO1 + PB2 ------> QUADSPI_CLK + PG6 ------> QUADSPI_BK1_NCS + */ + GPIO_InitStruct.Pin = QSPI_BK1_IO3_Pin|QSPI_BK1_IO2_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF9_QSPI; + HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = QSPI_BK1_IO0_Pin|QSPI_BK1_IO1_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = QSPI_CLK_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF9_QSPI; + HAL_GPIO_Init(QSPI_CLK_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = QSPI_BK1_NCS_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(QSPI_BK1_NCS_GPIO_Port, &GPIO_InitStruct); + + /* USER CODE BEGIN QUADSPI_MspInit 1 */ + + /* USER CODE END QUADSPI_MspInit 1 */ + } + +} + +/** +* @brief QSPI MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hqspi: QSPI handle pointer +* @retval None +*/ +void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef* hqspi) +{ + if(hqspi->Instance==QUADSPI) + { + /* USER CODE BEGIN QUADSPI_MspDeInit 0 */ + + /* USER CODE END QUADSPI_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_QSPI_CLK_DISABLE(); + + /**QUADSPI GPIO Configuration + PF6 ------> QUADSPI_BK1_IO3 + PF7 ------> QUADSPI_BK1_IO2 + PF8 ------> QUADSPI_BK1_IO0 + PF9 ------> QUADSPI_BK1_IO1 + PB2 ------> QUADSPI_CLK + PG6 ------> QUADSPI_BK1_NCS + */ + HAL_GPIO_DeInit(GPIOF, QSPI_BK1_IO3_Pin|QSPI_BK1_IO2_Pin|QSPI_BK1_IO0_Pin|QSPI_BK1_IO1_Pin); + + HAL_GPIO_DeInit(QSPI_CLK_GPIO_Port, QSPI_CLK_Pin); + + HAL_GPIO_DeInit(QSPI_BK1_NCS_GPIO_Port, QSPI_BK1_NCS_Pin); + + /* USER CODE BEGIN QUADSPI_MspDeInit 1 */ + + /* USER CODE END QUADSPI_MspDeInit 1 */ + } + +} + +/** +* @brief SD MSP Initialization +* This function configures the hardware resources used in this example +* @param hsd: SD handle pointer +* @retval None +*/ +void HAL_SD_MspInit(SD_HandleTypeDef* hsd) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hsd->Instance==SDIO) + { + /* USER CODE BEGIN SDIO_MspInit 0 */ + + /* USER CODE END SDIO_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_SDIO_CLK_ENABLE(); + + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + /**SDIO GPIO Configuration + PC8 ------> SDIO_D0 + PC9 ------> SDIO_D1 + PC10 ------> SDIO_D2 + PC11 ------> SDIO_D3 + PC12 ------> SDIO_CK + PD2 ------> SDIO_CMD + */ + GPIO_InitStruct.Pin = uSD_D0_Pin|uSD_D1_Pin|uSD_D2_Pin|uSD_D3_Pin + |uSD_CLK_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = uSD_CMD_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; + HAL_GPIO_Init(uSD_CMD_GPIO_Port, &GPIO_InitStruct); + + /* USER CODE BEGIN SDIO_MspInit 1 */ + + /* USER CODE END SDIO_MspInit 1 */ + } + +} + +/** +* @brief SD MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hsd: SD handle pointer +* @retval None +*/ +void HAL_SD_MspDeInit(SD_HandleTypeDef* hsd) +{ + if(hsd->Instance==SDIO) + { + /* USER CODE BEGIN SDIO_MspDeInit 0 */ + + /* USER CODE END SDIO_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SDIO_CLK_DISABLE(); + + /**SDIO GPIO Configuration + PC8 ------> SDIO_D0 + PC9 ------> SDIO_D1 + PC10 ------> SDIO_D2 + PC11 ------> SDIO_D3 + PC12 ------> SDIO_CK + PD2 ------> SDIO_CMD + */ + HAL_GPIO_DeInit(GPIOC, uSD_D0_Pin|uSD_D1_Pin|uSD_D2_Pin|uSD_D3_Pin + |uSD_CLK_Pin); + + HAL_GPIO_DeInit(uSD_CMD_GPIO_Port, uSD_CMD_Pin); + + /* USER CODE BEGIN SDIO_MspDeInit 1 */ + + /* USER CODE END SDIO_MspDeInit 1 */ + } + +} + +/** +* @brief UART MSP Initialization +* This function configures the hardware resources used in this example +* @param huart: UART handle pointer +* @retval None +*/ +void HAL_UART_MspInit(UART_HandleTypeDef* huart) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(huart->Instance==USART2) + { + /* USER CODE BEGIN USART2_MspInit 0 */ + + /* USER CODE END USART2_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_USART2_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**USART2 GPIO Configuration + PA2 ------> USART2_TX + PA3 ------> USART2_RX + */ + GPIO_InitStruct.Pin = STLINK_RX_Pin|STLINK_TX_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF7_USART2; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN USART2_MspInit 1 */ + + /* USER CODE END USART2_MspInit 1 */ + } + +} + +/** +* @brief UART MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param huart: UART handle pointer +* @retval None +*/ +void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) +{ + if(huart->Instance==USART2) + { + /* USER CODE BEGIN USART2_MspDeInit 0 */ + + /* USER CODE END USART2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USART2_CLK_DISABLE(); + + /**USART2 GPIO Configuration + PA2 ------> USART2_TX + PA3 ------> USART2_RX + */ + HAL_GPIO_DeInit(GPIOA, STLINK_RX_Pin|STLINK_TX_Pin); + + /* USER CODE BEGIN USART2_MspDeInit 1 */ + + /* USER CODE END USART2_MspDeInit 1 */ + } + +} + +static uint32_t FSMC_Initialized = 0; + +static void HAL_FSMC_MspInit(void){ + /* USER CODE BEGIN FSMC_MspInit 0 */ + + /* USER CODE END FSMC_MspInit 0 */ + GPIO_InitTypeDef GPIO_InitStruct ={0}; + if (FSMC_Initialized) { + return; + } + FSMC_Initialized = 1; + /* Peripheral clock enable */ + __HAL_RCC_FSMC_CLK_ENABLE(); + + /** FSMC GPIO Configuration + PF0 ------> FSMC_A0 + PE7 ------> FSMC_D4 + PE8 ------> FSMC_D5 + PE9 ------> FSMC_D6 + PE10 ------> FSMC_D7 + PE11 ------> FSMC_D8 + PE12 ------> FSMC_D9 + PE13 ------> FSMC_D10 + PE14 ------> FSMC_D11 + PE15 ------> FSMC_D12 + PD8 ------> FSMC_D13 + PD9 ------> FSMC_D14 + PD10 ------> FSMC_D15 + PD14 ------> FSMC_D0 + PD15 ------> FSMC_D1 + PD0 ------> FSMC_D2 + PD1 ------> FSMC_D3 + PD4 ------> FSMC_NOE + PD5 ------> FSMC_NWE + PD7 ------> FSMC_NE1 + */ + GPIO_InitStruct.Pin = A0_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_FSMC; + HAL_GPIO_Init(A0_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = D4_Pin|D5_Pin|D6_Pin|D7_Pin + |D8_Pin|D9_Pin|D10_Pin|D11_Pin + |D12_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_FSMC; + HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = D13_Pin|D14_Pin|D15_Pin|D0_Pin + |D1_Pin|D2_Pin|D3_Pin|FMC_NOE_Pin + |FMC_NWE_Pin|FMC_NE1_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_FSMC; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + /* USER CODE BEGIN FSMC_MspInit 1 */ + + /* USER CODE END FSMC_MspInit 1 */ +} + +void HAL_SRAM_MspInit(SRAM_HandleTypeDef* hsram){ + /* USER CODE BEGIN SRAM_MspInit 0 */ + + /* USER CODE END SRAM_MspInit 0 */ + HAL_FSMC_MspInit(); + /* USER CODE BEGIN SRAM_MspInit 1 */ + + /* USER CODE END SRAM_MspInit 1 */ +} + +static uint32_t FSMC_DeInitialized = 0; + +static void HAL_FSMC_MspDeInit(void){ + /* USER CODE BEGIN FSMC_MspDeInit 0 */ + + /* USER CODE END FSMC_MspDeInit 0 */ + if (FSMC_DeInitialized) { + return; + } + FSMC_DeInitialized = 1; + /* Peripheral clock enable */ + __HAL_RCC_FSMC_CLK_DISABLE(); + + /** FSMC GPIO Configuration + PF0 ------> FSMC_A0 + PE7 ------> FSMC_D4 + PE8 ------> FSMC_D5 + PE9 ------> FSMC_D6 + PE10 ------> FSMC_D7 + PE11 ------> FSMC_D8 + PE12 ------> FSMC_D9 + PE13 ------> FSMC_D10 + PE14 ------> FSMC_D11 + PE15 ------> FSMC_D12 + PD8 ------> FSMC_D13 + PD9 ------> FSMC_D14 + PD10 ------> FSMC_D15 + PD14 ------> FSMC_D0 + PD15 ------> FSMC_D1 + PD0 ------> FSMC_D2 + PD1 ------> FSMC_D3 + PD4 ------> FSMC_NOE + PD5 ------> FSMC_NWE + PD7 ------> FSMC_NE1 + */ + HAL_GPIO_DeInit(A0_GPIO_Port, A0_Pin); + + HAL_GPIO_DeInit(GPIOE, D4_Pin|D5_Pin|D6_Pin|D7_Pin + |D8_Pin|D9_Pin|D10_Pin|D11_Pin + |D12_Pin); + + HAL_GPIO_DeInit(GPIOD, D13_Pin|D14_Pin|D15_Pin|D0_Pin + |D1_Pin|D2_Pin|D3_Pin|FMC_NOE_Pin + |FMC_NWE_Pin|FMC_NE1_Pin); + + /* USER CODE BEGIN FSMC_MspDeInit 1 */ + + /* USER CODE END FSMC_MspDeInit 1 */ +} + +void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef* hsram){ + /* USER CODE BEGIN SRAM_MspDeInit 0 */ + + /* USER CODE END SRAM_MspDeInit 0 */ + HAL_FSMC_MspDeInit(); + /* USER CODE BEGIN SRAM_MspDeInit 1 */ + + /* USER CODE END SRAM_MspDeInit 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/ports/stm32f4/common-hal/board/__init__.c b/ports/stm32f4/common-hal/board/__init__.c new file mode 100644 index 00000000000..880033ed679 --- /dev/null +++ b/ports/stm32f4/common-hal/board/__init__.c @@ -0,0 +1,25 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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. + */ diff --git a/ports/stm32f4/common-hal/digitalio/DigitalInOut.c b/ports/stm32f4/common-hal/digitalio/DigitalInOut.c new file mode 100644 index 00000000000..0805779f432 --- /dev/null +++ b/ports/stm32f4/common-hal/digitalio/DigitalInOut.c @@ -0,0 +1,159 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * + * 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 "shared-bindings/digitalio/DigitalInOut.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" +#include "stm32f4xx_hal.h" +#include "stm32f4xx_ll_gpio.h" + +void common_hal_digitalio_digitalinout_never_reset( + digitalio_digitalinout_obj_t *self) { + never_reset_pin_number(self->pin->port_number, self->pin->number); +} + +digitalinout_result_t common_hal_digitalio_digitalinout_construct( + digitalio_digitalinout_obj_t *self, const mcu_pin_obj_t *pin) { + + claim_pin(pin); + self->pin = pin; + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = (1 << pin->number); + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(pin->port, &GPIO_InitStruct); + + return DIGITALINOUT_OK; +} + +bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t *self) { + return self->pin == mp_const_none; +} + +void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self) { + if (common_hal_digitalio_digitalinout_deinited(self)) { + return; + } + + reset_pin_number(self->pin->port_number, self->pin->number); + self->pin = mp_const_none; +} + +void common_hal_digitalio_digitalinout_switch_to_input( + digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = (1 << self->pin->number); + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(self->pin->port, &GPIO_InitStruct); + + common_hal_digitalio_digitalinout_set_pull(self, pull); +} + +void common_hal_digitalio_digitalinout_switch_to_output( + digitalio_digitalinout_obj_t *self, bool value, + digitalio_drive_mode_t drive_mode) { + + common_hal_digitalio_digitalinout_set_drive_mode(self, drive_mode); + common_hal_digitalio_digitalinout_set_value(self, value); +} + +digitalio_direction_t common_hal_digitalio_digitalinout_get_direction( + digitalio_digitalinout_obj_t *self) { + + return (LL_GPIO_GetPinMode(self->pin->port, (1 << self->pin->number)) + == LL_GPIO_MODE_INPUT) ? DIRECTION_INPUT : DIRECTION_OUTPUT; +} + +void common_hal_digitalio_digitalinout_set_value( + digitalio_digitalinout_obj_t *self, bool value) { + HAL_GPIO_WritePin(self->pin->port, 1 << self->pin->number, value); +} + +bool common_hal_digitalio_digitalinout_get_value( + digitalio_digitalinout_obj_t *self) { + return (LL_GPIO_GetPinMode(self->pin->port, (1 << self->pin->number)) == LL_GPIO_MODE_INPUT) + ? HAL_GPIO_ReadPin(self->pin->port, (1 << self->pin->number)) + : LL_GPIO_IsOutputPinSet(self->pin->port, (1 << self->pin->number)); +} + +void common_hal_digitalio_digitalinout_set_drive_mode( + digitalio_digitalinout_obj_t *self, + digitalio_drive_mode_t drive_mode) { + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = (1 << self->pin->number); + GPIO_InitStruct.Mode = (drive_mode == DRIVE_MODE_OPEN_DRAIN ? + GPIO_MODE_OUTPUT_OD : GPIO_MODE_OUTPUT_PP); + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(self->pin->port, &GPIO_InitStruct); +} + +digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( + digitalio_digitalinout_obj_t *self) { + + return LL_GPIO_GetPinOutputType(self->pin->port, (1 << self->pin->port_number)) + == LL_GPIO_OUTPUT_OPENDRAIN ? DRIVE_MODE_OPEN_DRAIN : DRIVE_MODE_PUSH_PULL; +} + +void common_hal_digitalio_digitalinout_set_pull( + digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { + + switch (pull) { + case PULL_UP: + LL_GPIO_SetPinPull(self->pin->port,(1 << self->pin->number),LL_GPIO_PULL_UP); + break; + case PULL_DOWN: + LL_GPIO_SetPinPull(self->pin->port,(1 << self->pin->number),LL_GPIO_PULL_DOWN); + break; + case PULL_NONE: + LL_GPIO_SetPinPull(self->pin->port,(1 << self->pin->number),LL_GPIO_PULL_NO); + break; + default: + break; + } +} + +digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( + digitalio_digitalinout_obj_t *self) { + + + switch (LL_GPIO_GetPinPull(self->pin->port,(1 << self->pin->number))) { + case LL_GPIO_PULL_UP: + return PULL_UP; + case LL_GPIO_PULL_DOWN: + return PULL_DOWN; + case LL_GPIO_PULL_NO: + return PULL_NONE; + default: + return PULL_NONE; + } +} diff --git a/ports/stm32f4/common-hal/digitalio/DigitalInOut.h b/ports/stm32f4/common-hal/digitalio/DigitalInOut.h new file mode 100644 index 00000000000..76aa2c85564 --- /dev/null +++ b/ports/stm32f4/common-hal/digitalio/DigitalInOut.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_STM32F4_COMMON_HAL_DIGITALIO_DIGITALINOUT_H +#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_DIGITALIO_DIGITALINOUT_H + +#include "common-hal/microcontroller/Pin.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t *pin; +} digitalio_digitalinout_obj_t; + +#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_DIGITALIO_DIGITALINOUT_H diff --git a/ports/stm32f4/common-hal/digitalio/__init__.c b/ports/stm32f4/common-hal/digitalio/__init__.c new file mode 100644 index 00000000000..20fad459593 --- /dev/null +++ b/ports/stm32f4/common-hal/digitalio/__init__.c @@ -0,0 +1 @@ +// No digitalio module functions. diff --git a/ports/stm32f4/common-hal/microcontroller/Pin.c b/ports/stm32f4/common-hal/microcontroller/Pin.c new file mode 100644 index 00000000000..6bfe56515e2 --- /dev/null +++ b/ports/stm32f4/common-hal/microcontroller/Pin.c @@ -0,0 +1,81 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * + * 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 "shared-bindings/microcontroller/Pin.h" + +#include "py/mphal.h" +#include "stm32f4/pins.h" +#include "stm32f4xx_hal.h" + +#define GPIO_PORT_COUNT 5 + +STATIC uint16_t claimed_pins[GPIO_PORT_COUNT]; +STATIC uint16_t never_reset_pins[GPIO_PORT_COUNT]; +GPIO_TypeDef * ports[GPIO_PORT_COUNT] = {GPIOA, GPIOB, GPIOC, GPIOD, GPIOE}; + +void reset_all_pins(void) { + // Reset claimed pins + for (uint8_t i = 0; i < GPIO_PORT_COUNT; i++) { + claimed_pins[i] = never_reset_pins[i]; + } + for (uint8_t i = 0; i < GPIO_PORT_COUNT; i++) { + HAL_GPIO_DeInit(ports[i], ~never_reset_pins[i]); + } +} + +// Mark pin as free and return it to a quiescent state. +void reset_pin_number(uint8_t pin_port, uint8_t pin_number) { + if (pin_number == NO_PIN) { + return; + } + + // Clear claimed bit. + claimed_pins[pin_port] &= ~(1 << pin_number); + // Reset the pin + HAL_GPIO_DeInit(ports[pin_port], (1 << pin_number)); +} + + +void never_reset_pin_number(uint8_t pin_port, uint8_t pin_number) { + never_reset_pins[pin_port] |= 1 << pin_number; +} + +void claim_pin(const mcu_pin_obj_t* pin) { + // Set bit in claimed_pins bitmask. + claimed_pins[pin->port_number] |= 1 << pin->number; +} + + +bool pin_number_is_free(uint8_t pin_port, uint8_t pin_number) { + return !(claimed_pins[pin_port] & (1 << pin_number)); +} + +bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) { + + return pin_number_is_free(pin->port_number, pin->number); + +} diff --git a/ports/stm32f4/common-hal/microcontroller/Pin.h b/ports/stm32f4/common-hal/microcontroller/Pin.h new file mode 100644 index 00000000000..e5b1b9ceb0e --- /dev/null +++ b/ports/stm32f4/common-hal/microcontroller/Pin.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_STM34F4_COMMON_HAL_MICROCONTROLLER_PIN_H +#define MICROPY_INCLUDED_STM34F4_COMMON_HAL_MICROCONTROLLER_PIN_H + +#include "py/mphal.h" + +#include "peripherals/stm32f4/pins.h" + +void reset_all_pins(void); +// reset_pin_number takes the pin number instead of the pointer so that objects don't +// need to store a full pointer. +void reset_pin_number(uint8_t pin_port, uint8_t pin); +void claim_pin(const mcu_pin_obj_t* pin); +bool pin_number_is_free(uint8_t pin_port, uint8_t pin_number); +void never_reset_pin_number(uint8_t pin_port, uint8_t pin_number); + +#endif // MICROPY_INCLUDED_STM34F4_COMMON_HAL_MICROCONTROLLER_PIN_H diff --git a/ports/stm32f4/common-hal/microcontroller/Processor.c b/ports/stm32f4/common-hal/microcontroller/Processor.c new file mode 100644 index 00000000000..c59c340c09c --- /dev/null +++ b/ports/stm32f4/common-hal/microcontroller/Processor.c @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert for Adafruit Industries + * + * 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 "common-hal/microcontroller/Processor.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + + +float common_hal_mcu_processor_get_temperature(void) { + return 0; +} + +uint32_t common_hal_mcu_processor_get_frequency(void) { + return 64000000ul; +} + +void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { + for (int i=0; i<2; i++) { + ((uint32_t*) raw_id)[i] = 0; + } +} diff --git a/ports/stm32f4/common-hal/microcontroller/Processor.h b/ports/stm32f4/common-hal/microcontroller/Processor.h new file mode 100644 index 00000000000..c3ca4efd599 --- /dev/null +++ b/ports/stm32f4/common-hal/microcontroller/Processor.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_STM32F4_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H +#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H + +#define COMMON_HAL_MCU_PROCESSOR_UID_LENGTH 8 + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + // Stores no state currently. +} mcu_processor_obj_t; + +#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H diff --git a/ports/stm32f4/common-hal/microcontroller/__init__.c b/ports/stm32f4/common-hal/microcontroller/__init__.c new file mode 100644 index 00000000000..871caa018bf --- /dev/null +++ b/ports/stm32f4/common-hal/microcontroller/__init__.c @@ -0,0 +1,191 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "py/mphal.h" +#include "py/obj.h" +#include "py/runtime.h" + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/microcontroller/Processor.h" + +#include "shared-bindings/nvm/ByteArray.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/Processor.h" + +#include "supervisor/filesystem.h" + +// This routine should work even when interrupts are disabled. Used by OneWire +// for precise timing. +void common_hal_mcu_delay_us(uint32_t delay) { + //NRFX_DELAY_US(delay); +} + +void common_hal_mcu_disable_interrupts() { +} + +void common_hal_mcu_enable_interrupts() { +} + +void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { + // TODO: see atmel-samd for functionality +} + +void common_hal_mcu_reset(void) { + // filesystem_flush(); + // NVIC_SystemReset(); +} + +// The singleton microcontroller.Processor object, bound to microcontroller.cpu +// It currently only has properties, and no state. +const mcu_processor_obj_t common_hal_mcu_processor_obj = { + .base = { + .type = &mcu_processor_type, + }, +}; + +#if CIRCUITPY_INTERNAL_NVM_SIZE > 0 +// The singleton nvm.ByteArray object. +const nvm_bytearray_obj_t common_hal_mcu_nvm_obj = { + .base = { + .type = &nvm_bytearray_type, + }, +}; +#endif + +STATIC const mp_rom_map_elem_t mcu_pin_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_PE02), MP_ROM_PTR(&pin_PE02) }, + { MP_ROM_QSTR(MP_QSTR_PE03), MP_ROM_PTR(&pin_PE03) }, + { MP_ROM_QSTR(MP_QSTR_PE04), MP_ROM_PTR(&pin_PE04) }, + { MP_ROM_QSTR(MP_QSTR_PE05), MP_ROM_PTR(&pin_PE05) }, + { MP_ROM_QSTR(MP_QSTR_PE06), MP_ROM_PTR(&pin_PE06) }, + { MP_ROM_QSTR(MP_QSTR_PC13), MP_ROM_PTR(&pin_PC13) }, + { MP_ROM_QSTR(MP_QSTR_PF00), MP_ROM_PTR(&pin_PF00) }, + { MP_ROM_QSTR(MP_QSTR_PF01), MP_ROM_PTR(&pin_PF01) }, + { MP_ROM_QSTR(MP_QSTR_PF02), MP_ROM_PTR(&pin_PF02) }, + { MP_ROM_QSTR(MP_QSTR_PF03), MP_ROM_PTR(&pin_PF03) }, + { MP_ROM_QSTR(MP_QSTR_PF04), MP_ROM_PTR(&pin_PF04) }, + { MP_ROM_QSTR(MP_QSTR_PF05), MP_ROM_PTR(&pin_PF05) }, + { MP_ROM_QSTR(MP_QSTR_PF06), MP_ROM_PTR(&pin_PF06) }, + { MP_ROM_QSTR(MP_QSTR_PF07), MP_ROM_PTR(&pin_PF07) }, + { MP_ROM_QSTR(MP_QSTR_PF08), MP_ROM_PTR(&pin_PF08) }, + { MP_ROM_QSTR(MP_QSTR_PF09), MP_ROM_PTR(&pin_PF09) }, + { MP_ROM_QSTR(MP_QSTR_PF10), MP_ROM_PTR(&pin_PF10) }, + { MP_ROM_QSTR(MP_QSTR_PC00), MP_ROM_PTR(&pin_PC00) }, + { MP_ROM_QSTR(MP_QSTR_PC01), MP_ROM_PTR(&pin_PC01) }, + { MP_ROM_QSTR(MP_QSTR_PC02), MP_ROM_PTR(&pin_PC02) }, + { MP_ROM_QSTR(MP_QSTR_PC03), MP_ROM_PTR(&pin_PC03) }, + { MP_ROM_QSTR(MP_QSTR_PA00), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_PA01), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_PA02), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_PA03), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_PA04), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_PA05), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_PA06), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_PA07), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_PC04), MP_ROM_PTR(&pin_PC04) }, + { MP_ROM_QSTR(MP_QSTR_PC05), MP_ROM_PTR(&pin_PC05) }, + { MP_ROM_QSTR(MP_QSTR_PB00), MP_ROM_PTR(&pin_PB00) }, + { MP_ROM_QSTR(MP_QSTR_PB01), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_PB02), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_PF11), MP_ROM_PTR(&pin_PF11) }, + { MP_ROM_QSTR(MP_QSTR_PF12), MP_ROM_PTR(&pin_PF12) }, + { MP_ROM_QSTR(MP_QSTR_PF13), MP_ROM_PTR(&pin_PF13) }, + { MP_ROM_QSTR(MP_QSTR_PF14), MP_ROM_PTR(&pin_PF14) }, + { MP_ROM_QSTR(MP_QSTR_PF15), MP_ROM_PTR(&pin_PF15) }, + { MP_ROM_QSTR(MP_QSTR_PG00), MP_ROM_PTR(&pin_PG00) }, + { MP_ROM_QSTR(MP_QSTR_PG01), MP_ROM_PTR(&pin_PG01) }, + { MP_ROM_QSTR(MP_QSTR_PE07), MP_ROM_PTR(&pin_PE07) }, + { MP_ROM_QSTR(MP_QSTR_PE08), MP_ROM_PTR(&pin_PE08) }, + { MP_ROM_QSTR(MP_QSTR_PE09), MP_ROM_PTR(&pin_PE09) }, + { MP_ROM_QSTR(MP_QSTR_PE10), MP_ROM_PTR(&pin_PE10) }, + { MP_ROM_QSTR(MP_QSTR_PE11), MP_ROM_PTR(&pin_PE11) }, + { MP_ROM_QSTR(MP_QSTR_PE12), MP_ROM_PTR(&pin_PE12) }, + { MP_ROM_QSTR(MP_QSTR_PE13), MP_ROM_PTR(&pin_PE13) }, + { MP_ROM_QSTR(MP_QSTR_PE14), MP_ROM_PTR(&pin_PE14) }, + { MP_ROM_QSTR(MP_QSTR_PE15), MP_ROM_PTR(&pin_PE15) }, + { MP_ROM_QSTR(MP_QSTR_PB10), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_PB11), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_PB12), MP_ROM_PTR(&pin_PB12) }, + { MP_ROM_QSTR(MP_QSTR_PB13), MP_ROM_PTR(&pin_PB13) }, + { MP_ROM_QSTR(MP_QSTR_PB14), MP_ROM_PTR(&pin_PB14) }, + { MP_ROM_QSTR(MP_QSTR_PB15), MP_ROM_PTR(&pin_PB15) }, + { MP_ROM_QSTR(MP_QSTR_PD08), MP_ROM_PTR(&pin_PD08) }, + { MP_ROM_QSTR(MP_QSTR_PD09), MP_ROM_PTR(&pin_PD09) }, + { MP_ROM_QSTR(MP_QSTR_PD10), MP_ROM_PTR(&pin_PD10) }, + { MP_ROM_QSTR(MP_QSTR_PD11), MP_ROM_PTR(&pin_PD11) }, + { MP_ROM_QSTR(MP_QSTR_PD12), MP_ROM_PTR(&pin_PD12) }, + { MP_ROM_QSTR(MP_QSTR_PD13), MP_ROM_PTR(&pin_PD13) }, + { MP_ROM_QSTR(MP_QSTR_PD14), MP_ROM_PTR(&pin_PD14) }, + { MP_ROM_QSTR(MP_QSTR_PD15), MP_ROM_PTR(&pin_PD15) }, + { MP_ROM_QSTR(MP_QSTR_PG02), MP_ROM_PTR(&pin_PG02) }, + { MP_ROM_QSTR(MP_QSTR_PG03), MP_ROM_PTR(&pin_PG03) }, + { MP_ROM_QSTR(MP_QSTR_PG04), MP_ROM_PTR(&pin_PG04) }, + { MP_ROM_QSTR(MP_QSTR_PG05), MP_ROM_PTR(&pin_PG05) }, + { MP_ROM_QSTR(MP_QSTR_PG06), MP_ROM_PTR(&pin_PG06) }, + { MP_ROM_QSTR(MP_QSTR_PG07), MP_ROM_PTR(&pin_PG07) }, + { MP_ROM_QSTR(MP_QSTR_PG08), MP_ROM_PTR(&pin_PG08) }, + { MP_ROM_QSTR(MP_QSTR_PC06), MP_ROM_PTR(&pin_PC06) }, + { MP_ROM_QSTR(MP_QSTR_PC07), MP_ROM_PTR(&pin_PC07) }, + { MP_ROM_QSTR(MP_QSTR_PC08), MP_ROM_PTR(&pin_PC08) }, + { MP_ROM_QSTR(MP_QSTR_PC09), MP_ROM_PTR(&pin_PC09) }, + { MP_ROM_QSTR(MP_QSTR_PA08), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_PA09), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_PA10), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_PA11), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_PA12), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_PA13), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_PA14), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_PA15), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_PC10), MP_ROM_PTR(&pin_PC10) }, + { MP_ROM_QSTR(MP_QSTR_PC11), MP_ROM_PTR(&pin_PC11) }, + { MP_ROM_QSTR(MP_QSTR_PC12), MP_ROM_PTR(&pin_PC12) }, + { MP_ROM_QSTR(MP_QSTR_PD00), MP_ROM_PTR(&pin_PD00) }, + { MP_ROM_QSTR(MP_QSTR_PD01), MP_ROM_PTR(&pin_PD01) }, + { MP_ROM_QSTR(MP_QSTR_PD02), MP_ROM_PTR(&pin_PD02) }, + { MP_ROM_QSTR(MP_QSTR_PD03), MP_ROM_PTR(&pin_PD03) }, + { MP_ROM_QSTR(MP_QSTR_PD04), MP_ROM_PTR(&pin_PD04) }, + { MP_ROM_QSTR(MP_QSTR_PD05), MP_ROM_PTR(&pin_PD05) }, + { MP_ROM_QSTR(MP_QSTR_PD06), MP_ROM_PTR(&pin_PD06) }, + { MP_ROM_QSTR(MP_QSTR_PD07), MP_ROM_PTR(&pin_PD07) }, + { MP_ROM_QSTR(MP_QSTR_PG09), MP_ROM_PTR(&pin_PG09) }, + { MP_ROM_QSTR(MP_QSTR_PG10), MP_ROM_PTR(&pin_PG10) }, + { MP_ROM_QSTR(MP_QSTR_PG11), MP_ROM_PTR(&pin_PG11) }, + { MP_ROM_QSTR(MP_QSTR_PG12), MP_ROM_PTR(&pin_PG12) }, + { MP_ROM_QSTR(MP_QSTR_PG13), MP_ROM_PTR(&pin_PG13) }, + { MP_ROM_QSTR(MP_QSTR_PG14), MP_ROM_PTR(&pin_PG14) }, + { MP_ROM_QSTR(MP_QSTR_PG15), MP_ROM_PTR(&pin_PG15) }, + { MP_ROM_QSTR(MP_QSTR_PB03), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_PB04), MP_ROM_PTR(&pin_PB04) }, + { MP_ROM_QSTR(MP_QSTR_PB05), MP_ROM_PTR(&pin_PB05) }, + { MP_ROM_QSTR(MP_QSTR_PB06), MP_ROM_PTR(&pin_PB06) }, + { MP_ROM_QSTR(MP_QSTR_PB07), MP_ROM_PTR(&pin_PB07) }, + { MP_ROM_QSTR(MP_QSTR_PB08), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_PB09), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_PE00), MP_ROM_PTR(&pin_PE00) }, + { MP_ROM_QSTR(MP_QSTR_PE01), MP_ROM_PTR(&pin_PE01) }, +}; +MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_globals_table); diff --git a/ports/stm32f4/common-hal/nvm/ByteArray.c b/ports/stm32f4/common-hal/nvm/ByteArray.c new file mode 100644 index 00000000000..ef70744ad6a --- /dev/null +++ b/ports/stm32f4/common-hal/nvm/ByteArray.c @@ -0,0 +1,81 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Nick Moore for Adafruit Industries + * + * 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. + */ + +//TODO: Implement for STM32. File required by Microcontroller Init + +#include "common-hal/nvm/ByteArray.h" + +#include +#include + +// defined in linker +extern uint32_t __fatfs_flash_start_addr[]; +extern uint32_t __fatfs_flash_length[]; + +#define NVM_START_ADDR ((uint32_t)__fatfs_flash_start_addr + \ + (uint32_t)__fatfs_flash_length - CIRCUITPY_INTERNAL_NVM_SIZE) + +uint32_t common_hal_nvm_bytearray_get_length(nvm_bytearray_obj_t *self) { + return CIRCUITPY_INTERNAL_NVM_SIZE; +} + +static void write_page(uint32_t page_addr, uint32_t offset, uint32_t len, uint8_t *bytes) { + // + // Write a whole page to flash, buffering it first and then erasing and rewriting + // it since we can only clear a whole page at a time. + + // if (offset == 0 && len == FLASH_PAGE_SIZE) { + // nrf_nvm_safe_flash_page_write(page_addr, bytes); + // } else { + // uint8_t buffer[FLASH_PAGE_SIZE]; + // memcpy(buffer, (uint8_t *)page_addr, FLASH_PAGE_SIZE); + // memcpy(buffer + offset, bytes, len); + // nrf_nvm_safe_flash_page_write(page_addr, buffer); + // } +} + +bool common_hal_nvm_bytearray_set_bytes(nvm_bytearray_obj_t *self, + // uint32_t start_index, uint8_t* values, uint32_t len) { + + // uint32_t address = NVM_START_ADDR + start_index; + // uint32_t offset = address % FLASH_PAGE_SIZE; + // uint32_t page_addr = address - offset; + + // while (len) { + // uint32_t write_len = MIN(len, FLASH_PAGE_SIZE - offset); + // write_page(page_addr, offset, write_len, values); + // len -= write_len; + // values += write_len; + // page_addr += FLASH_PAGE_SIZE; + // offset = 0; + // } + return true; +} + +void common_hal_nvm_bytearray_get_bytes(nvm_bytearray_obj_t *self, + uint32_t start_index, uint32_t len, uint8_t* values) { + memcpy(values, (uint8_t *)(NVM_START_ADDR + start_index), len); +} diff --git a/ports/stm32f4/common-hal/nvm/ByteArray.h b/ports/stm32f4/common-hal/nvm/ByteArray.h new file mode 100644 index 00000000000..ed00df9ffe9 --- /dev/null +++ b/ports/stm32f4/common-hal/nvm/ByteArray.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Nick Moore for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_STM32F4_COMMON_HAL_NVM_BYTEARRAY_H +#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_NVM_BYTEARRAY_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} nvm_bytearray_obj_t; + +#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_NVM_BYTEARRAY_H diff --git a/ports/stm32f4/common-hal/nvm/__init__.c b/ports/stm32f4/common-hal/nvm/__init__.c new file mode 100644 index 00000000000..3cdc9d3a4c0 --- /dev/null +++ b/ports/stm32f4/common-hal/nvm/__init__.c @@ -0,0 +1,27 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Nick Moore for Adafruit Industries + * + * 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. + */ + +// No nvm module functions. diff --git a/ports/stm32f4/common-hal/supervisor/Runtime.c b/ports/stm32f4/common-hal/supervisor/Runtime.c new file mode 100755 index 00000000000..feab6987d8b --- /dev/null +++ b/ports/stm32f4/common-hal/supervisor/Runtime.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Michael Schroeder + * + * 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 +#include "shared-bindings/supervisor/Runtime.h" +#include "supervisor/serial.h" + +bool common_hal_get_serial_connected(void) { + return (bool) serial_connected(); +} + +bool common_hal_get_serial_bytes_available(void) { + return (bool) serial_bytes_available(); +} + diff --git a/ports/stm32f4/common-hal/supervisor/Runtime.h b/ports/stm32f4/common-hal/supervisor/Runtime.h new file mode 100755 index 00000000000..9a798e05677 --- /dev/null +++ b/ports/stm32f4/common-hal/supervisor/Runtime.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Michael Schroeder + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_STM32F4_COMMON_HAL_SUPERVISOR_RUNTIME_H +#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_SUPERVISOR_RUNTIME_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + // Stores no state currently. +} super_runtime_obj_t; + +#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_SUPERVISOR_RUNTIME_H diff --git a/ports/stm32f4/common-hal/supervisor/__init__.c b/ports/stm32f4/common-hal/supervisor/__init__.c new file mode 100755 index 00000000000..ac88556b45d --- /dev/null +++ b/ports/stm32f4/common-hal/supervisor/__init__.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Michael Schroeder + * + * 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 "py/obj.h" + +#include "shared-bindings/supervisor/__init__.h" +#include "shared-bindings/supervisor/Runtime.h" + + +// The singleton supervisor.Runtime object, bound to supervisor.runtime +// It currently only has properties, and no state. +const super_runtime_obj_t common_hal_supervisor_runtime_obj = { + .base = { + .type = &supervisor_runtime_type, + }, +}; \ No newline at end of file diff --git a/ports/stm32f4/common-hal/time/__init__.c b/ports/stm32f4/common-hal/time/__init__.c new file mode 100644 index 00000000000..e3cb481ef42 --- /dev/null +++ b/ports/stm32f4/common-hal/time/__init__.c @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "py/mphal.h" + +#include "tick.h" + +uint64_t common_hal_time_monotonic(void) { + return ticks_ms; +} + +void common_hal_time_delay_ms(uint32_t delay) { + mp_hal_delay_ms(delay); +} diff --git a/ports/stm32f4/fatfs_port.c b/ports/stm32f4/fatfs_port.c new file mode 100644 index 00000000000..13ac21fb1bc --- /dev/null +++ b/ports/stm32f4/fatfs_port.c @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython 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 "py/runtime.h" +#include "lib/oofatfs/ff.h" + +DWORD get_fattime(void) { + // TODO: Implement this function. For now, fake it. + return ((2016 - 1980) << 25) | ((12) << 21) | ((4) << 16) | ((00) << 11) | ((18) << 5) | (23 / 2); +} diff --git a/ports/stm32f4/mpconfigport.h b/ports/stm32f4/mpconfigport.h new file mode 100644 index 00000000000..543a55942eb --- /dev/null +++ b/ports/stm32f4/mpconfigport.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2015 Glenn Ruben Bakke + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef STM32F4_MPCONFIGPORT_H__ +#define STM32F4_MPCONFIGPORT_H__ + +#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1) +#define MICROPY_PY_FUNCTION_ATTRS (1) +#define MICROPY_PY_IO (1) +#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) +#define MICROPY_PY_UJSON (1) + +// 24kiB stack +#define CIRCUITPY_DEFAULT_STACK_SIZE 0x6000 + +#include "py/circuitpy_mpconfig.h" + +#define MICROPY_PORT_ROOT_POINTERS \ + CIRCUITPY_COMMON_ROOT_POINTERS + +#endif // __INCLUDED_MPCONFIGPORT_H diff --git a/ports/stm32f4/mpconfigport.mk b/ports/stm32f4/mpconfigport.mk new file mode 100644 index 00000000000..814bb2b207d --- /dev/null +++ b/ports/stm32f4/mpconfigport.mk @@ -0,0 +1,22 @@ +# Define an equivalent for MICROPY_LONGINT_IMPL, to pass to $(MPY-TOOL) in py/mkrules.mk +# $(MPY-TOOL) needs to know what kind of longint to use (if any) to freeze long integers. +# This should correspond to the MICROPY_LONGINT_IMPL definition in mpconfigport.h. +MPY_TOOL_LONGINT_IMPL = -mlongint-impl=mpz + +# Internal math library is substantially smaller than toolchain one +INTERNAL_LIBM = 1 + +# Chip supplied serial number, in bytes +USB_SERIAL_NUMBER_LENGTH = 16 + +# Longints can be implemented as mpz, as longlong, or not +LONGINT_IMPL = MPZ + +#Reduced feature set for early port +CIRCUITPY_MINIMAL_BUILD = 1 + +ifeq ($(MCU_SUB_VARIANT), stm32f412zx) + CIRCUITPY_BOARD = 1 + CIRCUITPY_DIGITALIO = 1 + CIRCUITPY_MICROCONTROLLER = 1 +endif diff --git a/ports/stm32f4/mphalport.c b/ports/stm32f4/mphalport.c new file mode 100644 index 00000000000..ea864e7ceb5 --- /dev/null +++ b/ports/stm32f4/mphalport.c @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2015 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * 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 + +#include "py/mphal.h" +#include "py/mpstate.h" +#include "py/gc.h" + +/*------------------------------------------------------------------*/ +/* delay + *------------------------------------------------------------------*/ +void mp_hal_delay_ms(mp_uint_t delay) { + uint64_t start_tick = ticks_ms; + uint64_t duration = 0; + while (duration < delay) { + #ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP + #endif + // Check to see if we've been CTRL-Ced by autoreload or the user. + if(MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) || + MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { + break; + } + duration = (ticks_ms - start_tick); + // TODO(tannewt): Go to sleep for a little while while we wait. + } +} diff --git a/ports/stm32f4/mphalport.h b/ports/stm32f4/mphalport.h new file mode 100644 index 00000000000..131f2751dc6 --- /dev/null +++ b/ports/stm32f4/mphalport.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2015 Glenn Ruben Bakke + * + * 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. + */ + +#ifndef __STM32F4_HAL +#define __STM32F4_HAL + +#include +#include + +#include "lib/utils/interrupt_char.h" +#include "py/mpconfig.h" + +//extern nrfx_uarte_t serial_instance; + +extern volatile uint64_t ticks_ms; + +#define mp_hal_ticks_ms() ((mp_uint_t) ticks_ms) +//#define mp_hal_delay_us(us) NRFX_DELAY_US((uint32_t) (us)) + +bool mp_hal_stdin_any(void); + +#endif diff --git a/ports/stm32f4/peripherals/stm32f4/clocks.h b/ports/stm32f4/peripherals/stm32f4/clocks.h new file mode 100644 index 00000000000..c7ba846622c --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/clocks.h @@ -0,0 +1,27 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * + * 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. + */ + +void stm32f4_peripherals_clocks_init(void); diff --git a/ports/stm32f4/peripherals/stm32f4/gpio.h b/ports/stm32f4/peripherals/stm32f4/gpio.h new file mode 100644 index 00000000000..251cdb814e0 --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/gpio.h @@ -0,0 +1,27 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * + * 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. + */ + +void stm32f4_peripherals_gpio_init(void); diff --git a/ports/stm32f4/peripherals/stm32f4/pins.h b/ports/stm32f4/peripherals/stm32f4/pins.h new file mode 100644 index 00000000000..1b48cc1921a --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/pins.h @@ -0,0 +1,73 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * + * 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. + */ + +// DO NOT include this file directly. Use shared-bindings/microcontroller/Pin.h instead to ensure +// that all necessary includes are already included. + +#ifndef __MICROPY_INCLUDED_STM32F4_PERIPHERALS_PINS_H__ +#define __MICROPY_INCLUDED_STM32F4_PERIPHERALS_PINS_H__ + +#include +#include + +#include "stm32f4xx_hal.h" + +typedef struct { + mp_obj_base_t base; + //uint8_t number; //(3)port,(5)pin + uint8_t port_number; + GPIO_TypeDef * port; + uint8_t number; +} mcu_pin_obj_t; + +// extern GPIO_TypeDef *port_lookup_table[]; + +// static inline GPIO_TypeDef * get_GPIO_ptr(const mcu_pin_obj_t *p) +// { +// return port_lookup_table[0x7&( (p->number) >> 5)]; +// } + +extern const mp_obj_type_t mcu_pin_type; + +// Used in device-specific pins.c +#define PIN(p_port_num, p_port, p_number) \ +{ \ + { &mcu_pin_type }, \ + .port_number = (p_port_num), \ + .port = (p_port), \ + .number = (p_number), \ +} + +// Use illegal pin value to mark unassigned pins. +#define NO_PIN 0xff + +// Choose based on chip +#ifdef STM32F412Zx +#include "stm32f412zx/pins.h" +#endif + +#endif // __MICROPY_INCLUDED_STM32F4_PERIPHERALS_PINS_H__ diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/clocks.c b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/clocks.c new file mode 100644 index 00000000000..5b7a1e29871 --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/clocks.c @@ -0,0 +1,63 @@ + +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * + * 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 "stm32f4xx_hal.h" + +void stm32f4_peripherals_clocks_init(void) { + //System clock init + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + /** Configure the main internal regulator output voltage + */ + __HAL_RCC_PWR_CLK_ENABLE(); + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = 4; + RCC_OscInitStruct.PLL.PLLN = 192; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4; + RCC_OscInitStruct.PLL.PLLQ = 8; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3); + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S; + PeriphClkInitStruct.PLLI2S.PLLI2SN = 200; + PeriphClkInitStruct.PLLI2S.PLLI2SM = 5; + PeriphClkInitStruct.PLLI2S.PLLI2SR = 2; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); +} diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/gpio.c b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/gpio.c new file mode 100644 index 00000000000..a9ac97bae95 --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/gpio.c @@ -0,0 +1,137 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * + * 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. + */ + +/* GPIO PIN REFERENCE +#define DATA_Ready_Pin GPIO_PIN_2 +#define DATA_Ready_GPIO_Port GPIOE +#define CS_I2C_SPI_Pin GPIO_PIN_3 +#define CS_I2C_SPI_GPIO_Port GPIOE +#define INT1_Pin GPIO_PIN_4 +#define INT1_GPIO_Port GPIOE +#define INT2_Pin GPIO_PIN_5 +#define INT2_GPIO_Port GPIOE +#define PC14_OSC32_IN_Pin GPIO_PIN_14 +#define PC14_OSC32_IN_GPIO_Port GPIOC +#define PC15_OSC32_OUT_Pin GPIO_PIN_15 +#define PC15_OSC32_OUT_GPIO_Port GPIOC +#define PH0_OSC_IN_Pin GPIO_PIN_0 +#define PH0_OSC_IN_GPIO_Port GPIOH +#define PH1_OSC_OUT_Pin GPIO_PIN_1 +#define PH1_OSC_OUT_GPIO_Port GPIOH +#define OTG_FS_PowerSwitchOn_Pin GPIO_PIN_0 +#define OTG_FS_PowerSwitchOn_GPIO_Port GPIOC +#define PDM_OUT_Pin GPIO_PIN_3 +#define PDM_OUT_GPIO_Port GPIOC +#define I2S3_WS_Pin GPIO_PIN_4 +#define I2S3_WS_GPIO_Port GPIOA +#define SPI1_SCK_Pin GPIO_PIN_5 +#define SPI1_SCK_GPIO_Port GPIOA +#define SPI1_MISO_Pin GPIO_PIN_6 +#define SPI1_MISO_GPIO_Port GPIOA +#define SPI1_MOSI_Pin GPIO_PIN_7 +#define SPI1_MOSI_GPIO_Port GPIOA +#define CLK_IN_Pin GPIO_PIN_10 +#define CLK_IN_GPIO_Port GPIOB +#define LD4_Pin GPIO_PIN_12 +#define LD4_GPIO_Port GPIOD +#define LD3_Pin GPIO_PIN_13 +#define LD3_GPIO_Port GPIOD +#define LD5_Pin GPIO_PIN_14 +#define LD5_GPIO_Port GPIOD +#define LD6_Pin GPIO_PIN_15 +#define LD6_GPIO_Port GPIOD +#define I2S3_MCK_Pin GPIO_PIN_7 +#define I2S3_MCK_GPIO_Port GPIOC +#define VBUS_FS_Pin GPIO_PIN_9 +#define VBUS_FS_GPIO_Port GPIOA +#define OTG_FS_ID_Pin GPIO_PIN_10 +#define OTG_FS_ID_GPIO_Port GPIOA +#define OTG_FS_DM_Pin GPIO_PIN_11 +#define OTG_FS_DM_GPIO_Port GPIOA +#define OTG_FS_DP_Pin GPIO_PIN_12 +#define OTG_FS_DP_GPIO_Port GPIOA +#define SWDIO_Pin GPIO_PIN_13 +#define SWDIO_GPIO_Port GPIOA +#define SWCLK_Pin GPIO_PIN_14 +#define SWCLK_GPIO_Port GPIOA +#define I2S3_SCK_Pin GPIO_PIN_10 +#define I2S3_SCK_GPIO_Port GPIOC +#define I2S3_SD_Pin GPIO_PIN_12 +#define I2S3_SD_GPIO_Port GPIOC +#define Audio_RST_Pin GPIO_PIN_4 +#define Audio_RST_GPIO_Port GPIOD +#define OTG_FS_OverCurrent_Pin GPIO_PIN_5 +#define OTG_FS_OverCurrent_GPIO_Port GPIOD +#define SWO_Pin GPIO_PIN_3 +#define SWO_GPIO_Port GPIOB +#define Audio_SCL_Pin GPIO_PIN_6 +#define Audio_SCL_GPIO_Port GPIOB +#define Audio_SDA_Pin GPIO_PIN_9 +#define Audio_SDA_GPIO_Port GPIOB +#define MEMS_INT2_Pin GPIO_PIN_1 +#define MEMS_INT2_GPIO_Port GPIOE +*/ + +#define LD4_Pin GPIO_PIN_12 +#define LD4_GPIO_Port GPIOD +#define LD3_Pin GPIO_PIN_13 +#define LD3_GPIO_Port GPIOD +#define LD5_Pin GPIO_PIN_14 +#define LD5_GPIO_Port GPIOD +#define LD6_Pin GPIO_PIN_15 +#define LD6_GPIO_Port GPIOD + +#include "stm32f4xx_hal.h" + +void stm32f4_peripherals_gpio_init(void) { + //Enable all GPIO for now + GPIO_InitTypeDef GPIO_InitStruct = {0}; + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOD, LD4_Pin|LD3_Pin|LD5_Pin|LD6_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pins : LD4_Pin LD3_Pin LD5_Pin LD6_Pin */ + GPIO_InitStruct.Pin = LD4_Pin|LD3_Pin|LD5_Pin|LD6_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + //Status LED chain + HAL_GPIO_WritePin(GPIOD, LD4_Pin, GPIO_PIN_RESET); //LED 1 + HAL_GPIO_WritePin(GPIOD, LD3_Pin, GPIO_PIN_SET); //LED 2 + HAL_GPIO_WritePin(GPIOD, LD5_Pin, GPIO_PIN_SET); //LED 3 + HAL_GPIO_WritePin(GPIOD, LD6_Pin, GPIO_PIN_SET); //LED 4 +} + + diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.c b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.c new file mode 100644 index 00000000000..04502d714c6 --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.c @@ -0,0 +1,33 @@ + /* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * + * 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 "py/obj.h" +#include "py/mphal.h" +#include "stm32f4/pins.h" + + +//TODO +//const mcu_pin_obj_t pin_PE02 = PIN(4, GPIOE, 2); \ No newline at end of file diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.h b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.h new file mode 100644 index 00000000000..b060d9ed0bd --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/pins.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411RE_PINS_H +#define MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411RE_PINS_H + +//TODO +//Pins in datasheet order: DocID028087 Rev 7 page 50. LQFP100 only +//pg 50 +//extern const mcu_pin_obj_t pin_PE02; + + +#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411RE_PINS_H diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/clocks.c b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/clocks.c new file mode 100644 index 00000000000..0ccd9cb4892 --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/clocks.c @@ -0,0 +1,75 @@ + +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * + * 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 "stm32f4xx_hal.h" + +void stm32f4_peripherals_clocks_init(void) { + //System clock init + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + /** Configure the main internal regulator output voltage + */ + __HAL_RCC_PWR_CLK_ENABLE(); + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = 4; + RCC_OscInitStruct.PLL.PLLN = 72; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 3; + RCC_OscInitStruct.PLL.PLLR = 2; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1|RCC_PERIPHCLK_SDIO + |RCC_PERIPHCLK_CLK48; + PeriphClkInitStruct.PLLI2S.PLLI2SN = 50; + PeriphClkInitStruct.PLLI2S.PLLI2SM = 4; + PeriphClkInitStruct.PLLI2S.PLLI2SR = 2; + PeriphClkInitStruct.PLLI2S.PLLI2SQ = 2; + PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48CLKSOURCE_PLLQ; + PeriphClkInitStruct.SdioClockSelection = RCC_SDIOCLKSOURCE_CLK48; + PeriphClkInitStruct.PLLI2SSelection = RCC_PLLI2SCLKSOURCE_PLLSRC; + PeriphClkInitStruct.I2sApb1ClockSelection = RCC_I2SAPB1CLKSOURCE_PLLI2S; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI, RCC_MCODIV_1); +} diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/gpio.c b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/gpio.c new file mode 100644 index 00000000000..de783bafecc --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/gpio.c @@ -0,0 +1,218 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * + * 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. + */ + +/* GPIO PIN REFERENCE +#define LED3_Pin GPIO_PIN_2 +#define LED3_GPIO_Port GPIOE +#define LED4_Pin GPIO_PIN_3 +#define LED4_GPIO_Port GPIOE +#define DFSDM_DATIN3_Pin GPIO_PIN_4 +#define DFSDM_DATIN3_GPIO_Port GPIOE +#define A0_Pin GPIO_PIN_0 +#define A0_GPIO_Port GPIOF +#define LCD_BLCTRL_Pin GPIO_PIN_5 +#define LCD_BLCTRL_GPIO_Port GPIOF +#define QSPI_BK1_IO3_Pin GPIO_PIN_6 +#define QSPI_BK1_IO3_GPIO_Port GPIOF +#define QSPI_BK1_IO2_Pin GPIO_PIN_7 +#define QSPI_BK1_IO2_GPIO_Port GPIOF +#define QSPI_BK1_IO0_Pin GPIO_PIN_8 +#define QSPI_BK1_IO0_GPIO_Port GPIOF +#define QSPI_BK1_IO1_Pin GPIO_PIN_9 +#define QSPI_BK1_IO1_GPIO_Port GPIOF +#define STLK_MCO_Pin GPIO_PIN_0 +#define STLK_MCO_GPIO_Port GPIOH +#define DFSDM_CKOUT_Pin GPIO_PIN_2 +#define DFSDM_CKOUT_GPIO_Port GPIOC +#define JOY_SEL_Pin GPIO_PIN_0 +#define JOY_SEL_GPIO_Port GPIOA +#define STLINK_RX_Pin GPIO_PIN_2 +#define STLINK_RX_GPIO_Port GPIOA +#define STLINK_TX_Pin GPIO_PIN_3 +#define STLINK_TX_GPIO_Port GPIOA +#define CODEC_I2S3_WS_Pin GPIO_PIN_4 +#define CODEC_I2S3_WS_GPIO_Port GPIOA +#define DFSDM_DATIN0_Pin GPIO_PIN_1 +#define DFSDM_DATIN0_GPIO_Port GPIOB +#define QSPI_CLK_Pin GPIO_PIN_2 +#define QSPI_CLK_GPIO_Port GPIOB +#define EXT_RESET_Pin GPIO_PIN_11 +#define EXT_RESET_GPIO_Port GPIOF +#define CTP_RST_Pin GPIO_PIN_12 +#define CTP_RST_GPIO_Port GPIOF +#define JOY_RIGHT_Pin GPIO_PIN_14 +#define JOY_RIGHT_GPIO_Port GPIOF +#define JOY_LEFT_Pin GPIO_PIN_15 +#define JOY_LEFT_GPIO_Port GPIOF +#define JOY_UP_Pin GPIO_PIN_0 +#define JOY_UP_GPIO_Port GPIOG +#define JOY_DOWN_Pin GPIO_PIN_1 +#define JOY_DOWN_GPIO_Port GPIOG +#define D4_Pin GPIO_PIN_7 +#define D4_GPIO_Port GPIOE +#define D5_Pin GPIO_PIN_8 +#define D5_GPIO_Port GPIOE +#define D6_Pin GPIO_PIN_9 +#define D6_GPIO_Port GPIOE +#define D7_Pin GPIO_PIN_10 +#define D7_GPIO_Port GPIOE +#define D8_Pin GPIO_PIN_11 +#define D8_GPIO_Port GPIOE +#define D9_Pin GPIO_PIN_12 +#define D9_GPIO_Port GPIOE +#define D10_Pin GPIO_PIN_13 +#define D10_GPIO_Port GPIOE +#define D11_Pin GPIO_PIN_14 +#define D11_GPIO_Port GPIOE +#define D12_Pin GPIO_PIN_15 +#define D12_GPIO_Port GPIOE +#define I2C2_SCL_Pin GPIO_PIN_10 +#define I2C2_SCL_GPIO_Port GPIOB +#define M2_CKIN_Pin GPIO_PIN_11 +#define M2_CKIN_GPIO_Port GPIOB +#define CODEC_I2S3_SCK_Pin GPIO_PIN_12 +#define CODEC_I2S3_SCK_GPIO_Port GPIOB +#define D13_Pin GPIO_PIN_8 +#define D13_GPIO_Port GPIOD +#define D14_Pin GPIO_PIN_9 +#define D14_GPIO_Port GPIOD +#define D15_Pin GPIO_PIN_10 +#define D15_GPIO_Port GPIOD +#define LCD_RESET_Pin GPIO_PIN_11 +#define LCD_RESET_GPIO_Port GPIOD +#define D0_Pin GPIO_PIN_14 +#define D0_GPIO_Port GPIOD +#define D1_Pin GPIO_PIN_15 +#define D1_GPIO_Port GPIOD +#define CODEC_INT_Pin GPIO_PIN_2 +#define CODEC_INT_GPIO_Port GPIOG +#define LCD_TE_Pin GPIO_PIN_4 +#define LCD_TE_GPIO_Port GPIOG +#define CTP_INT_Pin GPIO_PIN_5 +#define CTP_INT_GPIO_Port GPIOG +#define QSPI_BK1_NCS_Pin GPIO_PIN_6 +#define QSPI_BK1_NCS_GPIO_Port GPIOG +#define USB_OTGFS_OVRCR_Pin GPIO_PIN_7 +#define USB_OTGFS_OVRCR_GPIO_Port GPIOG +#define USB_OTGFS_PPWR_EN_Pin GPIO_PIN_8 +#define USB_OTGFS_PPWR_EN_GPIO_Port GPIOG +#define CODEC_I2S3_MCK_Pin GPIO_PIN_7 +#define CODEC_I2S3_MCK_GPIO_Port GPIOC +#define uSD_D0_Pin GPIO_PIN_8 +#define uSD_D0_GPIO_Port GPIOC +#define uSD_D1_Pin GPIO_PIN_9 +#define uSD_D1_GPIO_Port GPIOC +#define M2_CKINA8_Pin GPIO_PIN_8 +#define M2_CKINA8_GPIO_Port GPIOA +#define USB_OTGFS_VBUS_Pin GPIO_PIN_9 +#define USB_OTGFS_VBUS_GPIO_Port GPIOA +#define USB_OTGFS_ID_Pin GPIO_PIN_10 +#define USB_OTGFS_ID_GPIO_Port GPIOA +#define USB_OTGFS_DM_Pin GPIO_PIN_11 +#define USB_OTGFS_DM_GPIO_Port GPIOA +#define USB_OTGFS_DP_Pin GPIO_PIN_12 +#define USB_OTGFS_DP_GPIO_Port GPIOA +#define SWDIO_Pin GPIO_PIN_13 +#define SWDIO_GPIO_Port GPIOA +#define SWCLK_Pin GPIO_PIN_14 +#define SWCLK_GPIO_Port GPIOA +#define uSD_D2_Pin GPIO_PIN_10 +#define uSD_D2_GPIO_Port GPIOC +#define uSD_D3_Pin GPIO_PIN_11 +#define uSD_D3_GPIO_Port GPIOC +#define uSD_CLK_Pin GPIO_PIN_12 +#define uSD_CLK_GPIO_Port GPIOC +#define D2_Pin GPIO_PIN_0 +#define D2_GPIO_Port GPIOD +#define D3_Pin GPIO_PIN_1 +#define D3_GPIO_Port GPIOD +#define uSD_CMD_Pin GPIO_PIN_2 +#define uSD_CMD_GPIO_Port GPIOD +#define uSD_DETECT_Pin GPIO_PIN_3 +#define uSD_DETECT_GPIO_Port GPIOD +#define FMC_NOE_Pin GPIO_PIN_4 +#define FMC_NOE_GPIO_Port GPIOD +#define FMC_NWE_Pin GPIO_PIN_5 +#define FMC_NWE_GPIO_Port GPIOD +#define FMC_NE1_Pin GPIO_PIN_7 +#define FMC_NE1_GPIO_Port GPIOD +#define SWO_Pin GPIO_PIN_3 +#define SWO_GPIO_Port GPIOB +#define CODEC_I2S3ext_SD_Pin GPIO_PIN_4 +#define CODEC_I2S3ext_SD_GPIO_Port GPIOB +#define CODEC_I2S3_SD_Pin GPIO_PIN_5 +#define CODEC_I2S3_SD_GPIO_Port GPIOB +#define I2C1_SCL_Pin GPIO_PIN_6 +#define I2C1_SCL_GPIO_Port GPIOB +#define I2C1_SDA_Pin GPIO_PIN_7 +#define I2C1_SDA_GPIO_Port GPIOB +#define I2C2_SDA_Pin GPIO_PIN_9 +#define I2C2_SDA_GPIO_Port GPIOB +#define LED1_Pin GPIO_PIN_0 +#define LED1_GPIO_Port GPIOE +#define LED2_Pin GPIO_PIN_1 +#define LED2_GPIO_Port GPIOE +*/ + +#include "stm32f4xx_hal.h" + +void stm32f4_peripherals_gpio_init(void) { + //Enable all GPIO for now + GPIO_InitTypeDef GPIO_InitStruct = {0}; + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOF_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_RESET); + //HAL_GPIO_WritePin(USB_OTGFS_PPWR_EN_GPIO_Port, USB_OTGFS_PPWR_EN_Pin, GPIO_PIN_SET); + + //Configure LED pins + GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); + + //Status LED chain + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0, GPIO_PIN_RESET); //LED 1 + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_SET); //LED 2 + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_SET); //LED 3 + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET); //LED 4 + + //TBD, USB power + // GPIO_InitStruct.Pin = USB_OTGFS_PPWR_EN_Pin; + // GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; + // GPIO_InitStruct.Pull = GPIO_NOPULL; + // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + // HAL_GPIO_Init(USB_OTGFS_PPWR_EN_GPIO_Port, &GPIO_InitStruct); +} + + diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.c b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.c new file mode 100644 index 00000000000..5a4703bea21 --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.c @@ -0,0 +1,159 @@ + /* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * + * 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 "py/obj.h" +#include "py/mphal.h" +#include "stm32f4/pins.h" + +const mcu_pin_obj_t pin_PE02 = PIN(4, GPIOE, 2); +const mcu_pin_obj_t pin_PE03 = PIN(4, GPIOE, 3); +const mcu_pin_obj_t pin_PE04 = PIN(4, GPIOE, 4); +const mcu_pin_obj_t pin_PE05 = PIN(4, GPIOE, 5); +const mcu_pin_obj_t pin_PE06 = PIN(4, GPIOE, 6); + +const mcu_pin_obj_t pin_PC13 = PIN(2, GPIOC, 13); + +const mcu_pin_obj_t pin_PF00 = PIN(5, GPIOF, 0); // 144 only +const mcu_pin_obj_t pin_PF01 = PIN(5, GPIOF, 1); // 144 only +const mcu_pin_obj_t pin_PF02 = PIN(5, GPIOF, 2); // 144 only +const mcu_pin_obj_t pin_PF03 = PIN(5, GPIOF, 3); // 144 only +const mcu_pin_obj_t pin_PF04 = PIN(5, GPIOF, 4); // 144 only +const mcu_pin_obj_t pin_PF05 = PIN(5, GPIOF, 5); // 144 only +const mcu_pin_obj_t pin_PF06 = PIN(5, GPIOF, 6); // 144 only +const mcu_pin_obj_t pin_PF07 = PIN(5, GPIOF, 7); // 144 only +const mcu_pin_obj_t pin_PF08 = PIN(5, GPIOF, 8); // 144 only +const mcu_pin_obj_t pin_PF09 = PIN(5, GPIOF, 9); // 144 only +const mcu_pin_obj_t pin_PF10 = PIN(5, GPIOF, 10); // 144 only + +const mcu_pin_obj_t pin_PC00 = PIN(2, GPIOC, 0); +const mcu_pin_obj_t pin_PC01 = PIN(2, GPIOC, 1); +const mcu_pin_obj_t pin_PC02 = PIN(2, GPIOC, 2); +const mcu_pin_obj_t pin_PC03 = PIN(2, GPIOC, 3); + +const mcu_pin_obj_t pin_PA00 = PIN(0, GPIOA, 0); +const mcu_pin_obj_t pin_PA01 = PIN(0, GPIOA, 1); +const mcu_pin_obj_t pin_PA02 = PIN(0, GPIOA, 2); +const mcu_pin_obj_t pin_PA03 = PIN(0, GPIOA, 3); +const mcu_pin_obj_t pin_PA04 = PIN(0, GPIOA, 4); +const mcu_pin_obj_t pin_PA05 = PIN(0, GPIOA, 5); +const mcu_pin_obj_t pin_PA06 = PIN(0, GPIOA, 6); +const mcu_pin_obj_t pin_PA07 = PIN(0, GPIOA, 7); + +const mcu_pin_obj_t pin_PC04 = PIN(2, GPIOC, 4); +const mcu_pin_obj_t pin_PC05 = PIN(2, GPIOC, 5); + +const mcu_pin_obj_t pin_PB00 = PIN(1, GPIOB, 0); +const mcu_pin_obj_t pin_PB01 = PIN(1, GPIOB, 1); +const mcu_pin_obj_t pin_PB02 = PIN(1, GPIOB, 2); + +const mcu_pin_obj_t pin_PF11 = PIN(5, GPIOF, 11); // 144 only +const mcu_pin_obj_t pin_PF12 = PIN(5, GPIOF, 12); // 144 only +const mcu_pin_obj_t pin_PF13 = PIN(5, GPIOF, 13); // 144 only +const mcu_pin_obj_t pin_PF14 = PIN(5, GPIOF, 14); // 144 only +const mcu_pin_obj_t pin_PF15 = PIN(5, GPIOF, 15); // 144 only + +const mcu_pin_obj_t pin_PG00 = PIN(6, GPIOG, 0); // 144 only +const mcu_pin_obj_t pin_PG01 = PIN(6, GPIOG, 1); // 144 only + +const mcu_pin_obj_t pin_PE07 = PIN(4, GPIOE, 7); +const mcu_pin_obj_t pin_PE08 = PIN(4, GPIOE, 8); +const mcu_pin_obj_t pin_PE09 = PIN(4, GPIOE, 9); +const mcu_pin_obj_t pin_PE10 = PIN(4, GPIOE, 10); +const mcu_pin_obj_t pin_PE11 = PIN(4, GPIOE, 11); +const mcu_pin_obj_t pin_PE12 = PIN(4, GPIOE, 12); +const mcu_pin_obj_t pin_PE13 = PIN(4, GPIOE, 13); +const mcu_pin_obj_t pin_PE14 = PIN(4, GPIOE, 14); +const mcu_pin_obj_t pin_PE15 = PIN(4, GPIOE, 15); + +const mcu_pin_obj_t pin_PB10 = PIN(1, GPIOB, 10); +const mcu_pin_obj_t pin_PB12 = PIN(1, GPIOB, 12); +const mcu_pin_obj_t pin_PB11 = PIN(1, GPIOB, 11); // 144 only +const mcu_pin_obj_t pin_PB13 = PIN(1, GPIOB, 13); +const mcu_pin_obj_t pin_PB14 = PIN(1, GPIOB, 14); +const mcu_pin_obj_t pin_PB15 = PIN(1, GPIOB, 15); + +const mcu_pin_obj_t pin_PD08 = PIN(3, GPIOD, 8); +const mcu_pin_obj_t pin_PD09 = PIN(3, GPIOD, 9); +const mcu_pin_obj_t pin_PD10 = PIN(3, GPIOD, 10); +const mcu_pin_obj_t pin_PD11 = PIN(3, GPIOD, 11); +const mcu_pin_obj_t pin_PD12 = PIN(3, GPIOD, 12); +const mcu_pin_obj_t pin_PD13 = PIN(3, GPIOD, 13); +const mcu_pin_obj_t pin_PD14 = PIN(3, GPIOD, 14); +const mcu_pin_obj_t pin_PD15 = PIN(3, GPIOD, 15); + +const mcu_pin_obj_t pin_PG02 = PIN(6, GPIOG, 2); // 144 only +const mcu_pin_obj_t pin_PG03 = PIN(6, GPIOG, 3); // 144 only +const mcu_pin_obj_t pin_PG04 = PIN(6, GPIOG, 4); // 144 only +const mcu_pin_obj_t pin_PG05 = PIN(6, GPIOG, 5); // 144 only +const mcu_pin_obj_t pin_PG06 = PIN(6, GPIOG, 6); // 144 only +const mcu_pin_obj_t pin_PG07 = PIN(6, GPIOG, 7); // 144 only +const mcu_pin_obj_t pin_PG08 = PIN(6, GPIOG, 8); // 144 only + +const mcu_pin_obj_t pin_PC06 = PIN(2, GPIOC, 6); +const mcu_pin_obj_t pin_PC07 = PIN(2, GPIOC, 7); +const mcu_pin_obj_t pin_PC08 = PIN(2, GPIOC, 8); +const mcu_pin_obj_t pin_PC09 = PIN(2, GPIOC, 9); + +const mcu_pin_obj_t pin_PA08 = PIN(0, GPIOA, 8); +const mcu_pin_obj_t pin_PA09 = PIN(0, GPIOA, 9); +const mcu_pin_obj_t pin_PA10 = PIN(0, GPIOA, 10); +const mcu_pin_obj_t pin_PA11 = PIN(0, GPIOA, 11); +const mcu_pin_obj_t pin_PA12 = PIN(0, GPIOA, 12); +const mcu_pin_obj_t pin_PA13 = PIN(0, GPIOA, 13); +const mcu_pin_obj_t pin_PA14 = PIN(0, GPIOA, 14); +const mcu_pin_obj_t pin_PA15 = PIN(0, GPIOA, 15); + +const mcu_pin_obj_t pin_PC10 = PIN(2, GPIOC, 10); +const mcu_pin_obj_t pin_PC11 = PIN(2, GPIOC, 11); +const mcu_pin_obj_t pin_PC12 = PIN(2, GPIOC, 12); + +const mcu_pin_obj_t pin_PD00 = PIN(3, GPIOD, 0); +const mcu_pin_obj_t pin_PD01 = PIN(3, GPIOD, 1); +const mcu_pin_obj_t pin_PD02 = PIN(3, GPIOD, 2); +const mcu_pin_obj_t pin_PD03 = PIN(3, GPIOD, 3); +const mcu_pin_obj_t pin_PD04 = PIN(3, GPIOD, 4); +const mcu_pin_obj_t pin_PD05 = PIN(3, GPIOD, 5); +const mcu_pin_obj_t pin_PD06 = PIN(3, GPIOD, 6); +const mcu_pin_obj_t pin_PD07 = PIN(3, GPIOD, 7); + +const mcu_pin_obj_t pin_PG09 = PIN(6, GPIOG, 9); // 144 only +const mcu_pin_obj_t pin_PG10 = PIN(6, GPIOG, 10); // 144 only +const mcu_pin_obj_t pin_PG11 = PIN(6, GPIOG, 11); // 144 only +const mcu_pin_obj_t pin_PG12 = PIN(6, GPIOG, 12); // 144 only +const mcu_pin_obj_t pin_PG13 = PIN(6, GPIOG, 13); // 144 only +const mcu_pin_obj_t pin_PG14 = PIN(6, GPIOG, 14); // 144 only +const mcu_pin_obj_t pin_PG15 = PIN(6, GPIOG, 15); // 144 only + +const mcu_pin_obj_t pin_PB03 = PIN(1, GPIOB, 3); +const mcu_pin_obj_t pin_PB04 = PIN(1, GPIOB, 4); +const mcu_pin_obj_t pin_PB05 = PIN(1, GPIOB, 5); +const mcu_pin_obj_t pin_PB06 = PIN(1, GPIOB, 6); +const mcu_pin_obj_t pin_PB07 = PIN(1, GPIOB, 7); +const mcu_pin_obj_t pin_PB08 = PIN(1, GPIOB, 8); +const mcu_pin_obj_t pin_PB09 = PIN(1, GPIOB, 9); + +const mcu_pin_obj_t pin_PE00 = PIN(4, GPIOE, 0); +const mcu_pin_obj_t pin_PE01 = PIN(4, GPIOE, 1); \ No newline at end of file diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.h b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.h new file mode 100644 index 00000000000..a74bf7c5d1f --- /dev/null +++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/pins.h @@ -0,0 +1,156 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F412ZG_PINS_H +#define MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F412ZG_PINS_H + +//Pins in datasheet order: DocID028087 Rev 7 page 50. LQFP100 only +//pg 50 +extern const mcu_pin_obj_t pin_PE02; +extern const mcu_pin_obj_t pin_PE03; +extern const mcu_pin_obj_t pin_PE04; +extern const mcu_pin_obj_t pin_PE05; +extern const mcu_pin_obj_t pin_PE06; +extern const mcu_pin_obj_t pin_PC13; +//pg 51 +extern const mcu_pin_obj_t pin_PF00; // 144 only +extern const mcu_pin_obj_t pin_PF01; // 144 only +extern const mcu_pin_obj_t pin_PF02; // 144 only +extern const mcu_pin_obj_t pin_PF03; // 144 only +extern const mcu_pin_obj_t pin_PF04; // 144 only +extern const mcu_pin_obj_t pin_PF05; // 144 only +extern const mcu_pin_obj_t pin_PF06; // 144 only +extern const mcu_pin_obj_t pin_PF07; // 144 only +extern const mcu_pin_obj_t pin_PF08; // 144 only +extern const mcu_pin_obj_t pin_PF09; // 144 only +extern const mcu_pin_obj_t pin_PF10; // 144 only +//pg 52 +extern const mcu_pin_obj_t pin_PC00; +extern const mcu_pin_obj_t pin_PC01; +extern const mcu_pin_obj_t pin_PC02; +extern const mcu_pin_obj_t pin_PC03; +extern const mcu_pin_obj_t pin_PA00; +extern const mcu_pin_obj_t pin_PA01; +extern const mcu_pin_obj_t pin_PA02; +//pg 53 +extern const mcu_pin_obj_t pin_PA03; +extern const mcu_pin_obj_t pin_PA04; +extern const mcu_pin_obj_t pin_PA05; +extern const mcu_pin_obj_t pin_PA06; +extern const mcu_pin_obj_t pin_PA07; +extern const mcu_pin_obj_t pin_PC04; +//pg 54 +extern const mcu_pin_obj_t pin_PC05; +extern const mcu_pin_obj_t pin_PB00; +extern const mcu_pin_obj_t pin_PB01; +extern const mcu_pin_obj_t pin_PB02; +extern const mcu_pin_obj_t pin_PF11; // 144 only +extern const mcu_pin_obj_t pin_PF12; // 144 only +extern const mcu_pin_obj_t pin_PF13; // 144 only +extern const mcu_pin_obj_t pin_PF14; // 144 only +extern const mcu_pin_obj_t pin_PF15; // 144 only +extern const mcu_pin_obj_t pin_PG00; // 144 only +extern const mcu_pin_obj_t pin_PG01; // 144 only +//pg 55 +extern const mcu_pin_obj_t pin_PE07; +extern const mcu_pin_obj_t pin_PE08; +extern const mcu_pin_obj_t pin_PE09; +extern const mcu_pin_obj_t pin_PE10; +extern const mcu_pin_obj_t pin_PE11; +extern const mcu_pin_obj_t pin_PE12; +extern const mcu_pin_obj_t pin_PE13; +extern const mcu_pin_obj_t pin_PE14; +//pg 56 +extern const mcu_pin_obj_t pin_PE15; +extern const mcu_pin_obj_t pin_PB10; +extern const mcu_pin_obj_t pin_PB11; // 144 only +extern const mcu_pin_obj_t pin_PB12; +extern const mcu_pin_obj_t pin_PB13; +//pg 57 +extern const mcu_pin_obj_t pin_PB14; +extern const mcu_pin_obj_t pin_PB15; +extern const mcu_pin_obj_t pin_PD08; +extern const mcu_pin_obj_t pin_PD09; +extern const mcu_pin_obj_t pin_PD10; +extern const mcu_pin_obj_t pin_PD11; +extern const mcu_pin_obj_t pin_PD12; +//pg 58 +extern const mcu_pin_obj_t pin_PD13; +extern const mcu_pin_obj_t pin_PD14; +extern const mcu_pin_obj_t pin_PD15; +extern const mcu_pin_obj_t pin_PG02; // 144 only +extern const mcu_pin_obj_t pin_PG03; // 144 only +extern const mcu_pin_obj_t pin_PG04; // 144 only +extern const mcu_pin_obj_t pin_PG05; // 144 only +extern const mcu_pin_obj_t pin_PG06; // 144 only +extern const mcu_pin_obj_t pin_PG07; // 144 only +extern const mcu_pin_obj_t pin_PG08; // 144 only +//pg 59 +extern const mcu_pin_obj_t pin_PC06; +extern const mcu_pin_obj_t pin_PC07; +extern const mcu_pin_obj_t pin_PC08; +extern const mcu_pin_obj_t pin_PC09; +extern const mcu_pin_obj_t pin_PA08; +extern const mcu_pin_obj_t pin_PA09; +extern const mcu_pin_obj_t pin_PA10; +//pg 60 +extern const mcu_pin_obj_t pin_PA11; +extern const mcu_pin_obj_t pin_PA12; +extern const mcu_pin_obj_t pin_PA13; +extern const mcu_pin_obj_t pin_PA14; +extern const mcu_pin_obj_t pin_PA15; +extern const mcu_pin_obj_t pin_PC10; +extern const mcu_pin_obj_t pin_PC11; +//pg 61 +extern const mcu_pin_obj_t pin_PC12; +extern const mcu_pin_obj_t pin_PD00; +extern const mcu_pin_obj_t pin_PD01; +extern const mcu_pin_obj_t pin_PD02; +extern const mcu_pin_obj_t pin_PD03; +extern const mcu_pin_obj_t pin_PD04; +extern const mcu_pin_obj_t pin_PD05; +extern const mcu_pin_obj_t pin_PD06; +extern const mcu_pin_obj_t pin_PD07; +//pg 62 +extern const mcu_pin_obj_t pin_PG09; // 144 only +extern const mcu_pin_obj_t pin_PG10; // 144 only +extern const mcu_pin_obj_t pin_PG11; // 144 only +extern const mcu_pin_obj_t pin_PG12; // 144 only +extern const mcu_pin_obj_t pin_PG13; // 144 only +extern const mcu_pin_obj_t pin_PG14; // 144 only +extern const mcu_pin_obj_t pin_PG15; // 144 only +extern const mcu_pin_obj_t pin_PB03; +extern const mcu_pin_obj_t pin_PB04; +//pg 63 +extern const mcu_pin_obj_t pin_PB05; +extern const mcu_pin_obj_t pin_PB06; +extern const mcu_pin_obj_t pin_PB07; +extern const mcu_pin_obj_t pin_PB08; +extern const mcu_pin_obj_t pin_PB09; +extern const mcu_pin_obj_t pin_PE00; +extern const mcu_pin_obj_t pin_PE01; + +#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F412ZG_PINS_H diff --git a/ports/stm32f4/qstrdefsport.h b/ports/stm32f4/qstrdefsport.h new file mode 100644 index 00000000000..3ba897069bf --- /dev/null +++ b/ports/stm32f4/qstrdefsport.h @@ -0,0 +1 @@ +// qstrs specific to this port diff --git a/ports/stm32f4/stm32f4 b/ports/stm32f4/stm32f4 new file mode 160000 index 00000000000..12411ade32a --- /dev/null +++ b/ports/stm32f4/stm32f4 @@ -0,0 +1 @@ +Subproject commit 12411ade32aeec4e49c969d8d095463b0c2fb1f0 diff --git a/ports/stm32f4/supervisor/cpu.s b/ports/stm32f4/supervisor/cpu.s new file mode 100755 index 00000000000..9e6807a5e2e --- /dev/null +++ b/ports/stm32f4/supervisor/cpu.s @@ -0,0 +1,27 @@ +.syntax unified +.cpu cortex-m4 +.thumb +.text +.align 2 + +@ uint cpu_get_regs_and_sp(r0=uint regs[10]) +.global cpu_get_regs_and_sp +.thumb +.thumb_func +.type cpu_get_regs_and_sp, %function +cpu_get_regs_and_sp: +@ store registers into given array +str r4, [r0], #4 +str r5, [r0], #4 +str r6, [r0], #4 +str r7, [r0], #4 +str r8, [r0], #4 +str r9, [r0], #4 +str r10, [r0], #4 +str r11, [r0], #4 +str r12, [r0], #4 +str r13, [r0], #4 + +@ return the sp +mov r0, sp +bx lr diff --git a/ports/stm32f4/supervisor/internal_flash.c b/ports/stm32f4/supervisor/internal_flash.c new file mode 100644 index 00000000000..fa776ae1de2 --- /dev/null +++ b/ports/stm32f4/supervisor/internal_flash.c @@ -0,0 +1,73 @@ +/* + * This file is part of the MicroPython 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 "supervisor/flash.h" + +#include +#include + +#include "extmod/vfs.h" +#include "extmod/vfs_fat.h" +#include "py/mphal.h" +#include "py/obj.h" +#include "py/runtime.h" +#include "lib/oofatfs/ff.h" + + +/*------------------------------------------------------------------*/ +/* Internal Flash API + *------------------------------------------------------------------*/ +static inline uint32_t lba2addr(uint32_t block) { +} + +void supervisor_flash_init(void) { +} + +uint32_t supervisor_flash_get_block_size(void) { + return FILESYSTEM_BLOCK_SIZE; +} + +uint32_t supervisor_flash_get_block_count(void) { + return false; +} + +void supervisor_flash_flush(void) { + +} + +mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { + + return 0; // success +} + +mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks) { + + + return 0; // success +} + +void supervisor_flash_release_cache(void) { +} + diff --git a/ports/stm32f4/supervisor/internal_flash.h b/ports/stm32f4/supervisor/internal_flash.h new file mode 100644 index 00000000000..8c015a3e463 --- /dev/null +++ b/ports/stm32f4/supervisor/internal_flash.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython 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. + */ +#ifndef MICROPY_INCLUDED_STM32F4_INTERNAL_FLASH_H +#define MICROPY_INCLUDED_STM32F4_INTERNAL_FLASH_H + +#include +#include + +#include "py/mpconfig.h" + +#define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms +#define INTERNAL_FLASH_IDLE_TICK(tick) (((tick) & INTERNAL_FLASH_SYSTICK_MASK) == 2) + +#endif // MICROPY_INCLUDED_STM32F4_INTERNAL_FLASH_H diff --git a/ports/stm32f4/supervisor/internal_flash_root_pointers.h b/ports/stm32f4/supervisor/internal_flash_root_pointers.h new file mode 100644 index 00000000000..7a8681bd95c --- /dev/null +++ b/ports/stm32f4/supervisor/internal_flash_root_pointers.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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. + */ +#ifndef MICROPY_INCLUDED_STM32F4_INTERNAL_FLASH_ROOT_POINTERS_H +#define MICROPY_INCLUDED_STM32F4_INTERNAL_FLASH_ROOT_POINTERS_H + +#define FLASH_ROOT_POINTERS + +#endif // MICROPY_INCLUDED_STM32F4_INTERNAL_FLASH_ROOT_POINTERS_H diff --git a/ports/stm32f4/supervisor/port.c b/ports/stm32f4/supervisor/port.c new file mode 100644 index 00000000000..af4d1b8d84b --- /dev/null +++ b/ports/stm32f4/supervisor/port.c @@ -0,0 +1,80 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * + * 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 +#include "supervisor/port.h" +#include "boards/board.h" +#include "tick.h" + +#include "stm32f4/clocks.h" +#include "stm32f4/gpio.h" + +#include "stm32f4xx_hal.h" + +//#include "shared-bindings/rtc/__init__.h" + +static void power_warning_handler(void) { + reset_into_safe_mode(BROWNOUT); +} + +safe_mode_t port_init(void) { + HAL_Init(); + + stm32f4_peripherals_clocks_init(); + stm32f4_peripherals_gpio_init(); + + tick_init(); + board_init(); + + return NO_SAFE_MODE; +} + +void reset_port(void) { + +} + +void reset_to_bootloader(void) { + +} + +void reset_cpu(void) { + +} + +extern uint32_t _ebss; +// Place the word to save just after our BSS section that gets blanked. +void port_set_saved_word(uint32_t value) { + _ebss = value; +} + +uint32_t port_get_saved_word(void) { + return _ebss; +} + +// void HardFault_Handler(void) { + +// } diff --git a/ports/stm32f4/supervisor/qspi_flash.c b/ports/stm32f4/supervisor/qspi_flash.c new file mode 100644 index 00000000000..f3915273b38 --- /dev/null +++ b/ports/stm32f4/supervisor/qspi_flash.c @@ -0,0 +1,162 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/spi_flash_api.h" + +#include +#include + +#include "py/mpconfig.h" // for EXTERNAL_FLASH_QSPI_DUAL +//#include "nrfx_qspi.h" + +//#include "shared-bindings/microcontroller/__init__.h" + +#include "supervisor/shared/external_flash/common_commands.h" +#include "supervisor/shared/external_flash/qspi_flash.h" + +bool spi_flash_command(uint8_t command) { + // nrf_qspi_cinstr_conf_t cinstr_cfg = { + // .opcode = command, + // .length = 1, + // .io2_level = true, + // .io3_level = true, + // .wipwait = false, + // .wren = false + // }; + return false; //nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL) == NRFX_SUCCESS; +} + +bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length) { + // nrf_qspi_cinstr_conf_t cinstr_cfg = { + // .opcode = command, + // .length = length + 1, + // .io2_level = true, + // .io3_level = true, + // .wipwait = false, + // .wren = false + // }; + // return nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, response) == NRFX_SUCCESS; + return false; + +} + +bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) { + // nrf_qspi_cinstr_conf_t cinstr_cfg = { + // .opcode = command, + // .length = length + 1, + // .io2_level = true, + // .io3_level = true, + // .wipwait = false, + // .wren = false // We do this manually. + // }; + // return nrfx_qspi_cinstr_xfer(&cinstr_cfg, data, NULL) == NRFX_SUCCESS; + return false; +} + +bool spi_flash_sector_command(uint8_t command, uint32_t address) { + // if (command != CMD_SECTOR_ERASE) { + // return false; + // } + // return nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, address) == NRFX_SUCCESS; + return false; +} + +bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) { + // return nrfx_qspi_write(data, length, address) == NRFX_SUCCESS; + return false; +} + +bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t length) { + // return nrfx_qspi_read(data, length, address) == NRFX_SUCCESS; + return false; +} + +void spi_flash_init(void) { + // Init QSPI flash +// nrfx_qspi_config_t qspi_cfg = { +// .xip_offset = 0, +// .pins = { +// .sck_pin = MICROPY_QSPI_SCK, +// .csn_pin = MICROPY_QSPI_CS, +// .io0_pin = MICROPY_QSPI_DATA0, +// .io1_pin = NRF_QSPI_PIN_NOT_CONNECTED, +// .io2_pin = NRF_QSPI_PIN_NOT_CONNECTED, +// .io3_pin = NRF_QSPI_PIN_NOT_CONNECTED, + +// }, +// .prot_if = { +// .readoc = NRF_QSPI_READOC_FASTREAD, +// .writeoc = NRF_QSPI_WRITEOC_PP, +// .addrmode = NRF_QSPI_ADDRMODE_24BIT, +// .dpmconfig = false +// }, +// .phy_if = { +// .sck_freq = NRF_QSPI_FREQ_32MDIV16, // Start at a slow 2MHz and speed up once we know what we're talking to. +// .sck_delay = 10, // min time CS must stay high before going low again. in unit of 62.5 ns +// .spi_mode = NRF_QSPI_MODE_0, +// .dpmen = false +// }, +// .irq_priority = 7, +// }; + +// #if EXTERNAL_FLASH_QSPI_DUAL +// qspi_cfg.pins.io1_pin = MICROPY_QSPI_DATA1; +// qspi_cfg.prot_if.readoc = NRF_QSPI_READOC_READ2O; +// qspi_cfg.prot_if.writeoc = NRF_QSPI_WRITEOC_PP2O; +// #else +// qspi_cfg.pins.io1_pin = MICROPY_QSPI_DATA1; +// qspi_cfg.pins.io2_pin = MICROPY_QSPI_DATA2; +// qspi_cfg.pins.io3_pin = MICROPY_QSPI_DATA3; +// qspi_cfg.prot_if.readoc = NRF_QSPI_READOC_READ4IO; +// qspi_cfg.prot_if.writeoc = NRF_QSPI_WRITEOC_PP4O; +// #endif + +// // No callback for blocking API +// nrfx_qspi_init(&qspi_cfg, NULL, NULL); +} + +void spi_flash_init_device(const external_flash_device* device) { + // check_quad_enable(device); + + // // Switch to single output line if the device doesn't support quad programs. + // if (!device->supports_qspi_writes) { + // NRF_QSPI->IFCONFIG0 &= ~QSPI_IFCONFIG0_WRITEOC_Msk; + // NRF_QSPI->IFCONFIG0 |= QSPI_IFCONFIG0_WRITEOC_PP << QSPI_IFCONFIG0_WRITEOC_Pos; + // } + + // // Speed up as much as we can. + // // Start at 16 MHz and go down. + // // At 32 MHz GD25Q16C doesn't work reliably on Feather 52840, even though it should work up to 104 MHz. + // // sckfreq = 0 is 32 Mhz + // // sckfreq = 1 is 16 MHz, etc. + // uint8_t sckfreq = 1; + // while (32000000 / (sckfreq + 1) > device->max_clock_speed_mhz * 1000000 && sckfreq < 16) { + // sckfreq += 1; + // } + // NRF_QSPI->IFCONFIG1 &= ~QSPI_IFCONFIG1_SCKFREQ_Msk; + // NRF_QSPI->IFCONFIG1 |= sckfreq << QSPI_IFCONFIG1_SCKFREQ_Pos; +} diff --git a/ports/stm32f4/supervisor/serial.c b/ports/stm32f4/supervisor/serial.c new file mode 100644 index 00000000000..3154dc3e583 --- /dev/null +++ b/ports/stm32f4/supervisor/serial.c @@ -0,0 +1,75 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "py/mphal.h" +#include +#include "supervisor/serial.h" +#include "stm32f4xx_hal.h" + +UART_HandleTypeDef huart2; + +void serial_init(void) { + huart2.Instance = USART2; + huart2.Init.BaudRate = 9600; + huart2.Init.WordLength = UART_WORDLENGTH_8B; + huart2.Init.StopBits = UART_STOPBITS_1; + huart2.Init.Parity = UART_PARITY_NONE; + huart2.Init.Mode = UART_MODE_TX_RX; + huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart2.Init.OverSampling = UART_OVERSAMPLING_16; + if (HAL_UART_Init(&huart2) == HAL_OK) + { + //HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET); + } + //HAL_UART_Transmit(&huart2, (uint8_t*)"Serial On", 9, 5000); + //HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET); +} + +bool serial_connected(void) { + return true; +} + +char serial_read(void) { + uint8_t data; + HAL_UART_Receive(&huart2, &data, 1,5000); + return data; +} + +bool serial_bytes_available(void) { + return __HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE); +} + +void serial_write(const char* text) { + serial_write_substring(text, strlen(text)); +} + +void serial_write_substring(const char *text, uint32_t len) { + if (len == 0) { + return; + } + HAL_UART_Transmit(&huart2, (uint8_t*)text, len, 5000); +} + diff --git a/ports/stm32f4/supervisor/usb.c b/ports/stm32f4/supervisor/usb.c new file mode 100644 index 00000000000..9135235238a --- /dev/null +++ b/ports/stm32f4/supervisor/usb.c @@ -0,0 +1,80 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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 "tick.h" +#include "supervisor/usb.h" +#include "lib/utils/interrupt_char.h" +#include "lib/mp-readline/readline.h" +#include "stm32f4xx_hal.h" + +#define USB_OTGFS_VBUS_Pin GPIO_PIN_9 +#define USB_OTGFS_VBUS_GPIO_Port GPIOA +#define USB_OTGFS_ID_Pin GPIO_PIN_10 +#define USB_OTGFS_ID_GPIO_Port GPIOA +#define USB_OTGFS_DM_Pin GPIO_PIN_11 +#define USB_OTGFS_DM_GPIO_Port GPIOA +#define USB_OTGFS_DP_Pin GPIO_PIN_12 +#define USB_OTGFS_DP_GPIO_Port GPIOA + + +void init_usb_hardware(void) { + // HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET); //LED 2 + GPIO_InitTypeDef GPIO_InitStruct = {0}; + /**USB_OTG_FS GPIO Configuration + PA10 ------> USB_OTG_FS_ID + PA11 ------> USB_OTG_FS_DM + PA12 ------> USB_OTG_FS_DP + */ + GPIO_InitStruct.Pin = USB_OTGFS_VBUS_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(USB_OTGFS_VBUS_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = USB_OTGFS_DM_Pin|USB_OTGFS_DP_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + //TinyUSB suggestion + GPIO_InitStruct.Pin = USB_OTGFS_ID_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Peripheral clock enable */ + __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); + + /* Peripheral interrupt init */ + HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(OTG_FS_IRQn); + + //HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET); //LED 3 +} diff --git a/ports/stm32f4/system_stm32f4xx.c b/ports/stm32f4/system_stm32f4xx.c new file mode 100644 index 00000000000..3303f969d96 --- /dev/null +++ b/ports/stm32f4/system_stm32f4xx.c @@ -0,0 +1,761 @@ +/** + ****************************************************************************** + * @file system_stm32f4xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File. + * + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32f4xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f4xx_system + * @{ + */ + +/** @addtogroup STM32F4xx_System_Private_Includes + * @{ + */ + + +#include "stm32f4xx.h" + +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Defines + * @{ + */ + +/************************* Miscellaneous Configuration ************************/ +/*!< Uncomment the following line if you need to use external SRAM or SDRAM as data memory */ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\ + || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) +/* #define DATA_IN_ExtSRAM */ +#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx || STM32F469xx || STM32F479xx ||\ + STM32F412Zx || STM32F412Vx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) +/* #define DATA_IN_ExtSDRAM */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx ||\ + STM32F479xx */ + +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +/******************************************************************************/ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Variables + * @{ + */ + /* This variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ +uint32_t SystemCoreClock = 16000000; +const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; +const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4}; +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes + * @{ + */ + +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) + static void SystemInit_ExtMemCtl(void); +#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system + * Initialize the FPU setting, vector table location and External memory + * configuration. + * @param None + * @retval None + */ +void SystemInit(void) +{ + /* FPU settings ------------------------------------------------------------*/ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ + #endif + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set HSION bit */ + RCC->CR |= (uint32_t)0x00000001; + + /* Reset CFGR register */ + RCC->CFGR = 0x00000000; + + /* Reset HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFFF; + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x24003010; + + /* Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + + /* Disable all interrupts */ + RCC->CIR = 0x00000000; + +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) + SystemInit_ExtMemCtl(); +#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ + + /* Configure the Vector Table location add offset address ------------------*/ +#ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ +#endif +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (its value + * depends on the application requirements), user has to ensure that HSE_VALUE + * is same as the real frequency of the crystal used. Otherwise, this function + * may have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; + case 0x04: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + case 0x08: /* PLL used as system clock source */ + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N + SYSCLK = PLL_VCO / PLL_P + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; + pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; + + if (pllsource != 0) + { + /* HSE used as PLL clock source */ + pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + else + { + /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + + pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; + SystemCoreClock = pllvco/pllp; + break; + default: + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK frequency --------------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK frequency */ + SystemCoreClock >>= tmp; +} + +#if defined (DATA_IN_ExtSRAM) && defined (DATA_IN_ExtSDRAM) +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F469xx) || defined(STM32F479xx) +/** + * @brief Setup the external memory controller. + * Called in startup_stm32f4xx.s before jump to main. + * This function configures the external memories (SRAM/SDRAM) + * This SRAM/SDRAM will be used as program data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ + __IO uint32_t tmp = 0x00; + + register uint32_t tmpreg = 0, timeout = 0xFFFF; + register __IO uint32_t index; + + /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock */ + RCC->AHB1ENR |= 0x000001F8; + + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN); + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x00CCC0CC; + GPIOD->AFR[1] = 0xCCCCCCCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xAAAA0A8A; + /* Configure PDx pins speed to 100 MHz */ + GPIOD->OSPEEDR = 0xFFFF0FCF; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00CC0CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA828A; + /* Configure PEx pins speed to 100 MHz */ + GPIOE->OSPEEDR = 0xFFFFC3CF; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0xCCCCCCCC; + GPIOF->AFR[1] = 0xCCCCCCCC; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA800AAA; + /* Configure PFx pins speed to 50 MHz */ + GPIOF->OSPEEDR = 0xAA800AAA; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0xCCCCCCCC; + GPIOG->AFR[1] = 0xCCCCCCCC; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0xAAAAAAAA; + /* Configure PGx pins speed to 50 MHz */ + GPIOG->OSPEEDR = 0xAAAAAAAA; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + + /* Connect PHx pins to FMC Alternate function */ + GPIOH->AFR[0] = 0x00C0CC00; + GPIOH->AFR[1] = 0xCCCCCCCC; + /* Configure PHx pins in Alternate function mode */ + GPIOH->MODER = 0xAAAA08A0; + /* Configure PHx pins speed to 50 MHz */ + GPIOH->OSPEEDR = 0xAAAA08A0; + /* Configure PHx pins Output type to push-pull */ + GPIOH->OTYPER = 0x00000000; + /* No pull-up, pull-down for PHx pins */ + GPIOH->PUPDR = 0x00000000; + + /* Connect PIx pins to FMC Alternate function */ + GPIOI->AFR[0] = 0xCCCCCCCC; + GPIOI->AFR[1] = 0x00000CC0; + /* Configure PIx pins in Alternate function mode */ + GPIOI->MODER = 0x0028AAAA; + /* Configure PIx pins speed to 50 MHz */ + GPIOI->OSPEEDR = 0x0028AAAA; + /* Configure PIx pins Output type to push-pull */ + GPIOI->OTYPER = 0x00000000; + /* No pull-up, pull-down for PIx pins */ + GPIOI->PUPDR = 0x00000000; + +/*-- FMC Configuration -------------------------------------------------------*/ + /* Enable the FMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + + FMC_Bank5_6->SDCR[0] = 0x000019E4; + FMC_Bank5_6->SDTR[0] = 0x01115351; + + /* SDRAM initialization sequence */ + /* Clock enable command */ + FMC_Bank5_6->SDCMR = 0x00000011; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Delay */ + for (index = 0; index<1000; index++); + + /* PALL command */ + FMC_Bank5_6->SDCMR = 0x00000012; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Auto refresh command */ + FMC_Bank5_6->SDCMR = 0x00000073; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* MRD register program */ + FMC_Bank5_6->SDCMR = 0x00046014; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Set refresh count */ + tmpreg = FMC_Bank5_6->SDRTR; + FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1)); + + /* Disable write protection */ + tmpreg = FMC_Bank5_6->SDCR[0]; + FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF); + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001011; + FMC_Bank1->BTCR[3] = 0x00000201; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +#if defined(STM32F469xx) || defined(STM32F479xx) + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001091; + FMC_Bank1->BTCR[3] = 0x00110212; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F469xx || STM32F479xx */ + + (void)(tmp); +} +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */ +#elif defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) +/** + * @brief Setup the external memory controller. + * Called in startup_stm32f4xx.s before jump to main. + * This function configures the external memories (SRAM/SDRAM) + * This SRAM/SDRAM will be used as program data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ + __IO uint32_t tmp = 0x00; +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) +#if defined (DATA_IN_ExtSDRAM) + register uint32_t tmpreg = 0, timeout = 0xFFFF; + register __IO uint32_t index; + +#if defined(STM32F446xx) + /* Enable GPIOA, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG interface + clock */ + RCC->AHB1ENR |= 0x0000007D; +#else + /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface + clock */ + RCC->AHB1ENR |= 0x000001F8; +#endif /* STM32F446xx */ + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN); + +#if defined(STM32F446xx) + /* Connect PAx pins to FMC Alternate function */ + GPIOA->AFR[0] |= 0xC0000000; + GPIOA->AFR[1] |= 0x00000000; + /* Configure PDx pins in Alternate function mode */ + GPIOA->MODER |= 0x00008000; + /* Configure PDx pins speed to 50 MHz */ + GPIOA->OSPEEDR |= 0x00008000; + /* Configure PDx pins Output type to push-pull */ + GPIOA->OTYPER |= 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOA->PUPDR |= 0x00000000; + + /* Connect PCx pins to FMC Alternate function */ + GPIOC->AFR[0] |= 0x00CC0000; + GPIOC->AFR[1] |= 0x00000000; + /* Configure PDx pins in Alternate function mode */ + GPIOC->MODER |= 0x00000A00; + /* Configure PDx pins speed to 50 MHz */ + GPIOC->OSPEEDR |= 0x00000A00; + /* Configure PDx pins Output type to push-pull */ + GPIOC->OTYPER |= 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOC->PUPDR |= 0x00000000; +#endif /* STM32F446xx */ + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x000000CC; + GPIOD->AFR[1] = 0xCC000CCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xA02A000A; + /* Configure PDx pins speed to 50 MHz */ + GPIOD->OSPEEDR = 0xA02A000A; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00000CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA800A; + /* Configure PEx pins speed to 50 MHz */ + GPIOE->OSPEEDR = 0xAAAA800A; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0xCCCCCCCC; + GPIOF->AFR[1] = 0xCCCCCCCC; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA800AAA; + /* Configure PFx pins speed to 50 MHz */ + GPIOF->OSPEEDR = 0xAA800AAA; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0xCCCCCCCC; + GPIOG->AFR[1] = 0xCCCCCCCC; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0xAAAAAAAA; + /* Configure PGx pins speed to 50 MHz */ + GPIOG->OSPEEDR = 0xAAAAAAAA; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F469xx) || defined(STM32F479xx) + /* Connect PHx pins to FMC Alternate function */ + GPIOH->AFR[0] = 0x00C0CC00; + GPIOH->AFR[1] = 0xCCCCCCCC; + /* Configure PHx pins in Alternate function mode */ + GPIOH->MODER = 0xAAAA08A0; + /* Configure PHx pins speed to 50 MHz */ + GPIOH->OSPEEDR = 0xAAAA08A0; + /* Configure PHx pins Output type to push-pull */ + GPIOH->OTYPER = 0x00000000; + /* No pull-up, pull-down for PHx pins */ + GPIOH->PUPDR = 0x00000000; + + /* Connect PIx pins to FMC Alternate function */ + GPIOI->AFR[0] = 0xCCCCCCCC; + GPIOI->AFR[1] = 0x00000CC0; + /* Configure PIx pins in Alternate function mode */ + GPIOI->MODER = 0x0028AAAA; + /* Configure PIx pins speed to 50 MHz */ + GPIOI->OSPEEDR = 0x0028AAAA; + /* Configure PIx pins Output type to push-pull */ + GPIOI->OTYPER = 0x00000000; + /* No pull-up, pull-down for PIx pins */ + GPIOI->PUPDR = 0x00000000; +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */ + +/*-- FMC Configuration -------------------------------------------------------*/ + /* Enable the FMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + + /* Configure and enable SDRAM bank1 */ +#if defined(STM32F446xx) + FMC_Bank5_6->SDCR[0] = 0x00001954; +#else + FMC_Bank5_6->SDCR[0] = 0x000019E4; +#endif /* STM32F446xx */ + FMC_Bank5_6->SDTR[0] = 0x01115351; + + /* SDRAM initialization sequence */ + /* Clock enable command */ + FMC_Bank5_6->SDCMR = 0x00000011; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Delay */ + for (index = 0; index<1000; index++); + + /* PALL command */ + FMC_Bank5_6->SDCMR = 0x00000012; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Auto refresh command */ +#if defined(STM32F446xx) + FMC_Bank5_6->SDCMR = 0x000000F3; +#else + FMC_Bank5_6->SDCMR = 0x00000073; +#endif /* STM32F446xx */ + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* MRD register program */ +#if defined(STM32F446xx) + FMC_Bank5_6->SDCMR = 0x00044014; +#else + FMC_Bank5_6->SDCMR = 0x00046014; +#endif /* STM32F446xx */ + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Set refresh count */ + tmpreg = FMC_Bank5_6->SDRTR; +#if defined(STM32F446xx) + FMC_Bank5_6->SDRTR = (tmpreg | (0x0000050C<<1)); +#else + FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1)); +#endif /* STM32F446xx */ + + /* Disable write protection */ + tmpreg = FMC_Bank5_6->SDCR[0]; + FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF); +#endif /* DATA_IN_ExtSDRAM */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */ + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\ + || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) + +#if defined(DATA_IN_ExtSRAM) +/*-- GPIOs Configuration -----------------------------------------------------*/ + /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ + RCC->AHB1ENR |= 0x00000078; + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN); + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x00CCC0CC; + GPIOD->AFR[1] = 0xCCCCCCCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xAAAA0A8A; + /* Configure PDx pins speed to 100 MHz */ + GPIOD->OSPEEDR = 0xFFFF0FCF; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00CC0CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA828A; + /* Configure PEx pins speed to 100 MHz */ + GPIOE->OSPEEDR = 0xFFFFC3CF; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0x00CCCCCC; + GPIOF->AFR[1] = 0xCCCC0000; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA000AAA; + /* Configure PFx pins speed to 100 MHz */ + GPIOF->OSPEEDR = 0xFF000FFF; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0x00CCCCCC; + GPIOG->AFR[1] = 0x000000C0; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0x00085AAA; + /* Configure PGx pins speed to 100 MHz */ + GPIOG->OSPEEDR = 0x000CAFFF; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + +/*-- FMC/FSMC Configuration --------------------------------------------------*/ + /* Enable the FMC/FSMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001011; + FMC_Bank1->BTCR[3] = 0x00000201; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +#if defined(STM32F469xx) || defined(STM32F479xx) + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001091; + FMC_Bank1->BTCR[3] = 0x00110212; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F469xx || STM32F479xx */ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx)\ + || defined(STM32F412Zx) || defined(STM32F412Vx) + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN); + /* Configure and enable Bank1_SRAM2 */ + FSMC_Bank1->BTCR[2] = 0x00001011; + FSMC_Bank1->BTCR[3] = 0x00000201; + FSMC_Bank1E->BWTR[2] = 0x0FFFFFFF; +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F412Zx || STM32F412Vx */ + +#endif /* DATA_IN_ExtSRAM */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\ + STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx */ + (void)(tmp); +} +#endif /* DATA_IN_ExtSRAM && DATA_IN_ExtSDRAM */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/ports/stm32f4/tick.c b/ports/stm32f4/tick.c new file mode 100644 index 00000000000..5bd2da6edcc --- /dev/null +++ b/ports/stm32f4/tick.c @@ -0,0 +1,85 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "tick.h" + +#include "supervisor/shared/autoreload.h" +#include "supervisor/filesystem.h" +#include "shared-module/gamepad/__init__.h" +#include "shared-bindings/microcontroller/Processor.h" + +#include "stm32f4xx.h" + +// Global millisecond tick count +volatile uint64_t ticks_ms = 0; + +void SysTick_Handler(void) { + // SysTick interrupt handler called when the SysTick timer reaches zero + // (every millisecond). + ticks_ms += 1; + +#if CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS > 0 + filesystem_tick(); +#endif +#ifdef CIRCUITPY_AUTORELOAD_DELAY_MS + autoreload_tick(); +#endif +#ifdef CIRCUITPY_GAMEPAD_TICKS + if (!(ticks_ms & CIRCUITPY_GAMEPAD_TICKS)) { + gamepad_tick(); + } +#endif +} + +void tick_init() { + uint32_t ticks_per_ms = SystemCoreClock/ 1000; + SysTick_Config(ticks_per_ms); // interrupt is enabled +} + +void tick_delay(uint32_t us) { + uint32_t ticks_per_us = SystemCoreClock / 1000 / 1000; + uint32_t us_between_ticks = SysTick->VAL / ticks_per_us; + uint64_t start_ms = ticks_ms; + while (us > 1000) { + while (ticks_ms == start_ms) {} + us -= us_between_ticks; + start_ms = ticks_ms; + us_between_ticks = 1000; + } + while (SysTick->VAL > ((us_between_ticks - us) * ticks_per_us)) {} +} + +// us counts down! +void current_tick(uint64_t* ms, uint32_t* us_until_ms) { + uint32_t ticks_per_us = SystemCoreClock / 1000 / 1000; + *ms = ticks_ms; + *us_until_ms = SysTick->VAL / ticks_per_us; +} + +void wait_until(uint64_t ms, uint32_t us_until_ms) { + uint32_t ticks_per_us = SystemCoreClock / 1000 / 1000; + while(ticks_ms <= ms && SysTick->VAL / ticks_per_us >= us_until_ms) {} +} diff --git a/ports/stm32f4/tick.h b/ports/stm32f4/tick.h new file mode 100644 index 00000000000..e4772fa2cf6 --- /dev/null +++ b/ports/stm32f4/tick.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ +#ifndef MICROPY_INCLUDED_STM32F4_TICK_H +#define MICROPY_INCLUDED_STM32F4_TICK_H + +#include "py/mpconfig.h" + +#include + +extern volatile uint64_t ticks_ms; + +extern struct timer_descriptor ms_timer; + +void tick_init(void); + +void tick_delay(uint32_t us); + +void current_tick(uint64_t* ms, uint32_t* us_until_ms); +// Do not call this with interrupts disabled because it may be waiting for +// ticks_ms to increment. +void wait_until(uint64_t ms, uint32_t us_until_ms); + +#endif // MICROPY_INCLUDED_STM32F4_TICK_H diff --git a/ports/teensy/Makefile b/ports/teensy/Makefile index 08ecf0f9132..e6d848b65aa 100644 --- a/ports/teensy/Makefile +++ b/ports/teensy/Makefile @@ -104,6 +104,7 @@ STM_SRC_S = $(addprefix ports/stm32/,\ LIB_SRC_C = $(addprefix lib/,\ libc/string0.c \ + mp-readline/builtin_input.c \ mp-readline/readline.c \ utils/pyexec.c \ utils/sys_stdio_mphal.c \ diff --git a/ports/unix/Makefile b/ports/unix/Makefile index cbdd3f3fbe3..7ffa0fd082f 100644 --- a/ports/unix/Makefile +++ b/ports/unix/Makefile @@ -74,7 +74,7 @@ else # Use gcc syntax for map file LDFLAGS_ARCH = -Wl,-Map=$@.map,--cref -Wl,--gc-sections endif -LDFLAGS = $(LDFLAGS_MOD) $(LDFLAGS_ARCH) -lm $(LDFLAGS_EXTRA) +LDFLAGS = -Lbuild $(LDFLAGS_MOD) $(LDFLAGS_ARCH) -lm $(LDFLAGS_EXTRA) ifeq ($(MICROPY_FORCE_32BIT),1) # Note: you may need to install i386 versions of dependency packages, @@ -149,8 +149,21 @@ SRC_C = \ alloc.c \ coverage.c \ fatfs_port.c \ + supervisor/stub/filesystem.c \ + supervisor/stub/safe_mode.c \ + supervisor/stub/serial.c \ + supervisor/stub/stack.c \ + supervisor/shared/translate.c \ $(SRC_MOD) +PY_EXTMOD_O_BASENAME += \ + extmod/machine_mem.o \ + extmod/machine_pinbase.o \ + extmod/machine_signal.o \ + extmod/machine_pulse.o \ + extmod/machine_i2c.o \ + extmod/machine_spi.o + LIB_SRC_C = $(addprefix lib/,\ $(LIB_SRC_C_EXTRA) \ timeutils/timeutils.c \ @@ -188,7 +201,7 @@ include $(TOP)/py/mkrules.mk test: $(PROG) $(TOP)/tests/run-tests $(eval DIRNAME=ports/$(notdir $(CURDIR))) - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests --auto-jobs # install micropython in /usr/local/bin TARGET = micropython @@ -244,7 +257,7 @@ coverage: $(MAKE) \ COPT="-O0" CFLAGS_EXTRA='$(CFLAGS_EXTRA) -DMP_CONFIGFILE="" \ -fprofile-arcs -ftest-coverage \ - -Wdouble-promotion -Wformat -Wmissing-declarations -Wmissing-prototypes -Wsign-compare \ + -Wformat -Wmissing-declarations -Wmissing-prototypes -Wsign-compare \ -Wold-style-definition -Wpointer-arith -Wshadow -Wuninitialized -Wunused-parameter \ -DMICROPY_UNIX_COVERAGE' \ LDFLAGS_EXTRA='-fprofile-arcs -ftest-coverage' \ @@ -253,14 +266,17 @@ coverage: coverage_test: coverage $(eval DIRNAME=ports/$(notdir $(CURDIR))) - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests -d thread - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --emit native - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --via-mpy -d basics float + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --auto-jobs + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --auto-jobs -d thread + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --auto-jobs --emit native + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests -j1 --via-mpy -d basics float cat $(TOP)/tests/basics/0prelim.py | ./micropython_coverage | grep -q 'abc' gcov -o build-coverage/py $(TOP)/py/*.c gcov -o build-coverage/extmod $(TOP)/extmod/*.c +coverage_clean: + $(MAKE) V=2 BUILD=build-coverage PROG=micropython_coverage clean + # Value of configure's --host= option (required for cross-compilation). # Deduce it from CROSS_COMPILE by default, but can be overridden. ifneq ($(CROSS_COMPILE),) diff --git a/ports/unix/coverage.c b/ports/unix/coverage.c index 7820f6d7366..841924c58d4 100644 --- a/ports/unix/coverage.c +++ b/ports/unix/coverage.c @@ -173,7 +173,7 @@ STATIC mp_obj_t extra_coverage(void) { gc_unlock(); // using gc_realloc to resize to 0, which means free the memory - void *p = gc_alloc(4, false); + void *p = gc_alloc(4, false, false); mp_printf(&mp_plat_print, "%p\n", gc_realloc(p, 0, false)); // calling gc_nbytes with a non-heap pointer diff --git a/ports/unix/file.c b/ports/unix/file.c index 165bbd00b03..c0cf6dcc433 100644 --- a/ports/unix/file.c +++ b/ports/unix/file.c @@ -35,6 +35,7 @@ #include "py/stream.h" #include "py/builtin.h" #include "py/mphal.h" +#include "supervisor/shared/translate.h" #include "fdfile.h" #if MICROPY_PY_IO && !MICROPY_VFS @@ -46,7 +47,7 @@ #ifdef MICROPY_CPYTHON_COMPAT STATIC void check_fd_is_open(const mp_obj_fdfile_t *o) { if (o->fd < 0) { - mp_raise_ValueError("I/O operation on closed file"); + mp_raise_ValueError(translate("I/O operation on closed file")); } } #else @@ -204,9 +205,9 @@ STATIC mp_obj_t fdfile_open(const mp_obj_type_t *type, mp_arg_val_t *args) { return MP_OBJ_FROM_PTR(o); } -STATIC mp_obj_t fdfile_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t fdfile_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS]; - mp_arg_parse_all_kw_array(n_args, n_kw, args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals); + mp_arg_parse_all(n_args, args, kw_args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals); return fdfile_open(type, arg_vals); } diff --git a/ports/unix/main.c b/ports/unix/main.c index 1cf237a2b26..d1187ae905f 100644 --- a/ports/unix/main.c +++ b/ports/unix/main.c @@ -38,6 +38,7 @@ #include #include "py/compile.h" +#include "py/frozenmod.h" #include "py/runtime.h" #include "py/builtin.h" #include "py/repl.h" @@ -470,7 +471,9 @@ MP_NOINLINE int main_(int argc, char **argv) { path = "~/.micropython/lib:/usr/lib/micropython"; #endif } - size_t path_num = 1; // [0] is for current dir (or base dir of the script) + size_t path_num = 2; // [0] is for current dir (or base dir of the script) + // [1] is for frozen files. + size_t builtin_path_count = path_num; if (*path == ':') { path_num++; } @@ -484,9 +487,11 @@ MP_NOINLINE int main_(int argc, char **argv) { mp_obj_t *path_items; mp_obj_list_get(mp_sys_path, &path_num, &path_items); path_items[0] = MP_OBJ_NEW_QSTR(MP_QSTR_); + // Frozen modules are in their own pseudo-dir, e.g., ".frozen". + path_items[1] = MP_OBJ_NEW_QSTR(MP_FROZEN_FAKE_DIR_QSTR); { char *p = path; - for (mp_uint_t i = 1; i < path_num; i++) { + for (mp_uint_t i = builtin_path_count; i < path_num; i++) { char *p1 = strchr(p, PATHLIST_SEP_CHAR); if (p1 == NULL) { p1 = p + strlen(p); @@ -506,6 +511,9 @@ MP_NOINLINE int main_(int argc, char **argv) { } } + + + mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); #if defined(MICROPY_UNIX_COVERAGE) diff --git a/ports/unix/modffi.c b/ports/unix/modffi.c index 024f83c1412..03dc9e4ec69 100644 --- a/ports/unix/modffi.c +++ b/ports/unix/modffi.c @@ -36,6 +36,8 @@ #include "py/binary.h" #include "py/mperrno.h" +#include "supervisor/shared/translate.h" + /* * modffi uses character codes to encode a value type, based on "struct" * module type codes, with some extensions and overridings. @@ -133,7 +135,7 @@ STATIC ffi_type *get_ffi_type(mp_obj_t o_in) } // TODO: Support actual libffi type objects - mp_raise_TypeError("Unknown type"); + mp_raise_TypeError(translate("Unknown type")); } STATIC mp_obj_t return_ffi_value(ffi_arg val, char type) @@ -151,7 +153,7 @@ STATIC mp_obj_t return_ffi_value(ffi_arg val, char type) #if MICROPY_PY_BUILTINS_FLOAT case 'f': { union { ffi_arg ffi; float flt; } val_union = { .ffi = val }; - return mp_obj_new_float(val_union.flt); + return mp_obj_new_float((mp_float_t) val_union.flt); } case 'd': { double *p = (double*)&val; @@ -202,7 +204,7 @@ STATIC mp_obj_t make_func(mp_obj_t rettype_in, void *func, mp_obj_t argtypes_in) int res = ffi_prep_cif(&o->cif, FFI_DEFAULT_ABI, nparams, char2ffi_type(*rettype), o->params); if (res != FFI_OK) { - mp_raise_ValueError("Error in ffi_prep_cif"); + mp_raise_ValueError(translate("Error in ffi_prep_cif")); } return MP_OBJ_FROM_PTR(o); @@ -260,12 +262,12 @@ STATIC mp_obj_t mod_ffi_callback(mp_obj_t rettype_in, mp_obj_t func_in, mp_obj_t int res = ffi_prep_cif(&o->cif, FFI_DEFAULT_ABI, nparams, char2ffi_type(*rettype), o->params); if (res != FFI_OK) { - mp_raise_ValueError("Error in ffi_prep_cif"); + mp_raise_ValueError(translate("Error in ffi_prep_cif")); } res = ffi_prep_closure_loc(o->clo, &o->cif, call_py_func, MP_OBJ_TO_PTR(func_in), o->func); if (res != FFI_OK) { - mp_raise_ValueError("ffi_prep_closure_loc"); + mp_raise_ValueError(translate("ffi_prep_closure_loc")); } return MP_OBJ_FROM_PTR(o); @@ -302,9 +304,9 @@ STATIC mp_obj_t ffimod_addr(mp_obj_t self_in, mp_obj_t symname_in) { } MP_DEFINE_CONST_FUN_OBJ_2(ffimod_addr_obj, ffimod_addr); -STATIC mp_obj_t ffimod_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t ffimod_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)n_args; - (void)n_kw; + (void)kw_args; const char *fname = NULL; if (args[0] != mp_const_none) { @@ -408,7 +410,7 @@ STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const } error: - mp_raise_TypeError("Don't know how to pass object to native function"); + mp_raise_TypeError(translate("Don't know how to pass object to native function")); } STATIC const mp_obj_type_t ffifunc_type = { @@ -479,7 +481,7 @@ STATIC const mp_obj_type_t opaque_type = { */ STATIC mp_obj_t mod_ffi_open(size_t n_args, const mp_obj_t *args) { - return ffimod_make_new(&ffimod_type, n_args, 0, args); + return ffimod_make_new(&ffimod_type, n_args, args, NULL); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_ffi_open_obj, 1, 2, mod_ffi_open); diff --git a/ports/unix/modmachine.c b/ports/unix/modmachine.c index 48dddec0ae7..b2bca12063a 100644 --- a/ports/unix/modmachine.c +++ b/ports/unix/modmachine.c @@ -35,6 +35,8 @@ #include "extmod/machine_signal.h" #include "extmod/machine_pulse.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PLAT_DEV_MEM #include #include @@ -48,7 +50,7 @@ uintptr_t mod_machine_mem_get_addr(mp_obj_t addr_o, uint align) { uintptr_t addr = mp_obj_int_get_truncated(addr_o); if ((addr & (align - 1)) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "address %08x is not aligned to %d bytes", addr, align)); + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, translate("address %08x is not aligned to %d bytes"), addr, align)); } #if MICROPY_PLAT_DEV_MEM { diff --git a/ports/unix/modtime.c b/ports/unix/modtime.c index a74b81f374e..a8f6ed5c6ea 100644 --- a/ports/unix/modtime.c +++ b/ports/unix/modtime.c @@ -60,7 +60,7 @@ static inline int msec_sleep_tv(struct timeval *tv) { #endif #if defined(MP_CLOCKS_PER_SEC) -#define CLOCK_DIV (MP_CLOCKS_PER_SEC / 1000.0F) +#define CLOCK_DIV (mp_float_t) (MP_CLOCKS_PER_SEC / 1000.0F) #else #error Unsupported clock() implementation #endif @@ -83,7 +83,7 @@ STATIC mp_obj_t mod_time_clock(void) { // float cannot represent full range of int32 precisely, so we pre-divide // int to reduce resolution, and then actually do float division hoping // to preserve integer part resolution. - return mp_obj_new_float((float)(clock() / 1000) / CLOCK_DIV); + return mp_obj_new_float((mp_float_t)(clock() / 1000) / CLOCK_DIV); #else return mp_obj_new_int((mp_int_t)clock()); #endif diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c index ba50e6165e7..84e9298fd3d 100644 --- a/ports/unix/modusocket.c +++ b/ports/unix/modusocket.c @@ -45,6 +45,8 @@ #include "py/builtin.h" #include "py/mphal.h" +#include "supervisor/shared/translate.h" + /* The idea of this module is to implement reasonable minimum of socket-related functions to write typical clients and servers. @@ -323,9 +325,9 @@ STATIC mp_obj_t socket_makefile(size_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_makefile_obj, 1, 3, socket_makefile); -STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - (void)n_kw; + (void)kw_args; int family = AF_INET; int type = SOCK_STREAM; @@ -469,7 +471,7 @@ STATIC mp_obj_t mod_socket_getaddrinfo(size_t n_args, const mp_obj_t *args) { if (res != 0) { // CPython: socket.gaierror - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[addrinfo error %d]", res)); + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, translate("[addrinfo error %d]"), res)); } assert(addr_list); diff --git a/ports/unix/mpconfigport_coverage.h b/ports/unix/mpconfigport_coverage.h index f0e6fbe94b7..97c05cfee4f 100644 --- a/ports/unix/mpconfigport_coverage.h +++ b/ports/unix/mpconfigport_coverage.h @@ -47,6 +47,7 @@ #define MICROPY_VFS_POSIX (1) #undef MICROPY_VFS_FAT #define MICROPY_VFS_FAT (1) +#define MICROPY_FATFS_USE_LABEL (1) #define MICROPY_PY_FRAMEBUF (1) #define MICROPY_PY_COLLECTIONS_NAMEDTUPLE__ASDICT (1) diff --git a/ports/windows/.appveyor.yml b/ports/windows/.appveyor.yml deleted file mode 100644 index 795330eff01..00000000000 --- a/ports/windows/.appveyor.yml +++ /dev/null @@ -1,52 +0,0 @@ -environment: - # Python version used - MICROPY_CPYTHON3: c:/python34/python.exe - -init: - # Set build version number to commit to be travis-like -- ps: Update-AppveyorBuild -Version $env:appveyor_repo_commit.substring(0,8) - -configuration: -- Debug -- Release - -platform: -- x86 -- x64 - -build: - project: ports/windows/micropython.vcxproj - verbosity: normal - -test_script: -- cmd: >- - cd tests - - %MICROPY_CPYTHON3% run-tests - -# After the build/test phase for the MSVC build completes, -# build and test with mingw-w64, release versions only. -after_test: -- ps: | - if ($env:configuration -eq 'Debug') { - return - } - $env:MSYSTEM = if ($platform -eq 'x86') {'MINGW32'} else {'MINGW64'} - $env:CHERE_INVOKING = 'enabled_from_arguments' - cd (Join-Path $env:APPVEYOR_BUILD_FOLDER 'ports/windows') - C:\msys64\usr\bin\bash.exe -l -c "make -B -j4 V=1" - if ($LASTEXITCODE -ne 0) { - throw "$env:MSYSTEM build exited with code $LASTEXITCODE" - } - cd (Join-Path $env:APPVEYOR_BUILD_FOLDER 'tests') - & $env:MICROPY_CPYTHON3 run-tests -e math_fun -e float2int_double -e float_parse -e math_domain_special - if ($LASTEXITCODE -ne 0) { - throw "$env:MSYSTEM tests exited with code $LASTEXITCODE" - } - -skip_tags: true - -deploy: off - -nuget: - disable_publish_on_pr: true diff --git a/py/argcheck.c b/py/argcheck.c index d53bca73a6c..a8df206e280 100644 --- a/py/argcheck.c +++ b/py/argcheck.c @@ -29,44 +29,58 @@ #include "py/runtime.h" -void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw) { +#include "supervisor/shared/translate.h" + + +void mp_arg_check_num(size_t n_args, mp_map_t *kw_args, size_t n_args_min, size_t n_args_max, bool takes_kw) { + size_t n_kw = 0; + if (kw_args != NULL) { + n_kw = kw_args->used; + } + mp_arg_check_num_kw_array(n_args, n_kw, n_args_min, n_args_max, takes_kw); +} + +void mp_arg_check_num_kw_array(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw) { + // NOTE(tannewt): This prevents this function from being optimized away. + // Without it, functions can crash when reading invalid args. + __asm volatile (""); // TODO maybe take the function name as an argument so we can print nicer error messages - if (n_kw && !takes_kw) { - if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { + if (n_kw > 0 && !takes_kw) { + #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); - } else { - mp_raise_TypeError("function does not take keyword arguments"); - } + #else + mp_raise_TypeError(translate("function does not take keyword arguments")); + #endif } if (n_args_min == n_args_max) { if (n_args != n_args_min) { - if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { + #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); - } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "function takes %d positional arguments but %d were given", - n_args_min, n_args)); - } + #else + mp_raise_TypeError_varg( + translate("function takes %d positional arguments but %d were given"), + n_args_min, n_args); + #endif } } else { if (n_args < n_args_min) { - if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { + #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); - } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "function missing %d required positional arguments", - n_args_min - n_args)); - } + #else + mp_raise_TypeError_varg( + translate("function missing %d required positional arguments"), + n_args_min - n_args); + #endif } else if (n_args > n_args_max) { - if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { + #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); - } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "function expected at most %d arguments, got %d", - n_args_max, n_args)); - } + #else + mp_raise_TypeError_varg( + translate("function expected at most %d arguments, got %d"), + n_args_max, n_args); + #endif } } } @@ -88,8 +102,8 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_arg_error_terse_mismatch(); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "'%q' argument required", allowed[i].qst)); + mp_raise_TypeError_varg( + translate("'%q' argument required"), allowed[i].qst); } } out_vals[i] = allowed[i].defval; @@ -114,7 +128,7 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n mp_arg_error_terse_mismatch(); } else { // TODO better error message - mp_raise_TypeError("extra positional arguments given"); + mp_raise_TypeError(translate("extra positional arguments given")); } } if (kws_found < kws->used) { @@ -122,7 +136,7 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n mp_arg_error_terse_mismatch(); } else { // TODO better error message - mp_raise_TypeError("extra keyword arguments given"); + mp_raise_TypeError(translate("extra keyword arguments given")); } } } @@ -134,11 +148,11 @@ void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args, } NORETURN void mp_arg_error_terse_mismatch(void) { - mp_raise_TypeError("argument num/types mismatch"); + mp_raise_TypeError(translate("argument num/types mismatch")); } #if MICROPY_CPYTHON_COMPAT NORETURN void mp_arg_error_unimpl_kw(void) { - mp_raise_NotImplementedError("keyword argument(s) not yet implemented - use normal args instead"); + mp_raise_NotImplementedError(translate("keyword argument(s) not yet implemented - use normal args instead")); } #endif diff --git a/py/asmarm.h b/py/asmarm.h index 871e35820be..56030309123 100644 --- a/py/asmarm.h +++ b/py/asmarm.h @@ -122,7 +122,7 @@ void asm_arm_bcc_label(asm_arm_t *as, int cond, uint label); void asm_arm_b_label(asm_arm_t *as, uint label); void asm_arm_bl_ind(asm_arm_t *as, void *fun_ptr, uint fun_id, uint reg_temp); -#if GENERIC_ASM_API +#if defined(GENERIC_ASM_API) && GENERIC_ASM_API // The following macros provide a (mostly) arch-independent API to // generate native code, and are used by the native emitter. diff --git a/py/asmthumb.h b/py/asmthumb.h index 8a7df5d504b..b7e2acc0480 100644 --- a/py/asmthumb.h +++ b/py/asmthumb.h @@ -238,7 +238,7 @@ void asm_thumb_b_label(asm_thumb_t *as, uint label); // convenience: picks narro void asm_thumb_bcc_label(asm_thumb_t *as, int cc, uint label); // convenience: picks narrow or wide branch void asm_thumb_bl_ind(asm_thumb_t *as, void *fun_ptr, uint fun_id, uint reg_temp); // convenience -#if GENERIC_ASM_API +#if defined(GENERIC_ASM_API) && GENERIC_ASM_API // The following macros provide a (mostly) arch-independent API to // generate native code, and are used by the native emitter. diff --git a/py/asmx64.h b/py/asmx64.h index 2fbbfa9ffc0..ed0b785fb23 100644 --- a/py/asmx64.h +++ b/py/asmx64.h @@ -114,7 +114,7 @@ void asm_x64_mov_r64_to_local(asm_x64_t* as, int src_r64, int dest_local_num); void asm_x64_mov_local_addr_to_r64(asm_x64_t* as, int local_num, int dest_r64); void asm_x64_call_ind(asm_x64_t* as, void* ptr, int temp_r32); -#if GENERIC_ASM_API +#if defined(GENERIC_ASM_API) && GENERIC_ASM_API // The following macros provide a (mostly) arch-independent API to // generate native code, and are used by the native emitter. diff --git a/py/asmx86.h b/py/asmx86.h index 09559850ca8..0908b8c7111 100644 --- a/py/asmx86.h +++ b/py/asmx86.h @@ -112,7 +112,7 @@ void asm_x86_mov_r32_to_local(asm_x86_t* as, int src_r32, int dest_local_num); void asm_x86_mov_local_addr_to_r32(asm_x86_t* as, int local_num, int dest_r32); void asm_x86_call_ind(asm_x86_t* as, void* ptr, mp_uint_t n_args, int temp_r32); -#if GENERIC_ASM_API +#if defined(GENERIC_ASM_API) && GENERIC_ASM_API // The following macros provide a (mostly) arch-independent API to // generate native code, and are used by the native emitter. diff --git a/py/asmxtensa.h b/py/asmxtensa.h index e6d4158cbc2..ef80f700a3b 100644 --- a/py/asmxtensa.h +++ b/py/asmxtensa.h @@ -239,7 +239,7 @@ void asm_xtensa_mov_local_reg(asm_xtensa_t *as, int local_num, uint reg_src); void asm_xtensa_mov_reg_local(asm_xtensa_t *as, uint reg_dest, int local_num); void asm_xtensa_mov_reg_local_addr(asm_xtensa_t *as, uint reg_dest, int local_num); -#if GENERIC_ASM_API +#if defined(GENERIC_ASM_API) && GENERIC_ASM_API // The following macros provide a (mostly) arch-independent API to // generate native code, and are used by the native emitter. diff --git a/py/bc.c b/py/bc.c index 89d8b74f911..69b4cb238b5 100644 --- a/py/bc.c +++ b/py/bc.c @@ -33,6 +33,8 @@ #include "py/bc0.h" #include "py/bc.h" +#include "supervisor/shared/translate.h" + #if MICROPY_DEBUG_VERBOSE // print debugging info #define DEBUG_PRINT (1) #else // don't print debugging info @@ -79,12 +81,12 @@ STATIC NORETURN void fun_pos_args_mismatch(mp_obj_fun_bc_t *f, size_t expected, mp_arg_error_terse_mismatch(); #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL (void)f; - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "function takes %d positional arguments but %d were given", expected, given)); + mp_raise_TypeError_varg( + translate("function takes %d positional arguments but %d were given"), expected, given); #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "%q() takes %d positional arguments but %d were given", - mp_obj_fun_get_name(MP_OBJ_FROM_PTR(f)), expected, given)); + mp_raise_TypeError_varg( + translate("%q() takes %d positional arguments but %d were given"), + mp_obj_fun_get_name(MP_OBJ_FROM_PTR(f)), expected, given); #endif } @@ -190,11 +192,18 @@ void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw for (size_t i = 0; i < n_kw; i++) { // the keys in kwargs are expected to be qstr objects mp_obj_t wanted_arg_name = kwargs[2 * i]; + if(MP_UNLIKELY(!MP_OBJ_IS_QSTR(wanted_arg_name))) { + #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + mp_raise_TypeError(translate("unexpected keyword argument")); + #else + mp_raise_TypeError(translate("keywords must be strings")); + #endif + } for (size_t j = 0; j < n_pos_args + n_kwonly_args; j++) { if (wanted_arg_name == arg_names[j]) { if (code_state->state[n_state - 1 - j] != MP_OBJ_NULL) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "function got multiple values for argument '%q'", MP_OBJ_QSTR_VALUE(wanted_arg_name))); + mp_raise_TypeError_varg( + translate("function got multiple values for argument '%q'"), MP_OBJ_QSTR_VALUE(wanted_arg_name)); } code_state->state[n_state - 1 - j] = kwargs[2 * i + 1]; goto continue2; @@ -202,12 +211,12 @@ void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw } // Didn't find name match with positional args if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) == 0) { - if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("unexpected keyword argument"); - } else { + #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + mp_raise_TypeError(translate("unexpected keyword argument")); + #else nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "unexpected keyword argument '%q'", MP_OBJ_QSTR_VALUE(wanted_arg_name))); - } + translate("unexpected keyword argument '%q'"), MP_OBJ_QSTR_VALUE(wanted_arg_name))); + #endif } mp_obj_dict_store(dict, kwargs[2 * i], kwargs[2 * i + 1]); continue2:; @@ -231,8 +240,8 @@ continue2:; // Check that all mandatory positional args are specified while (d < &code_state->state[n_state]) { if (*d++ == MP_OBJ_NULL) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "function missing required positional argument #%d", &code_state->state[n_state] - d)); + mp_raise_TypeError_varg( + translate("function missing required positional argument #%d"), &code_state->state[n_state] - d); } } @@ -247,8 +256,9 @@ continue2:; if (elem != NULL) { code_state->state[n_state - 1 - n_pos_args - i] = elem->value; } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "function missing required keyword argument '%q'", MP_OBJ_QSTR_VALUE(arg_names[n_pos_args + i]))); + mp_raise_TypeError_varg( + translate("function missing required keyword argument '%q'"), + MP_OBJ_QSTR_VALUE(arg_names[n_pos_args + i])); } } } @@ -256,7 +266,7 @@ continue2:; } else { // no keyword arguments given if (n_kwonly_args != 0) { - mp_raise_TypeError("function missing keyword-only argument"); + mp_raise_TypeError(translate("function missing keyword-only argument")); } if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) { *var_pos_kw_args = mp_obj_new_dict(0); diff --git a/py/binary.c b/py/binary.c index f509ff01088..6b46425cfb1 100644 --- a/py/binary.c +++ b/py/binary.c @@ -35,6 +35,8 @@ #include "py/objint.h" #include "py/runtime.h" +#include "supervisor/shared/translate.h" + // Helpers to work with binary-encoded data #ifndef alignof @@ -47,7 +49,7 @@ size_t mp_binary_get_size(char struct_type, char val_type, mp_uint_t *palign) { switch (struct_type) { case '<': case '>': switch (val_type) { - case 'b': case 'B': + case 'b': case 'B': case 'x': size = 1; break; case 'h': case 'H': size = 2; break; @@ -57,8 +59,10 @@ size_t mp_binary_get_size(char struct_type, char val_type, mp_uint_t *palign) { size = 4; break; case 'q': case 'Q': size = 8; break; +#if MICROPY_NONSTANDARD_TYPECODES case 'P': case 'O': case 'S': size = sizeof(void*); break; +#endif case 'f': size = sizeof(float); break; case 'd': @@ -75,7 +79,7 @@ size_t mp_binary_get_size(char struct_type, char val_type, mp_uint_t *palign) { // particular (or any) ABI. switch (val_type) { case BYTEARRAY_TYPECODE: - case 'b': case 'B': + case 'b': case 'B': case 'x': align = size = 1; break; case 'h': case 'H': align = alignof(short); @@ -89,9 +93,11 @@ size_t mp_binary_get_size(char struct_type, char val_type, mp_uint_t *palign) { case 'q': case 'Q': align = alignof(long long); size = sizeof(long long); break; +#if MICROPY_NONSTANDARD_TYPECODES case 'P': case 'O': case 'S': align = alignof(void*); size = sizeof(void*); break; +#endif case 'f': align = alignof(float); size = sizeof(float); break; @@ -103,7 +109,7 @@ size_t mp_binary_get_size(char struct_type, char val_type, mp_uint_t *palign) { } if (size == 0) { - mp_raise_ValueError("bad typecode"); + mp_raise_ValueError(translate("bad typecode")); } if (palign != NULL) { @@ -120,6 +126,7 @@ mp_obj_t mp_binary_get_val_array(char typecode, void *p, mp_uint_t index) { break; case BYTEARRAY_TYPECODE: case 'B': + case 'x': // value will be discarded val = ((unsigned char*)p)[index]; break; case 'h': @@ -148,12 +155,14 @@ mp_obj_t mp_binary_get_val_array(char typecode, void *p, mp_uint_t index) { case 'd': return mp_obj_new_float(((double*)p)[index]); #endif +#if MICROPY_NONSTANDARD_TYPECODES // Extension to CPython: array of objects case 'O': return ((mp_obj_t*)p)[index]; // Extension to CPython: array of pointers case 'P': return mp_obj_new_int((mp_int_t)(uintptr_t)((void**)p)[index]); +#endif } return MP_OBJ_NEW_SMALL_INT(val); } @@ -202,15 +211,17 @@ mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte **ptr) { long long val = mp_binary_get_int(size, is_signed(val_type), (struct_type == '>'), p); - if (val_type == 'O') { + if (MICROPY_NONSTANDARD_TYPECODES && (val_type == 'O')) { return (mp_obj_t)(mp_uint_t)val; +#if MICROPY_NONSTANDARD_TYPECODES } else if (val_type == 'S') { const char *s_val = (const char*)(uintptr_t)(mp_uint_t)val; return mp_obj_new_str(s_val, strlen(s_val)); +#endif #if MICROPY_PY_BUILTINS_FLOAT } else if (val_type == 'f') { union { uint32_t i; float f; } fpu = {val}; - return mp_obj_new_float(fpu.f); + return mp_obj_new_float((mp_float_t) fpu.f); } else if (val_type == 'd') { union { uint64_t i; double f; } fpu = {val}; return mp_obj_new_float(fpu.f); @@ -267,9 +278,11 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte ** mp_uint_t val; switch (val_type) { +#if MICROPY_NONSTANDARD_TYPECODES case 'O': val = (mp_uint_t)val_in; break; +#endif #if MICROPY_PY_BUILTINS_FLOAT case 'f': { union { uint32_t i; float f; } fp_sp; @@ -291,15 +304,20 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte ** break; } #endif - default: + default: { + bool signed_type = is_signed(val_type); #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE if (MP_OBJ_IS_TYPE(val_in, &mp_type_int)) { + // It's a longint. + mp_obj_int_buffer_overflow_check(val_in, size, signed_type); mp_obj_int_to_bytes_impl(val_in, struct_type == '>', size, p); return; } else #endif { val = mp_obj_get_int(val_in); + // Small int checking is separate, to be fast. + mp_small_int_buffer_overflow_check(val, size, signed_type); // zero/sign extend if needed if (BYTES_PER_WORD < 8 && size > sizeof(val)) { int c = (is_signed(val_type) && (mp_int_t)val < 0) ? 0xff : 0x00; @@ -309,6 +327,7 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte ** } } } + } } mp_binary_set_int(MIN((size_t)size, sizeof(val)), struct_type == '>', p, val); @@ -324,20 +343,30 @@ void mp_binary_set_val_array(char typecode, void *p, mp_uint_t index, mp_obj_t v ((double*)p)[index] = mp_obj_get_float(val_in); break; #endif +#if MICROPY_NONSTANDARD_TYPECODES // Extension to CPython: array of objects case 'O': ((mp_obj_t*)p)[index] = val_in; break; - default: +#endif + default: { + size_t size = mp_binary_get_size('@', typecode, NULL); + bool signed_type = is_signed(typecode); + #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE if (MP_OBJ_IS_TYPE(val_in, &mp_type_int)) { - size_t size = mp_binary_get_size('@', typecode, NULL); + // It's a long int. + mp_obj_int_buffer_overflow_check(val_in, size, signed_type); mp_obj_int_to_bytes_impl(val_in, MP_ENDIANNESS_BIG, size, (uint8_t*)p + index * size); return; } #endif - mp_binary_set_val_array_from_int(typecode, p, index, mp_obj_get_int(val_in)); + mp_int_t val = mp_obj_get_int(val_in); + // Small int checking is separate, to be fast. + mp_small_int_buffer_overflow_check(val, size, signed_type); + mp_binary_set_val_array_from_int(typecode, p, index, val); + } } } @@ -350,6 +379,8 @@ void mp_binary_set_val_array_from_int(char typecode, void *p, mp_uint_t index, m case 'B': ((unsigned char*)p)[index] = val; break; + case 'x': + ((unsigned char*)p)[index] = 0; case 'h': ((short*)p)[index] = val; break; @@ -384,9 +415,11 @@ void mp_binary_set_val_array_from_int(char typecode, void *p, mp_uint_t index, m ((double*)p)[index] = val; break; #endif +#if MICROPY_NONSTANDARD_TYPECODES // Extension to CPython: array of pointers case 'P': ((void**)p)[index] = (void*)(uintptr_t)val; break; +#endif } } diff --git a/py/builtinevex.c b/py/builtinevex.c index 846603f46b4..cb046b40764 100644 --- a/py/builtinevex.c +++ b/py/builtinevex.c @@ -31,6 +31,8 @@ #include "py/runtime.h" #include "py/builtin.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_BUILTINS_COMPILE typedef struct _mp_obj_code_t { @@ -94,7 +96,7 @@ STATIC mp_obj_t mp_builtin_compile(size_t n_args, const mp_obj_t *args) { case MP_QSTR_exec: parse_input_kind = MP_PARSE_FILE_INPUT; break; case MP_QSTR_eval: parse_input_kind = MP_PARSE_EVAL_INPUT; break; default: - mp_raise_ValueError("bad compile mode"); + mp_raise_ValueError(translate("bad compile mode")); } mp_obj_code_t *code = m_new_obj(mp_obj_code_t); diff --git a/py/builtinhelp.c b/py/builtinhelp.c index 6c2c3b92c03..9a3407a16fc 100644 --- a/py/builtinhelp.c +++ b/py/builtinhelp.c @@ -27,7 +27,9 @@ #include #include +#include "genhdr/mpversion.h" #include "py/builtin.h" +#include "py/mpconfig.h" #include "py/objmodule.h" #if MICROPY_PY_BUILTINS_HELP @@ -75,6 +77,16 @@ STATIC void mp_help_add_from_names(mp_obj_t list, const char *name) { } #endif +// These externs were originally declared inside mp_help_print_modules(), +// but they triggered -Wnested-externs, so they were moved outside. +#if MICROPY_MODULE_FROZEN_STR +extern const char mp_frozen_str_names[]; +#endif + +#if MICROPY_MODULE_FROZEN_MPY +extern const char mp_frozen_mpy_names[]; +#endif + STATIC void mp_help_print_modules(void) { mp_obj_t list = mp_obj_new_list(0, NULL); @@ -85,12 +97,10 @@ STATIC void mp_help_print_modules(void) { #endif #if MICROPY_MODULE_FROZEN_STR - extern const char mp_frozen_str_names[]; mp_help_add_from_names(list, mp_frozen_str_names); #endif #if MICROPY_MODULE_FROZEN_MPY - extern const char mp_frozen_mpy_names[]; mp_help_add_from_names(list, mp_frozen_mpy_names); #endif @@ -124,7 +134,10 @@ STATIC void mp_help_print_modules(void) { } // let the user know there may be other modules available from the filesystem - mp_print_str(MP_PYTHON_PRINTER, "Plus any modules on the filesystem\n"); + const compressed_string_t* compressed = translate("Plus any modules on the filesystem\n"); + char decompressed[compressed->length]; + decompress(compressed, decompressed); + mp_print_str(MP_PYTHON_PRINTER, decompressed); } #endif @@ -165,8 +178,12 @@ STATIC void mp_help_print_obj(const mp_obj_t obj) { STATIC mp_obj_t mp_builtin_help(size_t n_args, const mp_obj_t *args) { if (n_args == 0) { - // print a general help message - mp_print_str(MP_PYTHON_PRINTER, MICROPY_PY_BUILTINS_HELP_TEXT); + // print a general help message. Translate only works on single strings on one line. + const compressed_string_t* compressed = + translate("Welcome to Adafruit CircuitPython %s!\n\nPlease visit learn.adafruit.com/category/circuitpython for project guides.\n\nTo list built-in modules please do `help(\"modules\")`.\n"); + char decompressed[compressed->length]; + decompress(compressed, decompressed); + mp_printf(MP_PYTHON_PRINTER, decompressed, MICROPY_GIT_TAG); } else { // try to print something sensible about the given object mp_help_print_obj(args[0]); diff --git a/py/builtinimport.c b/py/builtinimport.c index b8ed096cafa..6ed0a759405 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -30,12 +30,16 @@ #include #include "py/compile.h" +#include "py/gc_long_lived.h" +#include "py/gc.h" #include "py/objmodule.h" #include "py/persistentcode.h" #include "py/runtime.h" #include "py/builtin.h" #include "py/frozenmod.h" +#include "supervisor/shared/translate.h" + #if MICROPY_DEBUG_VERBOSE // print debugging info #define DEBUG_PRINT (1) #define DEBUG_printf DEBUG_printf @@ -58,9 +62,13 @@ bool mp_obj_is_package(mp_obj_t module) { // (whatever is available, if at all). STATIC mp_import_stat_t mp_import_stat_any(const char *path) { #if MICROPY_MODULE_FROZEN - mp_import_stat_t st = mp_frozen_stat(path); - if (st != MP_IMPORT_STAT_NO_EXIST) { - return st; + if (strncmp(MP_FROZEN_FAKE_DIR_SLASH, + path, + MP_FROZEN_FAKE_DIR_SLASH_LENGTH) == 0) { + mp_import_stat_t st = mp_frozen_stat(path + MP_FROZEN_FAKE_DIR_SLASH_LENGTH); + if (st != MP_IMPORT_STAT_NO_EXIST) { + return st; + } } #endif return mp_import_stat(path); @@ -114,6 +122,7 @@ STATIC mp_import_stat_t find_file(const char *file_str, uint file_len, vstr_t *d vstr_reset(dest); size_t p_len; const char *p = mp_obj_str_get_data(path_items[i], &p_len); + DEBUG_printf("Looking in path: %d =%s=\n", i, p); if (p_len > 0) { vstr_add_strn(dest, p, p_len); vstr_add_char(dest, PATH_SEP_CHAR); @@ -141,15 +150,14 @@ STATIC void do_load_from_lexer(mp_obj_t module_obj, mp_lexer_t *lex) { // parse, compile and execute the module in its context mp_obj_dict_t *mod_globals = mp_obj_module_get_globals(module_obj); mp_parse_compile_execute(lex, MP_PARSE_FILE_INPUT, mod_globals, mod_globals); + mp_obj_module_set_globals(module_obj, make_dict_long_lived(mod_globals, 10)); } #endif #if MICROPY_PERSISTENT_CODE_LOAD || MICROPY_MODULE_FROZEN_MPY -STATIC void do_execute_raw_code(mp_obj_t module_obj, mp_raw_code_t *raw_code) { +STATIC void do_execute_raw_code(mp_obj_t module_obj, mp_raw_code_t *raw_code, const char *filename) { #if MICROPY_PY___FILE__ - // TODO - //qstr source_name = lex->source_name; - //mp_store_attr(module_obj, MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); + mp_store_attr(module_obj, MP_QSTR___file__, MP_OBJ_NEW_QSTR(qstr_from_str(filename))); #endif // execute the module in its context @@ -170,6 +178,8 @@ STATIC void do_execute_raw_code(mp_obj_t module_obj, mp_raw_code_t *raw_code) { // finish nlr block, restore context nlr_pop(); + mp_obj_module_set_globals(module_obj, + make_dict_long_lived(mp_obj_module_get_globals(module_obj), 10)); mp_globals_set(old_globals); mp_locals_set(old_locals); } else { @@ -186,37 +196,44 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { char *file_str = vstr_null_terminated_str(file); #endif - // If we support frozen modules (either as str or mpy) then try to find the - // requested filename in the list of frozen module filenames. - #if MICROPY_MODULE_FROZEN - void *modref; - int frozen_type = mp_find_frozen_module(file_str, file->len, &modref); - #endif + #if MICROPY_MODULE_FROZEN || MICROPY_MODULE_FROZEN_MPY + if (strncmp(MP_FROZEN_FAKE_DIR_SLASH, + file_str, + MP_FROZEN_FAKE_DIR_SLASH_LENGTH) == 0) { + // If we support frozen modules (either as str or mpy) then try to find the + // requested filename in the list of frozen module filenames. + #if MICROPY_MODULE_FROZEN + void *modref; + int frozen_type = mp_find_frozen_module(file_str + MP_FROZEN_FAKE_DIR_SLASH_LENGTH, file->len - MP_FROZEN_FAKE_DIR_SLASH_LENGTH, &modref); + #endif - // If we support frozen str modules and the compiler is enabled, and we - // found the filename in the list of frozen files, then load and execute it. - #if MICROPY_MODULE_FROZEN_STR - if (frozen_type == MP_FROZEN_STR) { - do_load_from_lexer(module_obj, modref); - return; - } - #endif + // If we support frozen str modules and the compiler is enabled, and we + // found the filename in the list of frozen files, then load and execute it. + #if MICROPY_MODULE_FROZEN_STR + if (frozen_type == MP_FROZEN_STR) { + do_load_from_lexer(module_obj, modref); + return; + } + #endif + + // If we support frozen mpy modules and we found a corresponding file (and + // its data) in the list of frozen files, execute it. + #if MICROPY_MODULE_FROZEN_MPY + if (frozen_type == MP_FROZEN_MPY) { + do_execute_raw_code(module_obj, modref, file_str); + return; + } + #endif - // If we support frozen mpy modules and we found a corresponding file (and - // its data) in the list of frozen files, execute it. - #if MICROPY_MODULE_FROZEN_MPY - if (frozen_type == MP_FROZEN_MPY) { - do_execute_raw_code(module_obj, modref); - return; } - #endif + #endif // MICROPY_MODULE_FROZEN || MICROPY_MODULE_FROZEN_MPY // If we support loading .mpy files then check if the file extension is of // the correct format and, if so, load and execute the file. #if MICROPY_PERSISTENT_CODE_LOAD if (file_str[file->len - 3] == 'm') { mp_raw_code_t *raw_code = mp_raw_code_load_file(file_str); - do_execute_raw_code(module_obj, raw_code); + do_execute_raw_code(module_obj, raw_code, file_str); return; } #endif @@ -231,7 +248,7 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { #else // If we get here then the file was not frozen and we can't compile scripts. - mp_raise_msg(&mp_type_ImportError, "script compilation not supported"); + mp_raise_ImportError(translate("script compilation not supported")); #endif } @@ -316,7 +333,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { // We must have some component left over to import from if (p == this_name) { - mp_raise_ValueError("cannot perform relative import"); + mp_raise_ValueError(translate("cannot perform relative import")); } uint new_mod_l = (mod_len == 0 ? (size_t)(p - this_name) : (size_t)(p - this_name) + 1 + mod_len); @@ -372,6 +389,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { mp_import_stat_t stat; if (vstr_len(&path) == 0) { // first module in the dotted-name; search for a directory or file + DEBUG_printf("Find file =%.*s=\n", vstr_len(&path), vstr_str(&path)); stat = find_file(mod_str, i, &path); } else { // latter module in the dotted-name; append to path @@ -399,10 +417,10 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { #endif // couldn't find the file, so fail if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_ImportError, "module not found"); + mp_raise_ImportError(translate("module not found")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError, - "no module named '%q'", mod_name)); + mp_raise_msg_varg(&mp_type_ImportError, + translate("no module named '%q'"), mod_name); } } } else { @@ -455,10 +473,18 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { // (the module that was just loaded) is not a package. This will be caught // on the next iteration because the file will not exist. } + + // Loading a module thrashes the heap significantly so we explicitly clean up + // afterwards. + gc_collect(); } if (outer_module_obj != MP_OBJ_NULL) { qstr s = qstr_from_strn(mod_str + last, i - last); mp_store_attr(outer_module_obj, s, module_obj); + // The above store can cause a dictionary rehash and new allocation. So, + // lets make sure the globals dictionary is still long lived. + mp_obj_module_set_globals(outer_module_obj, + make_dict_long_lived(mp_obj_module_get_globals(outer_module_obj), 10)); } outer_module_obj = module_obj; if (top_module_obj == MP_OBJ_NULL) { @@ -481,7 +507,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { // Check that it's not a relative import if (n_args >= 5 && MP_OBJ_SMALL_INT_VALUE(args[4]) != 0) { - mp_raise_NotImplementedError("relative import"); + mp_raise_NotImplementedError(translate("relative import")); } // Check if module already exists, and return it if it does @@ -503,10 +529,10 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { // Couldn't find the module, so fail if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_ImportError, "module not found"); + mp_raise_msg(&mp_type_ImportError, translate("module not found")); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError, - "no module named '%q'", module_name_qstr)); + translate("no module named '%q'"), module_name_qstr)); } } diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk new file mode 100644 index 00000000000..b17c312f7be --- /dev/null +++ b/py/circuitpy_defns.mk @@ -0,0 +1,405 @@ +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# Copyright (c) 2019 Dan Halbert for Adafruit Industries +# +# 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. + +# Common Makefile definitions that can be shared across CircuitPython ports. + +### +# Common compile warnings. + +BASE_CFLAGS = \ + -fsingle-precision-constant \ + -fno-strict-aliasing \ + -Wdouble-promotion \ + -Wno-endif-labels \ + -Wstrict-prototypes \ + -Werror-implicit-function-declaration \ + -Wfloat-equal \ + -Wundef \ + -Wshadow \ + -Wwrite-strings \ + -Wsign-compare \ + -Wmissing-format-attribute \ + -Wno-deprecated-declarations \ + -Wnested-externs \ + -Wunreachable-code \ + -Wcast-align \ + -Wno-error=lto-type-mismatch \ + -D__$(CHIP_VARIANT)__ \ + -ffunction-sections \ + -fdata-sections \ + -fshort-enums \ + -DCIRCUITPY_SOFTWARE_SAFE_MODE=0x0ADABEEF \ + -DCIRCUITPY_CANARY_WORD=0xADAF00 \ + -DCIRCUITPY_SAFE_RESTART_WORD=0xDEADBEEF \ + --param max-inline-insns-single=500 + +# Use these flags to debug build times and header includes. +# -ftime-report +# -H + + +### +# Handle frozen modules. + +ifneq ($(FROZEN_DIR),) +# To use frozen source modules, put your .py files in a subdirectory (eg scripts/) +# and then invoke make with FROZEN_DIR=scripts (be sure to build from scratch). +CFLAGS += -DMICROPY_MODULE_FROZEN_STR +CFLAGS += -Wno-error=lto-type-mismatch +endif + +# To use frozen bytecode, put your .py files in a subdirectory (eg frozen/) and +# then invoke make with FROZEN_MPY_DIR=frozen or FROZEN_MPY_DIRS="dir1 dir2" +# (be sure to build from scratch). + +ifneq ($(FROZEN_MPY_DIRS),) +CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool +CFLAGS += -DMICROPY_MODULE_FROZEN_MPY +CFLAGS += -Wno-error=lto-type-mismatch +endif + + +### +# Propagate longint choice from .mk to C. There's no easy string comparison +# in cpp conditionals, so we #define separate names for each. +ifeq ($(LONGINT_IMPL),NONE) +CFLAGS += -DLONGINT_IMPL_NONE +endif + +ifeq ($(LONGINT_IMPL),MPZ) +CFLAGS += -DLONGINT_IMPL_MPZ +endif + +ifeq ($(LONGINT_IMPL),LONGLONG) +CFLAGS += -DLONGINT_IMPL_LONGLONG +endif + + +### +# Select which builtin modules to compile and include. + +ifeq ($(CIRCUITPY_ANALOGIO),1) +SRC_PATTERNS += analogio/% +endif +ifeq ($(CIRCUITPY_AUDIOBUSIO),1) +SRC_PATTERNS += audiobusio/% +endif +ifeq ($(CIRCUITPY_AUDIOIO),1) +SRC_PATTERNS += audioio/% +endif +ifeq ($(CIRCUITPY_AUDIOPWMIO),1) +SRC_PATTERNS += audiopwmio/% +endif +ifeq ($(CIRCUITPY_AUDIOCORE),1) +SRC_PATTERNS += audiocore/% +endif +ifeq ($(CIRCUITPY_BITBANGIO),1) +SRC_PATTERNS += bitbangio/% +endif +# Some builds need bitbang SPI for the dotstar but don't make bitbangio available so include it separately. +ifeq ($(CIRCUITPY_BITBANG_APA102),1) +SRC_PATTERNS += bitbangio/SPI% +endif +ifeq ($(CIRCUITPY_BLEIO),1) +SRC_PATTERNS += _bleio/% +endif +ifeq ($(CIRCUITPY_BOARD),1) +SRC_PATTERNS += board/% +endif +ifeq ($(CIRCUITPY_BUSIO),1) +SRC_PATTERNS += busio/% bitbangio/OneWire.% +endif +ifeq ($(CIRCUITPY_DIGITALIO),1) +SRC_PATTERNS += digitalio/% +endif +ifeq ($(CIRCUITPY_DISPLAYIO),1) +SRC_PATTERNS += displayio/% terminalio/% fontio/% +endif +ifeq ($(CIRCUITPY_FREQUENCYIO),1) +SRC_PATTERNS += frequencyio/% +endif +ifeq ($(CIRCUITPY_GAMEPAD),1) +SRC_PATTERNS += gamepad/% +endif +ifeq ($(CIRCUITPY_GAMEPADSHIFT),1) +SRC_PATTERNS += gamepadshift/% +endif +ifeq ($(CIRCUITPY_I2CSLAVE),1) +SRC_PATTERNS += i2cslave/% +endif +ifeq ($(CIRCUITPY_MATH),1) +SRC_PATTERNS += math/% +endif +ifeq ($(CIRCUITPY_MICROCONTROLLER),1) +SRC_PATTERNS += microcontroller/% +endif +ifeq ($(CIRCUITPY_NEOPIXEL_WRITE),1) +SRC_PATTERNS += neopixel_write/% +endif +ifeq ($(CIRCUITPY_NETWORK),1) +SRC_PATTERNS += network/% socket/% +endif +ifeq ($(CIRCUITPY_NVM),1) +SRC_PATTERNS += nvm/% +endif +ifeq ($(CIRCUITPY_OS),1) +SRC_PATTERNS += os/% +endif +ifeq ($(CIRCUITPY_PIXELBUF),1) +SRC_PATTERNS += _pixelbuf/% +endif +ifeq ($(CIRCUITPY_PULSEIO),1) +SRC_PATTERNS += pulseio/% +endif +ifeq ($(CIRCUITPY_PS2IO),1) +SRC_PATTERNS += ps2io/% +endif +ifeq ($(CIRCUITPY_RANDOM),1) +SRC_PATTERNS += random/% +endif +ifeq ($(CIRCUITPY_ROTARYIO),1) +SRC_PATTERNS += rotaryio/% +endif +ifeq ($(CIRCUITPY_RTC),1) +SRC_PATTERNS += rtc/% +endif +ifeq ($(CIRCUITPY_SAMD),1) +SRC_PATTERNS += samd/% +endif +ifeq ($(CIRCUITPY_STAGE),1) +SRC_PATTERNS += _stage/% +endif +ifeq ($(CIRCUITPY_STORAGE),1) +SRC_PATTERNS += storage/% +endif +ifeq ($(CIRCUITPY_STRUCT),1) +SRC_PATTERNS += struct/% +endif +ifeq ($(CIRCUITPY_SUPERVISOR),1) +SRC_PATTERNS += supervisor/% +endif +ifeq ($(CIRCUITPY_TIME),1) +SRC_PATTERNS += time/% +endif +ifeq ($(CIRCUITPY_TOUCHIO),1) +SRC_PATTERNS += touchio/% +endif +ifeq ($(CIRCUITPY_UHEAP),1) +SRC_PATTERNS += uheap/% +endif +ifeq ($(CIRCUITPY_USB_HID),1) +SRC_PATTERNS += usb_hid/% +endif +ifeq ($(CIRCUITPY_USB_MIDI),1) +SRC_PATTERNS += usb_midi/% +endif +ifeq ($(CIRCUITPY_USTACK),1) +SRC_PATTERNS += ustack/% +endif +ifeq ($(CIRCUITPY_PEW),1) +SRC_PATTERNS += _pew/% +endif + +# All possible sources are listed here, and are filtered by SRC_PATTERNS in SRC_COMMON_HAL +SRC_COMMON_HAL_ALL = \ + _bleio/__init__.c \ + _bleio/Adapter.c \ + _bleio/Attribute.c \ + _bleio/Central.c \ + _bleio/Characteristic.c \ + _bleio/CharacteristicBuffer.c \ + _bleio/Descriptor.c \ + _bleio/Peripheral.c \ + _bleio/Scanner.c \ + _bleio/Service.c \ + _bleio/UUID.c \ + analogio/AnalogIn.c \ + analogio/AnalogOut.c \ + analogio/__init__.c \ + audiobusio/__init__.c \ + audiobusio/I2SOut.c \ + audiobusio/PDMIn.c \ + audiopwmio/__init__.c \ + audiopwmio/PWMAudioOut.c \ + audioio/__init__.c \ + audioio/AudioOut.c \ + board/__init__.c \ + busio/I2C.c \ + busio/SPI.c \ + busio/UART.c \ + busio/__init__.c \ + digitalio/DigitalInOut.c \ + digitalio/__init__.c \ + displayio/ParallelBus.c \ + frequencyio/__init__.c \ + frequencyio/FrequencyIn.c \ + i2cslave/I2CSlave.c \ + i2cslave/__init__.c \ + microcontroller/Pin.c \ + microcontroller/Processor.c \ + microcontroller/__init__.c \ + neopixel_write/__init__.c \ + nvm/ByteArray.c \ + nvm/__init__.c \ + os/__init__.c \ + pulseio/PWMOut.c \ + pulseio/PulseIn.c \ + pulseio/PulseOut.c \ + pulseio/__init__.c \ + ps2io/Ps2.c \ + ps2io/__init__.c \ + rotaryio/IncrementalEncoder.c \ + rotaryio/__init__.c \ + rtc/RTC.c \ + rtc/__init__.c \ + supervisor/Runtime.c \ + supervisor/__init__.c \ + time/__init__.c + +SRC_COMMON_HAL = $(filter $(SRC_PATTERNS), $(SRC_COMMON_HAL_ALL)) + +# These don't have corresponding files in each port but are still located in +# shared-bindings to make it clear what the contents of the modules are. +# All possible sources are listed here, and are filtered by SRC_PATTERNS. +SRC_BINDINGS_ENUMS = \ +$(filter $(SRC_PATTERNS), \ + _bleio/Address.c \ + _bleio/Attribute.c \ + _bleio/ScanEntry.c \ + digitalio/Direction.c \ + digitalio/DriveMode.c \ + digitalio/Pull.c \ + fontio/Glyph.c \ + microcontroller/RunMode.c \ + math/__init__.c \ + supervisor/__init__.c \ +) + +SRC_BINDINGS_ENUMS += \ + help.c \ + util.c + +SRC_SHARED_MODULE_ALL = \ + _bleio/Address.c \ + _bleio/Attribute.c \ + _bleio/ScanEntry.c \ + _pixelbuf/PixelBuf.c \ + _pixelbuf/__init__.c \ + _stage/Layer.c \ + _stage/Text.c \ + _stage/__init__.c \ + audiopwmio/__init__.c \ + audioio/__init__.c \ + audiocore/__init__.c \ + audiocore/Mixer.c \ + audiocore/RawSample.c \ + audiocore/WaveFile.c \ + bitbangio/I2C.c \ + bitbangio/OneWire.c \ + bitbangio/SPI.c \ + bitbangio/__init__.c \ + board/__init__.c \ + busio/OneWire.c \ + displayio/Bitmap.c \ + displayio/ColorConverter.c \ + displayio/Display.c \ + displayio/EPaperDisplay.c \ + displayio/FourWire.c \ + displayio/Group.c \ + displayio/I2CDisplay.c \ + displayio/OnDiskBitmap.c \ + displayio/Palette.c \ + displayio/Shape.c \ + displayio/TileGrid.c \ + displayio/__init__.c \ + fontio/BuiltinFont.c \ + fontio/__init__.c \ + gamepad/GamePad.c \ + gamepad/__init__.c \ + gamepadshift/GamePadShift.c \ + gamepadshift/__init__.c \ + os/__init__.c \ + random/__init__.c \ + socket/__init__.c \ + network/__init__.c \ + storage/__init__.c \ + struct/__init__.c \ + terminalio/Terminal.c \ + terminalio/__init__.c \ + uheap/__init__.c \ + ustack/__init__.c \ + _pew/__init__.c \ + _pew/PewPew.c + +# All possible sources are listed here, and are filtered by SRC_PATTERNS. +SRC_SHARED_MODULE = $(filter $(SRC_PATTERNS), $(SRC_SHARED_MODULE_ALL)) + +# Use the native touchio if requested. This flag is set conditionally in, say, mpconfigport.h. +# The presence of common-hal/touchio/* # does not imply it's available for all chips in a port, +# so there is an explicit flag. For example, SAMD21 touchio is native, but SAMD51 is not. +ifeq ($(CIRCUITPY_TOUCHIO_USE_NATIVE),1) +SRC_COMMON_HAL_ALL += \ + touchio/TouchIn.c \ + touchio/__init__.c +else +SRC_SHARED_MODULE_ALL += \ + touchio/TouchIn.c \ + touchio/__init__.c +endif + +# All possible sources are listed here, and are filtered by SRC_PATTERNS. +SRC_SHARED_MODULE_INTERNAL = \ +$(filter $(SRC_PATTERNS), \ + displayio/display_core.c \ +) + +ifeq ($(INTERNAL_LIBM),1) +SRC_LIBM = \ +$(addprefix lib/,\ + libm/math.c \ + libm/roundf.c \ + libm/fmodf.c \ + libm/nearbyintf.c \ + libm/ef_sqrt.c \ + libm/kf_rem_pio2.c \ + libm/kf_sin.c \ + libm/kf_cos.c \ + libm/kf_tan.c \ + libm/ef_rem_pio2.c \ + libm/sf_sin.c \ + libm/sf_cos.c \ + libm/sf_tan.c \ + libm/sf_frexp.c \ + libm/sf_modf.c \ + libm/sf_ldexp.c \ + libm/asinfacosf.c \ + libm/atanf.c \ + libm/atan2f.c \ + ) +endif + +.PHONY: check-release-needs-clean-build + +check-release-needs-clean-build: + @echo "RELEASE_NEEDS_CLEAN_BUILD = $(RELEASE_NEEDS_CLEAN_BUILD)" diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h new file mode 100644 index 00000000000..5ac66665a44 --- /dev/null +++ b/py/circuitpy_mpconfig.h @@ -0,0 +1,660 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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. + */ + +// This file contains settings that are common across CircuitPython ports, to make +// sure that the same feature set and settings are used, such as in atmel-samd +// and nrf. + +#include + +#ifndef __INCLUDED_MPCONFIG_CIRCUITPY_H +#define __INCLUDED_MPCONFIG_CIRCUITPY_H + +// This is CircuitPython. +#define CIRCUITPY 1 + +// REPR_C encodes qstrs, 31-bit ints, and 30-bit floats in a single 32-bit word. +#define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_C) + +// options to control how MicroPython is built +// TODO(tannewt): Reduce this number if we want the REPL to function under 512 +// free bytes. +// #define MICROPY_ALLOC_PARSE_RULE_INIT (64) + +// Sorted alphabetically for easy finding. +// +// default is 128; consider raising to reduce fragmentation. +#define MICROPY_ALLOC_PARSE_CHUNK_INIT (16) +// default is 512. +#define MICROPY_ALLOC_PATH_MAX (256) +#define MICROPY_CAN_OVERRIDE_BUILTINS (1) +#define MICROPY_COMP_CONST (1) +#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (1) +#define MICROPY_COMP_MODULE_CONST (1) +#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (0) +#define MICROPY_DEBUG_PRINTERS (0) +#define MICROPY_EMIT_INLINE_THUMB (0) +#define MICROPY_EMIT_THUMB (0) +#define MICROPY_EMIT_X64 (0) +#define MICROPY_ENABLE_DOC_STRING (0) +#define MICROPY_ENABLE_FINALISER (1) +#define MICROPY_ENABLE_GC (1) +#define MICROPY_ENABLE_SOURCE_LINE (1) +#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_NORMAL) +#define MICROPY_FLOAT_HIGH_QUALITY_HASH (0) +#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) +#define MICROPY_GC_ALLOC_THRESHOLD (0) +#define MICROPY_HELPER_LEXER_UNIX (0) +#define MICROPY_HELPER_REPL (1) +#define MICROPY_KBD_EXCEPTION (1) +#define MICROPY_MEM_STATS (0) +#define MICROPY_NONSTANDARD_TYPECODES (0) +#define MICROPY_OPT_COMPUTED_GOTO (1) +#define MICROPY_PERSISTENT_CODE_LOAD (1) + +#define MICROPY_PY_ARRAY (1) +#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) +#define MICROPY_PY_ASYNC_AWAIT (0) +#define MICROPY_PY_ATTRTUPLE (1) + +#define MICROPY_PY_BUILTINS_BYTEARRAY (1) +#define MICROPY_PY_BUILTINS_ENUMERATE (1) +#define MICROPY_PY_BUILTINS_FILTER (1) +#define MICROPY_PY_BUILTINS_HELP (1) +#define MICROPY_PY_BUILTINS_HELP_MODULES (1) +#define MICROPY_PY_BUILTINS_INPUT (1) +#define MICROPY_PY_BUILTINS_MEMORYVIEW (1) +#define MICROPY_PY_BUILTINS_MIN_MAX (1) +#define MICROPY_PY_BUILTINS_PROPERTY (1) +#define MICROPY_PY_BUILTINS_REVERSED (1) +#define MICROPY_PY_BUILTINS_ROUND_INT (1) +#define MICROPY_PY_BUILTINS_SET (1) +#define MICROPY_PY_BUILTINS_SLICE (1) +#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) +#define MICROPY_PY_BUILTINS_STR_UNICODE (1) + +#define MICROPY_PY_CMATH (0) +#define MICROPY_PY_COLLECTIONS (1) +#define MICROPY_PY_DESCRIPTORS (1) +#define MICROPY_PY_IO_FILEIO (1) +#define MICROPY_PY_GC (1) +// Supplanted by shared-bindings/math +#define MICROPY_PY_MATH (0) +#define MICROPY_PY_MICROPYTHON_MEM_INFO (0) +// Supplanted by shared-bindings/struct +#define MICROPY_PY_STRUCT (0) +#define MICROPY_PY_SYS (1) +#define MICROPY_PY_SYS_MAXSIZE (1) +#define MICROPY_PY_SYS_STDFILES (1) +// Supplanted by shared-bindings/random +#define MICROPY_PY_URANDOM (0) +#define MICROPY_PY_URANDOM_EXTRA_FUNCS (0) +#define MICROPY_PY___FILE__ (1) + +#define MICROPY_QSTR_BYTES_IN_HASH (1) +#define MICROPY_REPL_AUTO_INDENT (1) +#define MICROPY_REPL_EVENT_DRIVEN (0) +#define MICROPY_STACK_CHECK (1) +#define MICROPY_STREAMS_NON_BLOCK (1) +#define MICROPY_USE_INTERNAL_PRINTF (1) + +// fatfs configuration used in ffconf.h +// +// 1 = SFN/ANSI 437=LFN/U.S.(OEM) +#define MICROPY_FATFS_ENABLE_LFN (1) +#define MICROPY_FATFS_LFN_CODE_PAGE (437) +#define MICROPY_FATFS_USE_LABEL (1) +#define MICROPY_FATFS_RPATH (2) +#define MICROPY_FATFS_MULTI_PARTITION (1) + +// Only enable this if you really need it. It allocates a byte cache of this size. +// #define MICROPY_FATFS_MAX_SS (4096) + +#define FILESYSTEM_BLOCK_SIZE (512) + +#define MICROPY_VFS (1) +#define MICROPY_VFS_FAT (MICROPY_VFS) +#define MICROPY_READER_VFS (MICROPY_VFS) + + +// type definitions for the specific machine + +#define BYTES_PER_WORD (4) + +#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1)) + +// Track stack usage. Expose results via ustack module. +#define MICROPY_MAX_STACK_USAGE (0) + +// This port is intended to be 32-bit, but unfortunately, int32_t for +// different targets may be defined in different ways - either as int +// or as long. This requires different printf formatting specifiers +// to print such value. So, we avoid int32_t and use int directly. +#define UINT_FMT "%u" +#define INT_FMT "%d" +typedef int mp_int_t; // must be pointer size +typedef unsigned mp_uint_t; // must be pointer size +typedef long mp_off_t; + +#define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len) + +#define mp_type_fileio mp_type_vfs_fat_fileio +#define mp_type_textio mp_type_vfs_fat_textio + +#define mp_import_stat mp_vfs_import_stat +#define mp_builtin_open_obj mp_vfs_open_obj + +// extra built in names to add to the global namespace +#define MICROPY_PORT_BUILTINS \ + { MP_OBJ_NEW_QSTR(MP_QSTR_help), (mp_obj_t)&mp_builtin_help_obj }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_input), (mp_obj_t)&mp_builtin_input_obj }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj }, + +// board specific definitions +#include "mpconfigboard.h" + +// CIRCUITPY_FULL_BUILD is defined in a *.mk file. + +// Remove some lesser-used functionality to make small builds fit. +#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (CIRCUITPY_FULL_BUILD) +#define MICROPY_CPYTHON_COMPAT (CIRCUITPY_FULL_BUILD) +#define MICROPY_MODULE_WEAK_LINKS (CIRCUITPY_FULL_BUILD) +#define MICROPY_PY_ALL_SPECIAL_METHODS (CIRCUITPY_FULL_BUILD) +#define MICROPY_PY_BUILTINS_COMPLEX (CIRCUITPY_FULL_BUILD) +#define MICROPY_PY_BUILTINS_FROZENSET (CIRCUITPY_FULL_BUILD) +#define MICROPY_PY_BUILTINS_STR_CENTER (CIRCUITPY_FULL_BUILD) +#define MICROPY_PY_BUILTINS_STR_PARTITION (CIRCUITPY_FULL_BUILD) +#define MICROPY_PY_BUILTINS_STR_SPLITLINES (CIRCUITPY_FULL_BUILD) +#define MICROPY_PY_UERRNO (CIRCUITPY_FULL_BUILD) +// Opposite setting is deliberate. +#define MICROPY_PY_UERRNO_ERRORCODE (!CIRCUITPY_FULL_BUILD) +#define MICROPY_PY_URE (CIRCUITPY_FULL_BUILD) +#define MICROPY_PY_URE_MATCH_GROUPS (CIRCUITPY_FULL_BUILD) +#define MICROPY_PY_URE_MATCH_SPAN_START_END (CIRCUITPY_FULL_BUILD) +#define MICROPY_PY_URE_SUB (CIRCUITPY_FULL_BUILD) + +// LONGINT_IMPL_xxx are defined in the Makefile. +// +#ifdef LONGINT_IMPL_NONE +#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE) +#endif + +#ifdef LONGINT_IMPL_MPZ +#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) +#define MP_SSIZE_MAX (0x7fffffff) +#endif + +#ifdef LONGINT_IMPL_LONGLONG +#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_LONGLONG) +#define MP_SSIZE_MAX (0x7fffffff) +#endif + + +// These CIRCUITPY_xxx values should all be defined in the *.mk files as being on or off. +// So if any are not defined in *.mk, they'll throw an error here. + +#if CIRCUITPY_ANALOGIO +#define ANALOGIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, +extern const struct _mp_obj_module_t analogio_module; +#else +#define ANALOGIO_MODULE +#endif + +#if CIRCUITPY_AUDIOBUSIO +#define AUDIOBUSIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_audiobusio), (mp_obj_t)&audiobusio_module }, +extern const struct _mp_obj_module_t audiobusio_module; +#else +#define AUDIOBUSIO_MODULE +#endif + +#if CIRCUITPY_AUDIOCORE +#define AUDIOCORE_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_audiocore), (mp_obj_t)&audiocore_module }, +extern const struct _mp_obj_module_t audiocore_module; +#else +#define AUDIOCORE_MODULE +#endif + +#if CIRCUITPY_AUDIOIO +#define AUDIOIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_audioio), (mp_obj_t)&audioio_module }, +extern const struct _mp_obj_module_t audioio_module; +#else +#define AUDIOIO_MODULE +#endif + +#if CIRCUITPY_AUDIOPWMIO +#define AUDIOPWMIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_audiopwmio), (mp_obj_t)&audiopwmio_module }, +extern const struct _mp_obj_module_t audiopwmio_module; +#else +#define AUDIOPWMIO_MODULE +#endif + +#if CIRCUITPY_BITBANGIO +#define BITBANGIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module }, +extern const struct _mp_obj_module_t bitbangio_module; +#else +#define BITBANGIO_MODULE +#endif + +#if CIRCUITPY_BLEIO +#define BLEIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR__bleio), (mp_obj_t)&bleio_module }, +extern const struct _mp_obj_module_t bleio_module; +#else +#define BLEIO_MODULE +#endif + +#if CIRCUITPY_BOARD +#define BOARD_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&board_module }, +extern const struct _mp_obj_module_t board_module; + +#define BOARD_I2C (defined(DEFAULT_I2C_BUS_SDA) && defined(DEFAULT_I2C_BUS_SCL)) +#define BOARD_SPI (defined(DEFAULT_SPI_BUS_SCK) && defined(DEFAULT_SPI_BUS_MISO) && defined(DEFAULT_SPI_BUS_MOSI)) +#define BOARD_UART (defined(DEFAULT_UART_BUS_RX) && defined(DEFAULT_UART_BUS_TX)) + +// I2C and SPI are always allocated off the heap. + +#if BOARD_UART +#define BOARD_UART_ROOT_POINTER mp_obj_t shared_uart_bus; +#else +#define BOARD_UART_ROOT_POINTER +#endif + +#else +#define BOARD_MODULE +#define BOARD_UART_ROOT_POINTER +#endif + +#if CIRCUITPY_BUSIO +extern const struct _mp_obj_module_t busio_module; +#define BUSIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_busio), (mp_obj_t)&busio_module }, +#else +#define BUSIO_MODULE +#endif + +#if CIRCUITPY_DIGITALIO +extern const struct _mp_obj_module_t digitalio_module; +#define DIGITALIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_digitalio), (mp_obj_t)&digitalio_module }, +#else +#define DIGITALIO_MODULE +#endif + +#if CIRCUITPY_DISPLAYIO +extern const struct _mp_obj_module_t displayio_module; +extern const struct _mp_obj_module_t fontio_module; +extern const struct _mp_obj_module_t terminalio_module; +#define DISPLAYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_displayio), (mp_obj_t)&displayio_module }, +#define FONTIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_fontio), (mp_obj_t)&fontio_module }, +#define TERMINALIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_terminalio), (mp_obj_t)&terminalio_module }, +#define CIRCUITPY_DISPLAY_LIMIT (1) +#else +#define DISPLAYIO_MODULE +#define FONTIO_MODULE +#define TERMINALIO_MODULE +#define CIRCUITPY_DISPLAY_LIMIT (0) +#endif + +#if CIRCUITPY_FREQUENCYIO +extern const struct _mp_obj_module_t frequencyio_module; +#define FREQUENCYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_frequencyio), (mp_obj_t)&frequencyio_module }, +#else +#define FREQUENCYIO_MODULE +#endif + +#if CIRCUITPY_GAMEPAD +extern const struct _mp_obj_module_t gamepad_module; +#define GAMEPAD_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_gamepad),(mp_obj_t)&gamepad_module }, +#else +#define GAMEPAD_MODULE +#endif + +#if CIRCUITPY_GAMEPADSHIFT +extern const struct _mp_obj_module_t gamepadshift_module; +#define GAMEPADSHIFT_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_gamepadshift),(mp_obj_t)&gamepadshift_module }, +#else +#define GAMEPADSHIFT_MODULE +#endif + +#if CIRCUITPY_GAMEPAD || CIRCUITPY_GAMEPADSHIFT +// Scan gamepad every 32ms +#define CIRCUITPY_GAMEPAD_TICKS 0x1f +#define GAMEPAD_ROOT_POINTERS mp_obj_t gamepad_singleton; +#else +#define GAMEPAD_ROOT_POINTERS +#endif + +#if CIRCUITPY_I2CSLAVE +extern const struct _mp_obj_module_t i2cslave_module; +#define I2CSLAVE_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_i2cslave), (mp_obj_t)&i2cslave_module }, +#else +#define I2CSLAVE_MODULE +#endif + +#if CIRCUITPY_MATH +extern const struct _mp_obj_module_t math_module; +#define MATH_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, +#else +#define MATH_MODULE +#endif + +#if CIRCUITPY_MICROCONTROLLER +extern const struct _mp_obj_module_t microcontroller_module; +#define MICROCONTROLLER_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)µcontroller_module }, +#else +#define MICROCONTROLLER_MODULE +#endif + +#if CIRCUITPY_NEOPIXEL_WRITE +extern const struct _mp_obj_module_t neopixel_write_module; +#define NEOPIXEL_WRITE_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write),(mp_obj_t)&neopixel_write_module }, +#else +#define NEOPIXEL_WRITE_MODULE +#endif + +#if CIRCUITPY_NETWORK +extern const struct _mp_obj_module_t network_module; +extern const struct _mp_obj_module_t socket_module; +#define NETWORK_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_network), (mp_obj_t)&network_module }, +#define SOCKET_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&socket_module }, +#define NETWORK_ROOT_POINTERS mp_obj_list_t mod_network_nic_list; +#if MICROPY_PY_WIZNET5K + extern const struct _mp_obj_module_t wiznet_module; + #define WIZNET_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_wiznet), (mp_obj_t)&wiznet_module }, +#endif +#else +#define NETWORK_MODULE +#define SOCKET_MODULE +#define WIZNET_MODULE +#define NETWORK_ROOT_POINTERS +#endif + +// This is not a top-level module; it's microcontroller.nvm. +#if CIRCUITPY_NVM +extern const struct _mp_obj_module_t nvm_module; +#endif + +#if CIRCUITPY_OS +extern const struct _mp_obj_module_t os_module; +#define OS_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_os), (mp_obj_t)&os_module }, +#define OS_MODULE_ALT_NAME { MP_OBJ_NEW_QSTR(MP_QSTR__os), (mp_obj_t)&os_module }, +#else +#define OS_MODULE +#define OS_MODULE_ALT_NAME +#endif + +#if CIRCUITPY_PEW +extern const struct _mp_obj_module_t pew_module; +#define PEW_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR__pew),(mp_obj_t)&pew_module }, +#else +#define PEW_MODULE +#endif + +#if CIRCUITPY_PIXELBUF +extern const struct _mp_obj_module_t pixelbuf_module; +#define PIXELBUF_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR__pixelbuf),(mp_obj_t)&pixelbuf_module }, +#else +#define PIXELBUF_MODULE +#endif + +#if CIRCUITPY_PULSEIO +extern const struct _mp_obj_module_t pulseio_module; +#define PULSEIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module }, +#else +#define PULSEIO_MODULE +#endif + +#if CIRCUITPY_PS2IO +extern const struct _mp_obj_module_t ps2io_module; +#define PS2IO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_ps2io), (mp_obj_t)&ps2io_module }, +#else +#define PS2IO_MODULE +#endif + +#if CIRCUITPY_RANDOM +extern const struct _mp_obj_module_t random_module; +#define RANDOM_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_random), (mp_obj_t)&random_module }, +#else +#define RANDOM_MODULE +#endif + +#if CIRCUITPY_ROTARYIO +extern const struct _mp_obj_module_t rotaryio_module; +#define ROTARYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_rotaryio), (mp_obj_t)&rotaryio_module }, +#else +#define ROTARYIO_MODULE +#endif + +#if CIRCUITPY_RTC +extern const struct _mp_obj_module_t rtc_module; +#define RTC_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_rtc), (mp_obj_t)&rtc_module }, +#else +#define RTC_MODULE +#endif + +#if CIRCUITPY_SAMD +extern const struct _mp_obj_module_t samd_module; +#define SAMD_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_samd),(mp_obj_t)&samd_module }, +#else +#define SAMD_MODULE +#endif + +#if CIRCUITPY_STAGE +extern const struct _mp_obj_module_t stage_module; +#define STAGE_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR__stage), (mp_obj_t)&stage_module }, +#else +#define STAGE_MODULE +#endif + +#if CIRCUITPY_STORAGE +extern const struct _mp_obj_module_t storage_module; +#define STORAGE_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_storage), (mp_obj_t)&storage_module }, +#else +#define STORAGE_MODULE +#endif + +#if CIRCUITPY_STRUCT +extern const struct _mp_obj_module_t struct_module; +#define STRUCT_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&struct_module }, +#else +#define STRUCT_MODULE +#endif + +#if CIRCUITPY_SUPERVISOR +extern const struct _mp_obj_module_t supervisor_module; +#define SUPERVISOR_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_supervisor), (mp_obj_t)&supervisor_module }, +#else +#define SUPERVISOR_MODULE +#endif + +#if CIRCUITPY_TIME +extern const struct _mp_obj_module_t time_module; +#define TIME_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, +#define TIME_MODULE_ALT_NAME { MP_OBJ_NEW_QSTR(MP_QSTR__time), (mp_obj_t)&time_module }, +#else +#define TIME_MODULE +#define TIME_MODULE_ALT_NAME +#endif + +#if CIRCUITPY_TOUCHIO +extern const struct _mp_obj_module_t touchio_module; +#define TOUCHIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_touchio), (mp_obj_t)&touchio_module }, +#else +#define TOUCHIO_MODULE +#endif + +#if CIRCUITPY_UHEAP +extern const struct _mp_obj_module_t uheap_module; +#define UHEAP_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_uheap),(mp_obj_t)&uheap_module }, +#else +#define UHEAP_MODULE +#endif + +#if CIRCUITPY_USB_HID +extern const struct _mp_obj_module_t usb_hid_module; +#define USB_HID_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, +#else +#define USB_HID_MODULE +#endif + +#if CIRCUITPY_USB_MIDI +extern const struct _mp_obj_module_t usb_midi_module; +#define USB_MIDI_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_usb_midi),(mp_obj_t)&usb_midi_module }, +#else +#define USB_MIDI_MODULE +#endif + +#if CIRCUITPY_USTACK +extern const struct _mp_obj_module_t ustack_module; +#define USTACK_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_ustack),(mp_obj_t)&ustack_module }, +#else +#define USTACK_MODULE +#endif + +// These modules are not yet in shared-bindings, but we prefer the non-uxxx names. +#if MICROPY_PY_UERRNO +#define ERRNO_MODULE { MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mp_module_uerrno) }, +#else +#define ERRNO_MODULE +#endif + +#if MICROPY_PY_UJSON +#define JSON_MODULE { MP_ROM_QSTR(MP_QSTR_json), MP_ROM_PTR(&mp_module_ujson) }, +#else +#define JSON_MODULE +#endif + +#if MICROPY_PY_URE +#define RE_MODULE { MP_ROM_QSTR(MP_QSTR_re), MP_ROM_PTR(&mp_module_ure) }, +#else +#define RE_MODULE +#endif + +// Define certain native modules with weak links so they can be replaced with Python +// implementations. This list may grow over time. +#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \ + OS_MODULE \ + TIME_MODULE \ + +// Native modules that are weak links can be accessed directly +// by prepending their name with an underscore. This list should correspond to +// MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS, assuming you want the native modules +// to be accessible when overriden. +#define MICROPY_PORT_BUILTIN_MODULE_ALT_NAMES \ + OS_MODULE_ALT_NAME \ + TIME_MODULE_ALT_NAME \ + +// This is an inclusive list that should correspond to the CIRCUITPY_XXX list above, +// including dependencies such as TERMINALIO depending on DISPLAYIO (shown by indentation). +// Some of these definitions will be blank depending on what is turned on and off. +// Some are omitted because they're in MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS above. +#define MICROPY_PORT_BUILTIN_MODULES_STRONG_LINKS \ + ANALOGIO_MODULE \ + AUDIOBUSIO_MODULE \ + AUDIOCORE_MODULE \ + AUDIOIO_MODULE \ + AUDIOPWMIO_MODULE \ + BITBANGIO_MODULE \ + BLEIO_MODULE \ + BOARD_MODULE \ + BUSIO_MODULE \ + DIGITALIO_MODULE \ + DISPLAYIO_MODULE \ + FONTIO_MODULE \ + TERMINALIO_MODULE \ + ERRNO_MODULE \ + FREQUENCYIO_MODULE \ + GAMEPAD_MODULE \ + GAMEPADSHIFT_MODULE \ + I2CSLAVE_MODULE \ + JSON_MODULE \ + MATH_MODULE \ + MICROCONTROLLER_MODULE \ + NEOPIXEL_WRITE_MODULE \ + NETWORK_MODULE \ + SOCKET_MODULE \ + WIZNET_MODULE \ + PEW_MODULE \ + PIXELBUF_MODULE \ + PS2IO_MODULE \ + PULSEIO_MODULE \ + RANDOM_MODULE \ + RE_MODULE \ + ROTARYIO_MODULE \ + RTC_MODULE \ + SAMD_MODULE \ + STAGE_MODULE \ + STORAGE_MODULE \ + STRUCT_MODULE \ + SUPERVISOR_MODULE \ + TOUCHIO_MODULE \ + UHEAP_MODULE \ + USB_HID_MODULE \ + USB_MIDI_MODULE \ + USTACK_MODULE \ + +// If weak links are enabled, just include strong links in the main list of modules, +// and also include the underscore alternate names. +#if MICROPY_MODULE_WEAK_LINKS +#define MICROPY_PORT_BUILTIN_MODULES \ + MICROPY_PORT_BUILTIN_MODULES_STRONG_LINKS \ + MICROPY_PORT_BUILTIN_MODULE_ALT_NAMES +#else +// If weak links are disabled, included both strong and potentially weak lines +#define MICROPY_PORT_BUILTIN_MODULES \ + MICROPY_PORT_BUILTIN_MODULES_STRONG_LINKS \ + MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS +#endif + +// We need to provide a declaration/definition of alloca() +#include + +#define MP_STATE_PORT MP_STATE_VM + +#include "supervisor/flash_root_pointers.h" + +#define CIRCUITPY_COMMON_ROOT_POINTERS \ + const char *readline_hist[8]; \ + vstr_t *repl_line; \ + mp_obj_t rtc_time_source; \ + GAMEPAD_ROOT_POINTERS \ + mp_obj_t pew_singleton; \ + mp_obj_t terminal_tilegrid_tiles; \ + BOARD_UART_ROOT_POINTER \ + FLASH_ROOT_POINTERS \ + NETWORK_ROOT_POINTERS \ + +void run_background_tasks(void); +#define RUN_BACKGROUND_TASKS (run_background_tasks()) + +// TODO: Used in wiznet5k driver, but may not be needed in the long run. +#define MICROPY_THREAD_YIELD() + +#define MICROPY_VM_HOOK_LOOP run_background_tasks(); +#define MICROPY_VM_HOOK_RETURN run_background_tasks(); + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 +#define CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS 1000 +#define CIRCUITPY_BOOT_OUTPUT_FILE "/boot_out.txt" + +#endif // __INCLUDED_MPCONFIG_CIRCUITPY_H diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk new file mode 100644 index 00000000000..1af71a41622 --- /dev/null +++ b/py/circuitpy_mpconfig.mk @@ -0,0 +1,286 @@ +# +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# Copyright (c) 2019 Dan Halbert for Adafruit Industries +# +# 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. + + +# mpconfigboard.mk files can specify: +# CIRCUITPY_FULL_BUILD = 1 (which is the default) +# or +# CIRCUITPY_SMALL_BUILD = 1 +# which is the same as: +# CIRCUITPY_FULL_BUILD = 0 + +ifndef CIRCUITPY_FULL_BUILD + ifeq ($(CIRCUITPY_SMALL_BUILD),1) + CIRCUITPY_FULL_BUILD = 0 + CFLAGS += -DCIRCUITPY_FULL_BUILD=0 + else + CIRCUITPY_FULL_BUILD = 1 + CFLAGS += -DCIRCUITPY_FULL_BUILD=1 + endif +endif + +# Setting CIRCUITPY_MINIMAL_BUILD = 1 will disable all features +# Use for for early stage or highly restricted ports +ifndef CIRCUITPY_DEFAULT_BUILD + ifeq ($(CIRCUITPY_MINIMAL_BUILD),1) + CIRCUITPY_FULL_BUILD = 0 + CIRCUITPY_DEFAULT_BUILD = 0 + else + CIRCUITPY_DEFAULT_BUILD = 1 + endif +endif + + + +# All builtin modules are listed below, with default values (0 for off, 1 for on) +# Some are always on, some are always off, and some depend on CIRCUITPY_FULL_BUILD. +# +# *** You can override any of the defaults by defining them in your mpconfigboard.mk. + +ifndef CIRCUITPY_ANALOGIO +CIRCUITPY_ANALOGIO = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_ANALOGIO=$(CIRCUITPY_ANALOGIO) + +ifndef CIRCUITPY_AUDIOBUSIO +CIRCUITPY_AUDIOBUSIO = $(CIRCUITPY_FULL_BUILD) +endif +CFLAGS += -DCIRCUITPY_AUDIOBUSIO=$(CIRCUITPY_AUDIOBUSIO) + +ifndef CIRCUITPY_AUDIOIO +CIRCUITPY_AUDIOIO = $(CIRCUITPY_FULL_BUILD) +endif +CFLAGS += -DCIRCUITPY_AUDIOIO=$(CIRCUITPY_AUDIOIO) + +ifndef CIRCUITPY_AUDIOIO_COMPAT +CIRCUITPY_AUDIOIO_COMPAT = $(CIRCUITPY_AUDIOIO) +endif +CFLAGS += -DCIRCUITPY_AUDIOIO_COMPAT=$(CIRCUITPY_AUDIOIO_COMPAT) + + +ifndef CIRCUITPY_AUDIOPWMIO +CIRCUITPY_AUDIOPWMIO = 0 +endif +CFLAGS += -DCIRCUITPY_AUDIOPWMIO=$(CIRCUITPY_AUDIOPWMIO) + +ifndef CIRCUITPY_AUDIOCORE +ifeq ($(CIRCUITPY_AUDIOPWMIO),1) +CIRCUITPY_AUDIOCORE = $(CIRCUITPY_AUDIOPWMIO) +else +CIRCUITPY_AUDIOCORE = $(CIRCUITPY_AUDIOIO) +endif +endif +CFLAGS += -DCIRCUITPY_AUDIOCORE=$(CIRCUITPY_AUDIOCORE) + +ifndef CIRCUITPY_BITBANGIO +CIRCUITPY_BITBANGIO = $(CIRCUITPY_FULL_BUILD) +endif +CFLAGS += -DCIRCUITPY_BITBANGIO=$(CIRCUITPY_BITBANGIO) + +# Explicitly enabled for boards that support _bleio. +ifndef CIRCUITPY_BLEIO +CIRCUITPY_BLEIO = 0 +endif +CFLAGS += -DCIRCUITPY_BLEIO=$(CIRCUITPY_BLEIO) + +ifndef CIRCUITPY_BOARD +CIRCUITPY_BOARD = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_BOARD=$(CIRCUITPY_BOARD) + +ifndef CIRCUITPY_BUSIO +CIRCUITPY_BUSIO = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_BUSIO=$(CIRCUITPY_BUSIO) + +ifndef CIRCUITPY_DIGITALIO +CIRCUITPY_DIGITALIO = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_DIGITALIO=$(CIRCUITPY_DIGITALIO) + +ifndef CIRCUITPY_DISPLAYIO +CIRCUITPY_DISPLAYIO = $(CIRCUITPY_FULL_BUILD) +endif +CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO) + +ifndef CIRCUITPY_FREQUENCYIO +CIRCUITPY_FREQUENCYIO = $(CIRCUITPY_FULL_BUILD) +endif +CFLAGS += -DCIRCUITPY_FREQUENCYIO=$(CIRCUITPY_FREQUENCYIO) + +ifndef CIRCUITPY_GAMEPAD +CIRCUITPY_GAMEPAD = $(CIRCUITPY_FULL_BUILD) +endif +CFLAGS += -DCIRCUITPY_GAMEPAD=$(CIRCUITPY_GAMEPAD) + +ifndef CIRCUITPY_GAMEPADSHIFT +CIRCUITPY_GAMEPADSHIFT = 0 +endif +CFLAGS += -DCIRCUITPY_GAMEPADSHIFT=$(CIRCUITPY_GAMEPADSHIFT) + +ifndef CIRCUITPY_I2CSLAVE +CIRCUITPY_I2CSLAVE = $(CIRCUITPY_FULL_BUILD) +endif +CFLAGS += -DCIRCUITPY_I2CSLAVE=$(CIRCUITPY_I2CSLAVE) + +ifndef CIRCUITPY_MATH +CIRCUITPY_MATH = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH) + +ifndef CIRCUITPY_MICROCONTROLLER +CIRCUITPY_MICROCONTROLLER = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_MICROCONTROLLER=$(CIRCUITPY_MICROCONTROLLER) + +ifndef CIRCUITPY_NEOPIXEL_WRITE +CIRCUITPY_NEOPIXEL_WRITE = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_NEOPIXEL_WRITE=$(CIRCUITPY_NEOPIXEL_WRITE) + +# Only certain boards support NETWORK (Ethernet) +ifndef CIRCUITPY_NETWORK +CIRCUITPY_NETWORK = 0 +endif +CFLAGS += -DCIRCUITPY_NETWORK=$(CIRCUITPY_NETWORK) + +ifndef CIRCUITPY_NVM +CIRCUITPY_NVM = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_NVM=$(CIRCUITPY_NVM) + +ifndef CIRCUITPY_OS +CIRCUITPY_OS = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_OS=$(CIRCUITPY_OS) + +ifndef CIRCUITPY_PIXELBUF +CIRCUITPY_PIXELBUF = $(CIRCUITPY_FULL_BUILD) +endif +CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF) + +ifndef CIRCUITPY_PULSEIO +CIRCUITPY_PULSEIO = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_PULSEIO=$(CIRCUITPY_PULSEIO) + +# Only for SAMD boards for the moment +ifndef CIRCUITPY_PS2IO +CIRCUITPY_PS2IO = 0 +endif +CFLAGS += -DCIRCUITPY_PS2IO=$(CIRCUITPY_PS2IO) + +ifndef CIRCUITPY_RANDOM +CIRCUITPY_RANDOM = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_RANDOM=$(CIRCUITPY_RANDOM) + +ifndef CIRCUITPY_ROTARYIO +CIRCUITPY_ROTARYIO = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_ROTARYIO=$(CIRCUITPY_ROTARYIO) + +ifndef CIRCUITPY_RTC +CIRCUITPY_RTC = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_RTC=$(CIRCUITPY_RTC) + +# CIRCUITPY_SAMD is handled in the atmel-samd tree. +# Only for SAMD chips. +# Assume not a SAMD build. +ifndef CIRCUITPY_SAMD +CIRCUITPY_SAMD = 0 +endif +CFLAGS += -DCIRCUITPY_SAMD=$(CIRCUITPY_SAMD) + +# Currently always off. +ifndef CIRCUITPY_STAGE +CIRCUITPY_STAGE = 0 +endif +CFLAGS += -DCIRCUITPY_STAGE=$(CIRCUITPY_STAGE) + +ifndef CIRCUITPY_STORAGE +CIRCUITPY_STORAGE = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_STORAGE=$(CIRCUITPY_STORAGE) + +ifndef CIRCUITPY_STRUCT +CIRCUITPY_STRUCT = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_STRUCT=$(CIRCUITPY_STRUCT) + +ifndef CIRCUITPY_SUPERVISOR +CIRCUITPY_SUPERVISOR = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_SUPERVISOR=$(CIRCUITPY_SUPERVISOR) + +ifndef CIRCUITPY_TIME +CIRCUITPY_TIME = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_TIME=$(CIRCUITPY_TIME) + +# touchio might be native or generic. See circuitpy_defns.mk. +ifndef CIRCUITPY_TOUCHIO_USE_NATIVE +CIRCUITPY_TOUCHIO_USE_NATIVE = 0 +endif +CFLAGS += -DCIRCUITPY_TOUCHIO_USE_NATIVE=$(CIRCUITPY_TOUCHIO_USE_NATIVE) + +ifndef CIRCUITPY_TOUCHIO +CIRCUITPY_TOUCHIO = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_TOUCHIO=$(CIRCUITPY_TOUCHIO) + +# For debugging. +ifndef CIRCUITPY_UHEAP +CIRCUITPY_UHEAP = 0 +endif +CFLAGS += -DCIRCUITPY_UHEAP=$(CIRCUITPY_UHEAP) + +ifndef CIRCUITPY_USB_HID +CIRCUITPY_USB_HID = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_USB_HID=$(CIRCUITPY_USB_HID) + +ifndef CIRCUITPY_USB_MIDI +CIRCUITPY_USB_MIDI = $(CIRCUITPY_DEFAULT_BUILD) +endif +CFLAGS += -DCIRCUITPY_USB_MIDI=$(CIRCUITPY_USB_MIDI) + +ifndef CIRCUITPY_PEW +CIRCUITPY_PEW = 0 +endif +CFLAGS += -DCIRCUITPY_PEW=$(CIRCUITPY_PEW) + +# For debugging. +ifndef CIRCUITPY_USTACK +CIRCUITPY_USTACK = 0 +endif +CFLAGS += -DCIRCUITPY_USTACK=$(CIRCUITPY_USTACK) + + +ifndef CIRCUITPY_BITBANG_APA102 +CIRCUITPY_BITBANG_APA102 = 0 +endif +CFLAGS += -DCIRCUITPY_BITBANG_APA102=$(CIRCUITPY_BITBANG_APA102) diff --git a/py/compile.c b/py/compile.c index 7daf9110351..1218aa07e5f 100644 --- a/py/compile.c +++ b/py/compile.c @@ -36,6 +36,8 @@ #include "py/runtime.h" #include "py/asmbase.h" +#include "supervisor/shared/translate.h" + #if MICROPY_ENABLE_COMPILER // TODO need to mangle __attr names @@ -154,7 +156,7 @@ STATIC void compile_error_set_line(compiler_t *comp, mp_parse_node_t pn) { } } -STATIC void compile_syntax_error(compiler_t *comp, mp_parse_node_t pn, const char *msg) { +STATIC void compile_syntax_error(compiler_t *comp, mp_parse_node_t pn, const compressed_string_t *msg) { // only register the error if there has been no other error if (comp->compile_error == MP_OBJ_NULL) { comp->compile_error = mp_obj_new_exception_msg(&mp_type_SyntaxError, msg); @@ -392,7 +394,7 @@ STATIC void c_assign_atom_expr(compiler_t *comp, mp_parse_node_struct_t *pns, as } } - compile_syntax_error(comp, (mp_parse_node_t)pns, "can't assign to expression"); + compile_syntax_error(comp, (mp_parse_node_t)pns, translate("can't assign to expression")); } // we need to allow for a caller passing in 1 initial node (node_head) followed by an array of nodes (nodes_tail) @@ -411,7 +413,7 @@ STATIC void c_assign_tuple(compiler_t *comp, mp_parse_node_t node_head, uint num EMIT_ARG(unpack_ex, num_head + i, num_tail - i - 1); have_star_index = num_head + i; } else { - compile_syntax_error(comp, nodes_tail[i], "multiple *x in assignment"); + compile_syntax_error(comp, nodes_tail[i], translate("multiple *x in assignment")); return; } } @@ -537,7 +539,7 @@ STATIC void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_ return; cannot_assign: - compile_syntax_error(comp, pn, "can't assign to expression"); + compile_syntax_error(comp, pn, translate("can't assign to expression")); } // stuff for lambda and comprehensions and generators: @@ -637,7 +639,7 @@ STATIC void compile_funcdef_lambdef_param(compiler_t *comp, mp_parse_node_t pn) // check for non-default parameters given after default parameters (allowed by parser, but not syntactically valid) if (!comp->have_star && comp->num_default_params != 0) { - compile_syntax_error(comp, pn, "non-default argument follows default argument"); + compile_syntax_error(comp, pn, translate("non-default argument follows default argument")); return; } @@ -766,7 +768,7 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_ } if (name_len != 2) { - compile_syntax_error(comp, name_nodes[0], "invalid micropython decorator"); + compile_syntax_error(comp, name_nodes[0], translate("invalid micropython decorator")); return true; } @@ -784,7 +786,7 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_ *emit_options = MP_EMIT_OPT_ASM; #endif } else { - compile_syntax_error(comp, name_nodes[1], "invalid micropython decorator"); + compile_syntax_error(comp, name_nodes[1], translate("invalid micropython decorator")); } return true; @@ -938,7 +940,7 @@ STATIC void c_del_stmt(compiler_t *comp, mp_parse_node_t pn) { return; cannot_delete: - compile_syntax_error(comp, (mp_parse_node_t)pn, "can't delete expression"); + compile_syntax_error(comp, (mp_parse_node_t)pn, translate("can't delete expression")); } STATIC void compile_del_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { @@ -947,13 +949,13 @@ STATIC void compile_del_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { STATIC void compile_break_cont_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { uint16_t label; - const char *error_msg; + const compressed_string_t *error_msg; if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_break_stmt) { label = comp->break_label; - error_msg = "'break' outside loop"; + error_msg = translate("'break' outside loop"); } else { label = comp->continue_label; - error_msg = "'continue' outside loop"; + error_msg = translate("'continue' outside loop"); } if (label == INVALID_LABEL) { compile_syntax_error(comp, (mp_parse_node_t)pns, error_msg); @@ -964,7 +966,7 @@ STATIC void compile_break_cont_stmt(compiler_t *comp, mp_parse_node_struct_t *pn STATIC void compile_return_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { if (comp->scope_cur->kind != SCOPE_FUNCTION) { - compile_syntax_error(comp, (mp_parse_node_t)pns, "'return' outside function"); + compile_syntax_error(comp, (mp_parse_node_t)pns, translate("'return' outside function")); return; } if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { @@ -1164,7 +1166,7 @@ STATIC void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) { STATIC void compile_declare_global(compiler_t *comp, mp_parse_node_t pn, qstr qst, bool added, id_info_t *id_info) { if (!added && id_info->kind != ID_INFO_KIND_GLOBAL_EXPLICIT) { - compile_syntax_error(comp, pn, "identifier redefined as global"); + compile_syntax_error(comp, pn, translate("identifier redefined as global")); return; } id_info->kind = ID_INFO_KIND_GLOBAL_EXPLICIT; @@ -1180,10 +1182,10 @@ STATIC void compile_declare_nonlocal(compiler_t *comp, mp_parse_node_t pn, qstr if (added) { scope_find_local_and_close_over(comp->scope_cur, id_info, qst); if (id_info->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) { - compile_syntax_error(comp, pn, "no binding for nonlocal found"); + compile_syntax_error(comp, pn, translate("no binding for nonlocal found")); } } else if (id_info->kind != ID_INFO_KIND_FREE) { - compile_syntax_error(comp, pn, "identifier redefined as nonlocal"); + compile_syntax_error(comp, pn, translate("identifier redefined as nonlocal")); } } @@ -1192,7 +1194,7 @@ STATIC void compile_global_nonlocal_stmt(compiler_t *comp, mp_parse_node_struct_ bool is_global = MP_PARSE_NODE_STRUCT_KIND(pns) == PN_global_stmt; if (!is_global && comp->scope_cur->kind == SCOPE_MODULE) { - compile_syntax_error(comp, (mp_parse_node_t)pns, "can't declare nonlocal in outer code"); + compile_syntax_error(comp, (mp_parse_node_t)pns, translate("can't declare nonlocal in outer code")); return; } @@ -1537,7 +1539,7 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_ if (MP_PARSE_NODE_IS_NULL(pns_except->nodes[0])) { // this is a catch all exception handler if (i + 1 != n_except) { - compile_syntax_error(comp, pn_excepts[i], "default 'except' must be last"); + compile_syntax_error(comp, pn_excepts[i], translate("default 'except' must be last")); compile_decrease_except_level(comp); return; } @@ -2090,7 +2092,7 @@ STATIC void compile_comparison(compiler_t *comp, mp_parse_node_struct_t *pns) { } STATIC void compile_star_expr(compiler_t *comp, mp_parse_node_struct_t *pns) { - compile_syntax_error(comp, (mp_parse_node_t)pns, "*x must be assignment target"); + compile_syntax_error(comp, (mp_parse_node_t)pns, translate("*x must be assignment target")); } STATIC void compile_binary_op(compiler_t *comp, mp_parse_node_struct_t *pns) { @@ -2188,7 +2190,7 @@ STATIC void compile_atom_expr_normal(compiler_t *comp, mp_parse_node_struct_t *p } if (!found) { compile_syntax_error(comp, (mp_parse_node_t)pns_trail[0], - "super() can't find self"); // really a TypeError + translate("super() can't find self")); // really a TypeError return; } @@ -2251,14 +2253,14 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar mp_parse_node_struct_t *pns_arg = (mp_parse_node_struct_t*)args[i]; if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_arglist_star) { if (star_flags & MP_EMIT_STAR_FLAG_SINGLE) { - compile_syntax_error(comp, (mp_parse_node_t)pns_arg, "can't have multiple *x"); + compile_syntax_error(comp, (mp_parse_node_t)pns_arg, translate("can't have multiple *x")); return; } star_flags |= MP_EMIT_STAR_FLAG_SINGLE; star_args_node = pns_arg; } else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_arglist_dbl_star) { if (star_flags & MP_EMIT_STAR_FLAG_DOUBLE) { - compile_syntax_error(comp, (mp_parse_node_t)pns_arg, "can't have multiple **x"); + compile_syntax_error(comp, (mp_parse_node_t)pns_arg, translate("can't have multiple **x")); return; } star_flags |= MP_EMIT_STAR_FLAG_DOUBLE; @@ -2266,7 +2268,7 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar } else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_argument) { if (!MP_PARSE_NODE_IS_STRUCT_KIND(pns_arg->nodes[1], PN_comp_for)) { if (!MP_PARSE_NODE_IS_ID(pns_arg->nodes[0])) { - compile_syntax_error(comp, (mp_parse_node_t)pns_arg, "LHS of keyword arg must be an id"); + compile_syntax_error(comp, (mp_parse_node_t)pns_arg, translate("LHS of keyword arg must be an id")); return; } EMIT_ARG(load_const_str, MP_PARSE_NODE_LEAF_ARG(pns_arg->nodes[0])); @@ -2282,11 +2284,11 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar } else { normal_argument: if (star_flags) { - compile_syntax_error(comp, args[i], "non-keyword arg after */**"); + compile_syntax_error(comp, args[i], translate("non-keyword arg after */**")); return; } if (n_keyword > 0) { - compile_syntax_error(comp, args[i], "non-keyword arg after keyword arg"); + compile_syntax_error(comp, args[i], translate("non-keyword arg after keyword arg")); return; } compile_node(comp, args[i]); @@ -2458,9 +2460,9 @@ STATIC void compile_atom_brace(compiler_t *comp, mp_parse_node_struct_t *pns) { if (is_dict) { if (!is_key_value) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - compile_syntax_error(comp, (mp_parse_node_t)pns, "invalid syntax"); + compile_syntax_error(comp, (mp_parse_node_t)pns, translate("invalid syntax")); } else { - compile_syntax_error(comp, (mp_parse_node_t)pns, "expecting key:value for dict"); + compile_syntax_error(comp, (mp_parse_node_t)pns, translate("expecting key:value for dict")); } return; } @@ -2468,9 +2470,9 @@ STATIC void compile_atom_brace(compiler_t *comp, mp_parse_node_struct_t *pns) { } else { if (is_key_value) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - compile_syntax_error(comp, (mp_parse_node_t)pns, "invalid syntax"); + compile_syntax_error(comp, (mp_parse_node_t)pns, translate("invalid syntax")); } else { - compile_syntax_error(comp, (mp_parse_node_t)pns, "expecting just a value for set"); + compile_syntax_error(comp, (mp_parse_node_t)pns, translate("expecting just a value for set")); } return; } @@ -2595,7 +2597,7 @@ STATIC void compile_classdef(compiler_t *comp, mp_parse_node_struct_t *pns) { STATIC void compile_yield_expr(compiler_t *comp, mp_parse_node_struct_t *pns) { if (comp->scope_cur->kind != SCOPE_FUNCTION && comp->scope_cur->kind != SCOPE_LAMBDA) { - compile_syntax_error(comp, (mp_parse_node_t)pns, "'yield' outside function"); + compile_syntax_error(comp, (mp_parse_node_t)pns, translate("'yield' outside function")); return; } if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { @@ -2614,7 +2616,7 @@ STATIC void compile_yield_expr(compiler_t *comp, mp_parse_node_struct_t *pns) { #if MICROPY_PY_ASYNC_AWAIT STATIC void compile_atom_expr_await(compiler_t *comp, mp_parse_node_struct_t *pns) { if (comp->scope_cur->kind != SCOPE_FUNCTION && comp->scope_cur->kind != SCOPE_LAMBDA) { - compile_syntax_error(comp, (mp_parse_node_t)pns, "'await' outside function"); + compile_syntax_error(comp, (mp_parse_node_t)pns, translate("'await' outside function")); return; } compile_atom_expr_normal(comp, pns); @@ -2707,7 +2709,7 @@ STATIC void compile_node(compiler_t *comp, mp_parse_node_t pn) { STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn, pn_kind_t pn_name, pn_kind_t pn_star, pn_kind_t pn_dbl_star) { // check that **kw is last if ((comp->scope_cur->scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) { - compile_syntax_error(comp, pn, "invalid syntax"); + compile_syntax_error(comp, pn, translate("invalid syntax")); return; } @@ -2737,7 +2739,7 @@ STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == pn_star) { if (comp->have_star) { // more than one star - compile_syntax_error(comp, pn, "invalid syntax"); + compile_syntax_error(comp, pn, translate("invalid syntax")); return; } comp->have_star = true; @@ -2769,7 +2771,7 @@ STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn bool added; id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, param_name, &added); if (!added) { - compile_syntax_error(comp, pn, "name reused for argument"); + compile_syntax_error(comp, pn, translate("name reused for argument")); return; } id_info->kind = ID_INFO_KIND_LOCAL; @@ -2822,7 +2824,7 @@ STATIC void compile_scope_func_annotations(compiler_t *comp, mp_parse_node_t pn) qstr arg_type = MP_PARSE_NODE_LEAF_ARG(pn_annotation); EMIT_ARG(set_native_type, MP_EMIT_NATIVE_TYPE_ARG, id_info->local_num, arg_type); } else { - compile_syntax_error(comp, pn_annotation, "parameter annotation must be an identifier"); + compile_syntax_error(comp, pn_annotation, translate("parameter annotation must be an identifier")); } } } @@ -2964,7 +2966,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { qstr ret_type = MP_PARSE_NODE_LEAF_ARG(pn_annotation); EMIT_ARG(set_native_type, MP_EMIT_NATIVE_TYPE_RETURN, 0, ret_type); } else { - compile_syntax_error(comp, pn_annotation, "return annotation must be an identifier"); + compile_syntax_error(comp, pn_annotation, translate("return annotation must be an identifier")); } } } @@ -3092,7 +3094,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind comp->next_label = 0; if (scope->kind != SCOPE_FUNCTION) { - compile_syntax_error(comp, MP_PARSE_NODE_NULL, "inline assembler must be a function"); + compile_syntax_error(comp, MP_PARSE_NODE_NULL, translate("inline assembler must be a function")); return; } @@ -3129,10 +3131,10 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind case MP_QSTR_bool: type_sig = MP_NATIVE_TYPE_BOOL; break; case MP_QSTR_int: type_sig = MP_NATIVE_TYPE_INT; break; case MP_QSTR_uint: type_sig = MP_NATIVE_TYPE_UINT; break; - default: compile_syntax_error(comp, pn_annotation, "unknown type"); return; + default: compile_syntax_error(comp, pn_annotation, translate("unknown type")); return; } } else { - compile_syntax_error(comp, pn_annotation, "return annotation must be an identifier"); + compile_syntax_error(comp, pn_annotation, translate("return annotation must be an identifier")); } } @@ -3149,7 +3151,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) != PN_expr_stmt) { // not an instruction; error not_an_instruction: - compile_syntax_error(comp, nodes[i], "expecting an assembler instruction"); + compile_syntax_error(comp, nodes[i], translate("expecting an assembler instruction")); return; } @@ -3179,19 +3181,19 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind // emit instructions if (op == MP_QSTR_label) { if (!(n_args == 1 && MP_PARSE_NODE_IS_ID(pn_arg[0]))) { - compile_syntax_error(comp, nodes[i], "'label' requires 1 argument"); + compile_syntax_error(comp, nodes[i], translate("'label' requires 1 argument")); return; } uint lab = comp_next_label(comp); if (pass > MP_PASS_SCOPE) { if (!EMIT_INLINE_ASM_ARG(label, lab, MP_PARSE_NODE_LEAF_ARG(pn_arg[0]))) { - compile_syntax_error(comp, nodes[i], "label redefined"); + compile_syntax_error(comp, nodes[i], translate("label redefined")); return; } } } else if (op == MP_QSTR_align) { if (!(n_args == 1 && MP_PARSE_NODE_IS_SMALL_INT(pn_arg[0]))) { - compile_syntax_error(comp, nodes[i], "'align' requires 1 argument"); + compile_syntax_error(comp, nodes[i], translate("'align' requires 1 argument")); return; } if (pass > MP_PASS_SCOPE) { @@ -3200,14 +3202,14 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind } } else if (op == MP_QSTR_data) { if (!(n_args >= 2 && MP_PARSE_NODE_IS_SMALL_INT(pn_arg[0]))) { - compile_syntax_error(comp, nodes[i], "'data' requires at least 2 arguments"); + compile_syntax_error(comp, nodes[i], translate("'data' requires at least 2 arguments")); return; } if (pass > MP_PASS_SCOPE) { mp_int_t bytesize = MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0]); for (uint j = 1; j < n_args; j++) { if (!MP_PARSE_NODE_IS_SMALL_INT(pn_arg[j])) { - compile_syntax_error(comp, nodes[i], "'data' requires integer arguments"); + compile_syntax_error(comp, nodes[i], translate("'data' requires integer arguments")); return; } mp_asm_base_data((mp_asm_base_t*)comp->emit_inline_asm, diff --git a/py/emitglue.c b/py/emitglue.c index 74bf8ddca28..7708689dd45 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -142,11 +142,12 @@ mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, mp_obj_t def_ar fun = mp_obj_new_fun_asm(rc->n_pos_args, rc->data.u_native.fun_data, rc->data.u_native.type_sig); break; #endif - default: - // rc->kind should always be set and BYTECODE is the only remaining case - assert(rc->kind == MP_CODE_BYTECODE); + case MP_CODE_BYTECODE: fun = mp_obj_new_fun_bc(def_args, def_kw_args, rc->data.u_byte.bytecode, rc->data.u_byte.const_table); break; + default: + // All other kinds are invalid. + mp_raise_RuntimeError(translate("Corrupt raw code")); } // check for generator functions and if so wrap in generator object diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index 577f6567207..7f0ec66590d 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -59,7 +59,7 @@ struct _emit_inline_asm_t { qstr *label_lookup; }; -STATIC void emit_inline_thumb_error_msg(emit_inline_asm_t *emit, const char *msg) { +STATIC void emit_inline_thumb_error_msg(emit_inline_asm_t *emit, const compressed_string_t *msg) { *emit->error_slot = mp_obj_new_exception_msg(&mp_type_SyntaxError, msg); } @@ -99,17 +99,17 @@ STATIC void emit_inline_thumb_end_pass(emit_inline_asm_t *emit, mp_uint_t type_s STATIC mp_uint_t emit_inline_thumb_count_params(emit_inline_asm_t *emit, mp_uint_t n_params, mp_parse_node_t *pn_params) { if (n_params > 4) { - emit_inline_thumb_error_msg(emit, "can only have up to 4 parameters to Thumb assembly"); + emit_inline_thumb_error_msg(emit, translate("can only have up to 4 parameters to Thumb assembly")); return 0; } for (mp_uint_t i = 0; i < n_params; i++) { if (!MP_PARSE_NODE_IS_ID(pn_params[i])) { - emit_inline_thumb_error_msg(emit, "parameters must be registers in sequence r0 to r3"); + emit_inline_thumb_error_msg(emit, translate("parameters must be registers in sequence r0 to r3")); return 0; } const char *p = qstr_str(MP_PARSE_NODE_LEAF_ARG(pn_params[i])); if (!(strlen(p) == 2 && p[0] == 'r' && p[1] == '0' + i)) { - emit_inline_thumb_error_msg(emit, "parameters must be registers in sequence r0 to r3"); + emit_inline_thumb_error_msg(emit, translate("parameters must be registers in sequence r0 to r3")); return 0; } } @@ -185,7 +185,7 @@ STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, mp_parse_n if (r->reg > max_reg) { emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, - "'%s' expects at most r%d", op, max_reg)); + translate("'%s' expects at most r%d"), op, max_reg)); return 0; } else { return r->reg; @@ -194,7 +194,7 @@ STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, mp_parse_n } emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, - "'%s' expects a register", op)); + translate("'%s' expects a register"), op)); return 0; } @@ -208,7 +208,7 @@ STATIC mp_uint_t get_arg_special_reg(emit_inline_asm_t *emit, const char *op, mp } emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, - "'%s' expects a special register", op)); + translate("'%s' expects a special register"), op)); return 0; } @@ -227,7 +227,7 @@ STATIC mp_uint_t get_arg_vfpreg(emit_inline_asm_t *emit, const char *op, mp_pars if (regno > 31) { emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, - "'%s' expects at most r%d", op, 31)); + translate("'%s' expects at most r%d"), op, 31)); return 0; } else { return regno; @@ -236,7 +236,7 @@ STATIC mp_uint_t get_arg_vfpreg(emit_inline_asm_t *emit, const char *op, mp_pars malformed: emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, - "'%s' expects an FPU register", op)); + translate("'%s' expects an FPU register"), op)); return 0; } #endif @@ -289,19 +289,19 @@ STATIC mp_uint_t get_arg_reglist(emit_inline_asm_t *emit, const char *op, mp_par return reglist; bad_arg: - emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects {r0, r1, ...}", op)); + emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("'%s' expects {r0, r1, ...}"), op)); return 0; } STATIC uint32_t get_arg_i(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn, uint32_t fit_mask) { mp_obj_t o; if (!mp_parse_node_get_int_maybe(pn, &o)) { - emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects an integer", op)); + emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("'%s' expects an integer"), op)); return 0; } uint32_t i = mp_obj_get_int_truncated(o); if ((i & (~fit_mask)) != 0) { - emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' integer 0x%x does not fit in mask 0x%x", op, i, fit_mask)); + emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("'%s' integer 0x%x does not fit in mask 0x%x"), op, i, fit_mask)); return 0; } return i; @@ -325,13 +325,13 @@ STATIC bool get_arg_addr(emit_inline_asm_t *emit, const char *op, mp_parse_node_ return true; bad_arg: - emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects an address of the form [a, b]", op)); + emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("'%s' expects an address of the form [a, b]"), op)); return false; } STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) { if (!MP_PARSE_NODE_IS_ID(pn)) { - emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects a label", op)); + emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("'%s' expects a label"), op)); return 0; } qstr label_qstr = MP_PARSE_NODE_LEAF_ARG(pn); @@ -342,7 +342,7 @@ STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_ } // only need to have the labels on the last pass if (emit->pass == MP_PASS_EMIT) { - emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "label '%q' not defined", label_qstr)); + emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("label '%q' not defined"), label_qstr)); } return 0; } @@ -803,11 +803,11 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a return; unknown_op: - emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "unsupported Thumb instruction '%s' with %d arguments", op_str, n_args)); + emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("unsupported Thumb instruction '%s' with %d arguments"), op_str, n_args)); return; branch_not_in_range: - emit_inline_thumb_error_msg(emit, "branch not in range"); + emit_inline_thumb_error_msg(emit, translate("branch not in range")); return; } diff --git a/py/emitinlinextensa.c b/py/emitinlinextensa.c index 3d3217f5bb6..9cd65824bee 100644 --- a/py/emitinlinextensa.c +++ b/py/emitinlinextensa.c @@ -43,7 +43,7 @@ struct _emit_inline_asm_t { qstr *label_lookup; }; -STATIC void emit_inline_xtensa_error_msg(emit_inline_asm_t *emit, const char *msg) { +STATIC void emit_inline_xtensa_error_msg(emit_inline_asm_t *emit, const compressed_string_t *msg) { *emit->error_slot = mp_obj_new_exception_msg(&mp_type_SyntaxError, msg); } @@ -83,17 +83,17 @@ STATIC void emit_inline_xtensa_end_pass(emit_inline_asm_t *emit, mp_uint_t type_ STATIC mp_uint_t emit_inline_xtensa_count_params(emit_inline_asm_t *emit, mp_uint_t n_params, mp_parse_node_t *pn_params) { if (n_params > 4) { - emit_inline_xtensa_error_msg(emit, "can only have up to 4 parameters to Xtensa assembly"); + emit_inline_xtensa_error_msg(emit, translate("can only have up to 4 parameters to Xtensa assembly")); return 0; } for (mp_uint_t i = 0; i < n_params; i++) { if (!MP_PARSE_NODE_IS_ID(pn_params[i])) { - emit_inline_xtensa_error_msg(emit, "parameters must be registers in sequence a2 to a5"); + emit_inline_xtensa_error_msg(emit, translate("parameters must be registers in sequence a2 to a5")); return 0; } const char *p = qstr_str(MP_PARSE_NODE_LEAF_ARG(pn_params[i])); if (!(strlen(p) == 2 && p[0] == 'a' && p[1] == '2' + i)) { - emit_inline_xtensa_error_msg(emit, "parameters must be registers in sequence a2 to a5"); + emit_inline_xtensa_error_msg(emit, translate("parameters must be registers in sequence a2 to a5")); return 0; } } @@ -159,19 +159,19 @@ STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, mp_parse_n } emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, - "'%s' expects a register", op)); + translate("'%s' expects a register"), op)); return 0; } STATIC uint32_t get_arg_i(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn, int min, int max) { mp_obj_t o; if (!mp_parse_node_get_int_maybe(pn, &o)) { - emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects an integer", op)); + emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("'%s' expects an integer"), op)); return 0; } uint32_t i = mp_obj_get_int_truncated(o); if (min != max && ((int)i < min || (int)i > max)) { - emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' integer %d is not within range %d..%d", op, i, min, max)); + emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("'%s' integer %d is not within range %d..%d"), op, i, min, max)); return 0; } return i; @@ -179,7 +179,7 @@ STATIC uint32_t get_arg_i(emit_inline_asm_t *emit, const char *op, mp_parse_node STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) { if (!MP_PARSE_NODE_IS_ID(pn)) { - emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects a label", op)); + emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("'%s' expects a label"), op)); return 0; } qstr label_qstr = MP_PARSE_NODE_LEAF_ARG(pn); @@ -190,7 +190,7 @@ STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_ } // only need to have the labels on the last pass if (emit->pass == MP_PASS_EMIT) { - emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "label '%q' not defined", label_qstr)); + emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("label '%q' not defined"), label_qstr)); } return 0; } @@ -324,12 +324,12 @@ STATIC void emit_inline_xtensa_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_ return; unknown_op: - emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "unsupported Xtensa instruction '%s' with %d arguments", op_str, n_args)); + emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, translate("unsupported Xtensa instruction '%s' with %d arguments"), op_str, n_args)); return; /* branch_not_in_range: - emit_inline_xtensa_error_msg(emit, "branch not in range"); + emit_inline_xtensa_error_msg(emit, translate("branch not in range")); return; */ } diff --git a/py/emitnative.c b/py/emitnative.c index ad8f04aac70..67b0025c608 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -49,6 +49,8 @@ #include "py/emit.h" #include "py/bc.h" +#include "supervisor/shared/translate.h" + #if MICROPY_DEBUG_VERBOSE // print debugging info #define DEBUG_PRINT (1) #define DEBUG_printf DEBUG_printf @@ -178,7 +180,7 @@ STATIC void emit_native_set_native_type(emit_t *emit, mp_uint_t op, mp_uint_t ar case MP_QSTR_ptr8: type = VTYPE_PTR8; break; case MP_QSTR_ptr16: type = VTYPE_PTR16; break; case MP_QSTR_ptr32: type = VTYPE_PTR32; break; - default: EMIT_NATIVE_VIPER_TYPE_ERROR(emit, "unknown type '%q'", arg2); return; + default: EMIT_NATIVE_VIPER_TYPE_ERROR(emit, translate("unknown type '%q'"), arg2); return; } if (op == MP_EMIT_NATIVE_TYPE_RETURN) { emit->return_vtype = type; @@ -255,7 +257,7 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop // right now we have a restriction of maximum of 4 arguments if (scope->num_pos_args >= 5) { - EMIT_NATIVE_VIPER_TYPE_ERROR(emit, "Viper functions don't currently support more than 4 arguments"); + EMIT_NATIVE_VIPER_TYPE_ERROR(emit, translate("Viper functions don't currently support more than 4 arguments")); return; } @@ -737,7 +739,7 @@ STATIC void emit_get_stack_pointer_to_reg_for_pop(emit_t *emit, mp_uint_t reg_de break; default: // not handled - mp_raise_NotImplementedError("conversion to object"); + mp_raise_NotImplementedError(translate("conversion to object")); } } @@ -916,7 +918,7 @@ STATIC void emit_native_load_fast(emit_t *emit, qstr qst, mp_uint_t local_num) { DEBUG_printf("load_fast(%s, " UINT_FMT ")\n", qstr_str(qst), local_num); vtype_kind_t vtype = emit->local_vtype[local_num]; if (vtype == VTYPE_UNBOUND) { - EMIT_NATIVE_VIPER_TYPE_ERROR(emit, "local '%q' used before type known", qst); + EMIT_NATIVE_VIPER_TYPE_ERROR(emit, translate("local '%q' used before type known"), qst); } emit_native_pre(emit); if (local_num == 0) { @@ -1113,7 +1115,7 @@ STATIC void emit_native_load_subscr(emit_t *emit) { } default: EMIT_NATIVE_VIPER_TYPE_ERROR(emit, - "can't load from '%q'", vtype_to_qstr(vtype_base)); + translate("can't load from '%q'"), vtype_to_qstr(vtype_base)); } } else { // index is not an immediate @@ -1123,7 +1125,7 @@ STATIC void emit_native_load_subscr(emit_t *emit) { emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1); if (vtype_index != VTYPE_INT && vtype_index != VTYPE_UINT) { EMIT_NATIVE_VIPER_TYPE_ERROR(emit, - "can't load with '%q' index", vtype_to_qstr(vtype_index)); + translate("can't load with '%q' index"), vtype_to_qstr(vtype_index)); } switch (vtype_base) { case VTYPE_PTR8: { @@ -1151,7 +1153,7 @@ STATIC void emit_native_load_subscr(emit_t *emit) { } default: EMIT_NATIVE_VIPER_TYPE_ERROR(emit, - "can't load from '%q'", vtype_to_qstr(vtype_base)); + translate("can't load from '%q'"), vtype_to_qstr(vtype_base)); } } emit_post_push_reg(emit, VTYPE_INT, REG_RET); @@ -1183,7 +1185,7 @@ STATIC void emit_native_store_fast(emit_t *emit, qstr qst, mp_uint_t local_num) } else if (emit->local_vtype[local_num] != vtype) { // type of local is not the same as object stored in it EMIT_NATIVE_VIPER_TYPE_ERROR(emit, - "local '%q' has type '%q' but source is '%q'", + translate("local '%q' has type '%q' but source is '%q'"), qst, vtype_to_qstr(emit->local_vtype[local_num]), vtype_to_qstr(vtype)); } } @@ -1284,7 +1286,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) { #endif if (vtype_value != VTYPE_BOOL && vtype_value != VTYPE_INT && vtype_value != VTYPE_UINT) { EMIT_NATIVE_VIPER_TYPE_ERROR(emit, - "can't store '%q'", vtype_to_qstr(vtype_value)); + translate("can't store '%q'"), vtype_to_qstr(vtype_value)); } switch (vtype_base) { case VTYPE_PTR8: { @@ -1353,7 +1355,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) { } default: EMIT_NATIVE_VIPER_TYPE_ERROR(emit, - "can't store to '%q'", vtype_to_qstr(vtype_base)); + translate("can't store to '%q'"), vtype_to_qstr(vtype_base)); } } else { // index is not an immediate @@ -1364,7 +1366,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) { emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1); if (vtype_index != VTYPE_INT && vtype_index != VTYPE_UINT) { EMIT_NATIVE_VIPER_TYPE_ERROR(emit, - "can't store with '%q' index", vtype_to_qstr(vtype_index)); + translate("can't store with '%q' index"), vtype_to_qstr(vtype_index)); } #if N_X86 // special case: x86 needs byte stores to be from lower 4 regs (REG_ARG_3 is EDX) @@ -1374,7 +1376,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) { #endif if (vtype_value != VTYPE_BOOL && vtype_value != VTYPE_INT && vtype_value != VTYPE_UINT) { EMIT_NATIVE_VIPER_TYPE_ERROR(emit, - "can't store '%q'", vtype_to_qstr(vtype_value)); + translate("can't store '%q'"), vtype_to_qstr(vtype_value)); } switch (vtype_base) { case VTYPE_PTR8: { @@ -1414,7 +1416,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) { } default: EMIT_NATIVE_VIPER_TYPE_ERROR(emit, - "can't store to '%q'", vtype_to_qstr(vtype_base)); + translate("can't store to '%q'"), vtype_to_qstr(vtype_base)); } } @@ -1535,7 +1537,7 @@ STATIC void emit_native_jump_helper(emit_t *emit, bool pop) { } if (!(vtype == VTYPE_BOOL || vtype == VTYPE_INT || vtype == VTYPE_UINT)) { EMIT_NATIVE_VIPER_TYPE_ERROR(emit, - "can't implicitly convert '%q' to 'bool'", vtype_to_qstr(vtype)); + translate("can't implicitly convert '%q' to 'bool'"), vtype_to_qstr(vtype)); } } // For non-pop need to save the vtype so that emit_native_adjust_stack_size @@ -1769,7 +1771,7 @@ STATIC void emit_native_unary_op(emit_t *emit, mp_unary_op_t op) { } else { adjust_stack(emit, 1); EMIT_NATIVE_VIPER_TYPE_ERROR(emit, - "unary op %q not implemented", mp_unary_op_method_name[op]); + translate("unary op %q not implemented"), mp_unary_op_method_name[op]); } } @@ -1925,7 +1927,7 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) { // TODO other ops not yet implemented adjust_stack(emit, 1); EMIT_NATIVE_VIPER_TYPE_ERROR(emit, - "binary op %q not implemented", mp_binary_op_method_name[op]); + translate("binary op %q not implemented"), mp_binary_op_method_name[op]); } } else if (vtype_lhs == VTYPE_PYOBJ && vtype_rhs == VTYPE_PYOBJ) { emit_pre_pop_reg_reg(emit, &vtype_rhs, REG_ARG_3, &vtype_lhs, REG_ARG_2); @@ -1946,7 +1948,7 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) { } else { adjust_stack(emit, -1); EMIT_NATIVE_VIPER_TYPE_ERROR(emit, - "can't do binary op between '%q' and '%q'", + translate("can't do binary op between '%q' and '%q'"), vtype_to_qstr(vtype_lhs), vtype_to_qstr(vtype_rhs)); } } @@ -2121,7 +2123,7 @@ STATIC void emit_native_call_function(emit_t *emit, mp_uint_t n_positional, mp_u break; default: // this can happen when casting a cast: int(int) - mp_raise_NotImplementedError("casting"); + mp_raise_NotImplementedError(translate("casting")); } } else { assert(vtype_fun == VTYPE_PYOBJ); @@ -2168,7 +2170,7 @@ STATIC void emit_native_return_value(emit_t *emit) { emit_pre_pop_reg(emit, &vtype, REG_RET); if (vtype != emit->return_vtype) { EMIT_NATIVE_VIPER_TYPE_ERROR(emit, - "return expected '%q' but got '%q'", + translate("return expected '%q' but got '%q'"), vtype_to_qstr(emit->return_vtype), vtype_to_qstr(vtype)); } } @@ -2186,7 +2188,7 @@ STATIC void emit_native_raise_varargs(emit_t *emit, mp_uint_t n_args) { vtype_kind_t vtype_exc; emit_pre_pop_reg(emit, &vtype_exc, REG_ARG_1); // arg1 = object to raise if (vtype_exc != VTYPE_PYOBJ) { - EMIT_NATIVE_VIPER_TYPE_ERROR(emit, "must raise an object"); + EMIT_NATIVE_VIPER_TYPE_ERROR(emit, translate("must raise an object")); } // TODO probably make this 1 call to the runtime (which could even call convert, native_raise(obj, type)) emit_call(emit, MP_F_NATIVE_RAISE); @@ -2196,7 +2198,7 @@ STATIC void emit_native_yield(emit_t *emit, int kind) { // not supported (for now) (void)emit; (void)kind; - mp_raise_NotImplementedError("native yield"); + mp_raise_NotImplementedError(translate("native yield")); } STATIC void emit_native_start_except_handler(emit_t *emit) { diff --git a/py/frozenmod.c b/py/frozenmod.c index 06d4f84c8e0..a9143b582a6 100644 --- a/py/frozenmod.c +++ b/py/frozenmod.c @@ -43,14 +43,20 @@ extern const char mp_frozen_str_names[]; extern const uint32_t mp_frozen_str_sizes[]; extern const char mp_frozen_str_content[]; -// On input, *len contains size of name, on output - size of content -const char *mp_find_frozen_str(const char *str, size_t *len) { +// str_len is length of str. *len is set on on output to size of content +const char *mp_find_frozen_str(const char *str, size_t str_len, size_t *len) { + // If the frozen module pseudo dir (e.g., ".frozen/") is a prefix of str, remove it. + if (strncmp(str, MP_FROZEN_FAKE_DIR_SLASH, MP_FROZEN_FAKE_DIR_SLASH_LENGTH) == 0) { + str = str + MP_FROZEN_FAKE_DIR_SLASH_LENGTH; + str_len = str_len - MP_FROZEN_FAKE_DIR_SLASH_LENGTH; + } + const char *name = mp_frozen_str_names; size_t offset = 0; for (int i = 0; *name != 0; i++) { size_t l = strlen(name); - if (l == *len && !memcmp(str, name, l)) { + if (l == str_len && !memcmp(str, name, l)) { *len = mp_frozen_str_sizes[i]; return mp_frozen_str_content + offset; } @@ -60,19 +66,18 @@ const char *mp_find_frozen_str(const char *str, size_t *len) { return NULL; } -STATIC mp_lexer_t *mp_lexer_frozen_str(const char *str, size_t len) { - size_t name_len = len; - const char *content = mp_find_frozen_str(str, &len); +STATIC mp_lexer_t *mp_lexer_frozen_str(const char *str, size_t str_len) { + size_t file_len; + const char *content = mp_find_frozen_str(str, str_len, &file_len); if (content == NULL) { return NULL; } - qstr source = qstr_from_strn(str, name_len); - mp_lexer_t *lex = MICROPY_MODULE_FROZEN_LEXER(source, content, len, 0); + qstr source = qstr_from_strn(str, str_len); + mp_lexer_t *lex = MICROPY_MODULE_FROZEN_LEXER(source, content, file_len, 0); return lex; } - #endif #if MICROPY_MODULE_FROZEN_MPY @@ -82,11 +87,11 @@ STATIC mp_lexer_t *mp_lexer_frozen_str(const char *str, size_t len) { extern const char mp_frozen_mpy_names[]; extern const mp_raw_code_t *const mp_frozen_mpy_content[]; -STATIC const mp_raw_code_t *mp_find_frozen_mpy(const char *str, size_t len) { +STATIC const mp_raw_code_t *mp_find_frozen_mpy(const char *str, size_t str_len) { const char *name = mp_frozen_mpy_names; for (size_t i = 0; *name != 0; i++) { size_t l = strlen(name); - if (l == len && !memcmp(str, name, l)) { + if (l == str_len && !memcmp(str, name, l)) { return mp_frozen_mpy_content[i]; } name += l + 1; @@ -136,6 +141,12 @@ mp_import_stat_t mp_frozen_stat(const char *str) { } int mp_find_frozen_module(const char *str, size_t len, void **data) { + // If the frozen module pseudo dir (e.g., ".frozen/") is a prefix of str, remove it. + if (strncmp(str, MP_FROZEN_FAKE_DIR_SLASH, MP_FROZEN_FAKE_DIR_SLASH_LENGTH) == 0) { + str = str + MP_FROZEN_FAKE_DIR_SLASH_LENGTH; + len = len - MP_FROZEN_FAKE_DIR_SLASH_LENGTH; + } + #if MICROPY_MODULE_FROZEN_STR mp_lexer_t *lex = mp_lexer_frozen_str(str, len); if (lex != NULL) { diff --git a/py/frozenmod.h b/py/frozenmod.h index 8cddef6819c..1e50f3807af 100644 --- a/py/frozenmod.h +++ b/py/frozenmod.h @@ -34,8 +34,18 @@ enum { MP_FROZEN_MPY, }; +// Frozen modules are in a pseudo-directory, so sys.path can control how they're found. +#define MP_FROZEN_FAKE_DIR ".frozen" +#define MP_FROZEN_FAKE_DIR_LENGTH (sizeof(MP_FROZEN_FAKE_DIR)-1) + +#define MP_FROZEN_FAKE_DIR_SLASH (MP_FROZEN_FAKE_DIR "/") +#define MP_FROZEN_FAKE_DIR_SLASH_LENGTH (sizeof(MP_FROZEN_FAKE_DIR_SLASH)-1) + +// This should match MP_FROZEN_FAKE_DIR. +#define MP_FROZEN_FAKE_DIR_QSTR MP_QSTR__dot_frozen + int mp_find_frozen_module(const char *str, size_t len, void **data); -const char *mp_find_frozen_str(const char *str, size_t *len); +const char *mp_find_frozen_str(const char *str, size_t str_len, size_t *len); mp_import_stat_t mp_frozen_stat(const char *str); #endif // MICROPY_INCLUDED_PY_FROZENMOD_H diff --git a/py/gc.c b/py/gc.c old mode 100644 new mode 100755 index 0fc43ef4953..10b36950c4c --- a/py/gc.c +++ b/py/gc.c @@ -31,6 +31,8 @@ #include "py/gc.h" #include "py/runtime.h" +#include "supervisor/shared/safe_mode.h" + #if MICROPY_ENABLE_GC #if MICROPY_DEBUG_VERBOSE // print debugging info @@ -41,6 +43,9 @@ #define DEBUG_printf(...) (void)0 #endif +// Uncomment this if you want to use a debugger to capture state at every allocation and free. +// #define LOG_HEAP_ACTIVITY 1 + // make this 1 to dump the heap each time it changes #define EXTENSIVE_HEAP_PROFILING (0) @@ -63,15 +68,6 @@ #define AT_MARK (3) #define BLOCKS_PER_ATB (4) -#define ATB_MASK_0 (0x03) -#define ATB_MASK_1 (0x0c) -#define ATB_MASK_2 (0x30) -#define ATB_MASK_3 (0xc0) - -#define ATB_0_IS_FREE(a) (((a) & ATB_MASK_0) == 0) -#define ATB_1_IS_FREE(a) (((a) & ATB_MASK_1) == 0) -#define ATB_2_IS_FREE(a) (((a) & ATB_MASK_2) == 0) -#define ATB_3_IS_FREE(a) (((a) & ATB_MASK_3) == 0) #define BLOCK_SHIFT(block) (2 * ((block) & (BLOCKS_PER_ATB - 1))) #define ATB_GET_KIND(block) ((MP_STATE_MEM(gc_alloc_table_start)[(block) / BLOCKS_PER_ATB] >> BLOCK_SHIFT(block)) & 3) @@ -104,6 +100,17 @@ #define GC_EXIT() #endif +#ifdef LOG_HEAP_ACTIVITY +volatile uint32_t change_me; +#pragma GCC push_options +#pragma GCC optimize ("O0") +void __attribute__ ((noinline)) gc_log_change(uint32_t start_block, uint32_t length) { + change_me += start_block; + change_me += length; // Break on this line. +} +#pragma GCC pop_options +#endif + // TODO waste less memory; currently requires that all entries in alloc_table have a corresponding block in pool void gc_init(void *start, void *end) { // align end pointer on block boundary @@ -145,14 +152,19 @@ void gc_init(void *start, void *end) { memset(MP_STATE_MEM(gc_finaliser_table_start), 0, gc_finaliser_table_byte_len); #endif - // set last free ATB index to start of heap - MP_STATE_MEM(gc_last_free_atb_index) = 0; + // Set first free ATB index to the start of the heap. + MP_STATE_MEM(gc_first_free_atb_index) = 0; + // Set last free ATB index to the end of the heap. + MP_STATE_MEM(gc_last_free_atb_index) = MP_STATE_MEM(gc_alloc_table_byte_len) - 1; + // Set the lowest long lived ptr to the end of the heap to start. This will be lowered as long + // lived objects are allocated. + MP_STATE_MEM(gc_lowest_long_lived_ptr) = (void*) PTR_FROM_BLOCK(MP_STATE_MEM(gc_alloc_table_byte_len * BLOCKS_PER_ATB)); // unlock the GC MP_STATE_MEM(gc_lock_depth) = 0; // allow auto collection - MP_STATE_MEM(gc_auto_collect_enabled) = 1; + MP_STATE_MEM(gc_auto_collect_enabled) = true; #if MICROPY_GC_ALLOC_THRESHOLD // by default, maxuint for gc threshold, effectively turning gc-by-threshold off @@ -164,6 +176,8 @@ void gc_init(void *start, void *end) { mp_thread_mutex_init(&MP_STATE_MEM(gc_mutex)); #endif + MP_STATE_MEM(permanent_pointers) = NULL; + DEBUG_printf("GC layout:\n"); DEBUG_printf(" alloc table at %p, length " UINT_FMT " bytes, " UINT_FMT " blocks\n", MP_STATE_MEM(gc_alloc_table_start), MP_STATE_MEM(gc_alloc_table_byte_len), MP_STATE_MEM(gc_alloc_table_byte_len) * BLOCKS_PER_ATB); #if MICROPY_ENABLE_FINALISER @@ -172,6 +186,13 @@ void gc_init(void *start, void *end) { DEBUG_printf(" pool at %p, length " UINT_FMT " bytes, " UINT_FMT " blocks\n", MP_STATE_MEM(gc_pool_start), gc_pool_block_len * BYTES_PER_BLOCK, gc_pool_block_len); } +void gc_deinit(void) { + // Run any finalizers before we stop using the heap. + gc_sweep_all(); + + MP_STATE_MEM(gc_pool_start) = 0; +} + void gc_lock(void) { GC_ENTER(); MP_STATE_MEM(gc_lock_depth)++; @@ -293,11 +314,19 @@ STATIC void gc_sweep(void) { } #endif free_tail = 1; - DEBUG_printf("gc_sweep(%p)\n", PTR_FROM_BLOCK(block)); + ATB_ANY_TO_FREE(block); + #if CLEAR_ON_SWEEP + memset((void*)PTR_FROM_BLOCK(block), 0, BYTES_PER_BLOCK); + #endif + DEBUG_printf("gc_sweep(%x)\n", PTR_FROM_BLOCK(block)); + + #ifdef LOG_HEAP_ACTIVITY + gc_log_change(block, 0); + #endif #if MICROPY_PY_GC_COLLECT_RETVAL MP_STATE_MEM(gc_collected)++; #endif - // fall through to free the head + break; case AT_TAIL: if (free_tail) { @@ -316,6 +345,19 @@ STATIC void gc_sweep(void) { } } +// Mark can handle NULL pointers because it verifies the pointer is within the heap bounds. +STATIC void gc_mark(void* ptr) { + if (VERIFY_PTR(ptr)) { + size_t block = BLOCK_FROM_PTR(ptr); + if (ATB_GET_KIND(block) == AT_HEAD) { + // An unmarked head: mark it, and mark all its children + TRACE_MARK(block, ptr); + ATB_HEAD_TO_MARK(block); + gc_mark_subtree(block); + } + } +} + void gc_collect_start(void) { GC_ENTER(); MP_STATE_MEM(gc_lock_depth)++; @@ -332,6 +374,8 @@ void gc_collect_start(void) { size_t root_end = offsetof(mp_state_ctx_t, vm.qstr_last_chunk); gc_collect_root(ptrs + root_start / sizeof(void*), (root_end - root_start) / sizeof(void*)); + gc_mark(MP_STATE_MEM(permanent_pointers)); + #if MICROPY_ENABLE_PYSTACK // Trace root pointers from the Python stack. ptrs = (void**)(void*)MP_STATE_THREAD(pystack_start); @@ -339,25 +383,22 @@ void gc_collect_start(void) { #endif } +void gc_collect_ptr(void *ptr) { + gc_mark(ptr); +} + void gc_collect_root(void **ptrs, size_t len) { for (size_t i = 0; i < len; i++) { void *ptr = ptrs[i]; - if (VERIFY_PTR(ptr)) { - size_t block = BLOCK_FROM_PTR(ptr); - if (ATB_GET_KIND(block) == AT_HEAD) { - // An unmarked head: mark it, and mark all its children - TRACE_MARK(block, ptr); - ATB_HEAD_TO_MARK(block); - gc_mark_subtree(block); - } - } + gc_mark(ptr); } } void gc_collect_end(void) { gc_deal_with_stack_overflow(); gc_sweep(); - MP_STATE_MEM(gc_last_free_atb_index) = 0; + MP_STATE_MEM(gc_first_free_atb_index) = 0; + MP_STATE_MEM(gc_last_free_atb_index) = MP_STATE_MEM(gc_alloc_table_byte_len) - 1; MP_STATE_MEM(gc_lock_depth)--; GC_EXIT(); } @@ -433,7 +474,9 @@ void gc_info(gc_info_t *info) { GC_EXIT(); } -void *gc_alloc(size_t n_bytes, bool has_finaliser) { +// We place long lived objects at the end of the heap rather than the start. This reduces +// fragmentation by localizing the heap churn to one portion of memory (the start of the heap.) +void *gc_alloc(size_t n_bytes, bool has_finaliser, bool long_lived) { size_t n_blocks = ((n_bytes + BYTES_PER_BLOCK - 1) & (~(BYTES_PER_BLOCK - 1))) / BYTES_PER_BLOCK; DEBUG_printf("gc_alloc(" UINT_FMT " bytes -> " UINT_FMT " blocks)\n", n_bytes, n_blocks); @@ -442,6 +485,10 @@ void *gc_alloc(size_t n_bytes, bool has_finaliser) { return NULL; } + if (MP_STATE_MEM(gc_pool_start) == 0) { + reset_into_safe_mode(GC_ALLOC_OUTSIDE_VM); + } + GC_ENTER(); // check if GC is locked @@ -450,11 +497,11 @@ void *gc_alloc(size_t n_bytes, bool has_finaliser) { return NULL; } - size_t i; + size_t found_block = 0xffffffff; size_t end_block; size_t start_block; - size_t n_free = 0; - int collected = !MP_STATE_MEM(gc_auto_collect_enabled); + size_t n_free; + bool collected = !MP_STATE_MEM(gc_auto_collect_enabled); #if MICROPY_GC_ALLOC_THRESHOLD if (!collected && MP_STATE_MEM(gc_alloc_amount) >= MP_STATE_MEM(gc_alloc_threshold)) { @@ -462,18 +509,51 @@ void *gc_alloc(size_t n_bytes, bool has_finaliser) { gc_collect(); collected = 1; GC_ENTER(); + collected = true; } #endif - for (;;) { - + bool keep_looking = true; + + // When we start searching on the other side of the crossover block we make sure to + // perform a collect. That way we'll get the closest free block in our section. + size_t crossover_block = BLOCK_FROM_PTR(MP_STATE_MEM(gc_lowest_long_lived_ptr)); + while (keep_looking) { + int8_t direction = 1; + size_t start = MP_STATE_MEM(gc_first_free_atb_index); + if (long_lived) { + direction = -1; + start = MP_STATE_MEM(gc_last_free_atb_index); + } + n_free = 0; // look for a run of n_blocks available blocks - for (i = MP_STATE_MEM(gc_last_free_atb_index); i < MP_STATE_MEM(gc_alloc_table_byte_len); i++) { + for (size_t i = start; keep_looking && MP_STATE_MEM(gc_first_free_atb_index) <= i && i <= MP_STATE_MEM(gc_last_free_atb_index); i += direction) { byte a = MP_STATE_MEM(gc_alloc_table_start)[i]; - if (ATB_0_IS_FREE(a)) { if (++n_free >= n_blocks) { i = i * BLOCKS_PER_ATB + 0; goto found; } } else { n_free = 0; } - if (ATB_1_IS_FREE(a)) { if (++n_free >= n_blocks) { i = i * BLOCKS_PER_ATB + 1; goto found; } } else { n_free = 0; } - if (ATB_2_IS_FREE(a)) { if (++n_free >= n_blocks) { i = i * BLOCKS_PER_ATB + 2; goto found; } } else { n_free = 0; } - if (ATB_3_IS_FREE(a)) { if (++n_free >= n_blocks) { i = i * BLOCKS_PER_ATB + 3; goto found; } } else { n_free = 0; } + // Four ATB states are packed into a single byte. + int j = 0; + if (direction == -1) { + j = 3; + } + for (; keep_looking && 0 <= j && j <= 3; j += direction) { + if ((a & (0x3 << (j * 2))) == 0) { + if (++n_free >= n_blocks) { + found_block = i * BLOCKS_PER_ATB + j; + keep_looking = false; + } + } else { + if (!collected) { + size_t block = i * BLOCKS_PER_ATB + j; + if ((direction == 1 && block >= crossover_block) || + (direction == -1 && block < crossover_block)) { + keep_looking = false; + } + } + n_free = 0; + } + } + } + if (n_free >= n_blocks) { + break; } GC_EXIT(); @@ -483,25 +563,37 @@ void *gc_alloc(size_t n_bytes, bool has_finaliser) { } DEBUG_printf("gc_alloc(" UINT_FMT "): no free mem, triggering GC\n", n_bytes); gc_collect(); - collected = 1; + collected = true; + // Try again since we've hopefully freed up space. + keep_looking = true; GC_ENTER(); } + assert(found_block != 0xffffffff); - // found, ending at block i inclusive -found: - // get starting and end blocks, both inclusive - end_block = i; - start_block = i - n_free + 1; - - // Set last free ATB index to block after last block we found, for start of + // Found free space ending at found_block inclusive. + // Also, set last free ATB index to block after last block we found, for start of // next scan. To reduce fragmentation, we only do this if we were looking // for a single free block, which guarantees that there are no free blocks - // before this one. Also, whenever we free or shink a block we must check + // before this one. Also, whenever we free or shrink a block we must check // if this index needs adjusting (see gc_realloc and gc_free). - if (n_free == 1) { - MP_STATE_MEM(gc_last_free_atb_index) = (i + 1) / BLOCKS_PER_ATB; + if (!long_lived) { + end_block = found_block; + start_block = found_block - n_free + 1; + if (n_blocks == 1) { + MP_STATE_MEM(gc_first_free_atb_index) = (found_block + 1) / BLOCKS_PER_ATB; + } + } else { + start_block = found_block; + end_block = found_block + n_free - 1; + if (n_blocks == 1) { + MP_STATE_MEM(gc_last_free_atb_index) = (found_block - 1) / BLOCKS_PER_ATB; + } } + #ifdef LOG_HEAP_ACTIVITY + gc_log_change(start_block, end_block - start_block + 1); + #endif + // mark first block as used head ATB_FREE_TO_HEAD(start_block); @@ -516,6 +608,13 @@ void *gc_alloc(size_t n_bytes, bool has_finaliser) { void *ret_ptr = (void*)(MP_STATE_MEM(gc_pool_start) + start_block * BYTES_PER_BLOCK); DEBUG_printf("gc_alloc(%p)\n", ret_ptr); + // If the allocation was long live then update the lowest value. Its used to trigger early + // collects when allocations fail in their respective section. Its also used to ignore calls to + // gc_make_long_lived where the pointer is already in the long lived section. + if (long_lived && ret_ptr < MP_STATE_MEM(gc_lowest_long_lived_ptr)) { + MP_STATE_MEM(gc_lowest_long_lived_ptr) = ret_ptr; + } + #if MICROPY_GC_ALLOC_THRESHOLD MP_STATE_MEM(gc_alloc_amount) += n_blocks; #endif @@ -589,11 +688,17 @@ void gc_free(void *ptr) { #endif // set the last_free pointer to this block if it's earlier in the heap - if (block / BLOCKS_PER_ATB < MP_STATE_MEM(gc_last_free_atb_index)) { + if (block / BLOCKS_PER_ATB < MP_STATE_MEM(gc_first_free_atb_index)) { + MP_STATE_MEM(gc_first_free_atb_index) = block / BLOCKS_PER_ATB; + } + if (block / BLOCKS_PER_ATB > MP_STATE_MEM(gc_last_free_atb_index)) { MP_STATE_MEM(gc_last_free_atb_index) = block / BLOCKS_PER_ATB; } // free head and all of its tail blocks + #ifdef LOG_HEAP_ACTIVITY + gc_log_change(block, 0); + #endif do { ATB_ANY_TO_FREE(block); block += 1; @@ -627,6 +732,50 @@ size_t gc_nbytes(const void *ptr) { return 0; } +bool gc_has_finaliser(const void *ptr) { +#if MICROPY_ENABLE_FINALISER + GC_ENTER(); + if (VERIFY_PTR(ptr)) { + bool has_finaliser = FTB_GET(BLOCK_FROM_PTR(ptr)); + GC_EXIT(); + return has_finaliser; + } + + // invalid pointer + GC_EXIT(); +#else + (void) ptr; +#endif + return false; +} + +void *gc_make_long_lived(void *old_ptr) { + // If its already in the long lived section then don't bother moving it. + if (old_ptr >= MP_STATE_MEM(gc_lowest_long_lived_ptr)) { + return old_ptr; + } + size_t n_bytes = gc_nbytes(old_ptr); + if (n_bytes == 0) { + return old_ptr; + } + bool has_finaliser = gc_has_finaliser(old_ptr); + + // Try and find a new area in the long lived section to copy the memory to. + void* new_ptr = gc_alloc(n_bytes, has_finaliser, true); + if (new_ptr == NULL) { + return old_ptr; + } else if (old_ptr > new_ptr) { + // Return the old pointer if the new one is lower in the heap and free the new space. + gc_free(new_ptr); + return old_ptr; + } + // We copy everything over and let the garbage collection process delete the old copy. That way + // we ensure we don't delete memory that has a second reference. (Though if there is we may + // confuse things when its mutable.) + memcpy(new_ptr, old_ptr, n_bytes); + return new_ptr; +} + #if 0 // old, simple realloc that didn't expand memory in place void *gc_realloc(void *ptr, mp_uint_t n_bytes) { @@ -659,7 +808,7 @@ void *gc_realloc(void *ptr, mp_uint_t n_bytes) { void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) { // check for pure allocation if (ptr_in == NULL) { - return gc_alloc(n_bytes, false); + return gc_alloc(n_bytes, false, false); } // check for pure free @@ -725,7 +874,10 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) { } // set the last_free pointer to end of this block if it's earlier in the heap - if ((block + new_blocks) / BLOCKS_PER_ATB < MP_STATE_MEM(gc_last_free_atb_index)) { + if ((block + new_blocks) / BLOCKS_PER_ATB < MP_STATE_MEM(gc_first_free_atb_index)) { + MP_STATE_MEM(gc_first_free_atb_index) = (block + new_blocks) / BLOCKS_PER_ATB; + } + if ((block + new_blocks) / BLOCKS_PER_ATB > MP_STATE_MEM(gc_last_free_atb_index)) { MP_STATE_MEM(gc_last_free_atb_index) = (block + new_blocks) / BLOCKS_PER_ATB; } @@ -735,6 +887,10 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) { gc_dump_alloc_table(); #endif + #ifdef LOG_HEAP_ACTIVITY + gc_log_change(block, new_blocks); + #endif + return ptr_in; } @@ -760,6 +916,10 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) { gc_dump_alloc_table(); #endif + #ifdef LOG_HEAP_ACTIVITY + gc_log_change(block, new_blocks); + #endif + return ptr_in; } @@ -777,7 +937,7 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) { } // can't resize inplace; try to find a new contiguous chain - void *ptr_out = gc_alloc(n_bytes, ftb_state); + void *ptr_out = gc_alloc(n_bytes, ftb_state, false); // check that the alloc succeeded if (ptr_out == NULL) { @@ -791,6 +951,36 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) { } #endif // Alternative gc_realloc impl +bool gc_never_free(void *ptr) { + // Check to make sure the pointer is on the heap in the first place. + if (gc_nbytes(ptr) == 0) { + return false; + } + // Pointers are stored in a linked list where each block is BYTES_PER_BLOCK long and the first + // pointer is the next block of pointers. + void ** current_reference_block = MP_STATE_MEM(permanent_pointers); + while (current_reference_block != NULL) { + for (size_t i = 1; i < BYTES_PER_BLOCK / sizeof(void*); i++) { + if (current_reference_block[i] == NULL) { + current_reference_block[i] = ptr; + return true; + } + } + current_reference_block = current_reference_block[0]; + } + void** next_block = gc_alloc(BYTES_PER_BLOCK, false, true); + if (next_block == NULL) { + return false; + } + if (MP_STATE_MEM(permanent_pointers) == NULL) { + MP_STATE_MEM(permanent_pointers) = next_block; + } else { + current_reference_block[0] = next_block; + } + next_block[1] = ptr; + return true; +} + void gc_dump_info(void) { gc_info_t info; gc_info(&info); @@ -863,7 +1053,10 @@ void gc_dump_alloc_table(void) { */ /* this prints the uPy object type of the head block */ case AT_HEAD: { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" void **ptr = (void**)(MP_STATE_MEM(gc_pool_start) + bl * BYTES_PER_BLOCK); +#pragma GCC diagnostic pop if (*ptr == &mp_type_tuple) { c = 'T'; } else if (*ptr == &mp_type_list) { c = 'L'; } else if (*ptr == &mp_type_dict) { c = 'D'; } diff --git a/py/gc.h b/py/gc.h index 73d86e6c315..02bf4515877 100644 --- a/py/gc.h +++ b/py/gc.h @@ -32,6 +32,7 @@ #include "py/misc.h" void gc_init(void *start, void *end); +void gc_deinit(void); // These lock/unlock functions can be nested. // They can be used to prevent the GC from allocating/freeing. @@ -42,17 +43,25 @@ bool gc_is_locked(void); // A given port must implement gc_collect by using the other collect functions. void gc_collect(void); void gc_collect_start(void); +void gc_collect_ptr(void *ptr); void gc_collect_root(void **ptrs, size_t len); void gc_collect_end(void); +void *gc_alloc(size_t n_bytes, bool has_finaliser, bool long_lived); + // Use this function to sweep the whole heap and run all finalisers void gc_sweep_all(void); -void *gc_alloc(size_t n_bytes, bool has_finaliser); void gc_free(void *ptr); // does not call finaliser size_t gc_nbytes(const void *ptr); +bool gc_has_finaliser(const void *ptr); +void *gc_make_long_lived(void *old_ptr); void *gc_realloc(void *ptr, size_t n_bytes, bool allow_move); +// Prevents a pointer from ever being freed because it establishes a permanent reference to it. Use +// very sparingly because it can leak memory. +bool gc_never_free(void *ptr); + typedef struct _gc_info_t { size_t total; size_t used; diff --git a/py/gc_long_lived.c b/py/gc_long_lived.c new file mode 100755 index 00000000000..49bf1fcd79b --- /dev/null +++ b/py/gc_long_lived.c @@ -0,0 +1,144 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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 "py/emitglue.h" +#include "py/gc_long_lived.h" +#include "py/gc.h" +#include "py/mpstate.h" + +mp_obj_fun_bc_t *make_fun_bc_long_lived(mp_obj_fun_bc_t *fun_bc, uint8_t max_depth) { + #ifndef MICROPY_ENABLE_GC + return fun_bc; + #endif + if (fun_bc == NULL || fun_bc == mp_const_none || max_depth == 0) { + return fun_bc; + } + fun_bc->bytecode = gc_make_long_lived((byte*) fun_bc->bytecode); + fun_bc->globals = make_dict_long_lived(fun_bc->globals, max_depth - 1); + for (uint32_t i = 0; i < gc_nbytes(fun_bc->const_table) / sizeof(mp_obj_t); i++) { + // Skip things that aren't allocated on the heap (and hence have zero bytes.) + if (gc_nbytes((byte *)fun_bc->const_table[i]) == 0) { + continue; + } + // Try to detect raw code. + mp_raw_code_t* raw_code = MP_OBJ_TO_PTR(fun_bc->const_table[i]); + if (raw_code->kind == MP_CODE_BYTECODE) { + raw_code->data.u_byte.bytecode = gc_make_long_lived((byte*) raw_code->data.u_byte.bytecode); + raw_code->data.u_byte.const_table = gc_make_long_lived((byte*) raw_code->data.u_byte.const_table); + } + ((mp_uint_t *) fun_bc->const_table)[i] = (mp_uint_t) make_obj_long_lived( + (mp_obj_t) fun_bc->const_table[i], max_depth - 1); + + } + fun_bc->const_table = gc_make_long_lived((mp_uint_t*) fun_bc->const_table); + // extra_args stores keyword only argument default values. + size_t words = gc_nbytes(fun_bc) / sizeof(mp_uint_t*); + // Functions (mp_obj_fun_bc_t) have four pointers (base, globals, bytecode and const_table) + // before the variable length extra_args so remove them from the length. + for (size_t i = 0; i < words - 4; i++) { + if (fun_bc->extra_args[i] == NULL) { + continue; + } + if (MP_OBJ_IS_TYPE(fun_bc->extra_args[i], &mp_type_dict)) { + fun_bc->extra_args[i] = make_dict_long_lived(fun_bc->extra_args[i], max_depth - 1); + } else { + fun_bc->extra_args[i] = make_obj_long_lived(fun_bc->extra_args[i], max_depth - 1); + } + + } + return gc_make_long_lived(fun_bc); +} + +mp_obj_property_t *make_property_long_lived(mp_obj_property_t *prop, uint8_t max_depth) { + #ifndef MICROPY_ENABLE_GC + return prop; + #endif + if (max_depth == 0) { + return prop; + } + prop->proxy[0] = make_obj_long_lived((mp_obj_fun_bc_t*) prop->proxy[0], max_depth - 1); + prop->proxy[1] = make_obj_long_lived((mp_obj_fun_bc_t*) prop->proxy[1], max_depth - 1); + prop->proxy[2] = make_obj_long_lived((mp_obj_fun_bc_t*) prop->proxy[2], max_depth - 1); + return gc_make_long_lived(prop); +} + +mp_obj_dict_t *make_dict_long_lived(mp_obj_dict_t *dict, uint8_t max_depth) { + #ifndef MICROPY_ENABLE_GC + return dict; + #endif + if (dict == NULL || max_depth == 0 || dict == &MP_STATE_VM(dict_main)) { + return dict; + } + // Don't recurse unnecessarily. Return immediately if we've already seen this dict. + if (dict->map.scanning) { + return dict; + } + // Mark that we're processing this dict. + dict->map.scanning = 1; + + // Update all of the references first so that we reduce the chance of references to the old + // copies. + dict->map.table = gc_make_long_lived(dict->map.table); + for (size_t i = 0; i < dict->map.alloc; i++) { + if (MP_MAP_SLOT_IS_FILLED(&dict->map, i)) { + mp_obj_t value = dict->map.table[i].value; + dict->map.table[i].value = make_obj_long_lived(value, max_depth - 1); + } + } + dict = gc_make_long_lived(dict); + // Done recursing through this dict. + dict->map.scanning = 0; + return dict; +} + +mp_obj_str_t *make_str_long_lived(mp_obj_str_t *str) { + str->data = gc_make_long_lived((byte *) str->data); + return gc_make_long_lived(str); +} + +mp_obj_t make_obj_long_lived(mp_obj_t obj, uint8_t max_depth){ + #ifndef MICROPY_ENABLE_GC + return obj; + #endif + if (obj == NULL) { + return obj; + } + if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_bc)) { + mp_obj_fun_bc_t *fun_bc = MP_OBJ_TO_PTR(obj); + return MP_OBJ_FROM_PTR(make_fun_bc_long_lived(fun_bc, max_depth)); + } else if (MP_OBJ_IS_TYPE(obj, &mp_type_property)) { + mp_obj_property_t *prop = MP_OBJ_TO_PTR(obj); + return MP_OBJ_FROM_PTR(make_property_long_lived(prop, max_depth)); + } else if (MP_OBJ_IS_TYPE(obj, &mp_type_str) || MP_OBJ_IS_TYPE(obj, &mp_type_bytes)) { + mp_obj_str_t *str = MP_OBJ_TO_PTR(obj); + return MP_OBJ_FROM_PTR(make_str_long_lived(str)); + } else if (MP_OBJ_IS_TYPE(obj, &mp_type_type)) { + // Types are already long lived during creation. + return obj; + } else { + return gc_make_long_lived(obj); + } +} diff --git a/py/gc_long_lived.h b/py/gc_long_lived.h new file mode 100644 index 00000000000..229bc73911c --- /dev/null +++ b/py/gc_long_lived.h @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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. + */ + +// These helpers move MicroPython objects and their sub-objects to the long lived portion of the +// heap. + +#ifndef MICROPY_INCLUDED_PY_GC_LONG_LIVED_H +#define MICROPY_INCLUDED_PY_GC_LONG_LIVED_H + +#include "py/objfun.h" +#include "py/objproperty.h" +#include "py/objstr.h" + +mp_obj_fun_bc_t *make_fun_bc_long_lived(mp_obj_fun_bc_t *fun_bc, uint8_t max_depth); +mp_obj_property_t *make_property_long_lived(mp_obj_property_t *prop, uint8_t max_depth); +mp_obj_dict_t *make_dict_long_lived(mp_obj_dict_t *dict, uint8_t max_depth); +mp_obj_str_t *make_str_long_lived(mp_obj_str_t *str); +mp_obj_t make_obj_long_lived(mp_obj_t obj, uint8_t max_depth); + +#endif // MICROPY_INCLUDED_PY_GC_LONG_LIVED_H diff --git a/py/ioctl.h b/py/ioctl.h new file mode 100644 index 00000000000..ced42759007 --- /dev/null +++ b/py/ioctl.h @@ -0,0 +1,38 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2015 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. + */ +#ifndef MICROPY_INCLUDED_PY_IOCTL_H +#define MICROPY_INCLUDED_PY_IOCTL_H + +#define MP_IOCTL_POLL (0x100 | 1) + +// These values are compatible with Linux, which are in turn +// compatible with iBCS2 spec. +#define MP_IOCTL_POLL_RD (0x0001) +#define MP_IOCTL_POLL_WR (0x0004) +#define MP_IOCTL_POLL_ERR (0x0008) +#define MP_IOCTL_POLL_HUP (0x0010) + +#endif // MICROPY_INCLUDED_PY_IOCTL_H diff --git a/py/lexer.c b/py/lexer.c index e161700b169..755fa625beb 100644 --- a/py/lexer.c +++ b/py/lexer.c @@ -32,6 +32,8 @@ #include "py/lexer.h" #include "py/runtime.h" +#include "supervisor/shared/translate.h" + #if MICROPY_ENABLE_COMPILER #define TAB_SIZE (8) @@ -340,7 +342,7 @@ STATIC void parse_string_literal(mp_lexer_t *lex, bool is_raw) { // 3MB of text; even gzip-compressed and with minimal structure, it'll take // roughly half a meg of storage. This form of Unicode escape may be added // later on, but it's definitely not a priority right now. -- CJA 20140607 - mp_raise_NotImplementedError("unicode name escapes"); + mp_raise_NotImplementedError(translate("unicode name escapes")); break; default: if (c >= '0' && c <= '7') { diff --git a/py/makemoduledefs.py b/py/makemoduledefs.py new file mode 100644 index 00000000000..18d327f0029 --- /dev/null +++ b/py/makemoduledefs.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python + +# This pre-processor parses provided objects' c files for +# MP_REGISTER_MODULE(module_name, obj_module, enabled_define) +# These are used to generate a header with the required entries for +# "mp_rom_map_elem_t mp_builtin_module_table[]" in py/objmodule.c + +from __future__ import print_function + +import re +import os +import argparse + + +pattern = re.compile( + r"[\n;]\s*MP_REGISTER_MODULE\((.*?),\s*(.*?),\s*(.*?)\);", + flags=re.DOTALL +) + + +def find_c_file(obj_file, vpath): + """ Search vpaths for the c file that matches the provided object_file. + + :param str obj_file: object file to find the matching c file for + :param List[str] vpath: List of base paths, similar to gcc vpath + :return: str path to c file or None + """ + c_file = None + relative_c_file = os.path.splitext(obj_file)[0] + ".c" + relative_c_file = relative_c_file.lstrip('/\\') + for p in vpath: + possible_c_file = os.path.join(p, relative_c_file) + if os.path.exists(possible_c_file): + c_file = possible_c_file + break + + return c_file + + +def find_module_registrations(c_file): + """ Find any MP_REGISTER_MODULE definitions in the provided c file. + + :param str c_file: path to c file to check + :return: List[(module_name, obj_module, enabled_define)] + """ + global pattern + + if c_file is None: + # No c file to match the object file, skip + return set() + + with open(c_file) as c_file_obj: + return set(re.findall(pattern, c_file_obj.read())) + + +def generate_module_table_header(modules): + """ Generate header with module table entries for builtin modules. + + :param List[(module_name, obj_module, enabled_define)] modules: module defs + :return: None + """ + + # Print header file for all external modules. + mod_defs = [] + print("// Automatically generated by makemoduledefs.py.\n") + for module_name, obj_module, enabled_define in modules: + mod_def = "MODULE_DEF_{}".format(module_name.upper()) + mod_defs.append(mod_def) + print(( + "#if ({enabled_define})\n" + " extern const struct _mp_obj_module_t {obj_module};\n" + " #define {mod_def} {{ MP_ROM_QSTR({module_name}), MP_ROM_PTR(&{obj_module}) }},\n" + "#else\n" + " #define {mod_def}\n" + "#endif\n" + ).format(module_name=module_name, obj_module=obj_module, + enabled_define=enabled_define, mod_def=mod_def) + ) + + print("\n#define MICROPY_REGISTERED_MODULES \\") + + for mod_def in mod_defs: + print(" {mod_def} \\".format(mod_def=mod_def)) + + print("// MICROPY_REGISTERED_MODULES") + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--vpath", default=".", + help="comma separated list of folders to search for c files in") + parser.add_argument("files", nargs="*", + help="list of c files to search") + args = parser.parse_args() + + vpath = [p.strip() for p in args.vpath.split(',')] + + modules = set() + for obj_file in args.files: + c_file = find_c_file(obj_file, vpath) + modules |= find_module_registrations(c_file) + + generate_module_table_header(sorted(modules)) + + +if __name__ == '__main__': + main() diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py index 3c0a6090920..8e3835d861d 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -9,6 +9,17 @@ import re import sys +import collections +import gettext +import os.path + +py = os.path.dirname(sys.argv[0]) +top = os.path.dirname(py) + +sys.path.append(os.path.join(top, "tools/huffman")) + +import huffman + # Python 2/3 compatibility: # - iterating through bytes is different # - codepoint2name lives in a different module @@ -51,6 +62,18 @@ codepoint2name[ord('|')] = 'pipe' codepoint2name[ord('~')] = 'tilde' +C_ESCAPES = { + "\a": "\\a", + "\b": "\\b", + "\f": "\\f", + "\n": "\\n", + "\r": "\\r", + "\t": "\\t", + "\v": "\\v", + "\'": "\\'", + "\"": "\\\"" +} + # this must match the equivalent function in qstr.c def compute_hash(qstr, bytes_hash): hash = 5381 @@ -59,6 +82,155 @@ def compute_hash(qstr, bytes_hash): # Make sure that valid hash is never zero, zero means "hash not computed" return (hash & ((1 << (8 * bytes_hash)) - 1)) or 1 +def translate(translation_file, i18ns): + with open(translation_file, "rb") as f: + table = gettext.GNUTranslations(f) + + translations = [] + for original in i18ns: + unescaped = original + for s in C_ESCAPES: + unescaped = unescaped.replace(C_ESCAPES[s], s) + translation = table.gettext(unescaped) + # Add in carriage returns to work in terminals + translation = translation.replace("\n", "\r\n") + translations.append((original, translation)) + return translations + +def compute_huffman_coding(translations, qstrs, compression_filename): + all_strings = [x[1] for x in translations] + + # go through each qstr and print it out + for _, _, qstr in qstrs.values(): + all_strings.append(qstr) + all_strings_concat = "".join(all_strings).encode("utf-8") + counts = collections.Counter(all_strings_concat) + # add other values + for i in range(256): + if i not in counts: + counts[i] = 0 + cb = huffman.codebook(counts.items()) + values = bytearray() + length_count = {} + renumbered = 0 + last_l = None + canonical = {} + for ch, code in sorted(cb.items(), key=lambda x: (len(x[1]), x[0])): + values.append(ch) + l = len(code) + if l not in length_count: + length_count[l] = 0 + length_count[l] += 1 + if last_l: + renumbered <<= (l - last_l) + canonical[ch] = '{0:0{width}b}'.format(renumbered, width=l) + if chr(ch) in C_ESCAPES: + s = C_ESCAPES[chr(ch)] + else: + s = chr(ch) + print("//", ch, s, counts[ch], canonical[ch], renumbered) + renumbered += 1 + last_l = l + lengths = bytearray() + for i in range(1, max(length_count) + 1): + lengths.append(length_count.get(i, 0)) + print("//", values, lengths) + with open(compression_filename, "w") as f: + f.write("const uint8_t lengths[] = {{ {} }};\n".format(", ".join(map(str, lengths)))) + f.write("const uint8_t values[256] = {{ {} }};\n".format(", ".join(map(str, values)))) + return values, lengths + +def decompress(encoding_table, length, encoded): + values, lengths = encoding_table + #print(l, encoded) + dec = bytearray(length) + this_byte = 0 + this_bit = 7 + b = encoded[this_byte] + for i in range(length): + bits = 0 + bit_length = 0 + max_code = lengths[0] + searched_length = lengths[0] + while True: + bits <<= 1 + if 0x80 & b: + bits |= 1 + + b <<= 1 + bit_length += 1 + if this_bit == 0: + this_bit = 7 + this_byte += 1 + if this_byte < len(encoded): + b = encoded[this_byte] + else: + this_bit -= 1 + if max_code > 0 and bits < max_code: + #print('{0:0{width}b}'.format(bits, width=bit_length)) + break + max_code = (max_code << 1) + lengths[bit_length] + searched_length += lengths[bit_length] + + v = values[searched_length + bits - max_code] + dec[i] = v + return dec + +def compress(encoding_table, decompressed): + if not isinstance(decompressed, bytes): + raise TypeError() + values, lengths = encoding_table + enc = bytearray(len(decompressed) * 2) + #print(decompressed) + #print(lengths) + current_bit = 7 + current_byte = 0 + for c in decompressed: + #print() + #print("char", c, values.index(c)) + start = 0 + end = lengths[0] + bits = 1 + compressed = None + code = 0 + while compressed is None: + s = start + e = end + #print("{0:0{width}b}".format(code, width=bits)) + # Binary search! + while e > s: + midpoint = (s + e) // 2 + #print(s, e, midpoint) + if values[midpoint] == c: + compressed = code + (midpoint - start) + #print("found {0:0{width}b}".format(compressed, width=bits)) + break + elif c < values[midpoint]: + e = midpoint + else: + s = midpoint + 1 + code += end - start + code <<= 1 + start = end + end += lengths[bits] + bits += 1 + #print("next bit", bits) + + for i in range(bits - 1, 0, -1): + if compressed & (1 << (i - 1)): + enc[current_byte] |= 1 << current_bit + if current_bit == 0: + current_bit = 7 + #print("packed {0:0{width}b}".format(enc[current_byte], width=8)) + current_byte += 1 + else: + current_bit -= 1 + if current_bit != 7: + current_byte += 1 + if current_byte > len(decompressed): + print("Note: compression increased length", repr(decompressed.decode('utf-8')), len(decompressed), current_byte, file=sys.stderr) + return enc[:current_byte] + def qstr_escape(qst): def esc_char(m): c = ord(m.group(0)) @@ -73,6 +245,7 @@ def parse_input_headers(infiles): # read the qstrs in from the input files qcfgs = {} qstrs = {} + i18ns = set() for infile in infiles: with open(infile, 'rt') as f: for line in f: @@ -88,6 +261,12 @@ def parse_input_headers(infiles): qcfgs[match.group(1)] = value continue + + match = re.match(r'^TRANSLATE\("(.*)"\)$', line) + if match: + i18ns.add(match.group(1)) + continue + # is this a QSTR line? match = re.match(r'^Q\((.*)\)$', line) if not match: @@ -121,11 +300,11 @@ def parse_input_headers(infiles): order -= 100000 qstrs[ident] = (order, ident, qstr) - if not qcfgs: + if not qcfgs and qstrs: sys.stderr.write("ERROR: Empty preprocessor output - check for errors above\n") sys.exit(1) - return qcfgs, qstrs + return qcfgs, qstrs, i18ns def make_bytes(cfg_bytes_len, cfg_bytes_hash, qstr): qbytes = bytes_cons(qstr, 'utf8') @@ -144,7 +323,7 @@ def make_bytes(cfg_bytes_len, cfg_bytes_hash, qstr): qhash_str = ('\\x%02x' * cfg_bytes_hash) % tuple(((qhash >> (8 * i)) & 0xff) for i in range(cfg_bytes_hash)) return '(const byte*)"%s%s" "%s"' % (qhash_str, qlen_str, qdata) -def print_qstr_data(qcfgs, qstrs): +def print_qstr_data(encoding_table, qcfgs, qstrs, i18ns): # get config variables cfg_bytes_len = int(qcfgs['BYTES_IN_LEN']) cfg_bytes_hash = int(qcfgs['BYTES_IN_HASH']) @@ -156,14 +335,61 @@ def print_qstr_data(qcfgs, qstrs): # add NULL qstr with no hash or data print('QDEF(MP_QSTR_NULL, (const byte*)"%s%s" "")' % ('\\x00' * cfg_bytes_hash, '\\x00' * cfg_bytes_len)) + total_qstr_size = 0 + total_qstr_compressed_size = 0 # go through each qstr and print it out for order, ident, qstr in sorted(qstrs.values(), key=lambda x: x[0]): qbytes = make_bytes(cfg_bytes_len, cfg_bytes_hash, qstr) print('QDEF(MP_QSTR_%s, %s)' % (ident, qbytes)) + total_qstr_size += len(qstr) + + total_text_size = 0 + total_text_compressed_size = 0 + for original, translation in i18ns: + translation_encoded = translation.encode("utf-8") + compressed = compress(encoding_table, translation_encoded) + total_text_compressed_size += len(compressed) + decompressed = decompress(encoding_table, len(translation_encoded), compressed).decode("utf-8") + for c in C_ESCAPES: + decompressed = decompressed.replace(c, C_ESCAPES[c]) + print("TRANSLATION(\"{}\", {}, {{ {} }}) // {}".format(original, len(translation_encoded)+1, ", ".join(["0x{:02x}".format(x) for x in compressed]), decompressed)) + total_text_size += len(translation.encode("utf-8")) + + print() + print("// {} bytes worth of qstr".format(total_qstr_size)) + print("// {} bytes worth of translations".format(total_text_size)) + print("// {} bytes worth of translations compressed".format(total_text_compressed_size)) + print("// {} bytes saved".format(total_text_size - total_text_compressed_size)) + +def print_qstr_enums(qstrs): + # print out the starter of the generated C header file + print('// This file was automatically generated by makeqstrdata.py') + print('') -def do_work(infiles): - qcfgs, qstrs = parse_input_headers(infiles) - print_qstr_data(qcfgs, qstrs) + # add NULL qstr with no hash or data + print('QENUM(MP_QSTR_NULL)') + + # go through each qstr and print it out + for order, ident, qstr in sorted(qstrs.values(), key=lambda x: x[0]): + print('QENUM(MP_QSTR_%s)' % (ident,)) if __name__ == "__main__": - do_work(sys.argv[1:]) + import argparse + + parser = argparse.ArgumentParser(description='Process QSTR definitions into headers for compilation') + parser.add_argument('infiles', metavar='N', type=str, nargs='+', + help='an integer for the accumulator') + parser.add_argument('--translation', default=None, type=str, + help='translations for i18n() items') + parser.add_argument('--compression_filename', default=None, type=str, + help='header for compression info') + + args = parser.parse_args() + + qcfgs, qstrs, i18ns = parse_input_headers(args.infiles) + if args.translation: + translations = translate(args.translation, i18ns) + encoding_table = compute_huffman_coding(translations, qstrs, args.compression_filename) + print_qstr_data(encoding_table, qcfgs, qstrs, translations) + else: + print_qstr_enums(qstrs) diff --git a/py/makeqstrdefs.py b/py/makeqstrdefs.py index 176440136df..cb27ced3560 100644 --- a/py/makeqstrdefs.py +++ b/py/makeqstrdefs.py @@ -11,10 +11,51 @@ import sys import os +# Python 2/3 compatibility: +# - iterating through bytes is different +# - codepoint2name lives in a different module +import platform +if platform.python_version_tuple()[0] == '2': + bytes_cons = lambda val, enc=None: bytearray(val) + from htmlentitydefs import name2codepoint +elif platform.python_version_tuple()[0] == '3': + bytes_cons = bytes + from html.entities import name2codepoint + unichr = chr +# end compatibility code + # Blacklist of qstrings that are specially handled in further # processing and should be ignored QSTRING_BLACK_LIST = set(['NULL', 'number_of']) +# add some custom names to map characters that aren't in HTML +name2codepoint['hyphen'] = ord('-') +name2codepoint['space'] = ord(' ') +name2codepoint['squot'] = ord('\'') +name2codepoint['comma'] = ord(',') +name2codepoint['dot'] = ord('.') +name2codepoint['colon'] = ord(':') +name2codepoint['semicolon'] = ord(';') +name2codepoint['slash'] = ord('/') +name2codepoint['percent'] = ord('%') +name2codepoint['hash'] = ord('#') +name2codepoint['paren_open'] = ord('(') +name2codepoint['paren_close'] = ord(')') +name2codepoint['bracket_open'] = ord('[') +name2codepoint['bracket_close'] = ord(']') +name2codepoint['brace_open'] = ord('{') +name2codepoint['brace_close'] = ord('}') +name2codepoint['star'] = ord('*') +name2codepoint['bang'] = ord('!') +name2codepoint['backslash'] = ord('\\') +name2codepoint['plus'] = ord('+') +name2codepoint['dollar'] = ord('$') +name2codepoint['equals'] = ord('=') +name2codepoint['question'] = ord('?') +name2codepoint['at_sign'] = ord('@') +name2codepoint['caret'] = ord('^') +name2codepoint['pipe'] = ord('|') +name2codepoint['tilde'] = ord('~') def write_out(fname, output): if output: @@ -23,11 +64,21 @@ def write_out(fname, output): with open(args.output_dir + "/" + fname + ".qstr", "w") as f: f.write("\n".join(output) + "\n") +def qstr_unescape(qstr): + for name in name2codepoint: + if "__" + name + "__" in qstr: + continue + if "_" + name + "_" in qstr: + qstr = qstr.replace("_" + name + "_", str(unichr(name2codepoint[name]))) + return qstr + def process_file(f): - re_line = re.compile(r"#[line]*\s\d+\s\"([^\"]+)\"") + re_line = re.compile(r"#[line]*\s(\d+)\s\"([^\"]+)\"") re_qstr = re.compile(r'MP_QSTR_[_a-zA-Z0-9]+') + re_translate = re.compile(r'translate\(\"((?:(?=(\\?))\2.)*?)\"\)') output = [] last_fname = None + lineno = 0 for line in f: if line.isspace(): continue @@ -35,7 +86,9 @@ def process_file(f): if line.startswith(('# ', '#line')): m = re_line.match(line) assert m is not None - fname = m.group(1) + #print(m.groups()) + lineno = int(m.group(1)) + fname = m.group(2) if not fname.endswith(".c"): continue if fname != last_fname: @@ -46,7 +99,10 @@ def process_file(f): for match in re_qstr.findall(line): name = match.replace('MP_QSTR_', '') if name not in QSTRING_BLACK_LIST: - output.append('Q(' + name + ')') + output.append('Q(' + qstr_unescape(name) + ')') + for match in re_translate.findall(line): + output.append('TRANSLATE("' + match[0] + '")') + lineno += 1 write_out(last_fname, output) return "" diff --git a/py/makeversionhdr.py b/py/makeversionhdr.py index aedc292e4b6..7ceeaeadded 100644 --- a/py/makeversionhdr.py +++ b/py/makeversionhdr.py @@ -21,7 +21,7 @@ def get_version_info_from_git(): # Note: git describe doesn't work if no tag is available try: - git_tag = subprocess.check_output(["git", "describe", "--dirty", "--always"], stderr=subprocess.STDOUT, universal_newlines=True).strip() + git_tag = subprocess.check_output(["git", "describe", "--dirty", "--always", "--tags"], stderr=subprocess.STDOUT, universal_newlines=True).strip() except subprocess.CalledProcessError as er: if er.returncode == 128: # git exit code of 128 means no repository found @@ -47,17 +47,12 @@ def get_version_info_from_git(): return None # Try to extract MicroPython version from git tag - if git_tag.startswith("v"): - ver = git_tag[1:].split("-")[0].split(".") - if len(ver) == 2: - ver.append("0") - else: - ver = ["0", "0", "1"] + ver = git_tag.split("-")[0].split(".") return git_tag, git_hash, ver def get_version_info_from_docs_conf(): - with open(os.path.join(os.path.dirname(sys.argv[0]), "..", "docs", "conf.py")) as f: + with open(os.path.join(os.path.dirname(sys.argv[0]), "..", "conf.py")) as f: for line in f: if line.startswith("version = release = '"): ver = line.strip().split(" = ")[2].strip("'") @@ -75,6 +70,11 @@ def make_version_header(filename): info = get_version_info_from_docs_conf() git_tag, git_hash, ver = info + if len(ver) < 3: + ver = ("0", "0", "0") + version_string = git_hash + else: + version_string = ".".join(ver) # Generate the file with the git and version info file_data = """\ @@ -85,9 +85,10 @@ def make_version_header(filename): #define MICROPY_VERSION_MAJOR (%s) #define MICROPY_VERSION_MINOR (%s) #define MICROPY_VERSION_MICRO (%s) -#define MICROPY_VERSION_STRING "%s.%s.%s" +#define MICROPY_VERSION_STRING "%s" +#define MICROPY_FULL_VERSION_INFO ("Adafruit CircuitPython " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE "; " MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME) """ % (git_tag, git_hash, datetime.date.today().strftime("%Y-%m-%d"), - ver[0], ver[1], ver[2], ver[0], ver[1], ver[2]) + ver[0].replace('v', ''), ver[1], ver[2], version_string) # Check if the file contents changed from last time write_file = True @@ -99,7 +100,6 @@ def make_version_header(filename): # Only write the file if we need to if write_file: - print("GEN %s" % filename) with open(filename, 'w') as f: f.write(file_data) diff --git a/py/malloc.c b/py/malloc.c index ba5c952f3a8..f190582ab27 100644 --- a/py/malloc.c +++ b/py/malloc.c @@ -56,12 +56,15 @@ #undef malloc #undef free #undef realloc -#define malloc(b) gc_alloc((b), false) -#define malloc_with_finaliser(b) gc_alloc((b), true) +#define malloc_ll(b, ll) gc_alloc((b), false, (ll)) +#define malloc_with_finaliser(b) gc_alloc((b), true, false) #define free gc_free #define realloc(ptr, n) gc_realloc(ptr, n, true) #define realloc_ext(ptr, n, mv) gc_realloc(ptr, n, mv) #else +#define malloc_ll(b, ll) malloc(b) +#define malloc_with_finaliser(b) malloc((b)) + STATIC void *realloc_ext(void *ptr, size_t n_bytes, bool allow_move) { if (allow_move) { return realloc(ptr, n_bytes); @@ -74,8 +77,8 @@ STATIC void *realloc_ext(void *ptr, size_t n_bytes, bool allow_move) { } #endif // MICROPY_ENABLE_GC -void *m_malloc(size_t num_bytes) { - void *ptr = malloc(num_bytes); +void *m_malloc(size_t num_bytes, bool long_lived) { + void *ptr = malloc_ll(num_bytes, long_lived); if (ptr == NULL && num_bytes != 0) { m_malloc_fail(num_bytes); } @@ -88,8 +91,8 @@ void *m_malloc(size_t num_bytes) { return ptr; } -void *m_malloc_maybe(size_t num_bytes) { - void *ptr = malloc(num_bytes); +void *m_malloc_maybe(size_t num_bytes, bool long_lived) { + void *ptr = malloc_ll(num_bytes, long_lived); #if MICROPY_MEM_STATS MP_STATE_MEM(total_bytes_allocated) += num_bytes; MP_STATE_MEM(current_bytes_allocated) += num_bytes; @@ -115,8 +118,8 @@ void *m_malloc_with_finaliser(size_t num_bytes) { } #endif -void *m_malloc0(size_t num_bytes) { - void *ptr = m_malloc(num_bytes); +void *m_malloc0(size_t num_bytes, bool long_lived) { + void *ptr = m_malloc(num_bytes, long_lived); // If this config is set then the GC clears all memory, so we don't need to. #if !MICROPY_GC_CONSERVATIVE_CLEAR memset(ptr, 0, num_bytes); diff --git a/py/misc.h b/py/misc.h index e6d25b8509b..673568f2266 100644 --- a/py/misc.h +++ b/py/misc.h @@ -34,6 +34,8 @@ #include #include +#include "mpconfig.h" + typedef unsigned char byte; typedef unsigned int uint; @@ -57,13 +59,18 @@ typedef unsigned int uint; // TODO make a lazy m_renew that can increase by a smaller amount than requested (but by at least 1 more element) -#define m_new(type, num) ((type*)(m_malloc(sizeof(type) * (num)))) -#define m_new_maybe(type, num) ((type*)(m_malloc_maybe(sizeof(type) * (num)))) -#define m_new0(type, num) ((type*)(m_malloc0(sizeof(type) * (num)))) +#define m_new(type, num) ((type*)(m_malloc(sizeof(type) * (num), false))) +#define m_new_ll(type, num) ((type*)(m_malloc(sizeof(type) * (num), true))) +#define m_new_maybe(type, num) ((type*)(m_malloc_maybe(sizeof(type) * (num), false))) +#define m_new_ll_maybe(type, num) ((type*)(m_malloc_maybe(sizeof(type) * (num), true))) +#define m_new0(type, num) ((type*)(m_malloc0(sizeof(type) * (num), false))) +#define m_new0_ll(type, num) ((type*)(m_malloc0(sizeof(type) * (num), true))) #define m_new_obj(type) (m_new(type, 1)) +#define m_new_ll_obj(type) (m_new_ll(type, 1)) #define m_new_obj_maybe(type) (m_new_maybe(type, 1)) -#define m_new_obj_var(obj_type, var_type, var_num) ((obj_type*)m_malloc(sizeof(obj_type) + sizeof(var_type) * (var_num))) -#define m_new_obj_var_maybe(obj_type, var_type, var_num) ((obj_type*)m_malloc_maybe(sizeof(obj_type) + sizeof(var_type) * (var_num))) +#define m_new_obj_var(obj_type, var_type, var_num) ((obj_type*)m_malloc(sizeof(obj_type) + sizeof(var_type) * (var_num), false)) +#define m_new_obj_var_maybe(obj_type, var_type, var_num) ((obj_type*)m_malloc_maybe(sizeof(obj_type) + sizeof(var_type) * (var_num), false)) +#define m_new_ll_obj_var_maybe(obj_type, var_type, var_num) ((obj_type*)m_malloc_maybe(sizeof(obj_type) + sizeof(var_type) * (var_num), true)) #if MICROPY_ENABLE_FINALISER #define m_new_obj_with_finaliser(type) ((type*)(m_malloc_with_finaliser(sizeof(type)))) #define m_new_obj_var_with_finaliser(type, var_type, var_num) ((type*)m_malloc_with_finaliser(sizeof(type) + sizeof(var_type) * (var_num))) @@ -84,10 +91,10 @@ typedef unsigned int uint; #endif #define m_del_obj(type, ptr) (m_del(type, ptr, 1)) -void *m_malloc(size_t num_bytes); -void *m_malloc_maybe(size_t num_bytes); +void *m_malloc(size_t num_bytes, bool long_lived); +void *m_malloc_maybe(size_t num_bytes, bool long_lived); void *m_malloc_with_finaliser(size_t num_bytes); -void *m_malloc0(size_t num_bytes); +void *m_malloc0(size_t num_bytes, bool long_lived); #if MICROPY_MALLOC_USES_ALLOCATED_SIZE void *m_realloc(void *ptr, size_t old_num_bytes, size_t new_num_bytes); void *m_realloc_maybe(void *ptr, size_t old_num_bytes, size_t new_num_bytes, bool allow_move); diff --git a/py/mkenv.mk b/py/mkenv.mk index 2c9c86a7ae2..b76dd60f856 100644 --- a/py/mkenv.mk +++ b/py/mkenv.mk @@ -24,12 +24,17 @@ BUILD_VERBOSE = 0 endif ifeq ($(BUILD_VERBOSE),0) Q = @ +STEPECHO = @: +else ifeq ($(BUILD_VERBOSE),1) +Q = @ +STEPECHO = @echo else Q = +STEPECHO = @echo endif # Since this is a new feature, advertise it ifeq ($(BUILD_VERBOSE),0) -$(info Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.) +$(info Use make V=1, make V=2 or set BUILD_VERBOSE similarly in your environment to increase build verbosity.) endif # default settings; can be overridden in main Makefile @@ -37,12 +42,19 @@ endif PY_SRC ?= $(TOP)/py BUILD ?= build -RM = rm ECHO = @echo + +CD = cd CP = cp +FIND = find MKDIR = mkdir -SED = sed PYTHON = python +# Set default python interpreters +PYTHON2 ?= $(which python2 || which python2.7) +PYTHON3 ?= python3 +RM = rm +RSYNC = rsync +SED = sed AS = $(CROSS_COMPILE)as CC = $(CROSS_COMPILE)gcc @@ -60,7 +72,8 @@ endif MAKE_FROZEN = $(PYTHON) $(TOP)/tools/make-frozen.py MPY_CROSS = $(TOP)/mpy-cross/mpy-cross -MPY_TOOL = $(PYTHON) $(TOP)/tools/mpy-tool.py +MPY_TOOL = $(PYTHON3) $(TOP)/tools/mpy-tool.py +PREPROCESS_FROZEN_MODULES = PYTHONPATH=$(TOP)/tools/python-semver $(TOP)/tools/preprocess_frozen_modules.py all: .PHONY: all diff --git a/py/mkrules.mk b/py/mkrules.mk index 30ac520aa1c..292d2574651 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -20,18 +20,18 @@ endif # can be located. By following this scheme, it allows a single build rule # to be used to compile all .c files. -vpath %.S . $(TOP) +vpath %.S . $(TOP) $(USER_C_MODULES) $(BUILD)/%.o: %.S - $(ECHO) "CC $<" + $(STEPECHO) "CC $<" $(Q)$(CC) $(CFLAGS) -c -o $@ $< -vpath %.s . $(TOP) +vpath %.s . $(TOP) $(USER_C_MODULES) $(BUILD)/%.o: %.s - $(ECHO) "AS $<" + $(STEPECHO) "AS $<" $(Q)$(AS) -o $@ $< define compile_c -$(ECHO) "CC $<" +$(STEPECHO) "CC $<" $(Q)$(CC) $(CFLAGS) -c -MD -o $@ $< @# The following fixes the dependency file. @# See http://make.paulandlesley.org/autodep.html for details. @@ -42,17 +42,24 @@ $(Q)$(CC) $(CFLAGS) -c -MD -o $@ $< $(RM) -f $(@:.o=.d) endef -vpath %.c . $(TOP) +vpath %.c . $(TOP) $(USER_C_MODULES) $(BUILD)/%.o: %.c $(call compile_c) QSTR_GEN_EXTRA_CFLAGS += -DNO_QSTR + +# frozen.c and frozen_mpy.c are created in $(BUILD), so use our rule +# for those as well. +vpath %.c . $(BUILD) +$(BUILD)/%.o: %.c + $(call compile_c) + QSTR_GEN_EXTRA_CFLAGS += -I$(BUILD)/tmp -vpath %.c . $(TOP) +vpath %.c . $(TOP) $(USER_C_MODULES) $(BUILD)/%.pp: %.c - $(ECHO) "PreProcess $<" + $(STEPECHO) "PreProcess $<" $(Q)$(CC) $(CFLAGS) -E -Wp,-C,-dD,-dI -o $@ $< # The following rule uses | to create an order only prerequisite. Order only @@ -64,24 +71,24 @@ $(BUILD)/%.pp: %.c # the right .o's to get recompiled if the generated.h file changes. Adding # an order-only dependency to all of the .o's will cause the generated .h # to get built before we try to compile any of them. -$(OBJ): | $(HEADER_BUILD)/qstrdefs.generated.h $(HEADER_BUILD)/mpversion.h +$(OBJ): | $(HEADER_BUILD)/qstrdefs.enum.h $(HEADER_BUILD)/mpversion.h # The logic for qstr regeneration is: # - if anything in QSTR_GLOBAL_DEPENDENCIES is newer, then process all source files ($^) # - else, if list of newer prerequisites ($?) is not empty, then process just these ($?) # - else, process all source files ($^) [this covers "make -B" which can set $? to empty] -$(HEADER_BUILD)/qstr.i.last: $(SRC_QSTR) $(QSTR_GLOBAL_DEPENDENCIES) | $(HEADER_BUILD)/mpversion.h - $(ECHO) "GEN $@" - $(Q)$(CPP) $(QSTR_GEN_EXTRA_CFLAGS) $(CFLAGS) $(if $(filter $?,$(QSTR_GLOBAL_DEPENDENCIES)),$^,$(if $?,$?,$^)) >$(HEADER_BUILD)/qstr.i.last; +$(HEADER_BUILD)/qstr.i.last: $(SRC_QSTR) $(SRC_QSTR_PREPROCESSOR) $(QSTR_GLOBAL_DEPENDENCIES) | $(HEADER_BUILD)/mpversion.h + $(STEPECHO) "GEN $@" + $(Q)grep -lE "(MP_QSTR|translate)" $(if $(filter $?,$(QSTR_GLOBAL_DEPENDENCIES)),$^,$(if $?,$?,$^)) | xargs $(CPP) $(QSTR_GEN_EXTRA_CFLAGS) $(CFLAGS) $(SRC_QSTR_PREPROCESSOR) >$(HEADER_BUILD)/qstr.i.last; -$(HEADER_BUILD)/qstr.split: $(HEADER_BUILD)/qstr.i.last - $(ECHO) "GEN $@" - $(Q)$(PYTHON) $(PY_SRC)/makeqstrdefs.py split $(HEADER_BUILD)/qstr.i.last $(HEADER_BUILD)/qstr $(QSTR_DEFS_COLLECTED) +$(HEADER_BUILD)/qstr.split: $(HEADER_BUILD)/qstr.i.last $(PY_SRC)/makeqstrdefs.py + $(STEPECHO) "GEN $@" + $(Q)$(PYTHON3) $(PY_SRC)/makeqstrdefs.py split $(HEADER_BUILD)/qstr.i.last $(HEADER_BUILD)/qstr $(QSTR_DEFS_COLLECTED) $(Q)touch $@ -$(QSTR_DEFS_COLLECTED): $(HEADER_BUILD)/qstr.split - $(ECHO) "GEN $@" - $(Q)$(PYTHON) $(PY_SRC)/makeqstrdefs.py cat $(HEADER_BUILD)/qstr.i.last $(HEADER_BUILD)/qstr $(QSTR_DEFS_COLLECTED) +$(QSTR_DEFS_COLLECTED): $(HEADER_BUILD)/qstr.split $(PY_SRC)/makeqstrdefs.py + $(STEPECHO) "GEN $@" + $(Q)$(PYTHON3) $(PY_SRC)/makeqstrdefs.py cat $(HEADER_BUILD)/qstr.i.last $(HEADER_BUILD)/qstr $(QSTR_DEFS_COLLECTED) # $(sort $(var)) removes duplicates # @@ -91,36 +98,41 @@ $(QSTR_DEFS_COLLECTED): $(HEADER_BUILD)/qstr.split OBJ_DIRS = $(sort $(dir $(OBJ))) $(OBJ): | $(OBJ_DIRS) $(OBJ_DIRS): - $(MKDIR) -p $@ + $(Q)$(MKDIR) -p $@ $(HEADER_BUILD): - $(MKDIR) -p $@ + $(Q)$(MKDIR) -p $@ ifneq ($(FROZEN_DIR),) $(BUILD)/frozen.c: $(wildcard $(FROZEN_DIR)/*) $(HEADER_BUILD) $(FROZEN_EXTRA_DEPS) - $(ECHO) "GEN $@" + $(STEPECHO) "Generating $@" $(Q)$(MAKE_FROZEN) $(FROZEN_DIR) > $@ endif -ifneq ($(FROZEN_MPY_DIR),) +ifneq ($(FROZEN_MPY_DIRS),) # to build the MicroPython cross compiler -$(TOP)/mpy-cross/mpy-cross: $(TOP)/py/*.[ch] $(TOP)/mpy-cross/*.[ch] $(TOP)/ports/windows/fmode.c +# Currently not used, because the wrong mpy-cross may be left over from a previous build. Build by hand to make sure. +$(MPY_CROSS): $(TOP)/py/*.[ch] $(TOP)/mpy-cross/*.[ch] $(TOP)/ports/windows/fmode.c $(Q)$(MAKE) -C $(TOP)/mpy-cross -# make a list of all the .py files that need compiling and freezing -FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py' | $(SED) -e 's=^$(FROZEN_MPY_DIR)/==') -FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/frozen_mpy/,$(FROZEN_MPY_PY_FILES:.py=.mpy)) - -# to build .mpy files from .py files -$(BUILD)/frozen_mpy/%.mpy: $(FROZEN_MPY_DIR)/%.py $(TOP)/mpy-cross/mpy-cross - @$(ECHO) "MPY $<" - $(Q)$(MKDIR) -p $(dir $@) - $(Q)$(MPY_CROSS) -o $@ -s $(<:$(FROZEN_MPY_DIR)/%=%) $(MPY_CROSS_FLAGS) $< +# Copy all the modules and single python files to freeze to a common area, omitting top-level dirs (the repo names). +# Do any preprocessing necessary: currently, this adds version information, removes examples, and +# non-library .py files in the modules (setup.py and conf.py) +# Then compile .mpy files from all the .py files, placing them in the same directories as the .py files. +$(BUILD)/frozen_mpy: $(FROZEN_MPY_DIRS) + $(ECHO) FREEZE $(FROZEN_MPY_DIRS) + $(Q)$(MKDIR) -p $@ + $(Q)$(PREPROCESS_FROZEN_MODULES) -o $@ $(FROZEN_MPY_DIRS) + $(Q)$(CD) $@ && \ +$(FIND) -L . -type f -name '*.py' | sed 's=^\./==' | \ +xargs -n1 "$(abspath $(MPY_CROSS))" $(MPY_CROSS_FLAGS) # to build frozen_mpy.c from all .mpy files -$(BUILD)/frozen_mpy.c: $(FROZEN_MPY_MPY_FILES) $(BUILD)/genhdr/qstrdefs.generated.h - @$(ECHO) "GEN $@" - $(Q)$(MPY_TOOL) -f -q $(BUILD)/genhdr/qstrdefs.preprocessed.h $(FROZEN_MPY_MPY_FILES) > $@ +# You need to define MPY_TOOL_LONGINT_IMPL in mpconfigport.mk +# if the default will not work (mpz is the default). +$(BUILD)/frozen_mpy.c: $(BUILD)/frozen_mpy $(BUILD)/genhdr/qstrdefs.generated.h $(TOP)/tools/mpy-tool.py + $(STEPECHO) "Creating $@" + $(Q)$(MPY_TOOL) $(MPY_TOOL_LONGINT_IMPL) -f -q $(BUILD)/genhdr/qstrdefs.preprocessed.h $(shell $(FIND) -L $(BUILD)/frozen_mpy -type f -name '*.mpy') > $@ endif ifneq ($(PROG),) @@ -129,7 +141,7 @@ ifneq ($(PROG),) all: $(PROG) $(PROG): $(OBJ) - $(ECHO) "LINK $@" + $(STEPECHO) "LINK $@" # Do not pass COPT here - it's *C* compiler optimizations. For example, # we may want to compile using Thumb, but link with non-Thumb libc. $(Q)$(CC) -o $@ $^ $(LIB) $(LDFLAGS) @@ -194,4 +206,7 @@ print-def: @$(CC) -E -Wp,-dM __empty__.c @$(RM) -f __empty__.c +tags: + ctags -e -R $(TOP) + -include $(OBJ:.o=.P) diff --git a/py/modbuiltins.c b/py/modbuiltins.c index c169b2ee495..e764f1987ef 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -35,6 +35,8 @@ #include "py/builtin.h" #include "py/stream.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_BUILTINS_FLOAT #include #endif @@ -79,7 +81,7 @@ STATIC mp_obj_t mp_builtin___build_class__(size_t n_args, const mp_obj_t *args) meta_args[2] = class_locals; // dict of members mp_obj_t new_class = mp_call_function_n_kw(meta, 3, 0, meta_args); - // store into cell if neede + // store into cell if needed if (cell != mp_const_none) { mp_obj_cell_set(cell, new_class); } @@ -157,7 +159,7 @@ STATIC mp_obj_t mp_builtin_chr(mp_obj_t o_in) { str[3] = (c & 0x3F) | 0x80; len = 4; } else { - mp_raise_ValueError("chr() arg not in range(0x110000)"); + mp_raise_ValueError(translate("chr() arg not in range(0x110000)")); } return mp_obj_new_str_via_qstr((char*)str, len); #else @@ -166,7 +168,7 @@ STATIC mp_obj_t mp_builtin_chr(mp_obj_t o_in) { uint8_t str[1] = {ord}; return mp_obj_new_str_via_qstr((char*)str, 1); } else { - mp_raise_ValueError("chr() arg not in range(256)"); + mp_raise_ValueError(translate("chr() arg not in range(256)")); } #endif } @@ -280,7 +282,7 @@ STATIC mp_obj_t mp_builtin_min_max(size_t n_args, const mp_obj_t *args, mp_map_t if (default_elem != NULL) { best_obj = default_elem->value; } else { - mp_raise_ValueError("arg is an empty sequence"); + mp_raise_ValueError(translate("arg is an empty sequence")); } } return best_obj; @@ -314,7 +316,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_min_obj, 1, mp_builtin_min); STATIC mp_obj_t mp_builtin_next(mp_obj_t o) { mp_obj_t ret = mp_iternext_allow_raise(o); if (ret == MP_OBJ_STOP_ITERATION) { - nlr_raise(mp_obj_new_exception(&mp_type_StopIteration)); + mp_raise_msg(&mp_type_StopIteration, NULL); } else { return ret; } @@ -345,10 +347,10 @@ STATIC mp_obj_t mp_builtin_ord(mp_obj_t o_in) { } if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("ord expects a character"); + mp_raise_TypeError(translate("ord expects a character")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "ord() expected a character, but string of length %d found", (int)len)); + mp_raise_TypeError_varg( + translate("ord() expected a character, but string of length %d found"), (int)len); } } MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_ord_obj, mp_builtin_ord); @@ -358,7 +360,7 @@ STATIC mp_obj_t mp_builtin_pow(size_t n_args, const mp_obj_t *args) { case 2: return mp_binary_op(MP_BINARY_OP_POWER, args[0], args[1]); default: #if !MICROPY_PY_BUILTINS_POW3 - mp_raise_msg(&mp_type_NotImplementedError, "3-arg pow() not supported"); + mp_raise_msg(&mp_type_NotImplementedError, translate("3-arg pow() not supported")); #elif MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_MPZ return mp_binary_op(MP_BINARY_OP_MODULO, mp_binary_op(MP_BINARY_OP_POWER, args[0], args[1]), args[2]); #else @@ -369,10 +371,11 @@ STATIC mp_obj_t mp_builtin_pow(size_t n_args, const mp_obj_t *args) { MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_pow_obj, 2, 3, mp_builtin_pow); STATIC mp_obj_t mp_builtin_print(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_sep, ARG_end, ARG_file }; + enum { ARG_sep, ARG_end, ARG_flush, ARG_file }; static const mp_arg_t allowed_args[] = { { MP_QSTR_sep, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_QSTR(MP_QSTR__space_)} }, { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_QSTR(MP_QSTR__0x0a_)} }, + { MP_QSTR_flush, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES { MP_QSTR_file, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_sys_stdout_obj)} }, #endif @@ -412,6 +415,9 @@ STATIC mp_obj_t mp_builtin_print(size_t n_args, const mp_obj_t *pos_args, mp_map } #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES mp_stream_write_adaptor(print.data, end_data, u.len[1]); + if (u.args[ARG_flush].u_bool) { + mp_stream_flush(MP_OBJ_FROM_PTR(print.data)); + } #else mp_print_strn(&mp_plat_print, end_data, u.len[1], 0, 0, 0); #endif @@ -449,13 +455,13 @@ STATIC mp_obj_t mp_builtin_round(size_t n_args, const mp_obj_t *args) { return o_in; } - #if !MICROPY_PY_BUILTINS_ROUND_INT - mp_raise_NotImplementedError(NULL); - #else mp_int_t num_dig = mp_obj_get_int(args[1]); if (num_dig >= 0) { return o_in; } + #if !MICROPY_PY_BUILTINS_ROUND_INT + mp_raise_NotImplementedError(NULL); + #else mp_obj_t mult = mp_binary_op(MP_BINARY_OP_POWER, MP_OBJ_NEW_SMALL_INT(10), MP_OBJ_NEW_SMALL_INT(-num_dig)); mp_obj_t half_mult = mp_binary_op(MP_BINARY_OP_FLOOR_DIVIDE, mult, MP_OBJ_NEW_SMALL_INT(2)); @@ -512,9 +518,9 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_sum_obj, 1, 2, mp_builtin_sum); STATIC mp_obj_t mp_builtin_sorted(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { if (n_args > 1) { - mp_raise_TypeError("must use keyword argument for key function"); + mp_raise_TypeError(translate("must use keyword argument for key function")); } - mp_obj_t self = mp_type_list.make_new(&mp_type_list, 1, 0, args); + mp_obj_t self = mp_type_list.make_new(&mp_type_list, 1, args, NULL); mp_obj_list_sort(1, &self, kwargs); return self; @@ -712,9 +718,11 @@ STATIC const mp_rom_map_elem_t mp_module_builtins_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_IndentationError), MP_ROM_PTR(&mp_type_IndentationError) }, { MP_ROM_QSTR(MP_QSTR_IndexError), MP_ROM_PTR(&mp_type_IndexError) }, { MP_ROM_QSTR(MP_QSTR_KeyboardInterrupt), MP_ROM_PTR(&mp_type_KeyboardInterrupt) }, + { MP_ROM_QSTR(MP_QSTR_ReloadException), MP_ROM_PTR(&mp_type_ReloadException) }, { MP_ROM_QSTR(MP_QSTR_KeyError), MP_ROM_PTR(&mp_type_KeyError) }, { MP_ROM_QSTR(MP_QSTR_LookupError), MP_ROM_PTR(&mp_type_LookupError) }, { MP_ROM_QSTR(MP_QSTR_MemoryError), MP_ROM_PTR(&mp_type_MemoryError) }, + { MP_ROM_QSTR(MP_QSTR_MpyError), MP_ROM_PTR(&mp_type_MpyError) }, { MP_ROM_QSTR(MP_QSTR_NameError), MP_ROM_PTR(&mp_type_NameError) }, { MP_ROM_QSTR(MP_QSTR_NotImplementedError), MP_ROM_PTR(&mp_type_NotImplementedError) }, { MP_ROM_QSTR(MP_QSTR_OSError), MP_ROM_PTR(&mp_type_OSError) }, diff --git a/py/modcollections.c b/py/modcollections.c index bb6488471c7..91e7355281f 100644 --- a/py/modcollections.c +++ b/py/modcollections.c @@ -29,7 +29,7 @@ #if MICROPY_PY_COLLECTIONS STATIC const mp_rom_map_elem_t mp_module_collections_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ucollections) }, + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_collections) }, #if MICROPY_PY_COLLECTIONS_DEQUE { MP_ROM_QSTR(MP_QSTR_deque), MP_ROM_PTR(&mp_type_deque) }, #endif diff --git a/py/modio.c b/py/modio.c index e75432b28d2..d7c1a58a8c2 100644 --- a/py/modio.c +++ b/py/modio.c @@ -46,11 +46,11 @@ STATIC const mp_obj_type_t mp_type_iobase; STATIC mp_obj_base_t iobase_singleton = {&mp_type_iobase}; -STATIC mp_obj_t iobase_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t iobase_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type; (void)n_args; - (void)n_kw; (void)args; + (void)kw_args; return MP_OBJ_FROM_PTR(&iobase_singleton); } @@ -113,8 +113,8 @@ typedef struct _mp_obj_bufwriter_t { byte buf[0]; } mp_obj_bufwriter_t; -STATIC mp_obj_t bufwriter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 2, 2, false); +STATIC mp_obj_t bufwriter_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 2, 2, false); size_t alloc = mp_obj_get_int(args[1]); mp_obj_bufwriter_t *o = m_new_obj_var(mp_obj_bufwriter_t, byte, alloc); o->base.type = type; @@ -230,14 +230,14 @@ STATIC mp_obj_t resource_stream(mp_obj_t package_in, mp_obj_t path_in) { const char *path = mp_obj_str_get_data(path_in, &len); vstr_add_strn(&path_buf, path, len); - len = path_buf.len; - const char *data = mp_find_frozen_str(path_buf.buf, &len); + size_t file_len; + const char *data = mp_find_frozen_str(path_buf.buf, path_buf.len, &file_len); if (data != NULL) { mp_obj_stringio_t *o = m_new_obj(mp_obj_stringio_t); o->base.type = &mp_type_bytesio; o->vstr = m_new_obj(vstr_t); - vstr_init_fixed_buf(o->vstr, len + 1, (char*)data); - o->vstr->len = len; + vstr_init_fixed_buf(o->vstr, file_len + 1, (char*)data); + o->vstr->len = file_len; o->pos = 0; return MP_OBJ_FROM_PTR(o); } diff --git a/py/modmath.c b/py/modmath.c index 7eda7594d97..9d75ea2d528 100644 --- a/py/modmath.c +++ b/py/modmath.c @@ -27,6 +27,8 @@ #include "py/builtin.h" #include "py/runtime.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_BUILTINS_FLOAT && MICROPY_PY_MATH #include @@ -36,7 +38,7 @@ #define MP_PI MICROPY_FLOAT_CONST(3.14159265358979323846) STATIC NORETURN void math_error(void) { - mp_raise_ValueError("math domain error"); + mp_raise_ValueError(translate("math domain error")); } STATIC mp_obj_t math_generic_1(mp_obj_t x_obj, mp_float_t (*f)(mp_float_t)) { @@ -186,8 +188,12 @@ STATIC mp_obj_t mp_math_log(size_t n_args, const mp_obj_t *args) { mp_float_t base = mp_obj_get_float(args[1]); if (base <= (mp_float_t)0.0) { math_error(); +// Turn off warning when comparing exactly with integral value 1.0 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" } else if (base == (mp_float_t)1.0) { - mp_raise_msg(&mp_type_ZeroDivisionError, "division by zero"); +#pragma GCC diagnostic pop + mp_raise_msg(&mp_type_ZeroDivisionError, translate("division by zero")); } return mp_obj_new_float(l / MICROPY_FLOAT_C_FUN(log)(base)); } diff --git a/py/modmicropython.c b/py/modmicropython.c index 864d1a5c5bc..a45d44653a5 100644 --- a/py/modmicropython.c +++ b/py/modmicropython.c @@ -32,6 +32,8 @@ #include "py/gc.h" #include "py/mphal.h" +#include "supervisor/shared/translate.h" + // Various builtins specific to MicroPython runtime, // living in micropython module @@ -150,7 +152,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_micropython_kbd_intr_obj, mp_micropython_kbd #if MICROPY_ENABLE_SCHEDULER STATIC mp_obj_t mp_micropython_schedule(mp_obj_t function, mp_obj_t arg) { if (!mp_sched_schedule(function, arg)) { - mp_raise_msg(&mp_type_RuntimeError, "schedule stack full"); + mp_raise_msg(&mp_type_RuntimeError, translate("schedule stack full")); } return mp_const_none; } diff --git a/py/modstruct.c b/py/modstruct.c index 8617a8e0d3e..a238d3935a2 100644 --- a/py/modstruct.c +++ b/py/modstruct.c @@ -33,6 +33,7 @@ #include "py/objtuple.h" #include "py/binary.h" #include "py/parsenum.h" +#include "supervisor/shared/translate.h" #if MICROPY_PY_STRUCT @@ -96,7 +97,10 @@ STATIC size_t calc_size_items(const char *fmt, size_t *total_sz) { total_cnt += 1; size += cnt; } else { - total_cnt += cnt; + // Pad bytes are skipped and don't get included in the item count. + if (*fmt != 'x') { + total_cnt += cnt; + } mp_uint_t align; size_t sz = mp_binary_get_size(fmt_type, *fmt, &align); while (cnt--) { @@ -141,7 +145,7 @@ STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) { // negative offsets are relative to the end of the buffer offset = bufinfo.len + offset; if (offset < 0) { - mp_raise_ValueError("buffer too small"); + mp_raise_ValueError(translate("buffer too small")); } } p += offset; @@ -149,7 +153,7 @@ STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) { // Check that the input buffer is big enough to unpack all the values if (p + total_sz > end_p) { - mp_raise_ValueError("buffer too small"); + mp_raise_ValueError(translate("buffer too small")); } for (size_t i = 0; i < num_items;) { @@ -165,7 +169,10 @@ STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) { } else { while (cnt--) { item = mp_binary_get_val(fmt_type, *fmt, &p); - res->items[i++] = item; + // Pad bytes ('x') are just skipped. + if (*fmt != 'x') { + res->items[i++] = item; + } } } fmt++; @@ -203,7 +210,11 @@ STATIC void struct_pack_into_internal(mp_obj_t fmt_in, byte *p, size_t n_args, c } else { // If we run out of args then we just finish; CPython would raise struct.error while (cnt-- && i < n_args) { - mp_binary_set_val(fmt_type, *fmt, args[i++], &p); + mp_binary_set_val(fmt_type, *fmt, args[i], &p); + // Pad bytes don't have a corresponding argument. + if (*fmt != 'x') { + i++; + } } } fmt++; @@ -230,7 +241,7 @@ STATIC mp_obj_t struct_pack_into(size_t n_args, const mp_obj_t *args) { // negative offsets are relative to the end of the buffer offset = (mp_int_t)bufinfo.len + offset; if (offset < 0) { - mp_raise_ValueError("buffer too small"); + mp_raise_ValueError(translate("buffer too small")); } } byte *p = (byte *)bufinfo.buf; @@ -240,7 +251,7 @@ STATIC mp_obj_t struct_pack_into(size_t n_args, const mp_obj_t *args) { // Check that the output buffer is big enough to hold all the values mp_int_t sz = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0])); if (p + sz > end_p) { - mp_raise_ValueError("buffer too small"); + mp_raise_ValueError(translate("buffer too small")); } struct_pack_into_internal(args[0], p, n_args - 3, &args[3]); diff --git a/py/modsys.c b/py/modsys.c index 98addfcfc07..68e048d91d7 100644 --- a/py/modsys.c +++ b/py/modsys.c @@ -69,7 +69,7 @@ STATIC MP_DEFINE_ATTRTUPLE( mp_sys_implementation_obj, impl_fields, 2, - MP_ROM_QSTR(MP_QSTR_micropython), + MP_ROM_QSTR(MP_QSTR_circuitpython), MP_ROM_PTR(&mp_sys_implementation_version_info_obj) ); #else @@ -77,7 +77,7 @@ STATIC const mp_rom_obj_tuple_t mp_sys_implementation_obj = { {&mp_type_tuple}, 2, { - MP_ROM_QSTR(MP_QSTR_micropython), + MP_OBJ_NEW_QSTR(MP_QSTR_circuitpython), MP_ROM_PTR(&mp_sys_implementation_version_info_obj), } }; @@ -135,7 +135,7 @@ STATIC mp_obj_t mp_sys_exc_info(void) { t->items[0] = MP_OBJ_FROM_PTR(mp_obj_get_type(cur_exc)); t->items[1] = cur_exc; - t->items[2] = mp_const_none; + t->items[2] = mp_obj_exception_get_traceback_obj(cur_exc); return MP_OBJ_FROM_PTR(t); } MP_DEFINE_CONST_FUN_OBJ_0(mp_sys_exc_info_obj, mp_sys_exc_info); diff --git a/py/modthread.c b/py/modthread.c index 61ada503515..1c00f6397ed 100644 --- a/py/modthread.c +++ b/py/modthread.c @@ -30,6 +30,8 @@ #include "py/runtime.h" #include "py/stackctrl.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_THREAD #include "py/mpthread.h" @@ -235,7 +237,7 @@ STATIC mp_obj_t mod_thread_start_new_thread(size_t n_args, const mp_obj_t *args) } else { // positional and keyword arguments if (mp_obj_get_type(args[2]) != &mp_type_dict) { - mp_raise_TypeError("expecting a dict for keyword args"); + mp_raise_TypeError(translate("expecting a dict for keyword args")); } mp_map_t *map = &((mp_obj_dict_t*)MP_OBJ_TO_PTR(args[2]))->map; th_args = m_new_obj_var(thread_entry_args_t, mp_obj_t, pos_args_len + 2 * map->used); diff --git a/py/moduerrno.c b/py/moduerrno.c index de66c941b0e..7915603e4e6 100644 --- a/py/moduerrno.c +++ b/py/moduerrno.c @@ -30,7 +30,7 @@ #include "py/obj.h" #include "py/mperrno.h" -#if MICROPY_PY_UERRNO +#include "supervisor/shared/translate.h" // This list can be defined per port in mpconfigport.h to tailor it to a // specific port's needs. If it's not defined then we provide a default. @@ -61,6 +61,8 @@ #endif +#if MICROPY_PY_UERRNO + #if MICROPY_PY_UERRNO_ERRORCODE STATIC const mp_rom_map_elem_t errorcode_table[] = { #define X(e) { MP_ROM_INT(MP_ ## e), MP_ROM_QSTR(MP_QSTR_## e) }, @@ -82,7 +84,11 @@ STATIC const mp_obj_dict_t errorcode_dict = { #endif STATIC const mp_rom_map_elem_t mp_module_uerrno_globals_table[] = { +#if CIRCUITPY + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_errno) }, +#else { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uerrno) }, +#endif #if MICROPY_PY_UERRNO_ERRORCODE { MP_ROM_QSTR(MP_QSTR_errorcode), MP_ROM_PTR(&errorcode_dict) }, #endif @@ -99,24 +105,64 @@ const mp_obj_module_t mp_module_uerrno = { .globals = (mp_obj_dict_t*)&mp_module_uerrno_globals, }; -qstr mp_errno_to_str(mp_obj_t errno_val) { +const char* mp_errno_to_str(mp_obj_t errno_val) { + // Otherwise, return the Exxxx string for that error code #if MICROPY_PY_UERRNO_ERRORCODE // We have the errorcode dict so can do a lookup using the hash map mp_map_elem_t *elem = mp_map_lookup((mp_map_t*)&errorcode_dict.map, errno_val, MP_MAP_LOOKUP); if (elem == NULL) { - return MP_QSTR_NULL; + return ""; } else { - return MP_OBJ_QSTR_VALUE(elem->value); + return qstr_str(MP_OBJ_QSTR_VALUE(elem->value)); } #else // We don't have the errorcode dict so do a simple search in the modules dict for (size_t i = 0; i < MP_ARRAY_SIZE(mp_module_uerrno_globals_table); ++i) { if (errno_val == mp_module_uerrno_globals_table[i].value) { - return MP_OBJ_QSTR_VALUE(mp_module_uerrno_globals_table[i].key); + return qstr_str(MP_OBJ_QSTR_VALUE(mp_module_uerrno_globals_table[i].key)); } } - return MP_QSTR_NULL; + return ""; #endif } +#else //MICROPY_PY_UERRNO + +const char* mp_errno_to_str(mp_obj_t errno_val) { + int v = MP_OBJ_SMALL_INT_VALUE(errno_val); + #define X(e) if (v == e) return qstr_str(MP_QSTR_ ## e); + MICROPY_PY_UERRNO_LIST + #undef X + + return ""; +} + #endif //MICROPY_PY_UERRNO + + +// For commonly encountered errors, return human readable strings, otherwise try errno name +const char *mp_common_errno_to_str(mp_obj_t errno_val, char *buf, size_t len) { + if (!MP_OBJ_IS_SMALL_INT(errno_val)) { + return NULL; + } + + const compressed_string_t* desc = NULL; + switch (MP_OBJ_SMALL_INT_VALUE(errno_val)) { + case EPERM: desc = translate("Permission denied"); break; + case ENOENT: desc = translate("No such file/directory"); break; + case EIO: desc = translate("Input/output error"); break; + case EACCES: desc = translate("Permission denied"); break; + case EEXIST: desc = translate("File exists"); break; + case ENODEV: desc = translate("Unsupported operation"); break; + case EINVAL: desc = translate("Invalid argument"); break; + case ENOSPC: desc = translate("No space left on device"); break; + case EROFS: desc = translate("Read-only filesystem"); break; + } + if (desc != NULL && desc->length <= len) { + decompress(desc, buf); + return buf; + } + + const char *msg = mp_errno_to_str(errno_val); + return msg[0] != '\0' ? msg : NULL; +} diff --git a/py/mpconfig.h b/py/mpconfig.h old mode 100644 new mode 100755 index 08d1005491c..3ec383817ed --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -40,11 +40,16 @@ // to another, you must rebuild from scratch using "-B" switch to make. #ifdef MP_CONFIGFILE -#include MP_CONFIGFILE +#include "mpconfigport_coverage.h" #else #include #endif +// Is this a CircuitPython build? +#ifndef CIRCUITPY +#define CIRCUITPY 0 +#endif + // Any options not explicitly set in mpconfigport.h will get default // values below. @@ -130,6 +135,12 @@ #define MICROPY_ALLOC_QSTR_CHUNK_INIT (128) #endif +// Max number of entries in newly allocated QSTR pools. Smaller numbers may make QSTR lookups +// slightly slower but reduce the waste of unused spots. +#ifndef MICROPY_QSTR_POOL_MAX_ENTRIES +#define MICROPY_QSTR_POOL_MAX_ENTRIES (64) +#endif + // Initial amount for lexer indentation level #ifndef MICROPY_ALLOC_LEXER_INDENT_INIT #define MICROPY_ALLOC_LEXER_INDENT_INIT (10) @@ -422,6 +433,11 @@ #define MICROPY_READER_VFS (0) #endif +// Number of VFS mounts to persist across soft-reset. +#ifndef MICROPY_FATFS_NUM_PERSISTENT +#define MICROPY_FATFS_NUM_PERSISTENT (0) +#endif + // Hook for the VM at the start of the opcode loop (can contain variable // definitions usable by the other hook functions) #ifndef MICROPY_VM_HOOK_INIT @@ -465,6 +481,11 @@ #define MICROPY_STACK_CHECK (0) #endif +// Whether to measure maximum stack excursion +#ifndef MICROPY_MAX_STACK_USAGE +#define MICROPY_MAX_STACK_USAGE (0) +#endif + // Whether to have an emergency exception buffer #ifndef MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF #define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (0) @@ -942,6 +963,12 @@ typedef double mp_float_t; #define MICROPY_PY_ARRAY_SLICE_ASSIGN (0) #endif +// Whether to support nonstandard typecodes "O", "P" and "S" +// in array and struct modules. +#ifndef MICROPY_NONSTANDARD_TYPECODES +#define MICROPY_NONSTANDARD_TYPECODES (1) +#endif + // Whether to support attrtuple type (MicroPython extension) // It provides space-efficient tuples with attribute access #ifndef MICROPY_PY_ATTRTUPLE @@ -1142,6 +1169,18 @@ typedef double mp_float_t; #define MICROPY_PY_URE (0) #endif +#ifndef MICROPY_PY_URE_MATCH_GROUPS +#define MICROPY_PY_URE_MATCH_GROUPS (0) +#endif + +#ifndef MICROPY_PY_URE_MATCH_SPAN_START_END +#define MICROPY_PY_URE_MATCH_SPAN_START_END (0) +#endif + +#ifndef MICROPY_PY_URE_SUB +#define MICROPY_PY_URE_SUB (0) +#endif + #ifndef MICROPY_PY_UHEAPQ #define MICROPY_PY_UHEAPQ (0) #endif @@ -1216,6 +1255,26 @@ typedef double mp_float_t; #define MICROPY_PY_BTREE (0) #endif +#ifndef MICROPY_PY_OS_DUPTERM +#define MICROPY_PY_OS_DUPTERM (0) +#endif + +#ifndef MICROPY_PY_LWIP +#define MICROPY_PY_LWIP (0) +#endif + +#ifndef MICROPY_PY_LWIP_SLIP +#define MICROPY_PY_LWIP_SLIP (0) +#endif + +#ifndef MICROPY_HW_ENABLE_USB +#define MICROPY_HW_ENABLE_USB (0) +#endif + +#ifndef MICROPY_PY_WEBREPL +#define MICROPY_PY_WEBREPL (0) +#endif + /*****************************************************************************/ /* Hooks for a port to add builtins */ diff --git a/py/mperrno.h b/py/mperrno.h index 0cad75a17cb..911a9b41317 100644 --- a/py/mperrno.h +++ b/py/mperrno.h @@ -27,6 +27,7 @@ #define MICROPY_INCLUDED_PY_MPERRNO_H #include "py/mpconfig.h" +#include "py/obj.h" #if MICROPY_USE_INTERNAL_ERRNO @@ -139,12 +140,7 @@ #endif -#if MICROPY_PY_UERRNO - -#include "py/obj.h" - -qstr mp_errno_to_str(mp_obj_t errno_val); - -#endif +const char* mp_errno_to_str(mp_obj_t errno_val); +const char *mp_common_errno_to_str(mp_obj_t errno_val, char *buf, size_t len); #endif // MICROPY_INCLUDED_PY_MPERRNO_H diff --git a/py/mpstate.h b/py/mpstate.h index 8c3b710cbd8..a3d7e5dccb7 100644 --- a/py/mpstate.h +++ b/py/mpstate.h @@ -76,20 +76,23 @@ typedef struct _mp_state_mem_t { byte *gc_pool_start; byte *gc_pool_end; + void *gc_lowest_long_lived_ptr; + int gc_stack_overflow; size_t gc_stack[MICROPY_ALLOC_GC_STACK_SIZE]; uint16_t gc_lock_depth; - // This variable controls auto garbage collection. If set to 0 then the + // This variable controls auto garbage collection. If set to false then the // GC won't automatically run when gc_alloc can't find enough blocks. But // you can still allocate/free memory and also explicitly call gc_collect. - uint16_t gc_auto_collect_enabled; + bool gc_auto_collect_enabled; #if MICROPY_GC_ALLOC_THRESHOLD size_t gc_alloc_amount; size_t gc_alloc_threshold; #endif + size_t gc_first_free_atb_index; size_t gc_last_free_atb_index; #if MICROPY_PY_GC_COLLECT_RETVAL @@ -100,6 +103,8 @@ typedef struct _mp_state_mem_t { // This is a global mutex used to make the GC thread-safe. mp_thread_mutex_t gc_mutex; #endif + + void** permanent_pointers; } mp_state_mem_t; // This structure hold runtime and VM information. It includes a section @@ -133,6 +138,9 @@ typedef struct _mp_state_vm_t { mp_obj_exception_t mp_kbd_exception; #endif + // exception object of type ReloadException + mp_obj_exception_t mp_reload_exception; + // dictionary with loaded modules (may be exposed as sys.modules) mp_obj_dict_t mp_loaded_modules_dict; @@ -171,6 +179,7 @@ typedef struct _mp_state_vm_t { #if MICROPY_PY_OS_DUPTERM mp_obj_t dupterm_objs[MICROPY_PY_OS_DUPTERM]; + mp_obj_t dupterm_arr_obj; #endif #if MICROPY_PY_LWIP_SLIP @@ -223,6 +232,10 @@ typedef struct _mp_state_thread_t { // Stack top at the start of program char *stack_top; + #if MICROPY_MAX_STACK_USAGE + char* stack_bottom; + #endif + #if MICROPY_STACK_CHECK size_t stack_limit; #endif diff --git a/py/nlr.c b/py/nlr.c index 03d01577e14..1bfd9c19b03 100644 --- a/py/nlr.c +++ b/py/nlr.c @@ -28,7 +28,7 @@ #if !MICROPY_NLR_SETJMP // When not using setjmp, nlr_push_tail is called from inline asm so needs special care -#if MICROPY_NLR_X86 && MICROPY_NLR_OS_WINDOWS +#if defined(MICROPY_NLR_X86) && MICROPY_NLR_X86 && defined(MICROPY_NLR_OS_WINDOWS) && MICROPY_NLR_OS_WINDOWS // On these 32-bit platforms make sure nlr_push_tail doesn't have a leading underscore unsigned int nlr_push_tail(nlr_buf_t *nlr) asm("nlr_push_tail"); #else diff --git a/py/nlr.h b/py/nlr.h index 90595a12d37..802f5f39a35 100644 --- a/py/nlr.h +++ b/py/nlr.h @@ -35,7 +35,8 @@ #include "py/mpconfig.h" // If MICROPY_NLR_SETJMP is not enabled then auto-detect the machine arch -#if !MICROPY_NLR_SETJMP +#if !defined(MICROPY_NLR_SETJMP) || !MICROPY_NLR_SETJMP +#define MICROPY_NLR_SETJMP (0) // A lot of nlr-related things need different treatment on Windows #if defined(_WIN32) || defined(__CYGWIN__) #define MICROPY_NLR_OS_WINDOWS 1 diff --git a/py/nlrthumb.c b/py/nlrthumb.c index c283023551d..69d3f868afd 100644 --- a/py/nlrthumb.c +++ b/py/nlrthumb.c @@ -74,7 +74,13 @@ __attribute__((naked)) unsigned int nlr_push(nlr_buf_t *nlr) { #else "b nlr_push_tail \n" // do the rest in C #endif - ); + : // output operands + : "r" (nlr) // input operands + // Do not use r1, r2, r3 as temporary saving registers. + // gcc 7.2.1 started doing this, and r3 got clobbered in nlr_push_tail. + // See https://github.com/adafruit/circuitpython/issues/500 for details. + : "r1", "r2", "r3" // clobbers + ); #if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)) // Older versions of gcc give an error when naked functions don't return a value diff --git a/py/nlrx64.c b/py/nlrx64.c index a3a1cf341b9..9b2b22c225b 100644 --- a/py/nlrx64.c +++ b/py/nlrx64.c @@ -26,7 +26,7 @@ #include "py/mpstate.h" -#if MICROPY_NLR_X64 +#if defined(MICROPY_NLR_X64) && MICROPY_NLR_X64 #undef nlr_push diff --git a/py/nlrx86.c b/py/nlrx86.c index 59b97d8ee6a..4900a4c0d22 100644 --- a/py/nlrx86.c +++ b/py/nlrx86.c @@ -26,14 +26,14 @@ #include "py/mpstate.h" -#if MICROPY_NLR_X86 +#if defined(MICROPY_NLR_X86) && MICROPY_NLR_X86 #undef nlr_push // For reference, x86 callee save regs are: // ebx, esi, edi, ebp, esp, eip -#if MICROPY_NLR_OS_WINDOWS +#if defined(MICROPY_NLR_OS_WINDOWS) && MICROPY_NLR_OS_WINDOWS unsigned int nlr_push_tail(nlr_buf_t *nlr) asm("nlr_push_tail"); #else __attribute__((used)) unsigned int nlr_push_tail(nlr_buf_t *nlr); diff --git a/py/nlrxtensa.c b/py/nlrxtensa.c index cd3dee364c2..d66c7a9a7fa 100644 --- a/py/nlrxtensa.c +++ b/py/nlrxtensa.c @@ -26,7 +26,7 @@ #include "py/mpstate.h" -#if MICROPY_NLR_XTENSA +#if defined(MICROPY_NLR_XTENSA) && MICROPY_NLR_XTENSA #undef nlr_push diff --git a/py/obj.c b/py/obj.c index a1de89a0329..322a302f97a 100644 --- a/py/obj.c +++ b/py/obj.c @@ -33,10 +33,14 @@ #include "py/objtype.h" #include "py/objint.h" #include "py/objstr.h" +#include "py/qstr.h" #include "py/runtime.h" #include "py/stackctrl.h" #include "py/stream.h" // for mp_obj_print +#include "supervisor/shared/stack.h" +#include "supervisor/shared/translate.h" + mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in) { if (MP_OBJ_IS_SMALL_INT(o_in)) { return (mp_obj_type_t*)&mp_type_int; @@ -79,24 +83,40 @@ void mp_obj_print(mp_obj_t o_in, mp_print_kind_t kind) { // helper function to print an exception with traceback void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc) { - if (mp_obj_is_exception_instance(exc)) { + if (mp_obj_is_exception_instance(exc) && stack_ok()) { size_t n, *values; mp_obj_exception_get_traceback(exc, &n, &values); if (n > 0) { assert(n % 3 == 0); - mp_print_str(print, "Traceback (most recent call last):\n"); + // Decompress the format strings + const compressed_string_t* traceback = translate("Traceback (most recent call last):\n"); + char decompressed[traceback->length]; + decompress(traceback, decompressed); +#if MICROPY_ENABLE_SOURCE_LINE + const compressed_string_t* frame = translate(" File \"%q\", line %d"); +#else + const compressed_string_t* frame = translate(" File \"%q\""); +#endif + char decompressed_frame[frame->length]; + decompress(frame, decompressed_frame); + const compressed_string_t* block_fmt = translate(", in %q\n"); + char decompressed_block[block_fmt->length]; + decompress(block_fmt, decompressed_block); + + // Print the traceback + mp_print_str(print, decompressed); for (int i = n - 3; i >= 0; i -= 3) { #if MICROPY_ENABLE_SOURCE_LINE - mp_printf(print, " File \"%q\", line %d", values[i], (int)values[i + 1]); + mp_printf(print, decompressed_frame, values[i], (int)values[i + 1]); #else - mp_printf(print, " File \"%q\"", values[i]); + mp_printf(print, decompressed_frame, values[i]); #endif // the block name can be NULL if it's unknown qstr block = values[i + 2]; if (block == MP_QSTR_NULL) { mp_print_str(print, "\n"); } else { - mp_printf(print, ", in %q\n", block); + mp_printf(print, decompressed_block, block); } } } @@ -236,10 +256,10 @@ mp_int_t mp_obj_get_int(mp_const_obj_t arg) { return mp_obj_int_get_checked(arg); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("can't convert to int"); + mp_raise_TypeError(translate("can't convert to int")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "can't convert %s to int", mp_obj_get_type_str(arg))); + mp_raise_TypeError_varg( + translate("can't convert %s to int"), mp_obj_get_type_str(arg)); } } } @@ -299,10 +319,10 @@ mp_float_t mp_obj_get_float(mp_obj_t arg) { if (!mp_obj_get_float_maybe(arg, &val)) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("can't convert to float"); + mp_raise_TypeError(translate("can't convert to float")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "can't convert %s to float", mp_obj_get_type_str(arg))); + mp_raise_TypeError_varg( + translate("can't convert %s to float"), mp_obj_get_type_str(arg)); } } @@ -332,10 +352,10 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) { mp_obj_complex_get(arg, real, imag); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("can't convert to complex"); + mp_raise_TypeError(translate("can't convert to complex")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "can't convert %s to complex", mp_obj_get_type_str(arg))); + mp_raise_TypeError_varg( + translate("can't convert %s to complex"), mp_obj_get_type_str(arg)); } } } @@ -350,10 +370,10 @@ void mp_obj_get_array(mp_obj_t o, size_t *len, mp_obj_t **items) { mp_obj_list_get(o, len, items); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("expected tuple/list"); + mp_raise_TypeError(translate("expected tuple/list")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "object '%s' is not a tuple or list", mp_obj_get_type_str(o))); + mp_raise_TypeError_varg( + translate("object '%s' is not a tuple or list"), mp_obj_get_type_str(o)); } } } @@ -364,10 +384,10 @@ void mp_obj_get_array_fixed_n(mp_obj_t o, size_t len, mp_obj_t **items) { mp_obj_get_array(o, &seq_len, items); if (seq_len != len) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_ValueError("tuple/list has wrong length"); + mp_raise_ValueError(translate("tuple/list has wrong length")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "requested length %d but object has length %d", (int)len, (int)seq_len)); + mp_raise_ValueError_varg(translate("requested length %d but object has length %d"), + (int)len, (int)seq_len); } } } @@ -379,11 +399,11 @@ size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool i = MP_OBJ_SMALL_INT_VALUE(index); } else if (!mp_obj_get_int_maybe(index, &i)) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("indices must be integers"); + mp_raise_TypeError(translate("indices must be integers")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "%q indices must be integers, not %s", - type->name, mp_obj_get_type_str(index))); + mp_raise_TypeError_varg( + translate("%q indices must be integers, not %s"), + type->name, mp_obj_get_type_str(index)); } } @@ -399,10 +419,10 @@ size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool } else { if (i < 0 || (mp_uint_t)i >= len) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_IndexError, "index out of range"); + mp_raise_IndexError(translate("index out of range")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_IndexError, - "%q index out of range", type->name)); + mp_raise_msg_varg(&mp_type_IndexError, + translate("%q index out of range"), type->name); } } } @@ -434,10 +454,10 @@ mp_obj_t mp_obj_len(mp_obj_t o_in) { mp_obj_t len = mp_obj_len_maybe(o_in); if (len == MP_OBJ_NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("object has no len"); + mp_raise_TypeError(translate("object has no len")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "object of type '%s' has no len()", mp_obj_get_type_str(o_in))); + mp_raise_TypeError_varg( + translate("object of type '%s' has no len()"), mp_obj_get_type_str(o_in)); } } else { return len; @@ -468,6 +488,8 @@ mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) { mp_obj_type_t *type = mp_obj_get_type(base); if (type->subscr != NULL) { mp_obj_t ret = type->subscr(base, index, value); + // May have called port specific C code. Make sure it didn't mess up the heap. + assert_heap_ok(); if (ret != MP_OBJ_NULL) { return ret; } @@ -475,24 +497,24 @@ mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) { } if (value == MP_OBJ_NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("object does not support item deletion"); + mp_raise_TypeError(translate("object does not support item deletion")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "'%s' object does not support item deletion", mp_obj_get_type_str(base))); + mp_raise_TypeError_varg( + translate("'%s' object does not support item deletion"), mp_obj_get_type_str(base)); } } else if (value == MP_OBJ_SENTINEL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("object is not subscriptable"); + mp_raise_TypeError(translate("object is not subscriptable")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "'%s' object is not subscriptable", mp_obj_get_type_str(base))); + mp_raise_TypeError_varg( + translate("'%s' object is not subscriptable"), mp_obj_get_type_str(base)); } } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("object does not support item assignment"); + mp_raise_TypeError(translate("object does not support item assignment")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "'%s' object does not support item assignment", mp_obj_get_type_str(base))); + mp_raise_TypeError_varg( + translate("'%s' object does not support item assignment"), mp_obj_get_type_str(base)); } } } @@ -509,6 +531,36 @@ mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf) { return self; } +typedef struct { + mp_obj_base_t base; + mp_fun_1_t iternext; + mp_obj_t obj; + mp_int_t cur; +} mp_obj_generic_it_t; + +STATIC mp_obj_t generic_it_iternext(mp_obj_t self_in) { + mp_obj_generic_it_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_type_t *type = mp_obj_get_type(self->obj); + mp_obj_t current_length = type->unary_op(MP_UNARY_OP_LEN, self->obj); + if (self->cur < MP_OBJ_SMALL_INT_VALUE(current_length)) { + mp_obj_t o_out = type->subscr(self->obj, MP_OBJ_NEW_SMALL_INT(self->cur), MP_OBJ_SENTINEL); + self->cur += 1; + return o_out; + } else { + return MP_OBJ_STOP_ITERATION; + } +} + +mp_obj_t mp_obj_new_generic_iterator(mp_obj_t obj, mp_obj_iter_buf_t *iter_buf) { + assert(sizeof(mp_obj_generic_it_t) <= sizeof(mp_obj_iter_buf_t)); + mp_obj_generic_it_t *o = (mp_obj_generic_it_t*)iter_buf; + o->base.type = &mp_type_polymorph_iter; + o->iternext = generic_it_iternext; + o->obj = obj; + o->cur = 0; + return MP_OBJ_FROM_PTR(o); +} + bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) { mp_obj_type_t *type = mp_obj_get_type(obj); if (type->buffer_p.get_buffer == NULL) { @@ -523,7 +575,7 @@ bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) { void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) { if (!mp_get_buffer(obj, bufinfo, flags)) { - mp_raise_TypeError("object with buffer protocol required"); + mp_raise_TypeError(translate("object with buffer protocol required")); } } diff --git a/py/obj.h b/py/obj.h index a64cd0f6944..cf4216d02f5 100644 --- a/py/obj.h +++ b/py/obj.h @@ -26,12 +26,16 @@ #ifndef MICROPY_INCLUDED_PY_OBJ_H #define MICROPY_INCLUDED_PY_OBJ_H +#include + #include "py/mpconfig.h" #include "py/misc.h" #include "py/qstr.h" #include "py/mpprint.h" #include "py/runtime0.h" +#include "supervisor/shared/translate.h" + // This is the definition of the opaque MicroPython object type. // All concrete objects have an encoding within this type and the // particular encoding is specified by MICROPY_OBJ_REPR. @@ -291,6 +295,13 @@ typedef struct _mp_rom_obj_t { mp_const_obj_t o; } mp_rom_obj_t; #define MP_DEFINE_CONST_FUN_OBJ_KW(obj_name, n_args_min, fun_name) \ const mp_obj_fun_builtin_var_t obj_name = \ {{&mp_type_fun_builtin_var}, true, n_args_min, MP_OBJ_FUN_ARGS_MAX, .fun.kw = fun_name} +#define MP_DEFINE_CONST_PROP_GET(obj_name, fun_name) \ + const mp_obj_fun_builtin_fixed_t fun_name##_obj = {{&mp_type_fun_builtin_1}, .fun._1 = fun_name}; \ + const mp_obj_property_t obj_name = { \ + .base.type = &mp_type_property, \ + .proxy = {(mp_obj_t)&fun_name##_obj, \ + (mp_obj_t)&mp_const_none_obj, \ + (mp_obj_t)&mp_const_none_obj}, } // These macros are used to define constant map/dict objects // You can put "static" in front of the definition to make it local @@ -327,6 +338,13 @@ typedef struct _mp_rom_obj_t { mp_const_obj_t o; } mp_rom_obj_t; #define MP_DEFINE_CONST_STATICMETHOD_OBJ(obj_name, fun_name) const mp_rom_obj_static_class_method_t obj_name = {{&mp_type_staticmethod}, fun_name} #define MP_DEFINE_CONST_CLASSMETHOD_OBJ(obj_name, fun_name) const mp_rom_obj_static_class_method_t obj_name = {{&mp_type_classmethod}, fun_name} +// Declare a module as a builtin, processed by makemoduledefs.py +// param module_name: MP_QSTR_ +// param obj_module: mp_obj_module_t instance +// prarm enabled_define: used as `#if (enabled_define) around entry` + +#define MP_REGISTER_MODULE(module_name, obj_module, enabled_define) + // Underlying map/hash table implementation (not dict object or map function) typedef struct _mp_map_elem_t { @@ -348,7 +366,9 @@ typedef struct _mp_map_t { size_t all_keys_are_qstrs : 1; size_t is_fixed : 1; // a fixed array that can't be modified; must also be ordered size_t is_ordered : 1; // an ordered array - size_t used : (8 * sizeof(size_t) - 3); + size_t scanning : 1; // true if we're in the middle of scanning linked dictionaries, + // e.g., make_dict_long_lived() + size_t used : (8 * sizeof(size_t) - 4); size_t alloc; mp_map_elem_t *table; } mp_map_t; @@ -419,7 +439,7 @@ typedef struct _mp_obj_iter_buf_t { #define MP_OBJ_ITER_BUF_NSLOTS ((sizeof(mp_obj_iter_buf_t) + sizeof(mp_obj_t) - 1) / sizeof(mp_obj_t)) typedef void (*mp_print_fun_t)(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind); -typedef mp_obj_t (*mp_make_new_fun_t)(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); +typedef mp_obj_t (*mp_make_new_fun_t)(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); typedef mp_obj_t (*mp_call_fun_t)(mp_obj_t fun, size_t n_args, size_t n_kw, const mp_obj_t *args); typedef mp_obj_t (*mp_unary_op_fun_t)(mp_unary_op_t op, mp_obj_t); typedef mp_obj_t (*mp_binary_op_fun_t)(mp_binary_op_t op, mp_obj_t, mp_obj_t); @@ -575,9 +595,11 @@ extern const mp_obj_type_t mp_type_ImportError; extern const mp_obj_type_t mp_type_IndentationError; extern const mp_obj_type_t mp_type_IndexError; extern const mp_obj_type_t mp_type_KeyboardInterrupt; +extern const mp_obj_type_t mp_type_ReloadException; extern const mp_obj_type_t mp_type_KeyError; extern const mp_obj_type_t mp_type_LookupError; extern const mp_obj_type_t mp_type_MemoryError; +extern const mp_obj_type_t mp_type_MpyError; extern const mp_obj_type_t mp_type_NameError; extern const mp_obj_type_t mp_type_NotImplementedError; extern const mp_obj_type_t mp_type_OSError; @@ -625,7 +647,9 @@ mp_obj_t mp_obj_new_str(const char* data, size_t len); mp_obj_t mp_obj_new_str_via_qstr(const char* data, size_t len); mp_obj_t mp_obj_new_str_from_vstr(const mp_obj_type_t *type, vstr_t *vstr); mp_obj_t mp_obj_new_bytes(const byte* data, size_t len); +mp_obj_t mp_obj_new_bytes_of_zeros(size_t len); mp_obj_t mp_obj_new_bytearray(size_t n, void *items); +mp_obj_t mp_obj_new_bytearray_of_zeros(size_t n); mp_obj_t mp_obj_new_bytearray_by_ref(size_t n, void *items); #if MICROPY_PY_BUILTINS_FLOAT mp_obj_t mp_obj_new_int_from_float(mp_float_t val); @@ -634,8 +658,9 @@ mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag); mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type); mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg); mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, size_t n_args, const mp_obj_t *args); -mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg); -mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!) +mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg); +mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!) +mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, va_list ap); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!) mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args, mp_obj_t def_kw_args, const byte *code, const mp_uint_t *const_table); mp_obj_t mp_obj_new_fun_native(mp_obj_t def_args_in, mp_obj_t def_kw_args, const void *fun_data, const mp_uint_t *const_table); mp_obj_t mp_obj_new_fun_viper(size_t n_args, void *fun_data, mp_uint_t type_sig); @@ -644,6 +669,7 @@ mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun); mp_obj_t mp_obj_new_closure(mp_obj_t fun, size_t n_closed, const mp_obj_t *closed); mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items); mp_obj_t mp_obj_new_list(size_t n, mp_obj_t *items); +mp_obj_t mp_obj_new_list_from_iter(mp_obj_t iterable); mp_obj_t mp_obj_new_dict(size_t n_args); mp_obj_t mp_obj_new_set(size_t n_args, mp_obj_t *items); mp_obj_t mp_obj_new_slice(mp_obj_t start, mp_obj_t stop, mp_obj_t step); @@ -655,7 +681,7 @@ mp_obj_t mp_obj_new_memoryview(byte typecode, size_t nitems, void *items); mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in); const char *mp_obj_get_type_str(mp_const_obj_t o_in); bool mp_obj_is_subclass_fast(mp_const_obj_t object, mp_const_obj_t classinfo); // arguments should be type objects -mp_obj_t mp_instance_cast_to_native_base(mp_const_obj_t self_in, mp_const_obj_t native_type); +mp_obj_t mp_instance_cast_to_native_base(mp_obj_t self_in, mp_const_obj_t native_type); void mp_obj_print_helper(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind); void mp_obj_print(mp_obj_t o, mp_print_kind_t kind); @@ -702,8 +728,9 @@ bool mp_obj_exception_match(mp_obj_t exc, mp_const_obj_t exc_type); void mp_obj_exception_clear_traceback(mp_obj_t self_in); void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qstr block); void mp_obj_exception_get_traceback(mp_obj_t self_in, size_t *n, size_t **values); +mp_obj_t mp_obj_exception_get_traceback_obj(mp_obj_t self_in); mp_obj_t mp_obj_exception_get_value(mp_obj_t self_in); -mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args); +mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); mp_obj_t mp_alloc_emergency_exception_buf(mp_obj_t size_in); void mp_init_emergency_exception_buf(void); @@ -738,6 +765,7 @@ void mp_obj_tuple_del(mp_obj_t self_in); mp_int_t mp_obj_tuple_hash(mp_obj_t self_in); // list +mp_obj_t mp_obj_list_clear(mp_obj_t self_in); mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg); mp_obj_t mp_obj_list_remove(mp_obj_t self_in, mp_obj_t value); void mp_obj_list_get(mp_obj_t self_in, size_t *len, mp_obj_t **items); @@ -794,12 +822,17 @@ mp_obj_t mp_identity(mp_obj_t self); MP_DECLARE_CONST_FUN_OBJ_1(mp_identity_obj); mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf); +// Generic iterator that uses unary op and subscr to iterate over a native type. It will be slower +// than a custom iterator but applies broadly. +mp_obj_t mp_obj_new_generic_iterator(mp_obj_t self, mp_obj_iter_buf_t *iter_buf); + // module typedef struct _mp_obj_module_t { mp_obj_base_t base; mp_obj_dict_t *globals; } mp_obj_module_t; mp_obj_dict_t *mp_obj_module_get_globals(mp_obj_t self_in); +void mp_obj_module_set_globals(mp_obj_t self_in, mp_obj_dict_t *globals); // check if given module object is a package bool mp_obj_is_package(mp_obj_t module); @@ -826,6 +859,8 @@ typedef struct { mp_int_t step; } mp_bound_slice_t; +// Compute the new length of a sequence and ensure an exception is thrown on overflow. +size_t mp_seq_multiply_len(size_t item_sz, size_t len); void mp_seq_multiply(const void *items, size_t item_sz, size_t len, size_t times, void *dest); #if MICROPY_PY_BUILTINS_SLICE bool mp_seq_get_fast_slice_indexes(mp_uint_t len, mp_obj_t slice, mp_bound_slice_t *indexes); diff --git a/py/objarray.c b/py/objarray.c index aa9fa3b737a..9114a63c5a3 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -34,6 +34,8 @@ #include "py/objstr.h" #include "py/objarray.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_ARRAY || MICROPY_PY_BUILTINS_BYTEARRAY || MICROPY_PY_BUILTINS_MEMORYVIEW // About memoryview object: We want to reuse as much code as possible from @@ -155,9 +157,9 @@ STATIC mp_obj_t array_construct(char typecode, mp_obj_t initializer) { #endif #if MICROPY_PY_ARRAY -STATIC mp_obj_t array_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t array_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 1, 2, false); + mp_arg_check_num(n_args, kw_args, 1, 2, false); // get typecode const char *typecode = mp_obj_str_get_str(args[0]); @@ -173,9 +175,9 @@ STATIC mp_obj_t array_make_new(const mp_obj_type_t *type_in, size_t n_args, size #endif #if MICROPY_PY_BUILTINS_BYTEARRAY -STATIC mp_obj_t bytearray_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t bytearray_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 0, 1, false); + mp_arg_check_num(n_args, kw_args, 0, 1, false); if (n_args == 0) { // no args: construct an empty bytearray @@ -205,13 +207,13 @@ mp_obj_t mp_obj_new_memoryview(byte typecode, size_t nitems, void *items) { return MP_OBJ_FROM_PTR(self); } -STATIC mp_obj_t memoryview_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t memoryview_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; // TODO possibly allow memoryview constructor to take start/stop so that one // can do memoryview(b, 4, 8) instead of memoryview(b)[4:8] (uses less RAM) - mp_arg_check_num(n_args, n_kw, 1, 1, false); + mp_arg_check_num(n_args, kw_args, 1, 1, false); mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ); @@ -241,6 +243,39 @@ STATIC mp_obj_t array_unary_op(mp_unary_op_t op, mp_obj_t o_in) { STATIC mp_obj_t array_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { mp_obj_array_t *lhs = MP_OBJ_TO_PTR(lhs_in); switch (op) { + case MP_BINARY_OP_MULTIPLY: + case MP_BINARY_OP_INPLACE_MULTIPLY: { + if (!MP_OBJ_IS_INT(rhs_in)) { + return MP_OBJ_NULL; // op not supported + } + mp_uint_t repeat = mp_obj_get_int(rhs_in); + bool inplace = (op == MP_BINARY_OP_INPLACE_MULTIPLY); + mp_buffer_info_t lhs_bufinfo; + array_get_buffer(lhs_in, &lhs_bufinfo, MP_BUFFER_READ); + mp_obj_array_t *res; + byte *ptr; + size_t orig_lhs_bufinfo_len = lhs_bufinfo.len; + if(inplace) { + res = lhs; + size_t item_sz = mp_binary_get_size('@', lhs->typecode, NULL); + lhs->items = m_renew(byte, lhs->items, (lhs->len + lhs->free) * item_sz, lhs->len * repeat * item_sz); + lhs->len = lhs->len * repeat; + lhs->free = 0; + if (!repeat) + return MP_OBJ_FROM_PTR(res); + repeat--; + ptr = (byte*)res->items + orig_lhs_bufinfo_len; + } else { + res = array_new(lhs_bufinfo.typecode, lhs->len * repeat); + ptr = (byte*)res->items; + } + if(orig_lhs_bufinfo_len) { + for(;repeat--; ptr += orig_lhs_bufinfo_len) { + memcpy(ptr, lhs_bufinfo.buf, orig_lhs_bufinfo_len); + } + } + return MP_OBJ_FROM_PTR(res); + } case MP_BINARY_OP_ADD: { // allow to add anything that has the buffer protocol (extension to CPython) mp_buffer_info_t lhs_bufinfo; @@ -375,7 +410,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value } else if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) { mp_bound_slice_t slice; if (!mp_seq_get_fast_slice_indexes(o->len, index_in, &slice)) { - mp_raise_NotImplementedError("only slices with step=1 (aka None) are supported"); + mp_raise_NotImplementedError(translate("only slices with step=1 (aka None) are supported")); } if (value != MP_OBJ_SENTINEL) { #if MICROPY_PY_ARRAY_SLICE_ASSIGN @@ -388,7 +423,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value mp_obj_array_t *src_slice = MP_OBJ_TO_PTR(value); if (item_sz != mp_binary_get_size('@', src_slice->typecode & TYPECODE_MASK, NULL)) { compat_error: - mp_raise_ValueError("lhs and rhs should be compatible"); + mp_raise_ValueError(translate("lhs and rhs should be compatible")); } src_len = src_slice->len; src_items = src_slice->items; @@ -406,7 +441,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value src_len = bufinfo.len; src_items = bufinfo.buf; } else { - mp_raise_NotImplementedError("array/bytes required on right side"); + mp_raise_NotImplementedError(translate("array/bytes required on right side")); } // TODO: check src/dst compat @@ -425,7 +460,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value } #endif if (len_adj > 0) { - if (len_adj > o->free) { + if ((mp_uint_t) len_adj > o->free) { // TODO: alloc policy; at the moment we go conservative o->items = m_renew(byte, o->items, (o->len + o->free) * item_sz, (o->len + len_adj) * item_sz); o->free = 0; @@ -436,9 +471,11 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value } else { mp_seq_replace_slice_no_grow(dest_items, o->len, slice.start, slice.stop, src_items, src_len, item_sz); +#if MICROPY_NONSTANDARD_TYPECODES // Clear "freed" elements at the end of list // TODO: This is actually only needed for typecode=='O' mp_seq_clear(dest_items, o->len + len_adj, o->len, item_sz); +#endif // TODO: alloc policy after shrinking } o->len += len_adj; @@ -574,6 +611,12 @@ mp_obj_t mp_obj_new_bytearray(size_t n, void *items) { return MP_OBJ_FROM_PTR(o); } +mp_obj_t mp_obj_new_bytearray_of_zeros(size_t n) { + mp_obj_array_t *o = array_new(BYTEARRAY_TYPECODE, n); + memset(o->items, 0, n); + return MP_OBJ_FROM_PTR(o); +} + // Create bytearray which references specified memory area mp_obj_t mp_obj_new_bytearray_by_ref(size_t n, void *items) { mp_obj_array_t *o = m_new_obj(mp_obj_array_t); diff --git a/py/objbool.c b/py/objbool.c index 5755b188e98..cd7d7100c9c 100644 --- a/py/objbool.c +++ b/py/objbool.c @@ -50,9 +50,9 @@ STATIC void bool_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_ } } -STATIC mp_obj_t bool_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t bool_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 0, 1, false); + mp_arg_check_num(n_args, kw_args, 0, 1, false); if (n_args == 0) { return mp_const_false; diff --git a/py/objboundmeth.c b/py/objboundmeth.c index b0df6a68a70..a05680d4103 100644 --- a/py/objboundmeth.c +++ b/py/objboundmeth.c @@ -92,6 +92,9 @@ STATIC void bound_meth_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { if (attr == MP_QSTR___name__) { mp_obj_bound_meth_t *o = MP_OBJ_TO_PTR(self_in); dest[0] = MP_OBJ_NEW_QSTR(mp_obj_fun_get_name(o->meth)); + } else if (attr == MP_QSTR___func__) { + mp_obj_bound_meth_t *o = MP_OBJ_TO_PTR(self_in); + dest[0] = o->meth; } } #endif diff --git a/py/objcomplex.c b/py/objcomplex.c index 409d6566650..b38e2c5fa62 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -31,11 +31,16 @@ #include "py/parsenum.h" #include "py/runtime.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_BUILTINS_COMPLEX #include #include "py/formatfloat.h" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" + typedef struct _mp_obj_complex_t { mp_obj_base_t base; mp_float_t real; @@ -70,9 +75,9 @@ STATIC void complex_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_ } } -STATIC mp_obj_t complex_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t complex_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 0, 2, false); + mp_arg_check_num(n_args, kw_args, 0, 2, false); switch (n_args) { case 0: @@ -195,13 +200,13 @@ mp_obj_t mp_obj_complex_binary_op(mp_binary_op_t op, mp_float_t lhs_real, mp_flo } case MP_BINARY_OP_FLOOR_DIVIDE: case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE: - mp_raise_TypeError("can't do truncated division of a complex number"); + mp_raise_TypeError(translate("can't do truncated division of a complex number")); case MP_BINARY_OP_TRUE_DIVIDE: case MP_BINARY_OP_INPLACE_TRUE_DIVIDE: if (rhs_imag == 0) { if (rhs_real == 0) { - mp_raise_msg(&mp_type_ZeroDivisionError, "complex division by zero"); + mp_raise_msg(&mp_type_ZeroDivisionError, translate("complex division by zero")); } lhs_real /= rhs_real; lhs_imag /= rhs_real; @@ -229,7 +234,7 @@ mp_obj_t mp_obj_complex_binary_op(mp_binary_op_t op, mp_float_t lhs_real, mp_flo if (rhs_imag == 0 && rhs_real >= 0) { lhs_real = (rhs_real == 0); } else { - mp_raise_msg(&mp_type_ZeroDivisionError, "0.0 to a complex power"); + mp_raise_msg(&mp_type_ZeroDivisionError, translate("0.0 to a complex power")); } } else { mp_float_t ln1 = MICROPY_FLOAT_C_FUN(log)(abs1); @@ -251,4 +256,6 @@ mp_obj_t mp_obj_complex_binary_op(mp_binary_op_t op, mp_float_t lhs_real, mp_flo return mp_obj_new_complex(lhs_real, lhs_imag); } +#pragma GCC diagnostic pop + #endif diff --git a/py/objdeque.c b/py/objdeque.c index 1cff1f8d3b4..b2785b5b60f 100644 --- a/py/objdeque.c +++ b/py/objdeque.c @@ -28,6 +28,8 @@ #include #include "py/mpconfig.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_COLLECTIONS_DEQUE #include "py/runtime.h" @@ -42,8 +44,8 @@ typedef struct _mp_obj_deque_t { #define FLAG_CHECK_OVERFLOW 1 } mp_obj_deque_t; -STATIC mp_obj_t deque_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 2, 3, false); +STATIC mp_obj_t deque_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 2, 3, false); /* Initialization from existing sequence is not supported, so an empty tuple must be passed as such. */ @@ -102,7 +104,7 @@ STATIC mp_obj_t mp_obj_deque_append(mp_obj_t self_in, mp_obj_t arg) { } if (self->flags & FLAG_CHECK_OVERFLOW && new_i_put == self->i_get) { - mp_raise_msg(&mp_type_IndexError, "full"); + mp_raise_msg(&mp_type_IndexError, translate("full")); } self->items[self->i_put] = arg; @@ -122,7 +124,7 @@ STATIC mp_obj_t deque_popleft(mp_obj_t self_in) { mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); if (self->i_get == self->i_put) { - mp_raise_msg(&mp_type_IndexError, "empty"); + mp_raise_msg(&mp_type_IndexError, translate("empty")); } mp_obj_t ret = self->items[self->i_get]; diff --git a/py/objdict.c b/py/objdict.c index c0647067a10..683fcb748ec 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -31,6 +31,8 @@ #include "py/builtin.h" #include "py/objtype.h" +#include "supervisor/shared/translate.h" + #define MP_OBJ_IS_DICT_TYPE(o) (MP_OBJ_IS_OBJ(o) && ((mp_obj_base_t*)MP_OBJ_TO_PTR(o))->type->make_new == dict_make_new) STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs); @@ -79,7 +81,7 @@ STATIC void dict_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_ } } -STATIC mp_obj_t dict_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t dict_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { mp_obj_t dict_out = mp_obj_new_dict(0); mp_obj_dict_t *dict = MP_OBJ_TO_PTR(dict_out); dict->base.type = type; @@ -88,11 +90,12 @@ STATIC mp_obj_t dict_make_new(const mp_obj_type_t *type, size_t n_args, size_t n dict->map.is_ordered = 1; } #endif - if (n_args > 0 || n_kw > 0) { - mp_obj_t args2[2] = {dict_out, args[0]}; // args[0] is always valid, even if it's not a positional arg - mp_map_t kwargs; - mp_map_init_fixed_table(&kwargs, n_kw, args + n_args); - dict_update(n_args + 1, args2, &kwargs); // dict_update will check that n_args + 1 == 1 or 2 + if (n_args > 0 || kw_args != NULL) { + mp_obj_t args2[2] = {dict_out, NULL}; // args[0] is always valid, even if it's not a positional arg + if (n_args > 0) { + args2[1] = args[0]; + } + dict_update(n_args + 1, args2, kw_args); // dict_update will check that n_args + 1 == 1 or 2 } return dict_out; } @@ -309,7 +312,7 @@ STATIC mp_obj_t dict_popitem(mp_obj_t self_in) { size_t cur = 0; mp_map_elem_t *next = dict_iter_next(self, &cur); if (next == NULL) { - mp_raise_msg(&mp_type_KeyError, "popitem(): dictionary is empty"); + mp_raise_msg(&mp_type_KeyError, translate("popitem(): dictionary is empty")); } self->map.used--; mp_obj_t items[] = {next->key, next->value}; @@ -326,7 +329,7 @@ STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwarg mp_obj_dict_t *self = MP_OBJ_TO_PTR(args[0]); mp_ensure_not_fixed(self); - mp_arg_check_num(n_args, kwargs->used, 1, 2, true); + mp_arg_check_num(n_args, kwargs, 1, 2, true); if (n_args == 2) { // given a positional argument @@ -352,7 +355,7 @@ STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwarg if (key == MP_OBJ_STOP_ITERATION || value == MP_OBJ_STOP_ITERATION || stop != MP_OBJ_STOP_ITERATION) { - mp_raise_ValueError("dict update sequence has wrong length"); + mp_raise_ValueError(translate("dict update sequence has wrong length")); } else { mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; } diff --git a/py/objenumerate.c b/py/objenumerate.c index 1a9d30f8368..818725d856c 100644 --- a/py/objenumerate.c +++ b/py/objenumerate.c @@ -39,7 +39,7 @@ typedef struct _mp_obj_enumerate_t { STATIC mp_obj_t enumerate_iternext(mp_obj_t self_in); -STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { #if MICROPY_CPYTHON_COMPAT static const mp_arg_t allowed_args[] = { { MP_QSTR_iterable, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, @@ -50,7 +50,7 @@ STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, siz struct { mp_arg_val_t iterable, start; } arg_vals; - mp_arg_parse_all_kw_array(n_args, n_kw, args, + mp_arg_parse_all(n_args, args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t*)&arg_vals); // create enumerate object @@ -59,7 +59,7 @@ STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, siz o->iter = mp_getiter(arg_vals.iterable.u_obj, NULL); o->cur = arg_vals.start.u_int; #else - (void)n_kw; + (void)kw_args; mp_obj_enumerate_t *o = m_new_obj(mp_obj_enumerate_t); o->base.type = type; o->iter = mp_getiter(args[0], NULL); diff --git a/py/objexcept.c b/py/objexcept.c index 1e746bc81c3..c33ada0d698 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -30,6 +30,7 @@ #include #include "py/objlist.h" +#include "py/objnamedtuple.h" #include "py/objstr.h" #include "py/objtuple.h" #include "py/objtype.h" @@ -37,6 +38,8 @@ #include "py/gc.h" #include "py/mperrno.h" +#include "supervisor/shared/translate.h" + // Number of items per traceback entry (file, line, block) #define TRACEBACK_ENTRY_LEN (3) @@ -110,16 +113,16 @@ void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kin mp_print_str(print, ""); return; } else if (o->args->len == 1) { - #if MICROPY_PY_UERRNO // try to provide a nice OSError error message - if (o->base.type == &mp_type_OSError && MP_OBJ_IS_SMALL_INT(o->args->items[0])) { - qstr qst = mp_errno_to_str(o->args->items[0]); - if (qst != MP_QSTR_NULL) { - mp_printf(print, "[Errno " INT_FMT "] %q", MP_OBJ_SMALL_INT_VALUE(o->args->items[0]), qst); + if (MP_OBJ_IS_SMALL_INT(o->args->items[0]) && + mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(o->base.type), MP_OBJ_FROM_PTR(&mp_type_OSError))) { + char decompressed[50]; + const char *msg = mp_common_errno_to_str(o->args->items[0], decompressed, sizeof(decompressed)); + if (msg != NULL) { + mp_printf(print, "[Errno " INT_FMT "] %s", MP_OBJ_SMALL_INT_VALUE(o->args->items[0]), msg); return; } } - #endif mp_obj_print_helper(print, o->args->items[0], PRINT_STR); return; } @@ -127,8 +130,8 @@ void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kin mp_obj_tuple_print(print, MP_OBJ_FROM_PTR(o->args), kind); } -mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, false); +mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, MP_OBJ_FUN_ARGS_MAX, false); // Try to allocate memory for the exception, with fallback to emergency exception object mp_obj_exception_t *o_exc = m_new_obj_maybe(mp_obj_exception_t); @@ -206,6 +209,31 @@ void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { dest[0] = MP_OBJ_FROM_PTR(self->args); } else if (self->base.type == &mp_type_StopIteration && attr == MP_QSTR_value) { dest[0] = mp_obj_exception_get_value(self_in); + #if MICROPY_CPYTHON_COMPAT + } else if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(self->base.type), MP_OBJ_FROM_PTR(&mp_type_OSError))) { + if (attr == MP_QSTR_errno) { + dest[0] = mp_obj_exception_get_value(self_in); + } else if (attr == MP_QSTR_strerror) { + if (self->args->len > 1) { + dest[0] = self->args->items[1]; + } else if (self->args->len > 0) { + char decompressed[50]; + const char *msg = mp_common_errno_to_str(self->args->items[0], decompressed, sizeof(decompressed)); + if (msg != NULL) { + dest[0] = mp_obj_new_str(msg, strlen(msg)); + } else { + dest[0] = mp_const_none; + } + } else { + dest[0] = mp_const_none; + } + } else if (attr == MP_QSTR_filename) { + dest[0] = self->args->len > 2 ? self->args->items[2] : mp_const_none; + // skip winerror + } else if (attr == MP_QSTR_filename2) { + dest[0] = self->args->len > 4 ? self->args->items[4] : mp_const_none; + } + #endif } } @@ -221,6 +249,7 @@ const mp_obj_type_t mp_type_BaseException = { // http://docs.python.org/3/library/exceptions.html MP_DEFINE_EXCEPTION(SystemExit, BaseException) MP_DEFINE_EXCEPTION(KeyboardInterrupt, BaseException) +MP_DEFINE_EXCEPTION(ReloadException, BaseException) MP_DEFINE_EXCEPTION(GeneratorExit, BaseException) MP_DEFINE_EXCEPTION(Exception, BaseException) #if MICROPY_PY_ASYNC_AWAIT @@ -247,9 +276,7 @@ MP_DEFINE_EXCEPTION(Exception, BaseException) MP_DEFINE_EXCEPTION(UnboundLocalError, NameError) */ MP_DEFINE_EXCEPTION(OSError, Exception) -#if MICROPY_PY_BUILTINS_TIMEOUTERROR - MP_DEFINE_EXCEPTION(TimeoutError, OSError) -#endif + MP_DEFINE_EXCEPTION(TimeoutError, OSError) /* MP_DEFINE_EXCEPTION(BlockingIOError, OSError) MP_DEFINE_EXCEPTION(ChildProcessError, OSError) @@ -284,6 +311,7 @@ MP_DEFINE_EXCEPTION(Exception, BaseException) MP_DEFINE_EXCEPTION(UnicodeError, ValueError) //TODO: Implement more UnicodeError subclasses which take arguments #endif + MP_DEFINE_EXCEPTION(MpyError, ValueError) /* MP_DEFINE_EXCEPTION(Warning, Exception) MP_DEFINE_EXCEPTION(DeprecationWarning, Warning) @@ -309,10 +337,10 @@ mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg) mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, size_t n_args, const mp_obj_t *args) { assert(exc_type->make_new == mp_obj_exception_make_new); - return exc_type->make_new(exc_type, n_args, 0, args); + return exc_type->make_new(exc_type, n_args, args, NULL); } -mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg) { +mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg) { return mp_obj_new_exception_msg_varg(exc_type, msg); } @@ -349,7 +377,16 @@ STATIC void exc_add_strn(void *data, const char *str, size_t len) { pr->len += len; } -mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...) { + +mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, ...) { + va_list ap; + va_start(ap, fmt); + mp_obj_t exception = mp_obj_new_exception_msg_vlist(exc_type, fmt, ap); + va_end(ap); + return exception; +} + +mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, va_list ap) { assert(fmt != NULL); // Check that the given type is an exception type @@ -357,7 +394,7 @@ mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char // Try to allocate memory for the message mp_obj_str_t *o_str = m_new_obj_maybe(mp_obj_str_t); - size_t o_str_alloc = strlen(fmt) + 1; + size_t o_str_alloc = fmt->length + 1; byte *o_str_buf = m_new_maybe(byte, o_str_alloc); bool used_emg_buf = false; @@ -383,18 +420,16 @@ mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char } if (o_str_buf == NULL) { - // No memory for the string buffer: assume that the fmt string is in ROM - // and use that data as the data of the string - o_str->len = o_str_alloc - 1; // will be equal to strlen(fmt) - o_str->data = (const byte*)fmt; + // No memory for the string buffer: the string is compressed so don't add it. + o_str->len = 0; + o_str->data = NULL; } else { // We have some memory to format the string struct _exc_printer_t exc_pr = {!used_emg_buf, o_str_alloc, 0, o_str_buf}; mp_print_t print = {&exc_pr, exc_add_strn}; - va_list ap; - va_start(ap, fmt); - mp_vprintf(&print, fmt, ap); - va_end(ap); + char fmt_decompressed[fmt->length]; + decompress(fmt, fmt_decompressed); + mp_vprintf(&print, fmt_decompressed, ap); exc_pr.buf[exc_pr.len] = '\0'; o_str->len = exc_pr.len; o_str->data = exc_pr.buf; @@ -404,7 +439,7 @@ mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char o_str->base.type = &mp_type_str; o_str->hash = qstr_compute_hash(o_str->data, o_str->len); mp_obj_t arg = MP_OBJ_FROM_PTR(o_str); - return mp_obj_exception_make_new(exc_type, 1, 0, &arg); + return mp_obj_exception_make_new(exc_type, 1, &arg, NULL); } // return true if the given object is an exception type @@ -517,3 +552,164 @@ void mp_obj_exception_get_traceback(mp_obj_t self_in, size_t *n, size_t **values *values = self->traceback_data; } } + +#if MICROPY_PY_SYS_EXC_INFO +STATIC const mp_obj_namedtuple_type_t code_type_obj = { + .base = { + .base = { + .type = &mp_type_type + }, + .name = MP_QSTR_code, + .print = namedtuple_print, + .make_new = namedtuple_make_new, + .unary_op = mp_obj_tuple_unary_op, + .binary_op = mp_obj_tuple_binary_op, + .attr = namedtuple_attr, + .subscr = mp_obj_tuple_subscr, + .getiter = mp_obj_tuple_getiter, + .parent = &mp_type_tuple, + }, + .n_fields = 15, + .fields = { + MP_QSTR_co_argcount, + MP_QSTR_co_kwonlyargcount, + MP_QSTR_co_nlocals, + MP_QSTR_co_stacksize, + MP_QSTR_co_flags, + MP_QSTR_co_code, + MP_QSTR_co_consts, + MP_QSTR_co_names, + MP_QSTR_co_varnames, + MP_QSTR_co_freevars, + MP_QSTR_co_cellvars, + MP_QSTR_co_filename, + MP_QSTR_co_name, + MP_QSTR_co_firstlineno, + MP_QSTR_co_lnotab, + }, +}; + +STATIC mp_obj_t code_make_new(qstr file, qstr block) { + mp_obj_t elems[15] = { + mp_obj_new_int(0), // co_argcount + mp_obj_new_int(0), // co_kwonlyargcount + mp_obj_new_int(0), // co_nlocals + mp_obj_new_int(0), // co_stacksize + mp_obj_new_int(0), // co_flags + mp_obj_new_bytearray(0, NULL), // co_code + mp_obj_new_tuple(0, NULL), // co_consts + mp_obj_new_tuple(0, NULL), // co_names + mp_obj_new_tuple(0, NULL), // co_varnames + mp_obj_new_tuple(0, NULL), // co_freevars + mp_obj_new_tuple(0, NULL), // co_cellvars + MP_OBJ_NEW_QSTR(file), // co_filename + MP_OBJ_NEW_QSTR(block), // co_name + mp_obj_new_int(1), // co_firstlineno + mp_obj_new_bytearray(0, NULL), // co_lnotab + }; + + return namedtuple_make_new((const mp_obj_type_t*)&code_type_obj, 15, elems, NULL); +} + +STATIC const mp_obj_namedtuple_type_t frame_type_obj = { + .base = { + .base = { + .type = &mp_type_type + }, + .name = MP_QSTR_frame, + .print = namedtuple_print, + .make_new = namedtuple_make_new, + .unary_op = mp_obj_tuple_unary_op, + .binary_op = mp_obj_tuple_binary_op, + .attr = namedtuple_attr, + .subscr = mp_obj_tuple_subscr, + .getiter = mp_obj_tuple_getiter, + .parent = &mp_type_tuple, + }, + .n_fields = 8, + .fields = { + MP_QSTR_f_back, + MP_QSTR_f_builtins, + MP_QSTR_f_code, + MP_QSTR_f_globals, + MP_QSTR_f_lasti, + MP_QSTR_f_lineno, + MP_QSTR_f_locals, + MP_QSTR_f_trace, + }, +}; + +STATIC mp_obj_t frame_make_new(mp_obj_t f_code, int f_lineno) { + mp_obj_t elems[8] = { + mp_const_none, // f_back + mp_obj_new_dict(0), // f_builtins + f_code, // f_code + mp_obj_new_dict(0), // f_globals + mp_obj_new_int(0), // f_lasti + mp_obj_new_int(f_lineno), // f_lineno + mp_obj_new_dict(0), // f_locals + mp_const_none, // f_trace + }; + + return namedtuple_make_new((const mp_obj_type_t*)&frame_type_obj, 8, elems, NULL); +} + +STATIC const mp_obj_namedtuple_type_t traceback_type_obj = { + .base = { + .base = { + .type = &mp_type_type + }, + .name = MP_QSTR_traceback, + .print = namedtuple_print, + .make_new = namedtuple_make_new, + .unary_op = mp_obj_tuple_unary_op, + .binary_op = mp_obj_tuple_binary_op, + .attr = namedtuple_attr, + .subscr = mp_obj_tuple_subscr, + .getiter = mp_obj_tuple_getiter, + .parent = &mp_type_tuple, + }, + .n_fields = 4, + .fields = { + MP_QSTR_tb_frame, + MP_QSTR_tb_lasti, + MP_QSTR_tb_lineno, + MP_QSTR_tb_next, + }, +}; + +STATIC mp_obj_t traceback_from_values(size_t *values, mp_obj_t tb_next) { + int lineno = values[1]; + + mp_obj_t elems[4] = { + frame_make_new(code_make_new(values[0], values[2]), lineno), + mp_obj_new_int(0), + mp_obj_new_int(lineno), + tb_next, + }; + + return namedtuple_make_new((const mp_obj_type_t*)&traceback_type_obj, 4, elems, NULL); +}; + +mp_obj_t mp_obj_exception_get_traceback_obj(mp_obj_t self_in) { + mp_obj_exception_t *self = MP_OBJ_TO_PTR(self_in); + + if (!mp_obj_is_exception_instance(self)) { + return mp_const_none; + } + + size_t n, *values; + mp_obj_exception_get_traceback(self, &n, &values); + if (n == 0) { + return mp_const_none; + } + + mp_obj_t tb_next = mp_const_none; + + for (size_t i = 0; i < n; i += 3) { + tb_next = traceback_from_values(&values[i], tb_next); + } + + return tb_next; +} +#endif diff --git a/py/objfilter.c b/py/objfilter.c index cb965d8c323..af95326e609 100644 --- a/py/objfilter.c +++ b/py/objfilter.c @@ -34,8 +34,8 @@ typedef struct _mp_obj_filter_t { mp_obj_t iter; } mp_obj_filter_t; -STATIC mp_obj_t filter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 2, 2, false); +STATIC mp_obj_t filter_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 2, 2, false); mp_obj_filter_t *o = m_new_obj(mp_obj_filter_t); o->base.type = type; o->fun = args[0]; diff --git a/py/objfloat.c b/py/objfloat.c index b62fe8e71de..f544ade0530 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -32,11 +32,16 @@ #include "py/parsenum.h" #include "py/runtime.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_BUILTINS_FLOAT #include #include "py/formatfloat.h" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" + #if MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_C && MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_D // M_E and M_PI are not part of the math.h standard and may not be defined @@ -128,9 +133,9 @@ STATIC void float_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t } } -STATIC mp_obj_t float_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t float_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 0, 1, false); + mp_arg_check_num(n_args, kw_args, 0, 1, false); switch (n_args) { case 0: @@ -262,7 +267,7 @@ mp_obj_t mp_obj_float_binary_op(mp_binary_op_t op, mp_float_t lhs_val, mp_obj_t case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE: if (rhs_val == 0) { zero_division_error: - mp_raise_msg(&mp_type_ZeroDivisionError, "division by zero"); + mp_raise_msg(&mp_type_ZeroDivisionError, translate("division by zero")); } // Python specs require that x == (x//y)*y + (x%y) so we must // call divmod to compute the correct floor division, which @@ -300,7 +305,7 @@ mp_obj_t mp_obj_float_binary_op(mp_binary_op_t op, mp_float_t lhs_val, mp_obj_t #if MICROPY_PY_BUILTINS_COMPLEX return mp_obj_complex_binary_op(MP_BINARY_OP_POWER, lhs_val, 0, rhs_in); #else - mp_raise_ValueError("complex values not supported"); + mp_raise_ValueError(translate("complex values not supported")); #endif } lhs_val = MICROPY_FLOAT_C_FUN(pow)(lhs_val, rhs_val); @@ -328,4 +333,6 @@ mp_obj_t mp_obj_float_binary_op(mp_binary_op_t op, mp_float_t lhs_val, mp_obj_t return mp_obj_new_float(lhs_val); } +#pragma GCC diagnostic pop + #endif // MICROPY_PY_BUILTINS_FLOAT diff --git a/py/objfun.c b/py/objfun.c index 8c51d92e068..b8364815be9 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -52,7 +52,7 @@ STATIC mp_obj_t fun_builtin_0_call(mp_obj_t self_in, size_t n_args, size_t n_kw, (void)args; assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_0)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); - mp_arg_check_num(n_args, n_kw, 0, 0, false); + mp_arg_check_num_kw_array(n_args, n_kw, 0, 0, false); return self->fun._0(); } @@ -66,7 +66,7 @@ const mp_obj_type_t mp_type_fun_builtin_0 = { STATIC mp_obj_t fun_builtin_1_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_1)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); - mp_arg_check_num(n_args, n_kw, 1, 1, false); + mp_arg_check_num_kw_array(n_args, n_kw, 1, 1, false); return self->fun._1(args[0]); } @@ -80,7 +80,7 @@ const mp_obj_type_t mp_type_fun_builtin_1 = { STATIC mp_obj_t fun_builtin_2_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_2)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); - mp_arg_check_num(n_args, n_kw, 2, 2, false); + mp_arg_check_num_kw_array(n_args, n_kw, 2, 2, false); return self->fun._2(args[0], args[1]); } @@ -94,7 +94,7 @@ const mp_obj_type_t mp_type_fun_builtin_2 = { STATIC mp_obj_t fun_builtin_3_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_3)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); - mp_arg_check_num(n_args, n_kw, 3, 3, false); + mp_arg_check_num_kw_array(n_args, n_kw, 3, 3, false); return self->fun._3(args[0], args[1], args[2]); } @@ -110,7 +110,7 @@ STATIC mp_obj_t fun_builtin_var_call(mp_obj_t self_in, size_t n_args, size_t n_k mp_obj_fun_builtin_var_t *self = MP_OBJ_TO_PTR(self_in); // check number of arguments - mp_arg_check_num(n_args, n_kw, self->n_args_min, self->n_args_max, self->is_kw); + mp_arg_check_num_kw_array(n_args, n_kw, self->n_args_min, self->n_args_max, self->is_kw); if (self->is_kw) { // function allows keywords @@ -436,7 +436,7 @@ typedef mp_uint_t (*viper_fun_4_t)(mp_uint_t, mp_uint_t, mp_uint_t, mp_uint_t); STATIC mp_obj_t fun_viper_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_obj_fun_viper_t *self = self_in; - mp_arg_check_num(n_args, n_kw, self->n_args, self->n_args, false); + mp_arg_check_num_kw_array(n_args, n_kw, self->n_args, self->n_args, false); void *fun = MICROPY_MAKE_POINTER_CALLABLE(self->fun_data); diff --git a/py/objgenerator.c b/py/objgenerator.c index a2ad490d63a..01d42ba94fa 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -34,6 +34,8 @@ #include "py/objfun.h" #include "py/stackctrl.h" +#include "supervisor/shared/translate.h" + /******************************************************************************/ /* generator wrapper */ @@ -103,7 +105,7 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_ } if (self->code_state.sp == self->code_state.state - 1) { if (send_value != mp_const_none) { - mp_raise_TypeError("can't send non-None value to a just-started generator"); + mp_raise_TypeError(translate("can't send non-None value to a just-started generator")); } } else { #if MICROPY_PY_GENERATOR_PEND_THROW @@ -121,7 +123,7 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_ // We set self->globals=NULL while executing, for a sentinel to ensure the generator // cannot be reentered during execution if (self->globals == NULL) { - mp_raise_ValueError("generator already executing"); + mp_raise_ValueError(translate("generator already executing")); } // Set up the correct globals context for the generator and execute it @@ -224,7 +226,7 @@ STATIC mp_obj_t gen_instance_close(mp_obj_t self_in) { mp_obj_t ret; switch (mp_obj_gen_resume(self_in, mp_const_none, MP_OBJ_FROM_PTR(&mp_const_GeneratorExit_obj), &ret)) { case MP_VM_RETURN_YIELD: - mp_raise_msg(&mp_type_RuntimeError, "generator ignored GeneratorExit"); + mp_raise_RuntimeError(translate("generator ignored GeneratorExit")); // Swallow StopIteration & GeneratorExit (== successful close), and re-raise any other case MP_VM_RETURN_EXCEPTION: @@ -246,7 +248,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(gen_instance_close_obj, gen_instance_close); STATIC mp_obj_t gen_instance_pend_throw(mp_obj_t self_in, mp_obj_t exc_in) { mp_obj_gen_instance_t *self = MP_OBJ_TO_PTR(self_in); if (self->code_state.sp == self->code_state.state - 1) { - mp_raise_TypeError("can't pend throw to just-started generator"); + mp_raise_TypeError(translate("can't pend throw to just-started generator")); } mp_obj_t prev = *self->code_state.sp; *self->code_state.sp = exc_in; diff --git a/py/objint.c b/py/objint.c index 270e1696941..9e11871f109 100644 --- a/py/objint.c +++ b/py/objint.c @@ -35,14 +35,16 @@ #include "py/runtime.h" #include "py/binary.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_BUILTINS_FLOAT #include #endif // This dispatcher function is expected to be independent of the implementation of long int -STATIC mp_obj_t mp_obj_int_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t mp_obj_int_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 0, 2, false); + mp_arg_check_num(n_args, kw_args, 0, 2, false); switch (n_args) { case 0: @@ -139,9 +141,9 @@ STATIC mp_fp_as_int_class_t mp_classify_fp_as_int(mp_float_t val) { mp_obj_t mp_obj_new_int_from_float(mp_float_t val) { int cl = fpclassify(val); if (cl == FP_INFINITE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "can't convert inf to int")); + nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, translate("can't convert inf to int"))); } else if (cl == FP_NAN) { - mp_raise_ValueError("can't convert NaN to int"); + mp_raise_ValueError(translate("can't convert NaN to int")); } else { mp_fp_as_int_class_t icl = mp_classify_fp_as_int(val); if (icl == MP_FP_CLASS_FIT_SMALLINT) { @@ -158,7 +160,7 @@ mp_obj_t mp_obj_new_int_from_float(mp_float_t val) { return mp_obj_new_int_from_ll((long long)val); #endif } else { - mp_raise_ValueError("float too big"); + mp_raise_ValueError(translate("float too big")); } #endif } @@ -298,6 +300,76 @@ char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_co return b; } +#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE + +void mp_obj_int_buffer_overflow_check(mp_obj_t self_in, size_t nbytes, bool is_signed) +{ + if (is_signed) { + // self must be < 2**(bits - 1) + mp_obj_t edge = mp_binary_op(MP_BINARY_OP_INPLACE_LSHIFT, + mp_obj_new_int(1), + mp_obj_new_int(nbytes * 8 - 1)); + + if (mp_binary_op(MP_BINARY_OP_LESS, self_in, edge) == mp_const_true) { + // and >= -2**(bits - 1) + edge = mp_unary_op(MP_UNARY_OP_NEGATIVE, edge); + if (mp_binary_op(MP_BINARY_OP_MORE_EQUAL, self_in, edge) == mp_const_true) { + return; + } + } + } else { + // self must be >= 0 + if (mp_obj_int_sign(self_in) >= 0) { + // and < 2**(bits) + mp_obj_t edge = mp_binary_op(MP_BINARY_OP_INPLACE_LSHIFT, + mp_obj_new_int(1), + mp_obj_new_int(nbytes * 8)); + + if (mp_binary_op(MP_BINARY_OP_LESS, self_in, edge) == mp_const_true) { + return; + } + } + } + + mp_raise_OverflowError_varg(translate("value must fit in %d byte(s)"), nbytes); +} + +#endif // MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE + +void mp_small_int_buffer_overflow_check(mp_int_t val, size_t nbytes, bool is_signed) { + // Fast path for zero. + if (val == 0) { + return; + } + + // Trying to store negative values in unsigned bytes falls through to failure. + if (is_signed || val >= 0) { + + if (nbytes >= sizeof(val)) { + // All non-negative N bit signed integers fit in an unsigned N bit integer. + // This case prevents shifting too far below. + return; + } + + if (is_signed) { + mp_int_t edge = ((mp_int_t)1 << (nbytes * 8 - 1)); + if (-edge <= val && val < edge) { + return; + } + // Out of range, fall through to failure. + } else { + // Unsigned. We already know val >= 0. + mp_int_t edge = ((mp_int_t)1 << (nbytes * 8)); + if (val < edge) { + return; + } + } + // Fall through to failure. + } + + mp_raise_OverflowError_varg(translate("value must fit in %d byte(s)"), nbytes); +} + #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE int mp_obj_int_sign(mp_obj_t self_in) { @@ -323,19 +395,19 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i // This is called only with strings whose value doesn't fit in SMALL_INT mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base) { - mp_raise_msg(&mp_type_OverflowError, "long int not supported in this build"); + mp_raise_msg(&mp_type_OverflowError, translate("long int not supported in this build")); return mp_const_none; } // This is called when an integer larger than a SMALL_INT is needed (although val might still fit in a SMALL_INT) mp_obj_t mp_obj_new_int_from_ll(long long val) { - mp_raise_msg(&mp_type_OverflowError, "small int overflow"); + mp_raise_msg(&mp_type_OverflowError, translate("small int overflow")); return mp_const_none; } // This is called when an integer larger than a SMALL_INT is needed (although val might still fit in a SMALL_INT) mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) { - mp_raise_msg(&mp_type_OverflowError, "small int overflow"); + mp_raise_msg(&mp_type_OverflowError, translate("small int overflow")); return mp_const_none; } @@ -345,7 +417,7 @@ mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) { if ((value & ~MP_SMALL_INT_POSITIVE_MASK) == 0) { return MP_OBJ_NEW_SMALL_INT(value); } - mp_raise_msg(&mp_type_OverflowError, "small int overflow"); + mp_raise_msg(&mp_type_OverflowError, translate("small int overflow")); return mp_const_none; } @@ -353,7 +425,7 @@ mp_obj_t mp_obj_new_int(mp_int_t value) { if (MP_SMALL_INT_FITS(value)) { return MP_OBJ_NEW_SMALL_INT(value); } - mp_raise_msg(&mp_type_OverflowError, "small int overflow"); + mp_raise_msg(&mp_type_OverflowError, translate("small int overflow")); return mp_const_none; } @@ -435,11 +507,14 @@ STATIC mp_obj_t int_to_bytes(size_t n_args, const mp_obj_t *args) { #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE if (!MP_OBJ_IS_SMALL_INT(args[0])) { + mp_obj_int_buffer_overflow_check(args[0], len, false); mp_obj_int_to_bytes_impl(args[0], big_endian, len, data); } else #endif { mp_int_t val = MP_OBJ_SMALL_INT_VALUE(args[0]); + // Small int checking is separate, to be fast. + mp_small_int_buffer_overflow_check(val, len, false); size_t l = MIN((size_t)len, sizeof(val)); mp_binary_set_int(l, big_endian, data + (big_endian ? (len - l) : 0), val); } diff --git a/py/objint.h b/py/objint.h index 4b95acde9f8..e8c9bc3e063 100644 --- a/py/objint.h +++ b/py/objint.h @@ -53,6 +53,12 @@ char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_co int base, const char *prefix, char base_char, char comma); char *mp_obj_int_formatted_impl(char **buf, size_t *buf_size, size_t *fmt_size, mp_const_obj_t self_in, int base, const char *prefix, char base_char, char comma); +#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE +void mp_obj_int_buffer_overflow_check(mp_obj_t self_in, size_t nbytes, bool is_signed); +#endif + +void mp_small_int_buffer_overflow_check(mp_int_t val, size_t nbytes, bool is_signed); + mp_int_t mp_obj_int_hash(mp_obj_t self_in); mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf); void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf); diff --git a/py/objint_longlong.c b/py/objint_longlong.c index cb8d1672d9f..ce02fa1755f 100644 --- a/py/objint_longlong.c +++ b/py/objint_longlong.c @@ -32,6 +32,8 @@ #include "py/objint.h" #include "py/runtime.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_BUILTINS_FLOAT #include #endif @@ -184,7 +186,7 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i #if MICROPY_PY_BUILTINS_FLOAT return mp_obj_float_binary_op(op, lhs_val, rhs_in); #else - mp_raise_ValueError("negative power with no float support"); + mp_raise_ValueError(translate("negative power with no float support")); #endif } long long ans = 1; @@ -217,7 +219,7 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i } zero_division: - mp_raise_msg(&mp_type_ZeroDivisionError, "division by zero"); + mp_raise_msg(&mp_type_ZeroDivisionError, translate("division by zero")); } mp_obj_t mp_obj_new_int(mp_int_t value) { @@ -246,7 +248,7 @@ mp_obj_t mp_obj_new_int_from_ll(long long val) { mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) { // TODO raise an exception if the unsigned long long won't fit if (val >> (sizeof(unsigned long long) * 8 - 1) != 0) { - mp_raise_msg(&mp_type_OverflowError, "ulonglong too large"); + mp_raise_msg(&mp_type_OverflowError, translate("ulonglong too large")); } mp_obj_int_t *o = m_new_obj(mp_obj_int_t); o->base.type = &mp_type_int; diff --git a/py/objint_mpz.c b/py/objint_mpz.c index 0f05c84f47e..95e4d7e1768 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -33,6 +33,8 @@ #include "py/objint.h" #include "py/runtime.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_BUILTINS_FLOAT #include #endif @@ -225,7 +227,7 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE: { if (mpz_is_zero(zrhs)) { zero_division_error: - mp_raise_msg(&mp_type_ZeroDivisionError, "division by zero"); + mp_raise_msg(&mp_type_ZeroDivisionError, translate("division by zero")); } mpz_t rem; mpz_init_zero(&rem); mpz_divmod_inpl(&res->mpz, &rem, zlhs, zrhs); @@ -262,7 +264,7 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i case MP_BINARY_OP_INPLACE_RSHIFT: { mp_int_t irhs = mp_obj_int_get_checked(rhs_in); if (irhs < 0) { - mp_raise_ValueError("negative shift count"); + mp_raise_ValueError(translate("negative shift count")); } if (op == MP_BINARY_OP_LSHIFT || op == MP_BINARY_OP_INPLACE_LSHIFT) { mpz_shl_inpl(&res->mpz, zlhs, irhs); @@ -278,7 +280,7 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i #if MICROPY_PY_BUILTINS_FLOAT return mp_obj_float_binary_op(op, mpz_as_float(zlhs), rhs_in); #else - mp_raise_ValueError("negative power with no float support"); + mp_raise_ValueError(translate("negative power with no float support")); #endif } mpz_pow_inpl(&res->mpz, zlhs, zrhs); @@ -331,7 +333,7 @@ STATIC mpz_t *mp_mpz_for_int(mp_obj_t arg, mpz_t *temp) { mp_obj_t mp_obj_int_pow3(mp_obj_t base, mp_obj_t exponent, mp_obj_t modulus) { if (!MP_OBJ_IS_INT(base) || !MP_OBJ_IS_INT(exponent) || !MP_OBJ_IS_INT(modulus)) { - mp_raise_TypeError("pow() with 3 arguments requires integers"); + mp_raise_TypeError(translate("pow() with 3 arguments requires integers")); } else { mp_obj_t result = mp_obj_new_int_from_ull(0); // Use the _from_ull version as this forces an mpz int mp_obj_int_t *res_p = (mp_obj_int_t *) MP_OBJ_TO_PTR(result); @@ -341,6 +343,10 @@ mp_obj_t mp_obj_int_pow3(mp_obj_t base, mp_obj_t exponent, mp_obj_t modulus) { mpz_t *rhs = mp_mpz_for_int(exponent, &r_temp); mpz_t *mod = mp_mpz_for_int(modulus, &m_temp); + if (mpz_is_zero(mod)) { + mp_raise_msg(&mp_type_ValueError, translate("pow() 3rd argument cannot be 0")); + } + mpz_pow3_inpl(&(res_p->mpz), lhs, rhs, mod); if (lhs == &l_temp) { mpz_deinit(lhs); } @@ -406,7 +412,7 @@ mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) { return value; } else { // overflow - mp_raise_msg(&mp_type_OverflowError, "overflow converting long int to machine word"); + mp_raise_msg(&mp_type_OverflowError, translate("overflow converting long int to machine word")); } } } diff --git a/py/objlist.c b/py/objlist.c index 1a18f937d62..ea38e64e551 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -31,6 +31,8 @@ #include "py/runtime.h" #include "py/stackctrl.h" +#include "supervisor/shared/translate.h" + STATIC mp_obj_t mp_obj_new_list_iterator(mp_obj_t list, size_t cur, mp_obj_iter_buf_t *iter_buf); STATIC mp_obj_list_t *list_new(size_t n); STATIC mp_obj_t list_extend(mp_obj_t self_in, mp_obj_t arg_in); @@ -66,9 +68,14 @@ STATIC mp_obj_t list_extend_from_iter(mp_obj_t list, mp_obj_t iterable) { return list; } -STATIC mp_obj_t list_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +mp_obj_t mp_obj_new_list_from_iter(mp_obj_t iterable) { + mp_obj_t list = mp_obj_new_list(0, NULL); + return list_extend_from_iter(list, iterable); +} + +STATIC mp_obj_t list_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 0, 1, false); + mp_arg_check_num(n_args, kw_args, 0, 1, false); switch (n_args) { case 0: @@ -124,7 +131,8 @@ STATIC mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { if (n < 0) { n = 0; } - mp_obj_list_t *s = list_new(o->len * n); + size_t new_len = mp_seq_multiply_len(o->len, n); + mp_obj_list_t *s = list_new(new_len); mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items); return MP_OBJ_FROM_PTR(s); } @@ -268,7 +276,7 @@ STATIC mp_obj_t list_pop(size_t n_args, const mp_obj_t *args) { mp_check_self(MP_OBJ_IS_TYPE(args[0], &mp_type_list)); mp_obj_list_t *self = MP_OBJ_TO_PTR(args[0]); if (self->len == 0) { - mp_raise_msg(&mp_type_IndexError, "pop from empty list"); + mp_raise_IndexError(translate("pop from empty list")); } size_t index = mp_get_index(self->base.type, self->len, n_args == 1 ? MP_OBJ_NEW_SMALL_INT(-1) : args[1], false); mp_obj_t ret = self->items[index]; @@ -337,7 +345,7 @@ mp_obj_t mp_obj_list_sort(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ return mp_const_none; } -STATIC mp_obj_t list_clear(mp_obj_t self_in) { +mp_obj_t mp_obj_list_clear(mp_obj_t self_in) { mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_list)); mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in); self->len = 0; @@ -415,7 +423,7 @@ STATIC mp_obj_t list_reverse(mp_obj_t self_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_2(list_append_obj, mp_obj_list_append); STATIC MP_DEFINE_CONST_FUN_OBJ_2(list_extend_obj, list_extend); -STATIC MP_DEFINE_CONST_FUN_OBJ_1(list_clear_obj, list_clear); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(list_clear_obj, mp_obj_list_clear); STATIC MP_DEFINE_CONST_FUN_OBJ_1(list_copy_obj, list_copy); STATIC MP_DEFINE_CONST_FUN_OBJ_2(list_count_obj, list_count); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(list_index_obj, 2, 4, list_index); diff --git a/py/objmap.c b/py/objmap.c index 908c61507e7..cf71f99eeb0 100644 --- a/py/objmap.c +++ b/py/objmap.c @@ -36,8 +36,8 @@ typedef struct _mp_obj_map_t { mp_obj_t iters[]; } mp_obj_map_t; -STATIC mp_obj_t map_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 2, MP_OBJ_FUN_ARGS_MAX, false); +STATIC mp_obj_t map_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 2, MP_OBJ_FUN_ARGS_MAX, false); mp_obj_map_t *o = m_new_obj_var(mp_obj_map_t, mp_obj_t, n_args - 1); o->base.type = type; o->n_iters = n_args - 1; diff --git a/py/objmodule.c b/py/objmodule.c index c4aba3a7b40..627ba79e8a2 100644 --- a/py/objmodule.c +++ b/py/objmodule.c @@ -27,10 +27,13 @@ #include #include +#include "py/gc.h" #include "py/objmodule.h" #include "py/runtime.h" #include "py/builtin.h" +#include "genhdr/moduledefs.h" + STATIC void module_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; mp_obj_module_t *self = MP_OBJ_TO_PTR(self_in); @@ -84,8 +87,9 @@ STATIC void module_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { mp_obj_dict_delete(MP_OBJ_FROM_PTR(dict), MP_OBJ_NEW_QSTR(attr)); } else { // store attribute + mp_obj_t long_lived = gc_make_long_lived(dest[1]); // TODO CPython allows STORE_ATTR to a module, but is this the correct implementation? - mp_obj_dict_store(MP_OBJ_FROM_PTR(dict), MP_OBJ_NEW_QSTR(attr), dest[1]); + mp_obj_dict_store(MP_OBJ_FROM_PTR(dict), MP_OBJ_NEW_QSTR(attr), long_lived); } dest[0] = MP_OBJ_NULL; // indicate success } @@ -108,9 +112,9 @@ mp_obj_t mp_obj_new_module(qstr module_name) { } // create new module object - mp_obj_module_t *o = m_new_obj(mp_obj_module_t); + mp_obj_module_t *o = m_new_ll_obj(mp_obj_module_t); o->base.type = &mp_type_module; - o->globals = MP_OBJ_TO_PTR(mp_obj_new_dict(MICROPY_MODULE_DICT_SIZE)); + o->globals = MP_OBJ_TO_PTR(gc_make_long_lived(mp_obj_new_dict(MICROPY_MODULE_DICT_SIZE))); // store __name__ entry in the module mp_obj_dict_store(MP_OBJ_FROM_PTR(o->globals), MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(module_name)); @@ -128,6 +132,12 @@ mp_obj_dict_t *mp_obj_module_get_globals(mp_obj_t self_in) { return self->globals; } +void mp_obj_module_set_globals(mp_obj_t self_in, mp_obj_dict_t *globals) { + assert(MP_OBJ_IS_TYPE(self_in, &mp_type_module)); + mp_obj_module_t *self = MP_OBJ_TO_PTR(self_in); + self->globals = globals; +} + /******************************************************************************/ // Global module table and related functions @@ -140,11 +150,16 @@ STATIC const mp_rom_map_elem_t mp_builtin_module_table[] = { { MP_ROM_QSTR(MP_QSTR_array), MP_ROM_PTR(&mp_module_array) }, #endif #if MICROPY_PY_IO +#if CIRCUITPY + { MP_ROM_QSTR(MP_QSTR_io), MP_ROM_PTR(&mp_module_io) }, +#else { MP_ROM_QSTR(MP_QSTR_uio), MP_ROM_PTR(&mp_module_io) }, #endif +#endif #if MICROPY_PY_COLLECTIONS - { MP_ROM_QSTR(MP_QSTR_ucollections), MP_ROM_PTR(&mp_module_collections) }, + { MP_ROM_QSTR(MP_QSTR_collections), MP_ROM_PTR(&mp_module_collections) }, #endif +// CircuitPython: Now in shared-bindings/, so not defined here. #if MICROPY_PY_STRUCT { MP_ROM_QSTR(MP_QSTR_ustruct), MP_ROM_PTR(&mp_module_ustruct) }, #endif @@ -170,8 +185,13 @@ STATIC const mp_rom_map_elem_t mp_builtin_module_table[] = { // extmod modules #if MICROPY_PY_UERRNO +#if CIRCUITPY +// CircuitPython: Defined in MICROPY_PORT_BUILTIN_MODULES, so not defined here. +// TODO: move to shared-bindings/ +#else { MP_ROM_QSTR(MP_QSTR_uerrno), MP_ROM_PTR(&mp_module_uerrno) }, #endif +#endif #if MICROPY_PY_UCTYPES { MP_ROM_QSTR(MP_QSTR_uctypes), MP_ROM_PTR(&mp_module_uctypes) }, #endif @@ -179,11 +199,21 @@ STATIC const mp_rom_map_elem_t mp_builtin_module_table[] = { { MP_ROM_QSTR(MP_QSTR_uzlib), MP_ROM_PTR(&mp_module_uzlib) }, #endif #if MICROPY_PY_UJSON +#if CIRCUITPY +// CircuitPython: Defined in MICROPY_PORT_BUILTIN_MODULES, so not defined here. +// TODO: move to shared-bindings/ +#else { MP_ROM_QSTR(MP_QSTR_ujson), MP_ROM_PTR(&mp_module_ujson) }, #endif +#endif #if MICROPY_PY_URE +#if CIRCUITPY +// CircuitPython: Defined in MICROPY_PORT_BUILTIN_MODULES, so not defined here. +// TODO: move to shared-bindings/ +#else { MP_ROM_QSTR(MP_QSTR_ure), MP_ROM_PTR(&mp_module_ure) }, #endif +#endif #if MICROPY_PY_UHEAPQ { MP_ROM_QSTR(MP_QSTR_uheapq), MP_ROM_PTR(&mp_module_uheapq) }, #endif @@ -191,10 +221,10 @@ STATIC const mp_rom_map_elem_t mp_builtin_module_table[] = { { MP_ROM_QSTR(MP_QSTR_utimeq), MP_ROM_PTR(&mp_module_utimeq) }, #endif #if MICROPY_PY_UHASHLIB - { MP_ROM_QSTR(MP_QSTR_uhashlib), MP_ROM_PTR(&mp_module_uhashlib) }, + { MP_ROM_QSTR(MP_QSTR_hashlib), MP_ROM_PTR(&mp_module_uhashlib) }, #endif #if MICROPY_PY_UBINASCII - { MP_ROM_QSTR(MP_QSTR_ubinascii), MP_ROM_PTR(&mp_module_ubinascii) }, + { MP_ROM_QSTR(MP_QSTR_binascii), MP_ROM_PTR(&mp_module_ubinascii) }, #endif #if MICROPY_PY_URANDOM { MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&mp_module_urandom) }, @@ -223,6 +253,15 @@ STATIC const mp_rom_map_elem_t mp_builtin_module_table[] = { // extra builtin modules as defined by a port MICROPY_PORT_BUILTIN_MODULES + + #ifdef MICROPY_REGISTERED_MODULES + // builtin modules declared with MP_REGISTER_MODULE() + MICROPY_REGISTERED_MODULES + #endif + +#if defined(MICROPY_DEBUG_MODULES) && defined(MICROPY_PORT_BUILTIN_DEBUG_MODULES) + , MICROPY_PORT_BUILTIN_DEBUG_MODULES +#endif }; MP_DEFINE_CONST_MAP(mp_builtin_module_map, mp_builtin_module_table); diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index e7de899cf9d..a044fe3ff81 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -32,6 +32,8 @@ #include "py/objstr.h" #include "py/objnamedtuple.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_COLLECTIONS size_t mp_obj_namedtuple_find_field(const mp_obj_namedtuple_type_t *type, qstr name) { @@ -60,7 +62,7 @@ STATIC mp_obj_t namedtuple_asdict(mp_obj_t self_in) { MP_DEFINE_CONST_FUN_OBJ_1(namedtuple_asdict_obj, namedtuple_asdict); #endif -STATIC void namedtuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { +void namedtuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { (void)kind; mp_obj_namedtuple_t *o = MP_OBJ_TO_PTR(o_in); mp_printf(print, "%q", o->tuple.base.type->name); @@ -68,7 +70,7 @@ STATIC void namedtuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_ki mp_obj_attrtuple_print_helper(print, fields, &o->tuple); } -STATIC void namedtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { +void namedtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { if (dest[0] == MP_OBJ_NULL) { // load attribute mp_obj_namedtuple_t *self = MP_OBJ_TO_PTR(self_in); @@ -87,24 +89,28 @@ STATIC void namedtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } else { // delete/store attribute // provide more detailed error message than we'd get by just returning - mp_raise_msg(&mp_type_AttributeError, "can't set attribute"); + mp_raise_AttributeError(translate("can't set attribute")); } } -STATIC mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { const mp_obj_namedtuple_type_t *type = (const mp_obj_namedtuple_type_t*)type_in; size_t num_fields = type->n_fields; + size_t n_kw = 0; + if (kw_args != NULL) { + n_kw = kw_args->used; + } if (n_args + n_kw != num_fields) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_arg_error_terse_mismatch(); } else if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "function takes %d positional arguments but %d were given", - num_fields, n_args + n_kw)); + mp_raise_TypeError_varg( + translate("function takes %d positional arguments but %d were given"), + num_fields, n_args + n_kw); } else if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "%q() takes %d positional arguments but %d were given", - type->base.name, num_fields, n_args + n_kw)); + mp_raise_TypeError_varg( + translate("%q() takes %d positional arguments but %d were given"), + type->base.name, num_fields, n_args + n_kw); } } @@ -117,26 +123,26 @@ STATIC mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, // Fill in the remaining slots with the keyword args memset(&tuple->items[n_args], 0, sizeof(mp_obj_t) * n_kw); - for (size_t i = n_args; i < n_args + 2 * n_kw; i += 2) { - qstr kw = mp_obj_str_get_qstr(args[i]); + for (size_t i = 0; i < n_kw; i++) { + qstr kw = mp_obj_str_get_qstr(kw_args->table[i].key); size_t id = mp_obj_namedtuple_find_field(type, kw); if (id == (size_t)-1) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_arg_error_terse_mismatch(); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "unexpected keyword argument '%q'", kw)); + mp_raise_TypeError_varg( + translate("unexpected keyword argument '%q'"), kw); } } if (tuple->items[id] != MP_OBJ_NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_arg_error_terse_mismatch(); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "function got multiple values for argument '%q'", kw)); + mp_raise_TypeError_varg( + translate("function got multiple values for argument '%q'"), kw); } } - tuple->items[id] = args[i + 1]; + tuple->items[id] = kw_args->table[i].value; } return MP_OBJ_FROM_PTR(tuple); diff --git a/py/objnamedtuple.h b/py/objnamedtuple.h index d32af35afec..0ea0d28622d 100644 --- a/py/objnamedtuple.h +++ b/py/objnamedtuple.h @@ -1,9 +1,10 @@ /* - * 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) * - * Copyright (c) 2014-2017 Paul Sokolovsky + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,10 +24,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + #ifndef MICROPY_INCLUDED_PY_OBJNAMEDTUPLE_H #define MICROPY_INCLUDED_PY_OBJNAMEDTUPLE_H +#include + +#include "py/nlr.h" #include "py/objtuple.h" +#include "py/runtime.h" +#include "py/objstr.h" + +#if MICROPY_PY_COLLECTIONS typedef struct _mp_obj_namedtuple_type_t { mp_obj_type_t base; @@ -38,7 +47,12 @@ typedef struct _mp_obj_namedtuple_t { mp_obj_tuple_t tuple; } mp_obj_namedtuple_t; +void namedtuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind); size_t mp_obj_namedtuple_find_field(const mp_obj_namedtuple_type_t *type, qstr name); +void namedtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest); mp_obj_namedtuple_type_t *mp_obj_new_namedtuple_base(size_t n_fields, mp_obj_t *fields); +mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); + +#endif // MICROPY_PY_COLLECTIONS -#endif // MICROPY_INCLUDED_PY_OBJNAMEDTUPLE_H +#endif // MICROPY_INCLUDED_PY_OBJNAMEDTUPLE_H diff --git a/py/objobject.c b/py/objobject.c index 265fcfbf2b4..a42edde3c6c 100644 --- a/py/objobject.c +++ b/py/objobject.c @@ -29,13 +29,15 @@ #include "py/objtype.h" #include "py/runtime.h" +#include "supervisor/shared/translate.h" + typedef struct _mp_obj_object_t { mp_obj_base_t base; } mp_obj_object_t; -STATIC mp_obj_t object_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t object_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)args; - mp_arg_check_num(n_args, n_kw, 0, 0, false); + mp_arg_check_num(n_args, kw_args, 0, 0, false); mp_obj_object_t *o = m_new_obj(mp_obj_object_t); o->base.type = type; return MP_OBJ_FROM_PTR(o); @@ -50,7 +52,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(object___init___obj, object___init__); STATIC mp_obj_t object___new__(mp_obj_t cls) { if (!MP_OBJ_IS_TYPE(cls, &mp_type_type) || !mp_obj_is_instance_type((mp_obj_type_t*)MP_OBJ_TO_PTR(cls))) { - mp_raise_TypeError("__new__ arg must be a user-type"); + mp_raise_TypeError(translate("__new__ arg must be a user-type")); } // This executes only "__new__" part of instance creation. // TODO: This won't work well for classes with native bases. diff --git a/py/objproperty.c b/py/objproperty.c index b66d24a119a..ddf484af2b9 100644 --- a/py/objproperty.c +++ b/py/objproperty.c @@ -27,16 +27,13 @@ #include #include +#include "py/nlr.h" +#include "py/objproperty.h" #include "py/runtime.h" #if MICROPY_PY_BUILTINS_PROPERTY -typedef struct _mp_obj_property_t { - mp_obj_base_t base; - mp_obj_t proxy[3]; // getter, setter, deleter -} mp_obj_property_t; - -STATIC mp_obj_t property_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t property_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { enum { ARG_fget, ARG_fset, ARG_fdel, ARG_doc }; static const mp_arg_t allowed_args[] = { { MP_QSTR_, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} }, @@ -45,7 +42,7 @@ STATIC mp_obj_t property_make_new(const mp_obj_type_t *type, size_t n_args, size { MP_QSTR_doc, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} }, }; mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals); + mp_arg_parse_all(n_args, args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals); mp_obj_property_t *o = m_new_obj(mp_obj_property_t); o->base.type = type; diff --git a/py/objproperty.h b/py/objproperty.h new file mode 100644 index 00000000000..f95c1083c0f --- /dev/null +++ b/py/objproperty.h @@ -0,0 +1,40 @@ +/* + * 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. + */ +#ifndef MICROPY_INCLUDED_PY_OBJPROPERTY_H +#define MICROPY_INCLUDED_PY_OBJPROPERTY_H + +#include "py/obj.h" + +#if MICROPY_PY_BUILTINS_PROPERTY + +typedef struct _mp_obj_property_t { + mp_obj_base_t base; + mp_obj_t proxy[3]; // getter, setter, deleter +} mp_obj_property_t; + +#endif // MICROPY_PY_BUILTINS_PROPERTY + +#endif // MICROPY_INCLUDED_PY_OBJPROPERTY_H diff --git a/py/objrange.c b/py/objrange.c index 86aa0ccfe6f..30d55c56cdd 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -28,6 +28,8 @@ #include "py/runtime.h" +#include "supervisor/shared/translate.h" + /******************************************************************************/ /* range iterator */ @@ -89,8 +91,8 @@ STATIC void range_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind } } -STATIC mp_obj_t range_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 3, false); +STATIC mp_obj_t range_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 3, false); mp_obj_range_t *o = m_new_obj(mp_obj_range_t); o->base.type = type; @@ -105,7 +107,7 @@ STATIC mp_obj_t range_make_new(const mp_obj_type_t *type, size_t n_args, size_t if (n_args == 3) { o->step = mp_obj_get_int(args[2]); if (o->step == 0) { - mp_raise_ValueError("zero step"); + mp_raise_ValueError(translate("zero step")); } } } diff --git a/py/objreversed.c b/py/objreversed.c index e498b553de8..4937d081896 100644 --- a/py/objreversed.c +++ b/py/objreversed.c @@ -37,8 +37,8 @@ typedef struct _mp_obj_reversed_t { mp_uint_t cur_index; // current index, plus 1; 0=no more, 1=last one (index 0) } mp_obj_reversed_t; -STATIC mp_obj_t reversed_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 1, false); +STATIC mp_obj_t reversed_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); // check if __reversed__ exists, and if so delegate to it mp_obj_t dest[2]; diff --git a/py/objset.c b/py/objset.c index 799ba9df04d..5d1608c7ea9 100644 --- a/py/objset.c +++ b/py/objset.c @@ -31,6 +31,8 @@ #include "py/runtime.h" #include "py/builtin.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_BUILTINS_SET typedef struct _mp_obj_set_t { @@ -101,8 +103,8 @@ STATIC void set_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t #endif } -STATIC mp_obj_t set_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 1, false); +STATIC mp_obj_t set_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 1, false); switch (n_args) { case 0: { @@ -297,7 +299,7 @@ STATIC mp_obj_t set_issubset_internal(mp_obj_t self_in, mp_obj_t other_in, bool if (is_set_or_frozenset(self_in)) { self = MP_OBJ_TO_PTR(self_in); } else { - self = MP_OBJ_TO_PTR(set_make_new(&mp_type_set, 1, 0, &self_in)); + self = MP_OBJ_TO_PTR(set_make_new(&mp_type_set, 1, &self_in, NULL)); cleanup_self = true; } @@ -306,7 +308,7 @@ STATIC mp_obj_t set_issubset_internal(mp_obj_t self_in, mp_obj_t other_in, bool if (is_set_or_frozenset(other_in)) { other = MP_OBJ_TO_PTR(other_in); } else { - other = MP_OBJ_TO_PTR(set_make_new(&mp_type_set, 1, 0, &other_in)); + other = MP_OBJ_TO_PTR(set_make_new(&mp_type_set, 1, &other_in, NULL)); cleanup_other = true; } mp_obj_t out = mp_const_true; @@ -366,7 +368,7 @@ STATIC mp_obj_t set_pop(mp_obj_t self_in) { mp_obj_set_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_t obj = mp_set_remove_first(&self->set); if (obj == MP_OBJ_NULL) { - mp_raise_msg(&mp_type_KeyError, "pop from an empty set"); + mp_raise_msg(&mp_type_KeyError, translate("pop from an empty set")); } return obj; } diff --git a/py/objslice.c b/py/objslice.c index de996d831f1..5a15be55aac 100644 --- a/py/objslice.c +++ b/py/objslice.c @@ -28,6 +28,10 @@ #include #include "py/obj.h" +#include "py/runtime.h" +#include "py/runtime0.h" + +#include "supervisor/shared/translate.h" /******************************************************************************/ /* slice object */ @@ -56,6 +60,58 @@ STATIC void slice_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t } #if MICROPY_PY_BUILTINS_SLICE_ATTRS +STATIC mp_obj_t slice_indices(mp_obj_t self_in, mp_obj_t length_obj) { + mp_obj_slice_t *self = MP_OBJ_TO_PTR(self_in); + if (!MP_OBJ_IS_SMALL_INT(length_obj)) { + mp_raise_TypeError(translate("Length must be an int")); + } + + int length = MP_OBJ_SMALL_INT_VALUE(length_obj); + if (length < 0) { + mp_raise_ValueError(translate("Length must be non-negative")); + } + + mp_obj_t indices[3] = {MP_OBJ_NEW_SMALL_INT(0), length_obj, MP_OBJ_NEW_SMALL_INT(1)}; + mp_obj_t slice[2] = {self->start, self->stop}; + + int step = 1; + if (self->step != mp_const_none) { + indices[2] = self->step; + step = MP_OBJ_SMALL_INT_VALUE(self->step); + if (step < 0) { + indices[0] = MP_OBJ_NEW_SMALL_INT(length - 1); + indices[1] = MP_OBJ_NEW_SMALL_INT(-1); + } + if (step == 0) { + mp_raise_ValueError(translate("slice step cannot be zero")); + } + } + for (int i = 0; i < 2; i++) { + if (slice[i] == mp_const_none) { + continue; + } + int value = MP_OBJ_SMALL_INT_VALUE(slice[i]); + if (value < 0) { + value += length; + } + if (value < 0) { + if (step > 0) { + value = 0; + } else if (step < 0) { + value = -1; + } + } else if (value > length) { + value = length; + } + indices[i] = MP_OBJ_NEW_SMALL_INT(value); + } + + mp_obj_t tuple = mp_obj_new_tuple(3, indices); + + return tuple; +} +MP_DEFINE_CONST_FUN_OBJ_2(slice_indices_obj, slice_indices); + STATIC void slice_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { if (dest[0] != MP_OBJ_NULL) { // not load attribute @@ -68,8 +124,13 @@ STATIC void slice_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { dest[0] = self->stop; } else if (attr == MP_QSTR_step) { dest[0] = self->step; + } else if (attr == MP_QSTR_indices) { + mp_convert_member_lookup(self_in, self->base.type, (mp_obj_t) &slice_indices_obj, dest); } } + +STATIC mp_obj_t slice_make_new(const mp_obj_type_t *type, + size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); #endif const mp_obj_type_t mp_type_slice = { @@ -77,6 +138,7 @@ const mp_obj_type_t mp_type_slice = { .name = MP_QSTR_slice, .print = slice_print, #if MICROPY_PY_BUILTINS_SLICE_ATTRS + .make_new = slice_make_new, .attr = slice_attr, #endif }; @@ -90,6 +152,33 @@ mp_obj_t mp_obj_new_slice(mp_obj_t ostart, mp_obj_t ostop, mp_obj_t ostep) { return MP_OBJ_FROM_PTR(o); } +#if MICROPY_PY_BUILTINS_SLICE_ATTRS +STATIC mp_obj_t slice_make_new(const mp_obj_type_t *type, + size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + if (type != &mp_type_slice) { + mp_raise_NotImplementedError(translate("Cannot subclass slice")); + } + // check number of arguments + mp_arg_check_num(n_args, kw_args, 1, 3, false); + + // 1st argument is the pin + mp_obj_t start = mp_const_none; + mp_obj_t stop = mp_const_none; + mp_obj_t step = mp_const_none; + if (n_args == 1) { + stop = args[0]; + } else { + start = args[0]; + stop = args[1]; + if (n_args == 3) { + step = args[2]; + } + } + + return mp_obj_new_slice(start, stop, step); +} +#endif + void mp_obj_slice_get(mp_obj_t self_in, mp_obj_t *start, mp_obj_t *stop, mp_obj_t *step) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_slice)); mp_obj_slice_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/py/objstr.c b/py/objstr.c index da925234e23..6ef9a15b5e2 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -34,11 +34,19 @@ #include "py/runtime.h" #include "py/stackctrl.h" +#include "supervisor/shared/translate.h" + STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_t *args, mp_obj_t dict); STATIC mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf); STATIC NORETURN void bad_implicit_conversion(mp_obj_t self_in); +const char nibble_to_hex_upper[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F'}; + +const char nibble_to_hex_lower[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f'}; + /******************************************************************************/ /* str */ @@ -130,14 +138,14 @@ STATIC void str_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t } } -mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { #if MICROPY_CPYTHON_COMPAT - if (n_kw != 0) { + if (kw_args != NULL && kw_args->used != 0) { mp_arg_error_unimpl_kw(); } #endif - mp_arg_check_num(n_args, n_kw, 0, 3, false); + mp_arg_check_num(n_args, kw_args, 0, 3, false); switch (n_args) { case 0: @@ -188,15 +196,15 @@ mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_ } } -STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; #if MICROPY_CPYTHON_COMPAT - if (n_kw != 0) { + if (kw_args != NULL && kw_args->used != 0) { mp_arg_error_unimpl_kw(); } #else - (void)n_kw; + (void)kw_args; #endif if (n_args == 0) { @@ -256,7 +264,7 @@ STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, size mp_int_t val = mp_obj_get_int(item); #if MICROPY_FULL_CHECKS if (val < 0 || val > 255) { - mp_raise_ValueError("bytes value out of range"); + mp_raise_ValueError(translate("bytes value out of range")); } #endif vstr_add_byte(&vstr, val); @@ -265,7 +273,7 @@ STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, size return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); wrong_args: - mp_raise_TypeError("wrong number of arguments"); + mp_raise_TypeError(translate("wrong number of arguments")); } // like strstr but with specified length and allows \0 bytes @@ -330,8 +338,9 @@ mp_obj_t mp_obj_str_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i return mp_const_empty_bytes; } } + size_t new_len = mp_seq_multiply_len(lhs_len, n); vstr_t vstr; - vstr_init_len(&vstr, lhs_len * n); + vstr_init_len(&vstr, new_len); mp_seq_multiply(lhs_data, sizeof(*lhs_data), lhs_len, n, vstr.buf); return mp_obj_new_str_from_vstr(lhs_type, &vstr); } @@ -405,6 +414,15 @@ mp_obj_t mp_obj_str_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i #if !MICROPY_PY_BUILTINS_STR_UNICODE // objstrunicode defines own version +size_t str_offset_to_index(const mp_obj_type_t *type, const byte *self_data, size_t self_len, + size_t offset) { + if (offset > self_len) { + mp_raise_ValueError(translate("offset out of bounds")); + } + + return offset; +} + const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, size_t self_len, mp_obj_t index, bool is_slice) { size_t index_val = mp_get_index(type, self_len, index, is_slice); @@ -422,7 +440,7 @@ STATIC mp_obj_t bytes_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { mp_bound_slice_t slice; if (!mp_seq_get_fast_slice_indexes(self_len, index, &slice)) { - mp_raise_NotImplementedError("only slices with step=1 (aka None) are supported"); + mp_raise_NotImplementedError(translate("only slices with step=1 (aka None) are supported")); } return mp_obj_new_str_of_type(type, self_data + slice.start, slice.stop - slice.start); } @@ -453,7 +471,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { if (!MP_OBJ_IS_TYPE(arg, &mp_type_list) && !MP_OBJ_IS_TYPE(arg, &mp_type_tuple)) { // arg is not a list nor a tuple, try to convert it to a list // TODO: Try to optimize? - arg = mp_type_list.make_new(&mp_type_list, 1, 0, &arg); + arg = mp_type_list.make_new(&mp_type_list, 1, &arg, NULL); } mp_obj_get_array(arg, &seq_len, &seq_items); @@ -462,7 +480,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { for (size_t i = 0; i < seq_len; i++) { if (mp_obj_get_type(seq_items[i]) != self_type) { mp_raise_TypeError( - "join expects a list of str/bytes objects consistent with self object"); + translate("join expects a list of str/bytes objects consistent with self object")); } if (i > 0) { required_len += sep_len; @@ -537,7 +555,7 @@ mp_obj_t mp_obj_str_split(size_t n_args, const mp_obj_t *args) { const char *sep_str = mp_obj_str_get_data(sep, &sep_len); if (sep_len == 0) { - mp_raise_ValueError("empty separator"); + mp_raise_ValueError(translate("empty separator")); } for (;;) { @@ -636,13 +654,13 @@ STATIC mp_obj_t str_rsplit(size_t n_args, const mp_obj_t *args) { mp_int_t idx = splits; if (sep == mp_const_none) { - mp_raise_NotImplementedError("rsplit(None,n)"); + mp_raise_NotImplementedError(translate("rsplit(None,n)")); } else { size_t sep_len; const char *sep_str = mp_obj_str_get_data(sep, &sep_len); if (sep_len == 0) { - mp_raise_ValueError("empty separator"); + mp_raise_ValueError(translate("empty separator")); } const byte *beg = s; @@ -708,7 +726,7 @@ STATIC mp_obj_t str_finder(size_t n_args, const mp_obj_t *args, int direction, b out_error: // not found if (is_index) { - mp_raise_ValueError("substring not found"); + mp_raise_ValueError(translate("substring not found")); } else { return MP_OBJ_NEW_SMALL_INT(-1); } @@ -765,7 +783,7 @@ STATIC mp_obj_t str_endswith(size_t n_args, const mp_obj_t *args) { size_t suffix_len; const char *suffix = mp_obj_str_get_data(args[1], &suffix_len); if (n_args > 2) { - mp_raise_NotImplementedError("start/end indices"); + mp_raise_NotImplementedError(translate("start/end indices")); } if (suffix_len > str_len) { @@ -926,7 +944,7 @@ STATIC mp_obj_t arg_as_int(mp_obj_t arg) { #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE STATIC NORETURN void terse_str_format_value_error(void) { - mp_raise_ValueError("bad format string"); + mp_raise_ValueError(translate("bad format string")); } #else // define to nothing to improve coverage @@ -948,7 +966,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { terse_str_format_value_error(); } else { - mp_raise_ValueError("single '}' encountered in format string"); + mp_raise_ValueError(translate("single '}' encountered in format string")); } } if (*str != '{') { @@ -987,14 +1005,13 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { terse_str_format_value_error(); } else if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL) { - mp_raise_ValueError("bad conversion specifier"); + mp_raise_ValueError(translate("bad conversion specifier")); } else { if (str >= top) { mp_raise_ValueError( - "end of format while looking for conversion specifier"); + translate("end of format while looking for conversion specifier")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "unknown conversion specifier %c", *str)); + mp_raise_ValueError_varg(translate("unknown conversion specifier %c"), *str); } } } @@ -1025,14 +1042,14 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { terse_str_format_value_error(); } else { - mp_raise_ValueError("unmatched '{' in format"); + mp_raise_ValueError(translate("unmatched '{' in format")); } } if (*str != '}') { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { terse_str_format_value_error(); } else { - mp_raise_ValueError("expected ':' after format specifier"); + mp_raise_ValueError(translate("expected ':' after format specifier")); } } @@ -1046,12 +1063,12 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar terse_str_format_value_error(); } else { mp_raise_ValueError( - "can't switch from automatic field numbering to manual field specification"); + translate("can't switch from automatic field numbering to manual field specification")); } } field_name = str_to_int(field_name, field_name_top, &index); if ((uint)index >= n_args - 1) { - mp_raise_msg(&mp_type_IndexError, "tuple index out of range"); + mp_raise_IndexError(translate("tuple index out of range")); } arg = args[index + 1]; *arg_i = -1; @@ -1067,7 +1084,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar arg = key_elem->value; } if (field_name < field_name_top) { - mp_raise_NotImplementedError("attributes not supported yet"); + mp_raise_NotImplementedError(translate("attributes not supported yet")); } } else { if (*arg_i < 0) { @@ -1075,11 +1092,11 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar terse_str_format_value_error(); } else { mp_raise_ValueError( - "can't switch from manual field specification to automatic field numbering"); + translate("can't switch from manual field specification to automatic field numbering")); } } if ((uint)*arg_i >= n_args - 1) { - mp_raise_msg(&mp_type_IndexError, "tuple index out of range"); + mp_raise_IndexError(translate("tuple index out of range")); } arg = args[(*arg_i) + 1]; (*arg_i)++; @@ -1167,7 +1184,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { terse_str_format_value_error(); } else { - mp_raise_ValueError("invalid format specifier"); + mp_raise_ValueError(translate("invalid format specifier")); } } vstr_clear(&format_spec_vstr); @@ -1188,7 +1205,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { terse_str_format_value_error(); } else { - mp_raise_ValueError("sign not allowed in string format specifier"); + mp_raise_ValueError(translate("sign not allowed in string format specifier")); } } if (type == 'c') { @@ -1196,7 +1213,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar terse_str_format_value_error(); } else { mp_raise_ValueError( - "sign not allowed with integer format specifier 'c'"); + translate("sign not allowed with integer format specifier 'c'")); } } } @@ -1254,9 +1271,9 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { terse_str_format_value_error(); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "unknown format code '%c' for object of type '%s'", - type, mp_obj_get_type_str(arg))); + mp_raise_ValueError_varg( + translate("unknown format code '%c' for object of type '%s'"), + type, mp_obj_get_type_str(arg)); } } } @@ -1326,9 +1343,9 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { terse_str_format_value_error(); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "unknown format code '%c' for object of type 'float'", - type, mp_obj_get_type_str(arg))); + mp_raise_ValueError_varg( + translate("unknown format code '%c' for object of type 'float'"), + type, mp_obj_get_type_str(arg)); } } } else { @@ -1339,7 +1356,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar terse_str_format_value_error(); } else { mp_raise_ValueError( - "'=' alignment not allowed in string format specifier"); + translate("'=' alignment not allowed in string format specifier")); } } @@ -1362,9 +1379,9 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { terse_str_format_value_error(); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "unknown format code '%c' for object of type 'str'", - type, mp_obj_get_type_str(arg))); + mp_raise_ValueError_varg( + translate("unknown format code '%c' for object of type 'str'"), + type, mp_obj_get_type_str(arg)); } } } @@ -1411,7 +1428,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ // Dictionary value lookup if (*str == '(') { if (dict == MP_OBJ_NULL) { - mp_raise_TypeError("format requires a dict"); + mp_raise_TypeError(translate("format requires a dict")); } arg_i = 1; // we used up the single dict argument const byte *key = ++str; @@ -1420,7 +1437,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { terse_str_format_value_error(); } else { - mp_raise_ValueError("incomplete format key"); + mp_raise_ValueError(translate("incomplete format key")); } } ++str; @@ -1478,7 +1495,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { terse_str_format_value_error(); } else { - mp_raise_ValueError("incomplete format"); + mp_raise_ValueError(translate("incomplete format")); } } @@ -1486,7 +1503,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ if (arg == MP_OBJ_NULL) { if (arg_i >= n_args) { not_enough_args: - mp_raise_TypeError("not enough arguments for format string"); + mp_raise_TypeError(translate("not enough arguments for format string")); } arg = args[arg_i++]; } @@ -1496,14 +1513,14 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ size_t slen; const char *s = mp_obj_str_get_data(arg, &slen); if (slen != 1) { - mp_raise_TypeError("%%c requires int or char"); + mp_raise_TypeError(translate("%%c requires int or char")); } mp_print_strn(&print, s, 1, flags, ' ', width); } else if (arg_looks_integer(arg)) { char ch = mp_obj_get_int(arg); mp_print_strn(&print, &ch, 1, flags, ' ', width); } else { - mp_raise_TypeError("integer required"); + mp_raise_TypeError(translate("integer required")); } break; @@ -1565,15 +1582,15 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { terse_str_format_value_error(); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "unsupported format character '%c' (0x%x) at index %d", - *str, *str, str - start_str)); + mp_raise_ValueError_varg( + translate("unsupported format character '%c' (0x%x) at index %d"), + *str, *str, str - start_str); } } } if (arg_i != n_args) { - mp_raise_TypeError("not all arguments converted during string formatting"); + mp_raise_TypeError(translate("not all arguments converted during string formatting")); } return mp_obj_new_str_from_vstr(is_bytes ? &mp_type_bytes : &mp_type_str, &vstr); @@ -1740,7 +1757,7 @@ STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, int direction) { GET_STR_DATA_LEN(arg, sep, sep_len); if (sep_len == 0) { - mp_raise_ValueError("empty separator"); + mp_raise_ValueError(translate("empty separator")); } mp_obj_t result[3]; @@ -1874,7 +1891,7 @@ STATIC mp_obj_t bytes_decode(size_t n_args, const mp_obj_t *args) { args = new_args; n_args++; } - return mp_obj_str_make_new(&mp_type_str, n_args, 0, args); + return mp_obj_str_make_new(&mp_type_str, n_args, args, NULL); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bytes_decode_obj, 1, 3, bytes_decode); @@ -1887,7 +1904,7 @@ STATIC mp_obj_t str_encode(size_t n_args, const mp_obj_t *args) { args = new_args; n_args++; } - return bytes_make_new(NULL, n_args, 0, args); + return bytes_make_new(NULL, n_args, args, NULL); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_encode_obj, 1, 3, str_encode); #endif @@ -2077,6 +2094,14 @@ mp_obj_t mp_obj_new_bytes(const byte* data, size_t len) { return mp_obj_new_str_copy(&mp_type_bytes, data, len); } +mp_obj_t mp_obj_new_bytes_of_zeros(size_t len) { + vstr_t vstr; + vstr_init_len(&vstr, len); + memset(vstr.buf, 0, len); + return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); +} + + bool mp_obj_str_equal(mp_obj_t s1, mp_obj_t s2) { if (MP_OBJ_IS_QSTR(s1) && MP_OBJ_IS_QSTR(s2)) { return s1 == s2; @@ -2098,11 +2123,11 @@ bool mp_obj_str_equal(mp_obj_t s1, mp_obj_t s2) { STATIC NORETURN void bad_implicit_conversion(mp_obj_t self_in) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("can't convert to str implicitly"); + mp_raise_TypeError(translate("can't convert to str implicitly")); } else { const qstr src_name = mp_obj_get_type(self_in)->name; nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "can't convert '%q' object to %q implicitly", + translate("can't convert '%q' object to %q implicitly"), src_name, src_name == MP_QSTR_str ? MP_QSTR_bytes : MP_QSTR_str)); } } diff --git a/py/objstr.h b/py/objstr.h index 4e55cad0913..61a11d0bd6f 100644 --- a/py/objstr.h +++ b/py/objstr.h @@ -61,7 +61,7 @@ const byte *mp_obj_str_get_data_no_check(mp_obj_t self_in, size_t *len); else { str_len = ((mp_obj_str_t*)MP_OBJ_TO_PTR(str_obj_in))->len; str_data = ((mp_obj_str_t*)MP_OBJ_TO_PTR(str_obj_in))->data; } #endif -mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args); +mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); void mp_str_print_json(const mp_print_t *print, const byte *str_data, size_t str_len); mp_obj_t mp_obj_str_format(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs); mp_obj_t mp_obj_str_split(size_t n_args, const mp_obj_t *args); @@ -71,10 +71,15 @@ mp_obj_t mp_obj_new_str_of_type(const mp_obj_type_t *type, const byte* data, siz mp_obj_t mp_obj_str_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in); mp_int_t mp_obj_str_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags); +size_t str_offset_to_index(const mp_obj_type_t *type, const byte *self_data, size_t self_len, + size_t offset); const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, size_t self_len, mp_obj_t index, bool is_slice); const byte *find_subbytes(const byte *haystack, size_t hlen, const byte *needle, size_t nlen, int direction); +const char nibble_to_hex_upper[16]; +const char nibble_to_hex_lower[16]; + MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_encode_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_find_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_rfind_obj); diff --git a/py/objstringio.c b/py/objstringio.c index b405ee21e35..d2ca6decdba 100644 --- a/py/objstringio.c +++ b/py/objstringio.c @@ -33,12 +33,14 @@ #include "py/runtime.h" #include "py/stream.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_IO #if MICROPY_CPYTHON_COMPAT STATIC void check_stringio_is_open(const mp_obj_stringio_t *o) { if (o->vstr == NULL) { - mp_raise_ValueError("I/O operation on closed file"); + mp_raise_ValueError(translate("I/O operation on closed file")); } } #else @@ -184,8 +186,8 @@ STATIC mp_obj_stringio_t *stringio_new(const mp_obj_type_t *type) { return o; } -STATIC mp_obj_t stringio_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - (void)n_kw; // TODO check n_kw==0 +STATIC mp_obj_t stringio_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + (void)kw_args; // TODO check kw_args->used == 0 mp_uint_t sz = 16; bool initdata = false; diff --git a/py/objstrunicode.c b/py/objstrunicode.c index badb569d790..30000a51e77 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -32,6 +32,8 @@ #include "py/objlist.h" #include "py/runtime.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_BUILTINS_STR_UNICODE STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf); @@ -110,6 +112,26 @@ STATIC mp_obj_t uni_unary_op(mp_unary_op_t op, mp_obj_t self_in) { } } +size_t str_offset_to_index(const mp_obj_type_t *type, const byte *self_data, size_t self_len, + size_t offset) { + if (offset > self_len) { + mp_raise_ValueError(translate("offset out of bounds")); + } + + if (type == &mp_type_bytes) { + return offset; + } + + size_t index_val = 0; + const byte *s = self_data; + for (size_t i = 0; i < offset; i++, s++) { + if (!UTF8_IS_CONT(*s)) { + ++index_val; + } + } + return index_val; +} + // Convert an index into a pointer to its lead byte. Out of bounds indexing will raise IndexError or // be capped to the first/last character of the string, depending on is_slice. const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, size_t self_len, @@ -129,7 +151,7 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s if (MP_OBJ_IS_SMALL_INT(index)) { i = MP_OBJ_SMALL_INT_VALUE(index); } else if (!mp_obj_get_int_maybe(index, &i)) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "string indices must be integers, not %s", mp_obj_get_type_str(index))); + mp_raise_TypeError_varg(translate("string indices must be integers, not %s"), mp_obj_get_type_str(index)); } const byte *s, *top = self_data + self_len; if (i < 0) @@ -140,7 +162,7 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s if (is_slice) { return self_data; } - mp_raise_msg(&mp_type_IndexError, "string index out of range"); + mp_raise_IndexError(translate("string index out of range")); } if (!UTF8_IS_CONT(*s)) { ++i; @@ -159,7 +181,7 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s if (is_slice) { return top; } - mp_raise_msg(&mp_type_IndexError, "string index out of range"); + mp_raise_IndexError(translate("string index out of range")); } // Then check completion if (i-- == 0) { @@ -186,7 +208,7 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { mp_obj_t ostart, ostop, ostep; mp_obj_slice_get(index, &ostart, &ostop, &ostep); if (ostep != mp_const_none && ostep != MP_OBJ_NEW_SMALL_INT(1)) { - mp_raise_NotImplementedError("only slices with step=1 (aka None) are supported"); + mp_raise_NotImplementedError(translate("only slices with step=1 (aka None) are supported")); } const byte *pstart, *pstop; diff --git a/py/objtuple.c b/py/objtuple.c index 34b7664ebb5..ed13cdcef2c 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -30,6 +30,8 @@ #include "py/objtuple.h" #include "py/runtime.h" +#include "supervisor/shared/translate.h" + /******************************************************************************/ /* tuple */ @@ -57,10 +59,10 @@ void mp_obj_tuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t } } -STATIC mp_obj_t mp_obj_tuple_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t mp_obj_tuple_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 0, 1, false); + mp_arg_check_num(n_args, kw_args, 0, 1, false); switch (n_args) { case 0: @@ -158,7 +160,8 @@ mp_obj_t mp_obj_tuple_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { if (n <= 0) { return mp_const_empty_tuple; } - mp_obj_tuple_t *s = MP_OBJ_TO_PTR(mp_obj_new_tuple(o->len * n, NULL)); + size_t new_len = mp_seq_multiply_len(o->len, n); + mp_obj_tuple_t *s = MP_OBJ_TO_PTR(mp_obj_new_tuple(new_len, NULL)); mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items); return MP_OBJ_FROM_PTR(s); } @@ -182,7 +185,7 @@ mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { mp_bound_slice_t slice; if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) { - mp_raise_NotImplementedError("only slices with step=1 (aka None) are supported"); + mp_raise_NotImplementedError(translate("only slices with step=1 (aka None) are supported")); } mp_obj_tuple_t *res = MP_OBJ_TO_PTR(mp_obj_new_tuple(slice.stop - slice.start, NULL)); mp_seq_copy(res->items, self->items + slice.start, res->len, mp_obj_t); @@ -248,7 +251,8 @@ mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items) { } void mp_obj_tuple_get(mp_obj_t self_in, size_t *len, mp_obj_t **items) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_tuple)); + // type check is done on getiter method to allow tuple, namedtuple, attrtuple + mp_check_self(mp_obj_get_type(self_in)->getiter == mp_obj_tuple_getiter); mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in); *len = self->len; *items = &self->items[0]; diff --git a/py/objtuple.h b/py/objtuple.h index 74cde88d3d3..7f20ab7b6f8 100644 --- a/py/objtuple.h +++ b/py/objtuple.h @@ -40,6 +40,8 @@ typedef struct _mp_rom_obj_tuple_t { mp_rom_obj_t items[]; } mp_rom_obj_tuple_t; +extern const mp_obj_type_t mp_type_tuple; + void mp_obj_tuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind); mp_obj_t mp_obj_tuple_unary_op(mp_unary_op_t op, mp_obj_t self_in); mp_obj_t mp_obj_tuple_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs); diff --git a/py/objtype.c b/py/objtype.c index ef70dfce0f1..5133d849fc6 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -30,9 +30,12 @@ #include #include +#include "py/gc_long_lived.h" #include "py/objtype.h" #include "py/runtime.h" +#include "supervisor/shared/translate.h" + #if MICROPY_DEBUG_VERBOSE // print debugging info #define DEBUG_PRINT (1) #define DEBUG_printf DEBUG_printf @@ -47,7 +50,7 @@ #define TYPE_FLAG_IS_SUBCLASSED (0x0001) #define TYPE_FLAG_HAS_SPECIAL_ACCESSORS (0x0002) -STATIC mp_obj_t static_class_method_make_new(const mp_obj_type_t *self_in, size_t n_args, size_t n_kw, const mp_obj_t *args); +STATIC mp_obj_t static_class_method_make_new(const mp_obj_type_t *self_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); /******************************************************************************/ // instance object @@ -87,14 +90,14 @@ STATIC int instance_count_native_bases(const mp_obj_type_t *type, const mp_obj_t // This wrapper function is allows a subclass of a native type to call the // __init__() method (corresponding to type->make_new) of the native type. -STATIC mp_obj_t native_base_init_wrapper(size_t n_args, const mp_obj_t *args) { - mp_obj_instance_t *self = MP_OBJ_TO_PTR(args[0]); +STATIC mp_obj_t native_base_init_wrapper(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_obj_instance_t *self = MP_OBJ_TO_PTR(pos_args[0]); const mp_obj_type_t *native_base = NULL; instance_count_native_bases(self->base.type, &native_base); - self->subobj[0] = native_base->make_new(native_base, n_args - 1, 0, args + 1); + self->subobj[0] = native_base->make_new(native_base, n_args - 1, pos_args + 1, kw_args); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(native_base_init_wrapper_obj, 1, MP_OBJ_FUN_ARGS_MAX, native_base_init_wrapper); +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(native_base_init_wrapper_obj, 1, native_base_init_wrapper); #if !MICROPY_CPYTHON_COMPAT STATIC @@ -114,6 +117,16 @@ mp_obj_instance_t *mp_obj_new_instance(const mp_obj_type_t *class, const mp_obj_ return o; } +// When instances are first created they have the base_init wrapper as their native parent's +// instance because make_new combines __new__ and __init__. This object is invalid for the native +// code so it must call this method to ensure that the given object has been __init__'d and is +// valid. +void mp_obj_assert_native_inited(mp_obj_t native_object) { + if (native_object == MP_OBJ_FROM_PTR(&native_base_init_wrapper_obj)) { + mp_raise_NotImplementedError(translate("Call super().__init__() before accessing native object.")); + } +} + // TODO // This implements depth-first left-to-right MRO, which is not compliant with Python3 MRO // http://python-history.blogspot.com/2010/06/method-resolution-order.html @@ -146,7 +159,10 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_ // this should not be applied to class types, as will result in extra // lookup either. if (lookup->meth_offset != 0 && mp_obj_is_native_type(type)) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" if (*(void**)((char*)type + lookup->meth_offset) != NULL) { +#pragma GCC diagnostic pop DEBUG_printf("mp_obj_class_lookup: Matched special meth slot (off=%d) for %s\n", lookup->meth_offset, qstr_str(lookup->attr)); lookup->dest[0] = MP_OBJ_SENTINEL; @@ -165,6 +181,9 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_ // do a lookup, not a (base) type in which we found the class method. const mp_obj_type_t *org_type = (const mp_obj_type_t*)lookup->obj; mp_convert_member_lookup(MP_OBJ_NULL, org_type, elem->value, lookup->dest); + } else if (MP_OBJ_IS_TYPE(elem->value, &mp_type_property)) { + lookup->dest[0] = elem->value; + return; } else { mp_obj_instance_t *obj = lookup->obj; mp_obj_t obj_obj; @@ -275,7 +294,7 @@ STATIC void instance_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k mp_printf(print, "<%s object at %p>", mp_obj_get_type_str(self_in), self); } -mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size_t n_kw, const mp_obj_t *args) { +mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { assert(mp_obj_is_instance_type(self)); // look for __new__ function @@ -291,6 +310,10 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size const mp_obj_type_t *native_base = NULL; mp_obj_instance_t *o; + size_t n_kw = 0; + if (kw_args != 0) { + n_kw = kw_args->used; + } if (init_fn[0] == MP_OBJ_NULL || init_fn[0] == MP_OBJ_SENTINEL) { // Either there is no __new__() method defined or there is a native // constructor. In both cases create a blank instance. @@ -309,9 +332,12 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size mp_obj_t args2[1] = {MP_OBJ_FROM_PTR(self)}; new_ret = mp_call_function_n_kw(init_fn[0], 1, 0, args2); } else { + // TODO(tannewt): Could this be on the stack? It's deleted below. mp_obj_t *args2 = m_new(mp_obj_t, 1 + n_args + 2 * n_kw); args2[0] = MP_OBJ_FROM_PTR(self); - memcpy(args2 + 1, args, (n_args + 2 * n_kw) * sizeof(mp_obj_t)); + memcpy(args2 + 1, args, n_args * sizeof(mp_obj_t)); + // copy in kwargs + memcpy(args2 + 1 + n_args, kw_args->table, 2 * n_kw * sizeof(mp_obj_t)); new_ret = mp_call_function_n_kw(init_fn[0], n_args + 1, n_kw, args2); m_del(mp_obj_t, args2, 1 + n_args + 2 * n_kw); } @@ -337,22 +363,25 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size mp_obj_class_lookup(&lookup, self); if (init_fn[0] != MP_OBJ_NULL) { mp_obj_t init_ret; - if (n_args == 0 && n_kw == 0) { + if (n_args == 0 && kw_args == NULL) { init_ret = mp_call_method_n_kw(0, 0, init_fn); } else { + // TODO(tannewt): Could this be on the stack? It's deleted below. mp_obj_t *args2 = m_new(mp_obj_t, 2 + n_args + 2 * n_kw); args2[0] = init_fn[0]; args2[1] = init_fn[1]; - memcpy(args2 + 2, args, (n_args + 2 * n_kw) * sizeof(mp_obj_t)); + // copy in kwargs + memcpy(args2 + 2, args, n_args * sizeof(mp_obj_t)); + memcpy(args2 + 2 + n_args, kw_args->table, 2 * n_kw * sizeof(mp_obj_t)); init_ret = mp_call_method_n_kw(n_args, n_kw, args2); m_del(mp_obj_t, args2, 2 + n_args + 2 * n_kw); } if (init_ret != mp_const_none) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("__init__() should return None"); + mp_raise_TypeError(translate("__init__() should return None")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "__init__() should return None, not '%s'", mp_obj_get_type_str(init_ret))); + mp_raise_TypeError_varg(translate("__init__() should return None, not '%s'"), + mp_obj_get_type_str(init_ret)); } } @@ -361,7 +390,7 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size // If the type had a native base that was not explicitly initialised // (constructed) by the Python __init__() method then construct it now. if (native_base != NULL && o->subobj[0] == MP_OBJ_FROM_PTR(&native_base_init_wrapper_obj)) { - o->subobj[0] = native_base->make_new(native_base, n_args, n_kw, args); + o->subobj[0] = native_base->make_new(native_base, n_args, args, kw_args); } return MP_OBJ_FROM_PTR(o); @@ -597,6 +626,7 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des mp_obj_class_lookup(&lookup, self->base.type); mp_obj_t member = dest[0]; if (member != MP_OBJ_NULL) { + // changes here may may require changes to super_attr, below if (!(self->base.type->flags & TYPE_FLAG_HAS_SPECIAL_ACCESSORS)) { // Class doesn't have any special accessors to check so return straightaway return; @@ -613,7 +643,7 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des // the code. const mp_obj_t *proxy = mp_obj_property_get(member); if (proxy[0] == mp_const_none) { - mp_raise_msg(&mp_type_AttributeError, "unreadable attribute"); + mp_raise_AttributeError(translate("unreadable attribute")); } else { dest[0] = mp_call_function_n_kw(proxy[0], 1, 0, &self_in); } @@ -858,10 +888,10 @@ mp_obj_t mp_obj_instance_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons mp_obj_t call = mp_obj_instance_get_call(self_in, member); if (call == MP_OBJ_NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("object not callable"); + mp_raise_TypeError(translate("object not callable")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "'%s' object is not callable", mp_obj_get_type_str(self_in))); + mp_raise_TypeError_varg(translate("'%s' object is not callable"), + mp_obj_get_type_str(self_in)); } } mp_obj_instance_t *self = MP_OBJ_TO_PTR(self_in); @@ -944,6 +974,21 @@ STATIC bool check_for_special_accessors(mp_obj_t key, mp_obj_t value) { #endif return false; } + +STATIC bool map_has_special_accessors(const mp_map_t *map) { + if (map == NULL) { + return false; + } + for (size_t i = 0; i < map->alloc; i++) { + if (MP_MAP_SLOT_IS_FILLED(map, i)) { + const mp_map_elem_t *elem = &map->table[i]; + if (check_for_special_accessors(elem->key, elem->value)) { + return true; + } + } + } + return false; +} #endif STATIC void type_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { @@ -952,10 +997,10 @@ STATIC void type_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_ mp_printf(print, "", self->name); } -STATIC mp_obj_t type_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t type_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; - mp_arg_check_num(n_args, n_kw, 1, 3, false); + mp_arg_check_num(n_args, kw_args, 1, 3, false); switch (n_args) { case 1: @@ -968,7 +1013,7 @@ STATIC mp_obj_t type_make_new(const mp_obj_type_t *type_in, size_t n_args, size_ return mp_obj_new_type(mp_obj_str_get_qstr(args[0]), args[1], args[2]); default: - mp_raise_TypeError("type takes 1 or 3 arguments"); + mp_raise_TypeError(translate("type takes 1 or 3 arguments")); } } @@ -979,15 +1024,16 @@ STATIC mp_obj_t type_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp if (self->make_new == NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("cannot create instance"); + mp_raise_TypeError(translate("cannot create instance")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "cannot create '%q' instances", self->name)); + mp_raise_TypeError_varg(translate("cannot create '%q' instances"), self->name); } } - // make new instance - mp_obj_t o = self->make_new(self, n_args, n_kw, args); + // create a map directly from the given args array and make a new instance + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + mp_obj_t o = self->make_new(self, n_args, args, &kw_args); // return new instance return o; @@ -1038,7 +1084,7 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { if (check_for_special_accessors(MP_OBJ_NEW_QSTR(attr), dest[1])) { if (self->flags & TYPE_FLAG_IS_SUBCLASSED) { // This class is already subclassed so can't have special accessors added - mp_raise_msg(&mp_type_AttributeError, "can't add special method to already-subclassed class"); + mp_raise_msg(&mp_type_AttributeError, translate("can't add special method to already-subclassed class")); } self->flags |= TYPE_FLAG_HAS_SPECIAL_ACCESSORS; } @@ -1082,16 +1128,16 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) mp_obj_tuple_get(bases_tuple, &bases_len, &bases_items); for (size_t i = 0; i < bases_len; i++) { if (!MP_OBJ_IS_TYPE(bases_items[i], &mp_type_type)) { - mp_raise_TypeError(NULL); + mp_raise_TypeError(translate("type is not an acceptable base type")); } mp_obj_type_t *t = MP_OBJ_TO_PTR(bases_items[i]); // TODO: Verify with CPy, tested on function type if (t->make_new == NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("type is not an acceptable base type"); + mp_raise_TypeError(translate("type is not an acceptable base type")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "type '%q' is not an acceptable base type", t->name)); + mp_raise_TypeError_varg( + translate("type '%q' is not an acceptable base type"), t->name); } } #if ENABLE_SPECIAL_ACCESSORS @@ -1102,7 +1148,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) #endif } - mp_obj_type_t *o = m_new0(mp_obj_type_t, 1); + mp_obj_type_t *o = m_new0_ll(mp_obj_type_t, 1); o->base.type = &mp_type_type; o->flags = base_flags; o->name = name; @@ -1128,43 +1174,40 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) #if MICROPY_MULTIPLE_INHERITANCE o->parent = MP_OBJ_TO_PTR(bases_tuple); #else - mp_raise_NotImplementedError("multiple inheritance not supported"); + mp_raise_NotImplementedError(translate("multiple inheritance not supported")); #endif } else { o->parent = MP_OBJ_TO_PTR(bases_items[0]); } } - o->locals_dict = MP_OBJ_TO_PTR(locals_dict); + o->locals_dict = make_dict_long_lived(locals_dict, 10); - #if ENABLE_SPECIAL_ACCESSORS - // Check if the class has any special accessor methods - if (!(o->flags & TYPE_FLAG_HAS_SPECIAL_ACCESSORS)) { - for (size_t i = 0; i < o->locals_dict->map.alloc; i++) { - if (MP_MAP_SLOT_IS_FILLED(&o->locals_dict->map, i)) { - const mp_map_elem_t *elem = &o->locals_dict->map.table[i]; - if (check_for_special_accessors(elem->key, elem->value)) { - o->flags |= TYPE_FLAG_HAS_SPECIAL_ACCESSORS; - break; - } - } - } - } - #endif const mp_obj_type_t *native_base; size_t num_native_bases = instance_count_native_bases(o, &native_base); if (num_native_bases > 1) { - mp_raise_TypeError("multiple bases have instance lay-out conflict"); + mp_raise_TypeError(translate("multiple bases have instance lay-out conflict")); } mp_map_t *locals_map = &o->locals_dict->map; + #if ENABLE_SPECIAL_ACCESSORS + // Check if the class has any special accessor methods + if (!(o->flags & TYPE_FLAG_HAS_SPECIAL_ACCESSORS) && + (map_has_special_accessors(locals_map) || + (num_native_bases == 1 && + native_base->locals_dict != NULL && + map_has_special_accessors(&native_base->locals_dict->map)))) { + o->flags |= TYPE_FLAG_HAS_SPECIAL_ACCESSORS; + } + #endif + mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(MP_QSTR___new__), MP_MAP_LOOKUP); if (elem != NULL) { // __new__ slot exists; check if it is a function if (MP_OBJ_IS_FUN(elem->value)) { // __new__ is a function, wrap it in a staticmethod decorator - elem->value = static_class_method_make_new(&mp_type_staticmethod, 1, 0, &elem->value); + elem->value = static_class_method_make_new(&mp_type_staticmethod, 1, &elem->value, NULL); } } @@ -1190,13 +1233,13 @@ STATIC void super_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind mp_print_str(print, ">"); } -STATIC mp_obj_t super_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t super_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { (void)type_in; // 0 arguments are turned into 2 in the compiler // 1 argument is not yet implemented - mp_arg_check_num(n_args, n_kw, 2, 2, false); - if (!MP_OBJ_IS_TYPE(args[0], &mp_type_type)) { - mp_raise_TypeError(NULL); + mp_arg_check_num(n_args, kw_args, 2, 2, false); + if(!MP_OBJ_IS_TYPE(args[0], &mp_type_type)) { + mp_raise_TypeError(translate("first argument to super() must be type")); } mp_obj_super_t *o = m_new_obj(mp_obj_super_t); *o = (mp_obj_super_t){{type_in}, args[0], args[1]}; @@ -1258,6 +1301,29 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { // Looked up native __init__ so defer to it dest[0] = MP_OBJ_FROM_PTR(&native_base_init_wrapper_obj); dest[1] = self->obj; + } else { + mp_obj_t member = dest[0]; + // changes to mp_obj_instance_load_attr may require changes + // here... + #if MICROPY_PY_BUILTINS_PROPERTY + if (MP_OBJ_IS_TYPE(member, &mp_type_property)) { + const mp_obj_t *proxy = mp_obj_property_get(member); + if (proxy[0] == mp_const_none) { + mp_raise_AttributeError(translate("unreadable attribute")); + } else { + dest[0] = mp_call_function_n_kw(proxy[0], 1, 0, &self_in); + } + } + #endif + #if MICROPY_PY_DESCRIPTORS + mp_obj_t attr_get_method[4]; + mp_load_method_maybe(member, MP_QSTR___get__, attr_get_method); + if (attr_get_method[0] != MP_OBJ_NULL) { + attr_get_method[2] = self_in; + attr_get_method[3] = MP_OBJ_FROM_PTR(mp_obj_get_type(self_in)); + dest[0] = mp_call_method_n_kw(2, 0, attr_get_method); + } + #endif } return; } @@ -1338,7 +1404,7 @@ STATIC mp_obj_t mp_obj_is_subclass(mp_obj_t object, mp_obj_t classinfo) { } else if (MP_OBJ_IS_TYPE(classinfo, &mp_type_tuple)) { mp_obj_tuple_get(classinfo, &len, &items); } else { - mp_raise_TypeError("issubclass() arg 2 must be a class or a tuple of classes"); + mp_raise_TypeError(translate("issubclass() arg 2 must be a class or a tuple of classes")); } for (size_t i = 0; i < len; i++) { @@ -1352,7 +1418,7 @@ STATIC mp_obj_t mp_obj_is_subclass(mp_obj_t object, mp_obj_t classinfo) { STATIC mp_obj_t mp_builtin_issubclass(mp_obj_t object, mp_obj_t classinfo) { if (!MP_OBJ_IS_TYPE(object, &mp_type_type)) { - mp_raise_TypeError("issubclass() arg 1 must be a class"); + mp_raise_TypeError(translate("issubclass() arg 1 must be a class")); } return mp_obj_is_subclass(object, classinfo); } @@ -1365,11 +1431,14 @@ STATIC mp_obj_t mp_builtin_isinstance(mp_obj_t object, mp_obj_t classinfo) { MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_isinstance_obj, mp_builtin_isinstance); -mp_obj_t mp_instance_cast_to_native_base(mp_const_obj_t self_in, mp_const_obj_t native_type) { +mp_obj_t mp_instance_cast_to_native_base(mp_obj_t self_in, mp_const_obj_t native_type) { mp_obj_type_t *self_type = mp_obj_get_type(self_in); if (!mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(self_type), native_type)) { return MP_OBJ_NULL; } + if (MP_OBJ_FROM_PTR(self_type) == native_type) { + return self_in; + } mp_obj_instance_t *self = (mp_obj_instance_t*)MP_OBJ_TO_PTR(self_in); return self->subobj[0]; } @@ -1377,10 +1446,10 @@ mp_obj_t mp_instance_cast_to_native_base(mp_const_obj_t self_in, mp_const_obj_t /******************************************************************************/ // staticmethod and classmethod types (probably should go in a different file) -STATIC mp_obj_t static_class_method_make_new(const mp_obj_type_t *self, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t static_class_method_make_new(const mp_obj_type_t *self, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { assert(self == &mp_type_staticmethod || self == &mp_type_classmethod); - mp_arg_check_num(n_args, n_kw, 1, 1, false); + mp_arg_check_num(n_args, kw_args, 1, 1, false); mp_obj_static_class_method_t *o = m_new_obj(mp_obj_static_class_method_t); *o = (mp_obj_static_class_method_t){{self}, args[0]}; diff --git a/py/objtype.h b/py/objtype.h index 3fc8c6e1b0f..a32c8749673 100644 --- a/py/objtype.h +++ b/py/objtype.h @@ -37,6 +37,8 @@ typedef struct _mp_obj_instance_t { // TODO maybe cache __getattr__ and __setattr__ for efficient lookup of them } mp_obj_instance_t; +void mp_obj_assert_native_inited(mp_obj_t native_object); + #if MICROPY_CPYTHON_COMPAT // this is needed for object.__new__ mp_obj_instance_t *mp_obj_new_instance(const mp_obj_type_t *cls, const mp_obj_type_t **native_base); @@ -49,6 +51,6 @@ mp_obj_t mp_obj_instance_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons #define mp_obj_is_instance_type(type) ((type)->make_new == mp_obj_instance_make_new) #define mp_obj_is_native_type(type) ((type)->make_new != mp_obj_instance_make_new) // this needs to be exposed for the above macros to work correctly -mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self_in, size_t n_args, size_t n_kw, const mp_obj_t *args); +mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); #endif // MICROPY_INCLUDED_PY_OBJTYPE_H diff --git a/py/objzip.c b/py/objzip.c index 0183925e3c5..ce9afd55dec 100644 --- a/py/objzip.c +++ b/py/objzip.c @@ -36,8 +36,8 @@ typedef struct _mp_obj_zip_t { mp_obj_t iters[]; } mp_obj_zip_t; -STATIC mp_obj_t zip_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, false); +STATIC mp_obj_t zip_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, MP_OBJ_FUN_ARGS_MAX, false); mp_obj_zip_t *o = m_new_obj_var(mp_obj_zip_t, mp_obj_t, n_args); o->base.type = type; diff --git a/py/parse.c b/py/parse.c index 8c1286492fc..911b891e0f6 100644 --- a/py/parse.c +++ b/py/parse.c @@ -39,6 +39,8 @@ #include "py/objstr.h" #include "py/builtin.h" +#include "supervisor/shared/translate.h" + #if MICROPY_ENABLE_COMPILER #define RULE_ACT_ARG_MASK (0x0f) @@ -190,7 +192,7 @@ static const size_t FIRST_RULE_WITH_OFFSET_ABOVE_255 = #undef DEF_RULE_NC 0; -#if USE_RULE_NAME +#if defined(USE_RULE_NAME) && USE_RULE_NAME // Define an array of rule names corresponding to each rule STATIC const char *const rule_name_table[] = { #define DEF_RULE(rule, comp, kind, ...) #rule, @@ -249,6 +251,9 @@ STATIC const uint16_t *get_rule_arg(uint8_t r_id) { return &rule_arg_combined_table[off]; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" + STATIC void *parser_alloc(parser_t *parser, size_t num_bytes) { // use a custom memory allocator to store parse nodes sequentially in large chunks @@ -289,6 +294,7 @@ STATIC void *parser_alloc(parser_t *parser, size_t num_bytes) { chunk->union_.used += num_bytes; return ret; } +#pragma GCC diagnostic pop STATIC void push_rule(parser_t *parser, size_t src_line, uint8_t rule_id, size_t arg_i) { if (parser->rule_stack_top >= parser->rule_stack_alloc) { @@ -399,7 +405,7 @@ void mp_parse_node_print(mp_parse_node_t pn, size_t indent) { #endif } else { size_t n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); - #if USE_RULE_NAME + #if defined(USE_RULE_NAME) && USE_RULE_NAME printf("%s(%u) (n=%u)\n", rule_name_table[MP_PARSE_NODE_STRUCT_KIND(pns)], (uint)MP_PARSE_NODE_STRUCT_KIND(pns), (uint)n); #else printf("rule(%u) (n=%u)\n", (uint)MP_PARSE_NODE_STRUCT_KIND(pns), (uint)n); @@ -717,7 +723,7 @@ STATIC bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) { mp_obj_t value; if (!mp_parse_node_get_int_maybe(pn_value, &value)) { mp_obj_t exc = mp_obj_new_exception_msg(&mp_type_SyntaxError, - "constant must be an integer"); + translate("constant must be an integer")); mp_obj_exception_add_traceback(exc, parser->lexer->source_name, ((mp_parse_node_struct_t*)pn1)->source_line, MP_QSTR_NULL); nlr_raise(exc); @@ -837,11 +843,30 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) { parser.rule_stack_alloc = MICROPY_ALLOC_PARSE_RULE_INIT; parser.rule_stack_top = 0; - parser.rule_stack = m_new(rule_stack_t, parser.rule_stack_alloc); + parser.rule_stack = NULL; + while (parser.rule_stack_alloc > 1) { + parser.rule_stack = m_new_maybe(rule_stack_t, parser.rule_stack_alloc); + if (parser.rule_stack != NULL) { + break; + } else { + parser.rule_stack_alloc /= 2; + } + } parser.result_stack_alloc = MICROPY_ALLOC_PARSE_RESULT_INIT; parser.result_stack_top = 0; - parser.result_stack = m_new(mp_parse_node_t, parser.result_stack_alloc); + parser.result_stack = NULL; + while (parser.result_stack_alloc > 1) { + parser.result_stack = m_new_maybe(mp_parse_node_t, parser.result_stack_alloc); + if (parser.result_stack != NULL) { + break; + } else { + parser.result_stack_alloc /= 2; + } + } + if (parser.rule_stack == NULL || parser.result_stack == NULL) { + mp_raise_msg(&mp_type_MemoryError, translate("Unable to init parser")); + } parser.lexer = lex; @@ -1142,13 +1167,13 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) { mp_obj_t exc; if (lex->tok_kind == MP_TOKEN_INDENT) { exc = mp_obj_new_exception_msg(&mp_type_IndentationError, - "unexpected indent"); + translate("unexpected indent")); } else if (lex->tok_kind == MP_TOKEN_DEDENT_MISMATCH) { exc = mp_obj_new_exception_msg(&mp_type_IndentationError, - "unindent does not match any outer indentation level"); + translate("unindent does not match any outer indentation level")); } else { exc = mp_obj_new_exception_msg(&mp_type_SyntaxError, - "invalid syntax"); + translate("invalid syntax")); } // add traceback to give info about file name and location // we don't have a 'block' name, so just pass the NULL qstr to indicate this diff --git a/py/parsenum.c b/py/parsenum.c index b7e5a3c833d..6ef309b475f 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -32,6 +32,8 @@ #include "py/parsenum.h" #include "py/smallint.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PY_BUILTINS_FLOAT #include #endif @@ -55,7 +57,7 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m // check radix base if ((base != 0 && base < 2) || base > 36) { // this won't be reached if lex!=NULL - mp_raise_ValueError("int() arg 2 must be >= 2 and <= 36"); + mp_raise_ValueError(translate("int() arg 2 must be >= 2 and <= 36")); } // skip leading space @@ -146,11 +148,11 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m value_error: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_obj_t exc = mp_obj_new_exception_msg(&mp_type_ValueError, - "invalid syntax for integer"); + translate("invalid syntax for integer")); raise_exc(exc, lex); } else if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL) { mp_obj_t exc = mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "invalid syntax for integer with base %d", base); + translate("invalid syntax for integer with base %d"), base); raise_exc(exc, lex); } else { vstr_t vstr; @@ -212,7 +214,7 @@ mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool if (str + 2 < top && (str[1] | 0x20) == 'n' && (str[2] | 0x20) == 'f') { // inf str += 3; - dec_val = INFINITY; + dec_val = (mp_float_t) INFINITY; if (str + 4 < top && (str[0] | 0x20) == 'i' && (str[1] | 0x20) == 'n' && (str[2] | 0x20) == 'i' && (str[3] | 0x20) == 't' && (str[4] | 0x20) == 'y') { // infinity str += 5; @@ -326,7 +328,7 @@ mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool } #else if (imag || force_complex) { - raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, "complex values not supported"), lex); + raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, translate("complex values not supported")), lex); } #endif else { @@ -334,9 +336,9 @@ mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool } value_error: - raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, "invalid syntax for number"), lex); + raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, translate("invalid syntax for number")), lex); #else - raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, "decimal numbers not supported"), lex); + raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, translate("decimal numbers not supported")), lex); #endif } diff --git a/py/persistentcode.c b/py/persistentcode.c index 7113b0dc2ed..eb69bd40799 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -34,6 +34,8 @@ #include "py/persistentcode.h" #include "py/bc.h" +#include "supervisor/shared/translate.h" + #if MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE #include "py/smallint.h" @@ -100,20 +102,35 @@ STATIC void extract_prelude(const byte **ip, const byte **ip2, bytecode_prelude_ #include "py/parsenum.h" +STATIC void raise_corrupt_mpy(void) { + mp_raise_RuntimeError(translate("Corrupt .mpy file")); +} + STATIC int read_byte(mp_reader_t *reader) { - return reader->readbyte(reader->data); + mp_uint_t b = reader->readbyte(reader->data); + if (b == MP_READER_EOF) { + raise_corrupt_mpy(); + } + return b; } STATIC void read_bytes(mp_reader_t *reader, byte *buf, size_t len) { while (len-- > 0) { - *buf++ = reader->readbyte(reader->data); + mp_uint_t b =reader->readbyte(reader->data); + if (b == MP_READER_EOF) { + raise_corrupt_mpy(); + } + *buf++ = b; } } STATIC size_t read_uint(mp_reader_t *reader) { size_t unum = 0; for (;;) { - byte b = reader->readbyte(reader->data); + mp_uint_t b = reader->readbyte(reader->data); + if (b == MP_READER_EOF) { + raise_corrupt_mpy(); + } unum = (unum << 7) | (b & 0x7f); if ((b & 0x80) == 0) { break; @@ -124,10 +141,9 @@ STATIC size_t read_uint(mp_reader_t *reader) { STATIC qstr load_qstr(mp_reader_t *reader) { size_t len = read_uint(reader); - char *str = m_new(char, len); + char str[len]; read_bytes(reader, (byte*)str, len); qstr qst = qstr_from_strn(str, len); - m_del(char, str, len); return qst; } @@ -144,11 +160,12 @@ STATIC mp_obj_t load_obj(mp_reader_t *reader) { return mp_obj_new_str_from_vstr(obj_type == 's' ? &mp_type_str : &mp_type_bytes, &vstr); } else if (obj_type == 'i') { return mp_parse_num_integer(vstr.buf, vstr.len, 10, NULL); - } else { - assert(obj_type == 'f' || obj_type == 'c'); + } else if (obj_type == 'f' || obj_type == 'c') { return mp_parse_num_decimal(vstr.buf, vstr.len, obj_type == 'c', false, NULL); } } + raise_corrupt_mpy(); + return MP_OBJ_FROM_PTR(&mp_const_none_obj); } STATIC void load_bytecode_qstrs(mp_reader_t *reader, byte *ip, byte *ip_top) { @@ -219,7 +236,7 @@ mp_raw_code_t *mp_raw_code_load(mp_reader_t *reader) { || header[1] != MPY_VERSION || header[2] != MPY_FEATURE_FLAGS || header[3] > mp_small_int_bits()) { - mp_raise_ValueError("incompatible .mpy file"); + mp_raise_MpyError(translate("Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info.")); } mp_raw_code_t *rc = load_raw_code(reader); reader->close(reader->data); @@ -322,7 +339,7 @@ STATIC void save_bytecode_qstrs(mp_print_t *print, const byte *ip, const byte *i STATIC void save_raw_code(mp_print_t *print, mp_raw_code_t *rc) { if (rc->kind != MP_CODE_BYTECODE) { - mp_raise_ValueError("can only save bytecode"); + mp_raise_ValueError(translate("can only save bytecode")); } // save bytecode diff --git a/py/py.mk b/py/py.mk index 0027fbb880e..17cb792646d 100644 --- a/py/py.mk +++ b/py/py.mk @@ -7,6 +7,8 @@ HEADER_BUILD = $(BUILD)/genhdr # file containing qstr defs for the core Python bit PY_QSTR_DEFS = $(PY_SRC)/qstrdefs.h +TRANSLATION := en_US + # If qstr autogeneration is not disabled we specify the output header # for all collected qstrings. ifneq ($(QSTR_AUTOGEN_DISABLE),1) @@ -26,7 +28,7 @@ ifeq ($(MICROPY_PY_USSL),1) CFLAGS_MOD += -DMICROPY_PY_USSL=1 ifeq ($(MICROPY_SSL_AXTLS),1) CFLAGS_MOD += -DMICROPY_SSL_AXTLS=1 -I$(TOP)/lib/axtls/ssl -I$(TOP)/lib/axtls/crypto -I$(TOP)/lib/axtls/config -LDFLAGS_MOD += -Lbuild -laxtls +LDFLAGS_MOD += -L$(BUILD) -laxtls else ifeq ($(MICROPY_SSL_MBEDTLS),1) # Can be overridden by ports which have "builtin" mbedTLS MICROPY_SSL_MBEDTLS_INCLUDE ?= $(TOP)/lib/mbedtls/include @@ -103,6 +105,24 @@ $(BUILD)/$(BTREE_DIR)/%.o: CFLAGS += -Wno-old-style-definition -Wno-sign-compare $(BUILD)/extmod/modbtree.o: CFLAGS += $(BTREE_DEFS) endif +# External modules written in C. +ifneq ($(USER_C_MODULES),) +# pre-define USERMOD variables as expanded so that variables are immediate +# expanded as they're added to them +SRC_USERMOD := +CFLAGS_USERMOD := +LDFLAGS_USERMOD := +$(foreach module, $(wildcard $(USER_C_MODULES)/*/micropython.mk), \ + $(eval USERMOD_DIR = $(patsubst %/,%,$(dir $(module))))\ + $(info Including User C Module from $(USERMOD_DIR))\ + $(eval include $(module))\ +) + +SRC_MOD += $(patsubst $(USER_C_MODULES)/%.c,%.c,$(SRC_USERMOD)) +CFLAGS_MOD += $(CFLAGS_USERMOD) +LDFLAGS_MOD += $(LDFLAGS_USERMOD) +endif + # py object files PY_CORE_O_BASENAME = $(addprefix py/,\ mpstate.o \ @@ -114,6 +134,7 @@ PY_CORE_O_BASENAME = $(addprefix py/,\ nlrsetjmp.o \ malloc.o \ gc.o \ + gc_long_lived.o \ pystack.o \ qstr.o \ vstr.o \ @@ -193,6 +214,7 @@ PY_CORE_O_BASENAME = $(addprefix py/,\ objtype.o \ objzip.o \ opmethods.o \ + reload.o \ sequence.o \ stream.o \ binary.o \ @@ -229,12 +251,6 @@ PY_EXTMOD_O_BASENAME = \ extmod/moduhashlib.o \ extmod/modubinascii.o \ extmod/virtpin.o \ - extmod/machine_mem.o \ - extmod/machine_pinbase.o \ - extmod/machine_signal.o \ - extmod/machine_pulse.o \ - extmod/machine_i2c.o \ - extmod/machine_spi.o \ extmod/modussl_axtls.o \ extmod/modussl_mbedtls.o \ extmod/modurandom.o \ @@ -263,48 +279,87 @@ PY_O = $(PY_CORE_O) $(PY_EXTMOD_O) # object file for frozen files ifneq ($(FROZEN_DIR),) -PY_O += $(BUILD)/$(BUILD)/frozen.o +PY_O += $(BUILD)/frozen.o endif +# Combine old singular FROZEN_MPY_DIR with new multiple value form. +FROZEN_MPY_DIRS += $(FROZEN_MPY_DIR) + # object file for frozen bytecode (frozen .mpy files) -ifneq ($(FROZEN_MPY_DIR),) -PY_O += $(BUILD)/$(BUILD)/frozen_mpy.o +ifneq ($(FROZEN_MPY_DIRS),) +PY_O += $(BUILD)/frozen_mpy.o endif # Sources that may contain qstrings SRC_QSTR_IGNORE = py/nlr% +SRC_QSTR_EMITNATIVE = py/emitn% SRC_QSTR = $(SRC_MOD) $(filter-out $(SRC_QSTR_IGNORE),$(PY_CORE_O_BASENAME:.o=.c)) $(PY_EXTMOD_O_BASENAME:.o=.c) +# Sources that only hold QSTRs after pre-processing. +SRC_QSTR_PREPROCESSOR = $(addprefix $(TOP)/, $(filter $(SRC_QSTR_EMITNATIVE),$(PY_CORE_O_BASENAME:.o=.c))) # Anything that depends on FORCE will be considered out-of-date FORCE: .PHONY: FORCE $(HEADER_BUILD)/mpversion.h: FORCE | $(HEADER_BUILD) + $(STEPECHO) "GEN $@" $(Q)$(PYTHON) $(PY_SRC)/makeversionhdr.py $@ +# build a list of registered modules for py/objmodule.c. +$(HEADER_BUILD)/moduledefs.h: $(SRC_QSTR) $(QSTR_GLOBAL_DEPENDENCIES) | $(HEADER_BUILD)/mpversion.h + @$(ECHO) "GEN $@" + $(Q)$(PYTHON) $(PY_SRC)/makemoduledefs.py --vpath="., $(TOP), $(USER_C_MODULES)" $(SRC_QSTR) > $@ + +SRC_QSTR += $(HEADER_BUILD)/moduledefs.h + # mpconfigport.mk is optional, but changes to it may drastically change # overall config, so they need to be caught MPCONFIGPORT_MK = $(wildcard mpconfigport.mk) +$(HEADER_BUILD)/$(TRANSLATION).mo: $(TOP)/locale/$(TRANSLATION).po + $(Q)msgfmt -o $@ $^ + +$(HEADER_BUILD)/qstrdefs.preprocessed.h: $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEFS_COLLECTED) mpconfigport.h $(MPCONFIGPORT_MK) $(PY_SRC)/mpconfig.h | $(HEADER_BUILD) + $(STEPECHO) "GEN $@" + $(Q)cat $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEFS_COLLECTED) | $(SED) 's/^Q(.*)/"&"/' | $(CPP) $(CFLAGS) - | $(SED) 's/^"\(Q(.*)\)"/\1/' > $@ + # qstr data +$(HEADER_BUILD)/qstrdefs.enum.h: $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrdefs.preprocessed.h + $(STEPECHO) "GEN $@" + $(Q)$(PYTHON3) $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@ + # Adding an order only dependency on $(HEADER_BUILD) causes $(HEADER_BUILD) to get # created before we run the script to generate the .h # Note: we need to protect the qstr names from the preprocessor, so we wrap # the lines in "" and then unwrap after the preprocessor is finished. -$(HEADER_BUILD)/qstrdefs.generated.h: $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEFS_COLLECTED) $(PY_SRC)/makeqstrdata.py mpconfigport.h $(MPCONFIGPORT_MK) $(PY_SRC)/mpconfig.h | $(HEADER_BUILD) - $(ECHO) "GEN $@" - $(Q)cat $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEFS_COLLECTED) | $(SED) 's/^Q(.*)/"&"/' | $(CPP) $(CFLAGS) - | $(SED) 's/^"\(Q(.*)\)"/\1/' > $(HEADER_BUILD)/qstrdefs.preprocessed.h - $(Q)$(PYTHON) $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@ +$(HEADER_BUILD)/qstrdefs.generated.h: $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/$(TRANSLATION).mo $(HEADER_BUILD)/qstrdefs.preprocessed.h + $(STEPECHO) "GEN $@" + $(Q)$(PYTHON3) $(PY_SRC)/makeqstrdata.py --compression_filename $(HEADER_BUILD)/compression.generated.h --translation $(HEADER_BUILD)/$(TRANSLATION).mo $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@ + +$(PY_BUILD)/qstr.o: $(HEADER_BUILD)/qstrdefs.generated.h # Force nlr code to always be compiled with space-saving optimisation so # that the function preludes are of a minimal and predictable form. $(PY_BUILD)/nlr%.o: CFLAGS += -Os # optimising gc for speed; 5ms down to 4ms on pybv2 +ifndef SUPEROPT_GC + SUPEROPT_GC = 1 +endif + +ifeq ($(SUPEROPT_GC),1) $(PY_BUILD)/gc.o: CFLAGS += $(CSUPEROPT) +endif # optimising vm for speed, adds only a small amount to code size but makes a huge difference to speed (20% faster) +ifndef SUPEROPT_VM + SUPEROPT_VM = 1 +endif + +ifeq ($(SUPEROPT_VM),1) $(PY_BUILD)/vm.o: CFLAGS += $(CSUPEROPT) +endif + # Optimizing vm.o for modern deeply pipelined CPUs with branch predictors # may require disabling tail jump optimization. This will make sure that # each opcode has its own dispatching jump which will improve branch diff --git a/py/qstr.c b/py/qstr.c old mode 100644 new mode 100755 index 08c3e2505ea..eea57c1e0e1 --- a/py/qstr.c +++ b/py/qstr.c @@ -28,6 +28,7 @@ #include #include +#include "py/gc.h" #include "py/mpstate.h" #include "py/qstr.h" #include "py/gc.h" @@ -103,7 +104,9 @@ const qstr_pool_t mp_qstr_const_pool = { { #ifndef NO_QSTR #define QDEF(id, str) str, +#define TRANSLATION(id, length, compressed...) #include "genhdr/qstrdefs.generated.h" +#undef TRANSLATION #undef QDEF #endif }, @@ -141,14 +144,18 @@ STATIC qstr qstr_add(const byte *q_ptr) { // make sure we have room in the pool for a new qstr if (MP_STATE_VM(last_pool)->len >= MP_STATE_VM(last_pool)->alloc) { - qstr_pool_t *pool = m_new_obj_var_maybe(qstr_pool_t, const char*, MP_STATE_VM(last_pool)->alloc * 2); + uint32_t new_pool_length = MP_STATE_VM(last_pool)->alloc * 2; + if (new_pool_length > MICROPY_QSTR_POOL_MAX_ENTRIES) { + new_pool_length = MICROPY_QSTR_POOL_MAX_ENTRIES; + } + qstr_pool_t *pool = m_new_ll_obj_var_maybe(qstr_pool_t, const char*, new_pool_length); if (pool == NULL) { QSTR_EXIT(); - m_malloc_fail(MP_STATE_VM(last_pool)->alloc * 2); + m_malloc_fail(new_pool_length); } pool->prev = MP_STATE_VM(last_pool); pool->total_prev_len = MP_STATE_VM(last_pool)->total_prev_len + MP_STATE_VM(last_pool)->len; - pool->alloc = MP_STATE_VM(last_pool)->alloc * 2; + pool->alloc = new_pool_length; pool->len = 0; MP_STATE_VM(last_pool) = pool; DEBUG_printf("QSTR: allocate new pool of size %d\n", MP_STATE_VM(last_pool)->alloc); @@ -211,10 +218,10 @@ qstr qstr_from_strn(const char *str, size_t len) { if (al < MICROPY_ALLOC_QSTR_CHUNK_INIT) { al = MICROPY_ALLOC_QSTR_CHUNK_INIT; } - MP_STATE_VM(qstr_last_chunk) = m_new_maybe(byte, al); + MP_STATE_VM(qstr_last_chunk) = m_new_ll_maybe(byte, al); if (MP_STATE_VM(qstr_last_chunk) == NULL) { // failed to allocate a large chunk so try with exact size - MP_STATE_VM(qstr_last_chunk) = m_new_maybe(byte, n_bytes); + MP_STATE_VM(qstr_last_chunk) = m_new_ll_maybe(byte, n_bytes); if (MP_STATE_VM(qstr_last_chunk) == NULL) { QSTR_EXIT(); m_malloc_fail(n_bytes); diff --git a/py/qstr.h b/py/qstr.h index f4375ee0e92..39b904fb18a 100644 --- a/py/qstr.h +++ b/py/qstr.h @@ -38,9 +38,9 @@ // first entry in enum will be MP_QSTR_NULL=0, which indicates invalid/no qstr enum { #ifndef NO_QSTR -#define QDEF(id, str) id, -#include "genhdr/qstrdefs.generated.h" -#undef QDEF +#define QENUM(id) id, +#include "genhdr/qstrdefs.enum.h" +#undef QENUM #endif MP_QSTRnumber_of, // no underscore so it can't clash with any of the above }; diff --git a/py/reload.c b/py/reload.c new file mode 100644 index 00000000000..95305f2c9cf --- /dev/null +++ b/py/reload.c @@ -0,0 +1,16 @@ +// +// Created by Roy Hooper on 2018-05-14. +// + +#include "reload.h" +#include "py/mpstate.h" + +void mp_raise_reload_exception(void) { + MP_STATE_VM(mp_pending_exception) = MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception)); +#if MICROPY_ENABLE_SCHEDULER + if (MP_STATE_VM(sched_state) == MP_SCHED_IDLE) { + MP_STATE_VM(sched_state) = MP_SCHED_PENDING; + } +#endif + +} diff --git a/py/reload.h b/py/reload.h new file mode 100644 index 00000000000..72e84e5ca64 --- /dev/null +++ b/py/reload.h @@ -0,0 +1,10 @@ +// +// Created by Roy Hooper on 2018-05-14. +// + +#ifndef CIRCUITPYTHON_RELOAD_H +#define CIRCUITPYTHON_RELOAD_H + +void mp_raise_reload_exception(void); + +#endif //CIRCUITPYTHON_RELOAD_H diff --git a/py/repl.c b/py/repl.c index da0fefb3a91..aa91c3f12e0 100644 --- a/py/repl.c +++ b/py/repl.c @@ -187,6 +187,11 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { mp_load_method_protected(obj, q, dest, true); if (dest[0] != MP_OBJ_NULL) { + // special case; filter out words that begin with underscore + // unless there's already a partial match + if (s_len == 0 && d_str[0] == '_') { + continue; + } if (match_str == NULL) { match_str = d_str; match_len = d_len; @@ -210,6 +215,10 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print // nothing found if (q_first == 0) { + if (s_len == 0) { + *compl_str = " "; + return 4; + } // If there're no better alternatives, and if it's first word // in the line, try to complete "import". if (s_start == org_str) { diff --git a/py/ringbuf.h b/py/ringbuf.h index b4169270608..5f82cc0968f 100644 --- a/py/ringbuf.h +++ b/py/ringbuf.h @@ -26,6 +26,10 @@ #ifndef MICROPY_INCLUDED_PY_RINGBUF_H #define MICROPY_INCLUDED_PY_RINGBUF_H +#include "py/gc.h" + +#include + typedef struct _ringbuf_t { uint8_t *buf; uint16_t size; @@ -38,9 +42,9 @@ typedef struct _ringbuf_t { // ringbuf_t buf = {buf_array, sizeof(buf_array)}; // Dynamic initialization. This creates root pointer! -#define ringbuf_alloc(r, sz) \ +#define ringbuf_alloc(r, sz, long_lived) \ { \ - (r)->buf = m_new(uint8_t, sz); \ + (r)->buf = gc_alloc(sz, false, long_lived); \ (r)->size = sz; \ (r)->iget = (r)->iput = 0; \ } @@ -69,4 +73,30 @@ static inline int ringbuf_put(ringbuf_t *r, uint8_t v) { return 0; } +static inline uint16_t ringbuf_count(ringbuf_t *r) +{ + volatile int count = r->iput - r->iget; + if ( count < 0 ) { + count += r->size; + } + + return (uint16_t) count; +} + +static inline void ringbuf_clear(ringbuf_t *r) +{ + r->iput = r->iget = 0; +} + +// will overwrite old data +static inline void ringbuf_put_n(ringbuf_t* r, uint8_t* buf, uint8_t bufsize) +{ + for(uint8_t i=0; i < bufsize; i++) { + if ( ringbuf_put(r, buf[i]) < 0 ) { + // if full overwrite old data + (void) ringbuf_get(r); + ringbuf_put(r, buf[i]); + } + } +} #endif // MICROPY_INCLUDED_PY_RINGBUF_H diff --git a/py/runtime.c b/py/runtime.c index a2dac46a424..9968f26e062 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -24,14 +24,20 @@ * THE SOFTWARE. */ +#include #include #include #include +#include "extmod/vfs.h" + +// #include "py/mpstate.h" +// #include "py/nlr.h" #include "py/parsenum.h" #include "py/compile.h" #include "py/objstr.h" #include "py/objtuple.h" +#include "py/objtype.h" #include "py/objlist.h" #include "py/objmodule.h" #include "py/objgenerator.h" @@ -41,6 +47,8 @@ #include "py/stackctrl.h" #include "py/gc.h" +#include "supervisor/shared/translate.h" + #if MICROPY_DEBUG_VERBOSE // print debugging info #define DEBUG_PRINT (1) #define DEBUG_printf DEBUG_printf @@ -78,6 +86,12 @@ void mp_init(void) { MP_STATE_VM(mp_kbd_exception).args = (mp_obj_tuple_t*)&mp_const_empty_tuple_obj; #endif + MP_STATE_VM(mp_reload_exception).base.type = &mp_type_ReloadException; + MP_STATE_VM(mp_reload_exception).traceback_alloc = 0; + MP_STATE_VM(mp_reload_exception).traceback_len = 0; + MP_STATE_VM(mp_reload_exception).traceback_data = NULL; + MP_STATE_VM(mp_reload_exception).args = (mp_obj_tuple_t*)&mp_const_empty_tuple_obj; + // call port specific initialization if any #ifdef MICROPY_PORT_INIT_FUNC MICROPY_PORT_INIT_FUNC; @@ -108,17 +122,13 @@ void mp_init(void) { for (size_t i = 0; i < MICROPY_PY_OS_DUPTERM; ++i) { MP_STATE_VM(dupterm_objs[i]) = MP_OBJ_NULL; } + MP_STATE_VM(dupterm_arr_obj) = MP_OBJ_NULL; #endif - #if MICROPY_FSUSERMOUNT + #ifdef MICROPY_FSUSERMOUNT // zero out the pointers to the user-mounted devices - memset(MP_STATE_VM(fs_user_mount), 0, sizeof(MP_STATE_VM(fs_user_mount))); - #endif - - #if MICROPY_VFS - // initialise the VFS sub-system - MP_STATE_VM(vfs_cur) = NULL; - MP_STATE_VM(vfs_mount_table) = NULL; + memset(MP_STATE_VM(fs_user_mount) + MICROPY_FATFS_NUM_PERSISTENT, 0, + sizeof(MP_STATE_VM(fs_user_mount)) - MICROPY_FATFS_NUM_PERSISTENT); #endif #if MICROPY_PY_THREAD_GIL @@ -168,10 +178,10 @@ mp_obj_t mp_load_global(qstr qst) { elem = mp_map_lookup((mp_map_t*)&mp_module_builtins_globals.map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP); if (elem == NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_NameError, "name not defined"); + mp_raise_msg(&mp_type_NameError, translate("name not defined")); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_NameError, - "name '%q' is not defined", qst)); + translate("name '%q' is not defined"), qst)); } } } @@ -266,11 +276,11 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) { } } if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("unsupported type for operator"); + mp_raise_TypeError(translate("unsupported type for operator")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "unsupported type for %q: '%s'", - mp_unary_op_method_name[op], mp_obj_get_type_str(arg))); + mp_raise_TypeError_varg( + translate("unsupported type for %q: '%s'"), + mp_unary_op_method_name[op], mp_obj_get_type_str(arg)); } } } @@ -358,7 +368,7 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { case MP_BINARY_OP_INPLACE_LSHIFT: { if (rhs_val < 0) { // negative shift not allowed - mp_raise_ValueError("negative shift count"); + mp_raise_ValueError(translate("negative shift count")); } else if (rhs_val >= (mp_int_t)BITS_PER_WORD || lhs_val > (MP_SMALL_INT_MAX >> rhs_val) || lhs_val < (MP_SMALL_INT_MIN >> rhs_val)) { // left-shift will overflow, so use higher precision integer lhs = mp_obj_new_int_from_ll(lhs_val); @@ -373,7 +383,7 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { case MP_BINARY_OP_INPLACE_RSHIFT: if (rhs_val < 0) { // negative shift not allowed - mp_raise_ValueError("negative shift count"); + mp_raise_ValueError(translate("negative shift count")); } else { // standard precision is enough for right-shift if (rhs_val >= (mp_int_t)BITS_PER_WORD) { @@ -448,7 +458,7 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { lhs = mp_obj_new_float(lhs_val); goto generic_binary_op; #else - mp_raise_ValueError("negative power with no float support"); + mp_raise_ValueError(translate("negative power with no float support")); #endif } else { mp_int_t ans = 1; @@ -573,15 +583,15 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { unsupported_op: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("unsupported type for operator"); + mp_raise_TypeError(translate("unsupported type for operator")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "unsupported types for %q: '%s', '%s'", - mp_binary_op_method_name[op], mp_obj_get_type_str(lhs), mp_obj_get_type_str(rhs))); + mp_raise_TypeError_varg( + translate("unsupported types for %q: '%s', '%s'"), + mp_binary_op_method_name[op], mp_obj_get_type_str(lhs), mp_obj_get_type_str(rhs)); } zero_division: - mp_raise_msg(&mp_type_ZeroDivisionError, "division by zero"); + mp_raise_msg(&mp_type_ZeroDivisionError, translate("division by zero")); } mp_obj_t mp_call_function_0(mp_obj_t fun) { @@ -615,10 +625,9 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, size_t n_args, size_t n_kw, cons } if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("object not callable"); + mp_raise_TypeError(translate("object not callable")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "'%s' object is not callable", mp_obj_get_type_str(fun_in))); + mp_raise_TypeError_varg(translate("'%s' object is not callable"), mp_obj_get_type_str(fun_in)); } } @@ -844,17 +853,17 @@ void mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items) { too_short: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_ValueError("wrong number of values to unpack"); + mp_raise_ValueError(translate("wrong number of values to unpack")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "need more than %d values to unpack", (int)seq_len)); + mp_raise_ValueError_varg(translate("need more than %d values to unpack"), + (int)seq_len); } too_long: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_ValueError("wrong number of values to unpack"); + mp_raise_ValueError(translate("wrong number of values to unpack")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "too many values to unpack (expected %d)", (int)num)); + mp_raise_ValueError_varg(translate("too many values to unpack (expected %d)"), + (int)num); } } @@ -908,10 +917,10 @@ void mp_unpack_ex(mp_obj_t seq_in, size_t num_in, mp_obj_t *items) { too_short: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_ValueError("wrong number of values to unpack"); + mp_raise_ValueError(translate("wrong number of values to unpack")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "need more than %d values to unpack", (int)seq_len)); + mp_raise_ValueError_varg(translate("need more than %d values to unpack"), + (int)seq_len); } } @@ -947,10 +956,10 @@ STATIC mp_obj_t checked_fun_call(mp_obj_t self_in, size_t n_args, size_t n_kw, c const mp_obj_type_t *arg0_type = mp_obj_get_type(args[0]); if (arg0_type != self->type) { if (MICROPY_ERROR_REPORTING != MICROPY_ERROR_REPORTING_DETAILED) { - mp_raise_TypeError("argument has wrong type"); + mp_raise_TypeError(translate("argument has wrong type")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "argument should be a '%q' not a '%q'", self->type->name, arg0_type->name)); + mp_raise_TypeError_varg(translate("argument should be a '%q' not a '%q'"), + self->type->name, arg0_type->name); } } } @@ -1016,6 +1025,23 @@ void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t dest[0] = member; dest[1] = self; } + #if MICROPY_PY_BUILTINS_PROPERTY + // If self is MP_OBJ_NULL, we looking at the class itself, not an instance. + } else if (MP_OBJ_IS_TYPE(member, &mp_type_property) && mp_obj_is_native_type(type) && self != MP_OBJ_NULL) { + // object member is a property; delegate the load to the property + // Note: This is an optimisation for code size and execution time. + // The proper way to do it is have the functionality just below + // in a __get__ method of the property object, and then it would + // be called by the descriptor code down below. But that way + // requires overhead for the nested mp_call's and overhead for + // the code. + const mp_obj_t *proxy = mp_obj_property_get(member); + if (proxy[0] == mp_const_none) { + mp_raise_AttributeError(translate("unreadable attribute")); + } else { + dest[0] = mp_call_function_n_kw(proxy[0], 1, 0, &self); + } + #endif } else { // class member is a value, so just return that value dest[0] = member; @@ -1069,16 +1095,16 @@ void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) { if (dest[0] == MP_OBJ_NULL) { // no attribute/method called attr if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_AttributeError, "no such attribute"); + mp_raise_AttributeError(translate("no such attribute")); } else { // following CPython, we give a more detailed error message for type objects if (MP_OBJ_IS_TYPE(base, &mp_type_type)) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AttributeError, - "type object '%q' has no attribute '%q'", + translate("type object '%q' has no attribute '%q'"), ((mp_obj_type_t*)MP_OBJ_TO_PTR(base))->name, attr)); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AttributeError, - "'%s' object has no attribute '%q'", + translate("'%s' object has no attribute '%q'"), mp_obj_get_type_str(base), attr)); } } @@ -1111,12 +1137,42 @@ void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) { // success return; } + #if MICROPY_PY_BUILTINS_PROPERTY + } else if (type->locals_dict != NULL) { + // generic method lookup + // this is a lookup in the object (ie not class or type) + assert(type->locals_dict->base.type == &mp_type_dict); // Micro Python restriction, for now + mp_map_t *locals_map = &type->locals_dict->map; + mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP); + // If base is MP_OBJ_NULL, we looking at the class itself, not an instance. + if (elem != NULL && MP_OBJ_IS_TYPE(elem->value, &mp_type_property) && base != MP_OBJ_NULL) { + // attribute exists and is a property; delegate the store/delete + // Note: This is an optimisation for code size and execution time. + // The proper way to do it is have the functionality just below in + // a __set__/__delete__ method of the property object, and then it + // would be called by the descriptor code down below. But that way + // requires overhead for the nested mp_call's and overhead for + // the code. + const mp_obj_t *proxy = mp_obj_property_get(elem->value); + mp_obj_t dest[2] = {base, value}; + if (value == MP_OBJ_NULL) { + // delete attribute + if (proxy[2] != mp_const_none) { + mp_call_function_n_kw(proxy[2], 1, 0, dest); + return; + } + } else if (proxy[1] != mp_const_none) { + mp_call_function_n_kw(proxy[1], 2, 0, dest); + return; + } + } + #endif } if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_AttributeError, "no such attribute"); + mp_raise_AttributeError(translate("no such attribute")); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AttributeError, - "'%s' object has no attribute '%q'", + translate("'%s' object has no attribute '%q'"), mp_obj_get_type_str(base), attr)); } } @@ -1154,10 +1210,10 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) { // object not iterable if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("object not iterable"); + mp_raise_TypeError(translate("object not iterable")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "'%s' object is not iterable", mp_obj_get_type_str(o_in))); + mp_raise_TypeError_varg( + translate("'%s' object is not iterable"), mp_obj_get_type_str(o_in)); } } @@ -1176,10 +1232,10 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) { return mp_call_method_n_kw(0, 0, dest); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("object not an iterator"); + mp_raise_TypeError(translate("object not an iterator")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "'%s' object is not an iterator", mp_obj_get_type_str(o_in))); + mp_raise_TypeError_varg(translate("'%s' object is not an iterator"), + mp_obj_get_type_str(o_in)); } } } @@ -1212,10 +1268,10 @@ mp_obj_t mp_iternext(mp_obj_t o_in) { } } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_TypeError("object not an iterator"); + mp_raise_TypeError(translate("object not an iterator")); } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "'%s' object is not an iterator", mp_obj_get_type_str(o_in))); + mp_raise_TypeError_varg(translate("'%s' object is not an iterator"), + mp_obj_get_type_str(o_in)); } } } @@ -1317,7 +1373,7 @@ mp_obj_t mp_make_raise_obj(mp_obj_t o) { return o; } else { // o cannot be used as an exception, so return a type error (which will be raised by the caller) - return mp_obj_new_exception_msg(&mp_type_TypeError, "exceptions must derive from BaseException"); + return mp_obj_new_exception_msg(&mp_type_TypeError, translate("exceptions must derive from BaseException")); } } @@ -1346,7 +1402,7 @@ mp_obj_t mp_import_from(mp_obj_t module, qstr name) { if (dest[1] != MP_OBJ_NULL) { // Hopefully we can't import bound method from an object import_error: - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "cannot import name %q", name)); + mp_raise_msg_varg(&mp_type_ImportError, translate("cannot import name %q"), name); } if (dest[0] != MP_OBJ_NULL) { @@ -1451,14 +1507,14 @@ NORETURN void m_malloc_fail(size_t num_bytes) { DEBUG_printf("memory allocation failed, allocating %u bytes\n", (uint)num_bytes); #if MICROPY_ENABLE_GC if (gc_is_locked()) { - mp_raise_msg(&mp_type_MemoryError, "memory allocation failed, heap is locked"); + mp_raise_msg(&mp_type_MemoryError, translate("memory allocation failed, heap is locked")); } #endif - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_MemoryError, - "memory allocation failed, allocating %u bytes", (uint)num_bytes)); + mp_raise_msg_varg(&mp_type_MemoryError, + translate("memory allocation failed, allocating %u bytes"), (uint)num_bytes); } -NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const char *msg) { +NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg) { if (msg == NULL) { nlr_raise(mp_obj_new_exception(exc_type)); } else { @@ -1466,25 +1522,96 @@ NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const char *msg) { } } -NORETURN void mp_raise_ValueError(const char *msg) { +NORETURN void mp_raise_msg_varg(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, ...) { + va_list argptr; + va_start(argptr,fmt); + mp_obj_t exception = mp_obj_new_exception_msg_vlist(exc_type, fmt, argptr); + va_end(argptr); + nlr_raise(exception); +} + +NORETURN void mp_raise_AttributeError(const compressed_string_t *msg) { + mp_raise_msg(&mp_type_AttributeError, msg); +} + +NORETURN void mp_raise_RuntimeError(const compressed_string_t *msg) { + mp_raise_msg(&mp_type_RuntimeError, msg); +} + +NORETURN void mp_raise_ImportError(const compressed_string_t *msg) { + mp_raise_msg(&mp_type_ImportError, msg); +} + +NORETURN void mp_raise_IndexError(const compressed_string_t *msg) { + mp_raise_msg(&mp_type_IndexError, msg); +} + +NORETURN void mp_raise_ValueError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_ValueError, msg); } -NORETURN void mp_raise_TypeError(const char *msg) { +NORETURN void mp_raise_ValueError_varg(const compressed_string_t *fmt, ...) { + va_list argptr; + va_start(argptr,fmt); + mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_ValueError, fmt, argptr); + va_end(argptr); + nlr_raise(exception); +} + +NORETURN void mp_raise_TypeError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_TypeError, msg); } +NORETURN void mp_raise_TypeError_varg(const compressed_string_t *fmt, ...) { + va_list argptr; + va_start(argptr,fmt); + mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_TypeError, fmt, argptr); + va_end(argptr); + nlr_raise(exception); +} + NORETURN void mp_raise_OSError(int errno_) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno_))); } -NORETURN void mp_raise_NotImplementedError(const char *msg) { +NORETURN void mp_raise_OSError_msg(const compressed_string_t *msg) { + mp_raise_msg(&mp_type_OSError, msg); +} + +NORETURN void mp_raise_OSError_msg_varg(const compressed_string_t *fmt, ...) { + va_list argptr; + va_start(argptr,fmt); + mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_OSError, fmt, argptr); + va_end(argptr); + nlr_raise(exception); +} + +NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_NotImplementedError, msg); } +NORETURN void mp_raise_NotImplementedError_varg(const compressed_string_t *fmt, ...) { + va_list argptr; + va_start(argptr,fmt); + mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_NotImplementedError, fmt, argptr); + va_end(argptr); + nlr_raise(exception); +} + +NORETURN void mp_raise_OverflowError_varg(const compressed_string_t *fmt, ...) { + va_list argptr; + va_start(argptr,fmt); + mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_OverflowError, fmt, argptr); + va_end(argptr); + nlr_raise(exception); +} + +NORETURN void mp_raise_MpyError(const compressed_string_t *msg) { + mp_raise_msg(&mp_type_MpyError, msg); +} + #if MICROPY_STACK_CHECK || MICROPY_ENABLE_PYSTACK NORETURN void mp_raise_recursion_depth(void) { - nlr_raise(mp_obj_new_exception_arg1(&mp_type_RuntimeError, - MP_OBJ_NEW_QSTR(MP_QSTR_maximum_space_recursion_space_depth_space_exceeded))); + mp_raise_RuntimeError(translate("maximum recursion depth exceeded")); } #endif diff --git a/py/runtime.h b/py/runtime.h index ad65f3f46df..e8398cf0eaa 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -77,8 +77,9 @@ bool mp_sched_schedule(mp_obj_t function, mp_obj_t arg); // extra printing method specifically for mp_obj_t's which are integral type int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, int base, int base_char, int flags, char fill, int width, int prec); -void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw); +void mp_arg_check_num(size_t n_args, mp_map_t *kw_args, size_t n_args_min, size_t n_args_max, bool takes_kw); void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); +void mp_arg_check_num_kw_array(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw); void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args, size_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); NORETURN void mp_arg_error_terse_mismatch(void); NORETURN void mp_arg_error_unimpl_kw(void); @@ -147,12 +148,23 @@ mp_obj_t mp_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level); mp_obj_t mp_import_from(mp_obj_t module, qstr name); void mp_import_all(mp_obj_t module); -NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const char *msg); -//NORETURN void nlr_raise_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...); -NORETURN void mp_raise_ValueError(const char *msg); -NORETURN void mp_raise_TypeError(const char *msg); -NORETURN void mp_raise_NotImplementedError(const char *msg); +NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg); +NORETURN void mp_raise_msg_varg(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, ...); +NORETURN void mp_raise_ValueError(const compressed_string_t *msg); +NORETURN void mp_raise_ValueError_varg(const compressed_string_t *fmt, ...); +NORETURN void mp_raise_TypeError(const compressed_string_t *msg); +NORETURN void mp_raise_TypeError_varg(const compressed_string_t *fmt, ...); +NORETURN void mp_raise_AttributeError(const compressed_string_t *msg); +NORETURN void mp_raise_RuntimeError(const compressed_string_t *msg); +NORETURN void mp_raise_ImportError(const compressed_string_t *msg); +NORETURN void mp_raise_IndexError(const compressed_string_t *msg); NORETURN void mp_raise_OSError(int errno_); +NORETURN void mp_raise_OSError_msg(const compressed_string_t *msg); +NORETURN void mp_raise_OSError_msg_varg(const compressed_string_t *fmt, ...); +NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg); +NORETURN void mp_raise_NotImplementedError_varg(const compressed_string_t *fmt, ...); +NORETURN void mp_raise_OverflowError_varg(const compressed_string_t *fmt, ...); +NORETURN void mp_raise_MpyError(const compressed_string_t *msg); NORETURN void mp_raise_recursion_depth(void); #if MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG diff --git a/py/runtime0.h b/py/runtime0.h index 2e89de9f416..16434b315a7 100644 --- a/py/runtime0.h +++ b/py/runtime0.h @@ -26,6 +26,8 @@ #ifndef MICROPY_INCLUDED_PY_RUNTIME0_H #define MICROPY_INCLUDED_PY_RUNTIME0_H +#include "mpconfig.h" + // These must fit in 8 bits; see scope.h #define MP_SCOPE_FLAG_VARARGS (0x01) #define MP_SCOPE_FLAG_VARKEYWORDS (0x02) diff --git a/py/runtime_utils.c b/py/runtime_utils.c index b92c6bd767c..fd3f0711138 100644 --- a/py/runtime_utils.c +++ b/py/runtime_utils.c @@ -25,9 +25,10 @@ * THE SOFTWARE. */ +#include "py/mpconfig.h" #include "py/runtime.h" -mp_obj_t mp_call_function_1_protected(mp_obj_t fun, mp_obj_t arg) { +MP_NOINLINE mp_obj_t mp_call_function_1_protected(mp_obj_t fun, mp_obj_t arg) { nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mp_obj_t ret = mp_call_function_1(fun, arg); diff --git a/py/sequence.c b/py/sequence.c index c66fde98f64..a750e5bac4f 100644 --- a/py/sequence.c +++ b/py/sequence.c @@ -28,11 +28,21 @@ #include #include "py/runtime.h" +#include "supervisor/shared/translate.h" // Helpers for sequence types #define SWAP(type, var1, var2) { type t = var2; var2 = var1; var1 = t; } +// Detect when a multiply causes an overflow. +size_t mp_seq_multiply_len(size_t item_sz, size_t len) { + size_t new_len; + if (__builtin_mul_overflow(item_sz, len, &new_len)) { + mp_raise_msg(&mp_type_OverflowError, translate("small int overflow")); + } + return new_len; +} + // Implements backend of sequence * integer operation. Assumes elements are // memory-adjacent in sequence. void mp_seq_multiply(const void *items, size_t item_sz, size_t len, size_t times, void *dest) { @@ -53,7 +63,7 @@ bool mp_seq_get_fast_slice_indexes(mp_uint_t len, mp_obj_t slice, mp_bound_slice if (ostep != mp_const_none && ostep != MP_OBJ_NEW_SMALL_INT(1)) { indexes->step = mp_obj_get_int(ostep); if (indexes->step == 0) { - mp_raise_ValueError("slice step cannot be zero"); + mp_raise_ValueError(translate("slice step cannot be zero")); } } else { indexes->step = 1; @@ -260,7 +270,7 @@ mp_obj_t mp_seq_index_obj(const mp_obj_t *items, size_t len, size_t n_args, cons } } - mp_raise_ValueError("object not in sequence"); + mp_raise_ValueError(translate("object not in sequence")); } mp_obj_t mp_seq_count_obj(const mp_obj_t *items, size_t len, mp_obj_t value) { diff --git a/py/stackctrl.c b/py/stackctrl.c index 5c07796bde3..46cbefc8c17 100644 --- a/py/stackctrl.c +++ b/py/stackctrl.c @@ -28,6 +28,8 @@ #include "py/stackctrl.h" void mp_stack_ctrl_init(void) { + // Force routine to not be inlined. Better guarantee than MP_NOINLINE for -flto. + __asm volatile (""); volatile int stack_dummy; MP_STATE_THREAD(stack_top) = (char*)&stack_dummy; } @@ -38,6 +40,8 @@ void mp_stack_set_top(void *top) { mp_uint_t mp_stack_usage(void) { // Assumes descending stack + // Force routine to not be inlined. Better guarantee than MP_NOINLINE for -flto. + __asm volatile (""); volatile int stack_dummy; return MP_STATE_THREAD(stack_top) - (char*)&stack_dummy; } @@ -55,3 +59,41 @@ void mp_stack_check(void) { } #endif // MICROPY_STACK_CHECK + +#if MICROPY_MAX_STACK_USAGE + +// Fill stack space with this unusual value. +const char MP_MAX_STACK_USAGE_SENTINEL_BYTE = 0xEE; + +// Record absolute bottom (logical limit) of stack. +void mp_stack_set_bottom(void* stack_bottom) { + MP_STATE_THREAD(stack_bottom) = stack_bottom; +} + +// Return the current frame pointer. This can be used as an +// approximation for the stack pointer of the _calling_ function. +// This routine must not be inlined. This method is +// architecture-independent, as opposed to using asm("sp") or similar. +// +// The stack_dummy approach used elsewhere in this file is not safe in +// all cases. That value may be below the actual top of the stack. +static void* approx_stack_pointer(void){ + __asm volatile (""); + return __builtin_frame_address(0); +} + +// Fill stack space down toward the stack limit with a known unusual value. +void mp_stack_fill_with_sentinel(void) { + // Force routine to not be inlined. Better guarantee than MP_NOINLINE for -flto. + __asm volatile (""); + // Start filling stack just below the current stack frame. + // Continue until we've hit the bottom of the stack (lowest address, + // logical "ceiling" of stack). + char* p = (char *) approx_stack_pointer() - 1; + + while(p >= MP_STATE_THREAD(stack_bottom)) { + *p-- = MP_MAX_STACK_USAGE_SENTINEL_BYTE; + } +} + +#endif // MICROPY_MAX_STACK_USAGE diff --git a/py/stackctrl.h b/py/stackctrl.h index ff8da0ab138..18cd81e75be 100644 --- a/py/stackctrl.h +++ b/py/stackctrl.h @@ -45,4 +45,12 @@ void mp_stack_check(void); #endif +#if MICROPY_MAX_STACK_USAGE + +const char MP_MAX_STACK_USAGE_SENTINEL_BYTE; +void mp_stack_set_bottom(void* stack_bottom); +void mp_stack_fill_with_sentinel(void); + +#endif + #endif // MICROPY_INCLUDED_PY_STACKCTRL_H diff --git a/py/stream.c b/py/stream.c index 448de41bbbb..08c749cc301 100644 --- a/py/stream.c +++ b/py/stream.c @@ -31,6 +31,7 @@ #include "py/objstr.h" #include "py/stream.h" #include "py/runtime.h" +#include "supervisor/shared/translate.h" // This file defines generic Python stream read/write methods which // dispatch to the underlying stream interface of an object. @@ -92,7 +93,7 @@ const mp_stream_p_t *mp_get_stream_raise(mp_obj_t self_in, int flags) { || ((flags & MP_STREAM_OP_WRITE) && stream_p->write == NULL) || ((flags & MP_STREAM_OP_IOCTL) && stream_p->ioctl == NULL)) { // CPython: io.UnsupportedOperation, OSError subclass - mp_raise_msg(&mp_type_OSError, "stream operation not supported"); + mp_raise_msg(&mp_type_OSError, translate("stream operation not supported")); } return stream_p; } @@ -102,7 +103,7 @@ STATIC mp_obj_t stream_read_generic(size_t n_args, const mp_obj_t *args, byte fl // CPython does a readall, but here we silently let negatives through, // and they will cause a MemoryError. mp_int_t sz; - if (n_args == 1 || ((sz = mp_obj_get_int(args[1])) == -1)) { + if (n_args == 1 || args[1] == mp_const_none || ((sz = mp_obj_get_int(args[1])) == -1)) { return stream_readall(args[0]); } @@ -249,6 +250,9 @@ void mp_stream_write_adaptor(void *self, const char *buf, size_t len) { STATIC mp_obj_t stream_write_method(size_t n_args, const mp_obj_t *args) { mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ); + if (!mp_get_stream(args[0])->is_text && MP_OBJ_IS_STR(args[1])) { + mp_raise_ValueError(translate("string not supported; use bytes or bytearray")); + } size_t max_len = (size_t)-1; size_t off = 0; if (n_args == 3) { @@ -281,6 +285,9 @@ STATIC mp_obj_t stream_readinto(size_t n_args, const mp_obj_t *args) { // https://docs.python.org/3/library/socket.html#socket.socket.recv_into mp_uint_t len = bufinfo.len; if (n_args > 2) { + if (mp_get_stream(args[0])->pyserial_compatibility) { + mp_raise_ValueError(translate("length argument not allowed for this type")); + } len = mp_obj_get_int(args[2]); if (len > bufinfo.len) { len = bufinfo.len; @@ -461,16 +468,19 @@ STATIC mp_obj_t stream_tell(mp_obj_t self) { } MP_DEFINE_CONST_FUN_OBJ_1(mp_stream_tell_obj, stream_tell); -STATIC mp_obj_t stream_flush(mp_obj_t self) { +mp_obj_t mp_stream_flush(mp_obj_t self) { const mp_stream_p_t *stream_p = mp_get_stream(self); int error; + if (stream_p->ioctl == NULL) { + mp_raise_OSError(MP_EINVAL); + } mp_uint_t res = stream_p->ioctl(self, MP_STREAM_FLUSH, 0, &error); if (res == MP_STREAM_ERROR) { mp_raise_OSError(error); } return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_1(mp_stream_flush_obj, stream_flush); +MP_DEFINE_CONST_FUN_OBJ_1(mp_stream_flush_obj, mp_stream_flush); STATIC mp_obj_t stream_ioctl(size_t n_args, const mp_obj_t *args) { mp_buffer_info_t bufinfo; diff --git a/py/stream.h b/py/stream.h index 7b953138c37..03e24c7469c 100644 --- a/py/stream.h +++ b/py/stream.h @@ -70,6 +70,7 @@ typedef struct _mp_stream_p_t { mp_uint_t (*write)(mp_obj_t obj, const void *buf, mp_uint_t size, int *errcode); mp_uint_t (*ioctl)(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *errcode); mp_uint_t is_text : 1; // default is bytes, set this for text stream + bool pyserial_compatibility: 1; // adjust API to match pyserial more closely } mp_stream_p_t; MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_read_obj); @@ -112,6 +113,7 @@ mp_uint_t mp_stream_rw(mp_obj_t stream, void *buf, mp_uint_t size, int *errcode, #define mp_stream_read_exactly(stream, buf, size, err) mp_stream_rw(stream, buf, size, err, MP_STREAM_RW_READ) void mp_stream_write_adaptor(void *self, const char *buf, size_t len); +mp_obj_t mp_stream_flush(mp_obj_t self); #if MICROPY_STREAMS_POSIX_API // Functions with POSIX-compatible signatures diff --git a/py/vm.c b/py/vm.c index 498ecb491d5..b5f53ee9a09 100644 --- a/py/vm.c +++ b/py/vm.c @@ -136,7 +136,7 @@ mp_vm_return_kind_t mp_execute_bytecode(mp_code_state_t *code_state, volatile mp #define ENTRY(op) entry_##op #define ENTRY_DEFAULT entry_default #else - #define DISPATCH() goto dispatch_loop + #define DISPATCH() break #define DISPATCH_WITH_PEND_EXC_CHECK() goto pending_exception_check #define ENTRY(op) case op #define ENTRY_DEFAULT default @@ -252,7 +252,7 @@ run_code_state: ; if (obj_shared == MP_OBJ_NULL) { local_name_error: { MARK_EXC_IP_SELECTIVE(); - mp_obj_t obj = mp_obj_new_exception_msg(&mp_type_NameError, "local variable referenced before assignment"); + mp_obj_t obj = mp_obj_new_exception_msg(&mp_type_NameError, translate("local variable referenced before assignment")); RAISE(obj); } } @@ -1139,7 +1139,7 @@ unwind_jump:; } } if (obj == MP_OBJ_NULL) { - obj = mp_obj_new_exception_msg(&mp_type_RuntimeError, "no active exception to reraise"); + obj = mp_obj_new_exception_msg(&mp_type_RuntimeError, translate("no active exception to reraise")); RAISE(obj); } } else { @@ -1281,7 +1281,7 @@ unwind_jump:; } else #endif { - mp_obj_t obj = mp_obj_new_exception_msg(&mp_type_NotImplementedError, "byte code not implemented"); + mp_obj_t obj = mp_obj_new_exception_msg(&mp_type_NotImplementedError, translate("byte code not implemented")); nlr_pop(); fastn[0] = obj; return MP_VM_RETURN_EXCEPTION; diff --git a/py/vmentrytable.h b/py/vmentrytable.h index 615f4e2ce43..a0e2d406585 100644 --- a/py/vmentrytable.h +++ b/py/vmentrytable.h @@ -24,7 +24,7 @@ * THE SOFTWARE. */ -#if __clang__ +#ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Winitializer-overrides" #endif // __clang__ @@ -113,6 +113,6 @@ static const void *const entry_table[256] = { [MP_BC_BINARY_OP_MULTI ... MP_BC_BINARY_OP_MULTI + MP_BINARY_OP_NUM_BYTECODE - 1] = &&entry_MP_BC_BINARY_OP_MULTI, }; -#if __clang__ +#ifdef __clang__ #pragma clang diagnostic pop #endif // __clang__ diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 00000000000..7cd491adefa --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1 @@ +rst2pyi>=0.3.0 diff --git a/setup.py b/setup.py new file mode 100644 index 00000000000..1e0d81da369 --- /dev/null +++ b/setup.py @@ -0,0 +1,22 @@ +from datetime import datetime +from setuptools import setup +from pathlib import Path + +stub_root = Path("circuitpython-stubs") +stubs = [p.relative_to(stub_root).as_posix() for p in stub_root.glob("*.pyi")] + +now = datetime.utcnow() +version = now.strftime("%Y.%m.%d") + +setup( + name="circuitpython-stubs", + description="PEP 561 type stubs for CircuitPython", + url="https://github.com/adafruit/circuitpython", + maintainer="CircuitPythonistas", + author_email="circuitpython@adafruit.com", + version=version, + license="MIT", + package_data={"circuitpython-stubs": stubs}, + packages=["circuitpython-stubs"], + setup_requires=["setuptools>=38.6.0"], +) diff --git a/shared-bindings/_bleio/Adapter.c b/shared-bindings/_bleio/Adapter.c new file mode 100644 index 00000000000..0caca96b867 --- /dev/null +++ b/shared-bindings/_bleio/Adapter.c @@ -0,0 +1,125 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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 "py/objproperty.h" +#include "shared-bindings/_bleio/Address.h" +#include "shared-bindings/_bleio/Adapter.h" + +//| .. currentmodule:: _bleio +//| +//| :class:`Adapter` --- BLE adapter information +//| ---------------------------------------------------- +//| +//| Get current status of the BLE adapter +//| +//| Usage:: +//| +//| import _bleio +//| _bleio.adapter.enabled = True +//| print(_bleio.adapter.address) +//| + +//| .. class:: Adapter() +//| +//| You cannot create an instance of `_bleio.Adapter`. +//| Use `_bleio.adapter` to access the sole instance available. +//| + +//| .. attribute:: adapter.enabled +//| +//| State of the BLE adapter. +//| +STATIC mp_obj_t bleio_adapter_get_enabled(mp_obj_t self) { + return mp_obj_new_bool(common_hal_bleio_adapter_get_enabled()); +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_enabled_obj, bleio_adapter_get_enabled); + +static mp_obj_t bleio_adapter_set_enabled(mp_obj_t self, mp_obj_t value) { + const bool enabled = mp_obj_is_true(value); + + common_hal_bleio_adapter_set_enabled(enabled); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_adapter_set_enabled_obj, bleio_adapter_set_enabled); + +const mp_obj_property_t bleio_adapter_enabled_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_adapter_get_enabled_obj, + (mp_obj_t)&bleio_adapter_set_enabled_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. attribute:: adapter.address +//| +//| MAC address of the BLE adapter. (read-only) +//| +STATIC mp_obj_t bleio_adapter_get_address(mp_obj_t self) { + return MP_OBJ_FROM_PTR(common_hal_bleio_adapter_get_address()); + +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_address_obj, bleio_adapter_get_address); + +const mp_obj_property_t bleio_adapter_address_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_adapter_get_address_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. attribute:: adapter.default_name +//| +//| default_name of the BLE adapter. (read-only) +//| The name is "CIRCUITPY" + the last four hex digits of ``adapter.address``, +//| to make it easy to distinguish multiple CircuitPython boards. +//| +STATIC mp_obj_t bleio_adapter_get_default_name(mp_obj_t self) { + return common_hal_bleio_adapter_get_default_name(); + +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_default_name_obj, bleio_adapter_get_default_name); + +const mp_obj_property_t bleio_adapter_default_name_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_adapter_get_default_name_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC const mp_rom_map_elem_t bleio_adapter_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_enabled), MP_ROM_PTR(&bleio_adapter_enabled_obj) }, + { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_adapter_address_obj) }, + { MP_ROM_QSTR(MP_QSTR_default_name), MP_ROM_PTR(&bleio_adapter_default_name_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_adapter_locals_dict, bleio_adapter_locals_dict_table); + +const mp_obj_type_t bleio_adapter_type = { + .base = { &mp_type_type }, + .name = MP_QSTR_Adapter, + .locals_dict = (mp_obj_t)&bleio_adapter_locals_dict, +}; diff --git a/shared-bindings/_bleio/Adapter.h b/shared-bindings/_bleio/Adapter.h new file mode 100644 index 00000000000..932fc9c9581 --- /dev/null +++ b/shared-bindings/_bleio/Adapter.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H + +#include "shared-module/_bleio/Address.h" + +const mp_obj_type_t bleio_adapter_type; + +extern bool common_hal_bleio_adapter_get_enabled(void); +extern void common_hal_bleio_adapter_set_enabled(bool enabled); +extern bleio_address_obj_t *common_hal_bleio_adapter_get_address(void); +extern mp_obj_t common_hal_bleio_adapter_get_default_name(void); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H diff --git a/shared-bindings/_bleio/Address.c b/shared-bindings/_bleio/Address.c new file mode 100644 index 00000000000..cdee02b5d74 --- /dev/null +++ b/shared-bindings/_bleio/Address.c @@ -0,0 +1,210 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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 +#include + +#include "py/objproperty.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/_bleio/Address.h" +#include "shared-module/_bleio/Address.h" + +//| .. currentmodule:: _bleio +//| +//| :class:`Address` -- BLE address +//| ========================================================= +//| +//| Encapsulates the address of a BLE device. +//| + +//| .. class:: Address(address, address_type) +//| +//| Create a new Address object encapsulating the address value. +//| The value itself can be one of: +//| +//| :param buf address: The address value to encapsulate. A buffer object (bytearray, bytes) of 6 bytes. +//| :param int address_type: one of the integer values: `PUBLIC`, `RANDOM_STATIC`, +//| `RANDOM_PRIVATE_RESOLVABLE`, or `RANDOM_PRIVATE_NON_RESOLVABLE`. +//| +STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_address, ARG_address_type }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_address, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_address_type, MP_ARG_INT, {.u_int = BLEIO_ADDRESS_TYPE_PUBLIC } }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + bleio_address_obj_t *self = m_new_obj(bleio_address_obj_t); + self->base.type = &bleio_address_type; + + const mp_obj_t address = args[ARG_address].u_obj; + mp_buffer_info_t buf_info; + mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ); + if (buf_info.len != NUM_BLEIO_ADDRESS_BYTES) { + mp_raise_ValueError_varg(translate("Address must be %d bytes long"), NUM_BLEIO_ADDRESS_BYTES); + } + + const mp_int_t address_type = args[ARG_address_type].u_int; + if (address_type < BLEIO_ADDRESS_TYPE_MIN || address_type > BLEIO_ADDRESS_TYPE_MAX) { + mp_raise_ValueError(translate("Address type out of range")); + } + + common_hal_bleio_address_construct(self, buf_info.buf, address_type); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. attribute:: address_bytes +//| +//| The bytes that make up the device address (read-only). +//| +//| Note that the ``bytes`` object returned is in little-endian order: +//| The least significant byte is ``address_bytes[0]``. So the address will +//| appear to be reversed if you print the raw ``bytes`` object. If you print +//| or use `str()` on the :py:class:`~_bleio.Attribute` object itself, the address will be printed +//| in the expected order. For example: +//| +//| .. code-block:: pycon +//| +//| >>> import _bleio +//| >>> _bleio.adapter.address +//|
+//| >>> _bleio.adapter.address.address_bytes +//| b'5\xa8\xed\xf5\x1d\xc8' +//| +STATIC mp_obj_t bleio_address_get_address_bytes(mp_obj_t self_in) { + bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return common_hal_bleio_address_get_address_bytes(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_address_get_address_bytes_obj, bleio_address_get_address_bytes); + +const mp_obj_property_t bleio_address_address_bytes_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_address_get_address_bytes_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: type +//| +//| The address type (read-only). +//| One of the integer values: `PUBLIC`, `RANDOM_STATIC`, +//| `RANDOM_PRIVATE_RESOLVABLE`, or `RANDOM_PRIVATE_NON_RESOLVABLE`. +//| +STATIC mp_obj_t bleio_address_get_type(mp_obj_t self_in) { + bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_address_get_type(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_address_get_type_obj, bleio_address_get_type); + +const mp_obj_property_t bleio_address_type_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_address_get_type_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: __eq__(other) +//| +//| Two Address objects are equal if their addresses and address types are equal. +//| +STATIC mp_obj_t bleio_address_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { + switch (op) { + // Two Addresses are equal if their address bytes and address_type are equal + case MP_BINARY_OP_EQUAL: + if (MP_OBJ_IS_TYPE(rhs_in, &bleio_address_type)) { + bleio_address_obj_t *lhs = MP_OBJ_TO_PTR(lhs_in); + bleio_address_obj_t *rhs = MP_OBJ_TO_PTR(rhs_in); + return mp_obj_new_bool( + mp_obj_equal(common_hal_bleio_address_get_address_bytes(lhs), + common_hal_bleio_address_get_address_bytes(rhs)) && + common_hal_bleio_address_get_type(lhs) == + common_hal_bleio_address_get_type(rhs)); + + } else { + return mp_const_false; + } + + default: + return MP_OBJ_NULL; // op not supported + } +} + +STATIC void bleio_address_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_buffer_info_t buf_info; + mp_obj_t address_bytes = common_hal_bleio_address_get_address_bytes(self); + mp_get_buffer_raise(address_bytes, &buf_info, MP_BUFFER_READ); + + const uint8_t *buf = (uint8_t *) buf_info.buf; + mp_printf(print, "
", + buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]); +} + +//| .. data:: PUBLIC +//| +//| A publicly known address, with a company ID (high 24 bits)and company-assigned part (low 24 bits). +//| +//| .. data:: RANDOM_STATIC +//| +//| A randomly generated address that does not change often. It may never change or may change after +//| a power cycle. +//| +//| .. data:: RANDOM_PRIVATE_RESOLVABLE +//| +//| An address that is usable when the peer knows the other device's secret Identity Resolving Key (IRK). +//| +//| .. data:: RANDOM_PRIVATE_NON_RESOLVABLE +//| +//| A randomly generated address that changes on every connection. +//| +STATIC const mp_rom_map_elem_t bleio_address_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_address_bytes), MP_ROM_PTR(&bleio_address_address_bytes_obj) }, + { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_address_type_obj) }, + // These match the BLE_GAP_ADDR_TYPES values used by the nRF library. + { MP_ROM_QSTR(MP_QSTR_PUBLIC), MP_ROM_INT(0) }, + { MP_ROM_QSTR(MP_QSTR_RANDOM_STATIC), MP_ROM_INT(1) }, + { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_RESOLVABLE), MP_ROM_INT(2) }, + { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE), MP_ROM_INT(3) }, + +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_address_locals_dict, bleio_address_locals_dict_table); + +const mp_obj_type_t bleio_address_type = { + { &mp_type_type }, + .name = MP_QSTR_Address, + .make_new = bleio_address_make_new, + .print = bleio_address_print, + .binary_op = bleio_address_binary_op, + .locals_dict = (mp_obj_dict_t*)&bleio_address_locals_dict +}; diff --git a/shared-bindings/_bleio/Address.h b/shared-bindings/_bleio/Address.h new file mode 100644 index 00000000000..98b6f80e0e1 --- /dev/null +++ b/shared-bindings/_bleio/Address.h @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H + +#include "py/objtype.h" +#include "shared-module/_bleio/Address.h" + +#define BLEIO_ADDRESS_TYPE_PUBLIC (0) +#define BLEIO_ADDRESS_TYPE_RANDOM_STATIC (1) +#define BLEIO_ADDRESS_TYPE_RANDOM_PRIVATE_RESOLVABLE (2) +#define BLEIO_ADDRESS_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE (3) + +#define BLEIO_ADDRESS_TYPE_MIN BLEIO_ADDRESS_TYPE_PUBLIC +#define BLEIO_ADDRESS_TYPE_MAX BLEIO_ADDRESS_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE + +extern const mp_obj_type_t bleio_address_type; + +extern void common_hal_bleio_address_construct(bleio_address_obj_t *self, uint8_t *bytes, uint8_t address_type); +extern mp_obj_t common_hal_bleio_address_get_address_bytes(bleio_address_obj_t *self); +extern uint8_t common_hal_bleio_address_get_type(bleio_address_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H diff --git a/shared-bindings/_bleio/Attribute.c b/shared-bindings/_bleio/Attribute.c new file mode 100644 index 00000000000..2d8b15b9f48 --- /dev/null +++ b/shared-bindings/_bleio/Attribute.c @@ -0,0 +1,94 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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 "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/UUID.h" + +// + +//| .. currentmodule:: _bleio +//| +//| :class:`Attribute` -- BLE Attribute +//| ========================================================= +//| +//| Definitions associated with all BLE attributes: characteristics, descriptors, etc. +//| :py:class:`~_bleio.Attribute` is, notionally, a superclass of +//| :py:class:`~Characteristic` and :py:class:`~Descriptor`, +//| but is not defined as a Python superclass of those classes. +//| +//| .. class:: Attribute() +//| +//| You cannot create an instance of :py:class:`~_bleio.Attribute`. +//| + +STATIC const mp_rom_map_elem_t bleio_attribute_locals_dict_table[] = { + +//| .. data:: NO_ACCESS +//| +//| security mode: access not allowed +//| +//| .. data:: OPEN +//| +//| security_mode: no security (link is not encrypted) +//| +//| .. data:: ENCRYPT_NO_MITM +//| +//| security_mode: unauthenticated encryption, without man-in-the-middle protection +//| +//| .. data:: ENCRYPT_WITH_MITM +//| +//| security_mode: authenticated encryption, with man-in-the-middle protection +//| +//| .. data:: LESC_ENCRYPT_WITH_MITM +//| +//| security_mode: LESC encryption, with man-in-the-middle protection +//| +//| .. data:: SIGNED_NO_MITM +//| +//| security_mode: unauthenticated data signing, without man-in-the-middle protection +//| +//| .. data:: SIGNED_WITH_MITM +//| +//| security_mode: authenticated data signing, without man-in-the-middle protection +//| + { MP_ROM_QSTR(MP_QSTR_NO_ACCESS), MP_ROM_INT(SECURITY_MODE_NO_ACCESS) }, + { MP_ROM_QSTR(MP_QSTR_OPEN), MP_ROM_INT(SECURITY_MODE_OPEN) }, + { MP_ROM_QSTR(MP_QSTR_ENCRYPT_NO_MITM), MP_ROM_INT(SECURITY_MODE_ENC_NO_MITM) }, + { MP_ROM_QSTR(MP_QSTR_ENCRYPT_WITH_MITM), MP_ROM_INT(SECURITY_MODE_ENC_WITH_MITM) }, + { MP_ROM_QSTR(MP_QSTR_LESC_ENCRYPT_WITH_MITM), MP_ROM_INT(SECURITY_MODE_LESC_ENC_WITH_MITM) }, + { MP_ROM_QSTR(MP_QSTR_SIGNED_NO_MITM), MP_ROM_INT(SECURITY_MODE_SIGNED_NO_MITM) }, + { MP_ROM_QSTR(MP_QSTR_SIGNED_WITH_MITM), MP_ROM_INT(SECURITY_MODE_SIGNED_WITH_MITM) }, + +}; +STATIC MP_DEFINE_CONST_DICT(bleio_attribute_locals_dict, bleio_attribute_locals_dict_table); + +const mp_obj_type_t bleio_attribute_type = { + { &mp_type_type }, + .name = MP_QSTR_Attribute, + .locals_dict = (mp_obj_dict_t*)&bleio_attribute_locals_dict, +}; diff --git a/shared-bindings/_bleio/Attribute.h b/shared-bindings/_bleio/Attribute.h new file mode 100644 index 00000000000..a0ce045003a --- /dev/null +++ b/shared-bindings/_bleio/Attribute.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ATTRIBUTE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ATTRIBUTE_H + +#include "py/obj.h" + +#include "common-hal/_bleio/Attribute.h" +#include "shared-module/_bleio/Attribute.h" + +extern const mp_obj_type_t bleio_attribute_type; + +extern void common_hal_bleio_attribute_security_mode_check_valid(bleio_attribute_security_mode_t security_mode); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ATTRIBUTE_H diff --git a/shared-bindings/_bleio/Central.c b/shared-bindings/_bleio/Central.c new file mode 100644 index 00000000000..084f40cd626 --- /dev/null +++ b/shared-bindings/_bleio/Central.c @@ -0,0 +1,207 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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 +#include + +#include "ble_drv.h" +#include "py/objarray.h" +#include "py/objproperty.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/Address.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Central.h" +#include "shared-bindings/_bleio/Service.h" + +//| .. currentmodule:: _bleio +//| +//| :class:`Central` -- A BLE central device +//| ========================================================= +//| +//| Implement a BLE central, which runs locally. Can connect to a given address. +//| +//| Usage:: +//| +//| import _bleio +//| +//| scanner = _bleio.Scanner() +//| entries = scanner.scan(2.5) +//| +//| my_entry = None +//| for entry in entries: +//| if entry.name is not None and entry.name == 'InterestingPeripheral': +//| my_entry = entry +//| break +//| +//| if not my_entry: +//| raise Exception("'InterestingPeripheral' not found") +//| +//| central = _bleio.Central() +//| central.connect(my_entry.address, 10) # timeout after 10 seconds +//| remote_services = central.discover_remote_services() +//| + +//| .. class:: Central() +//| +//| Create a new Central object. +//| +STATIC mp_obj_t bleio_central_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 0, false); + + bleio_central_obj_t *self = m_new_obj(bleio_central_obj_t); + self->base.type = &bleio_central_type; + + common_hal_bleio_central_construct(self); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: connect(address, timeout, *, service_uuids_whitelist=None) +//| Attempts a connection to the remote peripheral. +//| +//| :param Address address: The address of the peripheral to connect to +//| :param float/int timeout: Try to connect for timeout seconds. +//| +STATIC mp_obj_t bleio_central_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + bleio_central_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + + enum { ARG_address, ARG_timeout, ARG_service_uuids_whitelist }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_timeout, MP_ARG_REQUIRED | MP_ARG_OBJ }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + if (!MP_OBJ_IS_TYPE(args[ARG_address].u_obj, &bleio_address_type)) { + mp_raise_ValueError(translate("Expected an Address")); + } + + bleio_address_obj_t *address = MP_OBJ_TO_PTR(args[ARG_address].u_obj); + mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj); + + // common_hal_bleio_central_connect() will validate that services is an iterable or None. + common_hal_bleio_central_connect(self, address, timeout); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_central_connect_obj, 3, bleio_central_connect); + + +//| .. method:: disconnect() +//| +//| Disconnects from the remote peripheral. +//| +STATIC mp_obj_t bleio_central_disconnect(mp_obj_t self_in) { + bleio_central_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_bleio_central_disconnect(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_disconnect_obj, bleio_central_disconnect); + +//| .. method:: discover_remote_services(service_uuids_whitelist=None) +//| Do BLE discovery for all services or for the given service UUIDS, +//| to find their handles and characteristics, and return the discovered services. +//| `Peripheral.connected` must be True. +//| +//| :param iterable service_uuids_whitelist: an iterable of :py:class:~`UUID` objects for the services +//| provided by the peripheral that you want to use. +//| The peripheral may provide more services, but services not listed are ignored +//| and will not be returned. +//| +//| If service_uuids_whitelist is None, then all services will undergo discovery, which can be slow. +//| +//| If the service UUID is 128-bit, or its characteristic UUID's are 128-bit, you +//| you must have already created a :py:class:~`UUID` object for that UUID in order for the +//| service or characteristic to be discovered. Creating the UUID causes the UUID to be registered +//| for use. (This restriction may be lifted in the future.) +//| +//| :return: A tuple of services provided by the remote peripheral. +//| +STATIC mp_obj_t bleio_central_discover_remote_services(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + bleio_central_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + + enum { ARG_service_uuids_whitelist }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_service_uuids_whitelist, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + if (!common_hal_bleio_central_get_connected(self)) { + mp_raise_ValueError(translate("Not connected")); + } + + return MP_OBJ_FROM_PTR(common_hal_bleio_central_discover_remote_services( + MP_OBJ_FROM_PTR(self), + args[ARG_service_uuids_whitelist].u_obj)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_central_discover_remote_services_obj, 1, bleio_central_discover_remote_services); + +//| .. attribute:: connected +//| +//| True if connected to a remove peripheral. +//| +STATIC mp_obj_t bleio_central_get_connected(mp_obj_t self_in) { + bleio_central_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(common_hal_bleio_central_get_connected(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_get_connected_obj, bleio_central_get_connected); + +const mp_obj_property_t bleio_central_connected_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_central_get_connected_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC const mp_rom_map_elem_t bleio_central_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_central_connect_obj) }, + { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_central_disconnect_obj) }, + { MP_ROM_QSTR(MP_QSTR_discover_remote_services), MP_ROM_PTR(&bleio_central_discover_remote_services_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_central_connected_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_central_locals_dict, bleio_central_locals_dict_table); + +const mp_obj_type_t bleio_central_type = { + { &mp_type_type }, + .name = MP_QSTR_Central, + .make_new = bleio_central_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_central_locals_dict +}; diff --git a/shared-bindings/_bleio/Central.h b/shared-bindings/_bleio/Central.h new file mode 100644 index 00000000000..85d788654f4 --- /dev/null +++ b/shared-bindings/_bleio/Central.h @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H + +#include "py/objtuple.h" +#include "common-hal/_bleio/Central.h" +#include "common-hal/_bleio/Service.h" + +extern const mp_obj_type_t bleio_central_type; + +extern void common_hal_bleio_central_construct(bleio_central_obj_t *self); +extern void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout); +extern void common_hal_bleio_central_disconnect(bleio_central_obj_t *self); +extern bool common_hal_bleio_central_get_connected(bleio_central_obj_t *self); +extern mp_obj_tuple_t *common_hal_bleio_central_discover_remote_services(bleio_central_obj_t *self, mp_obj_t service_uuids_whitelist); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H diff --git a/shared-bindings/_bleio/Characteristic.c b/shared-bindings/_bleio/Characteristic.c new file mode 100644 index 00000000000..19815558914 --- /dev/null +++ b/shared-bindings/_bleio/Characteristic.c @@ -0,0 +1,341 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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 "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/_bleio/Attribute.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/UUID.h" + +//| .. currentmodule:: _bleio +//| +//| :class:`Characteristic` -- BLE service characteristic +//| ========================================================= +//| +//| Stores information about a BLE service characteristic and allows reading +//| and writing of the characteristic's value. +//| +//| .. class:: Characteristic +//| +//| There is no regular constructor for a Characteristic. A new local Characteristic can be created +//| and attached to a Service by calling `add_to_service()`. +//| Remote Characteristic objects are created by `Central.discover_remote_services()` +//| or `Peripheral.discover_remote_services()` as part of remote Services. +//| + +//| .. method:: add_to_service(service, uuid, *, properties=0, read_perm=`Attribute.OPEN`, write_perm=`Attribute.OPEN`, max_length=20, fixed_length=False, initial_value=None) +//| +//| Create a new Characteristic object, and add it to this Service. +//| +//| :param Service service: The service that will provide this characteristic +//| :param UUID uuid: The uuid of the characteristic +//| :param int properties: The properties of the characteristic, +//| specified as a bitmask of these values bitwise-or'd together: +//| `BROADCAST`, `INDICATE`, `NOTIFY`, `READ`, `WRITE`, `WRITE_NO_RESPONSE`. +//| :param int read_perm: Specifies whether the characteristic can be read by a client, and if so, which +//| security mode is required. Must be one of the integer values `Attribute.NO_ACCESS`, `Attribute.OPEN`, +//| `Attribute.ENCRYPT_NO_MITM`, `Attribute.ENCRYPT_WITH_MITM`, `Attribute.LESC_ENCRYPT_WITH_MITM`, +//| `Attribute.SIGNED_NO_MITM`, or `Attribute.SIGNED_WITH_MITM`. +//| :param int write_perm: Specifies whether the characteristic can be written by a client, and if so, which +//| security mode is required. Values allowed are the same as ``read_perm``. +//| :param int max_length: Maximum length in bytes of the characteristic value. The maximum allowed is +//| is 512, or possibly 510 if ``fixed_length`` is False. The default, 20, is the maximum +//| number of data bytes that fit in a single BLE 4.x ATT packet. +//| :param bool fixed_length: True if the characteristic value is of fixed length. +//| :param buf initial_value: The initial value for this characteristic. If not given, will be +//| filled with zeros. +//| +//| :return: the new Characteristic. +//| +STATIC mp_obj_t bleio_characteristic_add_to_service(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + // class is arg[0], which we can ignore. + + enum { ARG_service, ARG_uuid, ARG_properties, ARG_read_perm, ARG_write_perm, + ARG_max_length, ARG_fixed_length, ARG_initial_value }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_service, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_properties, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_read_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SECURITY_MODE_OPEN} }, + { MP_QSTR_write_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SECURITY_MODE_OPEN} }, + { MP_QSTR_max_length, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = 20} }, + { MP_QSTR_fixed_length, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_initial_value, MP_ARG_KW_ONLY| MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mp_obj_t service_obj = args[ARG_service].u_obj; + if (!MP_OBJ_IS_TYPE(service_obj, &bleio_service_type)) { + mp_raise_ValueError(translate("Expected a Service")); + } + + const mp_obj_t uuid_obj = args[ARG_uuid].u_obj; + if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) { + mp_raise_ValueError(translate("Expected a UUID")); + } + + const bleio_characteristic_properties_t properties = args[ARG_properties].u_int; + if (properties & ~CHAR_PROP_ALL) { + mp_raise_ValueError(translate("Invalid properties")); + } + + const bleio_attribute_security_mode_t read_perm = args[ARG_read_perm].u_int; + common_hal_bleio_attribute_security_mode_check_valid(read_perm); + + const bleio_attribute_security_mode_t write_perm = args[ARG_write_perm].u_int; + common_hal_bleio_attribute_security_mode_check_valid(write_perm); + + const mp_int_t max_length = args[ARG_max_length].u_int; + const bool fixed_length = args[ARG_fixed_length].u_bool; + mp_obj_t initial_value = args[ARG_initial_value].u_obj; + + // Length will be validated in common_hal. + mp_buffer_info_t initial_value_bufinfo; + if (initial_value == mp_const_none) { + if (fixed_length && max_length > 0) { + initial_value = mp_obj_new_bytes_of_zeros(max_length); + } else { + initial_value = mp_const_empty_bytes; + } + } + mp_get_buffer_raise(initial_value, &initial_value_bufinfo, MP_BUFFER_READ); + + bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t); + characteristic->base.type = &bleio_characteristic_type; + + // Range checking on max_length arg is done by the common_hal layer, because + // it may vary depending on underlying BLE implementation. + common_hal_bleio_characteristic_construct( + characteristic, MP_OBJ_TO_PTR(service_obj), MP_OBJ_TO_PTR(uuid_obj), + properties, read_perm, write_perm, + max_length, fixed_length, &initial_value_bufinfo); + + common_hal_bleio_service_add_characteristic(service_obj, characteristic); + + return MP_OBJ_FROM_PTR(characteristic); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_characteristic_add_to_service_fun_obj, 3, bleio_characteristic_add_to_service); +STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(bleio_characteristic_add_to_service_obj, MP_ROM_PTR(&bleio_characteristic_add_to_service_fun_obj)); + + + +//| .. attribute:: properties +//| +//| An int bitmask representing which properties are set, specified as bitwise or'ing of +//| of these possible values. +//| `BROADCAST`, `INDICATE`, `NOTIFY`, `READ`, `WRITE`, `WRITE_NO_RESPONSE`. +//| +STATIC mp_obj_t bleio_characteristic_get_properties(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_characteristic_get_properties(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_properties_obj, bleio_characteristic_get_properties); + +const mp_obj_property_t bleio_characteristic_properties_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_properties_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. attribute:: uuid +//| +//| The UUID of this characteristic. (read-only) +//| Will be ``None`` if the 128-bit UUID for this characteristic is not known. +//| +STATIC mp_obj_t bleio_characteristic_get_uuid(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + bleio_uuid_obj_t *uuid = common_hal_bleio_characteristic_get_uuid(self); + return uuid ? MP_OBJ_FROM_PTR(uuid) : mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_uuid_obj, bleio_characteristic_get_uuid); + +const mp_obj_property_t bleio_characteristic_uuid_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_uuid_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. attribute:: value +//| +//| The value of this characteristic. +//| +STATIC mp_obj_t bleio_characteristic_get_value(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return common_hal_bleio_characteristic_get_value(self); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_value_obj, bleio_characteristic_get_value); + +STATIC mp_obj_t bleio_characteristic_set_value(mp_obj_t self_in, mp_obj_t value_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(value_in, &bufinfo, MP_BUFFER_READ); + + common_hal_bleio_characteristic_set_value(self, &bufinfo); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_value_obj, bleio_characteristic_set_value); + +const mp_obj_property_t bleio_characteristic_value_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_value_obj, + (mp_obj_t)&bleio_characteristic_set_value_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. attribute:: descriptors +//| +//| A tuple of :py:class:`Descriptor` that describe this characteristic. (read-only) +//| +STATIC mp_obj_t bleio_characteristic_get_descriptors(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + // Return list as a tuple so user won't be able to change it. + mp_obj_list_t *char_list = common_hal_bleio_characteristic_get_descriptor_list(self); + return mp_obj_new_tuple(char_list->len, char_list->items); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_descriptors_obj, bleio_characteristic_get_descriptors); + +const mp_obj_property_t bleio_characteristic_descriptors_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_descriptors_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. attribute:: service (read-only) +//| +//| The Service this Characteristic is a part of. +//| +STATIC mp_obj_t bleio_characteristic_get_service(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return common_hal_bleio_characteristic_get_service(self); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_service_obj, bleio_characteristic_get_service); + +const mp_obj_property_t bleio_characteristic_service_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_service_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. method:: set_cccd(*, notify=False, indicate=False) +//| +//| Set the remote characteristic's CCCD to enable or disable notification and indication. +//| +//| :param bool notify: True if Characteristic should receive notifications of remote writes +//| :param float indicate: True if Characteristic should receive indications of remote writes +//| +STATIC mp_obj_t bleio_characteristic_set_cccd(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + + enum { ARG_notify, ARG_indicate }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_notify, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_indicate, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + common_hal_bleio_characteristic_set_cccd(self, args[ARG_notify].u_bool, args[ARG_indicate].u_bool); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_characteristic_set_cccd_obj, 1, bleio_characteristic_set_cccd); + + +STATIC const mp_rom_map_elem_t bleio_characteristic_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_add_to_service), MP_ROM_PTR(&bleio_characteristic_add_to_service_obj) }, + { MP_ROM_QSTR(MP_QSTR_properties), MP_ROM_PTR(&bleio_characteristic_get_properties_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_characteristic_uuid_obj) }, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&bleio_characteristic_value_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_cccd), MP_ROM_PTR(&bleio_characteristic_set_cccd_obj) }, + + // Bitmask constants to represent properties +//| .. data:: BROADCAST +//| +//| property: allowed in advertising packets +//| +//| .. data:: INDICATE +//| +//| property: server will indicate to the client when the value is set and wait for a response +//| +//| .. data:: NOTIFY +//| +//| property: server will notify the client when the value is set +//| +//| .. data:: READ +//| +//| property: clients may read this characteristic +//| +//| .. data:: WRITE +//| +//| property: clients may write this characteristic; a response will be sent back +//| +//| .. data:: WRITE_NO_RESPONSE +//| +//| property: clients may write this characteristic; no response will be sent back +//| + { MP_ROM_QSTR(MP_QSTR_BROADCAST), MP_ROM_INT(CHAR_PROP_BROADCAST) }, + { MP_ROM_QSTR(MP_QSTR_INDICATE), MP_ROM_INT(CHAR_PROP_INDICATE) }, + { MP_ROM_QSTR(MP_QSTR_NOTIFY), MP_ROM_INT(CHAR_PROP_NOTIFY) }, + { MP_ROM_QSTR(MP_QSTR_READ), MP_ROM_INT(CHAR_PROP_READ) }, + { MP_ROM_QSTR(MP_QSTR_WRITE), MP_ROM_INT(CHAR_PROP_WRITE) }, + { MP_ROM_QSTR(MP_QSTR_WRITE_NO_RESPONSE), MP_ROM_INT(CHAR_PROP_WRITE_NO_RESPONSE) }, + +}; +STATIC MP_DEFINE_CONST_DICT(bleio_characteristic_locals_dict, bleio_characteristic_locals_dict_table); + +STATIC void bleio_characteristic_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->uuid) { + mp_printf(print, "Characteristic("); + bleio_uuid_print(print, MP_OBJ_FROM_PTR(self->uuid), kind); + mp_printf(print, ")"); + } else { + mp_printf(print, ""); + } +} + +const mp_obj_type_t bleio_characteristic_type = { + { &mp_type_type }, + .name = MP_QSTR_Characteristic, + .print = bleio_characteristic_print, + .locals_dict = (mp_obj_dict_t*)&bleio_characteristic_locals_dict, +}; diff --git a/shared-bindings/_bleio/Characteristic.h b/shared-bindings/_bleio/Characteristic.h new file mode 100644 index 00000000000..a816c605063 --- /dev/null +++ b/shared-bindings/_bleio/Characteristic.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H + +#include "shared-bindings/_bleio/Attribute.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-module/_bleio/Characteristic.h" +#include "common-hal/_bleio/Characteristic.h" +#include "common-hal/_bleio/Service.h" + +extern const mp_obj_type_t bleio_characteristic_type; + +extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo); +extern mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self); +extern void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo); +extern bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties(bleio_characteristic_obj_t *self); +extern bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self); +extern mp_obj_list_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self); +extern bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_characteristic_obj_t *self); +extern void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *self, bleio_descriptor_obj_t *descriptor); +extern void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H diff --git a/shared-bindings/_bleio/CharacteristicBuffer.c b/shared-bindings/_bleio/CharacteristicBuffer.c new file mode 100644 index 00000000000..9cc708eb78f --- /dev/null +++ b/shared-bindings/_bleio/CharacteristicBuffer.c @@ -0,0 +1,252 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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 "py/mperrno.h" +#include "py/ioctl.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/stream.h" + +#include "shared-bindings/_bleio/CharacteristicBuffer.h" +#include "shared-bindings/_bleio/UUID.h" +#include "shared-bindings/util.h" + +STATIC void raise_error_if_not_connected(bleio_characteristic_buffer_obj_t *self) { + if (!common_hal_bleio_characteristic_buffer_connected(self)) { + mp_raise_ValueError(translate("Not connected")); + } +} + +//| .. currentmodule:: _bleio +//| +//| :class:`CharacteristicBuffer` -- BLE Service incoming values buffer. +//| ===================================================================== +//| +//| Accumulates a Characteristic's incoming values in a FIFO buffer. +//| +//| .. class:: CharacteristicBuffer(characteristic, *, timeout=1, buffer_size=64) +//| +//| Monitor the given Characteristic. Each time a new value is written to the Characteristic +//| add the newly-written bytes to a FIFO buffer. +//| +//| :param Characteristic characteristic: The Characteristic to monitor. +//| It may be a local Characteristic provided by a Peripheral Service, or a remote Characteristic +//| in a remote Service that a Central has connected to. +//| :param int timeout: the timeout in seconds to wait for the first character and between subsequent characters. +//| :param int buffer_size: Size of ring buffer that stores incoming data coming from client. +//| Must be >= 1. +//| +STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_characteristic, ARG_timeout, ARG_buffer_size, }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_characteristic, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, + { MP_QSTR_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mp_obj_t characteristic = args[ARG_characteristic].u_obj; + + mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj); + if (timeout < 0.0f) { + mp_raise_ValueError(translate("timeout must be >= 0.0")); + } + + const int buffer_size = args[ARG_buffer_size].u_int; + if (buffer_size < 1) { + mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_buffer_size); + } + + if (!MP_OBJ_IS_TYPE(characteristic, &bleio_characteristic_type)) { + mp_raise_ValueError(translate("Expected a Characteristic")); + } + + bleio_characteristic_buffer_obj_t *self = m_new_obj(bleio_characteristic_buffer_obj_t); + self->base.type = &bleio_characteristic_buffer_type; + + common_hal_bleio_characteristic_buffer_construct(self, MP_OBJ_TO_PTR(characteristic), timeout, buffer_size); + + return MP_OBJ_FROM_PTR(self); +} + +STATIC void check_for_deinit(bleio_characteristic_buffer_obj_t *self) { + if (common_hal_bleio_characteristic_buffer_deinited(self)) { + raise_deinited_error(); + } +} + +// These are standard stream methods. Code is in py/stream.c. +// +//| .. method:: read(nbytes=None) +//| +//| Read characters. If ``nbytes`` is specified then read at most that many +//| bytes. Otherwise, read everything that arrives until the connection +//| times out. Providing the number of bytes expected is highly recommended +//| because it will be faster. +//| +//| :return: Data read +//| :rtype: bytes or None +//| +//| .. method:: readinto(buf) +//| +//| Read bytes into the ``buf``. Read at most ``len(buf)`` bytes. +//| +//| :return: number of bytes read and stored into ``buf`` +//| :rtype: int or None (on a non-blocking error) +//| +//| .. method:: readline() +//| +//| Read a line, ending in a newline character. +//| +//| :return: the line read +//| :rtype: int or None +//| + +// These three methods are used by the shared stream methods. +STATIC mp_uint_t bleio_characteristic_buffer_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { + bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + raise_error_if_not_connected(self); + byte *buf = buf_in; + + // make sure we want at least 1 char + if (size == 0) { + return 0; + } + + return common_hal_bleio_characteristic_buffer_read(self, buf, size, errcode); +} + +STATIC mp_uint_t bleio_characteristic_buffer_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { + mp_raise_NotImplementedError(translate("CharacteristicBuffer writing not provided")); + return 0; +} + +STATIC mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { + bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + raise_error_if_not_connected(self); + if (!common_hal_bleio_characteristic_buffer_connected(self)) { + mp_raise_ValueError(translate("Not connected")); + } + mp_uint_t ret; + if (request == MP_IOCTL_POLL) { + mp_uint_t flags = arg; + ret = 0; + if ((flags & MP_IOCTL_POLL_RD) && common_hal_bleio_characteristic_buffer_rx_characters_available(self) > 0) { + ret |= MP_IOCTL_POLL_RD; + } +// No writing provided. +// if ((flags & MP_IOCTL_POLL_WR) && common_hal_busio_uart_ready_to_tx(self)) { +// ret |= MP_IOCTL_POLL_WR; +// } + } else { + *errcode = MP_EINVAL; + ret = MP_STREAM_ERROR; + } + return ret; +} + +//| .. attribute:: in_waiting +//| +//| The number of bytes in the input buffer, available to be read +//| +STATIC mp_obj_t bleio_characteristic_buffer_obj_get_in_waiting(mp_obj_t self_in) { + bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_characteristic_buffer_rx_characters_available(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_buffer_get_in_waiting_obj, bleio_characteristic_buffer_obj_get_in_waiting); + +const mp_obj_property_t bleio_characteristic_buffer_in_waiting_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_characteristic_buffer_get_in_waiting_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: reset_input_buffer() +//| +//| Discard any unread characters in the input buffer. +//| +STATIC mp_obj_t bleio_characteristic_buffer_obj_reset_input_buffer(mp_obj_t self_in) { + bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_bleio_characteristic_buffer_clear_rx_buffer(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_buffer_reset_input_buffer_obj, bleio_characteristic_buffer_obj_reset_input_buffer); + +//| .. method:: deinit() +//| +//| Disable permanently. +//| +STATIC mp_obj_t bleio_characteristic_buffer_deinit(mp_obj_t self_in) { + bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_bleio_characteristic_buffer_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_buffer_deinit_obj, bleio_characteristic_buffer_deinit); + +STATIC const mp_rom_map_elem_t bleio_characteristic_buffer_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bleio_characteristic_buffer_deinit_obj) }, + + // Standard stream methods. + { MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + // CharacteristicBuffer is currently read-only. + // { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_reset_input_buffer), MP_ROM_PTR(&bleio_characteristic_buffer_reset_input_buffer_obj) }, + // Properties + { MP_ROM_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&bleio_characteristic_buffer_in_waiting_obj) }, + +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_characteristic_buffer_locals_dict, bleio_characteristic_buffer_locals_dict_table); + +STATIC const mp_stream_p_t characteristic_buffer_stream_p = { + .read = bleio_characteristic_buffer_read, + .write = bleio_characteristic_buffer_write, + .ioctl = bleio_characteristic_buffer_ioctl, + .is_text = false, + // Match PySerial when possible, such as disallowing optional length argument for .readinto() + .pyserial_compatibility = true, +}; + + +const mp_obj_type_t bleio_characteristic_buffer_type = { + { &mp_type_type }, + .name = MP_QSTR_CharacteristicBuffer, + .make_new = bleio_characteristic_buffer_make_new, + .getiter = mp_identity_getiter, + .iternext = mp_stream_unbuffered_iter, + .protocol = &characteristic_buffer_stream_p, + .locals_dict = (mp_obj_dict_t*)&bleio_characteristic_buffer_locals_dict +}; diff --git a/shared-bindings/_bleio/CharacteristicBuffer.h b/shared-bindings/_bleio/CharacteristicBuffer.h new file mode 100644 index 00000000000..83e6fef02f7 --- /dev/null +++ b/shared-bindings/_bleio/CharacteristicBuffer.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTICBUFFER_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTICBUFFER_H + +#include "common-hal/_bleio/CharacteristicBuffer.h" + +extern const mp_obj_type_t bleio_characteristic_buffer_type; + +extern void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, mp_float_t timeout, size_t buffer_size); +int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode); +uint32_t common_hal_bleio_characteristic_buffer_rx_characters_available(bleio_characteristic_buffer_obj_t *self); +void common_hal_bleio_characteristic_buffer_clear_rx_buffer(bleio_characteristic_buffer_obj_t *self); +bool common_hal_bleio_characteristic_buffer_deinited(bleio_characteristic_buffer_obj_t *self); +int common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_obj_t *self); +bool common_hal_bleio_characteristic_buffer_connected(bleio_characteristic_buffer_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTICBUFFER_H diff --git a/shared-bindings/_bleio/Descriptor.c b/shared-bindings/_bleio/Descriptor.c new file mode 100644 index 00000000000..0ab9fe8e9e8 --- /dev/null +++ b/shared-bindings/_bleio/Descriptor.c @@ -0,0 +1,231 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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 "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/_bleio/Attribute.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/UUID.h" + +//| .. currentmodule:: _bleio +//| +//| :class:`Descriptor` -- BLE descriptor +//| ========================================================= +//| +//| Stores information about a BLE descriptor. +//| Descriptors are attached to BLE characteristics and provide contextual +//| information about the characteristic. +//| +//| .. class:: Descriptor +//| +//| There is no regular constructor for a Descriptor. A new local Descriptor can be created +//| and attached to a Characteristic by calling `add_to_characteristic()`. +//| Remote Descriptor objects are created by `Central.discover_remote_services()` +//| or `Peripheral.discover_remote_services()` as part of remote Characteristics +//| in the remote Services that are discovered. +//| +//| .. classmethod:: add_to_characteristic(characteristic, uuid, *, read_perm=`Attribute.OPEN`, write_perm=`Attribute.OPEN`, max_length=20, fixed_length=False, initial_value=b'') +//| +//| Create a new Descriptor object, and add it to this Service. +//| +//| :param Characteristic characteristic: The characteristic that will hold this descriptor +//| :param UUID uuid: The uuid of the descriptor +//| :param int read_perm: Specifies whether the descriptor can be read by a client, and if so, which +//| security mode is required. Must be one of the integer values `Attribute.NO_ACCESS`, `Attribute.OPEN`, +//| `Attribute.ENCRYPT_NO_MITM`, `Attribute.ENCRYPT_WITH_MITM`, `Attribute.LESC_ENCRYPT_WITH_MITM`, +//| `Attribute.SIGNED_NO_MITM`, or `Attribute.SIGNED_WITH_MITM`. +//| :param int write_perm: Specifies whether the descriptor can be written by a client, and if so, which +//| security mode is required. Values allowed are the same as ``read_perm``. +//| :param int max_length: Maximum length in bytes of the descriptor value. The maximum allowed is +//| is 512, or possibly 510 if ``fixed_length`` is False. The default, 20, is the maximum +//| number of data bytes that fit in a single BLE 4.x ATT packet. +//| :param bool fixed_length: True if the descriptor value is of fixed length. +//| :param buf initial_value: The initial value for this descriptor. +//| +//| :return: the new Descriptor. +//| +STATIC mp_obj_t bleio_descriptor_add_to_characteristic(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + // class is arg[0], which we can ignore. + + enum { ARG_characteristic, ARG_uuid, ARG_read_perm, ARG_write_perm, + ARG_max_length, ARG_fixed_length, ARG_initial_value }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_characteristic, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_read_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SECURITY_MODE_OPEN} }, + { MP_QSTR_write_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SECURITY_MODE_OPEN} }, + { MP_QSTR_max_length, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = 20} }, + { MP_QSTR_fixed_length, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_initial_value, MP_ARG_KW_ONLY| MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mp_obj_t characteristic_obj = args[ARG_characteristic].u_obj; + if (!MP_OBJ_IS_TYPE(characteristic_obj, &bleio_characteristic_type)) { + mp_raise_ValueError(translate("Expected a Characteristic")); + } + + const mp_obj_t uuid_obj = args[ARG_uuid].u_obj; + if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) { + mp_raise_ValueError(translate("Expected a UUID")); + } + + const bleio_attribute_security_mode_t read_perm = args[ARG_read_perm].u_int; + common_hal_bleio_attribute_security_mode_check_valid(read_perm); + + const bleio_attribute_security_mode_t write_perm = args[ARG_write_perm].u_int; + common_hal_bleio_attribute_security_mode_check_valid(write_perm); + + const mp_int_t max_length = args[ARG_max_length].u_int; + const bool fixed_length = args[ARG_fixed_length].u_bool; + mp_obj_t initial_value = args[ARG_initial_value].u_obj; + + // Length will be validated in common_hal. + mp_buffer_info_t initial_value_bufinfo; + if (initial_value == mp_const_none) { + if (fixed_length && max_length > 0) { + initial_value = mp_obj_new_bytes_of_zeros(max_length); + } else { + initial_value = mp_const_empty_bytes; + } + } + mp_get_buffer_raise(initial_value, &initial_value_bufinfo, MP_BUFFER_READ); + + bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t); + descriptor->base.type = &bleio_descriptor_type; + + // Range checking on max_length arg is done by the common_hal layer, because + // it may vary depending on underlying BLE implementation. + common_hal_bleio_descriptor_construct( + descriptor, MP_OBJ_TO_PTR(characteristic_obj), MP_OBJ_TO_PTR(uuid_obj), + read_perm, write_perm, + max_length, fixed_length, &initial_value_bufinfo); + + common_hal_bleio_characteristic_add_descriptor(characteristic_obj, descriptor); + + return MP_OBJ_FROM_PTR(descriptor); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_descriptor_add_to_characteristic_fun_obj, 3, bleio_descriptor_add_to_characteristic); +STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(bleio_descriptor_add_to_characteristic_obj, MP_ROM_PTR(&bleio_descriptor_add_to_characteristic_fun_obj)); + +//| .. attribute:: uuid +//| +//| The descriptor uuid. (read-only) +//| +STATIC mp_obj_t bleio_descriptor_get_uuid(mp_obj_t self_in) { + bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); + + bleio_uuid_obj_t *uuid = common_hal_bleio_descriptor_get_uuid(self); + return uuid ? MP_OBJ_FROM_PTR(uuid) : mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_uuid_obj, bleio_descriptor_get_uuid); + +const mp_obj_property_t bleio_descriptor_uuid_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_descriptor_get_uuid_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: characteristic (read-only) +//| +//| The Characteristic this Descriptor is a part of. +//| +STATIC mp_obj_t bleio_descriptor_get_characteristic(mp_obj_t self_in) { + bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return common_hal_bleio_descriptor_get_characteristic(self); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_characteristic_obj, bleio_descriptor_get_characteristic); + +const mp_obj_property_t bleio_descriptor_characteristic_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_descriptor_get_characteristic_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. attribute:: value +//| +//| The value of this descriptor. +//| +STATIC mp_obj_t bleio_descriptor_get_value(mp_obj_t self_in) { + bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return common_hal_bleio_descriptor_get_value(self); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_value_obj, bleio_descriptor_get_value); + +STATIC mp_obj_t bleio_descriptor_set_value(mp_obj_t self_in, mp_obj_t value_in) { + bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(value_in, &bufinfo, MP_BUFFER_READ); + + common_hal_bleio_descriptor_set_value(self, &bufinfo); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_descriptor_set_value_obj, bleio_descriptor_set_value); + +const mp_obj_property_t bleio_descriptor_value_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_descriptor_get_value_obj, + (mp_obj_t)&bleio_descriptor_set_value_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC const mp_rom_map_elem_t bleio_descriptor_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_add_to_characteristic), MP_ROM_PTR(&bleio_descriptor_add_to_characteristic_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_descriptor_uuid_obj) }, + { MP_ROM_QSTR(MP_QSTR_characteristic), MP_ROM_PTR(&bleio_descriptor_characteristic_obj) }, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&bleio_descriptor_value_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_descriptor_locals_dict, bleio_descriptor_locals_dict_table); + +STATIC void bleio_descriptor_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->uuid) { + mp_printf(print, "Descriptor("); + bleio_uuid_print(print, MP_OBJ_FROM_PTR(self->uuid), kind); + mp_printf(print, ")"); + } else { + mp_printf(print, ""); + } +} + +const mp_obj_type_t bleio_descriptor_type = { + { &mp_type_type }, + .name = MP_QSTR_Descriptor, + .print = bleio_descriptor_print, + .locals_dict = (mp_obj_dict_t*)&bleio_descriptor_locals_dict +}; diff --git a/shared-bindings/_bleio/Descriptor.h b/shared-bindings/_bleio/Descriptor.h new file mode 100644 index 00000000000..7544bdb17b4 --- /dev/null +++ b/shared-bindings/_bleio/Descriptor.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H + +#include "shared-module/_bleio/Attribute.h" +#include "common-hal/_bleio/Characteristic.h" +#include "common-hal/_bleio/Descriptor.h" +#include "common-hal/_bleio/UUID.h" + +extern const mp_obj_type_t bleio_descriptor_type; + +extern void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_characteristic_obj_t *characteristic, bleio_uuid_obj_t *uuid, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo); +extern bleio_uuid_obj_t *common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self); +extern bleio_characteristic_obj_t *common_hal_bleio_descriptor_get_characteristic(bleio_descriptor_obj_t *self); +extern mp_obj_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self); +extern void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buffer_info_t *bufinfo); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H diff --git a/shared-bindings/_bleio/Peripheral.c b/shared-bindings/_bleio/Peripheral.c new file mode 100644 index 00000000000..0bf29274423 --- /dev/null +++ b/shared-bindings/_bleio/Peripheral.c @@ -0,0 +1,325 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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 +#include + +#include "ble_drv.h" +#include "py/objarray.h" +#include "py/objproperty.h" +#include "py/objstr.h" +#include "py/runtime.h" + +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Peripheral.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/UUID.h" +#include "shared-module/_bleio/ScanEntry.h" + +#include "common-hal/_bleio/Peripheral.h" + +#define ADV_INTERVAL_MIN (0.0020f) +#define ADV_INTERVAL_MIN_STRING "0.0020" +#define ADV_INTERVAL_MAX (10.24f) +#define ADV_INTERVAL_MAX_STRING "10.24" +// 20ms is recommended by Apple +#define ADV_INTERVAL_DEFAULT (0.1f) + +//| .. currentmodule:: _bleio +//| +//| :class:`Peripheral` -- A BLE peripheral device +//| ========================================================= +//| +//| Implement a BLE peripheral which runs locally. +//| Set up using the supplied services, and then allow advertising to be started and stopped. +//| +//| Usage:: +//| +//| from _bleio import Characteristic, Peripheral, Service +//| from adafruit_ble.advertising import ServerAdvertisement +//| +//| # Create a peripheral and start it up. +//| peripheral = _bleio.Peripheral() +//| +//| # Create a Service and add it to this Peripheral. +//| service = Service.add_to_peripheral(peripheral, _bleio.UUID(0x180f)) +//| +//| # Create a Characteristic and add it to the Service. +//| characteristic = Characteristic.add_to_service(service, +//| _bleio.UUID(0x2919), properties=Characteristic.READ | Characteristic.NOTIFY) +//| +//| adv = ServerAdvertisement(peripheral) +//| peripheral.start_advertising(adv.advertising_data_bytes, scan_response=adv.scan_response_bytes) +//| +//| while not peripheral.connected: +//| # Wait for connection. +//| pass +//| +//| .. class:: Peripheral(name=None) +//| +//| Create a new Peripheral object. +//| +//| :param str name: The name used when advertising this peripheral. If name is None, +//| _bleio.adapter.default_name will be used. +//| +STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_name }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_name, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + bleio_peripheral_obj_t *self = m_new_obj(bleio_peripheral_obj_t); + self->base.type = &bleio_peripheral_type; + + mp_obj_t name = args[ARG_name].u_obj; + if (name == mp_const_none) { + name = common_hal_bleio_adapter_get_default_name(); + } else if (!MP_OBJ_IS_STR(name)) { + mp_raise_ValueError(translate("name must be a string")); + } + + common_hal_bleio_peripheral_construct(self, name); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. attribute:: connected (read-only) +//| +//| True if connected to a BLE Central device. +//| +STATIC mp_obj_t bleio_peripheral_get_connected(mp_obj_t self_in) { + bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(common_hal_bleio_peripheral_get_connected(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_connected_obj, bleio_peripheral_get_connected); + +const mp_obj_property_t bleio_peripheral_connected_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_peripheral_get_connected_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. attribute:: services +//| +//| A tuple of :py:class:`Service` objects offered by this peripheral. (read-only) +//| +STATIC mp_obj_t bleio_peripheral_get_services(mp_obj_t self_in) { + bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); + // Return list as a tuple so user won't be able to change it. + mp_obj_list_t *services_list = common_hal_bleio_peripheral_get_services(self); + return mp_obj_new_tuple(services_list->len, services_list->items); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_services_obj, bleio_peripheral_get_services); + +const mp_obj_property_t bleio_peripheral_services_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_peripheral_get_services_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. attribute:: name +//| +//| The peripheral's name, included when advertising. (read-only) +//| +STATIC mp_obj_t bleio_peripheral_get_name(mp_obj_t self_in) { + bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return common_hal_bleio_peripheral_get_name(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_name_obj, bleio_peripheral_get_name); + +const mp_obj_property_t bleio_peripheral_name_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_peripheral_get_name_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. method:: start_advertising(data, *, scan_response=None, connectable=True, interval=0.1) +//| +//| Starts advertising the peripheral. The peripheral's name and +//| services are included in the advertisement packets. +//| +//| :param buf data: advertising data packet bytes +//| :param buf scan_response: scan response data packet bytes. ``None`` if no scan response is needed. +//| :param bool connectable: If `True` then other devices are allowed to connect to this peripheral. +//| :param float interval: advertising interval, in seconds +//| +STATIC mp_obj_t bleio_peripheral_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + + enum { ARG_data, ARG_scan_response, ARG_connectable, ARG_interval }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_scan_response, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, + { MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t data_bufinfo; + mp_get_buffer_raise(args[ARG_data].u_obj, &data_bufinfo, MP_BUFFER_READ); + + // Pass an empty buffer if scan_response not provided. + mp_buffer_info_t scan_response_bufinfo = { 0 }; + if (args[ARG_scan_response].u_obj != mp_const_none) { + mp_get_buffer_raise(args[ARG_scan_response].u_obj, &scan_response_bufinfo, MP_BUFFER_READ); + } + + if (args[ARG_interval].u_obj == MP_OBJ_NULL) { + args[ARG_interval].u_obj = mp_obj_new_float(ADV_INTERVAL_DEFAULT); + } + + const mp_float_t interval = mp_obj_float_get(args[ARG_interval].u_obj); + if (interval < ADV_INTERVAL_MIN || interval > ADV_INTERVAL_MAX) { + mp_raise_ValueError_varg(translate("interval must be in range %s-%s"), + ADV_INTERVAL_MIN_STRING, ADV_INTERVAL_MAX_STRING); + } + + common_hal_bleio_peripheral_start_advertising(self, args[ARG_connectable].u_bool, interval, + &data_bufinfo, &scan_response_bufinfo); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_peripheral_start_advertising_obj, 2, bleio_peripheral_start_advertising); + +//| .. method:: stop_advertising() +//| +//| Stop sending advertising packets. +STATIC mp_obj_t bleio_peripheral_stop_advertising(mp_obj_t self_in) { + bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_bleio_peripheral_stop_advertising(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_stop_advertising_obj, bleio_peripheral_stop_advertising); + +//| .. method:: disconnect() +//| +//| Disconnects from the remote central. +//| Normally the central initiates a disconnection. Use this only +//| if necessary for your application. +//| +STATIC mp_obj_t bleio_peripheral_disconnect(mp_obj_t self_in) { + bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_bleio_peripheral_disconnect(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_disconnect_obj, bleio_peripheral_disconnect); + +//| .. method:: discover_remote_services(service_uuids_whitelist=None) +//| Do BLE discovery for all services or for the given service UUIDS, +//| to find their handles and characteristics, and return the discovered services. +//| `Peripheral.connected` must be True. +//| +//| :param iterable service_uuids_whitelist: an iterable of :py:class:~`UUID` objects for the services +//| provided by the peripheral that you want to use. +//| The peripheral may provide more services, but services not listed are ignored +//| and will not be returned. +//| +//| If service_uuids_whitelist is None, then all services will undergo discovery, which can be slow. +//| +//| If the service UUID is 128-bit, or its characteristic UUID's are 128-bit, you +//| you must have already created a :py:class:~`UUID` object for that UUID in order for the +//| service or characteristic to be discovered. Creating the UUID causes the UUID to be registered +//| for use. (This restriction may be lifted in the future.) +//| +//| Thought it is unusual for a peripheral to act as a BLE client, it can do so, and +//| needs to be able to do discovery on its peer (a central). +//| Examples include a peripheral accessing a central that provides Current Time Service, +//| Apple Notification Center Service, or Battery Service. +//| +//| :return: A tuple of services provided by the remote central. +//| +STATIC mp_obj_t bleio_peripheral_discover_remote_services(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + + enum { ARG_service_uuids_whitelist }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_service_uuids_whitelist, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + if (!common_hal_bleio_peripheral_get_connected(self)) { + mp_raise_ValueError(translate("Not connected")); + } + + return MP_OBJ_FROM_PTR(common_hal_bleio_peripheral_discover_remote_services( + MP_OBJ_FROM_PTR(self), + args[ARG_service_uuids_whitelist].u_obj)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_peripheral_discover_remote_services_obj, 1, bleio_peripheral_discover_remote_services); + +//| .. method:: pair() +//| +//| Request pairing with connected central. +STATIC mp_obj_t bleio_peripheral_pair(mp_obj_t self_in) { + bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_bleio_peripheral_pair(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_pair_obj, bleio_peripheral_pair); + +STATIC const mp_rom_map_elem_t bleio_peripheral_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_peripheral_start_advertising_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_peripheral_stop_advertising_obj) }, + { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_peripheral_disconnect_obj) }, + { MP_ROM_QSTR(MP_QSTR_discover_remote_services), MP_ROM_PTR(&bleio_peripheral_discover_remote_services_obj) }, + { MP_ROM_QSTR(MP_QSTR_pair), MP_ROM_PTR(&bleio_peripheral_pair_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_peripheral_connected_obj) }, + { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_peripheral_name_obj) }, + { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_peripheral_services_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_peripheral_locals_dict, bleio_peripheral_locals_dict_table); + +const mp_obj_type_t bleio_peripheral_type = { + { &mp_type_type }, + .name = MP_QSTR_Peripheral, + .make_new = bleio_peripheral_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_peripheral_locals_dict +}; diff --git a/shared-bindings/_bleio/Peripheral.h b/shared-bindings/_bleio/Peripheral.h new file mode 100644 index 00000000000..bc56a933896 --- /dev/null +++ b/shared-bindings/_bleio/Peripheral.h @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H + +#include "py/objtuple.h" +#include "common-hal/_bleio/Peripheral.h" +#include "common-hal/_bleio/Service.h" + +extern const mp_obj_type_t bleio_peripheral_type; + +extern void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_t name); +extern void common_hal_bleio_peripheral_add_service(bleio_peripheral_obj_t *self, bleio_service_obj_t *service); +extern mp_obj_list_t *common_hal_bleio_peripheral_get_services(bleio_peripheral_obj_t *self); +extern bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self); +extern mp_obj_t common_hal_bleio_peripheral_get_name(bleio_peripheral_obj_t *self); +extern void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *device, bool connectable, float interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo); +extern void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *device); +extern void common_hal_bleio_peripheral_disconnect(bleio_peripheral_obj_t *device); +extern mp_obj_tuple_t *common_hal_bleio_peripheral_discover_remote_services(bleio_peripheral_obj_t *self, mp_obj_t service_uuids_whitelist); +extern void common_hal_bleio_peripheral_pair(bleio_peripheral_obj_t *device); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H diff --git a/shared-bindings/_bleio/ScanEntry.c b/shared-bindings/_bleio/ScanEntry.c new file mode 100644 index 00000000000..bec380d03f1 --- /dev/null +++ b/shared-bindings/_bleio/ScanEntry.c @@ -0,0 +1,111 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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 + +#include "py/objproperty.h" +#include "shared-bindings/_bleio/Address.h" +#include "shared-bindings/_bleio/ScanEntry.h" +#include "shared-bindings/_bleio/UUID.h" +#include "shared-module/_bleio/ScanEntry.h" + +//| .. currentmodule:: _bleio +//| +//| :class:`ScanEntry` -- BLE scan response entry +//| ========================================================= +//| +//| Encapsulates information about a device that was received as a +//| response to a BLE scan request. This object may only be created +//| by a `_bleio.Scanner`: it has no user-visible constructor. +//| + +//| .. attribute:: address +//| +//| The address of the device (read-only), of type `_bleio.Address`. +//| +STATIC mp_obj_t bleio_scanentry_get_address(mp_obj_t self_in) { + bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_bleio_scanentry_get_address(self); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_address_obj, bleio_scanentry_get_address); + +const mp_obj_property_t bleio_scanentry_address_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_scanentry_get_address_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. attribute:: advertisement_bytes +//| +//| All the advertisement data present in the packet, returned as a ``bytes`` object. (read-only) +//| +STATIC mp_obj_t scanentry_get_advertisement_bytes(mp_obj_t self_in) { + bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_bleio_scanentry_get_advertisement_bytes(self); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_advertisement_bytes_obj, scanentry_get_advertisement_bytes); + +const mp_obj_property_t bleio_scanentry_advertisement_bytes_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_scanentry_get_advertisement_bytes_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. attribute:: rssi +//| +//| The signal strength of the device at the time of the scan, in integer dBm. (read-only) +//| +STATIC mp_obj_t scanentry_get_rssi(mp_obj_t self_in) { + bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int(common_hal_bleio_scanentry_get_rssi(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_rssi_obj, scanentry_get_rssi); + +const mp_obj_property_t bleio_scanentry_rssi_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_scanentry_get_rssi_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + + +STATIC const mp_rom_map_elem_t bleio_scanentry_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_scanentry_address_obj) }, + { MP_ROM_QSTR(MP_QSTR_advertisement_bytes), MP_ROM_PTR(&bleio_scanentry_advertisement_bytes_obj) }, + { MP_ROM_QSTR(MP_QSTR_rssi), MP_ROM_PTR(&bleio_scanentry_rssi_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_scanentry_locals_dict, bleio_scanentry_locals_dict_table); + +const mp_obj_type_t bleio_scanentry_type = { + { &mp_type_type }, + .name = MP_QSTR_ScanEntry, + .locals_dict = (mp_obj_dict_t*)&bleio_scanentry_locals_dict +}; diff --git a/shared-bindings/_bleio/ScanEntry.h b/shared-bindings/_bleio/ScanEntry.h new file mode 100644 index 00000000000..8af1f050a8f --- /dev/null +++ b/shared-bindings/_bleio/ScanEntry.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H + +#include "py/obj.h" +#include "shared-module/_bleio/ScanEntry.h" + +extern const mp_obj_type_t bleio_scanentry_type; + +mp_obj_t common_hal_bleio_scanentry_get_address(bleio_scanentry_obj_t *self); +mp_obj_t common_hal_bleio_scanentry_get_advertisement_bytes(bleio_scanentry_obj_t *self); +mp_int_t common_hal_bleio_scanentry_get_rssi(bleio_scanentry_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H diff --git a/shared-bindings/_bleio/Scanner.c b/shared-bindings/_bleio/Scanner.c new file mode 100644 index 00000000000..94cec97529e --- /dev/null +++ b/shared-bindings/_bleio/Scanner.c @@ -0,0 +1,129 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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 "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/_bleio/ScanEntry.h" +#include "shared-bindings/_bleio/Scanner.h" + +#define INTERVAL_DEFAULT (0.1f) +#define INTERVAL_MIN (0.0025f) +#define INTERVAL_MIN_STRING "0.0025" +#define INTERVAL_MAX (40.959375f) +#define INTERVAL_MAX_STRING "40.959375" +#define WINDOW_DEFAULT (0.1f) + +//| .. currentmodule:: _bleio +//| +//| :class:`Scanner` -- scan for nearby BLE devices +//| ========================================================= +//| +//| Scan for nearby BLE devices. +//| +//| Usage:: +//| +//| import _bleio +//| scanner = _bleio.Scanner() +//| entries = scanner.scan(2.5) # Scan for 2.5 seconds +//| + +//| .. class:: Scanner() +//| +//| Create a new Scanner object. +//| +STATIC mp_obj_t bleio_scanner_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *all_args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 0, false); + + bleio_scanner_obj_t *self = m_new_obj(bleio_scanner_obj_t); + self->base.type = type; + + common_hal_bleio_scanner_construct(self); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: scan(timeout, \*, interval=0.1, window=0.1) +//| +//| Performs a BLE scan. +//| +//| :param float timeout: the scan timeout in seconds +//| :param float interval: the interval (in seconds) between the start of two consecutive scan windows +//| Must be in the range 0.0025 - 40.959375 seconds. +//| :param float window: the duration (in seconds) to scan a single BLE channel. +//| window must be <= interval. +//| :returns: an iterable of `ScanEntry` objects +//| :rtype: iterable +//| +STATIC mp_obj_t bleio_scanner_scan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_timeout, ARG_interval, ARG_window }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_timeout, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_window, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + }; + + bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj); + + if (args[ARG_interval].u_obj == MP_OBJ_NULL) { + args[ARG_interval].u_obj = mp_obj_new_float(INTERVAL_DEFAULT); + } + + if (args[ARG_window].u_obj == MP_OBJ_NULL) { + args[ARG_window].u_obj = mp_obj_new_float(WINDOW_DEFAULT); + } + + const mp_float_t interval = mp_obj_float_get(args[ARG_interval].u_obj); + if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) { + mp_raise_ValueError_varg(translate("interval must be in range %s-%s"), INTERVAL_MIN_STRING, INTERVAL_MAX_STRING); + } + + const mp_float_t window = mp_obj_float_get(args[ARG_window].u_obj); + if (window > interval) { + mp_raise_ValueError(translate("window must be <= interval")); + } + + return common_hal_bleio_scanner_scan(self, timeout, interval, window); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_scanner_scan_obj, 2, bleio_scanner_scan); + + +STATIC const mp_rom_map_elem_t bleio_scanner_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&bleio_scanner_scan_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_scanner_locals_dict, bleio_scanner_locals_dict_table); + +const mp_obj_type_t bleio_scanner_type = { + { &mp_type_type }, + .name = MP_QSTR_Scanner, + .make_new = bleio_scanner_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_scanner_locals_dict +}; diff --git a/shared-bindings/_bleio/Scanner.h b/shared-bindings/_bleio/Scanner.h new file mode 100644 index 00000000000..cbaa778662f --- /dev/null +++ b/shared-bindings/_bleio/Scanner.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H + +#include "py/objtype.h" +#include "common-hal/_bleio/Scanner.h" + +extern const mp_obj_type_t bleio_scanner_type; + +extern void common_hal_bleio_scanner_construct(bleio_scanner_obj_t *self); +extern mp_obj_t common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_float_t timeout, mp_float_t interval, mp_float_t window); +extern void common_hal_bleio_scanner_stop(bleio_scanner_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H diff --git a/shared-bindings/_bleio/Service.c b/shared-bindings/_bleio/Service.c new file mode 100644 index 00000000000..da5633f2a32 --- /dev/null +++ b/shared-bindings/_bleio/Service.c @@ -0,0 +1,201 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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 "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Peripheral.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/UUID.h" + +//| .. currentmodule:: _bleio +//| +//| :class:`Service` -- BLE service +//| ========================================================= +//| +//| Stores information about a BLE service and its characteristics. +//| +//| .. class:: Service +//| +//| There is no regular constructor for a Service. A new local Service can be created +//| and attached to a Peripheral by calling `add_to_peripheral()`. +//| Remote Service objects are created by `Central.discover_remote_services()` +//| or `Peripheral.discover_remote_services()`. +//| +//| .. classmethod:: add_to_peripheral(peripheral, uuid, *, secondary=False) +//| +//| Create a new Service object, identitied by the specified UUID, and add it +//| to the given Peripheral. +//| +//| To mark the service as secondary, pass `True` as :py:data:`secondary`. +//| +//| :param Peripheral peripheral: The peripheral that will provide this service +//| :param UUID uuid: The uuid of the service +//| :param bool secondary: If the service is a secondary one +// +//| :return: the new Service +//| +STATIC mp_obj_t bleio_service_add_to_peripheral(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + // class is arg[0], which we can ignore. + + enum { ARG_peripheral, ARG_uuid, ARG_secondary }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_peripheral, MP_ARG_REQUIRED | MP_ARG_OBJ,}, + { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_secondary, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mp_obj_t peripheral_obj = args[ARG_peripheral].u_obj; + if (!MP_OBJ_IS_TYPE(peripheral_obj, &bleio_peripheral_type)) { + mp_raise_ValueError(translate("Expected a Peripheral")); + } + + const mp_obj_t uuid_obj = args[ARG_uuid].u_obj; + if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) { + mp_raise_ValueError(translate("Expected a UUID")); + } + + const bool is_secondary = args[ARG_secondary].u_bool; + + bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t); + service->base.type = &bleio_service_type; + + common_hal_bleio_service_construct( + service, MP_OBJ_TO_PTR(peripheral_obj), MP_OBJ_TO_PTR(uuid_obj), is_secondary); + + common_hal_bleio_peripheral_add_service(peripheral_obj, service); + + return MP_OBJ_FROM_PTR(service); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_service_add_to_peripheral_fun_obj, 3, bleio_service_add_to_peripheral); +STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(bleio_service_add_to_peripheral_obj, MP_ROM_PTR(&bleio_service_add_to_peripheral_fun_obj)); + +//| .. attribute:: characteristics +//| +//| A tuple of :py:class:`Characteristic` designating the characteristics that are offered by this service. (read-only) +//| +STATIC mp_obj_t bleio_service_get_characteristics(mp_obj_t self_in) { + bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); + // Return list as a tuple so user won't be able to change it. + mp_obj_list_t *char_list = common_hal_bleio_service_get_characteristic_list(self); + return mp_obj_new_tuple(char_list->len, char_list->items); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_characteristics_obj, bleio_service_get_characteristics); + +const mp_obj_property_t bleio_service_characteristics_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_service_get_characteristics_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. attribute:: remote +//| +//| True if this is a service provided by a remote device. (read-only) +//| +STATIC mp_obj_t bleio_service_get_remote(mp_obj_t self_in) { + bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(common_hal_bleio_service_get_is_remote(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_remote_obj, bleio_service_get_remote); + +const mp_obj_property_t bleio_service_remote_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_service_get_remote_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. attribute:: secondary +//| +//| True if this is a secondary service. (read-only) +//| +STATIC mp_obj_t bleio_service_get_secondary(mp_obj_t self_in) { + bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(common_hal_bleio_service_get_is_secondary(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_secondary_obj, bleio_service_get_secondary); + +const mp_obj_property_t bleio_service_secondary_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_service_get_secondary_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| .. attribute:: uuid +//| +//| The UUID of this service. (read-only) +//| Will be ``None`` if the 128-bit UUID for this service is not known. +//| +STATIC mp_obj_t bleio_service_get_uuid(mp_obj_t self_in) { + bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); + + bleio_uuid_obj_t *uuid = common_hal_bleio_service_get_uuid(self); + return uuid ? MP_OBJ_FROM_PTR(uuid) : mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_uuid_obj, bleio_service_get_uuid); + +const mp_obj_property_t bleio_service_uuid_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_service_get_uuid_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + + +STATIC const mp_rom_map_elem_t bleio_service_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_add_to_peripheral), MP_ROM_PTR(&bleio_service_add_to_peripheral_obj) }, + { MP_ROM_QSTR(MP_QSTR_characteristics), MP_ROM_PTR(&bleio_service_characteristics_obj) }, + { MP_ROM_QSTR(MP_QSTR_secondary), MP_ROM_PTR(&bleio_service_secondary_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_service_uuid_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(bleio_service_locals_dict, bleio_service_locals_dict_table); + +STATIC void bleio_service_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->uuid) { + mp_printf(print, "Service("); + bleio_uuid_print(print, MP_OBJ_FROM_PTR(self->uuid), kind); + mp_printf(print, ")"); + } else { + mp_printf(print, ""); + } +} + +const mp_obj_type_t bleio_service_type = { + { &mp_type_type }, + .name = MP_QSTR_Service, + .print = bleio_service_print, + .locals_dict = (mp_obj_dict_t*)&bleio_service_locals_dict +}; diff --git a/shared-bindings/_bleio/Service.h b/shared-bindings/_bleio/Service.h new file mode 100644 index 00000000000..e061bcffcbe --- /dev/null +++ b/shared-bindings/_bleio/Service.h @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H + +#include "common-hal/_bleio/Peripheral.h" +#include "common-hal/_bleio/Service.h" + +const mp_obj_type_t bleio_service_type; + +extern void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_peripheral_obj_t *peripheral, bleio_uuid_obj_t *uuid, bool is_secondary); +extern bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self); +extern mp_obj_list_t *common_hal_bleio_service_get_characteristic_list(bleio_service_obj_t *self); +extern bool common_hal_bleio_service_get_is_remote(bleio_service_obj_t *self); +extern bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self); +extern void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H diff --git a/shared-bindings/_bleio/UUID.c b/shared-bindings/_bleio/UUID.c new file mode 100644 index 00000000000..3c0889aad99 --- /dev/null +++ b/shared-bindings/_bleio/UUID.c @@ -0,0 +1,280 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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 + +#include "py/objproperty.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/_bleio/UUID.h" + +//| .. currentmodule:: _bleio +//| +//| :class:`UUID` -- BLE UUID +//| ========================================================= +//| +//| A 16-bit or 128-bit UUID. Can be used for services, characteristics, descriptors and more. +//| + +//| .. class:: UUID(value) +//| +//| Create a new UUID or UUID object encapsulating the uuid value. +//| The value can be one of: +//| +//| - an `int` value in range 0 to 0xFFFF (Bluetooth SIG 16-bit UUID) +//| - a buffer object (bytearray, bytes) of 16 bytes in little-endian order (128-bit UUID) +//| - a string of hex digits of the form 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' +//| +//| Creating a 128-bit UUID registers the UUID with the onboard BLE software, and provides a +//| temporary 16-bit UUID that can be used in place of the full 128-bit UUID. +//| +//| :param value: The uuid value to encapsulate +//| :type value: int or typing.ByteString +//| +STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); + + bleio_uuid_obj_t *self = m_new_obj(bleio_uuid_obj_t); + self->base.type = type; + + const mp_obj_t value = pos_args[0]; + uint8_t uuid128[16]; + + if (MP_OBJ_IS_INT(value)) { + mp_int_t uuid16 = mp_obj_get_int(value); + if (uuid16 < 0 || uuid16 > 0xffff) { + mp_raise_ValueError(translate("UUID integer value must be 0-0xffff")); + } + + // NULL means no 128-bit value. + common_hal_bleio_uuid_construct(self, uuid16, NULL); + + } else { + if (MP_OBJ_IS_STR(value)) { + // 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' + GET_STR_DATA_LEN(value, chars, len); + char hex[32]; + // Validate length, hyphens, and hex digits. + bool good_uuid = + len == 36 && chars[8] == '-' && chars[13] == '-' && chars[18] == '-' && chars[23] == '-'; + if (good_uuid) { + size_t hex_idx = 0; + for (size_t i = 0; i < len; i++) { + if (unichar_isxdigit(chars[i])) { + hex[hex_idx] = chars[i]; + hex_idx++; + } + } + good_uuid = hex_idx == 32; + } + if (!good_uuid) { + mp_raise_ValueError(translate("UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'")); + } + + size_t hex_idx = 0; + for (int i = 15; i >= 0; i--) { + uuid128[i] = (unichar_xdigit_value(hex[hex_idx]) << 4) | unichar_xdigit_value(hex[hex_idx + 1]); + hex_idx += 2; + } + } else { + // Last possibility is that it's a buf. + mp_buffer_info_t bufinfo; + if (!mp_get_buffer(value, &bufinfo, MP_BUFFER_READ)) { + mp_raise_ValueError(translate("UUID value is not str, int or byte buffer")); + } + + if (bufinfo.len != 16) { + mp_raise_ValueError(translate("Byte buffer must be 16 bytes.")); + } + + memcpy(uuid128, bufinfo.buf, 16); + } + + // Str and bytes both get constructed the same way here. + uint32_t uuid16 = (uuid128[13] << 8) | uuid128[12]; + uuid128[12] = 0; + uuid128[13] = 0; + common_hal_bleio_uuid_construct(self, uuid16, uuid128); + } + + return MP_OBJ_FROM_PTR(self); +} + +//| .. attribute:: uuid16 +//| +//| The 16-bit part of the UUID. (read-only) +//| +//| :type: int +//| +STATIC mp_obj_t bleio_uuid_get_uuid16(mp_obj_t self_in) { + bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_uuid_get_uuid16(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_uuid16_obj, bleio_uuid_get_uuid16); + +const mp_obj_property_t bleio_uuid_uuid16_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_uuid_get_uuid16_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: uuid128 +//| +//| The 128-bit value of the UUID +//| Raises AttributeError if this is a 16-bit UUID. (read-only) +//| +//| :type: bytes +//| +STATIC mp_obj_t bleio_uuid_get_uuid128(mp_obj_t self_in) { + bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + + uint8_t uuid128[16]; + if (!common_hal_bleio_uuid_get_uuid128(self, uuid128)) { + mp_raise_AttributeError(translate("not a 128-bit UUID")); + } + return mp_obj_new_bytes(uuid128, 16); +} + +MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_uuid128_obj, bleio_uuid_get_uuid128); + +const mp_obj_property_t bleio_uuid_uuid128_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_uuid_get_uuid128_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: size +//| +//| 128 if this UUID represents a 128-bit vendor-specific UUID. 16 if this UUID represents a +//| 16-bit Bluetooth SIG assigned UUID. (read-only) 32-bit UUIDs are not currently supported. +//| +//| :type: int +//| +STATIC mp_obj_t bleio_uuid_get_size(mp_obj_t self_in) { + bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_uuid_get_size(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_size_obj, bleio_uuid_get_size); + +const mp_obj_property_t bleio_uuid_size_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_uuid_get_size_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t bleio_uuid_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_uuid16), MP_ROM_PTR(&bleio_uuid_uuid16_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid128), MP_ROM_PTR(&bleio_uuid_uuid128_obj) }, + { MP_ROM_QSTR(MP_QSTR_size), MP_ROM_PTR(&bleio_uuid_size_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_uuid_locals_dict, bleio_uuid_locals_dict_table); + +STATIC mp_obj_t bleio_uuid_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + switch (op) { + case MP_UNARY_OP_HASH: + if (common_hal_bleio_uuid_get_size(self) == 16) { + return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_uuid_get_uuid16(self)); + } else { + union { + uint8_t uuid128_bytes[16]; + uint16_t uuid128_uint16[8]; + } uuid128; + common_hal_bleio_uuid_get_uuid128(self, uuid128.uuid128_bytes); + int hash = 0; + for (size_t i = 0; i < MP_ARRAY_SIZE(uuid128.uuid128_uint16); i++) { + hash += uuid128.uuid128_uint16[i]; + } + return MP_OBJ_NEW_SMALL_INT(hash); + } + default: + return MP_OBJ_NULL; // op not supported + } +} + +//| + +//| .. method:: __eq__(other) +//| +//| Two UUID objects are equal if their values match and they are both 128-bit or both 16-bit. +//| +STATIC mp_obj_t bleio_uuid_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { + switch (op) { + // Two UUID's are equal if their uuid16 values and uuid128 references match. + case MP_BINARY_OP_EQUAL: + if (MP_OBJ_IS_TYPE(rhs_in, &bleio_uuid_type)) { + return mp_obj_new_bool( + common_hal_bleio_uuid_get_uuid16(lhs_in) == common_hal_bleio_uuid_get_uuid16(rhs_in) && + common_hal_bleio_uuid_get_uuid128_reference(lhs_in) == + common_hal_bleio_uuid_get_uuid128_reference(rhs_in)); + } else { + return mp_const_false; + } + + default: + return MP_OBJ_NULL; // op not supported + } +} + +void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint32_t size = common_hal_bleio_uuid_get_size(self); + if (size == 16) { + mp_printf(print, "UUID(0x%04x)", common_hal_bleio_uuid_get_uuid16(self)); + } else { + uint8_t uuid128[16]; + (void) common_hal_bleio_uuid_get_uuid128(self, uuid128); + mp_printf(print, "UUID('" + "%02x%02x%02x%02x-" + "%02x%02x-" + "%02x%02x-" + "%02x%02x-" + "%02x%02x%02x%02x%02x%02x')", + uuid128[15], uuid128[14], uuid128[13], uuid128[12], + uuid128[11], uuid128[10], + uuid128[9], uuid128[8], + uuid128[7], uuid128[6], + uuid128[5], uuid128[4], uuid128[3], uuid128[2], uuid128[1], uuid128[0]); + } +} + +const mp_obj_type_t bleio_uuid_type = { + { &mp_type_type }, + .name = MP_QSTR_UUID, + .print = bleio_uuid_print, + .make_new = bleio_uuid_make_new, + .unary_op = bleio_uuid_unary_op, + .binary_op = bleio_uuid_binary_op, + .locals_dict = (mp_obj_dict_t*)&bleio_uuid_locals_dict, +}; diff --git a/shared-bindings/_bleio/UUID.h b/shared-bindings/_bleio/UUID.h new file mode 100644 index 00000000000..46ac54ff39e --- /dev/null +++ b/shared-bindings/_bleio/UUID.h @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H + +#include "common-hal/_bleio/UUID.h" + +void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); + +extern const mp_obj_type_t bleio_uuid_type; + +extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, uint8_t uuid128[]); +extern uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self); +extern bool common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]); +extern uint32_t common_hal_bleio_uuid_get_uuid128_reference(bleio_uuid_obj_t *self); +extern uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H diff --git a/shared-bindings/_bleio/__init__.c b/shared-bindings/_bleio/__init__.c new file mode 100644 index 00000000000..f207be8cfc0 --- /dev/null +++ b/shared-bindings/_bleio/__init__.c @@ -0,0 +1,107 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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 "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Address.h" +#include "shared-bindings/_bleio/Attribute.h" +#include "shared-bindings/_bleio/Central.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/CharacteristicBuffer.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/Peripheral.h" +#include "shared-bindings/_bleio/ScanEntry.h" +#include "shared-bindings/_bleio/Scanner.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/UUID.h" + +//| :mod:`_bleio` --- Bluetooth Low Energy (BLE) communication +//| ================================================================ +//| +//| .. module:: _bleio +//| :synopsis: Bluetooth Low Energy functionality +//| :platform: nRF +//| +//| The `_bleio` module provides necessary low-level functionality for communicating +//| using Bluetooth Low Energy (BLE). The '_' prefix indicates this module is meant +//| for internal use by libraries but not by the end user. Its API may change incompatibly +//| between minor versions of CircuitPython. +//| Please use the +//| `adafruit_ble `_ +//| CircuitPython library instead, which builds on `_bleio`, and +//| provides higher-level convenience functionality, including predefined beacons, clients, +//| servers. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Address +//| Adapter +//| Attribute +//| Central +//| Characteristic +//| CharacteristicBuffer +//| Descriptor +//| Peripheral +//| ScanEntry +//| Scanner +//| Service +//| UUID +//| +//| .. attribute:: adapter +//| +//| BLE Adapter information, such as enabled state as well as MAC +//| address. +//| This object is the sole instance of `_bleio.Adapter`. +//| + +STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__bleio) }, + { MP_ROM_QSTR(MP_QSTR_Address), MP_ROM_PTR(&bleio_address_type) }, + { MP_ROM_QSTR(MP_QSTR_Attribute), MP_ROM_PTR(&bleio_attribute_type) }, + { MP_ROM_QSTR(MP_QSTR_Central), MP_ROM_PTR(&bleio_central_type) }, + { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) }, + { MP_ROM_QSTR(MP_QSTR_CharacteristicBuffer), MP_ROM_PTR(&bleio_characteristic_buffer_type) }, + { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, + { MP_ROM_QSTR(MP_QSTR_Peripheral), MP_ROM_PTR(&bleio_peripheral_type) }, + { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) }, + { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) }, + { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&bleio_service_type) }, + { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table); + +const mp_obj_module_t bleio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&bleio_module_globals, +}; diff --git a/shared-bindings/_bleio/__init__.h b/shared-bindings/_bleio/__init__.h new file mode 100644 index 00000000000..67379ae2e13 --- /dev/null +++ b/shared-bindings/_bleio/__init__.h @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO___INIT___H + +#include "py/objlist.h" + +#include "shared-bindings/_bleio/Adapter.h" + +#include "common-hal/_bleio/__init__.h" +#include "common-hal/_bleio/Adapter.h" + +extern const super_adapter_obj_t common_hal_bleio_adapter_obj; + +extern void common_hal_bleio_check_connected(uint16_t conn_handle); + +extern uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device); +extern mp_obj_list_t *common_hal_bleio_device_get_remote_service_list(mp_obj_t device); +extern void common_hal_bleio_device_discover_remote_services(mp_obj_t device, mp_obj_t service_uuids_whitelist); + +extern mp_obj_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle); +extern void common_hal_bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo); +extern void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, bool write_no_response); + + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO___INIT___H diff --git a/shared-bindings/_pew/PewPew.c b/shared-bindings/_pew/PewPew.c new file mode 100644 index 00000000000..3ff2087614e --- /dev/null +++ b/shared-bindings/_pew/PewPew.c @@ -0,0 +1,153 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Radomir Dopieralski + * + * 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 "py/obj.h" +#include "py/runtime.h" +#include "py/mphal.h" +#include "py/gc.h" +#include "py/mpstate.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/util.h" +#include "PewPew.h" +#include "shared-module/_pew/PewPew.h" +#include "supervisor/shared/translate.h" + + +//| .. currentmodule:: _pew +//| +//| :class:`PewPew` -- LED matrix and button driver +//| =============================================== +//| +//| This is an internal module to be used by the ``pew.py`` library from +//| https://github.com/pewpew-game/pew-pewpew-standalone-10.x to handle the +//| LED matrix display and buttons on the ``pewpew10`` board. +//| +//| Usage:: +//| +//| This singleton class is instantiated by the ``pew`` library, and +//| used internally by it. All user-visible interactions are done through +//| that library. +//| + +//| .. class:: PewPew(buffer, rows, cols, buttons) +//| +//| Initializes matrix scanning routines. +//| +//| The ``buffer`` is a 64 byte long ``bytearray`` that stores what should +//| be displayed on the matrix. ``rows`` and ``cols`` are both lists of +//| eight ``DigitalInputOutput`` objects that are connected to the matrix +//| rows and columns. ``buttons`` is a ``DigitalInputOutput`` object that +//| is connected to the common side of all buttons (the other sides of the +//| buttons are connected to rows of the matrix). +//| +STATIC mp_obj_t pewpew_make_new(const mp_obj_type_t *type, size_t n_args, + const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 4, 4, true); + enum { ARG_buffer, ARG_rows, ARG_cols, ARG_buttons }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_buffer, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_rows, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_cols, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_buttons, MP_ARG_OBJ | MP_ARG_REQUIRED }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), + allowed_args, args); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); + + size_t rows_size = 0; + mp_obj_t *rows; + mp_obj_get_array(args[ARG_rows].u_obj, &rows_size, &rows); + + size_t cols_size = 0; + mp_obj_t *cols; + mp_obj_get_array(args[ARG_cols].u_obj, &cols_size, &cols); + + if (bufinfo.len != rows_size * cols_size) { + mp_raise_ValueError(translate("Incorrect buffer size")); + } + + for (size_t i = 0; i < rows_size; ++i) { + if (!MP_OBJ_IS_TYPE(rows[i], &digitalio_digitalinout_type)) { + mp_raise_TypeError(translate("Row entry must be digitalio.DigitalInOut")); + } + digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(rows[i]); + if (common_hal_digitalio_digitalinout_deinited(pin)) { + raise_deinited_error(); + } + } + + for (size_t i = 0; i < cols_size; ++i) { + if (!MP_OBJ_IS_TYPE(cols[i], &digitalio_digitalinout_type)) { + mp_raise_TypeError(translate("Column entry must be digitalio.DigitalInOut")); + } + digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(cols[i]); + if (common_hal_digitalio_digitalinout_deinited(pin)) { + raise_deinited_error(); + } + } + + if (!MP_OBJ_IS_TYPE(args[ARG_buttons].u_obj, + &digitalio_digitalinout_type)) { + mp_raise_TypeError(translate("buttons must be digitalio.DigitalInOut")); + } + digitalio_digitalinout_obj_t *buttons = MP_OBJ_TO_PTR( + args[ARG_buttons].u_obj); + if (common_hal_digitalio_digitalinout_deinited(buttons)) { + raise_deinited_error(); + } + + pew_obj_t *pew = MP_STATE_VM(pew_singleton); + if (!pew) { + pew = m_new_obj(pew_obj_t); + pew->base.type = &pewpew_type; + pew = gc_make_long_lived(pew); + MP_STATE_VM(pew_singleton) = pew; + } + + pew->buffer = bufinfo.buf; + pew->rows = rows; + pew->rows_size = rows_size; + pew->cols = cols; + pew->cols_size = cols_size; + pew->buttons = buttons; + pew->pressed = 0; + pew_init(); + + return MP_OBJ_FROM_PTR(pew); +} + + +STATIC const mp_rom_map_elem_t pewpew_locals_dict_table[] = { +}; +STATIC MP_DEFINE_CONST_DICT(pewpew_locals_dict, pewpew_locals_dict_table); +const mp_obj_type_t pewpew_type = { + { &mp_type_type }, + .name = MP_QSTR_PewPew, + .make_new = pewpew_make_new, + .locals_dict = (mp_obj_dict_t*)&pewpew_locals_dict, +}; diff --git a/shared-bindings/_pew/PewPew.h b/shared-bindings/_pew/PewPew.h new file mode 100644 index 00000000000..f763847577f --- /dev/null +++ b/shared-bindings/_pew/PewPew.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Radomir Dopieralski + * + * 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. + */ + + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_PEW_PEWPEW_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_PEW_PEWPEW_H + +extern const mp_obj_type_t pewpew_type; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_PEW_PEWPEW_H diff --git a/shared-bindings/_pew/__init__.c b/shared-bindings/_pew/__init__.c new file mode 100644 index 00000000000..6c5520ac586 --- /dev/null +++ b/shared-bindings/_pew/__init__.c @@ -0,0 +1,67 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Radomir Dopieralski + * + * 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 "py/obj.h" +#include "py/runtime.h" +#include "py/mphal.h" +#include "PewPew.h" +#include "shared-module/_pew/PewPew.h" + +STATIC mp_obj_t get_pressed(void) { + pew_obj_t *pew = MP_STATE_VM(pew_singleton); + if (!pew) { + return mp_const_none; + } + uint8_t pressed = pew->pressed; + pew->pressed = 0; + return mp_obj_new_int(pressed); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(get_pressed_obj, get_pressed); + + +//| :mod:`_pew` --- LED matrix driver +//| ================================== +//| +//| .. module:: _pew +//| :synopsis: LED matrix driver +//| :platform: SAMD21 +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| PewPew +//| +STATIC const mp_rom_map_elem_t pew_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__pew) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PewPew), MP_ROM_PTR(&pewpew_type)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_get_pressed), MP_ROM_PTR(&get_pressed_obj)}, +}; +STATIC MP_DEFINE_CONST_DICT(pew_module_globals, + pew_module_globals_table); + +const mp_obj_module_t pew_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&pew_module_globals, +}; diff --git a/shared-bindings/_pixelbuf/PixelBuf.c b/shared-bindings/_pixelbuf/PixelBuf.c new file mode 100644 index 00000000000..420720e622c --- /dev/null +++ b/shared-bindings/_pixelbuf/PixelBuf.c @@ -0,0 +1,479 @@ +/* + * This file is part of the Circuit Python project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Roy Hooper + * + * 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 "py/obj.h" +#include "py/objarray.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/gc.h" + +#include + +#include "PixelBuf.h" +#include "shared-bindings/_pixelbuf/types.h" +#include "../../shared-module/_pixelbuf/PixelBuf.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + +extern const pixelbuf_byteorder_obj_t byteorder_BGR; +extern const mp_obj_type_t pixelbuf_byteorder_type; +extern const int32_t colorwheel(float pos); + +//| .. currentmodule:: pixelbuf +//| +//| :class:`PixelBuf` -- A fast RGB[W] pixel buffer for LED and similar devices +//| =========================================================================== +//| +//| :class:`~_pixelbuf.PixelBuf` implements an RGB[W] bytearray abstraction. +//| +//| .. class:: PixelBuf(size, buf, byteorder=BGR, brightness=0, rawbuf=None, offset=0, dotstar=False, auto_write=False, write_function=None, write_args=None) +//| +//| Create a PixelBuf object of the specified size, byteorder, and bits per pixel. +//| +//| When given a second bytearray (``rawbuf``), changing brightness adjusts the +//| brightness of all members of ``buf``. +//| +//| When only given ``buf``, ``brightness`` applies to the next pixel assignment. +//| +//| When ``dotstar`` is True, and ``bpp`` is 4, the 4th value in a tuple/list +//| is the individual pixel brightness (0-1). Not compatible with RGBW Byteorders. +//| Compatible `ByteOrder` classes are bpp=3, or bpp=4 and has_luminosity=True (g LBGR). +//| +//| :param ~int size: Number of pixelsx +//| :param ~bytearray buf: Bytearray to store pixel data in +//| :param ~_pixelbuf.ByteOrder byteorder: Byte order constant from `_pixelbuf` +//| :param ~float brightness: Brightness (0 to 1.0, default 1.0) +//| :param ~bytearray rawbuf: Bytearray to store raw pixel colors in +//| :param ~int offset: Offset from start of buffer (default 0) +//| :param ~bool dotstar: Dotstar mode (default False) +//| :param ~bool auto_write: Whether to automatically write pixels (Default False) +//| :param ~callable write_function: (optional) Callable to use to send pixels +//| :param ~list write_args: (optional) Tuple or list of args to pass to ``write_function``. The +//| PixelBuf instance is appended after these args. +//| +STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 2, MP_OBJ_FUN_ARGS_MAX, true); + enum { ARG_size, ARG_buf, ARG_byteorder, ARG_brightness, ARG_rawbuf, ARG_offset, ARG_dotstar, + ARG_auto_write, ARG_write_function, ARG_write_args }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_size, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_buf, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_byteorder, MP_ARG_OBJ, { .u_obj = mp_const_none } }, + { MP_QSTR_brightness, MP_ARG_OBJ, { .u_obj = mp_const_none } }, + { MP_QSTR_rawbuf, MP_ARG_OBJ, { .u_obj = mp_const_none } }, + { MP_QSTR_offset, MP_ARG_INT, { .u_int = 0 } }, + { MP_QSTR_dotstar, MP_ARG_BOOL, { .u_bool = false } }, + { MP_QSTR_auto_write, MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_write_function, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_write_args, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + if (mp_obj_is_subclass_fast(args[ARG_byteorder].u_obj, &pixelbuf_byteorder_type)) + mp_raise_TypeError_varg(translate("byteorder is not an instance of ByteOrder (got a %s)"), mp_obj_get_type_str(args[ARG_byteorder].u_obj)); + + pixelbuf_byteorder_obj_t *byteorder = (args[ARG_byteorder].u_obj == mp_const_none) ? MP_OBJ_FROM_PTR(&byteorder_BGR) : args[ARG_byteorder].u_obj; + + if (byteorder->has_white && args[ARG_dotstar].u_bool) + mp_raise_ValueError_varg(translate("Can not use dotstar with %s"), mp_obj_get_type_str(byteorder)); + + size_t effective_bpp = args[ARG_dotstar].u_bool ? 4 : byteorder->bpp; // Always 4 for DotStar + size_t bytes = args[ARG_size].u_int * effective_bpp; + size_t offset = args[ARG_offset].u_int; + mp_buffer_info_t bufinfo, rawbufinfo; + + mp_get_buffer_raise(args[ARG_buf].u_obj, &bufinfo, MP_BUFFER_READ | MP_BUFFER_WRITE); + bool two_buffers = args[ARG_rawbuf].u_obj != mp_const_none; + if (two_buffers) { + mp_get_buffer_raise(args[ARG_rawbuf].u_obj, &rawbufinfo, MP_BUFFER_READ | MP_BUFFER_WRITE); + if (rawbufinfo.len != bufinfo.len) { + mp_raise_ValueError(translate("rawbuf is not the same size as buf")); + } + } + + if (bytes + offset > bufinfo.len) + mp_raise_ValueError_varg(translate("buf is too small. need %d bytes"), bytes + offset); + + if (!MP_OBJ_IS_TYPE(args[ARG_write_args].u_obj, &mp_type_list) && + !MP_OBJ_IS_TYPE(args[ARG_write_args].u_obj, &mp_type_tuple) && + args[ARG_write_args].u_obj != mp_const_none) + { + mp_raise_ValueError(translate("write_args must be a list, tuple, or None")); + } + + // Validation complete, allocate and populate object. + pixelbuf_pixelbuf_obj_t *self = m_new_obj(pixelbuf_pixelbuf_obj_t); + + self->base.type = &pixelbuf_pixelbuf_type; + self->pixels = args[ARG_size].u_int; + self->bytes = bytes; + self->byteorder = *byteorder; // Copied because we modify for dotstar + self->bytearray = args[ARG_buf].u_obj; + self->two_buffers = two_buffers; + self->rawbytearray = two_buffers ? args[ARG_rawbuf].u_obj : NULL; + self->offset = offset; + self->dotstar_mode = args[ARG_dotstar].u_bool; + self->buf = (uint8_t *)bufinfo.buf + offset; + self->rawbuf = two_buffers ? (uint8_t *)rawbufinfo.buf + offset : NULL; + self->pixel_step = effective_bpp; + self->auto_write = args[ARG_auto_write].u_bool; + + if (self->dotstar_mode) { + // Ensure sane configuration + if (!self->byteorder.has_luminosity) { + self->byteorder.has_luminosity = true; + self->byteorder.byteorder.b += 1; + self->byteorder.byteorder.g += 1; + self->byteorder.byteorder.r += 1; + } + self->byteorder.byteorder.w = 0; + } + + // Show/auto-write callbacks + self->write_function = args[ARG_write_function].u_obj; + mp_obj_t function_args = args[ARG_write_args].u_obj; + mp_obj_t *src_objs = (mp_obj_t *)&mp_const_none_obj; + size_t num_items = 0; + if (function_args != mp_const_none) { + if (MP_OBJ_IS_TYPE(function_args, &mp_type_list)) { + mp_obj_list_t *t = MP_OBJ_TO_PTR(function_args); + num_items = t->len; + src_objs = t->items; + } else { + mp_obj_tuple_t *l = MP_OBJ_TO_PTR(function_args); + num_items = l->len; + src_objs = l->items; + } + } + self->write_function_args = mp_obj_new_tuple(num_items + 1, NULL); + for (size_t i = 0; i < num_items; i++) { + self->write_function_args->items[i] = src_objs[i]; + } + self->write_function_args->items[num_items] = self; + + if (args[ARG_brightness].u_obj == mp_const_none) { + self->brightness = 1.0; + } else { + self->brightness = mp_obj_get_float(args[ARG_brightness].u_obj); + if (self->brightness < 0) + self->brightness = 0; + else if (self->brightness > 1) + self->brightness = 1; + } + + if (self->dotstar_mode) { + // Initialize the buffer with the dotstar start bytes. + // Header and end must be setup by caller + for (uint i = 0; i < self->pixels * 4; i += 4) { + self->buf[i] = DOTSTAR_LED_START_FULL_BRIGHT; + if (two_buffers) { + self->rawbuf[i] = DOTSTAR_LED_START_FULL_BRIGHT; + } + } + } + + return MP_OBJ_FROM_PTR(self); +} + +//| .. attribute:: bpp +//| +//| The number of bytes per pixel in the buffer (read-only) +//| +STATIC mp_obj_t pixelbuf_pixelbuf_obj_get_bpp(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int_from_uint(self->byteorder.bpp); +} +MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_get_bpp_obj, pixelbuf_pixelbuf_obj_get_bpp); + +const mp_obj_property_t pixelbuf_pixelbuf_bpp_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pixelbuf_pixelbuf_get_bpp_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +//| .. attribute:: brightness +//| +//| Float value between 0 and 1. Output brightness. +//| If the PixelBuf was allocated with two both a buf and a rawbuf, +//| setting this value causes a recomputation of the values in buf. +//| If only a buf was provided, then the brightness only applies to +//| future pixel changes. +//| In DotStar mode +//| +STATIC mp_obj_t pixelbuf_pixelbuf_obj_get_brightness(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_float(self->brightness); +} +MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_get_brightness_obj, pixelbuf_pixelbuf_obj_get_brightness); + + +STATIC mp_obj_t pixelbuf_pixelbuf_obj_set_brightness(mp_obj_t self_in, mp_obj_t value) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + self->brightness = mp_obj_float_get(value); + if (self->brightness > 1) + self->brightness = 1; + else if (self->brightness < 0) + self->brightness = 0; + if (self->two_buffers) + pixelbuf_recalculate_brightness(self); + if (self->auto_write) + call_write_function(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(pixelbuf_pixelbuf_set_brightness_obj, pixelbuf_pixelbuf_obj_set_brightness); + +const mp_obj_property_t pixelbuf_pixelbuf_brightness_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pixelbuf_pixelbuf_get_brightness_obj, + (mp_obj_t)&pixelbuf_pixelbuf_set_brightness_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +void pixelbuf_recalculate_brightness(pixelbuf_pixelbuf_obj_t *self) { + uint8_t *buf = (uint8_t *)self->buf; + uint8_t *rawbuf = (uint8_t *)self->rawbuf; + // Compensate for shifted buffer (bpp=3 dotstar) + for (uint i = 0; i < self->bytes; i++) { + // Don't adjust per-pixel luminance bytes in dotstar mode + if (!self->dotstar_mode || (i % 4 != 0)) + buf[i] = rawbuf[i] * self->brightness; + } +} + +//| .. attribute:: auto_write +//| +//| Whether to automatically write the pixels after each update. +//| +STATIC mp_obj_t pixelbuf_pixelbuf_obj_get_auto_write(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(self->auto_write); +} +MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_get_auto_write_obj, pixelbuf_pixelbuf_obj_get_auto_write); + + +STATIC mp_obj_t pixelbuf_pixelbuf_obj_set_auto_write(mp_obj_t self_in, mp_obj_t value) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + self->auto_write = mp_obj_is_true(value); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(pixelbuf_pixelbuf_set_auto_write_obj, pixelbuf_pixelbuf_obj_set_auto_write); + +const mp_obj_property_t pixelbuf_pixelbuf_auto_write_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pixelbuf_pixelbuf_get_auto_write_obj, + (mp_obj_t)&pixelbuf_pixelbuf_set_auto_write_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +//| .. attribute:: buf +//| +//| (read-only) bytearray of pixel data after brightness adjustment. If an offset was provided +//| then this bytearray is the subset of the bytearray passed in that represents the +//| actual pixels. +//| +STATIC mp_obj_t pixelbuf_pixelbuf_obj_get_buf(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bytearray_by_ref(self->bytes, self->buf); +} +MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_get_buf_obj, pixelbuf_pixelbuf_obj_get_buf); + +const mp_obj_property_t pixelbuf_pixelbuf_buf_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pixelbuf_pixelbuf_get_buf_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: byteorder +//| +//| `ByteOrder` class for the buffer (read-only) +//| +STATIC mp_obj_t pixelbuf_pixelbuf_obj_get_byteorder(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + return &self->byteorder; +} +MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_get_byteorder_obj, pixelbuf_pixelbuf_obj_get_byteorder); + +const mp_obj_property_t pixelbuf_pixelbuf_byteorder_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pixelbuf_pixelbuf_get_byteorder_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC mp_obj_t pixelbuf_pixelbuf_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + switch (op) { + case MP_UNARY_OP_BOOL: return mp_const_true; + case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(self->pixels); + default: return MP_OBJ_NULL; // op not supported + } +} + +//| .. method:: show() +//| +//| Call the associated write function to display the pixels. +//| + +STATIC mp_obj_t pixelbuf_pixelbuf_show(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + call_write_function(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_show_obj, pixelbuf_pixelbuf_show); + +void call_write_function(pixelbuf_pixelbuf_obj_t *self) { + // execute function if it's set + if (self->write_function != mp_const_none) { + mp_call_function_n_kw(self->write_function, self->write_function_args->len, 0, self->write_function_args->items); + } +} + +//| .. method:: __getitem__(index) +//| +//| Returns the pixel value at the given index. +//| +//| .. method:: __setitem__(index, value) +//| +//| Sets the pixel value at the given index. +//| +STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); + + if (value == MP_OBJ_NULL) { + // delete item + // slice deletion + return MP_OBJ_NULL; // op not supported + } + + pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (0) { +#if MICROPY_PY_BUILTINS_SLICE + } else if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) { + mp_bound_slice_t slice; + + if (!mp_seq_get_fast_slice_indexes(self->bytes, index_in, &slice)) + mp_raise_NotImplementedError(translate("Only slices with step=1 (aka None) are supported")); + if ((slice.stop * self->pixel_step) > self->bytes) + mp_raise_IndexError(translate("Range out of bounds")); + + if (value == MP_OBJ_SENTINEL) { // Get + size_t len = slice.stop - slice.start; + return pixelbuf_get_pixel_array((uint8_t *) self->buf + slice.start, len, &self->byteorder, self->pixel_step, self->dotstar_mode); + } else { // Set + #if MICROPY_PY_ARRAY_SLICE_ASSIGN + + if (!(MP_OBJ_IS_TYPE(value, &mp_type_list) || MP_OBJ_IS_TYPE(value, &mp_type_tuple))) + mp_raise_ValueError(translate("tuple/list required on RHS")); + + size_t dst_len = slice.stop - slice.start; + + mp_obj_t *src_objs; + size_t num_items; + if (MP_OBJ_IS_TYPE(value, &mp_type_list)) { + mp_obj_list_t *t = MP_OBJ_TO_PTR(value); + num_items = t->len; + src_objs = t->items; + } else { + mp_obj_tuple_t *l = MP_OBJ_TO_PTR(value); + num_items = l->len; + src_objs = l->items; + } + if (num_items != dst_len) + mp_raise_ValueError_varg(translate("Unmatched number of items on RHS (expected %d, got %d)."), + dst_len, num_items); + + for (size_t i = slice.start; i < slice.stop; i++) { + mp_obj_t *item = src_objs[i-slice.start]; + if (MP_OBJ_IS_TYPE(value, &mp_type_list) || MP_OBJ_IS_TYPE(value, &mp_type_tuple) || MP_OBJ_IS_INT(value)) { + pixelbuf_set_pixel(self->buf + (i * self->pixel_step), + self->two_buffers ? self->rawbuf + (i * self->pixel_step) : NULL, + self->brightness, item, &self->byteorder, self->dotstar_mode); + } + } + if (self->auto_write) + call_write_function(self); + return mp_const_none; + #else + return MP_OBJ_NULL; // op not supported + #endif + } +#endif + } else { // Single index rather than slice. + size_t index = mp_get_index(self->base.type, self->pixels, index_in, false); + size_t offset = (index * self->pixel_step); + if (offset > self->bytes) + mp_raise_IndexError(translate("Pixel beyond bounds of buffer")); + + if (value == MP_OBJ_SENTINEL) { // Get + uint8_t *pixelstart = (uint8_t *)(self->two_buffers ? self->rawbuf : self->buf) + offset; + return pixelbuf_get_pixel(pixelstart, &self->byteorder, self->dotstar_mode); + } else { // Store + pixelbuf_set_pixel(self->buf + offset, self->two_buffers ? self->rawbuf + offset : NULL, + self->brightness, value, &self->byteorder, self->dotstar_mode); + if (self->auto_write) + call_write_function(self); + return mp_const_none; + } + } +} + +STATIC const mp_rom_map_elem_t pixelbuf_pixelbuf_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_auto_write), MP_ROM_PTR(&pixelbuf_pixelbuf_auto_write_obj)}, + { MP_ROM_QSTR(MP_QSTR_bpp), MP_ROM_PTR(&pixelbuf_pixelbuf_bpp_obj)}, + { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&pixelbuf_pixelbuf_brightness_obj)}, + { MP_ROM_QSTR(MP_QSTR_buf), MP_ROM_PTR(&pixelbuf_pixelbuf_buf_obj)}, + { MP_ROM_QSTR(MP_QSTR_byteorder), MP_ROM_PTR(&pixelbuf_pixelbuf_byteorder_obj)}, + { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&pixelbuf_pixelbuf_show_obj)}, +}; + +STATIC MP_DEFINE_CONST_DICT(pixelbuf_pixelbuf_locals_dict, pixelbuf_pixelbuf_locals_dict_table); + + +const mp_obj_type_t pixelbuf_pixelbuf_type = { + { &mp_type_type }, + .name = MP_QSTR_PixelBuf, + .subscr = pixelbuf_pixelbuf_subscr, + .make_new = pixelbuf_pixelbuf_make_new, + .unary_op = pixelbuf_pixelbuf_unary_op, + .print = NULL, + .locals_dict = (mp_obj_t)&pixelbuf_pixelbuf_locals_dict, +}; diff --git a/shared-bindings/_pixelbuf/PixelBuf.h b/shared-bindings/_pixelbuf/PixelBuf.h new file mode 100644 index 00000000000..0b1e3627834 --- /dev/null +++ b/shared-bindings/_pixelbuf/PixelBuf.h @@ -0,0 +1,56 @@ +/* + * This file is part of the Circuit Python project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Roy Hooper + * + * 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. + */ + +#ifndef CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H +#define CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H + +#include "shared-bindings/_pixelbuf/types.h" + +const mp_obj_type_t pixelbuf_pixelbuf_type; + +typedef struct { + mp_obj_base_t base; + size_t pixels; + size_t bytes; + size_t pixel_step; + pixelbuf_byteorder_obj_t byteorder; + mp_obj_t bytearray; + mp_obj_t rawbytearray; + mp_float_t brightness; + bool two_buffers; + size_t offset; + bool dotstar_mode; + uint8_t *rawbuf; + uint8_t *buf; + mp_obj_t write_function; + mp_obj_tuple_t *write_function_args; + bool auto_write; +} pixelbuf_pixelbuf_obj_t; + +void pixelbuf_recalculate_brightness(pixelbuf_pixelbuf_obj_t *self); +void call_write_function(pixelbuf_pixelbuf_obj_t *self); + +#endif // CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H diff --git a/shared-bindings/_pixelbuf/__init__.c b/shared-bindings/_pixelbuf/__init__.c new file mode 100644 index 00000000000..48b9f1cef1c --- /dev/null +++ b/shared-bindings/_pixelbuf/__init__.c @@ -0,0 +1,326 @@ +/* + * This file is part of the Circuit Python project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Roy Hooper + * + * 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 "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "py/objproperty.h" + +#include "types.h" +#include "__init__.h" + +#include "PixelBuf.h" +#include "../../shared-module/_pixelbuf/PixelBuf.h" + + +//| :mod:`_pixelbuf` --- Fast RGB(W) pixel buffer and helpers +//| =========================================================== + +//| .. module:: _pixelbuf +//| :synopsis: A fast RGB(W) pixel buffer library for like NeoPixel and DotStar. +//| +//| The `_pixelbuf` module provides :py:class:`PixelBuf` and :py:class:`ByteOrder` classes to accelerate +//| RGB(W) strip/matrix manipulation, such as DotStar and Neopixel. +//| + +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| PixelBuf + +//| .. class:: ByteOrder() +//| +//| Classes representing byteorders for circuitpython + + +//| .. attribute:: bpp +//| +//| The number of bytes per pixel (read-only) +//| + +//| .. attribute:: has_white +//| +//| Whether the pixel has white (in addition to RGB) +//| + +//| .. attribute:: has_luminosity +//| +//| Whether the pixel has luminosity (in addition to RGB) +//| + +//| .. attribute:: byteorder +//| +//| Tuple of byte order (r, g, b) or (r, g, b, w) or (r, g, b, l) +//| + + +STATIC void pixelbuf_byteorder_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_byteorder_type)); + pixelbuf_byteorder_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (dest[0] == MP_OBJ_NULL) { + // load attribute + mp_obj_t val; + if (attr == MP_QSTR_bpp) { + val = MP_OBJ_NEW_SMALL_INT(self->bpp); + } else if (attr == MP_QSTR_has_white) { + val = mp_obj_new_bool(self->has_white); + } else if (attr == MP_QSTR_has_luminosity) { + val = mp_obj_new_bool(self->has_luminosity); + } else if (attr == MP_QSTR_byteorder) { + mp_obj_t items[4]; + uint8_t n = self->bpp; + if (self->has_luminosity || self->has_white) { + n = 4; + } + uint8_t *values = (uint8_t *)&(self->byteorder); + for (uint8_t i=0; ibpp); + default: return MP_OBJ_NULL; // op not supported + } +} + +const mp_obj_type_t pixelbuf_byteorder_type = { + { &mp_type_type }, + .name = MP_QSTR_ByteOrder, + .print = pixelbuf_byteorder_print, + .unary_op = pixelbuf_byteorder_unary_op, + .attr = pixelbuf_byteorder_attr, +}; + + +// This macro is used to simplify RGB subclass definition +#define PIXELBUF_BYTEORDER(p_name, p_bpp, p_r, p_g, p_b, p_w, p_has_white, p_has_luminosity) \ +const pixelbuf_byteorder_obj_t byteorder_## p_name = { \ + { &pixelbuf_byteorder_type }, \ + .name = MP_QSTR_## p_name, \ + .bpp = p_bpp, \ + .byteorder = { p_r, p_g, p_b, p_w }, \ + .has_white = p_has_white, \ + .has_luminosity = p_has_luminosity, \ +}; + +//| .. function:: wheel(n) +//| +//| C implementation of the common wheel() function found in many examples. +//| Returns the colorwheel RGB value as an integer value for n (usable in :py:class:`PixelBuf`, neopixel, and dotstar). +//| + +STATIC mp_obj_t pixelbuf_wheel(mp_obj_t n) { + return MP_OBJ_NEW_SMALL_INT(colorwheel(MP_OBJ_IS_SMALL_INT(n) ? MP_OBJ_SMALL_INT_VALUE(n) : mp_obj_float_get(n))); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_wheel_obj, pixelbuf_wheel); + +const int32_t colorwheel(float pos) { + if (pos > 255) { + pos = pos - ((uint32_t)(pos / 256) * 256); + } + if (pos < 85) + return (uint8_t)(pos * 3) << 16 | (uint8_t)(255 - (pos * 3)) << 8; + else if (pos < 170) { + pos -= 85; + return (uint8_t)(255 - (pos * 3)) << 16 | (uint8_t)(pos * 3); + } else { + pos -= 170; + return (uint8_t)(pos * 3) << 8 | (uint8_t)(255 - pos * 3); + } +} + + +/// RGB +//| .. data:: RGB +//| +//| * **order** Red, Green, Blue +//| * **bpp** 3 +PIXELBUF_BYTEORDER(RGB, 3, 0, 1, 2, 3, false, false) +//| .. data:: RBG +//| +//| * **order** Red, Blue, Green +//| * **bpp** 3 +PIXELBUF_BYTEORDER(RBG, 3, 0, 2, 1, 3, false, false) +//| .. data:: GRB +//| +//| * **order** Green, Red, Blue +//| * **bpp** 3 +//| +//| Commonly used by NeoPixel. +PIXELBUF_BYTEORDER(GRB, 3, 1, 0, 2, 3, false, false) +//| .. data:: GBR +//| +//| * **order** Green, Blue, Red +//| * **bpp** 3 +PIXELBUF_BYTEORDER(GBR, 3, 1, 2, 0, 3, false, false) +//| .. data:: BRG +//| +//| * **order** Blue, Red, Green +//| * **bpp** 3 +PIXELBUF_BYTEORDER(BRG, 3, 2, 0, 1, 3, false, false) +//| .. data:: BGR +//| +//| * **order** Blue, Green, Red +//| * **bpp** 3 +//| +//| Commonly used by Dotstar. +PIXELBUF_BYTEORDER(BGR, 3, 2, 1, 0, 3, false, false) + +// RGBW +//| .. data:: RGBW +//| +//| * **order** Red, Green, Blue, White +//| * **bpp** 4 +//| * **has_white** True +PIXELBUF_BYTEORDER(RGBW, 4, 0, 1, 2, 3, true, false) +//| .. data:: RBGW +//| +//| * **order** Red, Blue, Green, White +//| * **bpp** 4 +//| * **has_white** True +PIXELBUF_BYTEORDER(RBGW, 4, 0, 2, 1, 3, true, false) +//| .. data:: GRBW +//| +//| * **order** Green, Red, Blue, White +//| * **bpp** 4 +//| * **has_white** True +//| +//| Commonly used by RGBW NeoPixels. +PIXELBUF_BYTEORDER(GRBW, 4, 1, 0, 2, 3, true, false) +//| .. data:: GBRW +//| +//| * **order** Green, Blue, Red, White +//| * **bpp** 4 +//| * **has_white** True +PIXELBUF_BYTEORDER(GBRW, 4, 1, 2, 0, 3, true, false) +//| .. data:: BRGW +//| +//| * **order** Blue, Red, Green, White +//| * **bpp** 4 +//| * **has_white** True +PIXELBUF_BYTEORDER(BRGW, 4, 2, 0, 1, 3, true, false) +//| .. data:: BGRW +//| +//| * **order** Blue, Green, Red, White +//| * **bpp** 4 +//| * **has_white** True +PIXELBUF_BYTEORDER(BGRW, 4, 2, 1, 0, 3, true, false) + +// Luminosity + RGB (eg for Dotstar) +// Luminosity chosen because the luminosity of a Dotstar at full bright +// burns the eyes like looking at the Sun. +// https://www.thesaurus.com/browse/luminosity?s=t +//| .. data:: LRGB +//| +//| * **order** *Luminosity*, Red, Green, Blue +//| * **bpp** 4 +//| * **has_luminosity** True +PIXELBUF_BYTEORDER(LRGB, 4, 1, 2, 3, 0, false, true) +//| .. data:: LRBG +//| +//| * **order** *Luminosity*, Red, Blue, Green +//| * **bpp** 4 +//| * **has_luminosity** True +PIXELBUF_BYTEORDER(LRBG, 4, 1, 3, 2, 0, false, true) +//| .. data:: LGRB +//| +//| * **order** *Luminosity*, Green, Red, Blue +//| * **bpp** 4 +//| * **has_luminosity** True +PIXELBUF_BYTEORDER(LGRB, 4, 2, 1, 3, 0, false, true) +//| .. data:: LGBR +//| +//| * **order** *Luminosity*, Green, Blue, Red +//| * **bpp** 4 +//| * **has_luminosity** True +PIXELBUF_BYTEORDER(LGBR, 4, 2, 3, 1, 0, false, true) +//| .. data:: LBRG +//| +//| * **order** *Luminosity*, Blue, Red, Green +//| * **bpp** 4 +//| * **has_luminosity** True +PIXELBUF_BYTEORDER(LBRG, 4, 3, 1, 2, 0, false, true) +//| .. data:: LBGR +//| +//| * **order** *Luminosity*, Blue, Green, Red +//| * **bpp** 4 +//| * **has_luminosity** True +//| +//| Actual format commonly used by DotStar (5 bit luninance value) +PIXELBUF_BYTEORDER(LBGR, 4, 3, 2, 1, 0, false, true) + +STATIC const mp_rom_map_elem_t pixelbuf_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__pixelbuf) }, + { MP_ROM_QSTR(MP_QSTR_PixelBuf), MP_ROM_PTR(&pixelbuf_pixelbuf_type) }, + { MP_ROM_QSTR(MP_QSTR_ByteOrder), MP_ROM_PTR(&pixelbuf_byteorder_type) }, + { MP_ROM_QSTR(MP_QSTR_RGB), MP_ROM_PTR(&byteorder_RGB) }, + { MP_ROM_QSTR(MP_QSTR_RBG), MP_ROM_PTR(&byteorder_RBG) }, + { MP_ROM_QSTR(MP_QSTR_GRB), MP_ROM_PTR(&byteorder_GRB) }, + { MP_ROM_QSTR(MP_QSTR_GBR), MP_ROM_PTR(&byteorder_GBR) }, + { MP_ROM_QSTR(MP_QSTR_BRG), MP_ROM_PTR(&byteorder_BRG) }, + { MP_ROM_QSTR(MP_QSTR_BGR), MP_ROM_PTR(&byteorder_BGR) }, + { MP_ROM_QSTR(MP_QSTR_RGBW), MP_ROM_PTR(&byteorder_RGBW) }, + { MP_ROM_QSTR(MP_QSTR_RBGW), MP_ROM_PTR(&byteorder_RBGW) }, + { MP_ROM_QSTR(MP_QSTR_GRBW), MP_ROM_PTR(&byteorder_GRBW) }, + { MP_ROM_QSTR(MP_QSTR_GBRW), MP_ROM_PTR(&byteorder_GBRW) }, + { MP_ROM_QSTR(MP_QSTR_BRGW), MP_ROM_PTR(&byteorder_BRGW) }, + { MP_ROM_QSTR(MP_QSTR_BGRW), MP_ROM_PTR(&byteorder_BGRW) }, + { MP_ROM_QSTR(MP_QSTR_LRGB), MP_ROM_PTR(&byteorder_LRGB) }, + { MP_ROM_QSTR(MP_QSTR_LRBG), MP_ROM_PTR(&byteorder_LRBG) }, + { MP_ROM_QSTR(MP_QSTR_LGRB), MP_ROM_PTR(&byteorder_LGRB) }, + { MP_ROM_QSTR(MP_QSTR_LGBR), MP_ROM_PTR(&byteorder_LGBR) }, + { MP_ROM_QSTR(MP_QSTR_LBRG), MP_ROM_PTR(&byteorder_LBRG) }, + { MP_ROM_QSTR(MP_QSTR_LBGR), MP_ROM_PTR(&byteorder_LBGR) }, + { MP_ROM_QSTR(MP_QSTR_wheel), MP_ROM_PTR(&pixelbuf_wheel_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(pixelbuf_module_globals, pixelbuf_module_globals_table); + +STATIC void pixelbuf_byteorder_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + pixelbuf_byteorder_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_printf(print, "%q.%q", MP_QSTR__pixelbuf, self->name); + return; +} + +const mp_obj_module_t pixelbuf_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&pixelbuf_module_globals, +}; diff --git a/shared-bindings/_pixelbuf/__init__.h b/shared-bindings/_pixelbuf/__init__.h new file mode 100644 index 00000000000..a62d67c4a44 --- /dev/null +++ b/shared-bindings/_pixelbuf/__init__.h @@ -0,0 +1,37 @@ +/* + * This file is part of the Circuit Python project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Roy Hooper + * + * 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. + */ + +#ifndef CP_SHARED_BINDINGS_PIXELBUF_INIT_H +#define CP_SHARED_BINDINGS_PIXELBUF_INIT_H + +#include "common-hal/digitalio/DigitalInOut.h" + +STATIC void pixelbuf_byteorder_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); +const int32_t colorwheel(float pos); +const mp_obj_type_t pixelbuf_byteorder_type; +extern void common_hal_neopixel_write(const digitalio_digitalinout_obj_t* gpio, uint8_t *pixels, uint32_t numBytes); + +#endif //CP_SHARED_BINDINGS_PIXELBUF_INIT_H diff --git a/shared-bindings/_pixelbuf/types.h b/shared-bindings/_pixelbuf/types.h new file mode 100644 index 00000000000..f7d757791bf --- /dev/null +++ b/shared-bindings/_pixelbuf/types.h @@ -0,0 +1,48 @@ +/* + * This file is part of the Circuit Python project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Roy Hooper + * + * 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. + */ + +#ifndef CIRCUITPYTHON_PIXELBUF_TYPES_H +#define CIRCUITPYTHON_PIXELBUF_TYPES_H + +//| :orphan: + +typedef struct { + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t w; +} pixelbuf_rgbw_t; + +typedef struct { + mp_obj_base_t base; + qstr name; + uint8_t bpp; + pixelbuf_rgbw_t byteorder; + bool has_white; + bool has_luminosity; +} pixelbuf_byteorder_obj_t; + +#endif // CIRCUITPYTHON_PIXELBUF_TYPES_H diff --git a/shared-bindings/_stage/Layer.c b/shared-bindings/_stage/Layer.c new file mode 100644 index 00000000000..12028b13197 --- /dev/null +++ b/shared-bindings/_stage/Layer.c @@ -0,0 +1,131 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Radomir Dopieralski + * + * 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 + +#include "__init__.h" +#include "Layer.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: _stage +//| +//| :class:`Layer` -- Keep information about a single layer of graphics +//| =================================================================== +//| +//| .. class:: Layer(width, height, graphic, palette, [grid]) +//| +//| Keep internal information about a layer of graphics (either a +//| ``Grid`` or a ``Sprite``) in a format suitable for fast rendering +//| with the ``render()`` function. +//| +//| :param int width: The width of the grid in tiles, or 1 for sprites. +//| :param int height: The height of the grid in tiles, or 1 for sprites. +//| :param bytearray graphic: The graphic data of the tiles. +//| :param bytearray palette: The color palette to be used. +//| :param bytearray grid: The contents of the grid map. +//| +//| This class is intended for internal use in the ``stage`` library and +//| it shouldn't be used on its own. +//| +STATIC mp_obj_t layer_make_new(const mp_obj_type_t *type, size_t n_args, + const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 4, 5, false); + + layer_obj_t *self = m_new_obj(layer_obj_t); + self->base.type = type; + + self->width = mp_obj_get_int(args[0]); + self->height = mp_obj_get_int(args[1]); + self->x = 0; + self->y = 0; + self->frame = 0; + self->rotation = false; + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ); + self->graphic = bufinfo.buf; + if (bufinfo.len != 2048) { + mp_raise_ValueError(translate("graphic must be 2048 bytes long")); + } + + mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); + self->palette = bufinfo.buf; + if (bufinfo.len != 32) { + mp_raise_ValueError(translate("palette must be 32 bytes long")); + } + + if (n_args > 4) { + mp_get_buffer_raise(args[4], &bufinfo, MP_BUFFER_READ); + self->map = bufinfo.buf; + if (bufinfo.len < (self->width * self->height) / 2) { + mp_raise_ValueError(translate("map buffer too small")); + } + } else { + self-> map = NULL; + } + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: move(x, y) +//| +//| Set the offset of the layer to the specified values. +//| +STATIC mp_obj_t layer_move(mp_obj_t self_in, mp_obj_t x_in, mp_obj_t y_in) { + layer_obj_t *self = MP_OBJ_TO_PTR(self_in); + self->x = mp_obj_get_int(x_in); + self->y = mp_obj_get_int(y_in); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(layer_move_obj, layer_move); + +//| .. method:: frame(frame, rotation) +//| +//| Set the animation frame of the sprite, and optionally rotation its +//| graphic. +//| +STATIC mp_obj_t layer_frame(mp_obj_t self_in, mp_obj_t frame_in, + mp_obj_t rotation_in) { + layer_obj_t *self = MP_OBJ_TO_PTR(self_in); + self->frame = mp_obj_get_int(frame_in); + self->rotation = mp_obj_get_int(rotation_in); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(layer_frame_obj, layer_frame); + + +STATIC const mp_rom_map_elem_t layer_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_move), MP_ROM_PTR(&layer_move_obj) }, + { MP_ROM_QSTR(MP_QSTR_frame), MP_ROM_PTR(&layer_frame_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(layer_locals_dict, layer_locals_dict_table); + +const mp_obj_type_t mp_type_layer = { + { &mp_type_type }, + .name = MP_QSTR_Layer, + .make_new = layer_make_new, + .locals_dict = (mp_obj_dict_t*)&layer_locals_dict, +}; diff --git a/shared-bindings/_stage/Layer.h b/shared-bindings/_stage/Layer.h new file mode 100644 index 00000000000..6d15dfb288d --- /dev/null +++ b/shared-bindings/_stage/Layer.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Radomir Dopieralski + * + * 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. + */ + +#ifndef MICROPY_INCLUDED__STAGE_LAYER_H +#define MICROPY_INCLUDED__STAGE_LAYER_H + +#include "shared-module/_stage/Layer.h" + +extern const mp_obj_type_t mp_type_layer; + +#endif // MICROPY_INCLUDED__STAGE_LAYER diff --git a/shared-bindings/_stage/Text.c b/shared-bindings/_stage/Text.c new file mode 100644 index 00000000000..49c1d00ca8a --- /dev/null +++ b/shared-bindings/_stage/Text.c @@ -0,0 +1,110 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Radomir Dopieralski + * + * 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 + +#include "__init__.h" +#include "Text.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: _stage +//| +//| :class:`Text` -- Keep information about a single text of text +//| ============================================================== +//| +//| .. class:: Text(width, height, font, palette, chars) +//| +//| Keep internal information about a text of text +//| in a format suitable for fast rendering +//| with the ``render()`` function. +//| +//| :param int width: The width of the grid in tiles, or 1 for sprites. +//| :param int height: The height of the grid in tiles, or 1 for sprites. +//| :param bytearray font: The font data of the characters. +//| :param bytearray palette: The color palette to be used. +//| :param bytearray chars: The contents of the character grid. +//| +//| This class is intended for internal use in the ``stage`` library and +//| it shouldn't be used on its own. +//| +STATIC mp_obj_t text_make_new(const mp_obj_type_t *type, size_t n_args, + const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 5, 5, false); + + text_obj_t *self = m_new_obj(text_obj_t); + self->base.type = type; + + self->width = mp_obj_get_int(args[0]); + self->height = mp_obj_get_int(args[1]); + self->x = 0; + self->y = 0; + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ); + self->font = bufinfo.buf; + if (bufinfo.len != 2048) { + mp_raise_ValueError(translate("font must be 2048 bytes long")); + } + + mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); + self->palette = bufinfo.buf; + if (bufinfo.len != 32) { + mp_raise_ValueError(translate("palette must be 32 bytes long")); + } + + mp_get_buffer_raise(args[4], &bufinfo, MP_BUFFER_READ); + self->chars = bufinfo.buf; + if (bufinfo.len < self->width * self->height) { + mp_raise_ValueError(translate("chars buffer too small")); + } + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: move(x, y) +//| +//| Set the offset of the text to the specified values. +//| +STATIC mp_obj_t text_move(mp_obj_t self_in, mp_obj_t x_in, mp_obj_t y_in) { + text_obj_t *self = MP_OBJ_TO_PTR(self_in); + self->x = mp_obj_get_int(x_in); + self->y = mp_obj_get_int(y_in); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(text_move_obj, text_move); + + +STATIC const mp_rom_map_elem_t text_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_move), MP_ROM_PTR(&text_move_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(text_locals_dict, text_locals_dict_table); + +const mp_obj_type_t mp_type_text = { + { &mp_type_type }, + .name = MP_QSTR_Text, + .make_new = text_make_new, + .locals_dict = (mp_obj_dict_t*)&text_locals_dict, +}; diff --git a/shared-bindings/_stage/Text.h b/shared-bindings/_stage/Text.h new file mode 100644 index 00000000000..77de62a110d --- /dev/null +++ b/shared-bindings/_stage/Text.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Radomir Dopieralski + * + * 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. + */ + +#ifndef MICROPY_INCLUDED__STAGE_TEXT_H +#define MICROPY_INCLUDED__STAGE_TEXT_H + +#include "shared-module/_stage/Text.h" + +extern const mp_obj_type_t mp_type_text; + +#endif // MICROPY_INCLUDED__STAGE_TEXT diff --git a/shared-bindings/_stage/__init__.c b/shared-bindings/_stage/__init__.c new file mode 100644 index 00000000000..d18d306f443 --- /dev/null +++ b/shared-bindings/_stage/__init__.c @@ -0,0 +1,132 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Radomir Dopieralski + * + * 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 "__init__.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/Display.h" +#include "shared-module/_stage/__init__.h" +#include "shared-module/displayio/display_core.h" +#include "Layer.h" +#include "Text.h" + +//| :mod:`_stage` --- C-level helpers for animation of sprites on a stage +//| ===================================================================== +//| +//| .. module:: _stage +//| :synopsis: C-level helpers for animation of sprites on a stage +//| :platform: SAMD21 +//| +//| The `_stage` module contains native code to speed-up the ```stage`` Library +//| `_. +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Layer +//| Text +//| +//| .. function:: render(x0, y0, x1, y1, layers, buffer, display[, scale]) +//| +//| Render and send to the display a fragment of the screen. +//| +//| :param int x0: Left edge of the fragment. +//| :param int y0: Top edge of the fragment. +//| :param int x1: Right edge of the fragment. +//| :param int y1: Bottom edge of the fragment. +//| :param list layers: A list of the :py:class:`~_stage.Layer` objects. +//| :param bytearray buffer: A buffer to use for rendering. +//| :param ~displayio.Display display: The display to use. +//| :param int scale: How many times should the image be scaled up. +//| +//| There are also no sanity checks, outside of the basic overflow +//| checking. The caller is responsible for making the passed parameters +//| valid. +//| +//| This function is intended for internal use in the ``stage`` library +//| and all the necessary checks are performed there. +STATIC mp_obj_t stage_render(size_t n_args, const mp_obj_t *args) { + uint16_t x0 = mp_obj_get_int(args[0]); + uint16_t y0 = mp_obj_get_int(args[1]); + uint16_t x1 = mp_obj_get_int(args[2]); + uint16_t y1 = mp_obj_get_int(args[3]); + + size_t layers_size = 0; + mp_obj_t *layers; + mp_obj_get_array(args[4], &layers_size, &layers); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[5], &bufinfo, MP_BUFFER_WRITE); + uint16_t *buffer = bufinfo.buf; + size_t buffer_size = bufinfo.len / 2; // 16-bit indexing + + mp_obj_t native_display = mp_instance_cast_to_native_base(args[6], + &displayio_display_type); + if (!MP_OBJ_IS_TYPE(native_display, &displayio_display_type)) { + mp_raise_TypeError(translate("argument num/types mismatch")); + } + displayio_display_obj_t *display = MP_OBJ_TO_PTR(native_display); + uint8_t scale = 1; + if (n_args >= 8) { + scale = mp_obj_get_int(args[7]); + } + + // TODO: Everything below should be in shared-module because it's not argument parsing. + while (!displayio_display_core_begin_transaction(&display->core)) { + RUN_BACKGROUND_TASKS; + } + displayio_area_t area; + area.x1 = x0; + area.y1 = y0; + area.x2 = x1; + area.y2 = y1; + displayio_display_core_set_region_to_update(&display->core, display->set_column_command, display->set_row_command, NO_COMMAND, NO_COMMAND, display->data_as_commands, false, &area); + + display->core.send(display->core.bus, DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, &display->write_ram_command, 1); + render_stage(x0, y0, x1, y1, layers, layers_size, buffer, buffer_size, + display, scale); + displayio_display_core_end_transaction(&display->core); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stage_render_obj, 7, 8, stage_render); + + +STATIC const mp_rom_map_elem_t stage_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__stage) }, + { MP_ROM_QSTR(MP_QSTR_Layer), MP_ROM_PTR(&mp_type_layer) }, + { MP_ROM_QSTR(MP_QSTR_Text), MP_ROM_PTR(&mp_type_text) }, + { MP_ROM_QSTR(MP_QSTR_render), MP_ROM_PTR(&stage_render_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(stage_module_globals, stage_module_globals_table); + +const mp_obj_module_t stage_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&stage_module_globals, +}; diff --git a/shared-bindings/_stage/__init__.h b/shared-bindings/_stage/__init__.h new file mode 100644 index 00000000000..2df81cb3b2d --- /dev/null +++ b/shared-bindings/_stage/__init__.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Radomir Dopieralski + * + * 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. + */ + +#ifndef MICROPY_INCLUDED__STAGE_H +#define MICROPY_INCLUDED__STAGE_H + +#include "shared-module/_stage/__init__.h" + +#endif // MICROPY_INCLUDED__STAGE diff --git a/shared-bindings/analogio/AnalogIn.c b/shared-bindings/analogio/AnalogIn.c new file mode 100644 index 00000000000..a8bbbf59af9 --- /dev/null +++ b/shared-bindings/analogio/AnalogIn.c @@ -0,0 +1,168 @@ +/* + * 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 + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/mphal.h" +#include "py/nlr.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/analogio/AnalogIn.h" +#include "shared-bindings/util.h" + +//| .. currentmodule:: analogio +//| +//| :class:`AnalogIn` -- read analog voltage +//| ============================================ +//| +//| Usage:: +//| +//| import analogio +//| from board import * +//| +//| adc = analogio.AnalogIn(A1) +//| val = adc.value +//| + +//| .. class:: AnalogIn(pin) +//| +//| Use the AnalogIn on the given pin. The reference voltage varies by +//| platform so use ``reference_voltage`` to read the configured setting. +//| +//| :param ~microcontroller.Pin pin: the pin to read from +//| +STATIC mp_obj_t analogio_analogin_make_new(const mp_obj_type_t *type, + mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + // check number of arguments + mp_arg_check_num(n_args, kw_args, 1, 1, false); + + // 1st argument is the pin + mp_obj_t pin_obj = args[0]; + assert_pin(pin_obj, false); + + analogio_analogin_obj_t *self = m_new_obj(analogio_analogin_obj_t); + self->base.type = &analogio_analogin_type; + const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj); + assert_pin_free(pin); + common_hal_analogio_analogin_construct(self, pin); + + return (mp_obj_t) self; +} + +//| .. method:: deinit() +//| +//| Turn off the AnalogIn and release the pin for other use. +//| +STATIC mp_obj_t analogio_analogin_deinit(mp_obj_t self_in) { + analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_analogio_analogin_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_deinit_obj, analogio_analogin_deinit); + +STATIC void check_for_deinit(analogio_analogin_obj_t *self) { + if (common_hal_analogio_analogin_deinited(self)) { + raise_deinited_error(); + } +} +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t analogio_analogin___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_analogio_analogin_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogin___exit___obj, 4, 4, analogio_analogin___exit__); + +//| .. attribute:: value +//| +//| The value on the analog pin between 0 and 65535 inclusive (16-bit). (read-only) +//| +//| Even if the underlying analog to digital converter (ADC) is lower +//| resolution, the value is 16-bit. +//| +STATIC mp_obj_t analogio_analogin_obj_get_value(mp_obj_t self_in) { + analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_analogio_analogin_get_value(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_get_value_obj, analogio_analogin_obj_get_value); + +const mp_obj_property_t analogio_analogin_value_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&analogio_analogin_get_value_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: reference_voltage +//| +//| The maximum voltage measurable (also known as the reference voltage) as a +//| `float` in Volts. +//| +STATIC mp_obj_t analogio_analogin_obj_get_reference_voltage(mp_obj_t self_in) { + analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_float(common_hal_analogio_analogin_get_reference_voltage(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_get_reference_voltage_obj, + analogio_analogin_obj_get_reference_voltage); + +const mp_obj_property_t analogio_analogin_reference_voltage_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&analogio_analogin_get_reference_voltage_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t analogio_analogin_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&analogio_analogin_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&analogio_analogin___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&analogio_analogin_value_obj)}, + { MP_ROM_QSTR(MP_QSTR_reference_voltage), MP_ROM_PTR(&analogio_analogin_reference_voltage_obj)}, +}; + +STATIC MP_DEFINE_CONST_DICT(analogio_analogin_locals_dict, analogio_analogin_locals_dict_table); + +const mp_obj_type_t analogio_analogin_type = { + { &mp_type_type }, + .name = MP_QSTR_AnalogIn, + .make_new = analogio_analogin_make_new, + .locals_dict = (mp_obj_t)&analogio_analogin_locals_dict, +}; diff --git a/shared-bindings/analogio/AnalogIn.h b/shared-bindings/analogio/AnalogIn.h new file mode 100644 index 00000000000..4aa7fca233c --- /dev/null +++ b/shared-bindings/analogio/AnalogIn.h @@ -0,0 +1,41 @@ +/* + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO_ANALOGIN_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO_ANALOGIN_H + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/analogio/AnalogIn.h" + +extern const mp_obj_type_t analogio_analogin_type; + +void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, const mcu_pin_obj_t *pin); +void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t* self); +bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t* self); +uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t* self); +float common_hal_analogio_analogin_get_reference_voltage(analogio_analogin_obj_t* self); + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO_ANALOGIN_H__ diff --git a/shared-bindings/analogio/AnalogOut.c b/shared-bindings/analogio/AnalogOut.c new file mode 100644 index 00000000000..0816da4657d --- /dev/null +++ b/shared-bindings/analogio/AnalogOut.c @@ -0,0 +1,151 @@ +/* + * 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 +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/analogio/AnalogOut.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: analogio +//| +//| :class:`AnalogOut` -- output analog voltage +//| ============================================ +//| +//| The AnalogOut is used to output analog values (a specific voltage). +//| +//| Example usage:: +//| +//| import analogio +//| from microcontroller import pin +//| +//| dac = analogio.AnalogOut(pin.PA02) # output on pin PA02 +//| dac.value = 32768 # makes PA02 1.65V +//| + +//| .. class:: AnalogOut(pin) +//| +//| Use the AnalogOut on the given pin. +//| +//| :param ~microcontroller.Pin pin: the pin to output to +//| +STATIC mp_obj_t analogio_analogout_make_new(const mp_obj_type_t *type, mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + // check arguments + mp_arg_check_num(n_args, kw_args, 1, 1, false); + + assert_pin(args[0], false); + const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(args[0]); + + analogio_analogout_obj_t *self = m_new_obj(analogio_analogout_obj_t); + self->base.type = &analogio_analogout_type; + assert_pin_free(pin); + common_hal_analogio_analogout_construct(self, pin); + + return self; +} + +//| .. method:: deinit() +//| +//| Turn off the AnalogOut and release the pin for other use. +//| +STATIC mp_obj_t analogio_analogout_deinit(mp_obj_t self_in) { + analogio_analogout_obj_t *self = self_in; + + common_hal_analogio_analogout_deinit(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogout_deinit_obj, analogio_analogout_deinit); + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t analogio_analogout___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_analogio_analogout_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogout___exit___obj, 4, 4, analogio_analogout___exit__); + +//| .. attribute:: value +//| +//| The value on the analog pin between 0 and 65535 inclusive (16-bit). (write-only) +//| +//| Even if the underlying digital to analog converter (DAC) is lower +//| resolution, the value is 16-bit. +STATIC mp_obj_t analogio_analogout_obj_set_value(mp_obj_t self_in, mp_obj_t value) { + analogio_analogout_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (common_hal_analogio_analogout_deinited(self)) { + raise_deinited_error(); + } + uint32_t v = mp_obj_get_int(value); + if (v >= (1 << 16)) { + mp_raise_ValueError(translate("AnalogOut is only 16 bits. Value must be less than 65536.")); + } + common_hal_analogio_analogout_set_value(self, v); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(analogio_analogout_set_value_obj, analogio_analogout_obj_set_value); + +const mp_obj_property_t analogio_analogout_value_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&analogio_analogout_set_value_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t analogio_analogout_locals_dict_table[] = { + // instance methods + { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&analogio_analogout_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&analogio_analogout___exit___obj) }, + + // Properties + { MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&analogio_analogout_value_obj }, +}; + +STATIC MP_DEFINE_CONST_DICT(analogio_analogout_locals_dict, analogio_analogout_locals_dict_table); + +const mp_obj_type_t analogio_analogout_type = { + { &mp_type_type }, + .name = MP_QSTR_AnalogOut, + .make_new = analogio_analogout_make_new, + .locals_dict = (mp_obj_t)&analogio_analogout_locals_dict, +}; diff --git a/shared-bindings/analogio/AnalogOut.h b/shared-bindings/analogio/AnalogOut.h new file mode 100644 index 00000000000..6fe5d9b193c --- /dev/null +++ b/shared-bindings/analogio/AnalogOut.h @@ -0,0 +1,40 @@ +/* + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO_ANALOGOUT_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO_ANALOGOUT_H + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/analogio/AnalogOut.h" + +extern const mp_obj_type_t analogio_analogout_type; + +void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self, const mcu_pin_obj_t *pin); +void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self); +bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self); +void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, uint16_t value); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO_ANALOGOUT_H diff --git a/shared-bindings/analogio/__init__.c b/shared-bindings/analogio/__init__.c new file mode 100644 index 00000000000..b468bcde0c5 --- /dev/null +++ b/shared-bindings/analogio/__init__.c @@ -0,0 +1,87 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/analogio/__init__.h" +#include "shared-bindings/analogio/AnalogIn.h" +#include "shared-bindings/analogio/AnalogOut.h" + +//| :mod:`analogio` --- Analog hardware support +//| ================================================= +//| +//| .. module:: analogio +//| :synopsis: Analog hardware support +//| :platform: SAMD21, ESP8266 +//| +//| The `analogio` module contains classes to provide access to analog IO +//| typically implemented with digital-to-analog (DAC) and analog-to-digital +//| (ADC) converters. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| AnalogIn +//| AnalogOut +//| +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed if the program continues after use. To do so, either +//| call :py:meth:`!deinit` or use a context manager. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +//| For example:: +//| +//| import analogio +//| from board import * +//| +//| pin = analogio.AnalogIn(A0) +//| print(pin.value) +//| pin.deinit() +//| +//| This example will initialize the the device, read +//| :py:data:`~analogio.AnalogIn.value` and then +//| :py:meth:`~analogio.AnalogIn.deinit` the hardware. The last step is optional +//| because CircuitPython will do it automatically after the program finishes. +//| + +STATIC const mp_rom_map_elem_t analogio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_analogio) }, + { MP_ROM_QSTR(MP_QSTR_AnalogIn), MP_ROM_PTR(&analogio_analogin_type) }, + { MP_ROM_QSTR(MP_QSTR_AnalogOut), MP_ROM_PTR(&analogio_analogout_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(analogio_module_globals, analogio_module_globals_table); + +const mp_obj_module_t analogio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&analogio_module_globals, +}; diff --git a/shared-bindings/analogio/__init__.h b/shared-bindings/analogio/__init__.h new file mode 100644 index 00000000000..284a95b6de8 --- /dev/null +++ b/shared-bindings/analogio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO___INIT___H + +#include "py/obj.h" + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO___INIT___H diff --git a/shared-bindings/audiobusio/I2SOut.c b/shared-bindings/audiobusio/I2SOut.c new file mode 100644 index 00000000000..9bce9c76097 --- /dev/null +++ b/shared-bindings/audiobusio/I2SOut.c @@ -0,0 +1,290 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/audiobusio/I2SOut.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: audiobusio +//| +//| :class:`I2SOut` -- Output an I2S audio signal +//| ======================================================== +//| +//| I2S is used to output an audio signal on an I2S bus. +//| +//| .. class:: I2SOut(bit_clock, word_select, data, *, left_justified) +//| +//| Create a I2SOut object associated with the given pins. +//| +//| :param ~microcontroller.Pin bit_clock: The bit clock (or serial clock) pin +//| :param ~microcontroller.Pin word_select: The word select (or left/right clock) pin +//| :param ~microcontroller.Pin data: The data pin +//| :param bool left_justified: True when data bits are aligned with the word select clock. False +//| when they are shifted by one to match classic I2S protocol. +//| +//| Simple 8ksps 440 Hz sine wave on `Metro M0 Express `_ +//| using `UDA1334 Breakout `_:: +//| +//| import audiobusio +//| import audiocore +//| import board +//| import array +//| import time +//| import math +//| +//| # Generate one period of sine wav. +//| length = 8000 // 440 +//| sine_wave = array.array("H", [0] * length) +//| for i in range(length): +//| sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15) + 2 ** 15) +//| +//| sine_wave = audiocore.RawSample(sine_wave, sample_rate=8000) +//| i2s = audiobusio.I2SOut(board.D1, board.D0, board.D9) +//| i2s.play(sine_wave, loop=True) +//| time.sleep(1) +//| i2s.stop() +//| +//| Playing a wave file from flash:: +//| +//| import board +//| import audioio +//| import audiocore +//| import audiobusio +//| import digitalio +//| +//| +//| f = open("cplay-5.1-16bit-16khz.wav", "rb") +//| wav = audiocore.WaveFile(f) +//| +//| a = audiobusio.I2SOut(board.D1, board.D0, board.D9) +//| +//| print("playing") +//| a.play(wav) +//| while a.playing: +//| pass +//| print("stopped") +//| +STATIC mp_obj_t audiobusio_i2sout_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_bit_clock, ARG_word_select, ARG_data, ARG_left_justified }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_bit_clock, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_word_select, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_data, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_left_justified, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t bit_clock_obj = args[ARG_bit_clock].u_obj; + assert_pin(bit_clock_obj, false); + const mcu_pin_obj_t *bit_clock = MP_OBJ_TO_PTR(bit_clock_obj); + + mp_obj_t word_select_obj = args[ARG_word_select].u_obj; + assert_pin(word_select_obj, false); + const mcu_pin_obj_t *word_select = MP_OBJ_TO_PTR(word_select_obj); + + mp_obj_t data_obj = args[ARG_data].u_obj; + assert_pin(data_obj, false); + const mcu_pin_obj_t *data = MP_OBJ_TO_PTR(data_obj); + + audiobusio_i2sout_obj_t *self = m_new_obj(audiobusio_i2sout_obj_t); + self->base.type = &audiobusio_i2sout_type; + common_hal_audiobusio_i2sout_construct(self, bit_clock, word_select, data, args[ARG_left_justified].u_bool); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialises the I2SOut and releases any hardware resources for reuse. +//| +STATIC mp_obj_t audiobusio_i2sout_deinit(mp_obj_t self_in) { + audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiobusio_i2sout_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_deinit_obj, audiobusio_i2sout_deinit); + +STATIC void check_for_deinit(audiobusio_i2sout_obj_t *self) { + if (common_hal_audiobusio_i2sout_deinited(self)) { + raise_deinited_error(); + } +} +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t audiobusio_i2sout_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_audiobusio_i2sout_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiobusio_i2sout___exit___obj, 4, 4, audiobusio_i2sout_obj___exit__); + + +//| .. method:: play(sample, *, loop=False) +//| +//| Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiocore.Mixer`. +//| +//| The sample itself should consist of 8 bit or 16 bit samples. +//| +STATIC mp_obj_t audiobusio_i2sout_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audiobusio_i2sout_play(self, sample, args[ARG_loop].u_bool); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiobusio_i2sout_play_obj, 1, audiobusio_i2sout_obj_play); + +//| .. method:: stop() +//| +//| Stops playback. +//| +STATIC mp_obj_t audiobusio_i2sout_obj_stop(mp_obj_t self_in) { + audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_audiobusio_i2sout_stop(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_stop_obj, audiobusio_i2sout_obj_stop); + +//| .. attribute:: playing +//| +//| True when the audio sample is being output. (read-only) +//| +STATIC mp_obj_t audiobusio_i2sout_obj_get_playing(mp_obj_t self_in) { + audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audiobusio_i2sout_get_playing(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_get_playing_obj, audiobusio_i2sout_obj_get_playing); + +const mp_obj_property_t audiobusio_i2sout_playing_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audiobusio_i2sout_get_playing_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: pause() +//| +//| Stops playback temporarily while remembering the position. Use `resume` to resume playback. +//| +STATIC mp_obj_t audiobusio_i2sout_obj_pause(mp_obj_t self_in) { + audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + if (!common_hal_audiobusio_i2sout_get_playing(self)) { + mp_raise_RuntimeError(translate("Not playing")); + } + common_hal_audiobusio_i2sout_pause(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_pause_obj, audiobusio_i2sout_obj_pause); + +//| .. method:: resume() +//| +//| Resumes sample playback after :py:func:`pause`. +//| +STATIC mp_obj_t audiobusio_i2sout_obj_resume(mp_obj_t self_in) { + audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + if (common_hal_audiobusio_i2sout_get_paused(self)) { + common_hal_audiobusio_i2sout_resume(self); + } + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_resume_obj, audiobusio_i2sout_obj_resume); + +//| .. attribute:: paused +//| +//| True when playback is paused. (read-only) +//| +STATIC mp_obj_t audiobusio_i2sout_obj_get_paused(mp_obj_t self_in) { + audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audiobusio_i2sout_get_paused(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_get_paused_obj, audiobusio_i2sout_obj_get_paused); + +const mp_obj_property_t audiobusio_i2sout_paused_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audiobusio_i2sout_get_paused_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t audiobusio_i2sout_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiobusio_i2sout_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiobusio_i2sout___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiobusio_i2sout_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiobusio_i2sout_stop_obj) }, + { MP_ROM_QSTR(MP_QSTR_pause), MP_ROM_PTR(&audiobusio_i2sout_pause_obj) }, + { MP_ROM_QSTR(MP_QSTR_resume), MP_ROM_PTR(&audiobusio_i2sout_resume_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiobusio_i2sout_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_paused), MP_ROM_PTR(&audiobusio_i2sout_paused_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(audiobusio_i2sout_locals_dict, audiobusio_i2sout_locals_dict_table); + +const mp_obj_type_t audiobusio_i2sout_type = { + { &mp_type_type }, + .name = MP_QSTR_I2SOut, + .make_new = audiobusio_i2sout_make_new, + .locals_dict = (mp_obj_dict_t*)&audiobusio_i2sout_locals_dict, +}; diff --git a/shared-bindings/audiobusio/I2SOut.h b/shared-bindings/audiobusio/I2SOut.h new file mode 100644 index 00000000000..edf4ecfa0ba --- /dev/null +++ b/shared-bindings/audiobusio/I2SOut.h @@ -0,0 +1,48 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOBUSIO_I2SOUT_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOBUSIO_I2SOUT_H + +#include "common-hal/audiobusio/I2SOut.h" +#include "common-hal/microcontroller/Pin.h" + +extern const mp_obj_type_t audiobusio_i2sout_type; + +void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t* self, + const mcu_pin_obj_t* bit_clock, const mcu_pin_obj_t* word_select, const mcu_pin_obj_t* data, + bool left_justified); + +void common_hal_audiobusio_i2sout_deinit(audiobusio_i2sout_obj_t* self); +bool common_hal_audiobusio_i2sout_deinited(audiobusio_i2sout_obj_t* self); +void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t* self, mp_obj_t sample, bool loop); +void common_hal_audiobusio_i2sout_stop(audiobusio_i2sout_obj_t* self); +bool common_hal_audiobusio_i2sout_get_playing(audiobusio_i2sout_obj_t* self); +void common_hal_audiobusio_i2sout_pause(audiobusio_i2sout_obj_t* self); +void common_hal_audiobusio_i2sout_resume(audiobusio_i2sout_obj_t* self); +bool common_hal_audiobusio_i2sout_get_paused(audiobusio_i2sout_obj_t* self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOBUSIO_I2SOUT_H diff --git a/shared-bindings/audiobusio/PDMIn.c b/shared-bindings/audiobusio/PDMIn.c new file mode 100644 index 00000000000..0c92c247804 --- /dev/null +++ b/shared-bindings/audiobusio/PDMIn.c @@ -0,0 +1,258 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/mphal.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/audiobusio/PDMIn.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: audiobusio +//| +//| :class:`PDMIn` -- Record an input PDM audio stream +//| ======================================================== +//| +//| PDMIn can be used to record an input audio signal on a given set of pins. +//| +//| .. class:: PDMIn(clock_pin, data_pin, *, sample_rate=16000, bit_depth=8, mono=True, oversample=64, startup_delay=0.11) +//| +//| Create a PDMIn object associated with the given pins. This allows you to +//| record audio signals from the given pins. Individual ports may put further +//| restrictions on the recording parameters. The overall sample rate is +//| determined by `sample_rate` x ``oversample``, and the total must be 1MHz or +//| higher, so `sample_rate` must be a minimum of 16000. +//| +//| :param ~microcontroller.Pin clock_pin: The pin to output the clock to +//| :param ~microcontroller.Pin data_pin: The pin to read the data from +//| :param int sample_rate: Target sample_rate of the resulting samples. Check `sample_rate` for actual value. +//| Minimum sample_rate is about 16000 Hz. +//| :param int bit_depth: Final number of bits per sample. Must be divisible by 8 +//| :param bool mono: True when capturing a single channel of audio, captures two channels otherwise +//| :param int oversample: Number of single bit samples to decimate into a final sample. Must be divisible by 8 +//| :param float startup_delay: seconds to wait after starting microphone clock +//| to allow microphone to turn on. Most require only 0.01s; some require 0.1s. Longer is safer. +//| Must be in range 0.0-1.0 seconds. +//| + +//| Record 8-bit unsigned samples to buffer:: +//| +//| import audiobusio +//| import board +//| +//| # Prep a buffer to record into +//| b = bytearray(200) +//| with audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000) as mic: +//| mic.record(b, len(b)) +//| +//| Record 16-bit unsigned samples to buffer:: +//| +//| import audiobusio +//| import board +//| +//| # Prep a buffer to record into. The array interface doesn't allow for +//| # constructing with a set size so we append to it until we have the size +//| # we want. +//| b = array.array("H") +//| for i in range(200): +//| b.append(0) +//| with audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000, bit_depth=16) as mic: +//| mic.record(b, len(b)) +//| +STATIC mp_obj_t audiobusio_pdmin_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_clock_pin, ARG_data_pin, ARG_sample_rate, ARG_bit_depth, ARG_mono, ARG_oversample, ARG_startup_delay }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_clock_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_data_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_sample_rate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 16000} }, + { MP_QSTR_bit_depth, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, + { MP_QSTR_mono, MP_ARG_KW_ONLY | MP_ARG_BOOL,{.u_bool = true} }, + { MP_QSTR_oversample, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} }, + { MP_QSTR_startup_delay, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + }; + // Default microphone startup delay is 110msecs. Have seen mics that need 100 msecs plus a bit. + static const float STARTUP_DELAY_DEFAULT = 0.110F; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t clock_pin_obj = args[ARG_clock_pin].u_obj; + assert_pin(clock_pin_obj, false); + const mcu_pin_obj_t *clock_pin = MP_OBJ_TO_PTR(clock_pin_obj); + assert_pin_free(clock_pin); + + mp_obj_t data_pin_obj = args[ARG_data_pin].u_obj; + assert_pin(data_pin_obj, false); + const mcu_pin_obj_t *data_pin = MP_OBJ_TO_PTR(data_pin_obj); + assert_pin_free(data_pin); + + // create PDMIn object from the given pin + audiobusio_pdmin_obj_t *self = m_new_obj(audiobusio_pdmin_obj_t); + self->base.type = &audiobusio_pdmin_type; + + uint32_t sample_rate = args[ARG_sample_rate].u_int; + uint8_t bit_depth = args[ARG_bit_depth].u_int; + if (bit_depth % 8 != 0) { + mp_raise_ValueError(translate("Bit depth must be multiple of 8.")); + } + uint8_t oversample = args[ARG_oversample].u_int; + if (oversample % 8 != 0) { + mp_raise_ValueError(translate("Oversample must be multiple of 8.")); + } + bool mono = args[ARG_mono].u_bool; + + mp_float_t startup_delay = (args[ARG_startup_delay].u_obj == MP_OBJ_NULL) + ? (mp_float_t)STARTUP_DELAY_DEFAULT + : mp_obj_get_float(args[ARG_startup_delay].u_obj); + if (startup_delay < 0.0 || startup_delay > 1.0) { + mp_raise_ValueError(translate("Microphone startup delay must be in range 0.0 to 1.0")); + } + + common_hal_audiobusio_pdmin_construct(self, clock_pin, data_pin, sample_rate, + bit_depth, mono, oversample); + + // Wait for the microphone to start up. Some start in 10 msecs; some take as much as 100 msecs. + mp_hal_delay_ms(startup_delay * 1000); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialises the PDMIn and releases any hardware resources for reuse. +//| +STATIC mp_obj_t audiobusio_pdmin_deinit(mp_obj_t self_in) { + audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiobusio_pdmin_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_pdmin_deinit_obj, audiobusio_pdmin_deinit); + +STATIC void check_for_deinit(audiobusio_pdmin_obj_t *self) { + if (common_hal_audiobusio_pdmin_deinited(self)) { + raise_deinited_error(); + } +} +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. +//| +STATIC mp_obj_t audiobusio_pdmin_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_audiobusio_pdmin_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiobusio_pdmin___exit___obj, 4, 4, audiobusio_pdmin_obj___exit__); + + +//| .. method:: record(destination, destination_length) +//| +//| Records destination_length bytes of samples to destination. This is +//| blocking. +//| +//| An IOError may be raised when the destination is too slow to record the +//| audio at the given rate. For internal flash, writing all 1s to the file +//| before recording is recommended to speed up writes. +//| +//| :return: The number of samples recorded. If this is less than ``destination_length``, +//| some samples were missed due to processing time. +//| +STATIC mp_obj_t audiobusio_pdmin_obj_record(mp_obj_t self_obj, mp_obj_t destination, mp_obj_t destination_length) { + audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_obj); + check_for_deinit(self); + if (!MP_OBJ_IS_SMALL_INT(destination_length) || MP_OBJ_SMALL_INT_VALUE(destination_length) < 0) { + mp_raise_TypeError(translate("destination_length must be an int >= 0")); + } + uint32_t length = MP_OBJ_SMALL_INT_VALUE(destination_length); + + mp_buffer_info_t bufinfo; + if (MP_OBJ_IS_TYPE(destination, &mp_type_fileio)) { + mp_raise_NotImplementedError(translate("Cannot record to a file")); + } else if (mp_get_buffer(destination, &bufinfo, MP_BUFFER_WRITE)) { + if (bufinfo.len / mp_binary_get_size('@', bufinfo.typecode, NULL) < length) { + mp_raise_ValueError(translate("Destination capacity is smaller than destination_length.")); + } + uint8_t bit_depth = common_hal_audiobusio_pdmin_get_bit_depth(self); + if (bufinfo.typecode != 'H' && bit_depth == 16) { + mp_raise_ValueError(translate("destination buffer must be an array of type 'H' for bit_depth = 16")); + } else if (bufinfo.typecode != 'B' && bufinfo.typecode != BYTEARRAY_TYPECODE && bit_depth == 8) { + mp_raise_ValueError(translate("destination buffer must be a bytearray or array of type 'B' for bit_depth = 8")); + } + // length is the buffer length in slots, not bytes. + uint32_t length_written = + common_hal_audiobusio_pdmin_record_to_buffer(self, bufinfo.buf, length); + return MP_OBJ_NEW_SMALL_INT(length_written); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_3(audiobusio_pdmin_record_obj, audiobusio_pdmin_obj_record); + +//| .. attribute:: sample_rate +//| +//| The actual sample_rate of the recording. This may not match the constructed +//| sample rate due to internal clock limitations. +//| +STATIC mp_obj_t audiobusio_pdmin_obj_get_sample_rate(mp_obj_t self_in) { + audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_audiobusio_pdmin_get_sample_rate(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_pdmin_get_sample_rate_obj, audiobusio_pdmin_obj_get_sample_rate); + +const mp_obj_property_t audiobusio_pdmin_sample_rate_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audiobusio_pdmin_get_sample_rate_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t audiobusio_pdmin_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiobusio_pdmin_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiobusio_pdmin___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_record), MP_ROM_PTR(&audiobusio_pdmin_record_obj) }, + { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&audiobusio_pdmin_sample_rate_obj) } +}; +STATIC MP_DEFINE_CONST_DICT(audiobusio_pdmin_locals_dict, audiobusio_pdmin_locals_dict_table); + +const mp_obj_type_t audiobusio_pdmin_type = { + { &mp_type_type }, + .name = MP_QSTR_PDMIn, + .make_new = audiobusio_pdmin_make_new, + .locals_dict = (mp_obj_dict_t*)&audiobusio_pdmin_locals_dict, +}; diff --git a/shared-bindings/audiobusio/PDMIn.h b/shared-bindings/audiobusio/PDMIn.h new file mode 100644 index 00000000000..c2a8bab2f8e --- /dev/null +++ b/shared-bindings/audiobusio/PDMIn.h @@ -0,0 +1,47 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOBUSIO_AUDIOOUT_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOBUSIO_AUDIOOUT_H + +#include "common-hal/audiobusio/PDMIn.h" +#include "common-hal/microcontroller/Pin.h" +#include "extmod/vfs_fat.h" + +extern const mp_obj_type_t audiobusio_pdmin_type; + +void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t* self, + const mcu_pin_obj_t* clock_pin, const mcu_pin_obj_t* data_pin, + uint32_t sample_rate, uint8_t bit_depth, bool mono, uint8_t oversample); +void common_hal_audiobusio_pdmin_deinit(audiobusio_pdmin_obj_t* self); +bool common_hal_audiobusio_pdmin_deinited(audiobusio_pdmin_obj_t* self); +uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* self, + uint16_t* buffer, uint32_t length); +uint8_t common_hal_audiobusio_pdmin_get_bit_depth(audiobusio_pdmin_obj_t* self); +uint32_t common_hal_audiobusio_pdmin_get_sample_rate(audiobusio_pdmin_obj_t* self); +// TODO(tannewt): Add record to file + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOBUSIO_AUDIOOUT_H diff --git a/shared-bindings/audiobusio/__init__.c b/shared-bindings/audiobusio/__init__.c new file mode 100644 index 00000000000..f7e3a07668e --- /dev/null +++ b/shared-bindings/audiobusio/__init__.c @@ -0,0 +1,73 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/audiobusio/__init__.h" +#include "shared-bindings/audiobusio/I2SOut.h" +#include "shared-bindings/audiobusio/PDMIn.h" + +//| :mod:`audiobusio` --- Support for audio input and output over digital bus +//| ========================================================================= +//| +//| .. module:: audiobusio +//| :synopsis: Support for audio input and output over digital bus +//| :platform: SAMD21 +//| +//| The `audiobusio` module contains classes to provide access to audio IO +//| over digital buses. These protocols are used to communicate audio to other +//| chips in the same circuit. It doesn't include audio interconnect protocols +//| such as S/PDIF. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| I2SOut +//| PDMIn +//| +//| All libraries change hardware state and should be deinitialized when they +//| are no longer needed. To do so, either call :py:meth:`!deinit` or use a +//| context manager. +//| + +STATIC const mp_rom_map_elem_t audiobusio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiobusio) }, + { MP_ROM_QSTR(MP_QSTR_I2SOut), MP_ROM_PTR(&audiobusio_i2sout_type) }, + { MP_ROM_QSTR(MP_QSTR_PDMIn), MP_ROM_PTR(&audiobusio_pdmin_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(audiobusio_module_globals, audiobusio_module_globals_table); + +const mp_obj_module_t audiobusio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&audiobusio_module_globals, +}; diff --git a/shared-bindings/audiobusio/__init__.h b/shared-bindings/audiobusio/__init__.h new file mode 100644 index 00000000000..f7a0c3cf9da --- /dev/null +++ b/shared-bindings/audiobusio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOBUSIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOBUSIO___INIT___H + +#include "py/obj.h" + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOBUSIO___INIT___H diff --git a/shared-bindings/audiocore/Mixer.c b/shared-bindings/audiocore/Mixer.c new file mode 100644 index 00000000000..9ab720434b0 --- /dev/null +++ b/shared-bindings/audiocore/Mixer.c @@ -0,0 +1,253 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/audiocore/Mixer.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/audiocore/RawSample.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: audiocore +//| +//| :class:`Mixer` -- Mixes one or more audio samples together +//| =========================================================== +//| +//| Mixer mixes multiple samples into one sample. +//| +//| .. class:: Mixer(channel_count=2, buffer_size=1024) +//| +//| Create a Mixer object that can mix multiple channels with the same sample rate. +//| +//| :param int channel_count: The maximum number of samples to mix at once +//| :param int buffer_size: The total size in bytes of the buffers to mix into +//| +//| Playing a wave file from flash:: +//| +//| import board +//| import audioio +//| import audiocore +//| import digitalio +//| +//| # Required for CircuitPlayground Express +//| speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) +//| speaker_enable.switch_to_output(value=True) +//| +//| music = audiocore.WaveFile(open("cplay-5.1-16bit-16khz.wav", "rb")) +//| drum = audiocore.WaveFile(open("drum.wav", "rb")) +//| mixer = audiocore.Mixer(voice_count=2, sample_rate=16000, channel_count=1, bits_per_sample=16, samples_signed=True) +//| a = audioio.AudioOut(board.A0) +//| +//| print("playing") +//| a.play(mixer) +//| mixer.play(music, voice=0) +//| while mixer.playing: +//| mixer.play(drum, voice=1) +//| time.sleep(1) +//| print("stopped") +//| +STATIC mp_obj_t audioio_mixer_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_voice_count, ARG_buffer_size, ARG_channel_count, ARG_bits_per_sample, ARG_samples_signed, ARG_sample_rate }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_voice_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 2} }, + { MP_QSTR_buffer_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1024} }, + { MP_QSTR_channel_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 2} }, + { MP_QSTR_bits_per_sample, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { MP_QSTR_samples_signed, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 8000} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t voice_count = args[ARG_voice_count].u_int; + if (voice_count < 1 || voice_count > 255) { + mp_raise_ValueError(translate("Invalid voice count")); + } + + mp_int_t channel_count = args[ARG_channel_count].u_int; + if (channel_count < 1 || channel_count > 2) { + mp_raise_ValueError(translate("Invalid channel count")); + } + mp_int_t sample_rate = args[ARG_sample_rate].u_int; + if (sample_rate < 1) { + mp_raise_ValueError(translate("Sample rate must be positive")); + } + mp_int_t bits_per_sample = args[ARG_bits_per_sample].u_int; + if (bits_per_sample != 8 && bits_per_sample != 16) { + mp_raise_ValueError(translate("bits_per_sample must be 8 or 16")); + } + audioio_mixer_obj_t *self = m_new_obj_var(audioio_mixer_obj_t, audioio_mixer_voice_t, voice_count); + self->base.type = &audioio_mixer_type; + common_hal_audioio_mixer_construct(self, voice_count, args[ARG_buffer_size].u_int, bits_per_sample, args[ARG_samples_signed].u_bool, channel_count, sample_rate); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialises the Mixer and releases any hardware resources for reuse. +//| +STATIC mp_obj_t audioio_mixer_deinit(mp_obj_t self_in) { + audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audioio_mixer_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_deinit_obj, audioio_mixer_deinit); + +STATIC void check_for_deinit(audioio_mixer_obj_t *self) { + if (common_hal_audioio_mixer_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t audioio_mixer_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_audioio_mixer_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_mixer___exit___obj, 4, 4, audioio_mixer_obj___exit__); + + +//| .. method:: play(sample, *, voice=0, loop=False) +//| +//| Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiocore.Mixer`. +//| +//| The sample must match the Mixer's encoding settings given in the constructor. +//| +STATIC mp_obj_t audioio_mixer_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_voice, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_voice, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audioio_mixer_play(self, sample, args[ARG_voice].u_int, args[ARG_loop].u_bool); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(audioio_mixer_play_obj, 1, audioio_mixer_obj_play); + +//| .. method:: stop_voice(voice=0) +//| +//| Stops playback of the sample on the given voice. +//| +STATIC mp_obj_t audioio_mixer_obj_stop_voice(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_voice }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_voice, MP_ARG_INT, {.u_int = 0} }, + }; + audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + common_hal_audioio_mixer_stop_voice(self, args[ARG_voice].u_int); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(audioio_mixer_stop_voice_obj, 1, audioio_mixer_obj_stop_voice); + +//| .. attribute:: playing +//| +//| True when any voice is being output. (read-only) +//| +STATIC mp_obj_t audioio_mixer_obj_get_playing(mp_obj_t self_in) { + audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audioio_mixer_get_playing(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_get_playing_obj, audioio_mixer_obj_get_playing); + +const mp_obj_property_t audioio_mixer_playing_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audioio_mixer_get_playing_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: sample_rate +//| +//| 32 bit value that dictates how quickly samples are played in Hertz (cycles per second). +//| +STATIC mp_obj_t audioio_mixer_obj_get_sample_rate(mp_obj_t self_in) { + audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_mixer_get_sample_rate(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_get_sample_rate_obj, audioio_mixer_obj_get_sample_rate); + + +const mp_obj_property_t audioio_mixer_sample_rate_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audioio_mixer_get_sample_rate_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t audioio_mixer_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audioio_mixer_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audioio_mixer___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audioio_mixer_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop_voice), MP_ROM_PTR(&audioio_mixer_stop_voice_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audioio_mixer_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&audioio_mixer_sample_rate_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(audioio_mixer_locals_dict, audioio_mixer_locals_dict_table); + +const mp_obj_type_t audioio_mixer_type = { + { &mp_type_type }, + .name = MP_QSTR_Mixer, + .make_new = audioio_mixer_make_new, + .locals_dict = (mp_obj_dict_t*)&audioio_mixer_locals_dict, +}; diff --git a/shared-bindings/audiocore/Mixer.h b/shared-bindings/audiocore/Mixer.h new file mode 100644 index 00000000000..ef12f9a701a --- /dev/null +++ b/shared-bindings/audiocore/Mixer.h @@ -0,0 +1,52 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_MIXER_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_MIXER_H + +#include "common-hal/microcontroller/Pin.h" +#include "shared-module/audiocore/Mixer.h" +#include "shared-bindings/audiocore/RawSample.h" + +extern const mp_obj_type_t audioio_mixer_type; + +void common_hal_audioio_mixer_construct(audioio_mixer_obj_t* self, + uint8_t voice_count, + uint32_t buffer_size, + uint8_t bits_per_sample, + bool samples_signed, + uint8_t channel_count, + uint32_t sample_rate); + +void common_hal_audioio_mixer_deinit(audioio_mixer_obj_t* self); +bool common_hal_audioio_mixer_deinited(audioio_mixer_obj_t* self); +void common_hal_audioio_mixer_play(audioio_mixer_obj_t* self, mp_obj_t sample, uint8_t voice, bool loop); +void common_hal_audioio_mixer_stop_voice(audioio_mixer_obj_t* self, uint8_t voice); + +bool common_hal_audioio_mixer_get_playing(audioio_mixer_obj_t* self); +uint32_t common_hal_audioio_mixer_get_sample_rate(audioio_mixer_obj_t* self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_MIXER_H diff --git a/shared-bindings/audiocore/RawSample.c b/shared-bindings/audiocore/RawSample.c new file mode 100644 index 00000000000..07f8c683f29 --- /dev/null +++ b/shared-bindings/audiocore/RawSample.c @@ -0,0 +1,188 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "shared-bindings/audiocore/RawSample.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: audiocore +//| +//| :class:`RawSample` -- A raw audio sample buffer +//| ======================================================== +//| +//| An in-memory sound sample +//| +//| .. class:: RawSample(buffer, *, channel_count=1, sample_rate=8000) +//| +//| Create a RawSample based on the given buffer of signed values. If channel_count is more than +//| 1 then each channel's samples should alternate. In other words, for a two channel buffer, the +//| first sample will be for channel 1, the second sample will be for channel two, the third for +//| channel 1 and so on. +//| +//| :param array buffer: An `array.array` with samples +//| :param int channel_count: The number of channels in the buffer +//| :param int sample_rate: The desired playback sample rate +//| +//| Simple 8ksps 440 Hz sin wave:: +//| +//| import audiocore +//| import audioio +//| import board +//| import array +//| import time +//| import math +//| +//| # Generate one period of sine wav. +//| length = 8000 // 440 +//| sine_wave = array.array("h", [0] * length) +//| for i in range(length): +//| sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15)) +//| +//| dac = audioio.AudioOut(board.SPEAKER) +//| sine_wave = audiocore.RawSample(sine_wave) +//| dac.play(sine_wave, loop=True) +//| time.sleep(1) +//| dac.stop() +//| +STATIC mp_obj_t audioio_rawsample_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_buffer, ARG_channel_count, ARG_sample_rate }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_buffer, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_channel_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1 } }, + { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 8000} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + audioio_rawsample_obj_t *self = m_new_obj(audioio_rawsample_obj_t); + self->base.type = &audioio_rawsample_type; + mp_buffer_info_t bufinfo; + if (mp_get_buffer(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ)) { + uint8_t bytes_per_sample = 1; + bool signed_samples = bufinfo.typecode == 'b' || bufinfo.typecode == 'h'; + if (bufinfo.typecode == 'h' || bufinfo.typecode == 'H') { + bytes_per_sample = 2; + } else if (bufinfo.typecode != 'b' && bufinfo.typecode != 'B' && bufinfo.typecode != BYTEARRAY_TYPECODE) { + mp_raise_ValueError(translate("sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or 'B'")); + } + common_hal_audioio_rawsample_construct(self, ((uint8_t*)bufinfo.buf), bufinfo.len, + bytes_per_sample, signed_samples, args[ARG_channel_count].u_int, + args[ARG_sample_rate].u_int); + } else { + mp_raise_TypeError(translate("buffer must be a bytes-like object")); + } + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialises the AudioOut and releases any hardware resources for reuse. +//| +STATIC mp_obj_t audioio_rawsample_deinit(mp_obj_t self_in) { + audioio_rawsample_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audioio_rawsample_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_rawsample_deinit_obj, audioio_rawsample_deinit); + +STATIC void check_for_deinit(audioio_rawsample_obj_t *self) { + if (common_hal_audioio_rawsample_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t audioio_rawsample_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_audioio_rawsample_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_rawsample___exit___obj, 4, 4, audioio_rawsample_obj___exit__); + +//| .. attribute:: sample_rate +//| +//| 32 bit value that dictates how quickly samples are played in Hertz (cycles per second). +//| When the sample is looped, this can change the pitch output without changing the underlying +//| sample. This will not change the sample rate of any active playback. Call ``play`` again to +//| change it. +//| +STATIC mp_obj_t audioio_rawsample_obj_get_sample_rate(mp_obj_t self_in) { + audioio_rawsample_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_rawsample_get_sample_rate(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audioio_rawsample_get_sample_rate_obj, audioio_rawsample_obj_get_sample_rate); + +STATIC mp_obj_t audioio_rawsample_obj_set_sample_rate(mp_obj_t self_in, mp_obj_t sample_rate) { + audioio_rawsample_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_audioio_rawsample_set_sample_rate(self, mp_obj_get_int(sample_rate)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audioio_rawsample_set_sample_rate_obj, audioio_rawsample_obj_set_sample_rate); + +const mp_obj_property_t audioio_rawsample_sample_rate_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audioio_rawsample_get_sample_rate_obj, + (mp_obj_t)&audioio_rawsample_set_sample_rate_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t audioio_rawsample_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audioio_rawsample_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audioio_rawsample___exit___obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&audioio_rawsample_sample_rate_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(audioio_rawsample_locals_dict, audioio_rawsample_locals_dict_table); + +const mp_obj_type_t audioio_rawsample_type = { + { &mp_type_type }, + .name = MP_QSTR_RawSample, + .make_new = audioio_rawsample_make_new, + .locals_dict = (mp_obj_dict_t*)&audioio_rawsample_locals_dict, +}; diff --git a/shared-bindings/audiocore/RawSample.h b/shared-bindings/audiocore/RawSample.h new file mode 100644 index 00000000000..b02778cad3b --- /dev/null +++ b/shared-bindings/audiocore/RawSample.h @@ -0,0 +1,44 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_RAWSAMPLE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_RAWSAMPLE_H + +#include "common-hal/microcontroller/Pin.h" +#include "shared-module/audiocore/RawSample.h" + +extern const mp_obj_type_t audioio_rawsample_type; + +void common_hal_audioio_rawsample_construct(audioio_rawsample_obj_t* self, + uint8_t* buffer, uint32_t len, uint8_t bytes_per_sample, bool samples_signed, + uint8_t channel_count, uint32_t sample_rate); + +void common_hal_audioio_rawsample_deinit(audioio_rawsample_obj_t* self); +bool common_hal_audioio_rawsample_deinited(audioio_rawsample_obj_t* self); +uint32_t common_hal_audioio_rawsample_get_sample_rate(audioio_rawsample_obj_t* self); +void common_hal_audioio_rawsample_set_sample_rate(audioio_rawsample_obj_t* self, uint32_t sample_rate); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_RAWSAMPLE_H diff --git a/shared-bindings/audiocore/WaveFile.c b/shared-bindings/audiocore/WaveFile.c new file mode 100644 index 00000000000..1b3a94ff377 --- /dev/null +++ b/shared-bindings/audiocore/WaveFile.c @@ -0,0 +1,214 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "lib/utils/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/audiocore/WaveFile.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: audiocore +//| +//| :class:`WaveFile` -- Load a wave file for audio playback +//| ======================================================== +//| +//| A .wav file prepped for audio playback. Only mono and stereo files are supported. Samples must +//| be 8 bit unsigned or 16 bit signed. If a buffer is provided, it will be used instead of allocating +//| an internal buffer. +//| +//| .. class:: WaveFile(file[, buffer]) +//| +//| Load a .wav file for playback with `audioio.AudioOut` or `audiobusio.I2SOut`. +//| +//| :param typing.BinaryIO file: Already opened wave file +//| :param bytearray buffer: Optional pre-allocated buffer, that will be split in half and used for double-buffering of the data. If not provided, two 512 byte buffers are allocated internally. +//| +//| +//| Playing a wave file from flash:: +//| +//| import board +//| import audiocore +//| import audioio +//| import digitalio +//| +//| # Required for CircuitPlayground Express +//| speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) +//| speaker_enable.switch_to_output(value=True) +//| +//| data = open("cplay-5.1-16bit-16khz.wav", "rb") +//| wav = audiocore.WaveFile(data) +//| a = audioio.AudioOut(board.A0) +//| +//| print("playing") +//| a.play(wav) +//| while a.playing: +//| pass +//| print("stopped") +//| +STATIC mp_obj_t audioio_wavefile_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 2, false); + + audioio_wavefile_obj_t *self = m_new_obj(audioio_wavefile_obj_t); + self->base.type = &audioio_wavefile_type; + if (!MP_OBJ_IS_TYPE(args[0], &mp_type_fileio)) { + mp_raise_TypeError(translate("file must be a file opened in byte mode")); + } + uint8_t *buffer = NULL; + size_t buffer_size = 0; + if (n_args >= 2) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE); + buffer = bufinfo.buf; + buffer_size = bufinfo.len; + } + common_hal_audioio_wavefile_construct(self, MP_OBJ_TO_PTR(args[0]), + buffer, buffer_size); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialises the WaveFile and releases all memory resources for reuse. +//| +STATIC mp_obj_t audioio_wavefile_deinit(mp_obj_t self_in) { + audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audioio_wavefile_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_deinit_obj, audioio_wavefile_deinit); + +STATIC void check_for_deinit(audioio_wavefile_obj_t *self) { + if (common_hal_audioio_wavefile_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t audioio_wavefile_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_audioio_wavefile_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_wavefile___exit___obj, 4, 4, audioio_wavefile_obj___exit__); + +//| .. attribute:: sample_rate +//| +//| 32 bit value that dictates how quickly samples are loaded into the DAC +//| in Hertz (cycles per second). When the sample is looped, this can change +//| the pitch output without changing the underlying sample. +//| +STATIC mp_obj_t audioio_wavefile_obj_get_sample_rate(mp_obj_t self_in) { + audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_wavefile_get_sample_rate(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_get_sample_rate_obj, audioio_wavefile_obj_get_sample_rate); + +STATIC mp_obj_t audioio_wavefile_obj_set_sample_rate(mp_obj_t self_in, mp_obj_t sample_rate) { + audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_audioio_wavefile_set_sample_rate(self, mp_obj_get_int(sample_rate)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audioio_wavefile_set_sample_rate_obj, audioio_wavefile_obj_set_sample_rate); + +const mp_obj_property_t audioio_wavefile_sample_rate_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audioio_wavefile_get_sample_rate_obj, + (mp_obj_t)&audioio_wavefile_set_sample_rate_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: bits_per_sample +//| +//| Bits per sample. (read only) +//| +STATIC mp_obj_t audioio_wavefile_obj_get_bits_per_sample(mp_obj_t self_in) { + audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_wavefile_get_bits_per_sample(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_get_bits_per_sample_obj, audioio_wavefile_obj_get_bits_per_sample); + +const mp_obj_property_t audioio_wavefile_bits_per_sample_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audioio_wavefile_get_bits_per_sample_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: channel_count +//| +//| Number of audio channels. (read only) +//| +STATIC mp_obj_t audioio_wavefile_obj_get_channel_count(mp_obj_t self_in) { + audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_wavefile_get_channel_count(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_get_channel_count_obj, audioio_wavefile_obj_get_channel_count); + +const mp_obj_property_t audioio_wavefile_channel_count_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audioio_wavefile_get_channel_count_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +STATIC const mp_rom_map_elem_t audioio_wavefile_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audioio_wavefile_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audioio_wavefile___exit___obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&audioio_wavefile_sample_rate_obj) }, + { MP_ROM_QSTR(MP_QSTR_bits_per_sample), MP_ROM_PTR(&audioio_wavefile_bits_per_sample_obj) }, + { MP_ROM_QSTR(MP_QSTR_channel_count), MP_ROM_PTR(&audioio_wavefile_channel_count_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(audioio_wavefile_locals_dict, audioio_wavefile_locals_dict_table); + +const mp_obj_type_t audioio_wavefile_type = { + { &mp_type_type }, + .name = MP_QSTR_WaveFile, + .make_new = audioio_wavefile_make_new, + .locals_dict = (mp_obj_dict_t*)&audioio_wavefile_locals_dict, +}; diff --git a/shared-bindings/audiocore/WaveFile.h b/shared-bindings/audiocore/WaveFile.h new file mode 100644 index 00000000000..f4a17231928 --- /dev/null +++ b/shared-bindings/audiocore/WaveFile.h @@ -0,0 +1,47 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_WAVEFILE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_WAVEFILE_H + +#include "py/obj.h" +#include "extmod/vfs_fat.h" + +#include "shared-module/audiocore/WaveFile.h" + +extern const mp_obj_type_t audioio_wavefile_type; + +void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t* self, + pyb_file_obj_t* file, uint8_t *buffer, size_t buffer_size); + +void common_hal_audioio_wavefile_deinit(audioio_wavefile_obj_t* self); +bool common_hal_audioio_wavefile_deinited(audioio_wavefile_obj_t* self); +uint32_t common_hal_audioio_wavefile_get_sample_rate(audioio_wavefile_obj_t* self); +void common_hal_audioio_wavefile_set_sample_rate(audioio_wavefile_obj_t* self, uint32_t sample_rate); +uint8_t common_hal_audioio_wavefile_get_bits_per_sample(audioio_wavefile_obj_t* self); +uint8_t common_hal_audioio_wavefile_get_channel_count(audioio_wavefile_obj_t* self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_WAVEFILE_H diff --git a/shared-bindings/audiocore/__init__.c b/shared-bindings/audiocore/__init__.c new file mode 100644 index 00000000000..c64759d4fff --- /dev/null +++ b/shared-bindings/audiocore/__init__.c @@ -0,0 +1,69 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-bindings/audiocore/Mixer.h" +#include "shared-bindings/audiocore/RawSample.h" +#include "shared-bindings/audiocore/WaveFile.h" + +//| :mod:`audiocore` --- Support for audio samples and mixer +//| ======================================================== +//| +//| .. module:: audiocore +//| :synopsis: Support for audio samples and mixer +//| :platform: SAMD21 +//| +//| The `audiocore` module contains core classes for audio IO +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Mixer +//| RawSample +//| WaveFile +//| + +STATIC const mp_rom_map_elem_t audiocore_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiocore) }, + { MP_ROM_QSTR(MP_QSTR_Mixer), MP_ROM_PTR(&audioio_mixer_type) }, + { MP_ROM_QSTR(MP_QSTR_RawSample), MP_ROM_PTR(&audioio_rawsample_type) }, + { MP_ROM_QSTR(MP_QSTR_WaveFile), MP_ROM_PTR(&audioio_wavefile_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(audiocore_module_globals, audiocore_module_globals_table); + +const mp_obj_module_t audiocore_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&audiocore_module_globals, +}; diff --git a/shared-bindings/audiocore/__init__.h b/shared-bindings/audiocore/__init__.h new file mode 100644 index 00000000000..02437cd1356 --- /dev/null +++ b/shared-bindings/audiocore/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOCORE___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOCORE___INIT___H + +#include "py/obj.h" + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOCORE___INIT___H diff --git a/shared-bindings/audioio/AudioOut.c b/shared-bindings/audioio/AudioOut.c new file mode 100644 index 00000000000..af2fce48e34 --- /dev/null +++ b/shared-bindings/audioio/AudioOut.c @@ -0,0 +1,291 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/audioio/AudioOut.h" +#include "shared-bindings/audiocore/RawSample.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: audioio +//| +//| :class:`AudioOut` -- Output an analog audio signal +//| ======================================================== +//| +//| AudioOut can be used to output an analog audio signal on a given pin. +//| +//| .. class:: AudioOut(left_channel, *, right_channel=None, quiescent_value=0x8000) +//| +//| Create a AudioOut object associated with the given pin(s). This allows you to +//| play audio signals out on the given pin(s). +//| +//| :param ~microcontroller.Pin left_channel: The pin to output the left channel to +//| :param ~microcontroller.Pin right_channel: The pin to output the right channel to +//| :param int quiescent_value: The output value when no signal is present. Samples should start +//| and end with this value to prevent audible popping. +//| +//| Simple 8ksps 440 Hz sin wave:: +//| +//| import audiocore +//| import audioio +//| import board +//| import array +//| import time +//| import math +//| +//| # Generate one period of sine wav. +//| length = 8000 // 440 +//| sine_wave = array.array("H", [0] * length) +//| for i in range(length): +//| sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15) + 2 ** 15) +//| +//| dac = audioio.AudioOut(board.SPEAKER) +//| sine_wave = audiocore.RawSample(sine_wave, sample_rate=8000) +//| dac.play(sine_wave, loop=True) +//| time.sleep(1) +//| dac.stop() +//| +//| Playing a wave file from flash:: +//| +//| import board +//| import audioio +//| import digitalio +//| +//| # Required for CircuitPlayground Express +//| speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) +//| speaker_enable.switch_to_output(value=True) +//| +//| data = open("cplay-5.1-16bit-16khz.wav", "rb") +//| wav = audiocore.WaveFile(data) +//| a = audioio.AudioOut(board.A0) +//| +//| print("playing") +//| a.play(wav) +//| while a.playing: +//| pass +//| print("stopped") +//| +STATIC mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_left_channel, ARG_right_channel, ARG_quiescent_value }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_left_channel, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_right_channel, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = mp_const_none} }, + { MP_QSTR_quiescent_value, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x8000} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t left_channel_obj = args[ARG_left_channel].u_obj; + assert_pin(left_channel_obj, false); + const mcu_pin_obj_t *left_channel_pin = MP_OBJ_TO_PTR(left_channel_obj); + + mp_obj_t right_channel_obj = args[ARG_right_channel].u_obj; + const mcu_pin_obj_t *right_channel_pin = NULL; + if (right_channel_obj != mp_const_none) { + assert_pin(right_channel_obj, false); + right_channel_pin = MP_OBJ_TO_PTR(right_channel_obj); + } + + // create AudioOut object from the given pin + audioio_audioout_obj_t *self = m_new_obj(audioio_audioout_obj_t); + self->base.type = &audioio_audioout_type; + common_hal_audioio_audioout_construct(self, left_channel_pin, right_channel_pin, args[ARG_quiescent_value].u_int); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialises the AudioOut and releases any hardware resources for reuse. +//| +STATIC mp_obj_t audioio_audioout_deinit(mp_obj_t self_in) { + audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audioio_audioout_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_deinit_obj, audioio_audioout_deinit); + +STATIC void check_for_deinit(audioio_audioout_obj_t *self) { + if (common_hal_audioio_audioout_deinited(self)) { + raise_deinited_error(); + } +} +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t audioio_audioout_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_audioio_audioout_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_audioout___exit___obj, 4, 4, audioio_audioout_obj___exit__); + + +//| .. method:: play(sample, *, loop=False) +//| +//| Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiocore.Mixer`. +//| +//| The sample itself should consist of 16 bit samples. Microcontrollers with a lower output +//| resolution will use the highest order bits to output. For example, the SAMD21 has a 10 bit +//| DAC that ignores the lowest 6 bits when playing 16 bit samples. +//| +STATIC mp_obj_t audioio_audioout_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audioio_audioout_play(self, sample, args[ARG_loop].u_bool); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(audioio_audioout_play_obj, 1, audioio_audioout_obj_play); + +//| .. method:: stop() +//| +//| Stops playback and resets to the start of the sample. +//| +STATIC mp_obj_t audioio_audioout_obj_stop(mp_obj_t self_in) { + audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_audioio_audioout_stop(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_stop_obj, audioio_audioout_obj_stop); + +//| .. attribute:: playing +//| +//| True when an audio sample is being output even if `paused`. (read-only) +//| +STATIC mp_obj_t audioio_audioout_obj_get_playing(mp_obj_t self_in) { + audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audioio_audioout_get_playing(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_get_playing_obj, audioio_audioout_obj_get_playing); + +const mp_obj_property_t audioio_audioout_playing_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audioio_audioout_get_playing_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: pause() +//| +//| Stops playback temporarily while remembering the position. Use `resume` to resume playback. +//| +STATIC mp_obj_t audioio_audioout_obj_pause(mp_obj_t self_in) { + audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + if (!common_hal_audioio_audioout_get_playing(self)) { + mp_raise_RuntimeError(translate("Not playing")); + } + common_hal_audioio_audioout_pause(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_pause_obj, audioio_audioout_obj_pause); + +//| .. method:: resume() +//| +//| Resumes sample playback after :py:func:`pause`. +//| +STATIC mp_obj_t audioio_audioout_obj_resume(mp_obj_t self_in) { + audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + if (common_hal_audioio_audioout_get_paused(self)) { + common_hal_audioio_audioout_resume(self); + } + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_resume_obj, audioio_audioout_obj_resume); + +//| .. attribute:: paused +//| +//| True when playback is paused. (read-only) +//| +STATIC mp_obj_t audioio_audioout_obj_get_paused(mp_obj_t self_in) { + audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audioio_audioout_get_paused(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_get_paused_obj, audioio_audioout_obj_get_paused); + +const mp_obj_property_t audioio_audioout_paused_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audioio_audioout_get_paused_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t audioio_audioout_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audioio_audioout_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audioio_audioout___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audioio_audioout_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audioio_audioout_stop_obj) }, + { MP_ROM_QSTR(MP_QSTR_pause), MP_ROM_PTR(&audioio_audioout_pause_obj) }, + { MP_ROM_QSTR(MP_QSTR_resume), MP_ROM_PTR(&audioio_audioout_resume_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audioio_audioout_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_paused), MP_ROM_PTR(&audioio_audioout_paused_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(audioio_audioout_locals_dict, audioio_audioout_locals_dict_table); + +const mp_obj_type_t audioio_audioout_type = { + { &mp_type_type }, + .name = MP_QSTR_AudioOut, + .make_new = audioio_audioout_make_new, + .locals_dict = (mp_obj_dict_t*)&audioio_audioout_locals_dict, +}; diff --git a/shared-bindings/audioio/AudioOut.h b/shared-bindings/audioio/AudioOut.h new file mode 100644 index 00000000000..1076ac5ccc1 --- /dev/null +++ b/shared-bindings/audioio/AudioOut.h @@ -0,0 +1,49 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_AUDIOOUT_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_AUDIOOUT_H + +#include "common-hal/audioio/AudioOut.h" +#include "common-hal/microcontroller/Pin.h" +#include "shared-bindings/audiocore/RawSample.h" + +extern const mp_obj_type_t audioio_audioout_type; + +// left_channel will always be non-NULL but right_channel may be for mono output. +void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self, + const mcu_pin_obj_t* left_channel, const mcu_pin_obj_t* right_channel, uint16_t default_value); + +void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t* self); +bool common_hal_audioio_audioout_deinited(audioio_audioout_obj_t* self); +void common_hal_audioio_audioout_play(audioio_audioout_obj_t* self, mp_obj_t sample, bool loop); +void common_hal_audioio_audioout_stop(audioio_audioout_obj_t* self); +bool common_hal_audioio_audioout_get_playing(audioio_audioout_obj_t* self); +void common_hal_audioio_audioout_pause(audioio_audioout_obj_t* self); +void common_hal_audioio_audioout_resume(audioio_audioout_obj_t* self); +bool common_hal_audioio_audioout_get_paused(audioio_audioout_obj_t* self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_AUDIOOUT_H diff --git a/shared-bindings/audioio/__init__.c b/shared-bindings/audioio/__init__.c new file mode 100644 index 00000000000..bd771dda2e2 --- /dev/null +++ b/shared-bindings/audioio/__init__.c @@ -0,0 +1,86 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/audioio/__init__.h" +#include "shared-bindings/audioio/AudioOut.h" + +#ifdef CIRCUITPY_AUDIOIO_COMPAT +#include "shared-bindings/audiocore/Mixer.h" +#include "shared-bindings/audiocore/RawSample.h" +#include "shared-bindings/audiocore/WaveFile.h" +#endif + +//| :mod:`audioio` --- Support for audio input and output +//| ====================================================== +//| +//| .. module:: audioio +//| :synopsis: Support for audio input and output +//| :platform: SAMD21 +//| +//| The `audioio` module contains classes to provide access to audio IO. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| AudioOut +//| +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed if the program continues after use. To do so, either +//| call :py:meth:`!deinit` or use a context manager. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +//| Since CircuitPython 5, `Mixer`, `RawSample` and `WaveFile` are moved +//| to :mod:`audiocore`. +//| +//| For compatibility with CircuitPython 4.x, some builds allow the items in +//| `audiocore` to be imported from `audioio`. This will be removed for all +//| boards in a future build of CicuitPython. +//| + +STATIC const mp_rom_map_elem_t audioio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audioio) }, + { MP_ROM_QSTR(MP_QSTR_AudioOut), MP_ROM_PTR(&audioio_audioout_type) }, +#ifdef CIRCUITPY_AUDIOIO_COMPAT + { MP_ROM_QSTR(MP_QSTR_Mixer), MP_ROM_PTR(&audioio_mixer_type) }, + { MP_ROM_QSTR(MP_QSTR_RawSample), MP_ROM_PTR(&audioio_rawsample_type) }, + { MP_ROM_QSTR(MP_QSTR_WaveFile), MP_ROM_PTR(&audioio_wavefile_type) }, +#endif +}; + +STATIC MP_DEFINE_CONST_DICT(audioio_module_globals, audioio_module_globals_table); + +const mp_obj_module_t audioio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&audioio_module_globals, +}; diff --git a/shared-bindings/audioio/__init__.h b/shared-bindings/audioio/__init__.h new file mode 100644 index 00000000000..e4b7067d118 --- /dev/null +++ b/shared-bindings/audioio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO___INIT___H + +#include "py/obj.h" + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO___INIT___H diff --git a/shared-bindings/audiopwmio/PWMAudioOut.c b/shared-bindings/audiopwmio/PWMAudioOut.c new file mode 100644 index 00000000000..92543d11285 --- /dev/null +++ b/shared-bindings/audiopwmio/PWMAudioOut.c @@ -0,0 +1,294 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/audiopwmio/PWMAudioOut.h" +#include "shared-bindings/audiocore/RawSample.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: audiopwmio +//| +//| :class:`PWMAudioOut` -- Output an analog audio signal +//| ======================================================== +//| +//| AudioOut can be used to output an analog audio signal on a given pin. +//| +//| .. class:: PWMAudioOut(left_channel, *, right_channel=None, quiescent_value=0x8000) +//| +//| Create a PWMAudioOut object associated with the given pin(s). This allows you to +//| play audio signals out on the given pin(s). In contrast to mod:`audioio`, +//| the pin(s) specified are digital pins, and are driven with a device-dependent PWM +//| signal. +//| +//| :param ~microcontroller.Pin left_channel: The pin to output the left channel to +//| :param ~microcontroller.Pin right_channel: The pin to output the right channel to +//| :param int quiescent_value: The output value when no signal is present. Samples should start +//| and end with this value to prevent audible popping. +//| +//| Simple 8ksps 440 Hz sin wave:: +//| +//| import audiocore +//| import audiopwmio +//| import board +//| import array +//| import time +//| import math +//| +//| # Generate one period of sine wav. +//| length = 8000 // 440 +//| sine_wave = array.array("H", [0] * length) +//| for i in range(length): +//| sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15) + 2 ** 15) +//| +//| dac = audiopwmio.PWMAudioOut(board.SPEAKER) +//| sine_wave = audiocore.RawSample(sine_wave, sample_rate=8000) +//| dac.play(sine_wave, loop=True) +//| time.sleep(1) +//| dac.stop() +//| +//| Playing a wave file from flash:: +//| +//| import board +//| import audiocore +//| import audiopwmio +//| import digitalio +//| +//| # Required for CircuitPlayground Express +//| speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) +//| speaker_enable.switch_to_output(value=True) +//| +//| data = open("cplay-5.1-16bit-16khz.wav", "rb") +//| wav = audiocore.WaveFile(data) +//| a = audiopwmio.PWMAudioOut(board.SPEAKER) +//| +//| print("playing") +//| a.play(wav) +//| while a.playing: +//| pass +//| print("stopped") +//| +STATIC mp_obj_t audiopwmio_pwmaudioout_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_left_channel, ARG_right_channel, ARG_quiescent_value }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_left_channel, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_right_channel, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = mp_const_none} }, + { MP_QSTR_quiescent_value, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x8000} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t left_channel_obj = args[ARG_left_channel].u_obj; + assert_pin(left_channel_obj, false); + const mcu_pin_obj_t *left_channel_pin = MP_OBJ_TO_PTR(left_channel_obj); + + mp_obj_t right_channel_obj = args[ARG_right_channel].u_obj; + const mcu_pin_obj_t *right_channel_pin = NULL; + if (right_channel_obj != mp_const_none) { + assert_pin(right_channel_obj, false); + right_channel_pin = MP_OBJ_TO_PTR(right_channel_obj); + } + + // create AudioOut object from the given pin + audiopwmio_pwmaudioout_obj_t *self = m_new_obj(audiopwmio_pwmaudioout_obj_t); + self->base.type = &audiopwmio_pwmaudioout_type; + common_hal_audiopwmio_pwmaudioout_construct(self, left_channel_pin, right_channel_pin, args[ARG_quiescent_value].u_int); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialises the PWMAudioOut and releases any hardware resources for reuse. +//| +STATIC mp_obj_t audiopwmio_pwmaudioout_deinit(mp_obj_t self_in) { + audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiopwmio_pwmaudioout_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(audiopwmio_pwmaudioout_deinit_obj, audiopwmio_pwmaudioout_deinit); + +STATIC void check_for_deinit(audiopwmio_pwmaudioout_obj_t *self) { + if (common_hal_audiopwmio_pwmaudioout_deinited(self)) { + raise_deinited_error(); + } +} +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t audiopwmio_pwmaudioout_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_audiopwmio_pwmaudioout_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiopwmio_pwmaudioout___exit___obj, 4, 4, audiopwmio_pwmaudioout_obj___exit__); + + +//| .. method:: play(sample, *, loop=False) +//| +//| Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiocore.Mixer`. +//| +//| The sample itself should consist of 16 bit samples. Microcontrollers with a lower output +//| resolution will use the highest order bits to output. For example, the SAMD21 has a 10 bit +//| DAC that ignores the lowest 6 bits when playing 16 bit samples. +//| +STATIC mp_obj_t audiopwmio_pwmaudioout_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audiopwmio_pwmaudioout_play(self, sample, args[ARG_loop].u_bool); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiopwmio_pwmaudioout_play_obj, 1, audiopwmio_pwmaudioout_obj_play); + +//| .. method:: stop() +//| +//| Stops playback and resets to the start of the sample. +//| +STATIC mp_obj_t audiopwmio_pwmaudioout_obj_stop(mp_obj_t self_in) { + audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_audiopwmio_pwmaudioout_stop(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiopwmio_pwmaudioout_stop_obj, audiopwmio_pwmaudioout_obj_stop); + +//| .. attribute:: playing +//| +//| True when an audio sample is being output even if `paused`. (read-only) +//| +STATIC mp_obj_t audiopwmio_pwmaudioout_obj_get_playing(mp_obj_t self_in) { + audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audiopwmio_pwmaudioout_get_playing(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiopwmio_pwmaudioout_get_playing_obj, audiopwmio_pwmaudioout_obj_get_playing); + +const mp_obj_property_t audiopwmio_pwmaudioout_playing_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audiopwmio_pwmaudioout_get_playing_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: pause() +//| +//| Stops playback temporarily while remembering the position. Use `resume` to resume playback. +//| +STATIC mp_obj_t audiopwmio_pwmaudioout_obj_pause(mp_obj_t self_in) { + audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + if (!common_hal_audiopwmio_pwmaudioout_get_playing(self)) { + mp_raise_RuntimeError(translate("Not playing")); + } + common_hal_audiopwmio_pwmaudioout_pause(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiopwmio_pwmaudioout_pause_obj, audiopwmio_pwmaudioout_obj_pause); + +//| .. method:: resume() +//| +//| Resumes sample playback after :py:func:`pause`. +//| +STATIC mp_obj_t audiopwmio_pwmaudioout_obj_resume(mp_obj_t self_in) { + audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + if (common_hal_audiopwmio_pwmaudioout_get_paused(self)) { + common_hal_audiopwmio_pwmaudioout_resume(self); + } + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiopwmio_pwmaudioout_resume_obj, audiopwmio_pwmaudioout_obj_resume); + +//| .. attribute:: paused +//| +//| True when playback is paused. (read-only) +//| +STATIC mp_obj_t audiopwmio_pwmaudioout_obj_get_paused(mp_obj_t self_in) { + audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audiopwmio_pwmaudioout_get_paused(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiopwmio_pwmaudioout_get_paused_obj, audiopwmio_pwmaudioout_obj_get_paused); + +const mp_obj_property_t audiopwmio_pwmaudioout_paused_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audiopwmio_pwmaudioout_get_paused_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t audiopwmio_pwmaudioout_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiopwmio_pwmaudioout_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiopwmio_pwmaudioout___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiopwmio_pwmaudioout_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiopwmio_pwmaudioout_stop_obj) }, + { MP_ROM_QSTR(MP_QSTR_pause), MP_ROM_PTR(&audiopwmio_pwmaudioout_pause_obj) }, + { MP_ROM_QSTR(MP_QSTR_resume), MP_ROM_PTR(&audiopwmio_pwmaudioout_resume_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiopwmio_pwmaudioout_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_paused), MP_ROM_PTR(&audiopwmio_pwmaudioout_paused_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(audiopwmio_pwmaudioout_locals_dict, audiopwmio_pwmaudioout_locals_dict_table); + +const mp_obj_type_t audiopwmio_pwmaudioout_type = { + { &mp_type_type }, + .name = MP_QSTR_PWMAudioOut, + .make_new = audiopwmio_pwmaudioout_make_new, + .locals_dict = (mp_obj_dict_t*)&audiopwmio_pwmaudioout_locals_dict, +}; diff --git a/shared-bindings/audiopwmio/PWMAudioOut.h b/shared-bindings/audiopwmio/PWMAudioOut.h new file mode 100644 index 00000000000..22afc70d38d --- /dev/null +++ b/shared-bindings/audiopwmio/PWMAudioOut.h @@ -0,0 +1,49 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOPWMIO_AUDIOOUT_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOPWMIO_AUDIOOUT_H + +#include "common-hal/audiopwmio/PWMAudioOut.h" +#include "common-hal/microcontroller/Pin.h" +#include "shared-bindings/audiocore/RawSample.h" + +extern const mp_obj_type_t audiopwmio_pwmaudioout_type; + +// left_channel will always be non-NULL but right_channel may be for mono output. +void common_hal_audiopwmio_pwmaudioout_construct(audiopwmio_pwmaudioout_obj_t* self, + const mcu_pin_obj_t* left_channel, const mcu_pin_obj_t* right_channel, uint16_t default_value); + +void common_hal_audiopwmio_pwmaudioout_deinit(audiopwmio_pwmaudioout_obj_t* self); +bool common_hal_audiopwmio_pwmaudioout_deinited(audiopwmio_pwmaudioout_obj_t* self); +void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t* self, mp_obj_t sample, bool loop); +void common_hal_audiopwmio_pwmaudioout_stop(audiopwmio_pwmaudioout_obj_t* self); +bool common_hal_audiopwmio_pwmaudioout_get_playing(audiopwmio_pwmaudioout_obj_t* self); +void common_hal_audiopwmio_pwmaudioout_pause(audiopwmio_pwmaudioout_obj_t* self); +void common_hal_audiopwmio_pwmaudioout_resume(audiopwmio_pwmaudioout_obj_t* self); +bool common_hal_audiopwmio_pwmaudioout_get_paused(audiopwmio_pwmaudioout_obj_t* self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOPWMIO_AUDIOOUT_H diff --git a/shared-bindings/audiopwmio/__init__.c b/shared-bindings/audiopwmio/__init__.c new file mode 100644 index 00000000000..8a2b202b361 --- /dev/null +++ b/shared-bindings/audiopwmio/__init__.c @@ -0,0 +1,71 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/audiopwmio/__init__.h" +#include "shared-bindings/audiopwmio/PWMAudioOut.h" + +//| :mod:`audiopwmio` --- Support for audio input and output +//| ======================================================== +//| +//| .. module:: audiopwmio +//| :synopsis: Support for audio output via digital PWM +//| :platform: NRF52 +//| +//| The `audiopwmio` module contains classes to provide access to audio IO. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| PWMAudioOut +//| +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed if the program continues after use. To do so, either +//| call :py:meth:`!deinit` or use a context manager. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +//| Since CircuitPython 5, `Mixer`, `RawSample` and `WaveFile` are moved +//| to :mod:`audiocore`. +//| + +STATIC const mp_rom_map_elem_t audiopwmio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiopwmio) }, + { MP_ROM_QSTR(MP_QSTR_PWMAudioOut), MP_ROM_PTR(&audiopwmio_pwmaudioout_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(audiopwmio_module_globals, audiopwmio_module_globals_table); + +const mp_obj_module_t audiopwmio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&audiopwmio_module_globals, +}; diff --git a/shared-bindings/audiopwmio/__init__.h b/shared-bindings/audiopwmio/__init__.h new file mode 100644 index 00000000000..e4b7067d118 --- /dev/null +++ b/shared-bindings/audiopwmio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO___INIT___H + +#include "py/obj.h" + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO___INIT___H diff --git a/shared-bindings/bitbangio/I2C.c b/shared-bindings/bitbangio/I2C.c new file mode 100644 index 00000000000..01a128393b5 --- /dev/null +++ b/shared-bindings/bitbangio/I2C.c @@ -0,0 +1,340 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +// This file contains all of the Python API definitions for the +// bitbangio.I2C class. + +#include "shared-bindings/bitbangio/I2C.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" + +#include "lib/utils/buffer_helper.h" +#include "lib/utils/context_manager_helpers.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: bitbangio +//| +//| :class:`I2C` --- Two wire serial protocol +//| ------------------------------------------ +//| +//| .. class:: I2C(scl, sda, *, frequency=400000, timeout) +//| +//| I2C is a two-wire protocol for communicating between devices. At the +//| physical level it consists of 2 wires: SCL and SDA, the clock and data +//| lines respectively. +//| +//| :param ~microcontroller.Pin scl: The clock pin +//| :param ~microcontroller.Pin sda: The data pin +//| :param int frequency: The clock frequency of the bus +//| :param int timeout: The maximum clock stretching timeout in microseconds +//| +STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_scl, ARG_sda, ARG_frequency, ARG_timeout }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 255} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + assert_pin(args[ARG_scl].u_obj, false); + assert_pin(args[ARG_sda].u_obj, false); + const mcu_pin_obj_t* scl = MP_OBJ_TO_PTR(args[ARG_scl].u_obj); + const mcu_pin_obj_t* sda = MP_OBJ_TO_PTR(args[ARG_sda].u_obj); + + bitbangio_i2c_obj_t *self = m_new_obj(bitbangio_i2c_obj_t); + self->base.type = &bitbangio_i2c_type; + shared_module_bitbangio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int); + return (mp_obj_t)self; +} + +//| .. method:: deinit() +//| +//| Releases control of the underlying hardware so other classes can use it. +//| +STATIC mp_obj_t bitbangio_i2c_obj_deinit(mp_obj_t self_in) { + bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + shared_module_bitbangio_i2c_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_deinit_obj, bitbangio_i2c_obj_deinit); + +STATIC void check_for_deinit(bitbangio_i2c_obj_t *self) { + if (shared_module_bitbangio_i2c_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() +//| +//| No-op used in Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware on context exit. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t bitbangio_i2c_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + shared_module_bitbangio_i2c_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_i2c_obj___exit___obj, 4, 4, bitbangio_i2c_obj___exit__); + +static void check_lock(bitbangio_i2c_obj_t *self) { + if (!shared_module_bitbangio_i2c_has_lock(self)) { + mp_raise_RuntimeError(translate("Function requires lock")); + } +} + +//| .. method:: scan() +//| +//| Scan all I2C addresses between 0x08 and 0x77 inclusive and return a list of +//| those that respond. A device responds if it pulls the SDA line low after +//| its address (including a read bit) is sent on the bus. +//| +STATIC mp_obj_t bitbangio_i2c_scan(mp_obj_t self_in) { + bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + check_lock(self); + mp_obj_t list = mp_obj_new_list(0, NULL); + // 7-bit addresses 0b0000xxx and 0b1111xxx are reserved + for (int addr = 0x08; addr < 0x78; ++addr) { + bool success = shared_module_bitbangio_i2c_probe(self, addr); + if (success) { + mp_obj_list_append(list, MP_OBJ_NEW_SMALL_INT(addr)); + } + } + return list; +} +MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_scan_obj, bitbangio_i2c_scan); + +//| .. method:: try_lock() +//| +//| Attempts to grab the I2C lock. Returns True on success. +//| +STATIC mp_obj_t bitbangio_i2c_obj_try_lock(mp_obj_t self_in) { + bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(shared_module_bitbangio_i2c_try_lock(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_try_lock_obj, bitbangio_i2c_obj_try_lock); + +//| .. method:: unlock() +//| +//| Releases the I2C lock. +//| +STATIC mp_obj_t bitbangio_i2c_obj_unlock(mp_obj_t self_in) { + bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + shared_module_bitbangio_i2c_unlock(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_unlock_obj, bitbangio_i2c_obj_unlock); + +//| .. method:: readfrom_into(address, buffer, *, start=0, end=None) +//| +//| Read into ``buffer`` from the slave specified by ``address``. +//| The number of bytes read will be the length of ``buffer``. +//| At least one byte must be read. +//| +//| If ``start`` or ``end`` is provided, then the buffer will be sliced +//| as if ``buffer[start:end]``. This will not cause an allocation like +//| ``buf[start:end]`` will so it saves memory. +//| +//| :param int address: 7-bit device address +//| :param bytearray buffer: buffer to write into +//| :param int start: Index to start writing at +//| :param int end: Index to write up to but not include +//| +// Shared arg parsing for readfrom_into and writeto_then_readfrom. +STATIC void readfrom(bitbangio_i2c_obj_t *self, mp_int_t address, mp_obj_t buffer, int32_t start, mp_int_t end) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_WRITE); + + size_t length = bufinfo.len; + normalize_buffer_bounds(&start, end, &length); + if (length == 0) { + mp_raise_ValueError(translate("Buffer must be at least length 1")); + } + + uint8_t status = shared_module_bitbangio_i2c_read(self, address, ((uint8_t*)bufinfo.buf) + start, length); + if (status != 0) { + mp_raise_OSError(status); + } +} + +STATIC mp_obj_t bitbangio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_address, ARG_buffer, ARG_start, ARG_end }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + }; + bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + readfrom(self, args[ARG_address].u_int, args[ARG_buffer].u_obj, args[ARG_start].u_int, + args[ARG_end].u_int); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_readfrom_into_obj, 3, bitbangio_i2c_readfrom_into); + +//| .. method:: writeto(address, buffer, *, start=0, end=None, stop=True) +//| +//| Write the bytes from ``buffer`` to the slave specified by ``address`` and then transmits a +//| stop bit. Use `writeto_then_readfrom` when needing a write, no stop and repeated start +//| before a read. +//| +//| If ``start`` or ``end`` is provided, then the buffer will be sliced +//| as if ``buffer[start:end]``. This will not cause an allocation like +//| ``buffer[start:end]`` will so it saves memory. +//| +//| Writing a buffer or slice of length zero is permitted, as it can be used +//| to poll for the existence of a device. +//| +//| :param int address: 7-bit device address +//| :param bytearray buffer: buffer containing the bytes to write +//| :param int start: Index to start writing from +//| :param int end: Index to read up to but not include +//| :param bool stop: If true, output an I2C stop condition after the buffer is written. +//| Deprecated. Will be removed in 6.x and act as stop=True. +//| +// Shared arg parsing for writeto and writeto_then_readfrom. +STATIC void writeto(bitbangio_i2c_obj_t *self, mp_int_t address, mp_obj_t buffer, int32_t start, mp_int_t end, bool stop) { + // get the buffer to write the data from + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_READ); + + size_t length = bufinfo.len; + normalize_buffer_bounds(&start, end, &length); + + // do the transfer + uint8_t status = shared_module_bitbangio_i2c_write(self, address, + ((uint8_t*) bufinfo.buf) + start, length, + stop); + if (status != 0) { + mp_raise_OSError(status); + } +} + +STATIC mp_obj_t bitbangio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_address, ARG_buffer, ARG_start, ARG_end, ARG_stop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + { MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, + }; + bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + writeto(self, args[ARG_address].u_int, args[ARG_buffer].u_obj, args[ARG_start].u_int, + args[ARG_end].u_int, args[ARG_stop].u_bool); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_writeto_obj, 1, bitbangio_i2c_writeto); + + +//| .. method:: writeto_then_readfrom(address, out_buffer, in_buffer, *, out_start=0, out_end=None, in_start=0, in_end=None) +//| +//| Write the bytes from ``out_buffer`` to the slave specified by ``address``, generate no stop +//| bit, generate a repeated start and read into ``in_buffer``. ``out_buffer`` and +//| ``in_buffer`` can be the same buffer because they are used sequentially. +//| +//| If ``start`` or ``end`` is provided, then the corresponding buffer will be sliced +//| as if ``buffer[start:end]``. This will not cause an allocation like ``buf[start:end]`` +//| will so it saves memory. +//| +//| :param int address: 7-bit device address +//| :param bytearray out_buffer: buffer containing the bytes to write +//| :param bytearray in_buffer: buffer to write into +//| :param int out_start: Index to start writing from +//| :param int out_end: Index to read up to but not include. Defaults to ``len(buffer)`` +//| :param int in_start: Index to start writing at +//| :param int in_end: Index to write up to but not include. Defaults to ``len(buffer)`` +//| +STATIC mp_obj_t bitbangio_i2c_writeto_then_readfrom(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_address, ARG_out_buffer, ARG_in_buffer, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_out_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_in_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_out_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_out_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + { MP_QSTR_in_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_in_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + }; + bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + writeto(self, args[ARG_address].u_int, args[ARG_out_buffer].u_obj, args[ARG_out_start].u_int, + args[ARG_out_end].u_int, false); + readfrom(self, args[ARG_address].u_int, args[ARG_in_buffer].u_obj, args[ARG_in_start].u_int, + args[ARG_in_end].u_int); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_writeto_then_readfrom_obj, 3, bitbangio_i2c_writeto_then_readfrom); + +STATIC const mp_rom_map_elem_t bitbangio_i2c_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bitbangio_i2c_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&bitbangio_i2c_obj___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&bitbangio_i2c_scan_obj) }, + + { MP_ROM_QSTR(MP_QSTR_try_lock), MP_ROM_PTR(&bitbangio_i2c_try_lock_obj) }, + { MP_ROM_QSTR(MP_QSTR_unlock), MP_ROM_PTR(&bitbangio_i2c_unlock_obj) }, + + { MP_ROM_QSTR(MP_QSTR_writeto), MP_ROM_PTR(&bitbangio_i2c_writeto_obj) }, + { MP_ROM_QSTR(MP_QSTR_readfrom_into), MP_ROM_PTR(&bitbangio_i2c_readfrom_into_obj) }, + { MP_ROM_QSTR(MP_QSTR_writeto_then_readfrom), MP_ROM_PTR(&bitbangio_i2c_writeto_then_readfrom_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bitbangio_i2c_locals_dict, bitbangio_i2c_locals_dict_table); + +const mp_obj_type_t bitbangio_i2c_type = { + { &mp_type_type }, + .name = MP_QSTR_I2C, + .make_new = bitbangio_i2c_make_new, + .locals_dict = (mp_obj_dict_t*)&bitbangio_i2c_locals_dict, +}; diff --git a/shared-bindings/bitbangio/I2C.h b/shared-bindings/bitbangio/I2C.h new file mode 100644 index 00000000000..1ce4d21e918 --- /dev/null +++ b/shared-bindings/bitbangio/I2C.h @@ -0,0 +1,65 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO_I2C_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO_I2C_H + +#include "py/obj.h" + +#include "common-hal/microcontroller/Pin.h" +#include "shared-module/bitbangio/types.h" + +// Type object used in Python. Should be shared between ports. +extern const mp_obj_type_t bitbangio_i2c_type; + +// Initializes the hardware peripheral. +extern void shared_module_bitbangio_i2c_construct(bitbangio_i2c_obj_t *self, + const mcu_pin_obj_t * scl, + const mcu_pin_obj_t * sda, + uint32_t frequency, + uint32_t us_timeout); + +extern void shared_module_bitbangio_i2c_deinit(bitbangio_i2c_obj_t *self); +extern bool shared_module_bitbangio_i2c_deinited(bitbangio_i2c_obj_t *self); + +extern bool shared_module_bitbangio_i2c_try_lock(bitbangio_i2c_obj_t *self); +extern bool shared_module_bitbangio_i2c_has_lock(bitbangio_i2c_obj_t *self); +extern void shared_module_bitbangio_i2c_unlock(bitbangio_i2c_obj_t *self); + +// Probe the bus to see if a device acknowledges the given address. +extern bool shared_module_bitbangio_i2c_probe(bitbangio_i2c_obj_t *self, uint8_t addr); + +extern uint8_t shared_module_bitbangio_i2c_write(bitbangio_i2c_obj_t *self, + uint16_t address, + const uint8_t * data, size_t len, + bool stop); + +// Reads memory of the i2c device picking up where it left off. +extern uint8_t shared_module_bitbangio_i2c_read(bitbangio_i2c_obj_t *self, + uint16_t address, + uint8_t * data, size_t len); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO_I2C_H diff --git a/shared-bindings/bitbangio/OneWire.c b/shared-bindings/bitbangio/OneWire.c new file mode 100644 index 00000000000..73bedcd8d50 --- /dev/null +++ b/shared-bindings/bitbangio/OneWire.c @@ -0,0 +1,174 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "lib/utils/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/runtime0.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/bitbangio/OneWire.h" +#include "shared-bindings/util.h" + +//| .. currentmodule:: bitbangio +//| +//| :class:`OneWire` -- Lowest-level of the Maxim OneWire protocol +//| =============================================================== +//| +//| :class:`~bitbangio.OneWire` implements the timing-sensitive foundation of +//| the Maxim (formerly Dallas Semi) OneWire protocol. +//| +//| Protocol definition is here: https://www.maximintegrated.com/en/app-notes/index.mvp/id/126 +//| +//| .. class:: OneWire(pin) +//| +//| Create a OneWire object associated with the given pin. The object +//| implements the lowest level timing-sensitive bits of the protocol. +//| +//| :param ~microcontroller.Pin pin: Pin to read pulses from. +//| +//| Read a short series of pulses:: +//| +//| import bitbangio +//| import board +//| +//| onewire = bitbangio.OneWire(board.D7) +//| onewire.reset() +//| onewire.write_bit(True) +//| onewire.write_bit(False) +//| print(onewire.read_bit()) +//| +STATIC mp_obj_t bitbangio_onewire_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_pin }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + assert_pin(args[ARG_pin].u_obj, false); + const mcu_pin_obj_t* pin = MP_OBJ_TO_PTR(args[ARG_pin].u_obj); + assert_pin_free(pin); + + bitbangio_onewire_obj_t *self = m_new_obj(bitbangio_onewire_obj_t); + self->base.type = &bitbangio_onewire_type; + + shared_module_bitbangio_onewire_construct(self, pin); + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialize the OneWire bus and release any hardware resources for reuse. +//| +STATIC mp_obj_t bitbangio_onewire_deinit(mp_obj_t self_in) { + bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + shared_module_bitbangio_onewire_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_deinit_obj, bitbangio_onewire_deinit); + +STATIC void check_for_deinit(bitbangio_onewire_obj_t *self) { + if (shared_module_bitbangio_onewire_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t bitbangio_onewire_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + shared_module_bitbangio_onewire_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_onewire___exit___obj, 4, 4, bitbangio_onewire_obj___exit__); + +//| .. method:: reset() +//| +//| Reset the OneWire bus +//| +STATIC mp_obj_t bitbangio_onewire_obj_reset(mp_obj_t self_in) { + bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + return mp_obj_new_bool(shared_module_bitbangio_onewire_reset(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_reset_obj, bitbangio_onewire_obj_reset); + +//| .. method:: read_bit() +//| +//| Read in a bit +//| +//| :returns: bit state read +//| :rtype: bool +//| +STATIC mp_obj_t bitbangio_onewire_obj_read_bit(mp_obj_t self_in) { + bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + return mp_obj_new_bool(shared_module_bitbangio_onewire_read_bit(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_read_bit_obj, bitbangio_onewire_obj_read_bit); + +//| .. method:: write_bit(value) +//| +//| Write out a bit based on value. +//| +STATIC mp_obj_t bitbangio_onewire_obj_write_bit(mp_obj_t self_in, mp_obj_t bool_obj) { + bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + shared_module_bitbangio_onewire_write_bit(self, mp_obj_is_true(bool_obj)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(bitbangio_onewire_write_bit_obj, bitbangio_onewire_obj_write_bit); + +STATIC const mp_rom_map_elem_t bitbangio_onewire_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bitbangio_onewire_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&bitbangio_onewire___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&bitbangio_onewire_reset_obj) }, + { MP_ROM_QSTR(MP_QSTR_read_bit), MP_ROM_PTR(&bitbangio_onewire_read_bit_obj) }, + { MP_ROM_QSTR(MP_QSTR_write_bit), MP_ROM_PTR(&bitbangio_onewire_write_bit_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(bitbangio_onewire_locals_dict, bitbangio_onewire_locals_dict_table); + +const mp_obj_type_t bitbangio_onewire_type = { + { &mp_type_type }, + .name = MP_QSTR_OneWire, + .make_new = bitbangio_onewire_make_new, + .locals_dict = (mp_obj_dict_t*)&bitbangio_onewire_locals_dict, +}; diff --git a/shared-bindings/bitbangio/OneWire.h b/shared-bindings/bitbangio/OneWire.h new file mode 100644 index 00000000000..ef50db737b1 --- /dev/null +++ b/shared-bindings/bitbangio/OneWire.h @@ -0,0 +1,43 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO_ONEWIRE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO_ONEWIRE_H + +#include "common-hal/microcontroller/Pin.h" +#include "shared-module/bitbangio/types.h" + +extern const mp_obj_type_t bitbangio_onewire_type; + +extern void shared_module_bitbangio_onewire_construct(bitbangio_onewire_obj_t* self, + const mcu_pin_obj_t* pin); +extern void shared_module_bitbangio_onewire_deinit(bitbangio_onewire_obj_t* self); +extern bool shared_module_bitbangio_onewire_deinited(bitbangio_onewire_obj_t* self); +extern bool shared_module_bitbangio_onewire_reset(bitbangio_onewire_obj_t* self); +extern bool shared_module_bitbangio_onewire_read_bit(bitbangio_onewire_obj_t* self); +extern void shared_module_bitbangio_onewire_write_bit(bitbangio_onewire_obj_t* self, bool bit); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO_ONEWIRE_H diff --git a/shared-bindings/bitbangio/SPI.c b/shared-bindings/bitbangio/SPI.c new file mode 100644 index 00000000000..9a51bde665a --- /dev/null +++ b/shared-bindings/bitbangio/SPI.c @@ -0,0 +1,326 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +// This file contains all of the Python API definitions for the +// bitbangio.SPI class. + +#include + +#include "shared-bindings/bitbangio/SPI.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" + +#include "lib/utils/buffer_helper.h" +#include "lib/utils/context_manager_helpers.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: bitbangio +//| +//| :class:`SPI` -- a 3-4 wire serial protocol +//| ----------------------------------------------- +//| +//| SPI is a serial protocol that has exclusive pins for data in and out of the +//| master. It is typically faster than :py:class:`~bitbangio.I2C` because a +//| separate pin is used to control the active slave rather than a transmitted +//| address. This class only manages three of the four SPI lines: `!clock`, +//| `!MOSI`, `!MISO`. Its up to the client to manage the appropriate slave +//| select line. (This is common because multiple slaves can share the `!clock`, +//| `!MOSI` and `!MISO` lines and therefore the hardware.) +//| +//| .. class:: SPI(clock, MOSI=None, MISO=None) +//| +//| Construct an SPI object on the given pins. +//| +//| :param ~microcontroller.Pin clock: the pin to use for the clock. +//| :param ~microcontroller.Pin MOSI: the Master Out Slave In pin. +//| :param ~microcontroller.Pin MISO: the Master In Slave Out pin. +//| + +// TODO(tannewt): Support LSB SPI. +STATIC mp_obj_t bitbangio_spi_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_clock, ARG_MOSI, ARG_MISO, ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_MOSI, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_MISO, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + assert_pin(args[ARG_clock].u_obj, false); + assert_pin(args[ARG_MOSI].u_obj, true); + assert_pin(args[ARG_MISO].u_obj, true); + const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(args[ARG_clock].u_obj); + const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(args[ARG_MOSI].u_obj); + const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(args[ARG_MISO].u_obj); + + bitbangio_spi_obj_t *self = m_new_obj(bitbangio_spi_obj_t); + self->base.type = &bitbangio_spi_type; + shared_module_bitbangio_spi_construct(self, clock, mosi, miso); + return (mp_obj_t)self; +} + +//| .. method:: deinit() +//| +//| Turn off the SPI bus. +//| +STATIC mp_obj_t bitbangio_spi_obj_deinit(mp_obj_t self_in) { + bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + shared_module_bitbangio_spi_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_deinit_obj, bitbangio_spi_obj_deinit); + +STATIC void check_for_deinit(bitbangio_spi_obj_t *self) { + if (shared_module_bitbangio_spi_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t bitbangio_spi_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + shared_module_bitbangio_spi_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_spi_obj___exit___obj, 4, 4, bitbangio_spi_obj___exit__); + + +static void check_lock(bitbangio_spi_obj_t *self) { + if (!shared_module_bitbangio_spi_has_lock(self)) { + mp_raise_RuntimeError(translate("Function requires lock")); + } +} + +//| .. method:: configure(*, baudrate=100000, polarity=0, phase=0, bits=8) +//| +//| Configures the SPI bus. Only valid when locked. +//| +//| :param int baudrate: the clock rate in Hertz +//| :param int polarity: the base state of the clock line (0 or 1) +//| :param int phase: the edge of the clock that data is captured. First (0) +//| or second (1). Rising or falling depends on clock polarity. +//| :param int bits: the number of bits per word +//| +STATIC mp_obj_t bitbangio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 100000} }, + { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, + }; + bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + uint8_t polarity = args[ARG_polarity].u_int; + if (polarity != 0 && polarity != 1) { + mp_raise_ValueError(translate("Invalid polarity")); + } + uint8_t phase = args[ARG_phase].u_int; + if (phase != 0 && phase != 1) { + mp_raise_ValueError(translate("Invalid phase")); + } + uint8_t bits = args[ARG_bits].u_int; + if (bits != 8 && bits != 9) { + mp_raise_ValueError(translate("Invalid number of bits")); + } + + shared_module_bitbangio_spi_configure(self, args[ARG_baudrate].u_int, polarity, phase, bits); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_configure_obj, 1, bitbangio_spi_configure); + +//| .. method:: try_lock() +//| +//| Attempts to grab the SPI lock. Returns True on success. +//| +//| :return: True when lock has been grabbed +//| :rtype: bool +//| +STATIC mp_obj_t bitbangio_spi_obj_try_lock(mp_obj_t self_in) { + bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(shared_module_bitbangio_spi_try_lock(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_try_lock_obj, bitbangio_spi_obj_try_lock); + +//| .. method:: unlock() +//| +//| Releases the SPI lock. +//| +STATIC mp_obj_t bitbangio_spi_obj_unlock(mp_obj_t self_in) { + bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + shared_module_bitbangio_spi_unlock(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_unlock_obj, bitbangio_spi_obj_unlock); + +//| .. method:: write(buf) +//| +//| Write the data contained in ``buf``. Requires the SPI being locked. +//| If the buffer is empty, nothing happens. +//| +// TODO(tannewt): Add support for start and end kwargs. +STATIC mp_obj_t bitbangio_spi_write(mp_obj_t self_in, mp_obj_t wr_buf) { + bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + mp_buffer_info_t src; + mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ); + if (src.len == 0) { + return mp_const_none; + } + check_lock(self); + bool ok = shared_module_bitbangio_spi_write(self, src.buf, src.len); + if (!ok) { + mp_raise_OSError(MP_EIO); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(bitbangio_spi_write_obj, bitbangio_spi_write); + + +//| .. method:: readinto(buf) +//| +//| Read into the buffer specified by ``buf`` while writing zeroes. +//| Requires the SPI being locked. +//| If the number of bytes to read is 0, nothing happens. +//| +// TODO(tannewt): Add support for start and end kwargs. +STATIC mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *args) { + bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(args[0]); + check_for_deinit(self); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE); + if (bufinfo.len == 0) { + return mp_const_none; + } + check_lock(args[0]); + bool ok = shared_module_bitbangio_spi_read(self, bufinfo.buf, bufinfo.len); + if (!ok) { + mp_raise_OSError(MP_EIO); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_spi_readinto_obj, 2, 2, bitbangio_spi_readinto); + +//| .. method:: write_readinto(buffer_out, buffer_in, *, out_start=0, out_end=None, in_start=0, in_end=None) +//| +//| Write out the data in ``buffer_out`` while simultaneously reading data into ``buffer_in``. +//| The lengths of the slices defined by ``buffer_out[out_start:out_end]`` and ``buffer_in[in_start:in_end]`` +//| must be equal. +//| If buffer slice lengths are both 0, nothing happens. +//| +//| :param bytearray buffer_out: Write out the data in this buffer +//| :param bytearray buffer_in: Read data into this buffer +//| :param int out_start: Start of the slice of buffer_out to write out: ``buffer_out[out_start:out_end]`` +//| :param int out_end: End of the slice; this index is not included. Defaults to ``len(buffer_out)`` +//| :param int in_start: Start of the slice of ``buffer_in`` to read into: ``buffer_in[in_start:in_end]`` +//| :param int in_end: End of the slice; this index is not included. Defaults to ``len(buffer_in)`` +//| +STATIC mp_obj_t bitbangio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_buffer_out, ARG_buffer_in, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_buffer_out, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_buffer_in, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_out_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_out_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + { MP_QSTR_in_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_in_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + }; + bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t buf_out_info; + mp_get_buffer_raise(args[ARG_buffer_out].u_obj, &buf_out_info, MP_BUFFER_READ); + int32_t out_start = args[ARG_out_start].u_int; + size_t out_length = buf_out_info.len; + normalize_buffer_bounds(&out_start, args[ARG_out_end].u_int, &out_length); + + mp_buffer_info_t buf_in_info; + mp_get_buffer_raise(args[ARG_buffer_in].u_obj, &buf_in_info, MP_BUFFER_WRITE); + int32_t in_start = args[ARG_in_start].u_int; + size_t in_length = buf_in_info.len; + normalize_buffer_bounds(&in_start, args[ARG_in_end].u_int, &in_length); + + if (out_length != in_length) { + mp_raise_ValueError(translate("buffer slices must be of equal length")); + } + + if (out_length == 0) { + return mp_const_none; + } + + bool ok = shared_module_bitbangio_spi_transfer(self, + ((uint8_t*)buf_out_info.buf) + out_start, + ((uint8_t*)buf_in_info.buf) + in_start, + out_length); + if (!ok) { + mp_raise_OSError(MP_EIO); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_write_readinto_obj, 2, bitbangio_spi_write_readinto); + +STATIC const mp_rom_map_elem_t bitbangio_spi_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bitbangio_spi_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&bitbangio_spi_obj___exit___obj) }, + + { MP_ROM_QSTR(MP_QSTR_configure), MP_ROM_PTR(&bitbangio_spi_configure_obj) }, + { MP_ROM_QSTR(MP_QSTR_try_lock), MP_ROM_PTR(&bitbangio_spi_try_lock_obj) }, + { MP_ROM_QSTR(MP_QSTR_unlock), MP_ROM_PTR(&bitbangio_spi_unlock_obj) }, + + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&bitbangio_spi_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&bitbangio_spi_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&bitbangio_spi_write_readinto_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(bitbangio_spi_locals_dict, bitbangio_spi_locals_dict_table); + +const mp_obj_type_t bitbangio_spi_type = { + { &mp_type_type }, + .name = MP_QSTR_SPI, + .make_new = bitbangio_spi_make_new, + .locals_dict = (mp_obj_dict_t*)&bitbangio_spi_locals_dict, +}; diff --git a/shared-bindings/bitbangio/SPI.h b/shared-bindings/bitbangio/SPI.h new file mode 100644 index 00000000000..c4b10b66637 --- /dev/null +++ b/shared-bindings/bitbangio/SPI.h @@ -0,0 +1,62 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO_SPI_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO_SPI_H + +#include "py/obj.h" + +#include "common-hal/microcontroller/Pin.h" +#include "shared-module/bitbangio/types.h" + +// Type object used in Python. Should be shared between ports. +extern const mp_obj_type_t bitbangio_spi_type; + +// Construct an underlying SPI object. +extern void shared_module_bitbangio_spi_construct(bitbangio_spi_obj_t *self, + const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, + const mcu_pin_obj_t * miso); + +extern void shared_module_bitbangio_spi_deinit(bitbangio_spi_obj_t *self); +extern bool shared_module_bitbangio_spi_deinited(bitbangio_spi_obj_t *self); + +extern void shared_module_bitbangio_spi_configure(bitbangio_spi_obj_t *self, + uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits); + +extern bool shared_module_bitbangio_spi_try_lock(bitbangio_spi_obj_t *self); +extern bool shared_module_bitbangio_spi_has_lock(bitbangio_spi_obj_t *self); +extern void shared_module_bitbangio_spi_unlock(bitbangio_spi_obj_t *self); + +// Writes out the given data. +extern bool shared_module_bitbangio_spi_write(bitbangio_spi_obj_t *self, const uint8_t *data, size_t len); + +// Reads in len bytes while outputting zeroes. +extern bool shared_module_bitbangio_spi_read(bitbangio_spi_obj_t *self, uint8_t *data, size_t len); + +// Transfer out len bytes while reading len bytes +extern bool shared_module_bitbangio_spi_transfer(bitbangio_spi_obj_t *self, const uint8_t *dout, uint8_t *din, size_t len); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO_SPI_H diff --git a/shared-bindings/bitbangio/__init__.c b/shared-bindings/bitbangio/__init__.c new file mode 100644 index 00000000000..3123fb199a6 --- /dev/null +++ b/shared-bindings/bitbangio/__init__.c @@ -0,0 +1,99 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +// bitbangio implements some standard protocols in the processor. Its only +// dependency is digitalio. + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/bitbangio/__init__.h" +#include "shared-bindings/bitbangio/I2C.h" +#include "shared-bindings/bitbangio/OneWire.h" +#include "shared-bindings/bitbangio/SPI.h" +#include "shared-module/bitbangio/types.h" + +#include "py/runtime.h" + +//| :mod:`bitbangio` --- Digital protocols implemented by the CPU +//| ============================================================= +//| +//| .. module:: bitbangio +//| :synopsis: Digital protocols implemented by the CPU +//| :platform: SAMD21, ESP8266 +//| +//| The `bitbangio` module contains classes to provide digital bus protocol +//| support regardless of whether the underlying hardware exists to use the +//| protocol. +//| +//| First try to use `busio` module instead which may utilize peripheral +//| hardware to implement the protocols. Native implementations will be faster +//| than bitbanged versions and have more capabilities. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| I2C +//| OneWire +//| SPI +//| +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed if the program continues after use. To do so, either +//| call :py:meth:`!deinit` or use a context manager. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +//| For example:: +//| +//| import bitbangio +//| from board import * +//| +//| i2c = bitbangio.I2C(SCL, SDA) +//| print(i2c.scan()) +//| i2c.deinit() +//| +//| This example will initialize the the device, run +//| :py:meth:`~bitbangio.I2C.scan` and then :py:meth:`~bitbangio.I2C.deinit` the +//| hardware. The last step is optional because CircuitPython automatically +//| resets hardware after a program finishes. +//| + +STATIC const mp_rom_map_elem_t bitbangio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bitbangio) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&bitbangio_i2c_type) }, + { MP_ROM_QSTR(MP_QSTR_OneWire), MP_ROM_PTR(&bitbangio_onewire_type) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&bitbangio_spi_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bitbangio_module_globals, bitbangio_module_globals_table); + +const mp_obj_module_t bitbangio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&bitbangio_module_globals, +}; diff --git a/shared-bindings/bitbangio/__init__.h b/shared-bindings/bitbangio/__init__.h new file mode 100644 index 00000000000..0e9206a441c --- /dev/null +++ b/shared-bindings/bitbangio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO___INIT___H + +#include "py/obj.h" + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO___INIT___H diff --git a/shared-bindings/board/__init__.c b/shared-bindings/board/__init__.c new file mode 100644 index 00000000000..47e2d64bc83 --- /dev/null +++ b/shared-bindings/board/__init__.c @@ -0,0 +1,119 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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 "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/board/__init__.h" + +//| :mod:`board` --- Board specific pin names +//| ======================================================== +//| +//| .. module:: board +//| :synopsis: Board specific pin names +//| +//| Common container for board base pin names. These will vary from board to +//| board so don't expect portability when using this module. +//| +//| .. warning:: The board module varies by board. The APIs documented here may or may not be +//| available on a specific board. + +//| .. function:: I2C() +//| +//| Returns the `busio.I2C` object for the board designated SDA and SCL pins. It is a singleton. +//| + +#if BOARD_I2C +mp_obj_t board_i2c(void) { + mp_obj_t singleton = common_hal_board_get_i2c(); + if (singleton != NULL) { + return singleton; + } + assert_pin_free(DEFAULT_I2C_BUS_SDA); + assert_pin_free(DEFAULT_I2C_BUS_SCL); + return common_hal_board_create_i2c(); +} +#else +mp_obj_t board_i2c(void) { + mp_raise_NotImplementedError_varg(translate("No default %q bus"), MP_QSTR_I2C); + return NULL; +} +#endif +MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c); + + +//| .. function:: SPI() +//| +//| Returns the `busio.SPI` object for the board designated SCK, MOSI and MISO pins. It is a +//| singleton. +//| +#if BOARD_SPI +mp_obj_t board_spi(void) { + mp_obj_t singleton = common_hal_board_get_spi(); + if (singleton != NULL) { + return singleton; + } + assert_pin_free(DEFAULT_SPI_BUS_SCK); + assert_pin_free(DEFAULT_SPI_BUS_MOSI); + assert_pin_free(DEFAULT_SPI_BUS_MISO); + return common_hal_board_create_spi(); +} +#else +mp_obj_t board_spi(void) { + mp_raise_NotImplementedError_varg(translate("No default %q bus"), MP_QSTR_SPI); + return NULL; +} +#endif +MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi); + +//| .. function:: UART() +//| +//| Returns the `busio.UART` object for the board designated TX and RX pins. It is a singleton. +//| +#if BOARD_UART +mp_obj_t board_uart(void) { + mp_obj_t singleton = common_hal_board_get_uart(); + if (singleton != NULL) { + return singleton; + } + + assert_pin_free(DEFAULT_UART_BUS_RX); + assert_pin_free(DEFAULT_UART_BUS_TX); + + return common_hal_board_create_uart(); +} +#else +mp_obj_t board_uart(void) { + mp_raise_NotImplementedError_varg(translate("No default %q bus"), MP_QSTR_SPI); + return NULL; +} +#endif +MP_DEFINE_CONST_FUN_OBJ_0(board_uart_obj, board_uart); + +const mp_obj_module_t board_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&board_module_globals, +}; diff --git a/shared-bindings/board/__init__.h b/shared-bindings/board/__init__.h new file mode 100644 index 00000000000..a9b652ba8df --- /dev/null +++ b/shared-bindings/board/__init__.h @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BOARD___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BOARD___INIT___H + +#include "py/obj.h" + +#include "shared-bindings/microcontroller/Pin.h" // for the pin definitions + +extern const mp_obj_dict_t board_module_globals; + +mp_obj_t common_hal_board_get_i2c(void); +mp_obj_t common_hal_board_create_i2c(void); +MP_DECLARE_CONST_FUN_OBJ_0(board_i2c_obj); + +mp_obj_t common_hal_board_get_spi(void); +mp_obj_t common_hal_board_create_spi(void); +MP_DECLARE_CONST_FUN_OBJ_0(board_spi_obj); + +mp_obj_t common_hal_board_get_uart(void); +mp_obj_t common_hal_board_create_uart(void); +MP_DECLARE_CONST_FUN_OBJ_0(board_uart_obj); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BOARD___INIT___H diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c new file mode 100644 index 00000000000..3bd89e2e201 --- /dev/null +++ b/shared-bindings/busio/I2C.c @@ -0,0 +1,353 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +// This file contains all of the Python API definitions for the +// busio.I2C class. + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/util.h" + +#include "lib/utils/buffer_helper.h" +#include "lib/utils/context_manager_helpers.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: busio +//| +//| :class:`I2C` --- Two wire serial protocol +//| ------------------------------------------ +//| +//| .. class:: I2C(scl, sda, *, frequency=400000, timeout=255) +//| +//| I2C is a two-wire protocol for communicating between devices. At the +//| physical level it consists of 2 wires: SCL and SDA, the clock and data +//| lines respectively. +//| +//| .. seealso:: Using this class directly requires careful lock management. +//| Instead, use :class:`~adafruit_bus_device.i2c_device.I2CDevice` to +//| manage locks. +//| +//| .. seealso:: Using this class to directly read registers requires manual +//| bit unpacking. Instead, use an existing driver or make one with +//| :ref:`Register ` data descriptors. +//| +//| :param ~microcontroller.Pin scl: The clock pin +//| :param ~microcontroller.Pin sda: The data pin +//| :param int frequency: The clock frequency in Hertz +//| :param int timeout: The maximum clock stretching timeut - (used only for bitbangio.I2C; ignored for busio.I2C) +//| +STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + busio_i2c_obj_t *self = m_new_obj(busio_i2c_obj_t); + self->base.type = &busio_i2c_type; + enum { ARG_scl, ARG_sda, ARG_frequency, ARG_timeout }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 255} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + assert_pin(args[ARG_scl].u_obj, false); + assert_pin(args[ARG_sda].u_obj, false); + const mcu_pin_obj_t* scl = MP_OBJ_TO_PTR(args[ARG_scl].u_obj); + assert_pin_free(scl); + const mcu_pin_obj_t* sda = MP_OBJ_TO_PTR(args[ARG_sda].u_obj); + assert_pin_free(sda); + common_hal_busio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int); + return (mp_obj_t)self; +} + +//| .. method:: deinit() +//| +//| Releases control of the underlying hardware so other classes can use it. +//| +STATIC mp_obj_t busio_i2c_obj_deinit(mp_obj_t self_in) { + busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_busio_i2c_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_deinit_obj, busio_i2c_obj_deinit); + +STATIC void check_for_deinit(busio_i2c_obj_t *self) { + if (common_hal_busio_i2c_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() +//| +//| No-op used in Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware on context exit. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t busio_i2c_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_busio_i2c_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_i2c___exit___obj, 4, 4, busio_i2c_obj___exit__); + +static void check_lock(busio_i2c_obj_t *self) { + asm(""); + if (!common_hal_busio_i2c_has_lock(self)) { + mp_raise_RuntimeError(translate("Function requires lock")); + } +} + +//| .. method:: scan() +//| +//| Scan all I2C addresses between 0x08 and 0x77 inclusive and return a +//| list of those that respond. +//| +//| :return: List of device ids on the I2C bus +//| :rtype: list +//| +STATIC mp_obj_t busio_i2c_scan(mp_obj_t self_in) { + busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + check_lock(self); + mp_obj_t list = mp_obj_new_list(0, NULL); + // 7-bit addresses 0b0000xxx and 0b1111xxx are reserved + for (int addr = 0x08; addr < 0x78; ++addr) { + bool success = common_hal_busio_i2c_probe(self, addr); + if (success) { + mp_obj_list_append(list, MP_OBJ_NEW_SMALL_INT(addr)); + } + } + return list; +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_scan_obj, busio_i2c_scan); + +//| .. method:: try_lock() +//| +//| Attempts to grab the I2C lock. Returns True on success. +//| +//| :return: True when lock has been grabbed +//| :rtype: bool +//| +STATIC mp_obj_t busio_i2c_obj_try_lock(mp_obj_t self_in) { + busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_busio_i2c_try_lock(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_try_lock_obj, busio_i2c_obj_try_lock); + +//| .. method:: unlock() +//| +//| Releases the I2C lock. +//| +STATIC mp_obj_t busio_i2c_obj_unlock(mp_obj_t self_in) { + busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_busio_i2c_unlock(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_unlock_obj, busio_i2c_obj_unlock); + +//| .. method:: readfrom_into(address, buffer, *, start=0, end=None) +//| +//| Read into ``buffer`` from the slave specified by ``address``. +//| The number of bytes read will be the length of ``buffer``. +//| At least one byte must be read. +//| +//| If ``start`` or ``end`` is provided, then the buffer will be sliced +//| as if ``buffer[start:end]``. This will not cause an allocation like +//| ``buf[start:end]`` will so it saves memory. +//| +//| :param int address: 7-bit device address +//| :param bytearray buffer: buffer to write into +//| :param int start: Index to start writing at +//| :param int end: Index to write up to but not include. Defaults to ``len(buffer)`` +//| +// Shared arg parsing for readfrom_into and writeto_then_readfrom. +STATIC void readfrom(busio_i2c_obj_t *self, mp_int_t address, mp_obj_t buffer, int32_t start, mp_int_t end) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_WRITE); + + size_t length = bufinfo.len; + normalize_buffer_bounds(&start, end, &length); + if (length == 0) { + mp_raise_ValueError(translate("Buffer must be at least length 1")); + } + + uint8_t status = common_hal_busio_i2c_read(self, address, ((uint8_t*)bufinfo.buf) + start, length); + if (status != 0) { + mp_raise_OSError(status); + } +} + +STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_address, ARG_buffer, ARG_start, ARG_end }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + }; + busio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + readfrom(self, args[ARG_address].u_int, args[ARG_buffer].u_obj, args[ARG_start].u_int, + args[ARG_end].u_int); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_readfrom_into_obj, 3, busio_i2c_readfrom_into); + +//| .. method:: writeto(address, buffer, *, start=0, end=None, stop=True) +//| +//| Write the bytes from ``buffer`` to the slave specified by ``address``. +//| Transmits a stop bit when stop is True. Setting stop=False is deprecated and stop will be +//| removed in CircuitPython 6.x. Use `writeto_then_readfrom` when needing a write, no stop and +//| repeated start before a read. +//| +//| If ``start`` or ``end`` is provided, then the buffer will be sliced +//| as if ``buffer[start:end]``. This will not cause an allocation like +//| ``buffer[start:end]`` will so it saves memory. +//| +//| Writing a buffer or slice of length zero is permitted, as it can be used +//| to poll for the existence of a device. +//| +//| :param int address: 7-bit device address +//| :param bytearray buffer: buffer containing the bytes to write +//| :param int start: Index to start writing from +//| :param int end: Index to read up to but not include. Defaults to ``len(buffer)`` +//| :param bool stop: If true, output an I2C stop condition after the buffer is written. +//| Deprecated. Will be removed in 6.x and act as stop=True. +//| +// Shared arg parsing for writeto and writeto_then_readfrom. +STATIC void writeto(busio_i2c_obj_t *self, mp_int_t address, mp_obj_t buffer, int32_t start, mp_int_t end, bool stop) { + // get the buffer to write the data from + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_READ); + + size_t length = bufinfo.len; + normalize_buffer_bounds(&start, end, &length); + + // do the transfer + uint8_t status = common_hal_busio_i2c_write(self, address, ((uint8_t*) bufinfo.buf) + start, + length, stop); + if (status != 0) { + mp_raise_OSError(status); + } +} + +STATIC mp_obj_t busio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_address, ARG_buffer, ARG_start, ARG_end, ARG_stop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + { MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, + }; + busio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + writeto(self, args[ARG_address].u_int, args[ARG_buffer].u_obj, args[ARG_start].u_int, + args[ARG_end].u_int, args[ARG_stop].u_bool); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_writeto_obj, 1, busio_i2c_writeto); + +//| .. method:: writeto_then_readfrom(address, out_buffer, in_buffer, *, out_start=0, out_end=None, in_start=0, in_end=None) +//| +//| Write the bytes from ``out_buffer`` to the slave specified by ``address``, generate no stop +//| bit, generate a repeated start and read into ``in_buffer``. ``out_buffer`` and +//| ``in_buffer`` can be the same buffer because they are used sequentially. +//| +//| If ``start`` or ``end`` is provided, then the corresponding buffer will be sliced +//| as if ``buffer[start:end]``. This will not cause an allocation like ``buf[start:end]`` +//| will so it saves memory. +//| +//| :param int address: 7-bit device address +//| :param bytearray out_buffer: buffer containing the bytes to write +//| :param bytearray in_buffer: buffer to write into +//| :param int out_start: Index to start writing from +//| :param int out_end: Index to read up to but not include. Defaults to ``len(buffer)`` +//| :param int in_start: Index to start writing at +//| :param int in_end: Index to write up to but not include. Defaults to ``len(buffer)`` +//| +STATIC mp_obj_t busio_i2c_writeto_then_readfrom(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_address, ARG_out_buffer, ARG_in_buffer, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_out_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_in_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_out_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_out_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + { MP_QSTR_in_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_in_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + }; + busio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + writeto(self, args[ARG_address].u_int, args[ARG_out_buffer].u_obj, args[ARG_out_start].u_int, + args[ARG_out_end].u_int, false); + readfrom(self, args[ARG_address].u_int, args[ARG_in_buffer].u_obj, args[ARG_in_start].u_int, + args[ARG_in_end].u_int); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_writeto_then_readfrom_obj, 3, busio_i2c_writeto_then_readfrom); + +STATIC const mp_rom_map_elem_t busio_i2c_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&busio_i2c_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&busio_i2c___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&busio_i2c_scan_obj) }, + + { MP_ROM_QSTR(MP_QSTR_try_lock), MP_ROM_PTR(&busio_i2c_try_lock_obj) }, + { MP_ROM_QSTR(MP_QSTR_unlock), MP_ROM_PTR(&busio_i2c_unlock_obj) }, + + { MP_ROM_QSTR(MP_QSTR_readfrom_into), MP_ROM_PTR(&busio_i2c_readfrom_into_obj) }, + { MP_ROM_QSTR(MP_QSTR_writeto), MP_ROM_PTR(&busio_i2c_writeto_obj) }, + { MP_ROM_QSTR(MP_QSTR_writeto_then_readfrom), MP_ROM_PTR(&busio_i2c_writeto_then_readfrom_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(busio_i2c_locals_dict, busio_i2c_locals_dict_table); + +const mp_obj_type_t busio_i2c_type = { + { &mp_type_type }, + .name = MP_QSTR_I2C, + .make_new = busio_i2c_make_new, + .locals_dict = (mp_obj_dict_t*)&busio_i2c_locals_dict, +}; diff --git a/shared-bindings/busio/I2C.h b/shared-bindings/busio/I2C.h new file mode 100644 index 00000000000..a2d5dbf5073 --- /dev/null +++ b/shared-bindings/busio/I2C.h @@ -0,0 +1,75 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +// Machine is the HAL for low-level, hardware accelerated functions. It is not +// meant to simplify APIs, its only meant to unify them so that other modules +// do not require port specific logic. +// +// This file includes externs for all functions a port should implement to +// support the machine module. + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_H + +#include "py/obj.h" + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/busio/I2C.h" + +// Type object used in Python. Should be shared between ports. +extern const mp_obj_type_t busio_i2c_type; + +// Initializes the hardware peripheral. +extern void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, + const mcu_pin_obj_t * scl, + const mcu_pin_obj_t * sda, + uint32_t frequency, + uint32_t timeout); + +extern void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self); +extern bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self); + +extern bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self); +extern bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self); +extern void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self); + +// Probe the bus to see if a device acknowledges the given address. +extern bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr); + +// Write to the device and return 0 on success or an appropriate error code from mperrno.h +extern uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, + const uint8_t * data, size_t len, + bool stop); + +// Reads memory of the i2c device picking up where it left off and return 0 on +// success or an appropriate error code from mperrno.h +extern uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, + uint8_t * data, size_t len); + +// This is used by the supervisor to claim I2C devices indefinitely. +extern void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_H diff --git a/shared-bindings/busio/OneWire.c b/shared-bindings/busio/OneWire.c new file mode 100644 index 00000000000..aca2a3ef20e --- /dev/null +++ b/shared-bindings/busio/OneWire.c @@ -0,0 +1,177 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "lib/utils/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/runtime0.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/busio/OneWire.h" +#include "shared-bindings/util.h" + +//| .. currentmodule:: busio +//| +//| :class:`OneWire` -- Lowest-level of the Maxim OneWire protocol +//| ================================================================= +//| +//| :class:`~busio.OneWire` implements the timing-sensitive foundation of the Maxim +//| (formerly Dallas Semi) OneWire protocol. +//| +//| Protocol definition is here: https://www.maximintegrated.com/en/app-notes/index.mvp/id/126 +//| +//| .. class:: OneWire(pin) +//| +//| Create a OneWire object associated with the given pin. The object +//| implements the lowest level timing-sensitive bits of the protocol. +//| +//| :param ~microcontroller.Pin pin: Pin connected to the OneWire bus +//| +//| Read a short series of pulses:: +//| +//| import busio +//| import board +//| +//| onewire = busio.OneWire(board.D7) +//| onewire.reset() +//| onewire.write_bit(True) +//| onewire.write_bit(False) +//| print(onewire.read_bit()) +//| +STATIC mp_obj_t busio_onewire_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_pin }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + assert_pin(args[ARG_pin].u_obj, false); + const mcu_pin_obj_t* pin = MP_OBJ_TO_PTR(args[ARG_pin].u_obj); + assert_pin_free(pin); + + busio_onewire_obj_t *self = m_new_obj(busio_onewire_obj_t); + self->base.type = &busio_onewire_type; + + common_hal_busio_onewire_construct(self, pin); + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialize the OneWire bus and release any hardware resources for reuse. +//| +STATIC mp_obj_t busio_onewire_deinit(mp_obj_t self_in) { + busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_busio_onewire_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_deinit_obj, busio_onewire_deinit); + +STATIC void check_for_deinit(busio_onewire_obj_t *self) { + if (common_hal_busio_onewire_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t busio_onewire_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_busio_onewire_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_onewire___exit___obj, 4, 4, busio_onewire_obj___exit__); + +//| .. method:: reset() +//| +//| Reset the OneWire bus and read presence +//| +//| :returns: False when at least one device is present +//| :rtype: bool +//| +STATIC mp_obj_t busio_onewire_obj_reset(mp_obj_t self_in) { + busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + return mp_obj_new_bool(common_hal_busio_onewire_reset(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_reset_obj, busio_onewire_obj_reset); + +//| .. method:: read_bit() +//| +//| Read in a bit +//| +//| :returns: bit state read +//| :rtype: bool +//| +STATIC mp_obj_t busio_onewire_obj_read_bit(mp_obj_t self_in) { + busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + return mp_obj_new_bool(common_hal_busio_onewire_read_bit(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_read_bit_obj, busio_onewire_obj_read_bit); + +//| .. method:: write_bit(value) +//| +//| Write out a bit based on value. +//| +STATIC mp_obj_t busio_onewire_obj_write_bit(mp_obj_t self_in, mp_obj_t bool_obj) { + busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + common_hal_busio_onewire_write_bit(self, mp_obj_is_true(bool_obj)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(busio_onewire_write_bit_obj, busio_onewire_obj_write_bit); + +STATIC const mp_rom_map_elem_t busio_onewire_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&busio_onewire_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&busio_onewire___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&busio_onewire_reset_obj) }, + { MP_ROM_QSTR(MP_QSTR_read_bit), MP_ROM_PTR(&busio_onewire_read_bit_obj) }, + { MP_ROM_QSTR(MP_QSTR_write_bit), MP_ROM_PTR(&busio_onewire_write_bit_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(busio_onewire_locals_dict, busio_onewire_locals_dict_table); + +const mp_obj_type_t busio_onewire_type = { + { &mp_type_type }, + .name = MP_QSTR_OneWire, + .make_new = busio_onewire_make_new, + .locals_dict = (mp_obj_dict_t*)&busio_onewire_locals_dict, +}; diff --git a/shared-bindings/busio/OneWire.h b/shared-bindings/busio/OneWire.h new file mode 100644 index 00000000000..9ee5f639b1f --- /dev/null +++ b/shared-bindings/busio/OneWire.h @@ -0,0 +1,43 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_ONEWIRE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_ONEWIRE_H + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/busio/OneWire.h" + +extern const mp_obj_type_t busio_onewire_type; + +extern void common_hal_busio_onewire_construct(busio_onewire_obj_t* self, + const mcu_pin_obj_t* pin); +extern void common_hal_busio_onewire_deinit(busio_onewire_obj_t* self); +extern bool common_hal_busio_onewire_deinited(busio_onewire_obj_t* self); +extern bool common_hal_busio_onewire_reset(busio_onewire_obj_t* self); +extern bool common_hal_busio_onewire_read_bit(busio_onewire_obj_t* self); +extern void common_hal_busio_onewire_write_bit(busio_onewire_obj_t* self, bool bit); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_ONEWIRE_H diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c new file mode 100644 index 00000000000..d47bf499a23 --- /dev/null +++ b/shared-bindings/busio/SPI.c @@ -0,0 +1,408 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +// This file contains all of the Python API definitions for the +// busio.SPI class. + +#include + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/util.h" + +#include "lib/utils/buffer_helper.h" +#include "lib/utils/context_manager_helpers.h" +#include "py/mperrno.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: busio +//| +//| :class:`SPI` -- a 3-4 wire serial protocol +//| ----------------------------------------------- +//| +//| SPI is a serial protocol that has exclusive pins for data in and out of the +//| master. It is typically faster than :py:class:`~busio.I2C` because a +//| separate pin is used to control the active slave rather than a transitted +//| address. This class only manages three of the four SPI lines: `!clock`, +//| `!MOSI`, `!MISO`. Its up to the client to manage the appropriate slave +//| select line. (This is common because multiple slaves can share the `!clock`, +//| `!MOSI` and `!MISO` lines and therefore the hardware.) +//| +//| .. class:: SPI(clock, MOSI=None, MISO=None) +//| +//| Construct an SPI object on the given pins. +//| +//| .. seealso:: Using this class directly requires careful lock management. +//| Instead, use :class:`~adafruit_bus_device.spi_device.SPIDevice` to +//| manage locks. +//| +//| .. seealso:: Using this class to directly read registers requires manual +//| bit unpacking. Instead, use an existing driver or make one with +//| :ref:`Register ` data descriptors. +//| +//| :param ~microcontroller.Pin clock: the pin to use for the clock. +//| :param ~microcontroller.Pin MOSI: the Master Out Slave In pin. +//| :param ~microcontroller.Pin MISO: the Master In Slave Out pin. +//| + +// TODO(tannewt): Support LSB SPI. +STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + busio_spi_obj_t *self = m_new_obj(busio_spi_obj_t); + self->base.type = &busio_spi_type; + enum { ARG_clock, ARG_MOSI, ARG_MISO }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_MOSI, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_MISO, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + assert_pin(args[ARG_clock].u_obj, false); + assert_pin(args[ARG_MOSI].u_obj, true); + assert_pin(args[ARG_MISO].u_obj, true); + const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(args[ARG_clock].u_obj); + assert_pin_free(clock); + const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(args[ARG_MOSI].u_obj); + assert_pin_free(mosi); + const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(args[ARG_MISO].u_obj); + assert_pin_free(miso); + common_hal_busio_spi_construct(self, clock, mosi, miso); + return (mp_obj_t)self; +} + +//| .. method:: deinit() +//| +//| Turn off the SPI bus. +//| +STATIC mp_obj_t busio_spi_obj_deinit(mp_obj_t self_in) { + busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_busio_spi_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_deinit_obj, busio_spi_obj_deinit); + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t busio_spi_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_busio_spi_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_spi_obj___exit___obj, 4, 4, busio_spi_obj___exit__); + +STATIC void check_lock(busio_spi_obj_t *self) { + asm(""); + if (!common_hal_busio_spi_has_lock(self)) { + mp_raise_RuntimeError(translate("Function requires lock")); + } +} + +STATIC void check_for_deinit(busio_spi_obj_t *self) { + if (common_hal_busio_spi_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: configure(*, baudrate=100000, polarity=0, phase=0, bits=8) +//| +//| Configures the SPI bus. The SPI object must be locked. +//| +//| :param int baudrate: the desired clock rate in Hertz. The actual clock rate may be higher or lower +//| due to the granularity of available clock settings. +//| Check the `frequency` attribute for the actual clock rate. +//| :param int polarity: the base state of the clock line (0 or 1) +//| :param int phase: the edge of the clock that data is captured. First (0) +//| or second (1). Rising or falling depends on clock polarity. +//| :param int bits: the number of bits per word +//| +//| .. note:: On the SAMD21, it is possible to set the baudrate to 24 MHz, but that +//| speed is not guaranteed to work. 12 MHz is the next available lower speed, and is +//| within spec for the SAMD21. +//| +//| .. note:: On the nRF52840, these baudrates are available: 125kHz, 250kHz, 1MHz, 2MHz, 4MHz, +//| and 8MHz. 16MHz and 32MHz are also available, but only on the first +//| `busio.SPI` object you create. Two more ``busio.SPI`` objects can be created, but they are restricted +//| to 8MHz maximum. This is a hardware restriction: there is only one high-speed SPI peripheral. +//| If you pick a a baudrate other than one of these, the nearest lower +//| baudrate will be chosen, with a minimum of 125kHz. +STATIC mp_obj_t busio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 100000} }, + { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, + }; + busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + uint8_t polarity = args[ARG_polarity].u_int; + if (polarity != 0 && polarity != 1) { + mp_raise_ValueError(translate("Invalid polarity")); + } + uint8_t phase = args[ARG_phase].u_int; + if (phase != 0 && phase != 1) { + mp_raise_ValueError(translate("Invalid phase")); + } + uint8_t bits = args[ARG_bits].u_int; + if (bits != 8 && bits != 9) { + mp_raise_ValueError(translate("Invalid number of bits")); + } + + if (!common_hal_busio_spi_configure(self, args[ARG_baudrate].u_int, + polarity, phase, bits)) { + mp_raise_OSError(MP_EIO); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_configure_obj, 1, busio_spi_configure); + +//| .. method:: try_lock() +//| +//| Attempts to grab the SPI lock. Returns True on success. +//| +//| :return: True when lock has been grabbed +//| :rtype: bool +//| +STATIC mp_obj_t busio_spi_obj_try_lock(mp_obj_t self_in) { + busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(common_hal_busio_spi_try_lock(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_try_lock_obj, busio_spi_obj_try_lock); + +//| .. method:: unlock() +//| +//| Releases the SPI lock. +//| +STATIC mp_obj_t busio_spi_obj_unlock(mp_obj_t self_in) { + busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_busio_spi_unlock(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_unlock_obj, busio_spi_obj_unlock); + +//| .. method:: write(buffer, *, start=0, end=None) +//| +//| Write the data contained in ``buffer``. The SPI object must be locked. +//| If the buffer is empty, nothing happens. +//| +//| :param bytearray buffer: Write out the data in this buffer +//| :param int start: Start of the slice of ``buffer`` to write out: ``buffer[start:end]`` +//| :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)`` +//| +STATIC mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_buffer, ARG_start, ARG_end }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + }; + busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); + int32_t start = args[ARG_start].u_int; + size_t length = bufinfo.len; + normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); + + if (length == 0) { + return mp_const_none; + } + + bool ok = common_hal_busio_spi_write(self, ((uint8_t*)bufinfo.buf) + start, length); + if (!ok) { + mp_raise_OSError(MP_EIO); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_obj, 2, busio_spi_write); + + +//| .. method:: readinto(buffer, *, start=0, end=None, write_value=0) +//| +//| Read into ``buffer`` while writing ``write_value`` for each byte read. +//| The SPI object must be locked. +//| If the number of bytes to read is 0, nothing happens. +//| +//| :param bytearray buffer: Read data into this buffer +//| :param int start: Start of the slice of ``buffer`` to read into: ``buffer[start:end]`` +//| :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)`` +//| :param int write_value: Value to write while reading. (Usually ignored.) +//| +STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_buffer, ARG_start, ARG_end, ARG_write_value }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + { MP_QSTR_write_value,MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + }; + busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE); + int32_t start = args[ARG_start].u_int; + size_t length = bufinfo.len; + normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); + + if (length == 0) { + return mp_const_none; + } + + bool ok = common_hal_busio_spi_read(self, ((uint8_t*)bufinfo.buf) + start, length, args[ARG_write_value].u_int); + if (!ok) { + mp_raise_OSError(MP_EIO); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_readinto_obj, 2, busio_spi_readinto); + +//| .. method:: write_readinto(buffer_out, buffer_in, *, out_start=0, out_end=None, in_start=0, in_end=None) +//| +//| Write out the data in ``buffer_out`` while simultaneously reading data into ``buffer_in``. +//| The SPI object must be locked. +//| The lengths of the slices defined by ``buffer_out[out_start:out_end]`` and ``buffer_in[in_start:in_end]`` +//| must be equal. +//| If buffer slice lengths are both 0, nothing happens. +//| +//| :param bytearray buffer_out: Write out the data in this buffer +//| :param bytearray buffer_in: Read data into this buffer +//| :param int out_start: Start of the slice of buffer_out to write out: ``buffer_out[out_start:out_end]`` +//| :param int out_end: End of the slice; this index is not included. Defaults to ``len(buffer_out)`` +//| :param int in_start: Start of the slice of ``buffer_in`` to read into: ``buffer_in[in_start:in_end]`` +//| :param int in_end: End of the slice; this index is not included. Defaults to ``len(buffer_in)`` +//| +STATIC mp_obj_t busio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_buffer_out, ARG_buffer_in, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_buffer_out, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_buffer_in, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_out_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_out_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + { MP_QSTR_in_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_in_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + }; + busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t buf_out_info; + mp_get_buffer_raise(args[ARG_buffer_out].u_obj, &buf_out_info, MP_BUFFER_READ); + int32_t out_start = args[ARG_out_start].u_int; + size_t out_length = buf_out_info.len; + normalize_buffer_bounds(&out_start, args[ARG_out_end].u_int, &out_length); + + mp_buffer_info_t buf_in_info; + mp_get_buffer_raise(args[ARG_buffer_in].u_obj, &buf_in_info, MP_BUFFER_WRITE); + int32_t in_start = args[ARG_in_start].u_int; + size_t in_length = buf_in_info.len; + normalize_buffer_bounds(&in_start, args[ARG_in_end].u_int, &in_length); + + if (out_length != in_length) { + mp_raise_ValueError(translate("buffer slices must be of equal length")); + } + + if (out_length == 0) { + return mp_const_none; + } + + bool ok = common_hal_busio_spi_transfer(self, + ((uint8_t*)buf_out_info.buf) + out_start, + ((uint8_t*)buf_in_info.buf) + in_start, + out_length); + if (!ok) { + mp_raise_OSError(MP_EIO); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_readinto_obj, 2, busio_spi_write_readinto); + +//| .. attribute:: frequency +//| +//| The actual SPI bus frequency. This may not match the frequency requested +//| due to internal limitations. +//| +STATIC mp_obj_t busio_spi_obj_get_frequency(mp_obj_t self_in) { + busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_busio_spi_get_frequency(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_get_frequency_obj, busio_spi_obj_get_frequency); + +const mp_obj_property_t busio_spi_frequency_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&busio_spi_get_frequency_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t busio_spi_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&busio_spi_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&busio_spi_obj___exit___obj) }, + + { MP_ROM_QSTR(MP_QSTR_configure), MP_ROM_PTR(&busio_spi_configure_obj) }, + { MP_ROM_QSTR(MP_QSTR_try_lock), MP_ROM_PTR(&busio_spi_try_lock_obj) }, + { MP_ROM_QSTR(MP_QSTR_unlock), MP_ROM_PTR(&busio_spi_unlock_obj) }, + + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&busio_spi_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&busio_spi_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&busio_spi_write_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&busio_spi_frequency_obj) } +}; +STATIC MP_DEFINE_CONST_DICT(busio_spi_locals_dict, busio_spi_locals_dict_table); + +const mp_obj_type_t busio_spi_type = { + { &mp_type_type }, + .name = MP_QSTR_SPI, + .make_new = busio_spi_make_new, + .locals_dict = (mp_obj_dict_t*)&busio_spi_locals_dict, +}; diff --git a/shared-bindings/busio/SPI.h b/shared-bindings/busio/SPI.h new file mode 100644 index 00000000000..b7b0715d136 --- /dev/null +++ b/shared-bindings/busio/SPI.h @@ -0,0 +1,73 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SPI_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SPI_H + +#include "py/obj.h" + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/busio/SPI.h" + +// Type object used in Python. Should be shared between ports. +extern const mp_obj_type_t busio_spi_type; + +// Construct an underlying SPI object. +extern void common_hal_busio_spi_construct(busio_spi_obj_t *self, + const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, + const mcu_pin_obj_t * miso); + +extern void common_hal_busio_spi_deinit(busio_spi_obj_t *self); +extern bool common_hal_busio_spi_deinited(busio_spi_obj_t *self); + +extern bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits); + +extern bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self); +extern bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self); +extern void common_hal_busio_spi_unlock(busio_spi_obj_t *self); + +// Writes out the given data. +extern bool common_hal_busio_spi_write(busio_spi_obj_t *self, const uint8_t *data, size_t len); + +// Reads in len bytes while outputting zeroes. +extern bool common_hal_busio_spi_read(busio_spi_obj_t *self, uint8_t *data, size_t len, uint8_t write_value); + +// Reads and write len bytes simultaneously. +extern bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_out, uint8_t *data_in, size_t len); + +// Return actual SPI bus frequency. +uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t* self); + +// Return SPI bus phase. +uint8_t common_hal_busio_spi_get_phase(busio_spi_obj_t* self); + +// Return SPI bus polarity. +uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t* self); + +// This is used by the supervisor to claim SPI devices indefinitely. +extern void common_hal_busio_spi_never_reset(busio_spi_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SPI_H diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c new file mode 100644 index 00000000000..c7eef8c4388 --- /dev/null +++ b/shared-bindings/busio/UART.c @@ -0,0 +1,383 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "shared-bindings/busio/UART.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" + +#include "lib/utils/context_manager_helpers.h" +#include "lib/utils/interrupt_char.h" + +#include "py/ioctl.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "supervisor/shared/translate.h" + + +//| .. currentmodule:: busio +//| +//| :class:`UART` -- a bidirectional serial protocol +//| ================================================= +//| +//| +//| .. class:: UART(tx, rx, *, baudrate=9600, bits=8, parity=None, stop=1, timeout=1, receiver_buffer_size=64) +//| +//| A common bidirectional serial protocol that uses an an agreed upon speed +//| rather than a shared clock line. +//| +//| :param ~microcontroller.Pin tx: the pin to transmit with, or ``None`` if this ``UART`` is receive-only. +//| :param ~microcontroller.Pin rx: the pin to receive on, or ``None`` if this ``UART`` is transmit-only. +//| :param int baudrate: the transmit and receive speed. +//| :param int bits: the number of bits per byte, 7, 8 or 9. +//| :param Parity parity: the parity used for error checking. +//| :param int stop: the number of stop bits, 1 or 2. +//| :param float timeout: the timeout in seconds to wait for the first character and between subsequent characters. Raises ``ValueError`` if timeout >100 seconds. +//| :param int receiver_buffer_size: the character length of the read buffer (0 to disable). (When a character is 9 bits the buffer will be 2 * receiver_buffer_size bytes.) +//| +//| *New in CircuitPython 4.0:* ``timeout`` has incompatibly changed units from milliseconds to seconds. +//| The new upper limit on ``timeout`` is meant to catch mistaken use of milliseconds. +//| +typedef struct { + mp_obj_base_t base; +} busio_uart_parity_obj_t; +extern const busio_uart_parity_obj_t busio_uart_parity_even_obj; +extern const busio_uart_parity_obj_t busio_uart_parity_odd_obj; + +STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + // Always initially allocate the UART object within the long-lived heap. + // This is needed to avoid crashes with certain UART implementations which + // cannot accomodate being moved after creation. (See + // https://github.com/adafruit/circuitpython/issues/1056) + busio_uart_obj_t *self = m_new_ll_obj(busio_uart_obj_t); + self->base.type = &busio_uart_type; + enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_timeout, ARG_receiver_buffer_size}; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 9600} }, + { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, + { MP_QSTR_parity, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, + { MP_QSTR_receiver_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + assert_pin(args[ARG_rx].u_obj, true); + const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(args[ARG_rx].u_obj); + assert_pin_free(rx); + + assert_pin(args[ARG_tx].u_obj, true); + const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(args[ARG_tx].u_obj); + assert_pin_free(tx); + + uint8_t bits = args[ARG_bits].u_int; + if (bits < 7 || bits > 9) { + mp_raise_ValueError(translate("bits must be 7, 8 or 9")); + } + + uart_parity_t parity = PARITY_NONE; + if (args[ARG_parity].u_obj == &busio_uart_parity_even_obj) { + parity = PARITY_EVEN; + } else if (args[ARG_parity].u_obj == &busio_uart_parity_odd_obj) { + parity = PARITY_ODD; + } + + uint8_t stop = args[ARG_stop].u_int; + if (stop != 1 && stop != 2) { + mp_raise_ValueError(translate("stop must be 1 or 2")); + } + + mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj); + if (timeout > (mp_float_t)100.0) { + mp_raise_ValueError(translate("timeout >100 (units are now seconds, not msecs)")); + } + + common_hal_busio_uart_construct(self, tx, rx, + args[ARG_baudrate].u_int, bits, parity, stop, timeout, + args[ARG_receiver_buffer_size].u_int); + return (mp_obj_t)self; +} + +//| .. method:: deinit() +//| +//| Deinitialises the UART and releases any hardware resources for reuse. +//| +STATIC mp_obj_t busio_uart_obj_deinit(mp_obj_t self_in) { + busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_busio_uart_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_deinit_obj, busio_uart_obj_deinit); + +STATIC void check_for_deinit(busio_uart_obj_t *self) { + if (common_hal_busio_uart_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t busio_uart_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_busio_uart_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_uart_obj___exit__); + +// These are standard stream methods. Code is in py/stream.c. +// +//| .. method:: read(nbytes=None) +//| +//| Read characters. If ``nbytes`` is specified then read at most that many +//| bytes. Otherwise, read everything that arrives until the connection +//| times out. Providing the number of bytes expected is highly recommended +//| because it will be faster. +//| +//| :return: Data read +//| :rtype: bytes or None +//| +//| .. method:: readinto(buf) +//| +//| Read bytes into the ``buf``. Read at most ``len(buf)`` bytes. +//| +//| :return: number of bytes read and stored into ``buf`` +//| :rtype: int or None (on a non-blocking error) +//| +//| *New in CircuitPython 4.0:* No length parameter is permitted. + +//| .. method:: readline() +//| +//| Read a line, ending in a newline character. +//| +//| :return: the line read +//| :rtype: int or None +//| +//| .. method:: write(buf) +//| +//| Write the buffer of bytes to the bus. +//| +//| *New in CircuitPython 4.0:* ``buf`` must be bytes, not a string. +//| +//| :return: the number of bytes written +//| :rtype: int or None +//| + +// These three methods are used by the shared stream methods. +STATIC mp_uint_t busio_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { + busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + byte *buf = buf_in; + + // make sure we want at least 1 char + if (size == 0) { + return 0; + } + + return common_hal_busio_uart_read(self, buf, size, errcode); +} + +STATIC mp_uint_t busio_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { + busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + const byte *buf = buf_in; + + return common_hal_busio_uart_write(self, buf, size, errcode); +} + +STATIC mp_uint_t busio_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { + busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + mp_uint_t ret; + if (request == MP_IOCTL_POLL) { + mp_uint_t flags = arg; + ret = 0; + if ((flags & MP_IOCTL_POLL_RD) && common_hal_busio_uart_rx_characters_available(self) > 0) { + ret |= MP_IOCTL_POLL_RD; + } + if ((flags & MP_IOCTL_POLL_WR) && common_hal_busio_uart_ready_to_tx(self)) { + ret |= MP_IOCTL_POLL_WR; + } + } else { + *errcode = MP_EINVAL; + ret = MP_STREAM_ERROR; + } + return ret; +} + +//| .. attribute:: baudrate +//| +//| The current baudrate. +//| +STATIC mp_obj_t busio_uart_obj_get_baudrate(mp_obj_t self_in) { + busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_busio_uart_get_baudrate(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_get_baudrate_obj, busio_uart_obj_get_baudrate); + +STATIC mp_obj_t busio_uart_obj_set_baudrate(mp_obj_t self_in, mp_obj_t baudrate) { + busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_busio_uart_set_baudrate(self, mp_obj_get_int(baudrate)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(busio_uart_set_baudrate_obj, busio_uart_obj_set_baudrate); + + +const mp_obj_property_t busio_uart_baudrate_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&busio_uart_get_baudrate_obj, + (mp_obj_t)&busio_uart_set_baudrate_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: in_waiting +//| +//| The number of bytes in the input buffer, available to be read +//| +STATIC mp_obj_t busio_uart_obj_get_in_waiting(mp_obj_t self_in) { + busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_busio_uart_rx_characters_available(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_get_in_waiting_obj, busio_uart_obj_get_in_waiting); + +const mp_obj_property_t busio_uart_in_waiting_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&busio_uart_get_in_waiting_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: reset_input_buffer() +//| +//| Discard any unread characters in the input buffer. +//| +STATIC mp_obj_t busio_uart_obj_reset_input_buffer(mp_obj_t self_in) { + busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_busio_uart_clear_rx_buffer(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_reset_input_buffer_obj, busio_uart_obj_reset_input_buffer); + +//| .. class:: busio.UART.Parity() +//| +//| Enum-like class to define the parity used to verify correct data transfer. +//| +//| .. data:: ODD +//| +//| Total number of ones should be odd. +//| +//| .. data:: EVEN +//| +//| Total number of ones should be even. +//| +const mp_obj_type_t busio_uart_parity_type; + +const busio_uart_parity_obj_t busio_uart_parity_odd_obj = { + { &busio_uart_parity_type }, +}; + +const busio_uart_parity_obj_t busio_uart_parity_even_obj = { + { &busio_uart_parity_type }, +}; + +STATIC const mp_rom_map_elem_t busio_uart_parity_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_ODD), MP_ROM_PTR(&busio_uart_parity_odd_obj) }, + { MP_ROM_QSTR(MP_QSTR_EVEN), MP_ROM_PTR(&busio_uart_parity_even_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(busio_uart_parity_locals_dict, busio_uart_parity_locals_dict_table); + +STATIC void busio_uart_parity_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + qstr parity = MP_QSTR_ODD; + if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&busio_uart_parity_even_obj)) { + parity = MP_QSTR_EVEN; + } + mp_printf(print, "%q.%q.%q.%q", MP_QSTR_busio, MP_QSTR_UART, MP_QSTR_Parity, parity); +} + +const mp_obj_type_t busio_uart_parity_type = { + { &mp_type_type }, + .name = MP_QSTR_Parity, + .print = busio_uart_parity_print, + .locals_dict = (mp_obj_t)&busio_uart_parity_locals_dict, +}; + +STATIC const mp_rom_map_elem_t busio_uart_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&busio_uart_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&busio_uart___exit___obj) }, + + // Standard stream methods. + { MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_reset_input_buffer), MP_ROM_PTR(&busio_uart_reset_input_buffer_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_baudrate), MP_ROM_PTR(&busio_uart_baudrate_obj) }, + { MP_ROM_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&busio_uart_in_waiting_obj) }, + + // Nested Enum-like Classes. + { MP_ROM_QSTR(MP_QSTR_Parity), MP_ROM_PTR(&busio_uart_parity_type) }, +}; +STATIC MP_DEFINE_CONST_DICT(busio_uart_locals_dict, busio_uart_locals_dict_table); + +STATIC const mp_stream_p_t uart_stream_p = { + .read = busio_uart_read, + .write = busio_uart_write, + .ioctl = busio_uart_ioctl, + .is_text = false, + // Match PySerial when possible, such as disallowing optional length argument for .readinto() + .pyserial_compatibility = true, +}; + +const mp_obj_type_t busio_uart_type = { + { &mp_type_type }, + .name = MP_QSTR_UART, + .make_new = busio_uart_make_new, + .getiter = mp_identity_getiter, + .iternext = mp_stream_unbuffered_iter, + .protocol = &uart_stream_p, + .locals_dict = (mp_obj_dict_t*)&busio_uart_locals_dict, +}; diff --git a/shared-bindings/busio/UART.h b/shared-bindings/busio/UART.h new file mode 100644 index 00000000000..776a996be8f --- /dev/null +++ b/shared-bindings/busio/UART.h @@ -0,0 +1,66 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_UART_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_UART_H + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/busio/UART.h" + +extern const mp_obj_type_t busio_uart_type; + +typedef enum { + PARITY_NONE, + PARITY_EVEN, + PARITY_ODD +} uart_parity_t; + +// Construct an underlying UART object. +extern void common_hal_busio_uart_construct(busio_uart_obj_t *self, + const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, + uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout, + uint16_t receiver_buffer_size); + +extern void common_hal_busio_uart_deinit(busio_uart_obj_t *self); +extern bool common_hal_busio_uart_deinited(busio_uart_obj_t *self); + +// Read characters. len is in characters NOT bytes! +extern size_t common_hal_busio_uart_read(busio_uart_obj_t *self, + uint8_t *data, size_t len, int *errcode); + +// Write characters. len is in characters NOT bytes! +extern size_t common_hal_busio_uart_write(busio_uart_obj_t *self, + const uint8_t *data, size_t len, int *errcode); + +extern uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self); +extern void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate); + + +extern uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self); +extern void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self); +extern bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_UART_H diff --git a/shared-bindings/busio/__init__.c b/shared-bindings/busio/__init__.c new file mode 100644 index 00000000000..ff2933dc6dd --- /dev/null +++ b/shared-bindings/busio/__init__.c @@ -0,0 +1,100 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/busio/__init__.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/busio/OneWire.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/busio/UART.h" + +#include "py/runtime.h" + +//| :mod:`busio` --- Hardware accelerated behavior +//| ================================================= +//| +//| .. module:: busio +//| :synopsis: Hardware accelerated behavior +//| :platform: SAMD21 +//| +//| The `busio` module contains classes to support a variety of serial +//| protocols. +//| +//| When the microcontroller does not support the behavior in a hardware +//| accelerated fashion it may internally use a bitbang routine. However, if +//| hardware support is available on a subset of pins but not those provided, +//| then a RuntimeError will be raised. Use the `bitbangio` module to explicitly +//| bitbang a serial protocol on any general purpose pins. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| I2C +//| OneWire +//| SPI +//| UART +//| +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed if the program continues after use. To do so, either +//| call :py:meth:`!deinit` or use a context manager. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +//| For example:: +//| +//| import busio +//| from board import * +//| +//| i2c = busio.I2C(SCL, SDA) +//| print(i2c.scan()) +//| i2c.deinit() +//| +//| This example will initialize the the device, run +//| :py:meth:`~busio.I2C.scan` and then :py:meth:`~busio.I2C.deinit` the +//| hardware. The last step is optional because CircuitPython automatically +//| resets hardware after a program finishes. +//| + +STATIC const mp_rom_map_elem_t busio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_busio) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&busio_i2c_type) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&busio_spi_type) }, + { MP_ROM_QSTR(MP_QSTR_OneWire), MP_ROM_PTR(&busio_onewire_type) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&busio_uart_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(busio_module_globals, busio_module_globals_table); + +const mp_obj_module_t busio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&busio_module_globals, +}; diff --git a/shared-bindings/busio/__init__.h b/shared-bindings/busio/__init__.h new file mode 100644 index 00000000000..bcea30504ba --- /dev/null +++ b/shared-bindings/busio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO___INIT___H + +#include "py/obj.h" + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO___INIT___H diff --git a/shared-bindings/digitalio/DigitalInOut.c b/shared-bindings/digitalio/DigitalInOut.c new file mode 100644 index 00000000000..16472c12c1c --- /dev/null +++ b/shared-bindings/digitalio/DigitalInOut.c @@ -0,0 +1,392 @@ +/* + * 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 +#include + +#include "lib/utils/context_manager_helpers.h" + +#include "py/nlr.h" +#include "py/objtype.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/mphal.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/Direction.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "shared-bindings/digitalio/Pull.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: digitalio +//| +//| :class:`DigitalInOut` -- digital input and output +//| ========================================================= +//| +//| A DigitalInOut is used to digitally control I/O pins. For analog control of +//| a pin, see the :py:class:`analogio.AnalogIn` and +//| :py:class:`analogio.AnalogOut` classes. +//| + +//| .. class:: DigitalInOut(pin) +//| +//| Create a new DigitalInOut object associated with the pin. Defaults to input +//| with no pull. Use :py:meth:`switch_to_input` and +//| :py:meth:`switch_to_output` to change the direction. +//| +//| :param ~microcontroller.Pin pin: The pin to control +//| +STATIC mp_obj_t digitalio_digitalinout_make_new(const mp_obj_type_t *type, + mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); + + digitalio_digitalinout_obj_t *self = m_new_obj(digitalio_digitalinout_obj_t); + self->base.type = &digitalio_digitalinout_type; + + assert_pin(args[0], false); + mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(args[0]); + assert_pin_free(pin); + common_hal_digitalio_digitalinout_construct(self, pin); + + return (mp_obj_t)self; +} + +//| .. method:: deinit() +//| +//| Turn off the DigitalInOut and release the pin for other use. +//| +STATIC mp_obj_t digitalio_digitalinout_obj_deinit(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_digitalio_digitalinout_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_deinit_obj, digitalio_digitalinout_obj_deinit); + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t digitalio_digitalinout_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_digitalio_digitalinout_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(digitalio_digitalinout_obj___exit___obj, 4, 4, digitalio_digitalinout_obj___exit__); + +STATIC void check_for_deinit(digitalio_digitalinout_obj_t *self) { + if (common_hal_digitalio_digitalinout_deinited(self)) { + raise_deinited_error(); + } +} + +//| +//| .. method:: switch_to_output(value=False, drive_mode=digitalio.DriveMode.PUSH_PULL) +//| +//| Set the drive mode and value and then switch to writing out digital +//| values. +//| +//| :param bool value: default value to set upon switching +//| :param ~digitalio.DriveMode drive_mode: drive mode for the output +//| +STATIC mp_obj_t digitalio_digitalinout_switch_to_output(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_value, ARG_drive_mode }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_value, MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_drive_mode, MP_ARG_OBJ, {.u_rom_obj = &digitalio_drive_mode_push_pull_obj} }, + }; + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + digitalio_drive_mode_t drive_mode = DRIVE_MODE_PUSH_PULL; + if (args[ARG_drive_mode].u_rom_obj == &digitalio_drive_mode_open_drain_obj) { + drive_mode = DRIVE_MODE_OPEN_DRAIN; + } + // do the transfer + common_hal_digitalio_digitalinout_switch_to_output(self, args[ARG_value].u_bool, drive_mode); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(digitalio_digitalinout_switch_to_output_obj, 1, digitalio_digitalinout_switch_to_output); + +//| .. method:: switch_to_input(pull=None) +//| +//| Set the pull and then switch to read in digital values. +//| +//| :param Pull pull: pull configuration for the input +//| +//| Example usage:: +//| +//| import digitalio +//| import board +//| +//| switch = digitalio.DigitalInOut(board.SLIDE_SWITCH) +//| switch.switch_to_input(pull=digitalio.Pull.UP) +//| # Or, after switch_to_input +//| switch.pull = digitalio.Pull.UP +//| print(switch.value) +//| +STATIC mp_obj_t digitalio_digitalinout_switch_to_input(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_pull }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, + }; + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + digitalio_pull_t pull = PULL_NONE; + if (args[ARG_pull].u_rom_obj == &digitalio_pull_up_obj) { + pull = PULL_UP; + }else if (args[ARG_pull].u_rom_obj == &digitalio_pull_down_obj) { + pull = PULL_DOWN; + } + // do the transfer + common_hal_digitalio_digitalinout_switch_to_input(self, pull); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(digitalio_digitalinout_switch_to_input_obj, 1, digitalio_digitalinout_switch_to_input); + +//| .. attribute:: direction +//| +//| The direction of the pin. +//| +//| Setting this will use the defaults from the corresponding +//| :py:meth:`switch_to_input` or :py:meth:`switch_to_output` method. If +//| you want to set pull, value or drive mode prior to switching, then use +//| those methods instead. +//| +typedef struct { + mp_obj_base_t base; +} digitalio_digitalio_direction_obj_t; +extern const digitalio_digitalio_direction_obj_t digitalio_digitalio_direction_in_obj; +extern const digitalio_digitalio_direction_obj_t digitalio_digitalio_direction_out_obj; + +STATIC mp_obj_t digitalio_digitalinout_obj_get_direction(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + digitalio_direction_t direction = common_hal_digitalio_digitalinout_get_direction(self); + if (direction == DIRECTION_INPUT) { + return (mp_obj_t)&digitalio_direction_input_obj; + } + return (mp_obj_t)&digitalio_direction_output_obj; +} +MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_direction_obj, digitalio_digitalinout_obj_get_direction); + +STATIC mp_obj_t digitalio_digitalinout_obj_set_direction(mp_obj_t self_in, mp_obj_t value) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (value == &digitalio_direction_input_obj) { + common_hal_digitalio_digitalinout_switch_to_input(self, PULL_NONE); + } else if (value == &digitalio_direction_output_obj) { + common_hal_digitalio_digitalinout_switch_to_output(self, false, DRIVE_MODE_PUSH_PULL); + } else { + mp_raise_ValueError(translate("Invalid direction.")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(digitalio_digitalinout_set_direction_obj, digitalio_digitalinout_obj_set_direction); + +const mp_obj_property_t digitalio_digitalio_direction_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&digitalio_digitalinout_get_direction_obj, + (mp_obj_t)&digitalio_digitalinout_set_direction_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: value +//| +//| The digital logic level of the pin. +//| +STATIC mp_obj_t digitalio_digitalinout_obj_get_value(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + bool value = common_hal_digitalio_digitalinout_get_value(self); + return mp_obj_new_bool(value); +} +MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_value_obj, digitalio_digitalinout_obj_get_value); + +STATIC mp_obj_t digitalio_digitalinout_obj_set_value(mp_obj_t self_in, mp_obj_t value) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_INPUT) { + mp_raise_AttributeError(translate("Cannot set value when direction is input.")); + return mp_const_none; + } + common_hal_digitalio_digitalinout_set_value(self, mp_obj_is_true(value)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(digitalio_digitalinout_set_value_obj, digitalio_digitalinout_obj_set_value); + +const mp_obj_property_t digitalio_digitalinout_value_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&digitalio_digitalinout_get_value_obj, + (mp_obj_t)&digitalio_digitalinout_set_value_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: drive_mode +//| +//| The pin drive mode. One of: +//| +//| - `digitalio.DriveMode.PUSH_PULL` +//| - `digitalio.DriveMode.OPEN_DRAIN` +//| +STATIC mp_obj_t digitalio_digitalinout_obj_get_drive_mode(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_INPUT) { + mp_raise_AttributeError(translate("Drive mode not used when direction is input.")); + return mp_const_none; + } + digitalio_drive_mode_t drive_mode = common_hal_digitalio_digitalinout_get_drive_mode(self); + if (drive_mode == DRIVE_MODE_PUSH_PULL) { + return (mp_obj_t)&digitalio_drive_mode_push_pull_obj; + } + return (mp_obj_t)&digitalio_drive_mode_open_drain_obj; +} +MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_drive_mode_obj, digitalio_digitalinout_obj_get_drive_mode); + +STATIC mp_obj_t digitalio_digitalinout_obj_set_drive_mode(mp_obj_t self_in, mp_obj_t drive_mode) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_INPUT) { + mp_raise_AttributeError(translate("Drive mode not used when direction is input.")); + return mp_const_none; + } + digitalio_drive_mode_t c_drive_mode = DRIVE_MODE_PUSH_PULL; + if (drive_mode == &digitalio_drive_mode_open_drain_obj) { + c_drive_mode = DRIVE_MODE_OPEN_DRAIN; + } + common_hal_digitalio_digitalinout_set_drive_mode(self, c_drive_mode); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(digitalio_digitalinout_set_drive_mode_obj, digitalio_digitalinout_obj_set_drive_mode); + +const mp_obj_property_t digitalio_digitalio_drive_mode_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&digitalio_digitalinout_get_drive_mode_obj, + (mp_obj_t)&digitalio_digitalinout_set_drive_mode_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: pull +//| +//| The pin pull direction. One of: +//| +//| - `digitalio.Pull.UP` +//| - `digitalio.Pull.DOWN` +//| - `None` +//| +//| :raises AttributeError: if `direction` is :py:data:`~digitalio.Direction.OUTPUT`. +//| +STATIC mp_obj_t digitalio_digitalinout_obj_get_pull(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_OUTPUT) { + mp_raise_AttributeError(translate("Pull not used when direction is output.")); + return mp_const_none; + } + digitalio_pull_t pull = common_hal_digitalio_digitalinout_get_pull(self); + if (pull == PULL_UP) { + return (mp_obj_t)&digitalio_pull_up_obj; + } else if (pull == PULL_DOWN) { + return (mp_obj_t)&digitalio_pull_down_obj; + } + return (mp_obj_t)&mp_const_none_obj; +} +MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_pull_obj, digitalio_digitalinout_obj_get_pull); + +STATIC mp_obj_t digitalio_digitalinout_obj_set_pull(mp_obj_t self_in, mp_obj_t pull_obj) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_OUTPUT) { + mp_raise_AttributeError(translate("Pull not used when direction is output.")); + return mp_const_none; + } + digitalio_pull_t pull = PULL_NONE; + if (pull_obj == &digitalio_pull_up_obj) { + pull = PULL_UP; + } else if (pull_obj == &digitalio_pull_down_obj) { + pull = PULL_DOWN; + } else if (pull_obj != mp_const_none) { + mp_raise_ValueError(translate("Unsupported pull value.")); + } + common_hal_digitalio_digitalinout_set_pull(self, pull); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(digitalio_digitalinout_set_pull_obj, digitalio_digitalinout_obj_set_pull); + +const mp_obj_property_t digitalio_digitalio_pull_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&digitalio_digitalinout_get_pull_obj, + (mp_obj_t)&digitalio_digitalinout_set_pull_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t digitalio_digitalinout_locals_dict_table[] = { + // instance methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&digitalio_digitalinout_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&digitalio_digitalinout_obj___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_switch_to_output), MP_ROM_PTR(&digitalio_digitalinout_switch_to_output_obj) }, + { MP_ROM_QSTR(MP_QSTR_switch_to_input), MP_ROM_PTR(&digitalio_digitalinout_switch_to_input_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_direction), MP_ROM_PTR(&digitalio_digitalio_direction_obj) }, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&digitalio_digitalinout_value_obj) }, + { MP_ROM_QSTR(MP_QSTR_drive_mode), MP_ROM_PTR(&digitalio_digitalio_drive_mode_obj) }, + { MP_ROM_QSTR(MP_QSTR_pull), MP_ROM_PTR(&digitalio_digitalio_pull_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(digitalio_digitalinout_locals_dict, digitalio_digitalinout_locals_dict_table); + +const mp_obj_type_t digitalio_digitalinout_type = { + { &mp_type_type }, + .name = MP_QSTR_DigitalInOut, + .make_new = digitalio_digitalinout_make_new, + .locals_dict = (mp_obj_t)&digitalio_digitalinout_locals_dict, +}; + +// Helper for validating digitalio.DigitalInOut arguments +digitalio_digitalinout_obj_t *assert_digitalinout(mp_obj_t obj) { + if (!MP_OBJ_IS_TYPE(obj, &digitalio_digitalinout_type)) { + mp_raise_TypeError(translate("argument num/types mismatch")); + } + digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(obj); + check_for_deinit(pin); + return pin; +} diff --git a/shared-bindings/digitalio/DigitalInOut.h b/shared-bindings/digitalio/DigitalInOut.h new file mode 100644 index 00000000000..eee0d580122 --- /dev/null +++ b/shared-bindings/digitalio/DigitalInOut.h @@ -0,0 +1,58 @@ +/* + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO_DIGITALINOUT_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO_DIGITALINOUT_H + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/Direction.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "shared-bindings/digitalio/Pull.h" + +extern const mp_obj_type_t digitalio_digitalinout_type; + +typedef enum { + DIGITALINOUT_OK, + DIGITALINOUT_PIN_BUSY +} digitalinout_result_t; + +digitalinout_result_t common_hal_digitalio_digitalinout_construct(digitalio_digitalinout_obj_t* self, const mcu_pin_obj_t* pin); +void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self); +bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t* self); +void common_hal_digitalio_digitalinout_switch_to_input(digitalio_digitalinout_obj_t* self, digitalio_pull_t pull); +void common_hal_digitalio_digitalinout_switch_to_output(digitalio_digitalinout_obj_t* self, bool value, digitalio_drive_mode_t drive_mode); +digitalio_direction_t common_hal_digitalio_digitalinout_get_direction(digitalio_digitalinout_obj_t* self); +void common_hal_digitalio_digitalinout_set_value(digitalio_digitalinout_obj_t* self, bool value); +bool common_hal_digitalio_digitalinout_get_value(digitalio_digitalinout_obj_t* self); +void common_hal_digitalio_digitalinout_set_drive_mode(digitalio_digitalinout_obj_t* self, digitalio_drive_mode_t drive_mode); +digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode(digitalio_digitalinout_obj_t* self); +void common_hal_digitalio_digitalinout_set_pull(digitalio_digitalinout_obj_t* self, digitalio_pull_t pull); +digitalio_pull_t common_hal_digitalio_digitalinout_get_pull(digitalio_digitalinout_obj_t* self); +void common_hal_digitalio_digitalinout_never_reset(digitalio_digitalinout_obj_t *self); +digitalio_digitalinout_obj_t *assert_digitalinout(mp_obj_t obj); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO_DIGITALINOUT_H diff --git a/shared-bindings/digitalio/Direction.c b/shared-bindings/digitalio/Direction.c new file mode 100644 index 00000000000..c8188fc8994 --- /dev/null +++ b/shared-bindings/digitalio/Direction.c @@ -0,0 +1,88 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 +#include + +#include "lib/utils/context_manager_helpers.h" + +#include "py/nlr.h" +#include "py/objtype.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/mphal.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + +//| .. currentmodule:: digitalio +//| +//| :class:`Direction` -- defines the direction of a digital pin +//| ============================================================= +//| +//| .. class:: Direction +//| +//| Enum-like class to define which direction the digital values are +//| going. +//| +//| .. data:: INPUT +//| +//| Read digital data in +//| +//| .. data:: OUTPUT +//| +//| Write digital data out +//| +const mp_obj_type_t digitalio_direction_type; + +const digitalio_direction_obj_t digitalio_direction_input_obj = { + { &digitalio_direction_type }, +}; + +const digitalio_direction_obj_t digitalio_direction_output_obj = { + { &digitalio_direction_type }, +}; + +STATIC const mp_rom_map_elem_t digitalio_direction_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_INPUT), MP_ROM_PTR(&digitalio_direction_input_obj) }, + { MP_ROM_QSTR(MP_QSTR_OUTPUT), MP_ROM_PTR(&digitalio_direction_output_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(digitalio_direction_locals_dict, digitalio_direction_locals_dict_table); + +STATIC void digitalio_direction_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + qstr direction = MP_QSTR_INPUT; + if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&digitalio_direction_output_obj)) { + direction = MP_QSTR_OUTPUT; + } + mp_printf(print, "%q.%q.%q", MP_QSTR_digitalio, MP_QSTR_Direction, direction); +} + +const mp_obj_type_t digitalio_direction_type = { + { &mp_type_type }, + .name = MP_QSTR_Direction, + .print = digitalio_direction_print, + .locals_dict = (mp_obj_t)&digitalio_direction_locals_dict, +}; diff --git a/shared-bindings/digitalio/Direction.h b/shared-bindings/digitalio/Direction.h new file mode 100644 index 00000000000..d71f48c2ed1 --- /dev/null +++ b/shared-bindings/digitalio/Direction.h @@ -0,0 +1,45 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO_DIRECTION_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO_DIRECTION_H + +#include "py/obj.h" + +typedef enum { + DIRECTION_INPUT, + DIRECTION_OUTPUT +} digitalio_direction_t; +typedef struct { + mp_obj_base_t base; +} digitalio_direction_obj_t; + +const mp_obj_type_t digitalio_direction_type; + +extern const digitalio_direction_obj_t digitalio_direction_input_obj; +extern const digitalio_direction_obj_t digitalio_direction_output_obj; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO_DIRECTION_H diff --git a/shared-bindings/digitalio/DriveMode.c b/shared-bindings/digitalio/DriveMode.c new file mode 100644 index 00000000000..51e1e2ee500 --- /dev/null +++ b/shared-bindings/digitalio/DriveMode.c @@ -0,0 +1,77 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/digitalio/DriveMode.h" + +//| .. currentmodule:: digitalio +//| +//| :class:`DriveMode` -- defines the drive mode of a digital pin +//| ============================================================= +//| +//| .. class:: DriveMode +//| +//| Enum-like class to define the drive mode used when outputting +//| digital values. +//| +//| .. data:: PUSH_PULL +//| +//| Output both high and low digital values +//| +//| .. data:: OPEN_DRAIN +//| +//| Output low digital values but go into high z for digital high. This is +//| useful for i2c and other protocols that share a digital line. +//| +const mp_obj_type_t digitalio_drive_mode_type; + +const digitalio_drive_mode_obj_t digitalio_drive_mode_push_pull_obj = { + { &digitalio_drive_mode_type }, +}; + +const digitalio_drive_mode_obj_t digitalio_drive_mode_open_drain_obj = { + { &digitalio_drive_mode_type }, +}; + +STATIC const mp_rom_map_elem_t digitalio_drive_mode_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_PUSH_PULL), MP_ROM_PTR(&digitalio_drive_mode_push_pull_obj) }, + { MP_ROM_QSTR(MP_QSTR_OPEN_DRAIN), MP_ROM_PTR(&digitalio_drive_mode_open_drain_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(digitalio_drive_mode_locals_dict, digitalio_drive_mode_locals_dict_table); + +STATIC void digitalio_drive_mode_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + qstr drive_mode = MP_QSTR_PUSH_PULL; + if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&digitalio_drive_mode_open_drain_obj)) { + drive_mode = MP_QSTR_OPEN_DRAIN; + } + mp_printf(print, "%q.%q.%q", MP_QSTR_digitalio, MP_QSTR_DriveMode, drive_mode); +} + +const mp_obj_type_t digitalio_drive_mode_type = { + { &mp_type_type }, + .name = MP_QSTR_DriveMode, + .print = digitalio_drive_mode_print, + .locals_dict = (mp_obj_t)&digitalio_drive_mode_locals_dict, +}; diff --git a/shared-bindings/digitalio/DriveMode.h b/shared-bindings/digitalio/DriveMode.h new file mode 100644 index 00000000000..47d036b3ae3 --- /dev/null +++ b/shared-bindings/digitalio/DriveMode.h @@ -0,0 +1,46 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO_DRIVEMODE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO_DRIVEMODE_H + +#include "py/obj.h" + +typedef enum { + DRIVE_MODE_PUSH_PULL, + DRIVE_MODE_OPEN_DRAIN +} digitalio_drive_mode_t; + +typedef struct { + mp_obj_base_t base; +} digitalio_drive_mode_obj_t; + +const mp_obj_type_t digitalio_drive_mode_type; + +extern const digitalio_drive_mode_obj_t digitalio_drive_mode_push_pull_obj; +extern const digitalio_drive_mode_obj_t digitalio_drive_mode_open_drain_obj; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO_DRIVEMODE_H diff --git a/shared-bindings/digitalio/Pull.c b/shared-bindings/digitalio/Pull.c new file mode 100644 index 00000000000..813268db783 --- /dev/null +++ b/shared-bindings/digitalio/Pull.c @@ -0,0 +1,78 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/digitalio/Pull.h" + +//| .. currentmodule:: digitalio +//| +//| :class:`Pull` -- defines the pull of a digital input pin +//| ============================================================= +//| +//| .. class:: Pull +//| +//| Enum-like class to define the pull value, if any, used while reading +//| digital values in. +//| +//| .. data:: UP +//| +//| When the input line isn't being driven the pull up can pull the state +//| of the line high so it reads as true. +//| +//| .. data:: DOWN +//| +//| When the input line isn't being driven the pull down can pull the +//| state of the line low so it reads as false. +//| +const mp_obj_type_t digitalio_pull_type; + +const digitalio_pull_obj_t digitalio_pull_up_obj = { + { &digitalio_pull_type }, +}; + +const digitalio_pull_obj_t digitalio_pull_down_obj = { + { &digitalio_pull_type }, +}; + +STATIC const mp_rom_map_elem_t digitalio_pull_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_UP), MP_ROM_PTR(&digitalio_pull_up_obj) }, + { MP_ROM_QSTR(MP_QSTR_DOWN), MP_ROM_PTR(&digitalio_pull_down_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(digitalio_pull_locals_dict, digitalio_pull_locals_dict_table); + +STATIC void digitalio_pull_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + qstr pull = MP_QSTR_UP; + if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&digitalio_pull_down_obj)) { + pull = MP_QSTR_DOWN; + } + mp_printf(print, "%q.%q.%q", MP_QSTR_digitalio, MP_QSTR_Pull, pull); +} + +const mp_obj_type_t digitalio_pull_type = { + { &mp_type_type }, + .name = MP_QSTR_Pull, + .print = digitalio_pull_print, + .locals_dict = (mp_obj_t)&digitalio_pull_locals_dict, +}; diff --git a/shared-bindings/digitalio/Pull.h b/shared-bindings/digitalio/Pull.h new file mode 100644 index 00000000000..22fb6cd0e7b --- /dev/null +++ b/shared-bindings/digitalio/Pull.h @@ -0,0 +1,46 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO_PULL_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO_PULL_H + +#include "py/obj.h" + +typedef enum _digitalio_pull_t { + PULL_NONE, + PULL_UP, + PULL_DOWN +} digitalio_pull_t; + +const mp_obj_type_t digitalio_pull_type; + +typedef struct { + mp_obj_base_t base; +} digitalio_pull_obj_t; +extern const digitalio_pull_obj_t digitalio_pull_up_obj; +extern const digitalio_pull_obj_t digitalio_pull_down_obj; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO_PULL_H diff --git a/shared-bindings/digitalio/__init__.c b/shared-bindings/digitalio/__init__.c new file mode 100644 index 00000000000..1632262d2ae --- /dev/null +++ b/shared-bindings/digitalio/__init__.c @@ -0,0 +1,107 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/digitalio/__init__.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/Direction.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "shared-bindings/digitalio/Pull.h" + +#include "py/runtime.h" + +//| :mod:`digitalio` --- Basic digital pin support +//| ================================================= +//| +//| .. module:: digitalio +//| :synopsis: Basic digital pin support +//| :platform: SAMD21, ESP8266 +//| +//| The `digitalio` module contains classes to provide access to basic digital IO. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| DigitalInOut +//| Direction +//| DriveMode +//| Pull +//| +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed if the program continues after use. To do so, either +//| call :py:meth:`!deinit` or use a context manager. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +//| For example:: +//| +//| import digitalio +//| from board import * +//| +//| pin = digitalio.DigitalInOut(D13) +//| print(pin.value) +//| +//| This example will initialize the the device, read +//| :py:data:`~digitalio.DigitalInOut.value` and then +//| :py:meth:`~digitalio.DigitalInOut.deinit` the hardware. +//| +//| Here is blinky:: +//| +//| import digitalio +//| from board import * +//| import time +//| +//| led = digitalio.DigitalInOut(D13) +//| led.direction = digitalio.Direction.OUTPUT +//| while True: +//| led.value = True +//| time.sleep(0.1) +//| led.value = False +//| time.sleep(0.1) +//| + +STATIC const mp_rom_map_elem_t digitalio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_digitalio) }, + { MP_ROM_QSTR(MP_QSTR_DigitalInOut), MP_ROM_PTR(&digitalio_digitalinout_type) }, + + // Enum-like Classes. + { MP_ROM_QSTR(MP_QSTR_Direction), MP_ROM_PTR(&digitalio_direction_type) }, + { MP_ROM_QSTR(MP_QSTR_DriveMode), MP_ROM_PTR(&digitalio_drive_mode_type) }, + { MP_ROM_QSTR(MP_QSTR_Pull), MP_ROM_PTR(&digitalio_pull_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(digitalio_module_globals, digitalio_module_globals_table); + +const mp_obj_module_t digitalio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&digitalio_module_globals, +}; diff --git a/shared-bindings/digitalio/__init__.h b/shared-bindings/digitalio/__init__.h new file mode 100644 index 00000000000..8ab7f789e70 --- /dev/null +++ b/shared-bindings/digitalio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO___INIT___H + +#include "py/obj.h" + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO___INIT___H diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c new file mode 100644 index 00000000000..91c17f2d134 --- /dev/null +++ b/shared-bindings/displayio/Bitmap.c @@ -0,0 +1,193 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/Bitmap.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`Bitmap` -- Stores values in a 2D array +//| ========================================================================== +//| +//| Stores values of a certain size in a 2D array +//| +//| .. class:: Bitmap(width, height, value_count) +//| +//| Create a Bitmap object with the given fixed size. Each pixel stores a value that is used to +//| index into a corresponding palette. This enables differently colored sprites to share the +//| underlying Bitmap. value_count is used to minimize the memory used to store the Bitmap. +//| +//| :param int width: The number of values wide +//| :param int height: The number of values high +//| :param int value_count: The number of possible pixel values. +//| +STATIC mp_obj_t displayio_bitmap_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 3, 3, false); + uint32_t width = mp_obj_get_int(pos_args[0]); + uint32_t height = mp_obj_get_int(pos_args[1]); + uint32_t value_count = mp_obj_get_int(pos_args[2]); + uint32_t bits = 1; + + if (value_count == 0) { + mp_raise_ValueError(translate("value_count must be > 0")); + } + while ((value_count - 1) >> bits) { + if (bits < 8) { + bits <<= 1; + } else { + bits += 8; + } + } + + displayio_bitmap_t *self = m_new_obj(displayio_bitmap_t); + self->base.type = &displayio_bitmap_type; + common_hal_displayio_bitmap_construct(self, width, height, bits); + + return MP_OBJ_FROM_PTR(self); +} +//| .. attribute:: width +//| +//| Width of the bitmap. (read only) +//| +STATIC mp_obj_t displayio_bitmap_obj_get_width(mp_obj_t self_in) { + displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_bitmap_get_width(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(displayio_bitmap_get_width_obj, displayio_bitmap_obj_get_width); + +const mp_obj_property_t displayio_bitmap_width_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_bitmap_get_width_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: height +//| +//| Height of the bitmap. (read only) +//| +STATIC mp_obj_t displayio_bitmap_obj_get_height(mp_obj_t self_in) { + displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_bitmap_get_height(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(displayio_bitmap_get_height_obj, displayio_bitmap_obj_get_height); + +const mp_obj_property_t displayio_bitmap_height_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_bitmap_get_height_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: __getitem__(index) +//| +//| Returns the value at the given index. The index can either be an x,y tuple or an int equal +//| to ``y * width + x``. +//| +//| This allows you to:: +//| +//| print(bitmap[0,1]) +//| +//| .. method:: __setitem__(index, value) +//| +//| Sets the value at the given index. The index can either be an x,y tuple or an int equal +//| to ``y * width + x``. +//| +//| This allows you to:: +//| +//| bitmap[0,1] = 3 +//| +STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj) { + if (value_obj == mp_const_none) { + // delete item + mp_raise_AttributeError(translate("Cannot delete values")); + return mp_const_none; + } + + displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); + + if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) { + // TODO(tannewt): Implement subscr after slices support start, stop and step tuples. + mp_raise_NotImplementedError(translate("Slices not supported")); + return mp_const_none; + } + + uint16_t x = 0; + uint16_t y = 0; + if (MP_OBJ_IS_SMALL_INT(index_obj)) { + mp_int_t i = MP_OBJ_SMALL_INT_VALUE(index_obj); + uint16_t width = common_hal_displayio_bitmap_get_width(self); + x = i % width; + y = i / width; + } else { + mp_obj_t* items; + mp_obj_get_array_fixed_n(index_obj, 2, &items); + x = mp_obj_get_int(items[0]); + y = mp_obj_get_int(items[1]); + if (x >= common_hal_displayio_bitmap_get_width(self) || y >= common_hal_displayio_bitmap_get_height(self)) { + mp_raise_IndexError(translate("pixel coordinates out of bounds")); + } + } + + if (value_obj == MP_OBJ_SENTINEL) { + // load + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_bitmap_get_pixel(self, x, y)); + } else { + mp_int_t value = mp_obj_get_int(value_obj); + if (value >= 1 << common_hal_displayio_bitmap_get_bits_per_value(self)) { + mp_raise_ValueError(translate("pixel value requires too many bits")); + } + common_hal_displayio_bitmap_set_pixel(self, x, y, value); + } + return mp_const_none; +} + +STATIC const mp_rom_map_elem_t displayio_bitmap_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&displayio_bitmap_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&displayio_bitmap_width_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_bitmap_locals_dict, displayio_bitmap_locals_dict_table); + +const mp_obj_type_t displayio_bitmap_type = { + { &mp_type_type }, + .name = MP_QSTR_Bitmap, + .make_new = displayio_bitmap_make_new, + .subscr = bitmap_subscr, + .locals_dict = (mp_obj_dict_t*)&displayio_bitmap_locals_dict, +}; diff --git a/shared-bindings/displayio/Bitmap.h b/shared-bindings/displayio/Bitmap.h new file mode 100644 index 00000000000..90694951fa4 --- /dev/null +++ b/shared-bindings/displayio/Bitmap.h @@ -0,0 +1,45 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_BITMAP_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_BITMAP_H + +#include "shared-module/displayio/Bitmap.h" + +extern const mp_obj_type_t displayio_bitmap_type; + +void common_hal_displayio_bitmap_construct(displayio_bitmap_t *self, uint32_t width, + uint32_t height, uint32_t bits_per_value); + +void common_hal_displayio_bitmap_load_row(displayio_bitmap_t *self, uint16_t y, uint8_t* data, + uint16_t len); +uint16_t common_hal_displayio_bitmap_get_height(displayio_bitmap_t *self); +uint16_t common_hal_displayio_bitmap_get_width(displayio_bitmap_t *self); +uint32_t common_hal_displayio_bitmap_get_bits_per_value(displayio_bitmap_t *self); +void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *bitmap, int16_t x, int16_t y, uint32_t value); +uint32_t common_hal_displayio_bitmap_get_pixel(displayio_bitmap_t *bitmap, int16_t x, int16_t y); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_BITMAP_H diff --git a/shared-bindings/displayio/ColorConverter.c b/shared-bindings/displayio/ColorConverter.c new file mode 100644 index 00000000000..d9524870dca --- /dev/null +++ b/shared-bindings/displayio/ColorConverter.c @@ -0,0 +1,92 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/ColorConverter.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`ColorConverter` -- Converts one color format to another +//| ========================================================================================= +//| +//| Converts one color format to another. +//| +//| .. class:: ColorConverter() +//| +//| Create a ColorConverter object to convert color formats. Only supports RGB888 to RGB565 +//| currently. +//| +// TODO(tannewt): Add support for other color formats. +//| +STATIC mp_obj_t displayio_colorconverter_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 0, false); + + displayio_colorconverter_t *self = m_new_obj(displayio_colorconverter_t); + self->base.type = &displayio_colorconverter_type; + common_hal_displayio_colorconverter_construct(self); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: convert(color) +//| +//| Converts the given RGB888 color to RGB565 +//| +STATIC mp_obj_t displayio_colorconverter_obj_convert(mp_obj_t self_in, mp_obj_t color_obj) { + displayio_colorconverter_t *self = MP_OBJ_TO_PTR(self_in); + + mp_int_t color; + if (!mp_obj_get_int_maybe(color_obj, &color)) { + mp_raise_ValueError(translate("color should be an int")); + } + _displayio_colorspace_t colorspace; + colorspace.depth = 16; + uint32_t output_color; + common_hal_displayio_colorconverter_convert(self, &colorspace, color, &output_color); + return MP_OBJ_NEW_SMALL_INT(output_color); +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_colorconverter_convert_obj, displayio_colorconverter_obj_convert); + +STATIC const mp_rom_map_elem_t displayio_colorconverter_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_convert), MP_ROM_PTR(&displayio_colorconverter_convert_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_colorconverter_locals_dict, displayio_colorconverter_locals_dict_table); + +const mp_obj_type_t displayio_colorconverter_type = { + { &mp_type_type }, + .name = MP_QSTR_ColorConverter, + .make_new = displayio_colorconverter_make_new, + .locals_dict = (mp_obj_dict_t*)&displayio_colorconverter_locals_dict, +}; diff --git a/shared-bindings/displayio/ColorConverter.h b/shared-bindings/displayio/ColorConverter.h new file mode 100644 index 00000000000..24895500e8a --- /dev/null +++ b/shared-bindings/displayio/ColorConverter.h @@ -0,0 +1,39 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_COLORCONVERTER_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_COLORCONVERTER_H + +#include "shared-module/displayio/ColorConverter.h" + +#include "shared-module/displayio/Palette.h" + +extern const mp_obj_type_t displayio_colorconverter_type; + +void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t* self); +void common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *colorconverter, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_COLORCONVERTER_H diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c new file mode 100644 index 00000000000..1eb1943b821 --- /dev/null +++ b/shared-bindings/displayio/Display.c @@ -0,0 +1,503 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/Display.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/objtype.h" +#include "py/runtime.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`Display` -- Manage updating a display over a display bus +//| ========================================================================== +//| +//| This initializes a display and connects it into CircuitPython. Unlike other +//| objects in CircuitPython, Display objects live until `displayio.release_displays()` +//| is called. This is done so that CircuitPython can use the display itself. +//| +//| Most people should not use this class directly. Use a specific display driver instead that will +//| contain the initialization sequence at minimum. +//| +//| .. class:: Display(display_bus, init_sequence, *, width, height, colstart=0, rowstart=0, rotation=0, color_depth=16, grayscale=False, pixels_in_byte_share_row=True, bytes_per_cell=1, reverse_pixels_in_byte=False, set_column_command=0x2a, set_row_command=0x2b, write_ram_command=0x2c, set_vertical_scroll=0, backlight_pin=None, brightness_command=None, brightness=1.0, auto_brightness=False, single_byte_bounds=False, data_as_commands=False, auto_refresh=True, native_frames_per_second=60) +//| +//| Create a Display object on the given display bus (`displayio.FourWire` or `displayio.ParallelBus`). +//| +//| The ``init_sequence`` is bitpacked to minimize the ram impact. Every command begins with a +//| command byte followed by a byte to determine the parameter count and if a delay is need after. +//| When the top bit of the second byte is 1, the next byte will be the delay time in milliseconds. +//| The remaining 7 bits are the parameter count excluding any delay byte. The third through final +//| bytes are the remaining command parameters. The next byte will begin a new command definition. +//| Here is a portion of ILI9341 init code: +//| +//| .. code-block:: python +//| +//| init_sequence = (b"\xe1\x0f\x00\x0E\x14\x03\x11\x07\x31\xC1\x48\x08\x0F\x0C\x31\x36\x0F" # Set Gamma +//| b"\x11\x80\x78"# Exit Sleep then delay 0x78 (120ms) +//| b"\x29\x80\x78"# Display on then delay 0x78 (120ms) +//| ) +//| display = displayio.Display(display_bus, init_sequence, width=320, height=240) +//| +//| The first command is 0xe1 with 15 (0xf) parameters following. The second and third are 0x11 and +//| 0x29 respectively with delays (0x80) of 120ms (0x78) and no parameters. Multiple byte literals +//| (b"") are merged together on load. The parens are needed to allow byte literals on subsequent +//| lines. +//| +//| The initialization sequence should always leave the display memory access inline with the scan +//| of the display to minimize tearing artifacts. +//| +//| :param display_bus: The bus that the display is connected to +//| :type display_bus: displayio.FourWire or displayio.ParallelBus +//| :param buffer init_sequence: Byte-packed initialization sequence. +//| :param int width: Width in pixels +//| :param int height: Height in pixels +//| :param int colstart: The index if the first visible column +//| :param int rowstart: The index if the first visible row +//| :param int rotation: The rotation of the display in degrees clockwise. Must be in 90 degree increments (0, 90, 180, 270) +//| :param int color_depth: The number of bits of color per pixel transmitted. (Some displays +//| support 18 bit but 16 is easier to transmit. The last bit is extrapolated.) +//| :param bool grayscale: True if the display only shows a single color. +//| :param bool pixels_in_byte_share_row: True when pixels are less than a byte and a byte includes pixels from the same row of the display. When False, pixels share a column. +//| :param int bytes_per_cell: Number of bytes per addressable memory location when color_depth < 8. When greater than one, bytes share a row or column according to pixels_in_byte_share_row. +//| :param bool reverse_pixels_in_byte: Reverses the pixel order within each byte when color_depth < 8. Does not apply across multiple bytes even if there is more than one byte per cell (bytes_per_cell.) +//| :param int set_column_command: Command used to set the start and end columns to update +//| :param int set_row_command: Command used so set the start and end rows to update +//| :param int write_ram_command: Command used to write pixels values into the update region. Ignored if data_as_commands is set. +//| :param int set_vertical_scroll: Command used to set the first row to show +//| :param microcontroller.Pin backlight_pin: Pin connected to the display's backlight +//| :param int brightness_command: Command to set display brightness. Usually available in OLED controllers. +//| :param bool brightness: Initial display brightness. This value is ignored if auto_brightness is True. +//| :param bool auto_brightness: If True, brightness is controlled via an ambient light sensor or other mechanism. +//| :param bool single_byte_bounds: Display column and row commands use single bytes +//| :param bool data_as_commands: Treat all init and boundary data as SPI commands. Certain displays require this. +//| :param bool auto_refresh: Automatically refresh the screen +//| :param int native_frames_per_second: Number of display refreshes per second that occur with the given init_sequence. +//| +STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_color_depth, ARG_grayscale, ARG_pixels_in_byte_share_row, ARG_bytes_per_cell, ARG_reverse_pixels_in_byte, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command, ARG_set_vertical_scroll, ARG_backlight_pin, ARG_brightness_command, ARG_brightness, ARG_auto_brightness, ARG_single_byte_bounds, ARG_data_as_commands, ARG_auto_refresh, ARG_native_frames_per_second }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_init_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, + { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, + { MP_QSTR_colstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_rowstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_rotation, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_color_depth, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { MP_QSTR_grayscale, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_pixels_in_byte_share_row, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_bytes_per_cell, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} }, + { MP_QSTR_reverse_pixels_in_byte, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_set_column_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2a} }, + { MP_QSTR_set_row_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2b} }, + { MP_QSTR_write_ram_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2c} }, + { MP_QSTR_set_vertical_scroll, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x0} }, + { MP_QSTR_backlight_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_brightness_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = NO_BRIGHTNESS_COMMAND} }, + { MP_QSTR_brightness, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, + { MP_QSTR_auto_brightness, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_single_byte_bounds, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_data_as_commands, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_auto_refresh, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_native_frames_per_second, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 60} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t display_bus = args[ARG_display_bus].u_obj; + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ); + + mp_obj_t backlight_pin_obj = args[ARG_backlight_pin].u_obj; + assert_pin(backlight_pin_obj, true); + const mcu_pin_obj_t* backlight_pin = NULL; + if (backlight_pin_obj != NULL && backlight_pin_obj != mp_const_none) { + backlight_pin = MP_OBJ_TO_PTR(backlight_pin_obj); + assert_pin_free(backlight_pin); + } + + mp_float_t brightness = mp_obj_get_float(args[ARG_brightness].u_obj); + + mp_int_t rotation = args[ARG_rotation].u_int; + if (rotation % 90 != 0) { + mp_raise_ValueError(translate("Display rotation must be in 90 degree increments")); + } + + displayio_display_obj_t *self = NULL; + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].display.base.type == NULL || + displays[i].display.base.type == &mp_type_NoneType) { + self = &displays[i].display; + break; + } + } + if (self == NULL) { + mp_raise_RuntimeError(translate("Too many displays")); + } + self->base.type = &displayio_display_type; + common_hal_displayio_display_construct( + self, + display_bus, args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, rotation, + args[ARG_color_depth].u_int, args[ARG_grayscale].u_bool, + args[ARG_pixels_in_byte_share_row].u_bool, args[ARG_bytes_per_cell].u_bool, args[ARG_reverse_pixels_in_byte].u_bool, + args[ARG_set_column_command].u_int, args[ARG_set_row_command].u_int, + args[ARG_write_ram_command].u_int, + args[ARG_set_vertical_scroll].u_int, + bufinfo.buf, bufinfo.len, + MP_OBJ_TO_PTR(backlight_pin), + args[ARG_brightness_command].u_int, + brightness, + args[ARG_auto_brightness].u_bool, + args[ARG_single_byte_bounds].u_bool, + args[ARG_data_as_commands].u_bool, + args[ARG_auto_refresh].u_bool, + args[ARG_native_frames_per_second].u_int + ); + + return self; +} + +// Helper to ensure we have the native super class instead of a subclass. +static displayio_display_obj_t* native_display(mp_obj_t display_obj) { + mp_obj_t native_display = mp_instance_cast_to_native_base(display_obj, &displayio_display_type); + mp_obj_assert_native_inited(native_display); + return MP_OBJ_TO_PTR(native_display); +} + +//| .. method:: show(group) +//| +//| Switches to displaying the given group of layers. When group is None, the default +//| CircuitPython terminal will be shown. +//| +//| :param Group group: The group to show. +STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in) { + displayio_display_obj_t *self = native_display(self_in); + displayio_group_t* group = NULL; + if (group_in != mp_const_none) { + group = MP_OBJ_TO_PTR(native_group(group_in)); + } + + bool ok = common_hal_displayio_display_show(self, group); + if (!ok) { + mp_raise_ValueError(translate("Group already used")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_show_obj, displayio_display_obj_show); + +//| .. method:: refresh(*, target_frames_per_second=60, minimum_frames_per_second=1) +//| +//| When auto refresh is off, waits for the target frame rate and then refreshes the display, +//| returning True. If the call has taken too long since the last refresh call for the given +//| target frame rate, then the refresh returns False immediately without updating the screen to +//| hopefully help getting caught up. +//| +//| If the time since the last successful refresh is below the minimum frame rate, then an +//| exception will be raised. Set minimum_frames_per_second to 0 to disable. +//| +//| When auto refresh is on, updates the display immediately. (The display will also update +//| without calls to this.) +//| +//| :param int target_frames_per_second: How many times a second `refresh` should be called and the screen updated. +//| :param int minimum_frames_per_second: The minimum number of times the screen should be updated per second. +//| +STATIC mp_obj_t displayio_display_obj_refresh(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_target_frames_per_second, ARG_minimum_frames_per_second }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_target_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 60} }, + { MP_QSTR_minimum_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + displayio_display_obj_t *self = native_display(pos_args[0]); + uint32_t maximum_ms_per_real_frame = 0xffffffff; + mp_int_t minimum_frames_per_second = args[ARG_minimum_frames_per_second].u_int; + if (minimum_frames_per_second > 0) { + maximum_ms_per_real_frame = 1000 / minimum_frames_per_second; + } + return mp_obj_new_bool(common_hal_displayio_display_refresh(self, 1000 / args[ARG_target_frames_per_second].u_int, maximum_ms_per_real_frame)); +} +MP_DEFINE_CONST_FUN_OBJ_KW(displayio_display_refresh_obj, 1, displayio_display_obj_refresh); + +//| .. attribute:: auto_refresh +//| +//| True when the display is refreshed automatically. +//| +STATIC mp_obj_t displayio_display_obj_get_auto_refresh(mp_obj_t self_in) { + displayio_display_obj_t *self = native_display(self_in); + return mp_obj_new_bool(common_hal_displayio_display_get_auto_refresh(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_auto_refresh_obj, displayio_display_obj_get_auto_refresh); + +STATIC mp_obj_t displayio_display_obj_set_auto_refresh(mp_obj_t self_in, mp_obj_t auto_refresh) { + displayio_display_obj_t *self = native_display(self_in); + + common_hal_displayio_display_set_auto_refresh(self, mp_obj_is_true(auto_refresh)); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_set_auto_refresh_obj, displayio_display_obj_set_auto_refresh); + +const mp_obj_property_t displayio_display_auto_refresh_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_display_get_auto_refresh_obj, + (mp_obj_t)&displayio_display_set_auto_refresh_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: brightness +//| +//| The brightness of the display as a float. 0.0 is off and 1.0 is full brightness. When +//| `auto_brightness` is True, the value of `brightness` will change automatically. +//| If `brightness` is set, `auto_brightness` will be disabled and will be set to False. +//| +STATIC mp_obj_t displayio_display_obj_get_brightness(mp_obj_t self_in) { + displayio_display_obj_t *self = native_display(self_in); + mp_float_t brightness = common_hal_displayio_display_get_brightness(self); + if (brightness < 0) { + mp_raise_RuntimeError(translate("Brightness not adjustable")); + } + return mp_obj_new_float(brightness); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_brightness_obj, displayio_display_obj_get_brightness); + +STATIC mp_obj_t displayio_display_obj_set_brightness(mp_obj_t self_in, mp_obj_t brightness_obj) { + displayio_display_obj_t *self = native_display(self_in); + common_hal_displayio_display_set_auto_brightness(self, false); + mp_float_t brightness = mp_obj_get_float(brightness_obj); + if (brightness < 0 || brightness > 1.0) { + mp_raise_ValueError(translate("Brightness must be 0-1.0")); + } + bool ok = common_hal_displayio_display_set_brightness(self, brightness); + if (!ok) { + mp_raise_RuntimeError(translate("Brightness not adjustable")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_set_brightness_obj, displayio_display_obj_set_brightness); + +const mp_obj_property_t displayio_display_brightness_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_display_get_brightness_obj, + (mp_obj_t)&displayio_display_set_brightness_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: auto_brightness +//| +//| True when the display brightness is adjusted automatically, based on an ambient +//| light sensor or other method. Note that some displays may have this set to True by default, +//| but not actually implement automatic brightness adjustment. `auto_brightness` is set to False +//| if `brightness` is set manually. +//| +STATIC mp_obj_t displayio_display_obj_get_auto_brightness(mp_obj_t self_in) { + displayio_display_obj_t *self = native_display(self_in); + return mp_obj_new_bool(common_hal_displayio_display_get_auto_brightness(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_auto_brightness_obj, displayio_display_obj_get_auto_brightness); + +STATIC mp_obj_t displayio_display_obj_set_auto_brightness(mp_obj_t self_in, mp_obj_t auto_brightness) { + displayio_display_obj_t *self = native_display(self_in); + + common_hal_displayio_display_set_auto_brightness(self, mp_obj_is_true(auto_brightness)); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_set_auto_brightness_obj, displayio_display_obj_set_auto_brightness); + +const mp_obj_property_t displayio_display_auto_brightness_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_display_get_auto_brightness_obj, + (mp_obj_t)&displayio_display_set_auto_brightness_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: width +//| +//| Gets the width of the board +//| +//| +STATIC mp_obj_t displayio_display_obj_get_width(mp_obj_t self_in) { + displayio_display_obj_t *self = native_display(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_display_get_width(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_width_obj, displayio_display_obj_get_width); + +const mp_obj_property_t displayio_display_width_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_display_get_width_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: height +//| +//| Gets the height of the board +//| +//| +STATIC mp_obj_t displayio_display_obj_get_height(mp_obj_t self_in) { + displayio_display_obj_t *self = native_display(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_display_get_height(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_height_obj, displayio_display_obj_get_height); + +const mp_obj_property_t displayio_display_height_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_display_get_height_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: rotation +//| +//| The rotation of the display as an int in degrees. +//| +STATIC mp_obj_t displayio_display_obj_get_rotation(mp_obj_t self_in) { + displayio_display_obj_t *self = native_display(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_display_get_rotation(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_rotation_obj, displayio_display_obj_get_rotation); + +const mp_obj_property_t displayio_display_rotation_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_display_get_rotation_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: bus +//| +//| The bus being used by the display +//| +//| +STATIC mp_obj_t displayio_display_obj_get_bus(mp_obj_t self_in) { + displayio_display_obj_t *self = native_display(self_in); + return common_hal_displayio_display_get_bus(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_bus_obj, displayio_display_obj_get_bus); + +const mp_obj_property_t displayio_display_bus_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_display_get_bus_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +//| .. method:: fill_row(y, buffer) +//| +//| Extract the pixels from a single row +//| +//| :param int y: The top edge of the area +//| :param bytearray buffer: The buffer in which to place the pixel data +STATIC mp_obj_t displayio_display_obj_fill_row(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_y, ARG_buffer }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_y, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = -1} }, + { MP_QSTR_buffer, MP_ARG_OBJ | MP_ARG_REQUIRED, {} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + displayio_display_obj_t *self = native_display(pos_args[0]); + mp_int_t y = args[ARG_y].u_int; + mp_obj_t *result = args[ARG_buffer].u_obj; + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(result, &bufinfo, MP_BUFFER_WRITE); + + if (bufinfo.typecode != BYTEARRAY_TYPECODE) { + mp_raise_ValueError(translate("Buffer is not a bytearray.")); + } + if (self->core.colorspace.depth != 16) { + mp_raise_ValueError(translate("Display must have a 16 bit colorspace.")); + } + + displayio_area_t area = { + .x1 = 0, + .y1 = y, + .x2 = self->core.width, + .y2 = y + 1 + }; + uint8_t pixels_per_word = (sizeof(uint32_t) * 8) / self->core.colorspace.depth; + uint16_t buffer_size = self->core.width / pixels_per_word; + uint16_t pixels_per_buffer = displayio_area_size(&area); + if (pixels_per_buffer % pixels_per_word) { + buffer_size += 1; + } + + uint32_t *result_buffer = bufinfo.buf; + size_t result_buffer_size = bufinfo.len; + + if (result_buffer_size >= (buffer_size * 4)) { + volatile uint32_t mask_length = (pixels_per_buffer / 32) + 1; + uint32_t mask[mask_length]; + + for (uint16_t k = 0; k < mask_length; k++) { + mask[k] = 0x00000000; + } + + displayio_display_core_fill_area(&self->core, &area, mask, result_buffer); + return result; + } else { + mp_raise_ValueError(translate("Buffer is too small")); + } +} +MP_DEFINE_CONST_FUN_OBJ_KW(displayio_display_fill_row_obj, 1, displayio_display_obj_fill_row); + +STATIC const mp_rom_map_elem_t displayio_display_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&displayio_display_show_obj) }, + { MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&displayio_display_refresh_obj) }, + { MP_ROM_QSTR(MP_QSTR_fill_row), MP_ROM_PTR(&displayio_display_fill_row_obj) }, + + { MP_ROM_QSTR(MP_QSTR_auto_refresh), MP_ROM_PTR(&displayio_display_auto_refresh_obj) }, + + { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&displayio_display_brightness_obj) }, + { MP_ROM_QSTR(MP_QSTR_auto_brightness), MP_ROM_PTR(&displayio_display_auto_brightness_obj) }, + + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&displayio_display_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&displayio_display_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_rotation), MP_ROM_PTR(&displayio_display_rotation_obj) }, + { MP_ROM_QSTR(MP_QSTR_bus), MP_ROM_PTR(&displayio_display_bus_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_display_locals_dict, displayio_display_locals_dict_table); + +const mp_obj_type_t displayio_display_type = { + { &mp_type_type }, + .name = MP_QSTR_Display, + .make_new = displayio_display_make_new, + .locals_dict = (mp_obj_dict_t*)&displayio_display_locals_dict, +}; diff --git a/shared-bindings/displayio/Display.h b/shared-bindings/displayio/Display.h new file mode 100644 index 00000000000..a3c77e4e823 --- /dev/null +++ b/shared-bindings/displayio/Display.h @@ -0,0 +1,71 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_DISPLAY_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_DISPLAY_H + +#include "common-hal/microcontroller/Pin.h" + +#include "shared-module/displayio/Display.h" +#include "shared-module/displayio/Group.h" + +extern const mp_obj_type_t displayio_display_type; + +#define DELAY 0x80 + +#define NO_BRIGHTNESS_COMMAND 0x100 + +void common_hal_displayio_display_construct(displayio_display_obj_t* self, + mp_obj_t bus, uint16_t width, uint16_t height, + int16_t colstart, int16_t rowstart, uint16_t rotation, uint16_t color_depth, bool grayscale, + bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte, + uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command, uint8_t set_vertical_scroll, + uint8_t* init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t* backlight_pin, uint16_t brightness_command, + mp_float_t brightness, bool auto_brightness, + bool single_byte_bounds, bool data_as_commands, bool auto_refresh, uint16_t native_frames_per_second); + +bool common_hal_displayio_display_show(displayio_display_obj_t* self, + displayio_group_t* root_group); + +bool common_hal_displayio_display_refresh(displayio_display_obj_t* self, uint32_t target_ms_per_frame, uint32_t maximum_ms_per_real_frame); + +bool common_hal_displayio_display_get_auto_refresh(displayio_display_obj_t* self); +void common_hal_displayio_display_set_auto_refresh(displayio_display_obj_t* self, bool auto_refresh); + +uint16_t common_hal_displayio_display_get_width(displayio_display_obj_t* self); +uint16_t common_hal_displayio_display_get_height(displayio_display_obj_t* self); +uint16_t common_hal_displayio_display_get_rotation(displayio_display_obj_t* self); + +bool common_hal_displayio_display_get_auto_brightness(displayio_display_obj_t* self); +void common_hal_displayio_display_set_auto_brightness(displayio_display_obj_t* self, bool auto_brightness); + +mp_float_t common_hal_displayio_display_get_brightness(displayio_display_obj_t* self); +bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self, mp_float_t brightness); + +mp_obj_t common_hal_displayio_display_get_bus(displayio_display_obj_t* self); + + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_DISPLAY_H diff --git a/shared-bindings/displayio/EPaperDisplay.c b/shared-bindings/displayio/EPaperDisplay.c new file mode 100644 index 00000000000..81e06f82f93 --- /dev/null +++ b/shared-bindings/displayio/EPaperDisplay.c @@ -0,0 +1,313 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/EPaperDisplay.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/objtype.h" +#include "py/runtime.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`EPaperDisplay` -- Manage updating an epaper display over a display bus +//| ============================================================================== +//| +//| This initializes an epaper display and connects it into CircuitPython. Unlike other +//| objects in CircuitPython, EPaperDisplay objects live until `displayio.release_displays()` +//| is called. This is done so that CircuitPython can use the display itself. +//| +//| Most people should not use this class directly. Use a specific display driver instead that will +//| contain the startup and shutdown sequences at minimum. +//| +//| .. class:: EPaperDisplay(display_bus, start_sequence, stop_sequence, *, width, height, ram_width, ram_height, colstart=0, rowstart=0, rotation=0, set_column_window_command=None, set_row_window_command=None, single_byte_bounds=False, write_black_ram_command, black_bits_inverted=False, write_color_ram_command=None, color_bits_inverted=False, highlight_color=0x000000, refresh_display_command, refresh_time=40, busy_pin=None, busy_state=True, seconds_per_frame=180, always_toggle_chip_select=False) +//| +//| Create a EPaperDisplay object on the given display bus (`displayio.FourWire` or `displayio.ParallelBus`). +//| +//| The ``start_sequence`` and ``stop_sequence`` are bitpacked to minimize the ram impact. Every +//| command begins with a command byte followed by a byte to determine the parameter count and if +//| a delay is need after. When the top bit of the second byte is 1, the next byte will be the +//| delay time in milliseconds. The remaining 7 bits are the parameter count excluding any delay +//| byte. The third through final bytes are the remaining command parameters. The next byte will +//| begin a new command definition. +//| +//| :param display_bus: The bus that the display is connected to +//| :type display_bus: displayio.FourWire or displayio.ParallelBus +//| :param buffer start_sequence: Byte-packed initialization sequence. +//| :param buffer stop_sequence: Byte-packed initialization sequence. +//| :param int width: Width in pixels +//| :param int height: Height in pixels +//| :param int ram_width: RAM width in pixels +//| :param int ram_height: RAM height in pixels +//| :param int colstart: The index if the first visible column +//| :param int rowstart: The index if the first visible row +//| :param int rotation: The rotation of the display in degrees clockwise. Must be in 90 degree increments (0, 90, 180, 270) +//| :param int set_column_window_command: Command used to set the start and end columns to update +//| :param int set_row_window_command: Command used so set the start and end rows to update +//| :param int set_current_column_command: Command used to set the current column location +//| :param int set_current_row_command: Command used to set the current row location +//| :param int write_black_ram_command: Command used to write pixels values into the update region +//| :param bool black_bits_inverted: True if 0 bits are used to show black pixels. Otherwise, 1 means to show black. +//| :param int write_color_ram_command: Command used to write pixels values into the update region +//| :param bool color_bits_inverted: True if 0 bits are used to show the color. Otherwise, 1 means to show color. +//| :param int highlight_color: RGB888 of source color to highlight with third ePaper color. +//| :param int refresh_display_command: Command used to start a display refresh +//| :param float refresh_time: Time it takes to refresh the display before the stop_sequence should be sent. Ignored when busy_pin is provided. +//| :param microcontroller.Pin busy_pin: Pin used to signify the display is busy +//| :param bool busy_state: State of the busy pin when the display is busy +//| :param float seconds_per_frame: Minimum number of seconds between screen refreshes +//| :param bool always_toggle_chip_select: When True, chip select is toggled every byte +//| +STATIC mp_obj_t displayio_epaperdisplay_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_display_bus, ARG_start_sequence, ARG_stop_sequence, ARG_width, ARG_height, ARG_ram_width, ARG_ram_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_set_column_window_command, ARG_set_row_window_command, ARG_set_current_column_command, ARG_set_current_row_command, ARG_write_black_ram_command, ARG_black_bits_inverted, ARG_write_color_ram_command, ARG_color_bits_inverted, ARG_highlight_color, ARG_refresh_display_command, ARG_refresh_time, ARG_busy_pin, ARG_busy_state, ARG_seconds_per_frame, ARG_always_toggle_chip_select }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_start_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_stop_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, + { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, + { MP_QSTR_ram_width, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, + { MP_QSTR_ram_height, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, + { MP_QSTR_colstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_rowstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_rotation, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_set_column_window_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = NO_COMMAND} }, + { MP_QSTR_set_row_window_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = NO_COMMAND} }, + { MP_QSTR_set_current_column_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = NO_COMMAND} }, + { MP_QSTR_set_current_row_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = NO_COMMAND} }, + { MP_QSTR_write_black_ram_command, MP_ARG_INT | MP_ARG_REQUIRED }, + { MP_QSTR_black_bits_inverted, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_write_color_ram_command, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_color_bits_inverted, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_highlight_color, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x000000} }, + { MP_QSTR_refresh_display_command, MP_ARG_INT | MP_ARG_REQUIRED }, + { MP_QSTR_refresh_time, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(40)} }, + { MP_QSTR_busy_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_busy_state, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_seconds_per_frame, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(180)} }, + { MP_QSTR_always_toggle_chip_select, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t display_bus = args[ARG_display_bus].u_obj; + + mp_buffer_info_t start_bufinfo; + mp_get_buffer_raise(args[ARG_start_sequence].u_obj, &start_bufinfo, MP_BUFFER_READ); + mp_buffer_info_t stop_bufinfo; + mp_get_buffer_raise(args[ARG_stop_sequence].u_obj, &stop_bufinfo, MP_BUFFER_READ); + + + mp_obj_t busy_pin_obj = args[ARG_busy_pin].u_obj; + assert_pin(busy_pin_obj, true); + const mcu_pin_obj_t* busy_pin = NULL; + if (busy_pin_obj != NULL && busy_pin_obj != mp_const_none) { + busy_pin = MP_OBJ_TO_PTR(busy_pin_obj); + assert_pin_free(busy_pin); + } + + mp_int_t rotation = args[ARG_rotation].u_int; + if (rotation % 90 != 0) { + mp_raise_ValueError(translate("Display rotation must be in 90 degree increments")); + } + + displayio_epaperdisplay_obj_t *self = NULL; + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].display.base.type == NULL || + displays[i].display.base.type == &mp_type_NoneType) { + self = &displays[i].epaper_display; + break; + } + } + if (self == NULL) { + mp_raise_RuntimeError(translate("Too many displays")); + } + + mp_float_t refresh_time = mp_obj_get_float(args[ARG_refresh_time].u_obj); + mp_float_t seconds_per_frame = mp_obj_get_float(args[ARG_seconds_per_frame].u_obj); + + mp_int_t write_color_ram_command = NO_COMMAND; + mp_int_t highlight_color = args[ARG_highlight_color].u_int; + if (args[ARG_write_color_ram_command].u_obj != mp_const_none) { + write_color_ram_command = mp_obj_get_int(args[ARG_write_color_ram_command].u_obj); + } + + self->base.type = &displayio_epaperdisplay_type; + common_hal_displayio_epaperdisplay_construct( + self, + display_bus, + start_bufinfo.buf, start_bufinfo.len, stop_bufinfo.buf, stop_bufinfo.len, + args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_ram_width].u_int, args[ARG_ram_height].u_int, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, rotation, + args[ARG_set_column_window_command].u_int, args[ARG_set_row_window_command].u_int, + args[ARG_set_current_column_command].u_int, args[ARG_set_current_row_command].u_int, + args[ARG_write_black_ram_command].u_int, args[ARG_black_bits_inverted].u_bool, write_color_ram_command, args[ARG_color_bits_inverted].u_bool, highlight_color, args[ARG_refresh_display_command].u_int, refresh_time, + busy_pin, args[ARG_busy_state].u_bool, seconds_per_frame, args[ARG_always_toggle_chip_select].u_bool + ); + + return self; +} + +// Helper to ensure we have the native super class instead of a subclass. +static displayio_epaperdisplay_obj_t* native_display(mp_obj_t display_obj) { + mp_obj_t native_display = mp_instance_cast_to_native_base(display_obj, &displayio_epaperdisplay_type); + mp_obj_assert_native_inited(native_display); + return MP_OBJ_TO_PTR(native_display); +} + +//| .. method:: show(group) +//| +//| Switches to displaying the given group of layers. When group is None, the default +//| CircuitPython terminal will be shown. +//| +//| :param Group group: The group to show. +STATIC mp_obj_t displayio_epaperdisplay_obj_show(mp_obj_t self_in, mp_obj_t group_in) { + displayio_epaperdisplay_obj_t *self = native_display(self_in); + displayio_group_t* group = NULL; + if (group_in != mp_const_none) { + group = MP_OBJ_TO_PTR(native_group(group_in)); + } + + bool ok = common_hal_displayio_epaperdisplay_show(self, group); + if (!ok) { + mp_raise_ValueError(translate("Group already used")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_epaperdisplay_show_obj, displayio_epaperdisplay_obj_show); + +//| .. method:: refresh() +//| +//| Refreshes the display immediately or raises an exception if too soon. Use +//| ``time.sleep(display.time_to_refresh)`` to sleep until a refresh can occur. +//| +STATIC mp_obj_t displayio_epaperdisplay_obj_refresh(mp_obj_t self_in) { + displayio_epaperdisplay_obj_t *self = native_display(self_in); + bool ok = common_hal_displayio_epaperdisplay_refresh(self); + if (!ok) { + mp_raise_RuntimeError(translate("Refresh too soon")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_epaperdisplay_refresh_obj, displayio_epaperdisplay_obj_refresh); + +//| .. attribute:: time_to_refresh +//| +//| Time, in fractional seconds, until the ePaper display can be refreshed. +//| +//| +STATIC mp_obj_t displayio_epaperdisplay_obj_get_time_to_refresh(mp_obj_t self_in) { + displayio_epaperdisplay_obj_t *self = native_display(self_in); + return mp_obj_new_float(common_hal_displayio_epaperdisplay_get_time_to_refresh(self) / 1000.0); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_epaperdisplay_get_time_to_refresh_obj, displayio_epaperdisplay_obj_get_time_to_refresh); + +const mp_obj_property_t displayio_epaperdisplay_time_to_refresh_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_epaperdisplay_get_time_to_refresh_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: width +//| +//| Gets the width of the display in pixels +//| +//| +STATIC mp_obj_t displayio_epaperdisplay_obj_get_width(mp_obj_t self_in) { + displayio_epaperdisplay_obj_t *self = native_display(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_epaperdisplay_get_width(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_epaperdisplay_get_width_obj, displayio_epaperdisplay_obj_get_width); + +const mp_obj_property_t displayio_epaperdisplay_width_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_epaperdisplay_get_width_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: height +//| +//| Gets the height of the display in pixels +//| +//| +STATIC mp_obj_t displayio_epaperdisplay_obj_get_height(mp_obj_t self_in) { + displayio_epaperdisplay_obj_t *self = native_display(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_epaperdisplay_get_height(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_epaperdisplay_get_height_obj, displayio_epaperdisplay_obj_get_height); + +const mp_obj_property_t displayio_epaperdisplay_height_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_epaperdisplay_get_height_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: bus +//| +//| The bus being used by the display +//| +//| +STATIC mp_obj_t displayio_epaperdisplay_obj_get_bus(mp_obj_t self_in) { + displayio_epaperdisplay_obj_t *self = native_display(self_in); + return common_hal_displayio_epaperdisplay_get_bus(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_epaperdisplay_get_bus_obj, displayio_epaperdisplay_obj_get_bus); + +const mp_obj_property_t displayio_epaperdisplay_bus_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_epaperdisplay_get_bus_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +STATIC const mp_rom_map_elem_t displayio_epaperdisplay_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&displayio_epaperdisplay_show_obj) }, + { MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&displayio_epaperdisplay_refresh_obj) }, + + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&displayio_epaperdisplay_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&displayio_epaperdisplay_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_bus), MP_ROM_PTR(&displayio_epaperdisplay_bus_obj) }, + { MP_ROM_QSTR(MP_QSTR_time_to_refresh), MP_ROM_PTR(&displayio_epaperdisplay_time_to_refresh_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_epaperdisplay_locals_dict, displayio_epaperdisplay_locals_dict_table); + +const mp_obj_type_t displayio_epaperdisplay_type = { + { &mp_type_type }, + .name = MP_QSTR_EPaperDisplay, + .make_new = displayio_epaperdisplay_make_new, + .locals_dict = (mp_obj_dict_t*)&displayio_epaperdisplay_locals_dict, +}; diff --git a/shared-bindings/displayio/EPaperDisplay.h b/shared-bindings/displayio/EPaperDisplay.h new file mode 100644 index 00000000000..e4b81c8838e --- /dev/null +++ b/shared-bindings/displayio/EPaperDisplay.h @@ -0,0 +1,61 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_EPAPERDISPLAY_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_EPAPERDISPLAY_H + +#include "common-hal/microcontroller/Pin.h" + +#include "shared-module/displayio/EPaperDisplay.h" +#include "shared-module/displayio/Group.h" + +extern const mp_obj_type_t displayio_epaperdisplay_type; + +#define DELAY 0x80 + +#define NO_COMMAND 0x100 + +void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t* self, + mp_obj_t bus, uint8_t* start_sequence, uint16_t start_sequence_len, uint8_t* stop_sequence, uint16_t stop_sequence_len, + uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height, int16_t colstart, int16_t rowstart, uint16_t rotation, + uint16_t set_column_window_command, uint16_t set_row_window_command, + uint16_t set_current_column_command, uint16_t set_current_row_command, + uint16_t write_black_ram_command, bool black_bits_inverted, uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, uint16_t refresh_display_command, mp_float_t refresh_time, + const mcu_pin_obj_t* busy_pin, bool busy_state, mp_float_t seconds_per_frame, bool always_toggle_chip_select); + +bool common_hal_displayio_epaperdisplay_refresh(displayio_epaperdisplay_obj_t* self); + +bool common_hal_displayio_epaperdisplay_show(displayio_epaperdisplay_obj_t* self, displayio_group_t* root_group); + +// Returns time in milliseconds. +uint32_t common_hal_displayio_epaperdisplay_get_time_to_refresh(displayio_epaperdisplay_obj_t* self); + +uint16_t common_hal_displayio_epaperdisplay_get_width(displayio_epaperdisplay_obj_t* self); +uint16_t common_hal_displayio_epaperdisplay_get_height(displayio_epaperdisplay_obj_t* self); + +mp_obj_t common_hal_displayio_epaperdisplay_get_bus(displayio_epaperdisplay_obj_t* self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_EPAPERDISPLAY_H diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c new file mode 100644 index 00000000000..51203d4604a --- /dev/null +++ b/shared-bindings/displayio/FourWire.c @@ -0,0 +1,172 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018-2019 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/FourWire.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`FourWire` -- Manage updating a display over SPI four wire protocol +//| ========================================================================== +//| +//| Manage updating a display over SPI four wire protocol in the background while Python code runs. +//| It doesn't handle display initialization. +//| +//| .. class:: FourWire(spi_bus, *, command, chip_select, reset=None, baudrate=24000000) +//| +//| Create a FourWire object associated with the given pins. +//| +//| The SPI bus and pins are then in use by the display until `displayio.release_displays()` is +//| called even after a reload. (It does this so CircuitPython can use the display after your code +//| is done.) So, the first time you initialize a display bus in code.py you should call +//| :py:func`displayio.release_displays` first, otherwise it will error after the first code.py run. +//| +//| :param busio.SPI spi_bus: The SPI bus that make up the clock and data lines +//| :param microcontroller.Pin command: Data or command pin +//| :param microcontroller.Pin chip_select: Chip select pin +//| :param microcontroller.Pin reset: Reset pin. When None only software reset can be used +//| :param int baudrate: Maximum baudrate in Hz for the display on the bus +//| +STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_spi_bus, ARG_command, ARG_chip_select, ARG_reset, ARG_baudrate }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_spi_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_reset, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_baudrate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 24000000} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t command = args[ARG_command].u_obj; + mp_obj_t chip_select = args[ARG_chip_select].u_obj; + assert_pin_free(command); + assert_pin_free(chip_select); + mp_obj_t reset = args[ARG_reset].u_obj; + if (reset != mp_const_none) { + assert_pin_free(reset); + } else { + reset = NULL; + } + + displayio_fourwire_obj_t* self = NULL; + mp_obj_t spi = args[ARG_spi_bus].u_obj; + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].fourwire_bus.base.type == NULL || + displays[i].fourwire_bus.base.type == &mp_type_NoneType) { + self = &displays[i].fourwire_bus; + self->base.type = &displayio_fourwire_type; + break; + } + } + if (self == NULL) { + mp_raise_RuntimeError(translate("Too many display busses")); + } + + common_hal_displayio_fourwire_construct(self, + MP_OBJ_TO_PTR(spi), command, chip_select, reset, args[ARG_baudrate].u_int); + return self; +} + +//| .. method:: reset() +//| +//| Performs a hardware reset via the reset pin. Raises an exception if called when no reset pin +//| is available. +//| +STATIC mp_obj_t displayio_fourwire_obj_reset(mp_obj_t self_in) { + displayio_fourwire_obj_t *self = self_in; + + if (!common_hal_displayio_fourwire_reset(self)) { + mp_raise_RuntimeError(translate("no reset pin available")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_fourwire_reset_obj, displayio_fourwire_obj_reset); + +//| .. method:: send(command, data, *, toggle_every_byte=False) +//| +//| Sends the given command value followed by the full set of data. Display state, such as +//| vertical scroll, set via ``send`` may or may not be reset once the code is done. +//| +STATIC mp_obj_t displayio_fourwire_obj_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_command, ARG_data, ARG_toggle_every_byte }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_command, MP_ARG_INT | MP_ARG_REQUIRED }, + { MP_QSTR_data, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_toggle_every_byte, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t command_int = args[ARG_command].u_int; + if (command_int > 255 || command_int < 0) { + mp_raise_ValueError(translate("Command must be an int between 0 and 255")); + } + displayio_fourwire_obj_t *self = pos_args[0]; + uint8_t command = command_int; + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ); + + // Wait for display bus to be available. + while (!common_hal_displayio_fourwire_begin_transaction(self)) { + RUN_BACKGROUND_TASKS; + } + display_chip_select_behavior_t chip_select = CHIP_SELECT_UNTOUCHED; + if (args[ARG_toggle_every_byte].u_bool) { + chip_select = CHIP_SELECT_TOGGLE_EVERY_BYTE; + } + common_hal_displayio_fourwire_send(self, DISPLAY_COMMAND, chip_select, &command, 1); + common_hal_displayio_fourwire_send(self, DISPLAY_DATA, chip_select, ((uint8_t*) bufinfo.buf), bufinfo.len); + common_hal_displayio_fourwire_end_transaction(self); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(displayio_fourwire_send_obj, 3, displayio_fourwire_obj_send); + +STATIC const mp_rom_map_elem_t displayio_fourwire_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&displayio_fourwire_reset_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&displayio_fourwire_send_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_fourwire_locals_dict, displayio_fourwire_locals_dict_table); + +const mp_obj_type_t displayio_fourwire_type = { + { &mp_type_type }, + .name = MP_QSTR_FourWire, + .make_new = displayio_fourwire_make_new, + .locals_dict = (mp_obj_dict_t*)&displayio_fourwire_locals_dict, +}; diff --git a/shared-bindings/displayio/FourWire.h b/shared-bindings/displayio/FourWire.h new file mode 100644 index 00000000000..d0935f06390 --- /dev/null +++ b/shared-bindings/displayio/FourWire.h @@ -0,0 +1,54 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_FOURWIRE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_FOURWIRE_H + +#include "shared-module/displayio/FourWire.h" + +#include "shared-bindings/displayio/__init__.h" +#include "common-hal/microcontroller/Pin.h" + +#include "shared-module/displayio/Group.h" + +extern const mp_obj_type_t displayio_fourwire_type; + +void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, + busio_spi_obj_t* spi, const mcu_pin_obj_t* command, + const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, uint32_t baudrate); + +void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self); + +bool common_hal_displayio_fourwire_reset(mp_obj_t self); +bool common_hal_displayio_fourwire_bus_free(mp_obj_t self); + +bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t self); + +void common_hal_displayio_fourwire_send(mp_obj_t self, display_byte_type_t byte_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length); + +void common_hal_displayio_fourwire_end_transaction(mp_obj_t self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_FOURWIRE_H diff --git a/shared-bindings/displayio/Group.c b/shared-bindings/displayio/Group.c new file mode 100644 index 00000000000..5a35424ce44 --- /dev/null +++ b/shared-bindings/displayio/Group.c @@ -0,0 +1,327 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/Group.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/objtype.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`Group` -- Group together sprites and subgroups +//| ========================================================================== +//| +//| Manage a group of sprites and groups and how they are inter-related. +//| +//| .. class:: Group(*, max_size=4, scale=1, x=0, y=0) +//| +//| Create a Group of a given size and scale. Scale is in one dimension. For example, scale=2 +//| leads to a layer's pixel being 2x2 pixels when in the group. +//| +//| :param int max_size: The maximum group size. +//| :param int scale: Scale of layer pixels in one dimension. +//| :param int x: Initial x position within the parent. +//| :param int y: Initial y position within the parent. +//| +STATIC mp_obj_t displayio_group_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_max_size, ARG_scale, ARG_x, ARG_y }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_max_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 4} }, + { MP_QSTR_scale, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} }, + { MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t max_size = args[ARG_max_size].u_int; + if (max_size < 1) { + mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_max_size); + } + + mp_int_t scale = args[ARG_scale].u_int; + if (scale < 1) { + mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_scale); + } + + displayio_group_t *self = m_new_obj(displayio_group_t); + self->base.type = &displayio_group_type; + common_hal_displayio_group_construct(self, max_size, scale, args[ARG_x].u_int, args[ARG_y].u_int); + + return MP_OBJ_FROM_PTR(self); +} + +// Helper to ensure we have the native super class instead of a subclass. +displayio_group_t* native_group(mp_obj_t group_obj) { + mp_obj_t native_group = mp_instance_cast_to_native_base(group_obj, &displayio_group_type); + if (native_group == MP_OBJ_NULL) { + mp_raise_ValueError_varg(translate("Must be a %q subclass."), MP_QSTR_Group); + } + mp_obj_assert_native_inited(native_group); + return MP_OBJ_TO_PTR(native_group); +} + +//| .. attribute:: scale +//| +//| Scales each pixel within the Group in both directions. For example, when scale=2 each pixel +//| will be represented by 2x2 pixels. +//| +STATIC mp_obj_t displayio_group_obj_get_scale(mp_obj_t self_in) { + displayio_group_t *self = native_group(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_group_get_scale(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_group_get_scale_obj, displayio_group_obj_get_scale); + +STATIC mp_obj_t displayio_group_obj_set_scale(mp_obj_t self_in, mp_obj_t scale_obj) { + displayio_group_t *self = native_group(self_in); + + mp_int_t scale = mp_obj_get_int(scale_obj); + if (scale < 1) { + mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_scale); + } + common_hal_displayio_group_set_scale(self, scale); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_set_scale_obj, displayio_group_obj_set_scale); + +const mp_obj_property_t displayio_group_scale_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_group_get_scale_obj, + (mp_obj_t)&displayio_group_set_scale_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: x +//| +//| X position of the Group in the parent. +//| +STATIC mp_obj_t displayio_group_obj_get_x(mp_obj_t self_in) { + displayio_group_t *self = native_group(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_group_get_x(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_group_get_x_obj, displayio_group_obj_get_x); + +STATIC mp_obj_t displayio_group_obj_set_x(mp_obj_t self_in, mp_obj_t x_obj) { + displayio_group_t *self = native_group(self_in); + + mp_int_t x = mp_obj_get_int(x_obj); + common_hal_displayio_group_set_x(self, x); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_set_x_obj, displayio_group_obj_set_x); + +const mp_obj_property_t displayio_group_x_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_group_get_x_obj, + (mp_obj_t)&displayio_group_set_x_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: y +//| +//| Y position of the Group in the parent. +//| +STATIC mp_obj_t displayio_group_obj_get_y(mp_obj_t self_in) { + displayio_group_t *self = native_group(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_group_get_y(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_group_get_y_obj, displayio_group_obj_get_y); + +STATIC mp_obj_t displayio_group_obj_set_y(mp_obj_t self_in, mp_obj_t y_obj) { + displayio_group_t *self = native_group(self_in); + + mp_int_t y = mp_obj_get_int(y_obj); + common_hal_displayio_group_set_y(self, y); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_set_y_obj, displayio_group_obj_set_y); + +const mp_obj_property_t displayio_group_y_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_group_get_y_obj, + (mp_obj_t)&displayio_group_set_y_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: append(layer) +//| +//| Append a layer to the group. It will be drawn above other layers. +//| +STATIC mp_obj_t displayio_group_obj_append(mp_obj_t self_in, mp_obj_t layer) { + displayio_group_t *self = native_group(self_in); + common_hal_displayio_group_insert(self, common_hal_displayio_group_get_len(self), layer); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_append_obj, displayio_group_obj_append); + +//| .. method:: insert(index, layer) +//| +//| Insert a layer into the group. +//| +STATIC mp_obj_t displayio_group_obj_insert(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t layer) { + displayio_group_t *self = native_group(self_in); + size_t index = mp_get_index(&displayio_group_type, common_hal_displayio_group_get_len(self), index_obj, false); + common_hal_displayio_group_insert(self, index, layer); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_3(displayio_group_insert_obj, displayio_group_obj_insert); + + +//| .. method:: index(layer) +//| +//| Returns the index of the first copy of layer. Raises ValueError if not found. +//| +STATIC mp_obj_t displayio_group_obj_index(mp_obj_t self_in, mp_obj_t layer) { + displayio_group_t *self = native_group(self_in); + mp_int_t index = common_hal_displayio_group_index(self, layer); + if (index < 0) { + mp_raise_ValueError(translate("object not in sequence")); + } + return MP_OBJ_NEW_SMALL_INT(index); +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_index_obj, displayio_group_obj_index); + +//| .. method:: pop(i=-1) +//| +//| Remove the ith item and return it. +//| +STATIC mp_obj_t displayio_group_obj_pop(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_i }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_i, MP_ARG_INT, {.u_int = -1} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + displayio_group_t *self = native_group(pos_args[0]); + + size_t index = mp_get_index(&displayio_group_type, + common_hal_displayio_group_get_len(self), + MP_OBJ_NEW_SMALL_INT(args[ARG_i].u_int), + false); + return common_hal_displayio_group_pop(self, index); +} +MP_DEFINE_CONST_FUN_OBJ_KW(displayio_group_pop_obj, 1, displayio_group_obj_pop); + + +//| .. method:: remove(layer) +//| +//| Remove the first copy of layer. Raises ValueError if it is not present. +//| +STATIC mp_obj_t displayio_group_obj_remove(mp_obj_t self_in, mp_obj_t layer) { + mp_obj_t index = displayio_group_obj_index(self_in, layer); + displayio_group_t *self = native_group(self_in); + + common_hal_displayio_group_pop(self, MP_OBJ_SMALL_INT_VALUE(index)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_remove_obj, displayio_group_obj_remove); + +//| .. method:: __len__() +//| +//| Returns the number of layers in a Group +//| +STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + displayio_group_t *self = native_group(self_in); + uint16_t len = common_hal_displayio_group_get_len(self); + switch (op) { + case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0); + case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len); + default: return MP_OBJ_NULL; // op not supported + } +} + +//| .. method:: __getitem__(index) +//| +//| Returns the value at the given index. +//| +//| This allows you to:: +//| +//| print(group[0]) +//| +//| .. method:: __setitem__(index, value) +//| +//| Sets the value at the given index. +//| +//| This allows you to:: +//| +//| group[0] = sprite +//| +//| .. method:: __delitem__(index) +//| +//| Deletes the value at the given index. +//| +//| This allows you to:: +//| +//| del group[0] +//| +STATIC mp_obj_t group_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) { + displayio_group_t *self = native_group(self_in); + + if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) { + mp_raise_NotImplementedError(translate("Slices not supported")); + } else { + size_t index = mp_get_index(&displayio_group_type, common_hal_displayio_group_get_len(self), index_obj, false); + + if (value == MP_OBJ_SENTINEL) { + // load + return common_hal_displayio_group_get(self, index); + } else if (value == MP_OBJ_NULL) { + common_hal_displayio_group_pop(self, index); + } else { + common_hal_displayio_group_set(self, index, value); + } + } + return mp_const_none; +} + +STATIC const mp_rom_map_elem_t displayio_group_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_scale), MP_ROM_PTR(&displayio_group_scale_obj) }, + { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&displayio_group_x_obj) }, + { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&displayio_group_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_append), MP_ROM_PTR(&displayio_group_append_obj) }, + { MP_ROM_QSTR(MP_QSTR_insert), MP_ROM_PTR(&displayio_group_insert_obj) }, + { MP_ROM_QSTR(MP_QSTR_index), MP_ROM_PTR(&displayio_group_index_obj) }, + { MP_ROM_QSTR(MP_QSTR_pop), MP_ROM_PTR(&displayio_group_pop_obj) }, + { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&displayio_group_remove_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_group_locals_dict, displayio_group_locals_dict_table); + +const mp_obj_type_t displayio_group_type = { + { &mp_type_type }, + .name = MP_QSTR_Group, + .make_new = displayio_group_make_new, + .subscr = group_subscr, + .unary_op = group_unary_op, + .getiter = mp_obj_new_generic_iterator, + .locals_dict = (mp_obj_dict_t*)&displayio_group_locals_dict, +}; diff --git a/shared-bindings/displayio/Group.h b/shared-bindings/displayio/Group.h new file mode 100644 index 00000000000..dc9616f2e92 --- /dev/null +++ b/shared-bindings/displayio/Group.h @@ -0,0 +1,51 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_GROUP_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_GROUP_H + +#include "shared-module/displayio/Group.h" + +extern const mp_obj_type_t displayio_group_type; + +displayio_group_t* native_group(mp_obj_t group_obj); + +void common_hal_displayio_group_construct(displayio_group_t* self, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y); +uint32_t common_hal_displayio_group_get_scale(displayio_group_t* self); +void common_hal_displayio_group_set_scale(displayio_group_t* self, uint32_t scale); +mp_int_t common_hal_displayio_group_get_x(displayio_group_t* self); +void common_hal_displayio_group_set_x(displayio_group_t* self, mp_int_t x); +mp_int_t common_hal_displayio_group_get_y(displayio_group_t* self); +void common_hal_displayio_group_set_y(displayio_group_t* self, mp_int_t y); +void common_hal_displayio_group_append(displayio_group_t* self, mp_obj_t layer); +void common_hal_displayio_group_insert(displayio_group_t* self, size_t index, mp_obj_t layer); +size_t common_hal_displayio_group_get_len(displayio_group_t* self); +mp_obj_t common_hal_displayio_group_pop(displayio_group_t* self, size_t index); +mp_int_t common_hal_displayio_group_index(displayio_group_t* self, mp_obj_t layer); +mp_obj_t common_hal_displayio_group_get(displayio_group_t* self, size_t index); +void common_hal_displayio_group_set(displayio_group_t* self, size_t index, mp_obj_t layer); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_GROUP_H diff --git a/shared-bindings/displayio/I2CDisplay.c b/shared-bindings/displayio/I2CDisplay.c new file mode 100644 index 00000000000..4339d182f44 --- /dev/null +++ b/shared-bindings/displayio/I2CDisplay.c @@ -0,0 +1,152 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/I2CDisplay.h" + +#include +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`I2CDisplay` -- Manage updating a display over I2C +//| ========================================================================== +//| +//| Manage updating a display over I2C in the background while Python code runs. +//| It doesn't handle display initialization. +//| +//| .. class:: I2CDisplay(i2c_bus, *, device_address, reset=None) +//| +//| Create a I2CDisplay object associated with the given I2C bus and reset pin. +//| +//| The I2C bus and pins are then in use by the display until `displayio.release_displays()` is +//| called even after a reload. (It does this so CircuitPython can use the display after your code +//| is done.) So, the first time you initialize a display bus in code.py you should call +//| :py:func`displayio.release_displays` first, otherwise it will error after the first code.py run. +//| +//| :param busio.I2C i2c_bus: The I2C bus that make up the clock and data lines +//| :param int device_address: The I2C address of the device +//| :param microcontroller.Pin reset: Reset pin. When None only software reset can be used +//| +STATIC mp_obj_t displayio_i2cdisplay_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_i2c_bus, ARG_device_address, ARG_reset }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_i2c_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_device_address, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_reset, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t reset = args[ARG_reset].u_obj; + if (reset != mp_const_none) { + assert_pin_free(reset); + } else { + reset = NULL; + } + + displayio_i2cdisplay_obj_t* self = NULL; + mp_obj_t i2c = args[ARG_i2c_bus].u_obj; + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].i2cdisplay_bus.base.type == NULL || + displays[i].i2cdisplay_bus.base.type == &mp_type_NoneType) { + self = &displays[i].i2cdisplay_bus; + self->base.type = &displayio_i2cdisplay_type; + break; + } + } + if (self == NULL) { + mp_raise_RuntimeError(translate("Too many display busses")); + } + + common_hal_displayio_i2cdisplay_construct(self, + MP_OBJ_TO_PTR(i2c), args[ARG_device_address].u_int, reset); + return self; +} + +//| .. method:: reset() +//| +//| Performs a hardware reset via the reset pin. Raises an exception if called when no reset pin +//| is available. +//| +STATIC mp_obj_t displayio_i2cdisplay_obj_reset(mp_obj_t self_in) { + displayio_i2cdisplay_obj_t *self = self_in; + + if (!common_hal_displayio_i2cdisplay_reset(self)) { + mp_raise_RuntimeError(translate("no reset pin available")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_i2cdisplay_reset_obj, displayio_i2cdisplay_obj_reset); + +//| .. method:: send(command, data) +//| +//| Sends the given command value followed by the full set of data. Display state, such as +//| vertical scroll, set via ``send`` may or may not be reset once the code is done. +//| +STATIC mp_obj_t displayio_i2cdisplay_obj_send(mp_obj_t self, mp_obj_t command_obj, mp_obj_t data_obj) { + mp_int_t command_int = MP_OBJ_SMALL_INT_VALUE(command_obj); + if (!MP_OBJ_IS_SMALL_INT(command_obj) || command_int > 255 || command_int < 0) { + mp_raise_ValueError(translate("Command must be 0-255")); + } + uint8_t command = command_int; + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(data_obj, &bufinfo, MP_BUFFER_READ); + + // Wait for display bus to be available. + while (!common_hal_displayio_i2cdisplay_begin_transaction(self)) { + RUN_BACKGROUND_TASKS; + } + uint8_t full_command[bufinfo.len + 1]; + full_command[0] = command; + memcpy(full_command + 1, ((uint8_t*) bufinfo.buf), bufinfo.len); + common_hal_displayio_i2cdisplay_send(self, DISPLAY_COMMAND, CHIP_SELECT_UNTOUCHED, full_command, bufinfo.len + 1); + common_hal_displayio_i2cdisplay_end_transaction(self); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_3(displayio_i2cdisplay_send_obj, displayio_i2cdisplay_obj_send); + +STATIC const mp_rom_map_elem_t displayio_i2cdisplay_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&displayio_i2cdisplay_reset_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&displayio_i2cdisplay_send_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_i2cdisplay_locals_dict, displayio_i2cdisplay_locals_dict_table); + +const mp_obj_type_t displayio_i2cdisplay_type = { + { &mp_type_type }, + .name = MP_QSTR_I2CDisplay, + .make_new = displayio_i2cdisplay_make_new, + .locals_dict = (mp_obj_dict_t*)&displayio_i2cdisplay_locals_dict, +}; diff --git a/shared-bindings/displayio/I2CDisplay.h b/shared-bindings/displayio/I2CDisplay.h new file mode 100644 index 00000000000..bae53c4914d --- /dev/null +++ b/shared-bindings/displayio/I2CDisplay.h @@ -0,0 +1,51 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_I2CDISPLAY_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_I2CDISPLAY_H + +#include "shared-module/displayio/I2CDisplay.h" + +#include "shared-bindings/displayio/__init__.h" +#include "common-hal/microcontroller/Pin.h" + +extern const mp_obj_type_t displayio_i2cdisplay_type; + +void common_hal_displayio_i2cdisplay_construct(displayio_i2cdisplay_obj_t* self, + busio_i2c_obj_t* i2c, uint16_t device_address, const mcu_pin_obj_t* reset); + +void common_hal_displayio_i2cdisplay_deinit(displayio_i2cdisplay_obj_t* self); + +bool common_hal_displayio_i2cdisplay_reset(mp_obj_t self); +bool common_hal_displayio_i2cdisplay_bus_free(mp_obj_t self); + +bool common_hal_displayio_i2cdisplay_begin_transaction(mp_obj_t self); + +void common_hal_displayio_i2cdisplay_send(mp_obj_t self, display_byte_type_t byte_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length); + +void common_hal_displayio_i2cdisplay_end_transaction(mp_obj_t self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_I2CDISPLAY_H diff --git a/shared-bindings/displayio/OnDiskBitmap.c b/shared-bindings/displayio/OnDiskBitmap.c new file mode 100644 index 00000000000..bf00ef855ec --- /dev/null +++ b/shared-bindings/displayio/OnDiskBitmap.c @@ -0,0 +1,147 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/OnDiskBitmap.h" + +#include + +#include "py/runtime.h" +#include "py/objproperty.h" +#include "supervisor/shared/translate.h" +#include "shared-bindings/displayio/OnDiskBitmap.h" + +//| .. currentmodule:: displayio +//| +//| :class:`OnDiskBitmap` -- Loads pixels straight from disk +//| ========================================================================== +//| +//| Loads values straight from disk. This minimizes memory use but can lead to +//| much slower pixel load times. These load times may result in frame tearing where only part of +//| the image is visible. +//| +//| It's easiest to use on a board with a built in display such as the `Hallowing M0 Express +//| `_. +//| +//| .. code-block:: Python +//| +//| import board +//| import displayio +//| import time +//| import pulseio +//| +//| board.DISPLAY.auto_brightness = False +//| board.DISPLAY.brightness = 0 +//| splash = displayio.Group() +//| board.DISPLAY.show(splash) +//| +//| with open("/sample.bmp", "rb") as f: +//| odb = displayio.OnDiskBitmap(f) +//| face = displayio.TileGrid(odb, pixel_shader=displayio.ColorConverter(), position=(0,0)) +//| splash.append(face) +//| # Wait for the image to load. +//| board.DISPLAY.wait_for_frame() +//| +//| # Fade up the backlight +//| for i in range(100): +//| board.DISPLAY.brightness = 0.01 * i +//| time.sleep(0.05) +//| +//| # Wait forever +//| while True: +//| pass +//| +//| .. class:: OnDiskBitmap(file) +//| +//| Create an OnDiskBitmap object with the given file. +//| +//| :param file file: The open bitmap file +//| +STATIC mp_obj_t displayio_ondiskbitmap_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); + + if (!MP_OBJ_IS_TYPE(pos_args[0], &mp_type_fileio)) { + mp_raise_TypeError(translate("file must be a file opened in byte mode")); + } + + displayio_ondiskbitmap_t *self = m_new_obj(displayio_ondiskbitmap_t); + self->base.type = &displayio_ondiskbitmap_type; + common_hal_displayio_ondiskbitmap_construct(self, MP_OBJ_TO_PTR(pos_args[0])); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. attribute:: width +//| +//| Width of the bitmap. (read only) +//| +STATIC mp_obj_t displayio_ondiskbitmap_obj_get_width(mp_obj_t self_in) { + displayio_ondiskbitmap_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_ondiskbitmap_get_width(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(displayio_ondiskbitmap_get_width_obj, displayio_ondiskbitmap_obj_get_width); + +const mp_obj_property_t displayio_ondiskbitmap_width_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_ondiskbitmap_get_width_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, + +}; + +//| .. attribute:: height +//| +//| Height of the bitmap. (read only) +//| +STATIC mp_obj_t displayio_ondiskbitmap_obj_get_height(mp_obj_t self_in) { + displayio_ondiskbitmap_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_ondiskbitmap_get_height(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(displayio_ondiskbitmap_get_height_obj, displayio_ondiskbitmap_obj_get_height); + +const mp_obj_property_t displayio_ondiskbitmap_height_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_ondiskbitmap_get_height_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, + +}; + +STATIC const mp_rom_map_elem_t displayio_ondiskbitmap_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&displayio_ondiskbitmap_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&displayio_ondiskbitmap_width_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_ondiskbitmap_locals_dict, displayio_ondiskbitmap_locals_dict_table); + +const mp_obj_type_t displayio_ondiskbitmap_type = { + { &mp_type_type }, + .name = MP_QSTR_OnDiskBitmap, + .make_new = displayio_ondiskbitmap_make_new, + .locals_dict = (mp_obj_dict_t*)&displayio_ondiskbitmap_locals_dict, +}; diff --git a/shared-bindings/displayio/OnDiskBitmap.h b/shared-bindings/displayio/OnDiskBitmap.h new file mode 100644 index 00000000000..9a6c81f8f1f --- /dev/null +++ b/shared-bindings/displayio/OnDiskBitmap.h @@ -0,0 +1,43 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_ONDISKBITMAP_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_ONDISKBITMAP_H + +#include "shared-module/displayio/OnDiskBitmap.h" +#include "extmod/vfs_fat.h" + +extern const mp_obj_type_t displayio_ondiskbitmap_type; + +void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self, pyb_file_obj_t* file); + +uint32_t common_hal_displayio_ondiskbitmap_get_pixel(displayio_ondiskbitmap_t *bitmap, + int16_t x, int16_t y); + +uint16_t common_hal_displayio_ondiskbitmap_get_height(displayio_ondiskbitmap_t *self); + +uint16_t common_hal_displayio_ondiskbitmap_get_width(displayio_ondiskbitmap_t *self); +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_ONDISKBITMAP_H diff --git a/shared-bindings/displayio/Palette.c b/shared-bindings/displayio/Palette.c new file mode 100644 index 00000000000..dda58e3c53d --- /dev/null +++ b/shared-bindings/displayio/Palette.c @@ -0,0 +1,181 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/Palette.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`Palette` -- Stores a mapping from bitmap pixel palette_indexes to display colors +//| ========================================================================================= +//| +//| Map a pixel palette_index to a full color. Colors are transformed to the display's format internally to +//| save memory. +//| +//| .. class:: Palette(color_count) +//| +//| Create a Palette object to store a set number of colors. +//| +//| :param int color_count: The number of colors in the Palette +// TODO(tannewt): Add support for other color formats. +// TODO(tannewt): Add support for 8-bit alpha blending. +//| +STATIC mp_obj_t displayio_palette_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_color_count }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_color_count, MP_ARG_REQUIRED | MP_ARG_INT }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + displayio_palette_t *self = m_new_obj(displayio_palette_t); + self->base.type = &displayio_palette_type; + common_hal_displayio_palette_construct(self, args[ARG_color_count].u_int); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: __len__() +//| +//| Returns the number of colors in a Palette +//| +STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + displayio_palette_t *self = MP_OBJ_TO_PTR(self_in); + switch (op) { + case MP_UNARY_OP_BOOL: return mp_const_true; + case MP_UNARY_OP_LEN: + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_palette_get_len(self)); + default: return MP_OBJ_NULL; // op not supported + } +} + +//| .. method:: __setitem__(index, value) +//| +//| Sets the pixel color at the given index. The index should be an integer in the range 0 to color_count-1. +//| +//| The value argument represents a color, and can be from 0x000000 to 0xFFFFFF (to represent an RGB value). +//| Value can be an int, bytes (3 bytes (RGB) or 4 bytes (RGB + pad byte)), or bytearray. +//| +//| This allows you to:: +//| +//| palette[0] = 0xFFFFFF # set using an integer +//| palette[1] = b'\xff\xff\x00' # set using 3 bytes +//| palette[2] = b'\xff\xff\x00\x00' # set using 4 bytes +//| palette[3] = bytearray(b'\x00\x00\xFF') # set using a bytearay of 3 or 4 bytes +//| +STATIC mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { + if (value == MP_OBJ_NULL) { + // delete item + return MP_OBJ_NULL; // op not supported + } + // Slicing not supported. Use a duplicate Palette to swap multiple colors atomically. + if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) { + return MP_OBJ_NULL; + } + displayio_palette_t *self = MP_OBJ_TO_PTR(self_in); + size_t index = mp_get_index(&displayio_palette_type, self->color_count, index_in, false); + // index read + if (value == MP_OBJ_SENTINEL) { + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_palette_get_color(self, index)); + } + + uint32_t color; + mp_int_t int_value; + mp_buffer_info_t bufinfo; + if (mp_get_buffer(value, &bufinfo, MP_BUFFER_READ)) { + if (bufinfo.typecode != 'b' && bufinfo.typecode != 'B' && bufinfo.typecode != BYTEARRAY_TYPECODE) { + mp_raise_ValueError(translate("color buffer must be a bytearray or array of type 'b' or 'B'")); + } + uint8_t* buf = bufinfo.buf; + if (bufinfo.len == 3 || bufinfo.len == 4) { + color = buf[0] << 16 | buf[1] << 8 | buf[2]; + } else { + mp_raise_ValueError(translate("color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)")); + } + } else if (mp_obj_get_int_maybe(value, &int_value)) { + if (int_value < 0 || int_value > 0xffffff) { + mp_raise_TypeError(translate("color must be between 0x000000 and 0xffffff")); + } + color = int_value; + } else { + mp_raise_TypeError(translate("color buffer must be a buffer or int")); + } + common_hal_displayio_palette_set_color(self, index, color); + return mp_const_none; +} + +//| .. method:: make_transparent(palette_index) +//| +STATIC mp_obj_t displayio_palette_obj_make_transparent(mp_obj_t self_in, mp_obj_t palette_index_obj) { + displayio_palette_t *self = MP_OBJ_TO_PTR(self_in); + + mp_int_t palette_index; + if (!mp_obj_get_int_maybe(palette_index_obj, &palette_index)) { + mp_raise_ValueError(translate("palette_index should be an int")); + } + common_hal_displayio_palette_make_transparent(self, palette_index); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_palette_make_transparent_obj, displayio_palette_obj_make_transparent); + +//| .. method:: make_opaque(palette_index) +//| +STATIC mp_obj_t displayio_palette_obj_make_opaque(mp_obj_t self_in, mp_obj_t palette_index_obj) { + displayio_palette_t *self = MP_OBJ_TO_PTR(self_in); + + mp_int_t palette_index; + if (!mp_obj_get_int_maybe(palette_index_obj, &palette_index)) { + mp_raise_ValueError(translate("palette_index should be an int")); + } + common_hal_displayio_palette_make_opaque(self, palette_index); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_palette_make_opaque_obj, displayio_palette_obj_make_opaque); + +STATIC const mp_rom_map_elem_t displayio_palette_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_make_transparent), MP_ROM_PTR(&displayio_palette_make_transparent_obj) }, + { MP_ROM_QSTR(MP_QSTR_make_opaque), MP_ROM_PTR(&displayio_palette_make_opaque_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_palette_locals_dict, displayio_palette_locals_dict_table); + +const mp_obj_type_t displayio_palette_type = { + { &mp_type_type }, + .name = MP_QSTR_Palette, + .make_new = displayio_palette_make_new, + .subscr = palette_subscr, + .unary_op = group_unary_op, + .getiter = mp_obj_new_generic_iterator, + .locals_dict = (mp_obj_dict_t*)&displayio_palette_locals_dict, +}; diff --git a/shared-bindings/displayio/Palette.h b/shared-bindings/displayio/Palette.h new file mode 100644 index 00000000000..8c9fe11e381 --- /dev/null +++ b/shared-bindings/displayio/Palette.h @@ -0,0 +1,42 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_PALETTE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_PALETTE_H + +#include "shared-module/displayio/Palette.h" + +extern const mp_obj_type_t displayio_palette_type; + +void common_hal_displayio_palette_construct(displayio_palette_t* self, uint16_t color_count); +void common_hal_displayio_palette_set_color(displayio_palette_t* self, uint32_t palette_index, uint32_t color); +uint32_t common_hal_displayio_palette_get_color(displayio_palette_t* self, uint32_t palette_index); +uint32_t common_hal_displayio_palette_get_len(displayio_palette_t* self); + +void common_hal_displayio_palette_make_opaque(displayio_palette_t* self, uint32_t palette_index); +void common_hal_displayio_palette_make_transparent(displayio_palette_t* self, uint32_t palette_index); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_PALETTE_H diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c new file mode 100644 index 00000000000..f7195b9ccbc --- /dev/null +++ b/shared-bindings/displayio/ParallelBus.c @@ -0,0 +1,161 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/ParallelBus.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`ParallelBus` -- Manage updating a display over 8-bit parallel bus +//| ============================================================================== +//| +//| Manage updating a display over 8-bit parallel bus in the background while Python code runs. This +//| protocol may be refered to as 8080-I Series Parallel Interface in datasheets. It doesn't handle +//| display initialization. +//| +//| .. class:: ParallelBus(*, data0, command, chip_select, write, read, reset) +//| +//| Create a ParallelBus object associated with the given pins. The bus is inferred from data0 +//| by implying the next 7 additional pins on a given GPIO port. +//| +//| The parallel bus and pins are then in use by the display until `displayio.release_displays()` +//| is called even after a reload. (It does this so CircuitPython can use the display after your +//| code is done.) So, the first time you initialize a display bus in code.py you should call +//| :py:func`displayio.release_displays` first, otherwise it will error after the first code.py run. +//| +//| :param microcontroller.Pin data0: The first data pin. The rest are implied +//| :param microcontroller.Pin command: Data or command pin +//| :param microcontroller.Pin chip_select: Chip select pin +//| :param microcontroller.Pin write: Write pin +//| :param microcontroller.Pin read: Read pin +//| :param microcontroller.Pin reset: Reset pin +//| +STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_data0, ARG_command, ARG_chip_select, ARG_write, ARG_read, ARG_reset }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_data0, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_write, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_read, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_reset, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t data0 = args[ARG_data0].u_obj; + mp_obj_t command = args[ARG_command].u_obj; + mp_obj_t chip_select = args[ARG_chip_select].u_obj; + mp_obj_t write = args[ARG_write].u_obj; + mp_obj_t read = args[ARG_read].u_obj; + mp_obj_t reset = args[ARG_reset].u_obj; + assert_pin_free(data0); + assert_pin_free(command); + assert_pin_free(chip_select); + assert_pin_free(write); + assert_pin_free(read); + assert_pin_free(reset); + + displayio_parallelbus_obj_t* self = NULL; + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].parallel_bus.base.type== NULL || + displays[i].parallel_bus.base.type == &mp_type_NoneType) { + self = &displays[i].parallel_bus; + self->base.type = &displayio_parallelbus_type; + break; + } + } + if (self == NULL) { + mp_raise_RuntimeError(translate("Too many display busses")); + } + + common_hal_displayio_parallelbus_construct(self, data0, command, chip_select, write, read, reset); + return self; +} + +//| .. method:: reset() +//| +//| Performs a hardware reset via the reset pin. Raises an exception if called when no reset pin +//| is available. +//| +STATIC mp_obj_t displayio_parallelbus_obj_reset(mp_obj_t self_in) { + displayio_parallelbus_obj_t *self = self_in; + + if (!common_hal_displayio_parallelbus_reset(self)) { + mp_raise_RuntimeError(translate("no reset pin available")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_parallelbus_reset_obj, displayio_parallelbus_obj_reset); + +//| .. method:: send(command, data) +//| +//| Sends the given command value followed by the full set of data. Display state, such as +//| vertical scroll, set via ``send`` may or may not be reset once the code is done. +//| +STATIC mp_obj_t displayio_parallelbus_obj_send(mp_obj_t self, mp_obj_t command_obj, mp_obj_t data_obj) { + mp_int_t command_int = MP_OBJ_SMALL_INT_VALUE(command_obj); + if (!MP_OBJ_IS_SMALL_INT(command_obj) || command_int > 255 || command_int < 0) { + mp_raise_ValueError(translate("Command must be an int between 0 and 255")); + } + uint8_t command = command_int; + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(data_obj, &bufinfo, MP_BUFFER_READ); + + // Wait for display bus to be available. + while (!common_hal_displayio_parallelbus_begin_transaction(self)) { + RUN_BACKGROUND_TASKS; + } + common_hal_displayio_parallelbus_send(self, DISPLAY_COMMAND, CHIP_SELECT_UNTOUCHED, &command, 1); + common_hal_displayio_parallelbus_send(self, DISPLAY_DATA, CHIP_SELECT_UNTOUCHED, ((uint8_t*) bufinfo.buf), bufinfo.len); + common_hal_displayio_parallelbus_end_transaction(self); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_3(displayio_parallelbus_send_obj, displayio_parallelbus_obj_send); + +STATIC const mp_rom_map_elem_t displayio_parallelbus_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&displayio_parallelbus_reset_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&displayio_parallelbus_send_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_parallelbus_locals_dict, displayio_parallelbus_locals_dict_table); + +const mp_obj_type_t displayio_parallelbus_type = { + { &mp_type_type }, + .name = MP_QSTR_ParallelBus, + .make_new = displayio_parallelbus_make_new, + .locals_dict = (mp_obj_dict_t*)&displayio_parallelbus_locals_dict, +}; diff --git a/shared-bindings/displayio/ParallelBus.h b/shared-bindings/displayio/ParallelBus.h new file mode 100644 index 00000000000..be2aef7d44a --- /dev/null +++ b/shared-bindings/displayio/ParallelBus.h @@ -0,0 +1,53 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_PARALLELBUS_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_PARALLELBUS_H + +#include "common-hal/displayio/ParallelBus.h" + +#include "common-hal/microcontroller/Pin.h" +#include "shared-bindings/displayio/__init__.h" +#include "shared-module/displayio/Group.h" + +extern const mp_obj_type_t displayio_parallelbus_type; + +void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self, + const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select, + const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset); + +void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self); + +bool common_hal_displayio_parallelbus_reset(mp_obj_t self); +bool common_hal_displayio_parallelbus_bus_free(mp_obj_t self); + +bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t self); + +void common_hal_displayio_parallelbus_send(mp_obj_t self, display_byte_type_t byte_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length); + +void common_hal_displayio_parallelbus_end_transaction(mp_obj_t self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_PARALLELBUS_H diff --git a/shared-bindings/displayio/Shape.c b/shared-bindings/displayio/Shape.c new file mode 100644 index 00000000000..faa9472fa69 --- /dev/null +++ b/shared-bindings/displayio/Shape.c @@ -0,0 +1,123 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/Shape.h" + +#include + +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`Shape` -- Represents a shape by defining its bounds on each row +//| ========================================================================== +//| +//| Represents any shape made by defining boundaries that may be mirrored. +//| +//| .. warning:: This will likely be changed before 4.0.0. Consider it very experimental. +//| +//| .. class:: Shape(width, height, *, mirror_x=False, mirror_y=False) +//| +//| Create a Shape object with the given fixed size. Each pixel is one bit and is stored by the +//| column boundaries of the shape on each row. Each row's boundary defaults to the full row. +//| +//| :param int width: The number of pixels wide +//| :param int height: The number of pixels high +//| :param bool mirror_x: When true the left boundary is mirrored to the right. +//| :param bool mirror_y: When true the top boundary is mirrored to the bottom. +//| +STATIC mp_obj_t displayio_shape_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_width, ARG_height, ARG_mirror_x, ARG_mirror_y }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_width, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_height, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_mirror_x, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_mirror_y, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t width = args[ARG_width].u_int; + if (width < 1) { + mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_width); + } + mp_int_t height = args[ARG_height].u_int; + if (height < 1) { + mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_height); + } + + displayio_shape_t *self = m_new_obj(displayio_shape_t); + self->base.type = &displayio_shape_type; + common_hal_displayio_shape_construct(self, + width, + height, + args[ARG_mirror_x].u_bool, + args[ARG_mirror_y].u_bool); + + return MP_OBJ_FROM_PTR(self); +} + + +//| .. method:: set_boundary(y, start_x, end_x) +//| +//| Loads pre-packed data into the given row. +//| +STATIC mp_obj_t displayio_shape_obj_set_boundary(size_t n_args, const mp_obj_t *args) { + (void) n_args; + displayio_shape_t *self = MP_OBJ_TO_PTR(args[0]); + mp_int_t y; + if (!mp_obj_get_int_maybe(args[1], &y)) { + mp_raise_ValueError(translate("y should be an int")); + } + mp_int_t start_x; + if (!mp_obj_get_int_maybe(args[2], &start_x)) { + mp_raise_ValueError(translate("start_x should be an int")); + } + mp_int_t end_x; + if (!mp_obj_get_int_maybe(args[3], &end_x)) { + mp_raise_ValueError(translate("end_x should be an int")); + } + common_hal_displayio_shape_set_boundary(self, y, start_x, end_x); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(displayio_shape_set_boundary_obj, 4, 4, displayio_shape_obj_set_boundary); + +STATIC const mp_rom_map_elem_t displayio_shape_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_set_boundary), MP_ROM_PTR(&displayio_shape_set_boundary_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_shape_locals_dict, displayio_shape_locals_dict_table); + +const mp_obj_type_t displayio_shape_type = { + { &mp_type_type }, + .name = MP_QSTR_Shape, + .make_new = displayio_shape_make_new, + .locals_dict = (mp_obj_dict_t*)&displayio_shape_locals_dict, +}; diff --git a/shared-bindings/displayio/Shape.h b/shared-bindings/displayio/Shape.h new file mode 100644 index 00000000000..d08a3878229 --- /dev/null +++ b/shared-bindings/displayio/Shape.h @@ -0,0 +1,41 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_SHAPE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_SHAPE_H + +#include "shared-module/displayio/Shape.h" + +extern const mp_obj_type_t displayio_shape_type; + +void common_hal_displayio_shape_construct(displayio_shape_t *self, uint32_t width, + uint32_t height, bool mirror_x, bool mirror_y); + +void common_hal_displayio_shape_set_boundary(displayio_shape_t *self, uint16_t y, uint16_t start_x, + uint16_t end_x); +uint32_t common_hal_displayio_shape_get_pixel(void *shape, int16_t x, int16_t y); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_SHAPE_H diff --git a/shared-bindings/displayio/TileGrid.c b/shared-bindings/displayio/TileGrid.c new file mode 100644 index 00000000000..53fbb51c893 --- /dev/null +++ b/shared-bindings/displayio/TileGrid.c @@ -0,0 +1,386 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/TileGrid.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/objtype.h" +#include "py/runtime.h" +#include "shared-bindings/displayio/Bitmap.h" +#include "shared-bindings/displayio/ColorConverter.h" +#include "shared-bindings/displayio/OnDiskBitmap.h" +#include "shared-bindings/displayio/Palette.h" +#include "shared-bindings/displayio/Shape.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`TileGrid` -- A grid of tiles sourced out of one bitmap +//| ========================================================================== +//| +//| Position a grid of tiles sourced from a bitmap and pixel_shader combination. Multiple grids +//| can share bitmaps and pixel shaders. +//| +//| A single tile grid is also known as a Sprite. +//| +//| .. class:: TileGrid(bitmap, *, pixel_shader, width=1, height=1, tile_width=None, tile_height=None, default_tile=0, x=0, y=0) +//| +//| Create a TileGrid object. The bitmap is source for 2d pixels. The pixel_shader is used to +//| convert the value and its location to a display native pixel color. This may be a simple color +//| palette lookup, a gradient, a pattern or a color transformer. +//| +//| tile_width and tile_height match the height of the bitmap by default. +//| +//| :param displayio.Bitmap bitmap: The bitmap storing one or more tiles. +//| :param displayio.Palette pixel_shader: The pixel shader that produces colors from values +//| :param int width: Width of the grid in tiles. +//| :param int height: Height of the grid in tiles. +//| :param int tile_width: Width of a single tile in pixels. Defaults to the full Bitmap and must evenly divide into the Bitmap's dimensions. +//| :param int tile_height: Height of a single tile in pixels. Defaults to the full Bitmap and must evenly divide into the Bitmap's dimensions. +//| :param int default_tile: Default tile index to show. +//| :param int x: Initial x position of the left edge within the parent. +//| :param int y: Initial y position of the top edge within the parent. +//| +STATIC mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_bitmap, ARG_pixel_shader, ARG_width, ARG_height, ARG_tile_width, ARG_tile_height, ARG_default_tile, ARG_x, ARG_y }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} }, + { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} }, + { MP_QSTR_tile_width, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_tile_height, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_default_tile, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t bitmap = args[ARG_bitmap].u_obj; + + uint16_t bitmap_width; + uint16_t bitmap_height; + mp_obj_t native = mp_instance_cast_to_native_base(bitmap, &displayio_shape_type); + if (native != MP_OBJ_NULL) { + displayio_shape_t* bmp = MP_OBJ_TO_PTR(native); + bitmap_width = bmp->width; + bitmap_height = bmp->height; + } else if (MP_OBJ_IS_TYPE(bitmap, &displayio_bitmap_type)) { + displayio_bitmap_t* bmp = MP_OBJ_TO_PTR(bitmap); + native = bitmap; + bitmap_width = bmp->width; + bitmap_height = bmp->height; + } else if (MP_OBJ_IS_TYPE(bitmap, &displayio_ondiskbitmap_type)) { + displayio_ondiskbitmap_t* bmp = MP_OBJ_TO_PTR(bitmap); + native = bitmap; + bitmap_width = bmp->width; + bitmap_height = bmp->height; + } else { + mp_raise_TypeError_varg(translate("unsupported %q type"), MP_QSTR_bitmap); + } + mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj; + if (!MP_OBJ_IS_TYPE(pixel_shader, &displayio_colorconverter_type) && + !MP_OBJ_IS_TYPE(pixel_shader, &displayio_palette_type)) { + mp_raise_TypeError_varg(translate("unsupported %q type"), MP_QSTR_pixel_shader); + } + uint16_t tile_width = args[ARG_tile_width].u_int; + if (tile_width == 0) { + tile_width = bitmap_width; + } + uint16_t tile_height = args[ARG_tile_height].u_int; + if (tile_height == 0) { + tile_height = bitmap_height; + } + if (bitmap_width % tile_width != 0) { + mp_raise_ValueError(translate("Tile width must exactly divide bitmap width")); + } + if (bitmap_height % tile_height != 0) { + mp_raise_ValueError(translate("Tile height must exactly divide bitmap height")); + } + + int16_t x = args[ARG_x].u_int; + int16_t y = args[ARG_y].u_int; + + displayio_tilegrid_t *self = m_new_obj(displayio_tilegrid_t); + self->base.type = &displayio_tilegrid_type; + common_hal_displayio_tilegrid_construct(self, native, + bitmap_width / tile_width, bitmap_height / tile_height, + pixel_shader, args[ARG_width].u_int, args[ARG_height].u_int, + tile_width, tile_height, x, y, args[ARG_default_tile].u_int); + return MP_OBJ_FROM_PTR(self); +} + +// Helper to ensure we have the native super class instead of a subclass. +static displayio_tilegrid_t* native_tilegrid(mp_obj_t tilegrid_obj) { + mp_obj_t native_tilegrid = mp_instance_cast_to_native_base(tilegrid_obj, &displayio_tilegrid_type); + mp_obj_assert_native_inited(native_tilegrid); + return MP_OBJ_TO_PTR(native_tilegrid); +} + +//| .. attribute:: x +//| +//| X position of the left edge in the parent. +//| +STATIC mp_obj_t displayio_tilegrid_obj_get_x(mp_obj_t self_in) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_tilegrid_get_x(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_x_obj, displayio_tilegrid_obj_get_x); + +STATIC mp_obj_t displayio_tilegrid_obj_set_x(mp_obj_t self_in, mp_obj_t x_obj) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + + mp_int_t x = mp_obj_get_int(x_obj); + common_hal_displayio_tilegrid_set_x(self, x); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_x_obj, displayio_tilegrid_obj_set_x); + +const mp_obj_property_t displayio_tilegrid_x_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_tilegrid_get_x_obj, + (mp_obj_t)&displayio_tilegrid_set_x_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: y +//| +//| Y position of the top edge in the parent. +//| +STATIC mp_obj_t displayio_tilegrid_obj_get_y(mp_obj_t self_in) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_tilegrid_get_y(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_y_obj, displayio_tilegrid_obj_get_y); + +STATIC mp_obj_t displayio_tilegrid_obj_set_y(mp_obj_t self_in, mp_obj_t y_obj) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + + mp_int_t y = mp_obj_get_int(y_obj); + common_hal_displayio_tilegrid_set_y(self, y); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_y_obj, displayio_tilegrid_obj_set_y); + +const mp_obj_property_t displayio_tilegrid_y_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_tilegrid_get_y_obj, + (mp_obj_t)&displayio_tilegrid_set_y_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: flip_x +//| +//| If true, the left edge rendered will be the right edge of the right-most tile. +//| +STATIC mp_obj_t displayio_tilegrid_obj_get_flip_x(mp_obj_t self_in) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + return mp_obj_new_bool(common_hal_displayio_tilegrid_get_flip_x(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_flip_x_obj, displayio_tilegrid_obj_get_flip_x); + +STATIC mp_obj_t displayio_tilegrid_obj_set_flip_x(mp_obj_t self_in, mp_obj_t flip_x_obj) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + + common_hal_displayio_tilegrid_set_flip_x(self, mp_obj_is_true(flip_x_obj)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_flip_x_obj, displayio_tilegrid_obj_set_flip_x); + +const mp_obj_property_t displayio_tilegrid_flip_x_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_tilegrid_get_flip_x_obj, + (mp_obj_t)&displayio_tilegrid_set_flip_x_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: flip_y +//| +//| If true, the top edge rendered will be the bottom edge of the bottom-most tile. +//| +STATIC mp_obj_t displayio_tilegrid_obj_get_flip_y(mp_obj_t self_in) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + return mp_obj_new_bool(common_hal_displayio_tilegrid_get_flip_y(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_flip_y_obj, displayio_tilegrid_obj_get_flip_y); + +STATIC mp_obj_t displayio_tilegrid_obj_set_flip_y(mp_obj_t self_in, mp_obj_t flip_y_obj) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + + common_hal_displayio_tilegrid_set_flip_y(self, mp_obj_is_true(flip_y_obj)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_flip_y_obj, displayio_tilegrid_obj_set_flip_y); + +const mp_obj_property_t displayio_tilegrid_flip_y_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_tilegrid_get_flip_y_obj, + (mp_obj_t)&displayio_tilegrid_set_flip_y_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +//| .. attribute:: transpose_xy +//| +//| If true, the TileGrid's axis will be swapped. When combined with mirroring, any 90 degree +//| rotation can be achieved along with the corresponding mirrored version. +//| +STATIC mp_obj_t displayio_tilegrid_obj_get_transpose_xy(mp_obj_t self_in) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + return mp_obj_new_bool(common_hal_displayio_tilegrid_get_transpose_xy(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_transpose_xy_obj, displayio_tilegrid_obj_get_transpose_xy); + +STATIC mp_obj_t displayio_tilegrid_obj_set_transpose_xy(mp_obj_t self_in, mp_obj_t transpose_xy_obj) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + + common_hal_displayio_tilegrid_set_transpose_xy(self, mp_obj_is_true(transpose_xy_obj)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_transpose_xy_obj, displayio_tilegrid_obj_set_transpose_xy); + +const mp_obj_property_t displayio_tilegrid_transpose_xy_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_tilegrid_get_transpose_xy_obj, + (mp_obj_t)&displayio_tilegrid_set_transpose_xy_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: pixel_shader +//| +//| The pixel shader of the tilegrid. +//| +STATIC mp_obj_t displayio_tilegrid_obj_get_pixel_shader(mp_obj_t self_in) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + return common_hal_displayio_tilegrid_get_pixel_shader(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_pixel_shader_obj, displayio_tilegrid_obj_get_pixel_shader); + +STATIC mp_obj_t displayio_tilegrid_obj_set_pixel_shader(mp_obj_t self_in, mp_obj_t pixel_shader) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + if (!MP_OBJ_IS_TYPE(pixel_shader, &displayio_palette_type) && !MP_OBJ_IS_TYPE(pixel_shader, &displayio_colorconverter_type)) { + mp_raise_TypeError(translate("pixel_shader must be displayio.Palette or displayio.ColorConverter")); + } + + common_hal_displayio_tilegrid_set_pixel_shader(self, pixel_shader); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_pixel_shader_obj, displayio_tilegrid_obj_set_pixel_shader); + +const mp_obj_property_t displayio_tilegrid_pixel_shader_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_tilegrid_get_pixel_shader_obj, + (mp_obj_t)&displayio_tilegrid_set_pixel_shader_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: __getitem__(index) +//| +//| Returns the tile index at the given index. The index can either be an x,y tuple or an int equal +//| to ``y * width + x``. +//| +//| This allows you to:: +//| +//| print(grid[0]) +//| +//| .. method:: __setitem__(index, tile_index) +//| +//| Sets the tile index at the given index. The index can either be an x,y tuple or an int equal +//| to ``y * width + x``. +//| +//| This allows you to:: +//| +//| grid[0] = 10 +//| +//| or:: +//| +//| grid[0,0] = 10 +//| +STATIC mp_obj_t tilegrid_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + + + if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) { + mp_raise_NotImplementedError(translate("Slices not supported")); + } else { + uint16_t x = 0; + uint16_t y = 0; + if (MP_OBJ_IS_SMALL_INT(index_obj)) { + mp_int_t i = MP_OBJ_SMALL_INT_VALUE(index_obj); + uint16_t width = common_hal_displayio_tilegrid_get_width(self); + x = i % width; + y = i / width; + } else { + mp_obj_t* items; + mp_obj_get_array_fixed_n(index_obj, 2, &items); + x = mp_obj_get_int(items[0]); + y = mp_obj_get_int(items[1]); + } + if (x >= common_hal_displayio_tilegrid_get_width(self) || + y >= common_hal_displayio_tilegrid_get_height(self)) { + mp_raise_IndexError(translate("Tile index out of bounds")); + } + + if (value_obj == MP_OBJ_SENTINEL) { + // load + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_tilegrid_get_tile(self, x, y)); + } else if (value_obj == mp_const_none) { + return MP_OBJ_NULL; // op not supported + } else { + mp_int_t value = mp_obj_get_int(value_obj); + if (value < 0 || value > 255) { + mp_raise_ValueError(translate("Tile value out of bounds")); + } + common_hal_displayio_tilegrid_set_tile(self, x, y, value); + } + } + return mp_const_none; +} + +STATIC const mp_rom_map_elem_t displayio_tilegrid_locals_dict_table[] = { + // Properties + { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&displayio_tilegrid_x_obj) }, + { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&displayio_tilegrid_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_flip_x), MP_ROM_PTR(&displayio_tilegrid_flip_x_obj) }, + { MP_ROM_QSTR(MP_QSTR_flip_y), MP_ROM_PTR(&displayio_tilegrid_flip_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_transpose_xy), MP_ROM_PTR(&displayio_tilegrid_transpose_xy_obj) }, + { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&displayio_tilegrid_pixel_shader_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_tilegrid_locals_dict, displayio_tilegrid_locals_dict_table); + +const mp_obj_type_t displayio_tilegrid_type = { + { &mp_type_type }, + .name = MP_QSTR_TileGrid, + .make_new = displayio_tilegrid_make_new, + .subscr = tilegrid_subscr, + .locals_dict = (mp_obj_dict_t*)&displayio_tilegrid_locals_dict, +}; diff --git a/shared-bindings/displayio/TileGrid.h b/shared-bindings/displayio/TileGrid.h new file mode 100644 index 00000000000..8227abfd37d --- /dev/null +++ b/shared-bindings/displayio/TileGrid.h @@ -0,0 +1,63 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_TILEGRID_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_TILEGRID_H + +#include "shared-module/displayio/TileGrid.h" + +extern const mp_obj_type_t displayio_tilegrid_type; + +void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_t bitmap, + uint16_t bitmap_width_in_tiles, uint16_t bitmap_height_in_tiles, + mp_obj_t pixel_shader, uint16_t width, uint16_t height, + uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint8_t default_tile); + +mp_int_t common_hal_displayio_tilegrid_get_x(displayio_tilegrid_t *self); +void common_hal_displayio_tilegrid_set_x(displayio_tilegrid_t *self, mp_int_t x); +mp_int_t common_hal_displayio_tilegrid_get_y(displayio_tilegrid_t *self); +void common_hal_displayio_tilegrid_set_y(displayio_tilegrid_t *self, mp_int_t y); +mp_obj_t common_hal_displayio_tilegrid_get_pixel_shader(displayio_tilegrid_t *self); +void common_hal_displayio_tilegrid_set_pixel_shader(displayio_tilegrid_t *self, mp_obj_t pixel_shader); + + +bool common_hal_displayio_tilegrid_get_flip_x(displayio_tilegrid_t *self); +void common_hal_displayio_tilegrid_set_flip_x(displayio_tilegrid_t *self, bool flip_x); +bool common_hal_displayio_tilegrid_get_flip_y(displayio_tilegrid_t *self); +void common_hal_displayio_tilegrid_set_flip_y(displayio_tilegrid_t *self, bool flip_y); +bool common_hal_displayio_tilegrid_get_transpose_xy(displayio_tilegrid_t *self); +void common_hal_displayio_tilegrid_set_transpose_xy(displayio_tilegrid_t *self, bool transpose_xy); + +uint16_t common_hal_displayio_tilegrid_get_width(displayio_tilegrid_t *self); +uint16_t common_hal_displayio_tilegrid_get_height(displayio_tilegrid_t *self); + +uint8_t common_hal_displayio_tilegrid_get_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y); +void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint8_t tile_index); + +// Private API for scrolling the TileGrid. +void common_hal_displayio_tilegrid_set_top_left(displayio_tilegrid_t *self, uint16_t x, uint16_t y); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_TILEGRID_H diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c new file mode 100644 index 00000000000..f7832559307 --- /dev/null +++ b/shared-bindings/displayio/__init__.c @@ -0,0 +1,115 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/displayio/__init__.h" +#include "shared-bindings/displayio/Bitmap.h" +#include "shared-bindings/displayio/ColorConverter.h" +#include "shared-bindings/displayio/Display.h" +#include "shared-bindings/displayio/EPaperDisplay.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/displayio/I2CDisplay.h" +#include "shared-bindings/displayio/OnDiskBitmap.h" +#include "shared-bindings/displayio/Palette.h" +#include "shared-bindings/displayio/ParallelBus.h" +#include "shared-bindings/displayio/Shape.h" +#include "shared-bindings/displayio/TileGrid.h" + +//| :mod:`displayio` --- Native display driving +//| ========================================================================= +//| +//| .. module:: displayio +//| :synopsis: Native helpers for driving displays +//| :platform: SAMD21, SAMD51, nRF52 +//| +//| The `displayio` module contains classes to manage display output +//| including synchronizing with refresh rates and partial updating. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Bitmap +//| ColorConverter +//| Display +//| EPaperDisplay +//| FourWire +//| Group +//| I2CDisplay +//| OnDiskBitmap +//| Palette +//| ParallelBus +//| Shape +//| TileGrid +//| + + +//| .. function:: release_displays() +//| +//| Releases any actively used displays so their busses and pins can be used again. This will also +//| release the builtin display on boards that have one. You will need to reinitialize it yourself +//| afterwards. This may take seconds to complete if an active EPaperDisplay is refreshing. +//| +//| Use this once in your code.py if you initialize a display. Place it right before the +//| initialization so the display is active as long as possible. +//| +STATIC mp_obj_t displayio_release_displays(void) { + common_hal_displayio_release_displays(); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(displayio_release_displays_obj, displayio_release_displays); + +STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_displayio) }, + { MP_ROM_QSTR(MP_QSTR_Bitmap), MP_ROM_PTR(&displayio_bitmap_type) }, + { MP_ROM_QSTR(MP_QSTR_ColorConverter), MP_ROM_PTR(&displayio_colorconverter_type) }, + { MP_ROM_QSTR(MP_QSTR_Display), MP_ROM_PTR(&displayio_display_type) }, + { MP_ROM_QSTR(MP_QSTR_EPaperDisplay), MP_ROM_PTR(&displayio_epaperdisplay_type) }, + { MP_ROM_QSTR(MP_QSTR_Group), MP_ROM_PTR(&displayio_group_type) }, + { MP_ROM_QSTR(MP_QSTR_OnDiskBitmap), MP_ROM_PTR(&displayio_ondiskbitmap_type) }, + { MP_ROM_QSTR(MP_QSTR_Palette), MP_ROM_PTR(&displayio_palette_type) }, + { MP_ROM_QSTR(MP_QSTR_Shape), MP_ROM_PTR(&displayio_shape_type) }, + { MP_ROM_QSTR(MP_QSTR_TileGrid), MP_ROM_PTR(&displayio_tilegrid_type) }, + + { MP_ROM_QSTR(MP_QSTR_FourWire), MP_ROM_PTR(&displayio_fourwire_type) }, + { MP_ROM_QSTR(MP_QSTR_I2CDisplay), MP_ROM_PTR(&displayio_i2cdisplay_type) }, + { MP_ROM_QSTR(MP_QSTR_ParallelBus), MP_ROM_PTR(&displayio_parallelbus_type) }, + + { MP_ROM_QSTR(MP_QSTR_release_displays), MP_ROM_PTR(&displayio_release_displays_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(displayio_module_globals, displayio_module_globals_table); + +const mp_obj_module_t displayio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&displayio_module_globals, +}; diff --git a/shared-bindings/displayio/__init__.h b/shared-bindings/displayio/__init__.h new file mode 100644 index 00000000000..122b1fbcbee --- /dev/null +++ b/shared-bindings/displayio/__init__.h @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H + +#include "py/obj.h" + +typedef enum { + DISPLAY_COMMAND, + DISPLAY_DATA +} display_byte_type_t; + + +typedef enum { + CHIP_SELECT_UNTOUCHED, + CHIP_SELECT_TOGGLE_EVERY_BYTE +} display_chip_select_behavior_t; + +typedef bool (*display_bus_bus_reset)(mp_obj_t bus); +typedef bool (*display_bus_bus_free)(mp_obj_t bus); +typedef bool (*display_bus_begin_transaction)(mp_obj_t bus); +typedef void (*display_bus_send)(mp_obj_t bus, display_byte_type_t byte_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length); +typedef void (*display_bus_end_transaction)(mp_obj_t bus); + +void common_hal_displayio_release_displays(void); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H diff --git a/shared-bindings/fontio/BuiltinFont.c b/shared-bindings/fontio/BuiltinFont.c new file mode 100644 index 00000000000..74bc4d29ea2 --- /dev/null +++ b/shared-bindings/fontio/BuiltinFont.c @@ -0,0 +1,110 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/fontio/BuiltinFont.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: fontio +//| +//| :class:`BuiltinFont` -- A font built into CircuitPython +//| ========================================================================================= +//| +//| A font built into CircuitPython. +//| +//| .. class:: BuiltinFont() +//| +//| Creation not supported. Available fonts are defined when CircuitPython is built. See the +//| `Adafruit_CircuitPython_Bitmap_Font `_ +//| library for dynamically loaded fonts. +//| + +//| .. attribute:: bitmap +//| +//| Bitmap containing all font glyphs starting with ASCII and followed by unicode. Use +//| `get_glyph` in most cases. This is useful for use with `displayio.TileGrid` and +//| `terminalio.Terminal`. +//| +STATIC mp_obj_t fontio_builtinfont_obj_get_bitmap(mp_obj_t self_in) { + fontio_builtinfont_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_fontio_builtinfont_get_bitmap(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(fontio_builtinfont_get_bitmap_obj, fontio_builtinfont_obj_get_bitmap); + +const mp_obj_property_t fontio_builtinfont_bitmap_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&fontio_builtinfont_get_bitmap_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: get_bounding_box() +//| +//| Returns the maximum bounds of all glyphs in the font in a tuple of two values: width, height. +//| +STATIC mp_obj_t fontio_builtinfont_obj_get_bounding_box(mp_obj_t self_in) { + fontio_builtinfont_t *self = MP_OBJ_TO_PTR(self_in); + + return common_hal_fontio_builtinfont_get_bounding_box(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(fontio_builtinfont_get_bounding_box_obj, fontio_builtinfont_obj_get_bounding_box); + + +//| .. method:: get_glyph(codepoint) +//| +//| Returns a `fontio.Glyph` for the given codepoint or None if no glyph is available. +//| +STATIC mp_obj_t fontio_builtinfont_obj_get_glyph(mp_obj_t self_in, mp_obj_t codepoint_obj) { + fontio_builtinfont_t *self = MP_OBJ_TO_PTR(self_in); + + mp_int_t codepoint; + if (!mp_obj_get_int_maybe(codepoint_obj, &codepoint)) { + mp_raise_ValueError_varg(translate("%q should be an int"), MP_QSTR_codepoint); + } + return common_hal_fontio_builtinfont_get_glyph(self, codepoint); +} +MP_DEFINE_CONST_FUN_OBJ_2(fontio_builtinfont_get_glyph_obj, fontio_builtinfont_obj_get_glyph); + +STATIC const mp_rom_map_elem_t fontio_builtinfont_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_bitmap), MP_ROM_PTR(&fontio_builtinfont_bitmap_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_bounding_box), MP_ROM_PTR(&fontio_builtinfont_get_bounding_box_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_glyph), MP_ROM_PTR(&fontio_builtinfont_get_glyph_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(fontio_builtinfont_locals_dict, fontio_builtinfont_locals_dict_table); + +const mp_obj_type_t fontio_builtinfont_type = { + { &mp_type_type }, + .name = MP_QSTR_BuiltinFont, + .locals_dict = (mp_obj_dict_t*)&fontio_builtinfont_locals_dict, +}; diff --git a/shared-bindings/fontio/BuiltinFont.h b/shared-bindings/fontio/BuiltinFont.h new file mode 100644 index 00000000000..e87445e6b2c --- /dev/null +++ b/shared-bindings/fontio/BuiltinFont.h @@ -0,0 +1,38 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO_BUILTINFONT_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO_BUILTINFONT_H + +#include "shared-module/fontio/BuiltinFont.h" + +extern const mp_obj_type_t fontio_builtinfont_type; + +mp_obj_t common_hal_fontio_builtinfont_get_bitmap(const fontio_builtinfont_t *self); +mp_obj_t common_hal_fontio_builtinfont_get_bounding_box(const fontio_builtinfont_t *self); +mp_obj_t common_hal_fontio_builtinfont_get_glyph(const fontio_builtinfont_t *self, mp_uint_t codepoint); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO_BUILTINFONT_H diff --git a/shared-bindings/fontio/Glyph.c b/shared-bindings/fontio/Glyph.c new file mode 100644 index 00000000000..a2328415217 --- /dev/null +++ b/shared-bindings/fontio/Glyph.c @@ -0,0 +1,75 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/fontio/Glyph.h" + +#include + +//| .. currentmodule:: fontio +//| +//| :class:`Glyph` -- Storage of glyph info +//| ========================================================================== +//| +//| .. class:: Glyph(bitmap, tile_index, width, height, dx, dy, shift_x, shift_y) +//| +//| Named tuple used to capture a single glyph and its attributes. +//| +//| :param displayio.Bitmap bitmap: the bitmap including the glyph +//| :param int tile_index: the tile index within the bitmap +//| :param int width: the width of the glyph's bitmap +//| :param int height: the height of the glyph's bitmap +//| :param int dx: x adjustment to the bitmap's position +//| :param int dy: y adjustment to the bitmap's position +//| :param int shift_x: the x difference to the next glyph +//| :param int shift_y: the y difference to the next glyph +//| +const mp_obj_namedtuple_type_t fontio_glyph_type = { + .base = { + .base = { + .type = &mp_type_type + }, + .name = MP_QSTR_Glyph, + .print = namedtuple_print, + .make_new = namedtuple_make_new, + .unary_op = mp_obj_tuple_unary_op, + .binary_op = mp_obj_tuple_binary_op, + .attr = namedtuple_attr, + .subscr = mp_obj_tuple_subscr, + .getiter = mp_obj_tuple_getiter, + .parent = &mp_type_tuple, + }, + .n_fields = 8, + .fields = { + MP_QSTR_bitmap, + MP_QSTR_tile_index, + MP_QSTR_width, + MP_QSTR_height, + MP_QSTR_dx, + MP_QSTR_dy, + MP_QSTR_shift_x, + MP_QSTR_shift_y + }, +}; diff --git a/shared-bindings/fontio/Glyph.h b/shared-bindings/fontio/Glyph.h new file mode 100644 index 00000000000..c58d812dd87 --- /dev/null +++ b/shared-bindings/fontio/Glyph.h @@ -0,0 +1,34 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO_GLYPH_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO_GLYPH_H + +#include "py/objnamedtuple.h" + +extern const mp_obj_namedtuple_type_t fontio_glyph_type; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO_GLYPH_H diff --git a/shared-bindings/fontio/__init__.c b/shared-bindings/fontio/__init__.c new file mode 100644 index 00000000000..cd0f5ab0f82 --- /dev/null +++ b/shared-bindings/fontio/__init__.c @@ -0,0 +1,65 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/fontio/__init__.h" +#include "shared-bindings/fontio/BuiltinFont.h" +#include "shared-bindings/fontio/Glyph.h" + +//| :mod:`fontio` --- Core font related data structures +//| ========================================================================= +//| +//| .. module:: fontio +//| :synopsis: Core font related data structures +//| :platform: SAMD21, SAMD51, nRF52 +//| +//| The `fontio` module contains classes to store font related information. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| BuiltinFont +//| Glyph +//| + +STATIC const mp_rom_map_elem_t fontio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_fontio) }, + { MP_ROM_QSTR(MP_QSTR_BuiltinFont), MP_ROM_PTR(&fontio_builtinfont_type) }, + { MP_ROM_QSTR(MP_QSTR_Glyph), MP_ROM_PTR(&fontio_glyph_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(fontio_module_globals, fontio_module_globals_table); + +const mp_obj_module_t fontio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&fontio_module_globals, +}; diff --git a/shared-bindings/fontio/__init__.h b/shared-bindings/fontio/__init__.h new file mode 100644 index 00000000000..209919777db --- /dev/null +++ b/shared-bindings/fontio/__init__.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO___INIT___H + + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO___INIT___H diff --git a/shared-bindings/frequencyio/FrequencyIn.c b/shared-bindings/frequencyio/FrequencyIn.c new file mode 100644 index 00000000000..e2b924c0795 --- /dev/null +++ b/shared-bindings/frequencyio/FrequencyIn.c @@ -0,0 +1,247 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Michael Schroeder + * + * 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 + +#include "lib/utils/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/runtime0.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/frequencyio/FrequencyIn.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: frequencyio +//| +//| :class:`FrequencyIn` -- Read a frequency signal +//| ======================================================== +//| +//| FrequencyIn is used to measure the frequency, in hertz, of a digital signal +//| on an incoming pin. Accuracy has shown to be within 10%, if not better. It +//| is recommended to utilize an average of multiple samples to smooth out readings. +//| +//| Frequencies below 1KHz are not currently detectable. +//| +//| FrequencyIn will not determine pulse width (use ``PulseIn``). +//| +//| .. class:: FrequencyIn(pin, capture_period=10) +//| +//| Create a FrequencyIn object associated with the given pin. +//| +//| :param ~microcontroller.Pin pin: Pin to read frequency from. +//| :param int capture_period: Keyword argument to set the measurement period, in +//| milliseconds. Default is 10ms; range is 1ms - 500ms. +//| +//| Read the incoming frequency from a pin:: +//| +//| import frequencyio +//| import board +//| +//| frequency = frequencyio.FrequencyIn(board.D11) +//| +//| # Loop while printing the detected frequency +//| while True: +//| print(frequency.value) +//| +//| # Optional clear() will reset the value +//| # to zero. Without this, if the incoming +//| # signal stops, the last reading will remain +//| # as the value. +//| frequency.clear() +//| +STATIC mp_obj_t frequencyio_frequencyin_make_new(const mp_obj_type_t *type, size_t n_args, + const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, true); + + frequencyio_frequencyin_obj_t *self = m_new_obj(frequencyio_frequencyin_obj_t); + self->base.type = &frequencyio_frequencyin_type; + enum { ARG_pin, ARG_capture_period }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_capture_period, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 10} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + assert_pin(args[ARG_pin].u_obj, false); + mcu_pin_obj_t* pin = MP_OBJ_TO_PTR(args[ARG_pin].u_obj); + assert_pin_free(pin); + + const uint16_t capture_period = args[ARG_capture_period].u_int; + + common_hal_frequencyio_frequencyin_construct(self, pin, capture_period); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialises the FrequencyIn and releases any hardware resources for reuse. +//| +STATIC mp_obj_t frequencyio_frequencyin_deinit(mp_obj_t self_in) { + frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_frequencyio_frequencyin_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_deinit_obj, frequencyio_frequencyin_deinit); + +STATIC void check_for_deinit(frequencyio_frequencyin_obj_t *self) { + if (common_hal_frequencyio_frequencyin_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t frequencyio_frequencyin_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_frequencyio_frequencyin_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(frequencyio_frequencyin___exit___obj, 4, 4, frequencyio_frequencyin_obj___exit__); + +//| .. method:: pause() +//| +//| Pause frequency capture. +//| +STATIC mp_obj_t frequencyio_frequencyin_obj_pause(mp_obj_t self_in) { + frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + common_hal_frequencyio_frequencyin_pause(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_pause_obj, frequencyio_frequencyin_obj_pause); + +//| .. method:: resume() +//| +//| Resumes frequency capture. +//| +STATIC mp_obj_t frequencyio_frequencyin_obj_resume(mp_obj_t self_in) { + frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + common_hal_frequencyio_frequencyin_resume(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_resume_obj, frequencyio_frequencyin_obj_resume); + +//| .. method:: clear() +//| +//| Clears the last detected frequency capture value. +//| + +STATIC mp_obj_t frequencyio_frequencyin_obj_clear(mp_obj_t self_in) { + frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + common_hal_frequencyio_frequencyin_clear(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_clear_obj, frequencyio_frequencyin_obj_clear); + +//| .. attribute:: capture_period +//| +//| The capture measurement period. Lower incoming frequencies will be measured +//| more accurately with longer capture periods. Higher frequencies are more +//| accurate with shorter capture periods. +//| +//| .. note:: When setting a new ``capture_period``, all previous capture information is +//| cleared with a call to ``clear()``. +//| +STATIC mp_obj_t frequencyio_frequencyin_obj_get_capture_period(mp_obj_t self_in) { + frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + return MP_OBJ_NEW_SMALL_INT(common_hal_frequencyio_frequencyin_get_capture_period(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequency_get_capture_period_obj, frequencyio_frequencyin_obj_get_capture_period); + +STATIC mp_obj_t frequencyio_frequencyin_obj_set_capture_period(mp_obj_t self_in, mp_obj_t capture_period) { + frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + common_hal_frequencyio_frequencyin_set_capture_period(self, mp_obj_get_int(capture_period)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(frequencyio_frequency_set_capture_period_obj, frequencyio_frequencyin_obj_set_capture_period); + +const mp_obj_property_t frequencyio_frequencyin_capture_period_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&frequencyio_frequency_get_capture_period_obj, + (mp_obj_t)&frequencyio_frequency_set_capture_period_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: __get__(index) +//| +//| Returns the value of the last frequency captured. +//| +STATIC mp_obj_t frequencyio_frequencyin_obj_get_value(mp_obj_t self_in) { + frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + //return MP_OBJ_NEW_SMALL_INT(common_hal_frequencyio_frequencyin_get_item(self)); + return mp_obj_new_int_from_float(common_hal_frequencyio_frequencyin_get_item(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_get_value_obj, frequencyio_frequencyin_obj_get_value); + +const mp_obj_property_t frequencyio_frequencyin_value_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&frequencyio_frequencyin_get_value_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t frequencyio_frequencyin_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&frequencyio_frequencyin_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&frequencyio_frequencyin___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&frequencyio_frequencyin_value_obj) }, + { MP_ROM_QSTR(MP_QSTR_pause), MP_ROM_PTR(&frequencyio_frequencyin_pause_obj) }, + { MP_ROM_QSTR(MP_QSTR_resume), MP_ROM_PTR(&frequencyio_frequencyin_resume_obj) }, + { MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&frequencyio_frequencyin_clear_obj) }, + { MP_ROM_QSTR(MP_QSTR_capture_period), MP_ROM_PTR(&frequencyio_frequencyin_capture_period_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(frequencyio_frequencyin_locals_dict, frequencyio_frequencyin_locals_dict_table); + +const mp_obj_type_t frequencyio_frequencyin_type = { + { &mp_type_type }, + .name = MP_QSTR_frequencyin, + .make_new = frequencyio_frequencyin_make_new, + .locals_dict = (mp_obj_dict_t*)&frequencyio_frequencyin_locals_dict, +}; diff --git a/shared-bindings/frequencyio/FrequencyIn.h b/shared-bindings/frequencyio/FrequencyIn.h new file mode 100644 index 00000000000..dba6c3a6612 --- /dev/null +++ b/shared-bindings/frequencyio/FrequencyIn.h @@ -0,0 +1,46 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Michael Schroeder + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_FREQUENCYIO_FREQUENCYIN_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_FREQUENCYIO_FREQUENCYIN_H + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/frequencyio/FrequencyIn.h" + +extern const mp_obj_type_t frequencyio_frequencyin_type; + +extern void common_hal_frequencyio_frequencyin_construct(frequencyio_frequencyin_obj_t *self, + const mcu_pin_obj_t *pin, uint16_t capture_period); +extern void common_hal_frequencyio_frequencyin_deinit(frequencyio_frequencyin_obj_t *self); +extern bool common_hal_frequencyio_frequencyin_deinited(frequencyio_frequencyin_obj_t *self); +extern void common_hal_frequencyio_frequencyin_pause(frequencyio_frequencyin_obj_t *self); +extern void common_hal_frequencyio_frequencyin_resume(frequencyio_frequencyin_obj_t *self); +extern void common_hal_frequencyio_frequencyin_clear(frequencyio_frequencyin_obj_t *self); +extern uint32_t common_hal_frequencyio_frequencyin_get_item(frequencyio_frequencyin_obj_t *self); +extern uint16_t common_hal_frequencyio_frequencyin_get_capture_period(frequencyio_frequencyin_obj_t *self); +extern void common_hal_frequencyio_frequencyin_set_capture_period(frequencyio_frequencyin_obj_t *self, uint16_t capture_period); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_FREQUENCYIO_FREQUENCYIN_H diff --git a/shared-bindings/frequencyio/__init__.c b/shared-bindings/frequencyio/__init__.c new file mode 100644 index 00000000000..48a02682492 --- /dev/null +++ b/shared-bindings/frequencyio/__init__.c @@ -0,0 +1,89 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Michael Schroeder + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/frequencyio/__init__.h" +#include "shared-bindings/frequencyio/FrequencyIn.h" + +//| :mod:`frequencyio` --- Support for frequency based protocols +//| ============================================================= +//| +//| .. module:: frequencyio +//| :synopsis: Support for frequency based protocols +//| :platform: SAMD51 +//| +//| The `frequencyio` module contains classes to provide access to basic frequency IO. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| FrequencyIn +//| + +//| .. warning:: This module is not available in SAMD21 builds. See the +//| :ref:`module-support-matrix` for more info. +//| + +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed if the program continues after use. To do so, either +//| call :py:meth:`!deinit` or use a context manager. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +//| For example:: +//| +//| import frequencyio +//| import time +//| from board import * +//| +//| frequency = frequencyio.FrequencyIn(D13) +//| frequency.capture_period = 15 +//| time.sleep(0.1) +//| +//| This example will initialize the the device, set +//| :py:data:`~frequencyio.FrequencyIn.capture_period`, and then sleep 0.1 seconds. +//| CircuitPython will automatically turn off FrequencyIn capture when it resets all +//| hardware after program completion. Use ``deinit()`` or a ``with`` statement +//| to do it yourself. +//| + +STATIC const mp_rom_map_elem_t frequencyio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_frequencyio) }, + { MP_ROM_QSTR(MP_QSTR_FrequencyIn), MP_ROM_PTR(&frequencyio_frequencyin_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(frequencyio_module_globals, frequencyio_module_globals_table); + +const mp_obj_module_t frequencyio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&frequencyio_module_globals, +}; diff --git a/shared-bindings/frequencyio/__init__.h b/shared-bindings/frequencyio/__init__.h new file mode 100644 index 00000000000..39157659440 --- /dev/null +++ b/shared-bindings/frequencyio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Michael Schroeder + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_FREQUENCYIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_FREQUENCYIO___INIT___H + +#include "py/obj.h" + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_FREQUENCYIO___INIT___H diff --git a/shared-bindings/gamepad/GamePad.c b/shared-bindings/gamepad/GamePad.c new file mode 100644 index 00000000000..d3c29019a5f --- /dev/null +++ b/shared-bindings/gamepad/GamePad.c @@ -0,0 +1,157 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski for Adafruit Industries + * + * 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 "shared-bindings/gamepad/GamePad.h" + +#include "py/obj.h" +#include "py/runtime.h" +#include "py/mphal.h" +#include "py/gc.h" +#include "py/mpstate.h" +#include "shared-bindings/gamepad/__init__.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "supervisor/shared/translate.h" + + +//| .. currentmodule:: gamepad +//| +//| :class:`GamePad` -- Scan buttons for presses +//| ============================================ +//| +//| Usage:: +//| +//| import board +//| import digitalio +//| import gamepad +//| import time +//| +//| B_UP = 1 << 0 +//| B_DOWN = 1 << 1 +//| +//| +//| pad = gamepad.GamePad( +//| digitalio.DigitalInOut(board.D10), +//| digitalio.DigitalInOut(board.D11), +//| ) +//| +//| y = 0 +//| while True: +//| buttons = pad.get_pressed() +//| if buttons & B_UP: +//| y -= 1 +//| print(y) +//| elif buttons & B_DOWN: +//| y += 1 +//| print(y) +//| time.sleep(0.1) +//| while buttons: +//| # Wait for all buttons to be released. +//| buttons = pad.get_pressed() +//| time.sleep(0.1) +//| + +//| .. class:: GamePad([b1[, b2[, b3[, b4[, b5[, b6[, b7[, b8]]]]]]]]) +//| +//| Initializes button scanning routines. +//| +//| The ``b1``-``b8`` parameters are ``DigitalInOut`` objects, which +//| immediately get switched to input with a pull-up, (unless they already +//| were set to pull-down, in which case they remain so), and then scanned +//| regularly for button presses. The order is the same as the order of +//| bits returned by the ``get_pressed`` function. You can re-initialize +//| it with different keys, then the new object will replace the previous +//| one. +//| +//| The basic feature required here is the ability to poll the keys at +//| regular intervals (so that de-bouncing is consistent) and fast enough +//| (so that we don't miss short button presses) while at the same time +//| letting the user code run normally, call blocking functions and wait +//| on delays. +//| +//| They button presses are accumulated, until the ``get_pressed`` method +//| is called, at which point the button state is cleared, and the new +//| button presses start to be recorded. +//| +STATIC mp_obj_t gamepad_make_new(const mp_obj_type_t *type, size_t n_args, + const mp_obj_t *args, mp_map_t *kw_args) { + if (n_args > 8 || n_args == 0) { + mp_raise_TypeError(translate("argument num/types mismatch")); + } + for (size_t i = 0; i < n_args; ++i) { + assert_digitalinout(args[i]); + } + gamepad_obj_t* gamepad_singleton = MP_STATE_VM(gamepad_singleton); + if (!gamepad_singleton || + !MP_OBJ_IS_TYPE(MP_OBJ_FROM_PTR(gamepad_singleton), &gamepad_type)) { + gamepad_singleton = m_new_obj(gamepad_obj_t); + gamepad_singleton->base.type = &gamepad_type; + gamepad_singleton = gc_make_long_lived(gamepad_singleton); + MP_STATE_VM(gamepad_singleton) = gamepad_singleton; + } + common_hal_gamepad_gamepad_init(gamepad_singleton, args, n_args); + return MP_OBJ_FROM_PTR(gamepad_singleton); +} + +//| .. method:: get_pressed() +//| +//| Get the status of buttons pressed since the last call and clear it. +//| +//| Returns an 8-bit number, with bits that correspond to buttons, +//| which have been pressed (or held down) since the last call to this +//| function set to 1, and the remaining bits set to 0. Then it clears +//| the button state, so that new button presses (or buttons that are +//| held down) can be recorded for the next call. +//| +STATIC mp_obj_t gamepad_get_pressed(mp_obj_t self_in) { + gamepad_obj_t* gamepad_singleton = MP_STATE_VM(gamepad_singleton); + mp_obj_t pressed = MP_OBJ_NEW_SMALL_INT(gamepad_singleton->pressed); + gamepad_singleton->pressed = gamepad_singleton->last; + return pressed; +} +MP_DEFINE_CONST_FUN_OBJ_1(gamepad_get_pressed_obj, gamepad_get_pressed); + + +//| .. method:: deinit() +//| +//| Disable button scanning. +//| +STATIC mp_obj_t gamepad_deinit(mp_obj_t self_in) { + common_hal_gamepad_gamepad_deinit(self_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(gamepad_deinit_obj, gamepad_deinit); + + +STATIC const mp_rom_map_elem_t gamepad_locals_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_get_pressed), MP_ROM_PTR(&gamepad_get_pressed_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&gamepad_deinit_obj)}, +}; +STATIC MP_DEFINE_CONST_DICT(gamepad_locals_dict, gamepad_locals_dict_table); +const mp_obj_type_t gamepad_type = { + { &mp_type_type }, + .name = MP_QSTR_GamePad, + .make_new = gamepad_make_new, + .locals_dict = (mp_obj_dict_t*)&gamepad_locals_dict, +}; diff --git a/shared-bindings/gamepad/GamePad.h b/shared-bindings/gamepad/GamePad.h new file mode 100644 index 00000000000..3bbad4c97b3 --- /dev/null +++ b/shared-bindings/gamepad/GamePad.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski for Adafruit Industries + * + * 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. + */ + + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPAD_GAMEPAD_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPAD_GAMEPAD_H + +#include "shared-module/gamepad/GamePad.h" + +extern const mp_obj_type_t gamepad_type; + +void common_hal_gamepad_gamepad_init(gamepad_obj_t *gamepad, const mp_obj_t pins[], size_t n_pins); +void common_hal_gamepad_gamepad_deinit(gamepad_obj_t *gamepad); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPAD_GAMEPAD_H diff --git a/shared-bindings/gamepad/__init__.c b/shared-bindings/gamepad/__init__.c new file mode 100644 index 00000000000..cea0b4ee962 --- /dev/null +++ b/shared-bindings/gamepad/__init__.c @@ -0,0 +1,54 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski for Adafruit Industries + * + * 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 "py/obj.h" +#include "py/runtime.h" +#include "py/mphal.h" +#include "shared-bindings/gamepad/GamePad.h" +#include "shared-bindings/util.h" + +//| :mod:`gamepad` --- Button handling +//| ================================== +//| +//| .. module:: gamepad +//| :synopsis: Button handling +//| :platform: SAMD21 +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| GamePad +//| +STATIC const mp_rom_map_elem_t gamepad_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_gamepad) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_GamePad), MP_ROM_PTR(&gamepad_type)}, +}; +STATIC MP_DEFINE_CONST_DICT(gamepad_module_globals, + gamepad_module_globals_table); + +const mp_obj_module_t gamepad_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&gamepad_module_globals, +}; diff --git a/shared-bindings/gamepad/__init__.h b/shared-bindings/gamepad/__init__.h new file mode 100644 index 00000000000..2ae5efb3a03 --- /dev/null +++ b/shared-bindings/gamepad/__init__.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski for Adafruit Industries + * + * 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. + */ + + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPAD___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPAD___INIT___H + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPAD___INIT___H diff --git a/shared-bindings/gamepadshift/GamePadShift.c b/shared-bindings/gamepadshift/GamePadShift.c new file mode 100644 index 00000000000..91203ad20db --- /dev/null +++ b/shared-bindings/gamepadshift/GamePadShift.c @@ -0,0 +1,123 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski for Adafruit Industries + * + * 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 "py/obj.h" +#include "py/runtime.h" +#include "py/mphal.h" +#include "py/gc.h" +#include "py/mpstate.h" +#include "shared-bindings/gamepadshift/GamePadShift.h" +#include "shared-bindings/gamepadshift/__init__.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: gamepadshift +//| +//| :class:`GamePadShift` -- Scan buttons for presses through a shift register +//| =========================================================================== +//| +//| .. class:: GamePadShift(clock, data, latch) +//| +//| Initializes button scanning routines. +//| +//| The ``clock``, ``data`` and ``latch`` parameters are ``DigitalInOut`` +//| objects connected to the shift register controlling the buttons. +//| +//| They button presses are accumulated, until the ``get_pressed`` method +//| is called, at which point the button state is cleared, and the new +//| button presses start to be recorded. +//| +//| Only one gamepad (`gamepad.GamePad` or `gamepadshift.GamePadShift`) +//| may be used at a time. +//| +STATIC mp_obj_t gamepadshift_make_new(const mp_obj_type_t *type, size_t n_args, + const mp_obj_t *pos_args, mp_map_t *kw_args) { + + enum { ARG_clock, ARG_data, ARG_latch }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ}, + { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_latch, MP_ARG_REQUIRED | MP_ARG_OBJ}, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), + allowed_args, args); + + digitalio_digitalinout_obj_t *clock_pin = assert_digitalinout(args[ARG_clock].u_obj); + digitalio_digitalinout_obj_t *data_pin = assert_digitalinout(args[ARG_data].u_obj); + digitalio_digitalinout_obj_t *latch_pin = assert_digitalinout(args[ARG_latch].u_obj); + + gamepadshift_obj_t* gamepad_singleton = MP_STATE_VM(gamepad_singleton); + if (!gamepad_singleton || + !MP_OBJ_IS_TYPE(MP_OBJ_FROM_PTR(gamepad_singleton), + &gamepadshift_type)) { + gamepad_singleton = m_new_obj(gamepadshift_obj_t); + gamepad_singleton->base.type = &gamepadshift_type; + gamepad_singleton = gc_make_long_lived(gamepad_singleton); + MP_STATE_VM(gamepad_singleton) = gamepad_singleton; + } + common_hal_gamepadshift_gamepadshift_init(gamepad_singleton, clock_pin, data_pin, latch_pin); + return MP_OBJ_FROM_PTR(gamepad_singleton); +} + +//| .. method:: get_pressed() +//| +//| Get the status of buttons pressed since the last call and clear it. +//| +//| Returns an 8-bit number, with bits that correspond to buttons, +//| which have been pressed (or held down) since the last call to this +//| function set to 1, and the remaining bits set to 0. Then it clears +//| the button state, so that new button presses (or buttons that are +//| held down) can be recorded for the next call. +//| +STATIC mp_obj_t gamepadshift_get_pressed(mp_obj_t self_in) { + gamepadshift_obj_t* gamepad_singleton = MP_STATE_VM(gamepad_singleton); + mp_obj_t pressed = MP_OBJ_NEW_SMALL_INT(gamepad_singleton->pressed); + gamepad_singleton->pressed = gamepad_singleton->last; + return pressed; +} +MP_DEFINE_CONST_FUN_OBJ_1(gamepadshift_get_pressed_obj, gamepadshift_get_pressed); + +//| .. method:: deinit() +//| +//| Disable button scanning. +//| +STATIC mp_obj_t gamepadshift_deinit(mp_obj_t self_in) { + common_hal_gamepadshift_gamepadshift_deinit(self_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(gamepadshift_deinit_obj, gamepadshift_deinit); + + +STATIC const mp_rom_map_elem_t gamepadshift_locals_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_get_pressed), MP_ROM_PTR(&gamepadshift_get_pressed_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&gamepadshift_deinit_obj)}, +}; +STATIC MP_DEFINE_CONST_DICT(gamepadshift_locals_dict, gamepadshift_locals_dict_table); +const mp_obj_type_t gamepadshift_type = { + { &mp_type_type }, + .name = MP_QSTR_GamePadShift, + .make_new = gamepadshift_make_new, + .locals_dict = (mp_obj_dict_t*)&gamepadshift_locals_dict, +}; diff --git a/shared-bindings/gamepadshift/GamePadShift.h b/shared-bindings/gamepadshift/GamePadShift.h new file mode 100644 index 00000000000..3e8ea9693d5 --- /dev/null +++ b/shared-bindings/gamepadshift/GamePadShift.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski for Adafruit Industries + * + * 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. + */ + + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPADSHIFT_GAMEPADSHIFT_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPADSHIFT_GAMEPADSHIFT_H + +#include "shared-module/gamepadshift/GamePadShift.h" + +extern const mp_obj_type_t gamepadshift_type; + +void common_hal_gamepadshift_gamepadshift_init(gamepadshift_obj_t *gamepadshift, + digitalio_digitalinout_obj_t *clock_pin, + digitalio_digitalinout_obj_t *data_pin, + digitalio_digitalinout_obj_t *latch_pin); + +void common_hal_gamepadshift_gamepadshift_deinit(gamepadshift_obj_t *gamepadshift); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPADSHIFT_GAMEPADSHIFT_H diff --git a/shared-bindings/gamepadshift/__init__.c b/shared-bindings/gamepadshift/__init__.c new file mode 100644 index 00000000000..2d366772603 --- /dev/null +++ b/shared-bindings/gamepadshift/__init__.c @@ -0,0 +1,54 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski for Adafruit Industries + * + * 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 "py/obj.h" +#include "py/runtime.h" +#include "py/mphal.h" +#include "shared-bindings/gamepadshift/GamePadShift.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/util.h" + +//| :mod:`gamepadshift` --- Tracks button presses read through a shift register +//| =========================================================================== +//| +//| .. module:: gamepadshift +//| :synopsis: Tracks button presses read through a shift register +//| :platform: SAMD21, SAMD51 +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| GamePadShift +//| +STATIC const mp_rom_map_elem_t gamepadshift_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_gamepadshift) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_GamePadShift), MP_ROM_PTR(&gamepadshift_type)}, +}; +STATIC MP_DEFINE_CONST_DICT(gamepadshift_module_globals, gamepadshift_module_globals_table); + +const mp_obj_module_t gamepadshift_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&gamepadshift_module_globals, +}; diff --git a/shared-bindings/gamepadshift/__init__.h b/shared-bindings/gamepadshift/__init__.h new file mode 100644 index 00000000000..4b4be756a65 --- /dev/null +++ b/shared-bindings/gamepadshift/__init__.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski for Adafruit Industries + * + * 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. + */ + + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPADSHIFT___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPADSHIFT___INIT___H + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPADSHIFT___INIT___H diff --git a/shared-bindings/help.c b/shared-bindings/help.c new file mode 100644 index 00000000000..4e7c3a78bba --- /dev/null +++ b/shared-bindings/help.c @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +//| :func:`help` - Built-in method to provide helpful information +//| ============================================================== +//| +//| .. function:: help(object=None) +//| +//| Prints a help method about the given object. When ``object`` is none, +//| prints general port information. +//| diff --git a/shared-bindings/i2cslave/I2CSlave.c b/shared-bindings/i2cslave/I2CSlave.c new file mode 100644 index 00000000000..c98ea52e066 --- /dev/null +++ b/shared-bindings/i2cslave/I2CSlave.c @@ -0,0 +1,449 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * 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 "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/i2cslave/I2CSlave.h" +#include "shared-bindings/time/__init__.h" +#include "shared-bindings/util.h" + +#include "lib/utils/buffer_helper.h" +#include "lib/utils/context_manager_helpers.h" +#include "lib/utils/interrupt_char.h" + +#include "py/mperrno.h" +#include "py/mphal.h" +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +STATIC mp_obj_t mp_obj_new_i2cslave_i2c_slave_request(i2cslave_i2c_slave_obj_t *slave, uint8_t address, bool is_read, bool is_restart) { + i2cslave_i2c_slave_request_obj_t *self = m_new_obj(i2cslave_i2c_slave_request_obj_t); + self->base.type = &i2cslave_i2c_slave_request_type; + self->slave = slave; + self->address = address; + self->is_read = is_read; + self->is_restart = is_restart; + return (mp_obj_t)self; +} + +//| .. currentmodule:: i2cslave +//| +//| :class:`I2CSlave` --- Two wire serial protocol slave +//| ---------------------------------------------------- +//| +//| .. class:: I2CSlave(scl, sda, addresses, smbus=False) +//| +//| I2C is a two-wire protocol for communicating between devices. +//| This implements the slave side. +//| +//| :param ~microcontroller.Pin scl: The clock pin +//| :param ~microcontroller.Pin sda: The data pin +//| :param tuple addresses: The I2C addresses to respond to (how many is hw dependent). +//| :param bool smbus: Use SMBUS timings if the hardware supports it +//| +STATIC mp_obj_t i2cslave_i2c_slave_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + i2cslave_i2c_slave_obj_t *self = m_new_obj(i2cslave_i2c_slave_obj_t); + self->base.type = &i2cslave_i2c_slave_type; + enum { ARG_scl, ARG_sda, ARG_addresses, ARG_smbus }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_addresses, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_smbus, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + assert_pin(args[ARG_scl].u_obj, false); + assert_pin(args[ARG_sda].u_obj, false); + const mcu_pin_obj_t* scl = MP_OBJ_TO_PTR(args[ARG_scl].u_obj); + assert_pin_free(scl); + const mcu_pin_obj_t* sda = MP_OBJ_TO_PTR(args[ARG_sda].u_obj); + assert_pin_free(sda); + + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(args[ARG_addresses].u_obj, &iter_buf); + mp_obj_t item; + uint8_t *addresses = NULL; + unsigned int i = 0; + while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + mp_int_t value; + if (!mp_obj_get_int_maybe(item, &value)) { + mp_raise_TypeError(translate("can't convert address to int")); + } + if (value < 0x00 || value > 0x7f) { + mp_raise_ValueError(translate("address out of bounds")); + } + addresses = m_renew(uint8_t, addresses, i, i + 1); + addresses[i++] = value; + } + if (i == 0) { + mp_raise_ValueError(translate("addresses is empty")); + } + + common_hal_i2cslave_i2c_slave_construct(self, scl, sda, addresses, i, args[ARG_smbus].u_bool); + return (mp_obj_t)self; +} + +//| .. method:: deinit() +//| +//| Releases control of the underlying hardware so other classes can use it. +//| +STATIC mp_obj_t i2cslave_i2c_slave_obj_deinit(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cslave_i2c_slave_type)); + i2cslave_i2c_slave_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_i2cslave_i2c_slave_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cslave_i2c_slave_deinit_obj, i2cslave_i2c_slave_obj_deinit); + +//| .. method:: __enter__() +//| +//| No-op used in Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware on context exit. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t i2cslave_i2c_slave_obj___exit__(size_t n_args, const mp_obj_t *args) { + mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cslave_i2c_slave_type)); + i2cslave_i2c_slave_obj_t *self = MP_OBJ_TO_PTR(args[0]); + common_hal_i2cslave_i2c_slave_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cslave_i2c_slave___exit___obj, 4, 4, i2cslave_i2c_slave_obj___exit__); + +//| .. method:: request(timeout=-1) +//| +//| Wait for an I2C request from a master. +//| +//| :param float timeout: Timeout in seconds. Zero means wait forever, a negative value means check once +//| :return: I2C Slave Request or None if timeout=-1 and there's no request +//| :rtype: ~i2cslave.I2CSlaveRequest +//| +STATIC mp_obj_t i2cslave_i2c_slave_request(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_check_self(MP_OBJ_IS_TYPE(pos_args[0], &i2cslave_i2c_slave_type)); + i2cslave_i2c_slave_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + if(common_hal_i2cslave_i2c_slave_deinited(self)) { + raise_deinited_error(); + } + enum { ARG_timeout }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1)} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + #if MICROPY_PY_BUILTINS_FLOAT + float f = mp_obj_get_float(args[ARG_timeout].u_obj) * 1000; + int timeout_ms = (int)f; + #else + int timeout_ms = mp_obj_get_int(args[ARG_timeout].u_obj) * 1000; + #endif + + bool forever = false; + uint64_t timeout_end = 0; + if (timeout_ms == 0) { + forever = true; + } else if (timeout_ms > 0) { + timeout_end = common_hal_time_monotonic() + timeout_ms; + } + + int last_error = 0; + + do { + uint8_t address; + bool is_read; + bool is_restart; + + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + return mp_const_none; + } + + int status = common_hal_i2cslave_i2c_slave_is_addressed(self, &address, &is_read, &is_restart); + if (status < 0) { + // On error try one more time before bailing out + if (last_error) { + mp_raise_OSError(last_error); + } + last_error = -status; + mp_hal_delay_ms(10); + continue; + } + + last_error = 0; + + if (status == 0) { + mp_hal_delay_us(10); + continue; + } + + return mp_obj_new_i2cslave_i2c_slave_request(self, address, is_read, is_restart); + } while (forever || common_hal_time_monotonic() < timeout_end); + + if (timeout_ms > 0) { + mp_raise_OSError(MP_ETIMEDOUT); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(i2cslave_i2c_slave_request_obj, 1, i2cslave_i2c_slave_request); + +STATIC const mp_rom_map_elem_t i2cslave_i2c_slave_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&i2cslave_i2c_slave_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&i2cslave_i2c_slave___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_request), MP_ROM_PTR(&i2cslave_i2c_slave_request_obj) }, + +}; + +STATIC MP_DEFINE_CONST_DICT(i2cslave_i2c_slave_locals_dict, i2cslave_i2c_slave_locals_dict_table); + +const mp_obj_type_t i2cslave_i2c_slave_type = { + { &mp_type_type }, + .name = MP_QSTR_I2CSlave, + .make_new = i2cslave_i2c_slave_make_new, + .locals_dict = (mp_obj_dict_t*)&i2cslave_i2c_slave_locals_dict, +}; + + +//| :class:`I2CSlaveRequest` --- I2C Slave Request +//| ---------------------------------------------- +//| +//| .. class:: I2CSlaveRequest(slave, address, is_read, is_restart) +//| +//| I2C transfer request from a master. +//| This cannot be instantiated directly, but is returned by :py:meth:`I2CSlave.request`. +//| +//| :param ~i2cslave.I2CSlave slave: The I2C Slave receiving this request +//| :param int address: I2C address +//| :param bool is_read: I2C Master read request +//| :param bool is_restart: Repeated Start Condition +//| +STATIC mp_obj_t i2cslave_i2c_slave_request_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 4, 4, false); + return mp_obj_new_i2cslave_i2c_slave_request(args[0], mp_obj_get_int(args[1]), mp_obj_is_true(args[2]), mp_obj_is_true(args[3])); +} + +//| .. method:: __enter__() +//| +//| No-op used in Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Close the request. +//| +STATIC mp_obj_t i2cslave_i2c_slave_request_obj___exit__(size_t n_args, const mp_obj_t *args) { + mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cslave_i2c_slave_request_type)); + i2cslave_i2c_slave_request_obj_t *self = MP_OBJ_TO_PTR(args[0]); + common_hal_i2cslave_i2c_slave_close(self->slave); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cslave_i2c_slave_request___exit___obj, 4, 4, i2cslave_i2c_slave_request_obj___exit__); + +//| .. attribute:: address +//| +//| The I2C address of the request. +//| +STATIC mp_obj_t i2cslave_i2c_slave_request_get_address(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cslave_i2c_slave_request_type)); + i2cslave_i2c_slave_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int(self->address); +} +MP_DEFINE_CONST_PROP_GET(i2cslave_i2c_slave_request_address_obj, i2cslave_i2c_slave_request_get_address); + +//| .. attribute:: is_read +//| +//| The I2C master is reading from the device. +//| +STATIC mp_obj_t i2cslave_i2c_slave_request_get_is_read(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cslave_i2c_slave_request_type)); + i2cslave_i2c_slave_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(self->is_read); +} +MP_DEFINE_CONST_PROP_GET(i2cslave_i2c_slave_request_is_read_obj, i2cslave_i2c_slave_request_get_is_read); + +//| .. attribute:: is_restart +//| +//| Is Repeated Start Condition. +//| +STATIC mp_obj_t i2cslave_i2c_slave_request_get_is_restart(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cslave_i2c_slave_request_type)); + i2cslave_i2c_slave_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(self->is_restart); +} +MP_DEFINE_CONST_PROP_GET(i2cslave_i2c_slave_request_is_restart_obj, i2cslave_i2c_slave_request_get_is_restart); + +//| .. method:: read(n=-1, ack=True) +//| +//| Read data. +//| If ack=False, the caller is responsible for calling :py:meth:`I2CSlaveRequest.ack`. +//| +//| :param int n: Number of bytes to read (negative means all) +//| :param bool ack: Whether or not to send an ACK after the n'th byte +//| :return: Bytes read +//| :rtype: bytearray +//| +STATIC mp_obj_t i2cslave_i2c_slave_request_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_check_self(MP_OBJ_IS_TYPE(pos_args[0], &i2cslave_i2c_slave_request_type)); + i2cslave_i2c_slave_request_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + enum { ARG_n, ARG_ack }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_n, MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_ack, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + if (self->is_read) { + mp_raise_OSError(MP_EACCES); + } + + int n = args[ARG_n].u_int; + if (n == 0) { + return mp_obj_new_bytearray(0, NULL); + } + bool ack = args[ARG_ack].u_bool; + + int i = 0; + uint8_t *buffer = NULL; + uint64_t timeout_end = common_hal_time_monotonic() + 10 * 1000; + while (common_hal_time_monotonic() < timeout_end) { + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + break; + } + + uint8_t data; + int num = common_hal_i2cslave_i2c_slave_read_byte(self->slave, &data); + if (num == 0) { + break; + } + + buffer = m_renew(uint8_t, buffer, i, i + 1); + buffer[i++] = data; + if (i == n) { + if (ack) { + common_hal_i2cslave_i2c_slave_ack(self->slave, true); + } + break; + } + common_hal_i2cslave_i2c_slave_ack(self->slave, true); + } + + return mp_obj_new_bytearray(i, buffer); +} +MP_DEFINE_CONST_FUN_OBJ_KW(i2cslave_i2c_slave_request_read_obj, 1, i2cslave_i2c_slave_request_read); + +//| .. method:: write(buffer) +//| +//| Write the data contained in buffer. +//| +//| :param bytearray buffer: Write out the data in this buffer +//| :return: Number of bytes written +//| +STATIC mp_obj_t i2cslave_i2c_slave_request_write(mp_obj_t self_in, mp_obj_t buf_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cslave_i2c_slave_request_type)); + i2cslave_i2c_slave_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (!self->is_read) { + mp_raise_OSError(MP_EACCES); + } + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); + + for (size_t i = 0; i < bufinfo.len; i++) { + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + break; + } + + int num = common_hal_i2cslave_i2c_slave_write_byte(self->slave, ((uint8_t *)(bufinfo.buf))[i]); + if (num == 0) { + return mp_obj_new_int(i); + } + } + + return mp_obj_new_int(bufinfo.len); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(i2cslave_i2c_slave_request_write_obj, i2cslave_i2c_slave_request_write); + +//| .. method:: ack(ack=True) +//| +//| Acknowledge or Not Acknowledge last byte received. +//| Use together with :py:meth:`I2CSlaveRequest.read` ack=False. +//| +//| :param bool ack: Whether to send an ACK or NACK +//| +STATIC mp_obj_t i2cslave_i2c_slave_request_ack(uint n_args, const mp_obj_t *args) { + mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cslave_i2c_slave_request_type)); + i2cslave_i2c_slave_request_obj_t *self = MP_OBJ_TO_PTR(args[0]); + bool ack = (n_args == 1) ? true : mp_obj_is_true(args[1]); + + if (self->is_read) { + mp_raise_OSError(MP_EACCES); + } + + common_hal_i2cslave_i2c_slave_ack(self->slave, ack); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cslave_i2c_slave_request_ack_obj, 1, 2, i2cslave_i2c_slave_request_ack); + +STATIC mp_obj_t i2cslave_i2c_slave_request_close(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cslave_i2c_slave_request_type)); + i2cslave_i2c_slave_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_i2cslave_i2c_slave_close(self->slave); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(i2cslave_i2c_slave_request_close_obj, i2cslave_i2c_slave_request_close); + +STATIC const mp_rom_map_elem_t i2cslave_i2c_slave_request_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&i2cslave_i2c_slave_request___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&i2cslave_i2c_slave_request_address_obj) }, + { MP_ROM_QSTR(MP_QSTR_is_read), MP_ROM_PTR(&i2cslave_i2c_slave_request_is_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_is_restart), MP_ROM_PTR(&i2cslave_i2c_slave_request_is_restart_obj) }, + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&i2cslave_i2c_slave_request_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&i2cslave_i2c_slave_request_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_ack), MP_ROM_PTR(&i2cslave_i2c_slave_request_ack_obj) }, + { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&i2cslave_i2c_slave_request_close_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(i2cslave_i2c_slave_request_locals_dict, i2cslave_i2c_slave_request_locals_dict_table); + +const mp_obj_type_t i2cslave_i2c_slave_request_type = { + { &mp_type_type }, + .name = MP_QSTR_I2CSlaveRequest, + .make_new = i2cslave_i2c_slave_request_make_new, + .locals_dict = (mp_obj_dict_t*)&i2cslave_i2c_slave_request_locals_dict, +}; diff --git a/shared-bindings/i2cslave/I2CSlave.h b/shared-bindings/i2cslave/I2CSlave.h new file mode 100644 index 00000000000..abb76141686 --- /dev/null +++ b/shared-bindings/i2cslave/I2CSlave.h @@ -0,0 +1,60 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_SLAVE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_SLAVE_H + +#include "py/obj.h" + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/i2cslave/I2CSlave.h" + +typedef struct { + mp_obj_base_t base; + i2cslave_i2c_slave_obj_t *slave; + uint16_t address; + bool is_read; + bool is_restart; +} i2cslave_i2c_slave_request_obj_t; + +extern const mp_obj_type_t i2cslave_i2c_slave_request_type; + +extern const mp_obj_type_t i2cslave_i2c_slave_type; + +extern void common_hal_i2cslave_i2c_slave_construct(i2cslave_i2c_slave_obj_t *self, + const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, + uint8_t *addresses, unsigned int num_addresses, bool smbus); +extern void common_hal_i2cslave_i2c_slave_deinit(i2cslave_i2c_slave_obj_t *self); +extern bool common_hal_i2cslave_i2c_slave_deinited(i2cslave_i2c_slave_obj_t *self); + +extern int common_hal_i2cslave_i2c_slave_is_addressed(i2cslave_i2c_slave_obj_t *self, + uint8_t *address, bool *is_read, bool *is_restart); +extern int common_hal_i2cslave_i2c_slave_read_byte(i2cslave_i2c_slave_obj_t *self, uint8_t *data); +extern int common_hal_i2cslave_i2c_slave_write_byte(i2cslave_i2c_slave_obj_t *self, uint8_t data); +extern void common_hal_i2cslave_i2c_slave_ack(i2cslave_i2c_slave_obj_t *self, bool ack); +extern void common_hal_i2cslave_i2c_slave_close(i2cslave_i2c_slave_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_SLAVE_H diff --git a/shared-bindings/i2cslave/__init__.c b/shared-bindings/i2cslave/__init__.c new file mode 100644 index 00000000000..1c692e54e79 --- /dev/null +++ b/shared-bindings/i2cslave/__init__.c @@ -0,0 +1,117 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +//#include "shared-bindings/i2cslave/__init__.h" +#include "shared-bindings/i2cslave/I2CSlave.h" + +#include "py/runtime.h" + +//| :mod:`i2cslave` --- Two wire serial protocol slave +//| ================================================== +//| +//| .. module:: i2cslave +//| :synopsis: Two wire serial protocol slave +//| :platform: SAMD21, SAMD51 +//| +//| The `i2cslave` module contains classes to support a I2C slave. +//| +//| Classes +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| I2CSlave +//| +//| Example emulating 2 devices:: +//| +//| import board +//| from i2cslave import I2CSlave +//| +//| regs = [0] * 16 +//| index = 0 +//| +//| with I2CSlave(board.SCL, board.SDA, (0x40, 0x41)) as slave: +//| while True: +//| r = slave.request() +//| if not r: +//| # Maybe do some housekeeping +//| continue +//| with r: # Closes the transfer if necessary by sending a NACK or feeding the master dummy bytes +//| if r.address == 0x40: +//| if not r.is_read: # Master write which is Slave read +//| b = r.read(1) +//| if not b or b[0] > 15: +//| break +//| index = b[0] +//| b = r.read(1) +//| if b: +//| regs[index] = b[0] +//| elif r.is_restart: # Combined transfer: This is the Master read message +//| n = r.write(bytes([regs[index]])) +//| #else: +//| # A read transfer is not supported in this example +//| # If the Master tries, it will get 0xff byte(s) by the ctx manager (r.close()) +//| elif r.address == 0x41: +//| if not r.is_read: +//| b = r.read(1) +//| if b and b[0] == 0xde: +//| # do something +//| pass +//| +//| This example sets up an I2C slave that can be accessed from Linux like this:: +//| +//| $ i2cget -y 1 0x40 0x01 +//| 0x00 +//| $ i2cset -y 1 0x40 0x01 0xaa +//| $ i2cget -y 1 0x40 0x01 +//| 0xaa +//| +//| .. warning:: +//| I2CSlave makes use of clock stretching in order to slow down the master. +//| Make sure the I2C master supports this. +//| +//| Raspberry Pi in particular does not support this with its I2C hw block. +//| This can be worked around by using the ``i2c-gpio`` bit banging driver. +//| Since the RPi firmware uses the hw i2c, it's not possible to emulate a HAT eeprom. +//| + +STATIC const mp_rom_map_elem_t i2cslave_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_i2cslave) }, + { MP_ROM_QSTR(MP_QSTR_I2CSlave), MP_ROM_PTR(&i2cslave_i2c_slave_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(i2cslave_module_globals, i2cslave_module_globals_table); + +const mp_obj_module_t i2cslave_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&i2cslave_module_globals, +}; diff --git a/shared-bindings/index.rst b/shared-bindings/index.rst new file mode 100644 index 00000000000..cbffdb61408 --- /dev/null +++ b/shared-bindings/index.rst @@ -0,0 +1,19 @@ +Core Modules +======================================== + +These core modules are intended on being consistent across ports and boards. +A module may not exist on a port/board if no underlying hardware support is +present or if flash space is limited. For example, a microcontroller without +analog features will not have `analogio`. See the `support_matrix` page for +a list of modules supported on each board. + +Modules +--------- + +.. toctree:: + :glob: + :maxdepth: 3 + + support_matrix + */__init__ + help diff --git a/shared-bindings/math/__init__.c b/shared-bindings/math/__init__.c new file mode 100644 index 00000000000..0bf8047c989 --- /dev/null +++ b/shared-bindings/math/__init__.c @@ -0,0 +1,447 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2017 Michael McWethy + * + * 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 "py/builtin.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +#if MICROPY_PY_BUILTINS_FLOAT + +#include + +// M_PI is not part of the math.h standard and may not be defined +// And by defining our own we can ensure it uses the correct const format. +#define MP_PI MICROPY_FLOAT_CONST(3.14159265358979323846) + + +//| :mod:`math` --- mathematical functions +//| ======================================================== +//| +//| .. module:: math +//| :synopsis: mathematical functions +//| :platform: SAMD21/SAMD51 +//| +//| The `math` module provides some basic mathematical functions for +//| working with floating-point numbers. +//| + +STATIC NORETURN void math_error(void) { + mp_raise_ValueError(translate("math domain error")); +} + +#define MATH_FUN_1(py_name, c_name) \ + STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj))); } \ + STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name); + +#define MATH_FUN_2(py_name, c_name) \ + STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj, mp_obj_t y_obj) { return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj), mp_obj_get_float(y_obj))); } \ + STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_math_## py_name ## _obj, mp_math_ ## py_name); + +#define MATH_FUN_1_TO_BOOL(py_name, c_name) \ + STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return mp_obj_new_bool(c_name(mp_obj_get_float(x_obj))); } \ + STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name); + +#define MATH_FUN_1_TO_INT(py_name, c_name) \ + STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return mp_obj_new_int_from_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj))); } \ + STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name); + +#define MATH_FUN_1_ERRCOND(py_name, c_name, error_condition) \ + STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { \ + mp_float_t x = mp_obj_get_float(x_obj); \ + if (error_condition) { \ + math_error(); \ + } \ + return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(x)); \ + } \ + STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name); + +#ifdef MP_NEED_LOG2 +// 1.442695040888963407354163704 is 1/_M_LN2 +#define log2(x) (log(x) * 1.442695040888963407354163704) +#endif + //| Constants + //| --------- + //| + //| .. data:: e + //| + //| base of the natural logarithm + //| + //| .. data:: pi + //| + //| the ratio of a circle's circumference to its diameter + //| + + //| Functions + //| --------- + //| + //| .. function:: acos(x) + //| + //| Return the inverse cosine of ``x``. + //| + //| .. function:: asin(x) + //| + //| Return the inverse sine of ``x``. + //| + //| .. function:: atan(x) + //| + //| Return the inverse tangent of ``x``. + //| + //| .. function:: atan2(y,x) + //| + //| Return the principal value of the inverse tangent of ``y/x``. + //| + //| .. function:: ceil(x) + //| + //| Return an integer, being ``x`` rounded towards positive infinity. + //| + //| .. function:: copysign(x,y) + //| + //| Return ``x`` with the sign of ``y``. + //| + //| .. function:: cos(x) + //| + //| Return the cosine of ``x``. + //| + //| .. function:: degrees(x) + //| + //| Return radians ``x`` converted to degrees. + //| + //| .. function:: exp(x) + //| + //| Return the exponential of ``x``. + //| + //| .. function:: fabs(x) + //| + //| Return the absolute value of ``x``. + //| + //| .. function:: floor(x) + //| + //| Return an integer, being ``x`` rounded towards negative infinity. + //| + //| .. function:: fmod(x,y) + //| + //| Return the remainder of ``x/y``. + //| + //| .. function:: frexp(x) + //| + //| Decomposes a floating-point number into its mantissa and exponent. + //| The returned value is the tuple ``(m, e)`` such that ``x == m * 2**e`` + //| exactly. If ``x == 0`` then the function returns ``(0.0, 0)``, otherwise + //| the relation ``0.5 <= abs(m) < 1`` holds. + //| + //| .. function:: isfinite(x) + //| + //| Return ``True`` if ``x`` is finite. + //| + //| .. function:: isinf(x) + //| + //| Return ``True`` if ``x`` is infinite. + //| + //| .. function:: isnan(x) + //| + //| Return ``True`` if ``x`` is not-a-number + //| + //| .. function:: ldexp(x, exp) + //| + //| Return ``x * (2**exp)``. + //| + //| .. function:: modf(x) + //| + //| Return a tuple of two floats, being the fractional and integral parts of + //| ``x``. Both return values have the same sign as ``x``. + //| + //| .. function:: pow(x, y) + //| + //| Returns ``x`` to the power of ``y``. + //| + //| .. function:: radians(x) + //| + //| Return degrees ``x`` converted to radians. + //| + //| .. function:: sin(x) + //| + //| Return the sine of ``x``. + //| + //| .. function:: sqrt(x) + //| + //| Returns the square root of ``x``. + //| + //| .. function:: tan(x) + //| + //| Return the tangent of ``x``. + //| + //| .. function:: trunc(x) + //| + //| Return an integer, being ``x`` rounded towards 0. + //| + MATH_FUN_1_ERRCOND(sqrt, sqrt, (x < (mp_float_t)0.0)) + +MATH_FUN_2(pow, pow) + +MATH_FUN_1(exp, exp) +#if MICROPY_PY_MATH_SPECIAL_FUNCTIONS +// Special functions +// ----------------- +// +// .. function:: expm1(x) +// +// Return ``exp(x) - 1``. +// +MATH_FUN_1(expm1, expm1) + +// .. function:: log2(x) +// +// Return the base-2 logarithm of ``x``. +// +MATH_FUN_1_ERRCOND(log2, log2, (x <= (mp_float_t)0.0)) + +// .. function:: log10(x) +// +// Return the base-10 logarithm of ``x``. +// +MATH_FUN_1_ERRCOND(log10, log10, (x <= (mp_float_t)0.0)) + +// .. function:: cosh(x) +// +// Return the hyperbolic cosine of ``x``. +// +MATH_FUN_1(cosh, cosh) + +// .. function:: sinh(x) +// +// Return the hyperbolic sine of ``x``. +// +MATH_FUN_1(sinh, sinh) + +// .. function:: tanh(x) +// +// Return the hyperbolic tangent of ``x``. +// +MATH_FUN_1(tanh, tanh) + +// .. function:: acosh(x) +// +// Return the inverse hyperbolic cosine of ``x``. +// +MATH_FUN_1(acosh, acosh) + +// .. function:: asinh(x) +// +// Return the inverse hyperbolic sine of ``x``. +// +MATH_FUN_1(asinh, asinh) + +// .. function:: atanh(x) +// +// Return the inverse hyperbolic tangent of ``x``. +// +MATH_FUN_1(atanh, atanh) +#endif + +MATH_FUN_1(cos, cos) + +MATH_FUN_1(sin, sin) + +MATH_FUN_1(tan, tan) + +MATH_FUN_1(acos, acos) + +MATH_FUN_1(asin, asin) + +MATH_FUN_1(atan, atan) + +MATH_FUN_2(atan2, atan2) + +MATH_FUN_1_TO_INT(ceil, ceil) + +MATH_FUN_2(copysign, copysign) + +MATH_FUN_1(fabs, fabs) + +MATH_FUN_1_TO_INT(floor, floor) //TODO: delegate to x.__floor__() if x is not a float + +MATH_FUN_2(fmod, fmod) + +MATH_FUN_1_TO_BOOL(isfinite, isfinite) + +MATH_FUN_1_TO_BOOL(isinf, isinf) + +MATH_FUN_1_TO_BOOL(isnan, isnan) + +MATH_FUN_1_TO_INT(trunc, trunc) + +MATH_FUN_2(ldexp, ldexp) +#if MICROPY_PY_MATH_SPECIAL_FUNCTIONS + +// .. function:: erf(x) +// +// Return the error function of ``x``. +// +MATH_FUN_1(erf, erf) + +// .. function:: erfc(x) +// +// Return the complementary error function of ``x``. +// +MATH_FUN_1(erfc, erfc) + +// .. function:: gamma(x) +// +// Return the gamma function of ``x``. +// +MATH_FUN_1(gamma, tgamma) + +// .. function:: lgamma(x) +// +// Return the natural logarithm of the gamma function of ``x``. +// +MATH_FUN_1(lgamma, lgamma) +#endif +//TODO: factorial, fsum + +// Function that takes a variable number of arguments + +// log(x[, base]) +STATIC mp_obj_t mp_math_log(size_t n_args, const mp_obj_t *args) { + mp_float_t x = mp_obj_get_float(args[0]); + if (x <= (mp_float_t)0.0) { + math_error(); + } + mp_float_t l = MICROPY_FLOAT_C_FUN(log)(x); + if (n_args == 1) { + return mp_obj_new_float(l); + } else { + mp_float_t base = mp_obj_get_float(args[1]); + if (base <= (mp_float_t)0.0) { + math_error(); +// Turn off warning when comparing exactly with integral value 1.0 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" + } else if (base == (mp_float_t)1.0) { +#pragma GCC diagnostic pop + mp_raise_msg(&mp_type_ZeroDivisionError, translate("division by zero")); + } + return mp_obj_new_float(l / MICROPY_FLOAT_C_FUN(log)(base)); + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_math_log_obj, 1, 2, mp_math_log); + +// Functions that return a tuple + + +STATIC mp_obj_t mp_math_frexp(mp_obj_t x_obj) { + int int_exponent = 0; + mp_float_t significand = MICROPY_FLOAT_C_FUN(frexp)(mp_obj_get_float(x_obj), &int_exponent); + mp_obj_t tuple[2]; + tuple[0] = mp_obj_new_float(significand); + tuple[1] = mp_obj_new_int(int_exponent); + return mp_obj_new_tuple(2, tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_frexp_obj, mp_math_frexp); + +STATIC mp_obj_t mp_math_modf(mp_obj_t x_obj) { + mp_float_t int_part = 0.0; + mp_float_t fractional_part = MICROPY_FLOAT_C_FUN(modf)(mp_obj_get_float(x_obj), &int_part); + mp_obj_t tuple[2]; + tuple[0] = mp_obj_new_float(fractional_part); + tuple[1] = mp_obj_new_float(int_part); + return mp_obj_new_tuple(2, tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_modf_obj, mp_math_modf); + +// Angular conversions + + +STATIC mp_obj_t mp_math_radians(mp_obj_t x_obj) { + return mp_obj_new_float(mp_obj_get_float(x_obj) * (MP_PI / MICROPY_FLOAT_CONST(180.0))); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_radians_obj, mp_math_radians); + + +STATIC mp_obj_t mp_math_degrees(mp_obj_t x_obj) { + return mp_obj_new_float(mp_obj_get_float(x_obj) * (MICROPY_FLOAT_CONST(180.0) / MP_PI)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_degrees_obj, mp_math_degrees); + +STATIC const mp_rom_map_elem_t mp_module_math_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_math) }, + { MP_ROM_QSTR(MP_QSTR_e), mp_const_float_e }, + { MP_ROM_QSTR(MP_QSTR_pi), mp_const_float_pi }, + { MP_ROM_QSTR(MP_QSTR_sqrt), MP_ROM_PTR(&mp_math_sqrt_obj) }, + { MP_ROM_QSTR(MP_QSTR_pow), MP_ROM_PTR(&mp_math_pow_obj) }, + { MP_ROM_QSTR(MP_QSTR_exp), MP_ROM_PTR(&mp_math_exp_obj) }, + #if MICROPY_PY_MATH_SPECIAL_FUNCTIONS + { MP_ROM_QSTR(MP_QSTR_expm1), MP_ROM_PTR(&mp_math_expm1_obj) }, + #endif + { MP_ROM_QSTR(MP_QSTR_log), MP_ROM_PTR(&mp_math_log_obj) }, + #if MICROPY_PY_MATH_SPECIAL_FUNCTIONS + { MP_ROM_QSTR(MP_QSTR_log2), MP_ROM_PTR(&mp_math_log2_obj) }, + { MP_ROM_QSTR(MP_QSTR_log10), MP_ROM_PTR(&mp_math_log10_obj) }, + { MP_ROM_QSTR(MP_QSTR_cosh), MP_ROM_PTR(&mp_math_cosh_obj) }, + { MP_ROM_QSTR(MP_QSTR_sinh), MP_ROM_PTR(&mp_math_sinh_obj) }, + { MP_ROM_QSTR(MP_QSTR_tanh), MP_ROM_PTR(&mp_math_tanh_obj) }, + { MP_ROM_QSTR(MP_QSTR_acosh), MP_ROM_PTR(&mp_math_acosh_obj) }, + { MP_ROM_QSTR(MP_QSTR_asinh), MP_ROM_PTR(&mp_math_asinh_obj) }, + { MP_ROM_QSTR(MP_QSTR_atanh), MP_ROM_PTR(&mp_math_atanh_obj) }, + #endif + { MP_ROM_QSTR(MP_QSTR_cos), MP_ROM_PTR(&mp_math_cos_obj) }, + { MP_ROM_QSTR(MP_QSTR_sin), MP_ROM_PTR(&mp_math_sin_obj) }, + { MP_ROM_QSTR(MP_QSTR_tan), MP_ROM_PTR(&mp_math_tan_obj) }, + { MP_ROM_QSTR(MP_QSTR_acos), MP_ROM_PTR(&mp_math_acos_obj) }, + { MP_ROM_QSTR(MP_QSTR_asin), MP_ROM_PTR(&mp_math_asin_obj) }, + { MP_ROM_QSTR(MP_QSTR_atan), MP_ROM_PTR(&mp_math_atan_obj) }, + { MP_ROM_QSTR(MP_QSTR_atan2), MP_ROM_PTR(&mp_math_atan2_obj) }, + { MP_ROM_QSTR(MP_QSTR_ceil), MP_ROM_PTR(&mp_math_ceil_obj) }, + { MP_ROM_QSTR(MP_QSTR_copysign), MP_ROM_PTR(&mp_math_copysign_obj) }, + { MP_ROM_QSTR(MP_QSTR_fabs), MP_ROM_PTR(&mp_math_fabs_obj) }, + { MP_ROM_QSTR(MP_QSTR_floor), MP_ROM_PTR(&mp_math_floor_obj) }, + { MP_ROM_QSTR(MP_QSTR_fmod), MP_ROM_PTR(&mp_math_fmod_obj) }, + { MP_ROM_QSTR(MP_QSTR_frexp), MP_ROM_PTR(&mp_math_frexp_obj) }, + { MP_ROM_QSTR(MP_QSTR_ldexp), MP_ROM_PTR(&mp_math_ldexp_obj) }, + { MP_ROM_QSTR(MP_QSTR_modf), MP_ROM_PTR(&mp_math_modf_obj) }, + { MP_ROM_QSTR(MP_QSTR_isfinite), MP_ROM_PTR(&mp_math_isfinite_obj) }, + { MP_ROM_QSTR(MP_QSTR_isinf), MP_ROM_PTR(&mp_math_isinf_obj) }, + { MP_ROM_QSTR(MP_QSTR_isnan), MP_ROM_PTR(&mp_math_isnan_obj) }, + { MP_ROM_QSTR(MP_QSTR_trunc), MP_ROM_PTR(&mp_math_trunc_obj) }, + { MP_ROM_QSTR(MP_QSTR_radians), MP_ROM_PTR(&mp_math_radians_obj) }, + { MP_ROM_QSTR(MP_QSTR_degrees), MP_ROM_PTR(&mp_math_degrees_obj) }, + #if MICROPY_PY_MATH_SPECIAL_FUNCTIONS + { MP_ROM_QSTR(MP_QSTR_erf), MP_ROM_PTR(&mp_math_erf_obj) }, + { MP_ROM_QSTR(MP_QSTR_erfc), MP_ROM_PTR(&mp_math_erfc_obj) }, + { MP_ROM_QSTR(MP_QSTR_gamma), MP_ROM_PTR(&mp_math_gamma_obj) }, + { MP_ROM_QSTR(MP_QSTR_lgamma), MP_ROM_PTR(&mp_math_lgamma_obj) }, + #endif +}; + +STATIC MP_DEFINE_CONST_DICT(mp_module_math_globals, mp_module_math_globals_table); + +const mp_obj_module_t math_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mp_module_math_globals, +}; + +#endif // MICROPY_PY_BUILTINS_FLOAT && MICROPY_PY_MATH diff --git a/shared-bindings/microcontroller/Pin.c b/shared-bindings/microcontroller/Pin.c new file mode 100644 index 00000000000..3635f0afbd9 --- /dev/null +++ b/shared-bindings/microcontroller/Pin.c @@ -0,0 +1,102 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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 "shared-bindings/board/__init__.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" + +#include "py/nlr.h" +#include "py/obj.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: microcontroller +//| +//| :class:`Pin` --- Pin reference +//| ------------------------------------------ +//| +//| Identifies an IO pin on the microcontroller. +//| +//| .. class:: Pin() +//| +//| Identifies an IO pin on the microcontroller. They are fixed by the +//| hardware so they cannot be constructed on demand. Instead, use +//| `board` or `microcontroller.pin` to reference the desired pin. +//| + +static void get_pin_name(const mcu_pin_obj_t *self, qstr* package, qstr* module, qstr* name) { + const mp_map_t* board_map = &board_module_globals.map; + for (uint8_t i = 0; i < board_map->alloc; i++) { + if (board_map->table[i].value == self) { + *package = 0; + *module = MP_QSTR_board; + *name = MP_OBJ_QSTR_VALUE(board_map->table[i].key); + return; + } + } + const mp_map_t* mcu_map = &mcu_pin_globals.map; + for (uint8_t i = 0; i < mcu_map->alloc; i++) { + if (mcu_map->table[i].value == self) { + *package = MP_QSTR_microcontroller; + *module = MP_QSTR_pin; + *name = MP_OBJ_QSTR_VALUE(mcu_map->table[i].key); + return; + } + } +} + +STATIC void mcu_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + mcu_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); + qstr package; + qstr module; + qstr name; + + get_pin_name(self, &package, &module, &name); + mp_printf(print, "%q.%q.%q", MP_QSTR_microcontroller, MP_QSTR_pin, name); +} + +const mp_obj_type_t mcu_pin_type = { + { &mp_type_type }, + .name = MP_QSTR_Pin, + .print = mcu_pin_print +}; + +void assert_pin(mp_obj_t obj, bool none_ok) { + if ((obj != mp_const_none || !none_ok) && !MP_OBJ_IS_TYPE(obj, &mcu_pin_type)) { + mp_raise_TypeError_varg(translate("Expected a %q"), mcu_pin_type.name); + } +} + +void assert_pin_free(const mcu_pin_obj_t* pin) { + if (pin != NULL && pin != MP_OBJ_TO_PTR(mp_const_none) && !common_hal_mcu_pin_is_free(pin)) { + qstr package; + qstr module; + qstr name; + + get_pin_name(pin, &package, &module, &name); + mp_raise_ValueError_varg(translate("%q in use"), name); + } +} diff --git a/shared-bindings/microcontroller/Pin.h b/shared-bindings/microcontroller/Pin.h new file mode 100644 index 00000000000..ed831b25896 --- /dev/null +++ b/shared-bindings/microcontroller/Pin.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER_PIN_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER_PIN_H + +#include "common-hal/microcontroller/Pin.h" +#include "py/obj.h" + +// Type object used in Python. Should be shared between ports. +extern const mp_obj_type_t mcu_pin_type; + +void assert_pin(mp_obj_t obj, bool none_ok); +void assert_pin_free(const mcu_pin_obj_t* pin); + +bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER_PIN_H diff --git a/shared-bindings/microcontroller/Processor.c b/shared-bindings/microcontroller/Processor.c new file mode 100644 index 00000000000..be685b0a824 --- /dev/null +++ b/shared-bindings/microcontroller/Processor.c @@ -0,0 +1,128 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert for Adafruit Industries + * + * 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 "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Processor.h" + +#include +#include + +#include "py/objproperty.h" + +#include "py/runtime.h" + +//| .. currentmodule:: microcontroller +//| +//| :class:`Processor` --- Microcontroller CPU information and control +//| ------------------------------------------------------------------ +//| +//| Get information about the microcontroller CPU and control it. +//| +//| Usage:: +//| +//| import microcontroller +//| print(microcontroller.cpu.frequency) +//| print(microcontroller.cpu.temperature) +//| + +//| .. class:: Processor() +//| +//| You cannot create an instance of `microcontroller.Processor`. +//| Use `microcontroller.cpu` to access the sole instance available. +//| + +//| .. attribute:: frequency +//| +//| The CPU operating frequency as an `int`, in Hertz. (read-only) +//| +STATIC mp_obj_t mcu_processor_get_frequency(mp_obj_t self) { + return mp_obj_new_int_from_uint(common_hal_mcu_processor_get_frequency()); +} + +MP_DEFINE_CONST_FUN_OBJ_1(mcu_processor_get_frequency_obj, mcu_processor_get_frequency); + +const mp_obj_property_t mcu_processor_frequency_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&mcu_processor_get_frequency_obj, // getter + (mp_obj_t)&mp_const_none_obj, // no setter + (mp_obj_t)&mp_const_none_obj, // no deleter + }, +}; + +//| .. attribute:: temperature +//| +//| The on-chip temperature, in Celsius, as a float. (read-only) +//| +//| Is `None` if the temperature is not available. +//| +STATIC mp_obj_t mcu_processor_get_temperature(mp_obj_t self) { + float temperature = common_hal_mcu_processor_get_temperature(); + return isnan(temperature) ? mp_const_none : mp_obj_new_float(temperature); +} + +MP_DEFINE_CONST_FUN_OBJ_1(mcu_processor_get_temperature_obj, mcu_processor_get_temperature); + +const mp_obj_property_t mcu_processor_temperature_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&mcu_processor_get_temperature_obj, // getter + (mp_obj_t)&mp_const_none_obj, // no setter + (mp_obj_t)&mp_const_none_obj, // no deleter + }, +}; + +//| .. attribute:: uid +//| +//| The unique id (aka serial number) of the chip as a `bytearray`. (read-only) +//| +STATIC mp_obj_t mcu_processor_get_uid(mp_obj_t self) { + uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH]; + common_hal_mcu_processor_get_uid(raw_id); + return mp_obj_new_bytearray(sizeof(raw_id), raw_id); +} + +MP_DEFINE_CONST_FUN_OBJ_1(mcu_processor_get_uid_obj, mcu_processor_get_uid); + +const mp_obj_property_t mcu_processor_uid_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&mcu_processor_get_uid_obj, // getter + (mp_obj_t)&mp_const_none_obj, // no setter + (mp_obj_t)&mp_const_none_obj, // no deleter + }, +}; + +STATIC const mp_rom_map_elem_t mcu_processor_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&mcu_processor_frequency_obj) }, + { MP_ROM_QSTR(MP_QSTR_temperature), MP_ROM_PTR(&mcu_processor_temperature_obj) }, + { MP_ROM_QSTR(MP_QSTR_uid), MP_ROM_PTR(&mcu_processor_uid_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(mcu_processor_locals_dict, mcu_processor_locals_dict_table); + +const mp_obj_type_t mcu_processor_type = { + { &mp_type_type }, + .name = MP_QSTR_Processor, + .locals_dict = (mp_obj_t)&mcu_processor_locals_dict, +}; diff --git a/shared-bindings/microcontroller/Processor.h b/shared-bindings/microcontroller/Processor.h new file mode 100644 index 00000000000..28f0544205c --- /dev/null +++ b/shared-bindings/microcontroller/Processor.h @@ -0,0 +1,40 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER_PROCESSOR_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER_PROCESSOR_H + +#include "py/obj.h" + +#include "common-hal/microcontroller/Processor.h" + +const mp_obj_type_t mcu_processor_type; + +uint32_t common_hal_mcu_processor_get_frequency(void); +float common_hal_mcu_processor_get_temperature(void); +void common_hal_mcu_processor_get_uid(uint8_t raw_id[]); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER_PROCESSOR_H diff --git a/shared-bindings/microcontroller/RunMode.c b/shared-bindings/microcontroller/RunMode.c new file mode 100644 index 00000000000..913242ad267 --- /dev/null +++ b/shared-bindings/microcontroller/RunMode.c @@ -0,0 +1,96 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/microcontroller/RunMode.h" + +//| .. currentmodule:: microcontroller +//| +//| :class:`RunMode` -- run state of the microcontroller +//| ============================================================= +//| +//| .. class:: RunMode() +//| +//| Enum-like class to define the run mode of the microcontroller and +//| CircuitPython. +//| +//| .. attribute:: NORMAL +//| +//| Run CircuitPython as normal. +//| +//| :type microcontroller.RunMode: +//| +//| .. attribute:: SAFE_MODE +//| +//| Run CircuitPython in safe mode. User code will not be run and the +//| file system will be writeable over USB. +//| +//| :type microcontroller.RunMode: +//| +//| .. attribute:: BOOTLOADER +//| +//| Run the bootloader. +//| +//| :type microcontroller.RunMode: +//| +const mp_obj_type_t mcu_runmode_type; + +const mcu_runmode_obj_t mcu_runmode_normal_obj = { + { &mcu_runmode_type }, +}; + +const mcu_runmode_obj_t mcu_runmode_safe_mode_obj = { + { &mcu_runmode_type }, +}; + +const mcu_runmode_obj_t mcu_runmode_bootloader_obj = { + { &mcu_runmode_type }, +}; + +STATIC const mp_rom_map_elem_t mcu_runmode_locals_dict_table[] = { + {MP_ROM_QSTR(MP_QSTR_NORMAL), MP_ROM_PTR(&mcu_runmode_normal_obj)}, + {MP_ROM_QSTR(MP_QSTR_SAFE_MODE), MP_ROM_PTR(&mcu_runmode_safe_mode_obj)}, + {MP_ROM_QSTR(MP_QSTR_BOOTLOADER), MP_ROM_PTR(&mcu_runmode_bootloader_obj)}, +}; +STATIC MP_DEFINE_CONST_DICT(mcu_runmode_locals_dict, mcu_runmode_locals_dict_table); + +STATIC void mcu_runmode_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + qstr runmode = MP_QSTR_NORMAL; + if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&mcu_runmode_safe_mode_obj)) { + runmode = MP_QSTR_SAFE_MODE; + } else if (MP_OBJ_TO_PTR(self_in) == + MP_ROM_PTR(&mcu_runmode_bootloader_obj)) { + runmode = MP_QSTR_BOOTLOADER; + } + mp_printf(print, "%q.%q.%q", MP_QSTR_microcontroller, MP_QSTR_RunMode, + runmode); +} + +const mp_obj_type_t mcu_runmode_type = { + { &mp_type_type }, + .name = MP_QSTR_RunMode, + .print = mcu_runmode_print, + .locals_dict = (mp_obj_t)&mcu_runmode_locals_dict, +}; diff --git a/shared-bindings/microcontroller/RunMode.h b/shared-bindings/microcontroller/RunMode.h new file mode 100644 index 00000000000..5e8b6e64655 --- /dev/null +++ b/shared-bindings/microcontroller/RunMode.h @@ -0,0 +1,47 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER_RUNMODE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER_RUNMODE_H + +#include "py/obj.h" + +typedef enum { + RUNMODE_NORMAL, + RUNMODE_SAFE_MODE, + RUNMODE_BOOTLOADER +} mcu_runmode_t; + +const mp_obj_type_t mcu_runmode_type; + +typedef struct { + mp_obj_base_t base; +} mcu_runmode_obj_t; +extern const mcu_runmode_obj_t mcu_runmode_normal_obj; +extern const mcu_runmode_obj_t mcu_runmode_safe_mode_obj; +extern const mcu_runmode_obj_t mcu_runmode_bootloader_obj; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER_RUNMODE_H diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c new file mode 100644 index 00000000000..090c4564dac --- /dev/null +++ b/shared-bindings/microcontroller/__init__.c @@ -0,0 +1,198 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +// Microcontroller contains pin references and microcontroller specific control +// functions. + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/microcontroller/Processor.h" + +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/Processor.h" + +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +//| :mod:`microcontroller` --- Pin references and cpu functionality +//| ================================================================ +//| +//| .. module:: microcontroller +//| :synopsis: Pin references and core functionality +//| :platform: SAMD21, ESP8266 +//| +//| The `microcontroller` module defines the pins from the perspective of the +//| microcontroller. See `board` for board-specific pin mappings. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Pin +//| Processor +//| RunMode +//| + +//| .. data:: cpu +//| +//| CPU information and control, such as ``cpu.temperature`` and ``cpu.frequency`` +//| (clock frequency). +//| This object is the sole instance of `microcontroller.Processor`. +//| + +//| .. function:: delay_us(delay) +//| +//| Dedicated delay method used for very short delays. **Do not** do long delays +//| because this stops all other functions from completing. Think of this as an empty +//| ``while`` loop that runs for the specified ``(delay)`` time. If you have other +//| code or peripherals (e.g audio recording) that require specific timing or +//| processing while you are waiting, explore a different avenue such as using +//| `time.sleep()`. +//| +STATIC mp_obj_t mcu_delay_us(mp_obj_t delay_obj) { + uint32_t delay = mp_obj_get_int(delay_obj); + + common_hal_mcu_delay_us(delay); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mcu_delay_us_obj, mcu_delay_us); + +//| .. function:: disable_interrupts() +//| +//| Disable all interrupts. Be very careful, this can stall everything. +//| +STATIC mp_obj_t mcu_disable_interrupts(void) { + common_hal_mcu_disable_interrupts(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_disable_interrupts_obj, mcu_disable_interrupts); + +//| .. function:: enable_interrupts() +//| +//| Enable the interrupts that were enabled at the last disable. +//| +STATIC mp_obj_t mcu_enable_interrupts(void) { + common_hal_mcu_enable_interrupts(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_enable_interrupts_obj, mcu_enable_interrupts); + +//| .. function:: on_next_reset(run_mode) +//| +//| Configure the run mode used the next time the microcontroller is reset but +//| not powered down. +//| +//| :param ~microcontroller.RunMode run_mode: The next run mode +//| +STATIC mp_obj_t mcu_on_next_reset(mp_obj_t run_mode_obj) { + mcu_runmode_t run_mode; + if (run_mode_obj == &mcu_runmode_normal_obj) { + run_mode = RUNMODE_NORMAL; + } else if (run_mode_obj == &mcu_runmode_safe_mode_obj) { + run_mode = RUNMODE_SAFE_MODE; + } else if (run_mode_obj == &mcu_runmode_bootloader_obj) { + run_mode = RUNMODE_BOOTLOADER; + } else { + mp_raise_ValueError(translate("Invalid run mode.")); + } + + common_hal_mcu_on_next_reset(run_mode); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mcu_on_next_reset_obj, mcu_on_next_reset); + +//| .. function:: reset() +//| +//| Reset the microcontroller. After reset, the microcontroller will enter the +//| run mode last set by `on_next_reset`. +//| +//| .. warning:: This may result in file system corruption when connected to a +//| host computer. Be very careful when calling this! Make sure the device +//| "Safely removed" on Windows or "ejected" on Mac OSX and Linux. +//| +STATIC mp_obj_t mcu_reset(void) { + common_hal_mcu_reset(); + // We won't actually get here because we're resetting. + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_reset_obj, mcu_reset); + +//| .. data:: nvm +//| +//| Available non-volatile memory. +//| This object is the sole instance of `nvm.ByteArray` when available or ``None`` otherwise. +//| +//| :type: nvm.ByteArray or None +//| + +//| :mod:`microcontroller.pin` --- Microcontroller pin names +//| -------------------------------------------------------- +//| +//| .. module:: microcontroller.pin +//| :synopsis: Microcontroller pin names +//| :platform: SAMD21 +//| +//| References to pins as named by the microcontroller +//| +const mp_obj_module_t mcu_pin_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mcu_pin_globals, +}; + +STATIC const mp_rom_map_elem_t mcu_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_microcontroller) }, + { MP_ROM_QSTR(MP_QSTR_cpu), MP_ROM_PTR(&common_hal_mcu_processor_obj) }, + { MP_ROM_QSTR(MP_QSTR_delay_us), MP_ROM_PTR(&mcu_delay_us_obj) }, + { MP_ROM_QSTR(MP_QSTR_disable_interrupts), MP_ROM_PTR(&mcu_disable_interrupts_obj) }, + { MP_ROM_QSTR(MP_QSTR_enable_interrupts), MP_ROM_PTR(&mcu_enable_interrupts_obj) }, + { MP_ROM_QSTR(MP_QSTR_on_next_reset), MP_ROM_PTR(&mcu_on_next_reset_obj) }, + { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&mcu_reset_obj) }, + #if CIRCUITPY_INTERNAL_NVM_SIZE > 0 + { MP_ROM_QSTR(MP_QSTR_nvm), MP_ROM_PTR(&common_hal_mcu_nvm_obj) }, + #else + { MP_ROM_QSTR(MP_QSTR_nvm), MP_ROM_PTR(&mp_const_none_obj) }, + #endif + { MP_ROM_QSTR(MP_QSTR_RunMode), MP_ROM_PTR(&mcu_runmode_type) }, + { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&mcu_pin_type) }, + { MP_ROM_QSTR(MP_QSTR_pin), MP_ROM_PTR(&mcu_pin_module) }, + { MP_ROM_QSTR(MP_QSTR_Processor), MP_ROM_PTR(&mcu_processor_type) }, + +}; + +STATIC MP_DEFINE_CONST_DICT(mcu_module_globals, mcu_module_globals_table); + +const mp_obj_module_t microcontroller_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mcu_module_globals, +}; diff --git a/shared-bindings/microcontroller/__init__.h b/shared-bindings/microcontroller/__init__.h new file mode 100644 index 00000000000..e1487c555a1 --- /dev/null +++ b/shared-bindings/microcontroller/__init__.h @@ -0,0 +1,58 @@ + +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER___INIT___H + +#include "py/mpconfig.h" +#include "py/obj.h" + +#include "common-hal/microcontroller/Processor.h" + +#include "shared-bindings/microcontroller/RunMode.h" + +extern void common_hal_mcu_delay_us(uint32_t); + +extern void common_hal_mcu_disable_interrupts(void); +extern void common_hal_mcu_enable_interrupts(void); + +extern void common_hal_mcu_on_next_reset(mcu_runmode_t runmode); +extern void common_hal_mcu_reset(void); + +extern const mp_obj_dict_t mcu_pin_globals; + +extern const mcu_processor_obj_t common_hal_mcu_processor_obj; + + +#if CIRCUITPY_INTERNAL_NVM_SIZE > 0 + +#include "common-hal/nvm/ByteArray.h" +extern const nvm_bytearray_obj_t common_hal_mcu_nvm_obj; + +#endif + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER___INIT___H diff --git a/shared-bindings/multiterminal/__init__.c b/shared-bindings/multiterminal/__init__.c new file mode 100644 index 00000000000..8de3c50d7b3 --- /dev/null +++ b/shared-bindings/multiterminal/__init__.c @@ -0,0 +1,115 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/multiterminal/__init__.h" + +#include "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +//| :mod:`multiterminal` --- Manage additional terminal sources +//| =========================================================== +//| +//| .. module:: multiterminal +//| :synopsis: Manage additional terminal sources +//| :platform: ESP8266 +//| +//| The `multiterminal` module allows you to configure an additional serial +//| terminal source. Incoming characters are accepted from both the internal +//| serial connection and the optional secondary connection. +//| + +//| .. function:: get_secondary_terminal() +//| +//| Returns the current secondary terminal. +//| +STATIC mp_obj_t multiterminal_obj_get_secondary_terminal() { + return common_hal_multiterminal_get_secondary_terminal(); +} +MP_DEFINE_CONST_FUN_OBJ_0(multiterminal_get_secondary_terminal_obj, multiterminal_obj_get_secondary_terminal); + +//| .. function:: set_secondary_terminal(stream) +//| +//| Read additional input from the given stream and write out back to it. +//| This doesn't replace the core stream (usually UART or native USB) but is +//| mixed in instead. +//| +//| :param stream stream: secondary stream +//| +STATIC mp_obj_t multiterminal_obj_set_secondary_terminal(mp_obj_t secondary_terminal) { + mp_obj_t write_m[3]; + mp_load_method_maybe(secondary_terminal, MP_QSTR_write, write_m); + mp_obj_t readinto_m[3]; + mp_load_method_maybe(secondary_terminal, MP_QSTR_readinto, readinto_m); + if (write_m[0] == MP_OBJ_NULL || readinto_m[0] == MP_OBJ_NULL) { + mp_raise_ValueError(translate("Stream missing readinto() or write() method.")); + return mp_const_none; + } + common_hal_multiterminal_set_secondary_terminal(secondary_terminal); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(multiterminal_set_secondary_terminal_obj, multiterminal_obj_set_secondary_terminal); + +//| .. function:: clear_secondary_terminal() +//| +//| Clears the secondary terminal. +//| +STATIC mp_obj_t multiterminal_obj_clear_secondary_terminal() { + common_hal_multiterminal_clear_secondary_terminal(); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(multiterminal_clear_secondary_terminal_obj, multiterminal_obj_clear_secondary_terminal); + +//| .. function:: schedule_secondary_terminal_read(socket) +//| +//| In cases where the underlying OS is doing task scheduling, this notifies +//| the OS when more data is available on the socket to read. This is useful +//| as a callback for lwip sockets. +//| +// TODO(tannewt): This is a funny API. Replace it with a direct call into the OS +// by the lwip object. +STATIC mp_obj_t multiterminal_obj_schedule_secondary_terminal_read(mp_obj_t socket) { + common_hal_multiterminal_schedule_secondary_terminal_read(socket); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(multiterminal_schedule_secondary_terminal_read_obj, multiterminal_obj_schedule_secondary_terminal_read); + +// TODO(tannewt): Expose the internal serial connection as `primary_terminal` + +STATIC const mp_rom_map_elem_t multiterminal_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_multiterminal) }, + { MP_ROM_QSTR(MP_QSTR_get_secondary_terminal), MP_ROM_PTR(&multiterminal_get_secondary_terminal_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_secondary_terminal), MP_ROM_PTR(&multiterminal_set_secondary_terminal_obj) }, + { MP_ROM_QSTR(MP_QSTR_clear_secondary_terminal), MP_ROM_PTR(&multiterminal_clear_secondary_terminal_obj) }, + { MP_ROM_QSTR(MP_QSTR_schedule_secondary_terminal_read), MP_ROM_PTR(&multiterminal_schedule_secondary_terminal_read_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(multiterminal_module_globals, multiterminal_module_globals_table); + +const mp_obj_module_t multiterminal_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&multiterminal_module_globals, +}; diff --git a/shared-bindings/multiterminal/__init__.h b/shared-bindings/multiterminal/__init__.h new file mode 100644 index 00000000000..7c288426306 --- /dev/null +++ b/shared-bindings/multiterminal/__init__.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef SHARED_BINDINGS_MULTITERMINAL___INIT___H +#define SHARED_BINDINGS_MULTITERMINAL___INIT___H + +#include "py/obj.h" + +void common_hal_multiterminal_schedule_secondary_terminal_read(mp_obj_t socket); +mp_obj_t common_hal_multiterminal_get_secondary_terminal(); +void common_hal_multiterminal_set_secondary_terminal(mp_obj_t secondary_terminal); +void common_hal_multiterminal_clear_secondary_terminal(); + +#endif // SHARED_BINDINGS_MULTITERMINAL___INIT___H diff --git a/shared-bindings/neopixel_write/__init__.c b/shared-bindings/neopixel_write/__init__.c new file mode 100644 index 00000000000..1ee66337bb0 --- /dev/null +++ b/shared-bindings/neopixel_write/__init__.c @@ -0,0 +1,89 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/neopixel_write/__init__.h" + +#include "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "supervisor/shared/translate.h" + +//| :mod:`neopixel_write` --- Low-level neopixel implementation +//| =========================================================== +//| +//| .. module:: neopixel_write +//| :synopsis: Low-level neopixel implementation +//| :platform: SAMD21 +//| +//| The `neopixel_write` module contains a helper method to write out bytes in +//| the 800khz neopixel protocol. +//| +//| For example, to turn off a single neopixel (like the status pixel on Express +//| boards.) +//| +//| .. code-block:: python +//| +//| import board +//| import neopixel_write +//| import digitalio +//| +//| pin = digitalio.DigitalInOut(board.NEOPIXEL) +//| pin.direction = digitalio.Direction.OUTPUT +//| pixel_off = bytearray([0, 0, 0]) +//| neopixel_write.neopixel_write(pin, pixel_off) +//| +//| .. function:: neopixel_write(digitalinout, buf) +//| +//| Write buf out on the given DigitalInOut. +//| +//| :param ~digitalio.DigitalInOut digitalinout: the DigitalInOut to output with +//| :param bytearray buf: The bytes to clock out. No assumption is made about color order +//| +STATIC mp_obj_t neopixel_write_neopixel_write_(mp_obj_t digitalinout_obj, mp_obj_t buf) { + if (!MP_OBJ_IS_TYPE(digitalinout_obj, &digitalio_digitalinout_type)) { + mp_raise_TypeError_varg(translate("Expected a %q"), digitalio_digitalinout_type.name); + } + // Convert parameters into expected types. + const digitalio_digitalinout_obj_t *digitalinout = MP_OBJ_TO_PTR(digitalinout_obj); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ); + // Call platform's neopixel write function with provided buffer and options. + common_hal_neopixel_write(digitalinout, (uint8_t*)bufinfo.buf, bufinfo.len); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(neopixel_write_neopixel_write_obj, neopixel_write_neopixel_write_); + +STATIC const mp_rom_map_elem_t neopixel_write_module_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write), (mp_obj_t)&neopixel_write_neopixel_write_obj }, +}; + +STATIC MP_DEFINE_CONST_DICT(neopixel_write_module_globals, neopixel_write_module_globals_table); + +const mp_obj_module_t neopixel_write_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&neopixel_write_module_globals, +}; diff --git a/shared-bindings/neopixel_write/__init__.h b/shared-bindings/neopixel_write/__init__.h new file mode 100644 index 00000000000..39b565ee2f1 --- /dev/null +++ b/shared-bindings/neopixel_write/__init__.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef SAMD_NEOPIXEL_WRITE_H +#define SAMD_NEOPIXEL_WRITE_H + +#include +#include + +#include "common-hal/digitalio/DigitalInOut.h" + +extern void common_hal_neopixel_write(const digitalio_digitalinout_obj_t* gpio, uint8_t *pixels, uint32_t numBytes); + +#endif diff --git a/shared-bindings/network/__init__.c b/shared-bindings/network/__init__.c new file mode 100644 index 00000000000..01763a73c5f --- /dev/null +++ b/shared-bindings/network/__init__.c @@ -0,0 +1,74 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 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 +#include +#include + +#include "py/objlist.h" +#include "py/runtime.h" +#include "py/mphal.h" +#include "py/mperrno.h" +#include "lib/netutils/netutils.h" + +#include "shared-bindings/network/__init__.h" + +#if CIRCUITPY_NETWORK + +//| :mod:`network` --- Network Interface Management +//| =============================================== +//| +//| .. module:: network +//| :synopsis: Network Interface Management +//| :platform: SAMD +//| +//| This module provides a registry of configured NICs. +//| It is used by the 'socket' module to look up a suitable +//| NIC when a socket is created. +//| +//| .. function:: route() +//| +//| Returns a list of all configured NICs. +//| + +STATIC mp_obj_t network_route(void) { + return MP_OBJ_FROM_PTR(&MP_STATE_PORT(mod_network_nic_list)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_route_obj, network_route); + +STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_network) }, + { MP_ROM_QSTR(MP_QSTR_route), MP_ROM_PTR(&network_route_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(mp_module_network_globals, mp_module_network_globals_table); + +const mp_obj_module_t network_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mp_module_network_globals, +}; + +#endif // CIRCUITPY_NETWORK diff --git a/shared-bindings/network/__init__.h b/shared-bindings/network/__init__.h new file mode 100644 index 00000000000..4fe5e75a37b --- /dev/null +++ b/shared-bindings/network/__init__.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython 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. + */ +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_NETWORK___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_NETWORK___INIT___H + +// nothing + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_NETWORK___INIT___H diff --git a/shared-bindings/nvm/ByteArray.c b/shared-bindings/nvm/ByteArray.c new file mode 100644 index 00000000000..31bedeacc0c --- /dev/null +++ b/shared-bindings/nvm/ByteArray.c @@ -0,0 +1,157 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/runtime0.h" +#include "shared-bindings/nvm/ByteArray.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: nvm +//| +//| :class:`ByteArray` -- Presents a stretch of non-volatile memory as a bytearray. +//| ================================================================================ +//| +//| Non-volatile memory is available as a byte array that persists over reloads +//| and power cycles. Each assignment causes an erase and write cycle so its recommended to assign +//| all values to change at once. +//| +//| Usage:: +//| +//| import microcontroller +//| microcontroller.nvm[0:3] = b"\xcc\x10\x00" +//| + +//| .. class:: ByteArray() +//| +//| Not currently dynamically supported. Access the sole instance through `microcontroller.nvm`. +//| + +//| .. method:: __len__() +//| +//| Return the length. This is used by (`len`) +//| +STATIC mp_obj_t nvm_bytearray_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + nvm_bytearray_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint16_t len = common_hal_nvm_bytearray_get_length(self); + switch (op) { + case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0); + case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len); + default: return MP_OBJ_NULL; // op not supported + } +} + +STATIC const mp_rom_map_elem_t nvm_bytearray_locals_dict_table[] = { +}; + +STATIC MP_DEFINE_CONST_DICT(nvm_bytearray_locals_dict, nvm_bytearray_locals_dict_table); + +STATIC mp_obj_t nvm_bytearray_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { + if (value == MP_OBJ_NULL) { + // delete item + // slice deletion + return MP_OBJ_NULL; // op not supported + } else { + nvm_bytearray_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (0) { +#if MICROPY_PY_BUILTINS_SLICE + } else if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) { + mp_bound_slice_t slice; + if (!mp_seq_get_fast_slice_indexes(common_hal_nvm_bytearray_get_length(self), index_in, &slice)) { + mp_raise_NotImplementedError(translate("only slices with step=1 (aka None) are supported")); + } + if (value != MP_OBJ_SENTINEL) { + #if MICROPY_PY_ARRAY_SLICE_ASSIGN + // Assign + size_t src_len = slice.stop - slice.start; + uint8_t* src_items; + if (MP_OBJ_IS_TYPE(value, &mp_type_array) || + MP_OBJ_IS_TYPE(value, &mp_type_bytearray) || + MP_OBJ_IS_TYPE(value, &mp_type_memoryview) || + MP_OBJ_IS_TYPE(value, &mp_type_bytes)) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(value, &bufinfo, MP_BUFFER_READ); + if (bufinfo.len != src_len) { + mp_raise_ValueError(translate("Slice and value different lengths.")); + } + src_len = bufinfo.len; + src_items = bufinfo.buf; + if (1 != mp_binary_get_size('@', bufinfo.typecode, NULL)) { + mp_raise_ValueError(translate("Array values should be single bytes.")); + } + } else { + mp_raise_NotImplementedError(translate("array/bytes required on right side")); + } + + if (!common_hal_nvm_bytearray_set_bytes(self, slice.start, src_items, src_len)) { + mp_raise_RuntimeError(translate("Unable to write to nvm.")); + } + return mp_const_none; + #else + return MP_OBJ_NULL; // op not supported + #endif + } else { + // Read slice. + size_t len = slice.stop - slice.start; + uint8_t *items = m_new(uint8_t, len); + common_hal_nvm_bytearray_get_bytes(self, slice.start, len, items); + return mp_obj_new_bytearray_by_ref(len, items); + } +#endif + } else { + // Single index rather than slice. + size_t index = mp_get_index(self->base.type, common_hal_nvm_bytearray_get_length(self), + index_in, false); + if (value == MP_OBJ_SENTINEL) { + // load + uint8_t value_out; + common_hal_nvm_bytearray_get_bytes(self, index, 1, &value_out); + return MP_OBJ_NEW_SMALL_INT(value_out); + } else { + // store + mp_int_t byte_value = mp_obj_get_int(value); + if (byte_value > 0xff || byte_value < 0) { + mp_raise_ValueError(translate("Bytes must be between 0 and 255.")); + } + uint8_t short_value = byte_value; + if (!common_hal_nvm_bytearray_set_bytes(self, index, &short_value, 1)) { + mp_raise_RuntimeError(translate("Unable to write to nvm.")); + } + return mp_const_none; + } + } + } +} + +const mp_obj_type_t nvm_bytearray_type = { + { &mp_type_type }, + .name = MP_QSTR_ByteArray, + .subscr = nvm_bytearray_subscr, + .unary_op = nvm_bytearray_unary_op, + .print = NULL, + .locals_dict = (mp_obj_t)&nvm_bytearray_locals_dict, +}; diff --git a/shared-bindings/nvm/ByteArray.h b/shared-bindings/nvm/ByteArray.h new file mode 100644 index 00000000000..5eee3ab5026 --- /dev/null +++ b/shared-bindings/nvm/ByteArray.h @@ -0,0 +1,43 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_NVM_BYTEARRAY_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_NVM_BYTEARRAY_H + +#include "common-hal/nvm/ByteArray.h" + +const mp_obj_type_t nvm_bytearray_type; + +uint32_t common_hal_nvm_bytearray_get_length(nvm_bytearray_obj_t *self); + +bool common_hal_nvm_bytearray_set_bytes(nvm_bytearray_obj_t *self, + uint32_t start_index, uint8_t* values, uint32_t len); +// len and values are intentionally swapped to signify values is an output and +// also leverage the compiler to validate uses are expected. +void common_hal_nvm_bytearray_get_bytes(nvm_bytearray_obj_t *self, + uint32_t start_index, uint32_t len, uint8_t* values); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_NVM_BYTEARRAY_H diff --git a/shared-bindings/nvm/__init__.c b/shared-bindings/nvm/__init__.c new file mode 100644 index 00000000000..811855c0933 --- /dev/null +++ b/shared-bindings/nvm/__init__.c @@ -0,0 +1,61 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" + +#include "shared-bindings/nvm/__init__.h" +#include "shared-bindings/nvm/ByteArray.h" + +//| :mod:`nvm` --- Non-volatile memory +//| =========================================================== +//| +//| .. module:: nvm +//| :synopsis: Non-volatile memory +//| :platform: SAMD21 +//| +//| The `nvm` module allows you to store whatever raw bytes you wish in a +//| reserved section non-volatile memory. +//| + +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| ByteArray +STATIC const mp_rom_map_elem_t nvm_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_nvm) }, + { MP_ROM_QSTR(MP_QSTR_ByteArray), MP_ROM_PTR(&nvm_bytearray_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(nvm_module_globals, nvm_module_globals_table); + +const mp_obj_module_t nvm_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&nvm_module_globals, +}; diff --git a/shared-bindings/nvm/__init__.h b/shared-bindings/nvm/__init__.h new file mode 100644 index 00000000000..9e179997474 --- /dev/null +++ b/shared-bindings/nvm/__init__.h @@ -0,0 +1,30 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef SHARED_BINDINGS_NVM_H +#define SHARED_BINDINGS_NVM_H + +#endif // SHARED_BINDINGS_NVM_H diff --git a/shared-bindings/os/__init__.c b/shared-bindings/os/__init__.c new file mode 100644 index 00000000000..55ebd6f59f4 --- /dev/null +++ b/shared-bindings/os/__init__.c @@ -0,0 +1,238 @@ +/* + * 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 Josef Gajdusek + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "extmod/vfs.h" +#include "lib/oofatfs/ff.h" +#include "lib/oofatfs/diskio.h" +#include "py/mpstate.h" +#include "py/obj.h" +#include "py/runtime.h" +#include "shared-bindings/os/__init__.h" + +//| :mod:`os` --- functions that an OS normally provides +//| ======================================================== +//| +//| .. module:: os +//| :synopsis: functions that an OS normally provides +//| :platform: SAMD21 +//| +//| The `os` module is a strict subset of the CPython `cpython:os` module. So, +//| code written in CircuitPython will work in CPython but not necessarily the +//| other way around. +//| + +//| .. function:: uname() +//| +//| Returns a named tuple of operating specific and CircuitPython port +//| specific information. +//| +STATIC mp_obj_t os_uname(void) { + return common_hal_os_uname(); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_uname_obj, os_uname); + +//| .. function:: chdir(path) +//| +//| Change current directory. +//| +mp_obj_t os_chdir(mp_obj_t path_in) { + const char *path = mp_obj_str_get_str(path_in); + common_hal_os_chdir(path); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(os_chdir_obj, os_chdir); + +//| .. function:: getcwd() +//| +//| Get the current directory. +//| +mp_obj_t os_getcwd(void) { + return common_hal_os_getcwd(); +} +MP_DEFINE_CONST_FUN_OBJ_0(os_getcwd_obj, os_getcwd); + +//| .. function:: listdir([dir]) +//| +//| With no argument, list the current directory. Otherwise list the given directory. +//| +mp_obj_t os_listdir(size_t n_args, const mp_obj_t *args) { + const char* path; + if (n_args == 1) { + path = mp_obj_str_get_str(args[0]); + } else { + path = mp_obj_str_get_str(common_hal_os_getcwd()); + } + return common_hal_os_listdir(path); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir); + +//| .. function:: mkdir(path) +//| +//| Create a new directory. +//| +mp_obj_t os_mkdir(mp_obj_t path_in) { + const char *path = mp_obj_str_get_str(path_in); + common_hal_os_mkdir(path); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir); + +//| .. function:: remove(path) +//| +//| Remove a file. +//| +mp_obj_t os_remove(mp_obj_t path_in) { + const char *path = mp_obj_str_get_str(path_in); + common_hal_os_remove(path); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove); + +//| .. function:: rmdir(path) +//| +//| Remove a directory. +//| +mp_obj_t os_rename(mp_obj_t old_path_in, mp_obj_t new_path_in) { + const char *old_path = mp_obj_str_get_str(old_path_in); + const char *new_path = mp_obj_str_get_str(new_path_in); + common_hal_os_rename(old_path, new_path); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(os_rename_obj, os_rename); + +//| .. function:: rename(old_path, new_path) +//| +//| Rename a file. +//| +mp_obj_t os_rmdir(mp_obj_t path_in) { + const char *path = mp_obj_str_get_str(path_in); + common_hal_os_rmdir(path); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(os_rmdir_obj, os_rmdir); + +//| .. function:: stat(path) +//| +//| Get the status of a file or directory. +//| +mp_obj_t os_stat(mp_obj_t path_in) { + const char *path = mp_obj_str_get_str(path_in); + return common_hal_os_stat(path); +} +MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat); + +//| .. function:: statvfs(path) +//| +//| Get the status of a fileystem. +//| +//| Returns a tuple with the filesystem information in the following order: +//| +//| * ``f_bsize`` -- file system block size +//| * ``f_frsize`` -- fragment size +//| * ``f_blocks`` -- size of fs in f_frsize units +//| * ``f_bfree`` -- number of free blocks +//| * ``f_bavail`` -- number of free blocks for unpriviliged users +//| * ``f_files`` -- number of inodes +//| * ``f_ffree`` -- number of free inodes +//| * ``f_favail`` -- number of free inodes for unpriviliged users +//| * ``f_flag`` -- mount flags +//| * ``f_namemax`` -- maximum filename length +//| +//| Parameters related to inodes: ``f_files``, ``f_ffree``, ``f_avail`` +//| and the ``f_flags`` parameter may return ``0`` as they can be unavailable +//| in a port-specific implementation. +//| +mp_obj_t os_statvfs(mp_obj_t path_in) { + const char *path = mp_obj_str_get_str(path_in); + return common_hal_os_statvfs(path); +} +MP_DEFINE_CONST_FUN_OBJ_1(os_statvfs_obj, os_statvfs); + +//| .. function:: sync() +//| +//| Sync all filesystems. +//| +STATIC mp_obj_t os_sync(void) { + for (mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) { + // this assumes that vfs->obj is fs_user_mount_t with block device functions + disk_ioctl(MP_OBJ_TO_PTR(vfs->obj), CTRL_SYNC, NULL); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync); + +//| .. function:: urandom(size) +//| +//| Returns a string of *size* random bytes based on a hardware True Random +//| Number Generator. When not available, it will raise a NotImplementedError. +//| +STATIC mp_obj_t os_urandom(mp_obj_t size_in) { + mp_int_t size = mp_obj_get_int(size_in); + uint8_t tmp[size]; + if (!common_hal_os_urandom(tmp, size)) { + mp_raise_NotImplementedError(translate("No hardware random available")); + } + return mp_obj_new_bytes(tmp, size); +} +MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom); + +STATIC const mp_rom_map_elem_t os_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_os) }, + + { MP_ROM_QSTR(MP_QSTR_uname), MP_ROM_PTR(&os_uname_obj) }, + + { MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&os_chdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&os_getcwd_obj) }, + { MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&os_listdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&os_mkdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&os_remove_obj) }, + { MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&os_rename_obj) }, + { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&os_rmdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&os_stat_obj) }, + { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&os_statvfs_obj) }, + { MP_ROM_QSTR(MP_QSTR_unlink), MP_ROM_PTR(&os_remove_obj) }, // unlink aliases to remove + + { MP_ROM_QSTR(MP_QSTR_sync), MP_ROM_PTR(&os_sync_obj) }, + + { MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&os_urandom_obj) }, + +//| .. data:: sep +//| +//| Separator used to delineate path components such as folder and file names. +//| + { MP_ROM_QSTR(MP_QSTR_sep), MP_ROM_QSTR(MP_QSTR__slash_) }, +}; + +STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table); + +const mp_obj_module_t os_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&os_module_globals, +}; diff --git a/shared-bindings/os/__init__.h b/shared-bindings/os/__init__.h new file mode 100644 index 00000000000..3776fef6437 --- /dev/null +++ b/shared-bindings/os/__init__.h @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_OS___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_OS___INIT___H + +#include +#include + +#include "py/objtuple.h" + +const mp_rom_obj_tuple_t common_hal_os_uname_info_obj; + +mp_obj_t common_hal_os_uname(void); +void common_hal_os_chdir(const char* path); +mp_obj_t common_hal_os_getcwd(void); +mp_obj_t common_hal_os_listdir(const char* path); +void common_hal_os_mkdir(const char* path); +void common_hal_os_remove(const char* path); +void common_hal_os_rename(const char* old_path, const char* new_path); +void common_hal_os_rmdir(const char* path); +mp_obj_t common_hal_os_stat(const char* path); +mp_obj_t common_hal_os_statvfs(const char* path); + +// Returns true if data was correctly sourced from a true random number generator. +bool common_hal_os_urandom(uint8_t* buffer, mp_uint_t length); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_OS___INIT___H diff --git a/shared-bindings/ps2io/Ps2.c b/shared-bindings/ps2io/Ps2.c new file mode 100644 index 00000000000..fb5c24b85ce --- /dev/null +++ b/shared-bindings/ps2io/Ps2.c @@ -0,0 +1,243 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Elvis Pfutzenreuter + * + * 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 + +#include "lib/utils/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/runtime0.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/ps2io/Ps2.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: ps2io +//| +//| :class:`Ps2` -- Communicate with a PS/2 keyboard or mouse +//| ========================================================= +//| +//| Ps2 implements the PS/2 keyboard/mouse serial protocol, used in +//| legacy devices. It is similar to UART but there are only two +//| lines (Data and Clock). PS/2 devices are 5V, so bidirectional +//| level converters must be used to connect the I/O lines to pins +//| of 3.3V boards. +//| +//| .. class:: Ps2(data_pin, clock_pin) +//| +//| Create a Ps2 object associated with the given pins. +//| +//| :param ~microcontroller.Pin data_pin: Pin tied to data wire. +//| :param ~microcontroller.Pin clock_pin: Pin tied to clock wire. +//| This pin must support interrupts. +//| +//| Read one byte from PS/2 keyboard and turn on Scroll Lock LED:: +//| +//| import ps2io +//| import board +//| +//| kbd = ps2io.Ps2(board.D10, board.D11) +//| +//| while len(kbd) == 0: +//| pass +//| +//| print(kbd.popleft()) +//| print(kbd.sendcmd(0xed)) +//| print(kbd.sendcmd(0x01)) +//| +STATIC mp_obj_t ps2io_ps2_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_datapin, ARG_clkpin }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_datapin, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_clkpin, MP_ARG_REQUIRED | MP_ARG_OBJ }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + assert_pin(args[ARG_clkpin].u_obj, false); + assert_pin(args[ARG_datapin].u_obj, false); + const mcu_pin_obj_t* clkpin = MP_OBJ_TO_PTR(args[ARG_clkpin].u_obj); + assert_pin_free(clkpin); + const mcu_pin_obj_t* datapin = MP_OBJ_TO_PTR(args[ARG_datapin].u_obj); + assert_pin_free(datapin); + + ps2io_ps2_obj_t *self = m_new_obj(ps2io_ps2_obj_t); + self->base.type = &ps2io_ps2_type; + + common_hal_ps2io_ps2_construct(self, datapin, clkpin); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialises the Ps2 and releases any hardware resources for reuse. +//| +STATIC mp_obj_t ps2io_ps2_deinit(mp_obj_t self_in) { + ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_ps2io_ps2_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(ps2io_ps2_deinit_obj, ps2io_ps2_deinit); + +STATIC void check_for_deinit(ps2io_ps2_obj_t *self) { + if (common_hal_ps2io_ps2_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t ps2io_ps2_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_ps2io_ps2_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ps2io_ps2___exit___obj, 4, 4, ps2io_ps2_obj___exit__); + +//| .. method:: popleft() +//| +//| Removes and returns the oldest received byte. When buffer +//| is empty, raises an IndexError exception. +//| +STATIC mp_obj_t ps2io_ps2_obj_popleft(mp_obj_t self_in) { + ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + int b = common_hal_ps2io_ps2_popleft(self); + if (b < 0) { + mp_raise_IndexError(translate("Pop from an empty Ps2 buffer")); + } + return MP_OBJ_NEW_SMALL_INT(b); +} +MP_DEFINE_CONST_FUN_OBJ_1(ps2io_ps2_popleft_obj, ps2io_ps2_obj_popleft); + +//| .. method:: sendcmd(byte) +//| +//| Sends a command byte to PS/2. Returns the response byte, typically +//| the general ack value (0xFA). Some commands return additional data +//| which is available through :py:func:`popleft()`. +//| +//| Raises a RuntimeError in case of failure. The root cause can be found +//| by calling :py:func:`clear_errors()`. It is advisable to call +//| :py:func:`clear_errors()` before :py:func:`sendcmd()` to flush any +//| previous errors. +//| +//| :param int byte: byte value of the command +//| +STATIC mp_obj_t ps2io_ps2_obj_sendcmd(mp_obj_t self_in, mp_obj_t ob) { + ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + mp_int_t cmd = mp_obj_get_int(ob) & 0xff; + int resp = common_hal_ps2io_ps2_sendcmd(self, cmd); + if (resp < 0) { + mp_raise_RuntimeError(translate("Failed sending command.")); + } + return MP_OBJ_NEW_SMALL_INT(resp); +} +MP_DEFINE_CONST_FUN_OBJ_2(ps2io_ps2_sendcmd_obj, ps2io_ps2_obj_sendcmd); + +//| .. method:: clear_errors() +//| +//| Returns and clears a bitmap with latest recorded communication errors. +//| +//| Reception errors (arise asynchronously, as data is received): +//| +//| 0x01: start bit not 0 +//| +//| 0x02: timeout +//| +//| 0x04: parity bit error +//| +//| 0x08: stop bit not 1 +//| +//| 0x10: buffer overflow, newest data discarded +//| +//| Transmission errors (can only arise in the course of sendcmd()): +//| +//| 0x100: clock pin didn't go to LO in time +//| +//| 0x200: clock pin didn't go to HI in time +//| +//| 0x400: data pin didn't ACK +//| +//| 0x800: clock pin didn't ACK +//| +//| 0x1000: device didn't respond to RTS +//| +//| 0x2000: device didn't send a response byte in time +//| +STATIC mp_obj_t ps2io_ps2_obj_clear_errors(mp_obj_t self_in) { + ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + return MP_OBJ_NEW_SMALL_INT(common_hal_ps2io_ps2_clear_errors(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(ps2io_ps2_clear_errors_obj, ps2io_ps2_obj_clear_errors); + +//| .. method:: __len__() +//| +//| Returns the number of received bytes in buffer, available +//| to :py:func:`popleft()`. +//| +STATIC mp_obj_t ps2_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + uint16_t len = common_hal_ps2io_ps2_get_len(self); + switch (op) { + case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0); + case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len); + default: return MP_OBJ_NULL; // op not supported + } +} + +STATIC const mp_rom_map_elem_t ps2io_ps2_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&ps2io_ps2_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&ps2io_ps2___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_popleft), MP_ROM_PTR(&ps2io_ps2_popleft_obj) }, + { MP_ROM_QSTR(MP_QSTR_sendcmd), MP_ROM_PTR(&ps2io_ps2_sendcmd_obj) }, + { MP_ROM_QSTR(MP_QSTR_clear_errors), MP_ROM_PTR(&ps2io_ps2_clear_errors_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(ps2io_ps2_locals_dict, ps2io_ps2_locals_dict_table); + +const mp_obj_type_t ps2io_ps2_type = { + { &mp_type_type }, + .name = MP_QSTR_Ps2, + .make_new = ps2io_ps2_make_new, + .unary_op = ps2_unary_op, + .locals_dict = (mp_obj_dict_t*)&ps2io_ps2_locals_dict, +}; diff --git a/shared-bindings/ps2io/Ps2.h b/shared-bindings/ps2io/Ps2.h new file mode 100644 index 00000000000..523869d55bf --- /dev/null +++ b/shared-bindings/ps2io/Ps2.h @@ -0,0 +1,45 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Elvis Pfutzenreuter + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO_PS2_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO_PS2_H + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/ps2io/Ps2.h" + +extern const mp_obj_type_t ps2io_ps2_type; + +extern void common_hal_ps2io_ps2_construct(ps2io_ps2_obj_t* self, + const mcu_pin_obj_t* data_pin, const mcu_pin_obj_t* clk_pin); +extern void common_hal_ps2io_ps2_deinit(ps2io_ps2_obj_t* self); +extern bool common_hal_ps2io_ps2_deinited(ps2io_ps2_obj_t* self); +extern uint16_t common_hal_ps2io_ps2_get_len(ps2io_ps2_obj_t* self); +extern int16_t common_hal_ps2io_ps2_popleft(ps2io_ps2_obj_t* self); +extern int16_t common_hal_ps2io_ps2_sendcmd(ps2io_ps2_obj_t* self, uint8_t b); +extern uint16_t common_hal_ps2io_ps2_clear_errors(ps2io_ps2_obj_t* self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO_PS2_H diff --git a/shared-bindings/ps2io/__init__.c b/shared-bindings/ps2io/__init__.c new file mode 100644 index 00000000000..ec7c43e51fb --- /dev/null +++ b/shared-bindings/ps2io/__init__.c @@ -0,0 +1,73 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Elvis Pfutzenreuter + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/ps2io/Ps2.h" + +//| :mod:`ps2io` --- Support for PS/2 protocol +//| ===================================================== +//| +//| .. module:: ps2io +//| :synopsis: Support for PS/2 based devices +//| :platform: SAMD21 +//| +//| The `ps2io` module contains classes to provide PS/2 communication. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Ps2 +//| + +//| .. warning:: This module is not available in some SAMD21 builds. See the +//| :ref:`module-support-matrix` for more info. +//| + +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed if the program continues after use. To do so, either +//| call :py:meth:`!deinit` or use a context manager. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| + +STATIC const mp_rom_map_elem_t ps2io_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ps2io) }, + { MP_ROM_QSTR(MP_QSTR_Ps2), MP_ROM_PTR(&ps2io_ps2_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(ps2io_module_globals, ps2io_module_globals_table); + +const mp_obj_module_t ps2io_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&ps2io_module_globals, +}; diff --git a/shared-bindings/ps2io/__init__.h b/shared-bindings/ps2io/__init__.h new file mode 100644 index 00000000000..1ff3d97b5cc --- /dev/null +++ b/shared-bindings/ps2io/__init__.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * Copyright (c) 2019 Elvis Pfutzenreuter + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO___INIT___H + +#include "py/obj.h" + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO___INIT___H diff --git a/shared-bindings/pulseio/PWMOut.c b/shared-bindings/pulseio/PWMOut.c new file mode 100644 index 00000000000..40981e0a81e --- /dev/null +++ b/shared-bindings/pulseio/PWMOut.c @@ -0,0 +1,242 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 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 + +#include "lib/utils/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/pulseio/PWMOut.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: pulseio +//| +//| :class:`PWMOut` -- Output a Pulse Width Modulated signal +//| ======================================================== +//| +//| PWMOut can be used to output a PWM signal on a given pin. +//| +//| .. class:: PWMOut(pin, *, duty_cycle=0, frequency=500, variable_frequency=False) +//| +//| Create a PWM object associated with the given pin. This allows you to +//| write PWM signals out on the given pin. Frequency is fixed after init +//| unless ``variable_frequency`` is True. +//| +//| .. note:: When ``variable_frequency`` is True, further PWM outputs may be +//| limited because it may take more internal resources to be flexible. So, +//| when outputting both fixed and flexible frequency signals construct the +//| fixed outputs first. +//| +//| :param ~microcontroller.Pin pin: The pin to output to +//| :param int duty_cycle: The fraction of each pulse which is high. 16-bit +//| :param int frequency: The target frequency in Hertz (32-bit) +//| :param bool variable_frequency: True if the frequency will change over time +//| +//| Simple LED fade:: +//| +//| import pulseio +//| import board +//| +//| pwm = pulseio.PWMOut(board.D13) # output on D13 +//| pwm.duty_cycle = 2 ** 15 # Cycles the pin with 50% duty cycle (half of 2 ** 16) at the default 500hz +//| +//| PWM at specific frequency (servos and motors):: +//| +//| import pulseio +//| import board +//| +//| pwm = pulseio.PWMOut(board.D13, frequency=50) +//| pwm.duty_cycle = 2 ** 15 # Cycles the pin with 50% duty cycle (half of 2 ** 16) at 50hz +//| +//| Variable frequency (usually tones):: +//| +//| import pulseio +//| import board +//| import time +//| +//| pwm = pulseio.PWMOut(board.D13, duty_cycle=2 ** 15, frequency=440, variable_frequency=True) +//| time.sleep(0.2) +//| pwm.frequency = 880 +//| time.sleep(0.1) +//| +STATIC mp_obj_t pulseio_pwmout_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + enum { ARG_pin, ARG_duty_cycle, ARG_frequency, ARG_variable_frequency }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ, }, + { MP_QSTR_duty_cycle, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 500} }, + { MP_QSTR_variable_frequency, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + mp_arg_val_t parsed_args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, parsed_args); + + mp_obj_t pin_obj = parsed_args[ARG_pin].u_obj; + assert_pin(pin_obj, false); + const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj); + assert_pin_free(pin); + + uint16_t duty_cycle = parsed_args[ARG_duty_cycle].u_int; + uint32_t frequency = parsed_args[ARG_frequency].u_int; + bool variable_frequency = parsed_args[ARG_variable_frequency].u_bool; + + // create PWM object from the given pin + pulseio_pwmout_obj_t *self = m_new_obj(pulseio_pwmout_obj_t); + self->base.type = &pulseio_pwmout_type; + pwmout_result_t result = common_hal_pulseio_pwmout_construct(self, pin, duty_cycle, frequency, variable_frequency); + if (result == PWMOUT_INVALID_PIN) { + mp_raise_ValueError(translate("Invalid pin")); + } else if (result == PWMOUT_INVALID_FREQUENCY) { + mp_raise_ValueError(translate("Invalid PWM frequency")); + } else if (result == PWMOUT_ALL_TIMERS_ON_PIN_IN_USE) { + mp_raise_ValueError(translate("All timers for this pin are in use")); + } else if (result == PWMOUT_ALL_TIMERS_IN_USE) { + mp_raise_RuntimeError(translate("All timers in use")); + } + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialises the PWMOut and releases any hardware resources for reuse. +//| +STATIC mp_obj_t pulseio_pwmout_deinit(mp_obj_t self_in) { + pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_pulseio_pwmout_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_deinit_obj, pulseio_pwmout_deinit); + +STATIC void check_for_deinit(pulseio_pwmout_obj_t *self) { + if (common_hal_pulseio_pwmout_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t pulseio_pwmout_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_pulseio_pwmout_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pwmout___exit___obj, 4, 4, pulseio_pwmout_obj___exit__); + +//| .. attribute:: duty_cycle +//| +//| 16 bit value that dictates how much of one cycle is high (1) versus low +//| (0). 0xffff will always be high, 0 will always be low and 0x7fff will +//| be half high and then half low. +STATIC mp_obj_t pulseio_pwmout_obj_get_duty_cycle(mp_obj_t self_in) { + pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pwmout_get_duty_cycle(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_get_duty_cycle_obj, pulseio_pwmout_obj_get_duty_cycle); + +STATIC mp_obj_t pulseio_pwmout_obj_set_duty_cycle(mp_obj_t self_in, mp_obj_t duty_cycle) { + pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + mp_int_t duty = mp_obj_get_int(duty_cycle); + if (duty < 0 || duty > 0xffff) { + mp_raise_ValueError(translate("PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)")); + } + common_hal_pulseio_pwmout_set_duty_cycle(self, duty); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(pulseio_pwmout_set_duty_cycle_obj, pulseio_pwmout_obj_set_duty_cycle); + +const mp_obj_property_t pulseio_pwmout_duty_cycle_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pulseio_pwmout_get_duty_cycle_obj, + (mp_obj_t)&pulseio_pwmout_set_duty_cycle_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: frequency +//| +//| 32 bit value that dictates the PWM frequency in Hertz (cycles per +//| second). Only writeable when constructed with ``variable_frequency=True``. +//| +STATIC mp_obj_t pulseio_pwmout_obj_get_frequency(mp_obj_t self_in) { + pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pwmout_get_frequency(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_get_frequency_obj, pulseio_pwmout_obj_get_frequency); + +STATIC mp_obj_t pulseio_pwmout_obj_set_frequency(mp_obj_t self_in, mp_obj_t frequency) { + pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (!common_hal_pulseio_pwmout_get_variable_frequency(self)) { + mp_raise_AttributeError(translate( + "PWM frequency not writable when variable_frequency is False on " + "construction.")); + } + common_hal_pulseio_pwmout_set_frequency(self, mp_obj_get_int(frequency)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(pulseio_pwmout_set_frequency_obj, pulseio_pwmout_obj_set_frequency); + +const mp_obj_property_t pulseio_pwmout_frequency_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pulseio_pwmout_get_frequency_obj, + (mp_obj_t)&pulseio_pwmout_set_frequency_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t pulseio_pwmout_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pulseio_pwmout_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&pulseio_pwmout___exit___obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_duty_cycle), MP_ROM_PTR(&pulseio_pwmout_duty_cycle_obj) }, + { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&pulseio_pwmout_frequency_obj) }, + // TODO(tannewt): Add enabled to determine whether the signal is output + // without giving up the resources. Useful for IR output. +}; +STATIC MP_DEFINE_CONST_DICT(pulseio_pwmout_locals_dict, pulseio_pwmout_locals_dict_table); + +const mp_obj_type_t pulseio_pwmout_type = { + { &mp_type_type }, + .name = MP_QSTR_PWMOut, + .make_new = pulseio_pwmout_make_new, + .locals_dict = (mp_obj_dict_t*)&pulseio_pwmout_locals_dict, +}; diff --git a/shared-bindings/pulseio/PWMOut.h b/shared-bindings/pulseio/PWMOut.h new file mode 100644 index 00000000000..c01e0c9261b --- /dev/null +++ b/shared-bindings/pulseio/PWMOut.h @@ -0,0 +1,58 @@ +/* + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PWMOUT_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PWMOUT_H + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/pulseio/PWMOut.h" + +extern const mp_obj_type_t pulseio_pwmout_type; + +typedef enum { + PWMOUT_OK, + PWMOUT_INVALID_PIN, + PWMOUT_INVALID_FREQUENCY, + PWMOUT_ALL_TIMERS_ON_PIN_IN_USE, + PWMOUT_ALL_TIMERS_IN_USE +} pwmout_result_t; + +extern pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, + const mcu_pin_obj_t* pin, uint16_t duty, uint32_t frequency, + bool variable_frequency); +extern void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self); +extern bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self); +extern void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty); +extern uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self); +extern void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_t frequency); +extern uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self); +extern bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self); + +// This is used by the supervisor to claim PWMOut devices indefinitely. +extern void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self); +extern void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PWMOUT_H diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c new file mode 100644 index 00000000000..8b69109f04b --- /dev/null +++ b/shared-bindings/pulseio/PulseIn.c @@ -0,0 +1,321 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "lib/utils/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/runtime0.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/pulseio/PulseIn.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: pulseio +//| +//| :class:`PulseIn` -- Read a series of pulse durations +//| ======================================================== +//| +//| PulseIn is used to measure a series of active and idle pulses. This is +//| commonly used in infrared receivers and low cost temperature sensors (DHT). +//| The pulsed signal consists of timed active and idle periods. Unlike PWM, +//| there is no set duration for active and idle pairs. +//| +//| .. class:: PulseIn(pin, maxlen=2, *, idle_state=False) +//| +//| Create a PulseIn object associated with the given pin. The object acts as +//| a read-only sequence of pulse lengths with a given max length. When it is +//| active, new pulse lengths are added to the end of the list. When there is +//| no more room (len() == `maxlen`) the oldest pulse length is removed to +//| make room. +//| +//| :param ~microcontroller.Pin pin: Pin to read pulses from. +//| :param int maxlen: Maximum number of pulse durations to store at once +//| :param bool idle_state: Idle state of the pin. At start and after `resume` +//| the first recorded pulse will the opposite state from idle. +//| +//| Read a short series of pulses:: +//| +//| import pulseio +//| import board +//| +//| pulses = pulseio.PulseIn(board.D7) +//| +//| # Wait for an active pulse +//| while len(pulses) == 0: +//| pass +//| # Pause while we do something with the pulses +//| pulses.pause() +//| +//| # Print the pulses. pulses[0] is an active pulse unless the length +//| # reached max length and idle pulses are recorded. +//| print(pulses) +//| +//| # Clear the rest +//| pulses.clear() +//| +//| # Resume with an 80 microsecond active pulse +//| pulses.resume(80) +//| +STATIC mp_obj_t pulseio_pulsein_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_pin, ARG_maxlen, ARG_idle_state }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_maxlen, MP_ARG_INT, {.u_int = 2} }, + { MP_QSTR_idle_state, MP_ARG_BOOL, {.u_bool = false} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + assert_pin(args[ARG_pin].u_obj, false); + const mcu_pin_obj_t* pin = MP_OBJ_TO_PTR(args[ARG_pin].u_obj); + assert_pin_free(pin); + + pulseio_pulsein_obj_t *self = m_new_obj(pulseio_pulsein_obj_t); + self->base.type = &pulseio_pulsein_type; + + common_hal_pulseio_pulsein_construct(self, pin, args[ARG_maxlen].u_int, + args[ARG_idle_state].u_bool); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialises the PulseIn and releases any hardware resources for reuse. +//| +STATIC mp_obj_t pulseio_pulsein_deinit(mp_obj_t self_in) { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_pulseio_pulsein_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_deinit_obj, pulseio_pulsein_deinit); + +STATIC void check_for_deinit(pulseio_pulsein_obj_t *self) { + if (common_hal_pulseio_pulsein_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t pulseio_pulsein_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_pulseio_pulsein_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pulsein___exit___obj, 4, 4, pulseio_pulsein_obj___exit__); + +//| .. method:: pause() +//| +//| Pause pulse capture +//| +STATIC mp_obj_t pulseio_pulsein_obj_pause(mp_obj_t self_in) { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + common_hal_pulseio_pulsein_pause(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_pause_obj, pulseio_pulsein_obj_pause); + +//| .. method:: resume(trigger_duration=0) +//| +//| Resumes pulse capture after an optional trigger pulse. +//| +//| .. warning:: Using trigger pulse with a device that drives both high and +//| low signals risks a short. Make sure your device is open drain (only +//| drives low) when using a trigger pulse. You most likely added a +//| "pull-up" resistor to your circuit to do this. +//| +//| :param int trigger_duration: trigger pulse duration in microseconds +//| +STATIC mp_obj_t pulseio_pulsein_obj_resume(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_trigger_duration }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_trigger_duration, MP_ARG_INT, {.u_int = 0} }, + }; + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + common_hal_pulseio_pulsein_resume(self, args[ARG_trigger_duration].u_int); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(pulseio_pulsein_resume_obj, 1, pulseio_pulsein_obj_resume); + +//| .. method:: clear() +//| +//| Clears all captured pulses +//| +STATIC mp_obj_t pulseio_pulsein_obj_clear(mp_obj_t self_in) { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + common_hal_pulseio_pulsein_clear(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_clear_obj, pulseio_pulsein_obj_clear); + +//| .. method:: popleft() +//| +//| Removes and returns the oldest read pulse. +//| +STATIC mp_obj_t pulseio_pulsein_obj_popleft(mp_obj_t self_in) { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pulsein_popleft(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_popleft_obj, pulseio_pulsein_obj_popleft); + +//| .. attribute:: maxlen +//| +//| The maximum length of the PulseIn. When len() is equal to maxlen, +//| it is unclear which pulses are active and which are idle. +//| +STATIC mp_obj_t pulseio_pulsein_obj_get_maxlen(mp_obj_t self_in) { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pulsein_get_maxlen(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_get_maxlen_obj, pulseio_pulsein_obj_get_maxlen); + +const mp_obj_property_t pulseio_pulsein_maxlen_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pulseio_pulsein_get_maxlen_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: paused +//| +//| True when pulse capture is paused as a result of :py:func:`pause` or an error during capture +//| such as a signal that is too fast. +//| +STATIC mp_obj_t pulseio_pulsein_obj_get_paused(mp_obj_t self_in) { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + return mp_obj_new_bool(common_hal_pulseio_pulsein_get_paused(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_get_paused_obj, pulseio_pulsein_obj_get_paused); + +const mp_obj_property_t pulseio_pulsein_paused_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pulseio_pulsein_get_paused_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: __len__() +//| +//| Returns the current pulse length +//| +//| This allows you to:: +//| +//| pulses = pulseio.PulseIn(pin) +//| print(len(pulses)) +//| +STATIC mp_obj_t pulsein_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + uint16_t len = common_hal_pulseio_pulsein_get_len(self); + switch (op) { + case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0); + case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len); + default: return MP_OBJ_NULL; // op not supported + } +} + +//| .. method:: __getitem__(index) +//| +//| Returns the value at the given index or values in slice. +//| +//| This allows you to:: +//| +//| pulses = pulseio.PulseIn(pin) +//| print(pulses[0]) +//| +STATIC mp_obj_t pulsein_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) { + if (value == mp_const_none) { + // delete item + mp_raise_AttributeError(translate("Cannot delete values")); + } else { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) { + mp_raise_NotImplementedError(translate("Slices not supported")); + } else { + size_t index = mp_get_index(&pulseio_pulsein_type, common_hal_pulseio_pulsein_get_len(self), index_obj, false); + if (value == MP_OBJ_SENTINEL) { + // load + return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pulsein_get_item(self, index)); + } else { + mp_raise_AttributeError(translate("Read-only")); + } + } + } + return mp_const_none; +} + +STATIC const mp_rom_map_elem_t pulseio_pulsein_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pulseio_pulsein_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&pulseio_pulsein___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_pause), MP_ROM_PTR(&pulseio_pulsein_pause_obj) }, + { MP_ROM_QSTR(MP_QSTR_resume), MP_ROM_PTR(&pulseio_pulsein_resume_obj) }, + { MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&pulseio_pulsein_clear_obj) }, + { MP_ROM_QSTR(MP_QSTR_popleft), MP_ROM_PTR(&pulseio_pulsein_popleft_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_maxlen), MP_ROM_PTR(&pulseio_pulsein_maxlen_obj) }, + { MP_ROM_QSTR(MP_QSTR_paused), MP_ROM_PTR(&pulseio_pulsein_paused_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(pulseio_pulsein_locals_dict, pulseio_pulsein_locals_dict_table); + +const mp_obj_type_t pulseio_pulsein_type = { + { &mp_type_type }, + .name = MP_QSTR_PulseIn, + .make_new = pulseio_pulsein_make_new, + .subscr = pulsein_subscr, + .unary_op = pulsein_unary_op, + .locals_dict = (mp_obj_dict_t*)&pulseio_pulsein_locals_dict, +}; diff --git a/shared-bindings/pulseio/PulseIn.h b/shared-bindings/pulseio/PulseIn.h new file mode 100644 index 00000000000..e28a3c2df4b --- /dev/null +++ b/shared-bindings/pulseio/PulseIn.h @@ -0,0 +1,48 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PULSEIN_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PULSEIN_H + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/pulseio/PulseIn.h" + +extern const mp_obj_type_t pulseio_pulsein_type; + +extern void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, + const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state); +extern void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self); +extern bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self); +extern void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self); +extern void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, uint16_t trigger_duration); +extern void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self); +extern uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self); +extern uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self); +extern bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self); +extern uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self); +extern uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_t index); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PULSEIN_H diff --git a/shared-bindings/pulseio/PulseOut.c b/shared-bindings/pulseio/PulseOut.c new file mode 100644 index 00000000000..172459e5df0 --- /dev/null +++ b/shared-bindings/pulseio/PulseOut.c @@ -0,0 +1,158 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "lib/utils/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/pulseio/PulseOut.h" +#include "shared-bindings/pulseio/PWMOut.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: pulseio +//| +//| :class:`PulseOut` -- Output a pulse train +//| ======================================================== +//| +//| PulseOut is used to pulse PWM "carrier" output on and off. This is commonly +//| used in infrared remotes. The pulsed signal consists of timed on and off +//| periods. Unlike PWM, there is no set duration for on and off pairs. +//| +//| .. class:: PulseOut(carrier) +//| +//| Create a PulseOut object associated with the given PWMout object. +//| +//| :param ~pulseio.PWMOut carrier: PWMOut that is set to output on the desired pin. +//| +//| Send a short series of pulses:: +//| +//| import array +//| import pulseio +//| import board +//| +//| # 50% duty cycle at 38kHz. +//| pwm = pulseio.PWMOut(board.D13, frequency=38000, duty_cycle=32768) +//| pulse = pulseio.PulseOut(pwm) +//| # on off on off on +//| pulses = array.array('H', [65000, 1000, 65000, 65000, 1000]) +//| pulse.send(pulses) +//| +//| # Modify the array of pulses. +//| pulses[0] = 200 +//| pulse.send(pulses) +//| +STATIC mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); + mp_obj_t carrier_obj = args[0]; + + if (!MP_OBJ_IS_TYPE(carrier_obj, &pulseio_pwmout_type)) { + mp_raise_TypeError_varg(translate("Expected a %q"), pulseio_pwmout_type.name); + } + + // create Pulse object from the given pin + pulseio_pulseout_obj_t *self = m_new_obj(pulseio_pulseout_obj_t); + self->base.type = &pulseio_pulseout_type; + + common_hal_pulseio_pulseout_construct(self, (pulseio_pwmout_obj_t *)MP_OBJ_TO_PTR(carrier_obj)); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialises the PulseOut and releases any hardware resources for reuse. +//| +STATIC mp_obj_t pulseio_pulseout_deinit(mp_obj_t self_in) { + pulseio_pulseout_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_pulseio_pulseout_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulseout_deinit_obj, pulseio_pulseout_deinit); + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t pulseio_pulseout_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_pulseio_pulseout_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pulseout___exit___obj, 4, 4, pulseio_pulseout_obj___exit__); + +//| .. method:: send(pulses) +//| +//| Pulse alternating on and off durations in microseconds starting with on. +//| ``pulses`` must be an `array.array` with data type 'H' for unsigned +//| halfword (two bytes). +//| +//| This method waits until the whole array of pulses has been sent and +//| ensures the signal is off afterwards. +//| +//| :param array.array pulses: pulse durations in microseconds +//| +STATIC mp_obj_t pulseio_pulseout_obj_send(mp_obj_t self_in, mp_obj_t pulses) { + pulseio_pulseout_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (common_hal_pulseio_pulseout_deinited(self)) { + raise_deinited_error(); + } + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(pulses, &bufinfo, MP_BUFFER_READ); + if (bufinfo.typecode != 'H') { + mp_raise_TypeError(translate("Array must contain halfwords (type 'H')")); + } + common_hal_pulseio_pulseout_send(self, (uint16_t *)bufinfo.buf, bufinfo.len / 2); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(pulseio_pulseout_send_obj, pulseio_pulseout_obj_send); + +STATIC const mp_rom_map_elem_t pulseio_pulseout_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pulseio_pulseout_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&pulseio_pulseout___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&pulseio_pulseout_send_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(pulseio_pulseout_locals_dict, pulseio_pulseout_locals_dict_table); + +const mp_obj_type_t pulseio_pulseout_type = { + { &mp_type_type }, + .name = MP_QSTR_PulseOut, + .make_new = pulseio_pulseout_make_new, + .locals_dict = (mp_obj_dict_t*)&pulseio_pulseout_locals_dict, +}; diff --git a/shared-bindings/pulseio/PulseOut.h b/shared-bindings/pulseio/PulseOut.h new file mode 100644 index 00000000000..2cf78d3f299 --- /dev/null +++ b/shared-bindings/pulseio/PulseOut.h @@ -0,0 +1,43 @@ +/* + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PULSEOUT_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PULSEOUT_H + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/pulseio/PulseOut.h" +#include "common-hal/pulseio/PWMOut.h" + +extern const mp_obj_type_t pulseio_pulseout_type; + +extern void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self, + const pulseio_pwmout_obj_t* carrier); +extern void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self); +extern bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self); +extern void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, + uint16_t* pulses, uint16_t len); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PULSEOUT_H diff --git a/shared-bindings/pulseio/__init__.c b/shared-bindings/pulseio/__init__.c new file mode 100644 index 00000000000..a3cec3dca5f --- /dev/null +++ b/shared-bindings/pulseio/__init__.c @@ -0,0 +1,91 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/pulseio/__init__.h" +#include "shared-bindings/pulseio/PulseIn.h" +#include "shared-bindings/pulseio/PulseOut.h" +#include "shared-bindings/pulseio/PWMOut.h" + +//| :mod:`pulseio` --- Support for pulse based protocols +//| ===================================================== +//| +//| .. module:: pulseio +//| :synopsis: Support for pulse based protocols +//| :platform: SAMD21, ESP8266 +//| +//| The `pulseio` module contains classes to provide access to basic pulse IO. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| PulseIn +//| PulseOut +//| PWMOut +//| + +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed if the program continues after use. To do so, either +//| call :py:meth:`!deinit` or use a context manager. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +//| For example:: +//| +//| import pulseio +//| import time +//| from board import * +//| +//| pwm = pulseio.PWMOut(D13) +//| pwm.duty_cycle = 2 ** 15 +//| time.sleep(0.1) +//| +//| This example will initialize the the device, set +//| :py:data:`~pulseio.PWMOut.duty_cycle`, and then sleep 0.1 seconds. +//| CircuitPython will automatically turn off the PWM when it resets all +//| hardware after program completion. Use ``deinit()`` or a ``with`` statement +//| to do it yourself. +//| + +STATIC const mp_rom_map_elem_t pulseio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pulseio) }, + { MP_ROM_QSTR(MP_QSTR_PulseIn), MP_ROM_PTR(&pulseio_pulsein_type) }, + { MP_ROM_QSTR(MP_QSTR_PulseOut), MP_ROM_PTR(&pulseio_pulseout_type) }, + { MP_ROM_QSTR(MP_QSTR_PWMOut), MP_ROM_PTR(&pulseio_pwmout_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(pulseio_module_globals, pulseio_module_globals_table); + +const mp_obj_module_t pulseio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&pulseio_module_globals, +}; diff --git a/shared-bindings/pulseio/__init__.h b/shared-bindings/pulseio/__init__.h new file mode 100644 index 00000000000..0691ad2828c --- /dev/null +++ b/shared-bindings/pulseio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO___INIT___H + +#include "py/obj.h" + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO___INIT___H diff --git a/shared-bindings/random/__init__.c b/shared-bindings/random/__init__.c new file mode 100644 index 00000000000..83698eac57f --- /dev/null +++ b/shared-bindings/random/__init__.c @@ -0,0 +1,189 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Paul Sokolovsky + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 +#include + +#include "py/obj.h" +#include "py/runtime.h" +#include "shared-bindings/random/__init__.h" +#include "supervisor/shared/translate.h" + +//| :mod:`random` --- psuedo-random numbers and choices +//| ======================================================== +//| +//| .. module:: random +//| :synopsis: psuedo-random numbers and choices +//| :platform: SAMD21, ESP8266 +//| +//| The `random` module is a strict subset of the CPython `cpython:random` +//| module. So, code written in CircuitPython will work in CPython but not +//| necessarily the other way around. +//| +//| Like its CPython cousin, CircuitPython's random seeds itself on first use +//| with a true random from os.urandom() when available or the uptime otherwise. +//| Once seeded, it will be deterministic, which is why its bad for cryptography. +//| +//| .. warning:: Numbers from this module are not cryptographically strong! Use +//| bytes from `os.urandom` directly for true randomness. +//| + +//| .. function:: seed(seed) +//| +//| Sets the starting seed of the random number generation. Further calls to +//| `random` will return deterministic results afterwards. +//| +STATIC mp_obj_t random_seed(mp_obj_t seed_in) { + mp_uint_t seed = mp_obj_get_int_truncated(seed_in); + shared_modules_random_seed(seed); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(random_seed_obj, random_seed); + +//| .. function:: getrandbits(k) +//| +//| Returns an integer with *k* random bits. +//| +STATIC mp_obj_t random_getrandbits(mp_obj_t num_in) { + int n = mp_obj_get_int(num_in); + if (n > 32 || n == 0) { + mp_raise_ValueError(NULL); + } + return mp_obj_new_int_from_uint(shared_modules_random_getrandbits((uint8_t) n)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(random_getrandbits_obj, random_getrandbits); + +//| .. function:: randrange(stop) +//| randrange(start, stop, step=1) +//| +//| Returns a randomly selected integer from ``range(start, stop, step)``. +//| +STATIC mp_obj_t random_randrange(size_t n_args, const mp_obj_t *args) { + mp_int_t start = 0; + mp_int_t stop = mp_obj_get_int(args[0]); + mp_int_t step = 1; + if (n_args == 1) { + // range(stop) + if (stop <= 0) { + mp_raise_ValueError(translate("stop not reachable from start")); + } + } else { + start = stop; + stop = mp_obj_get_int(args[1]); + if (n_args == 2) { + // range(start, stop) + if (start >= stop) { + mp_raise_ValueError(translate("stop not reachable from start")); + } + } else { + // range(start, stop, step) + step = mp_obj_get_int(args[2]); + mp_int_t n; + if (step > 0) { + n = (stop - start + step - 1) / step; + } else if (step < 0) { + n = (stop - start + step + 1) / step; + } else { + mp_raise_ValueError(translate("step must be non-zero")); + } + if (n <= 0) { + mp_raise_ValueError(translate("invalid step")); + } + } + } + + return mp_obj_new_int(shared_modules_random_randrange(start, stop, step)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(random_randrange_obj, 1, 3, random_randrange); + +//| .. function:: randint(a, b) +//| +//| Returns a randomly selected integer between a and b inclusive. Equivalent +//| to ``randrange(a, b + 1, 1)`` +//| +STATIC mp_obj_t random_randint(mp_obj_t a_in, mp_obj_t b_in) { + mp_int_t a = mp_obj_get_int(a_in); + mp_int_t b = mp_obj_get_int(b_in); + if (a > b) { + mp_raise_ValueError(NULL); + } + return mp_obj_new_int(shared_modules_random_randrange(a, b + 1, 1)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(random_randint_obj, random_randint); + +//| .. function:: choice(seq) +//| +//| Returns a randomly selected element from the given sequence. Raises +//| IndexError when the sequence is empty. +//| +STATIC mp_obj_t random_choice(mp_obj_t seq) { + mp_int_t len = mp_obj_get_int(mp_obj_len(seq)); + if (len == 0) { + mp_raise_IndexError(translate("empty sequence")); + } + return mp_obj_subscr(seq, mp_obj_new_int(shared_modules_random_randrange(0, len, 1)), MP_OBJ_SENTINEL); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(random_choice_obj, random_choice); + +//| .. function:: random() +//| +//| Returns a random float between 0 and 1.0. +//| +STATIC mp_obj_t random_random(void) { + return mp_obj_new_float(shared_modules_random_random()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(random_random_obj, random_random); + +//| .. function:: uniform(a, b) +//| +//| Returns a random float between a and b. It may or may not be inclusive +//| depending on float rounding. +//| +STATIC mp_obj_t random_uniform(mp_obj_t a_in, mp_obj_t b_in) { + mp_float_t a = mp_obj_get_float(a_in); + mp_float_t b = mp_obj_get_float(b_in); + return mp_obj_new_float(shared_modules_random_uniform(a, b)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(random_uniform_obj, random_uniform); + +STATIC const mp_rom_map_elem_t mp_module_random_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_random) }, + { MP_ROM_QSTR(MP_QSTR_seed), MP_ROM_PTR(&random_seed_obj) }, + { MP_ROM_QSTR(MP_QSTR_getrandbits), MP_ROM_PTR(&random_getrandbits_obj) }, + { MP_ROM_QSTR(MP_QSTR_randrange), MP_ROM_PTR(&random_randrange_obj) }, + { MP_ROM_QSTR(MP_QSTR_randint), MP_ROM_PTR(&random_randint_obj) }, + { MP_ROM_QSTR(MP_QSTR_choice), MP_ROM_PTR(&random_choice_obj) }, + { MP_ROM_QSTR(MP_QSTR_random), MP_ROM_PTR(&random_random_obj) }, + { MP_ROM_QSTR(MP_QSTR_uniform), MP_ROM_PTR(&random_uniform_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(mp_module_random_globals, mp_module_random_globals_table); + +const mp_obj_module_t random_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mp_module_random_globals, +}; diff --git a/shared-bindings/random/__init__.h b/shared-bindings/random/__init__.h new file mode 100644 index 00000000000..b5011b1a8c8 --- /dev/null +++ b/shared-bindings/random/__init__.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_RANDOM___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_RANDOM___INIT___H + +// This depends on shared_module because nearly all functionality is port +// agnostic. The random module only depends on the common_hal_os_urandom or +// common_hal_time_monotonic to seed it initially. + +void shared_modules_random_seed(mp_uint_t seed); +mp_uint_t shared_modules_random_getrandbits(uint8_t n); +mp_int_t shared_modules_random_randrange(mp_int_t start, mp_int_t stop, mp_int_t step); +mp_float_t shared_modules_random_random(void); +mp_float_t shared_modules_random_uniform(mp_float_t a, mp_float_t b); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_RANDOM___INIT___H diff --git a/shared-bindings/rotaryio/IncrementalEncoder.c b/shared-bindings/rotaryio/IncrementalEncoder.c new file mode 100644 index 00000000000..f2f15784783 --- /dev/null +++ b/shared-bindings/rotaryio/IncrementalEncoder.c @@ -0,0 +1,171 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "lib/utils/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/runtime0.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/rotaryio/IncrementalEncoder.h" +#include "shared-bindings/util.h" + +//| .. currentmodule:: rotaryio +//| +//| :class:`IncrementalEncoder` -- Track the relative position of an incremental encoder +//| ==================================================================================== +//| +//| IncrementalEncoder determines the relative rotational position based on two series of pulses. +//| +//| .. class:: IncrementalEncoder(pin_a, pin_b) +//| +//| Create an IncrementalEncoder object associated with the given pins. It tracks the positional +//| state of an incremental rotary encoder (also known as a quadrature encoder.) Position is +//| relative to the position when the object is contructed. +//| +//| :param ~microcontroller.Pin pin_a: First pin to read pulses from. +//| :param ~microcontroller.Pin pin_b: Second pin to read pulses from. +//| +//| For example:: +//| +//| import rotaryio +//| import time +//| from board import * +//| +//| enc = rotaryio.IncrementalEncoder(D1, D2) +//| last_position = None +//| while True: +//| position = enc.position +//| if last_position == None or position != last_position: +//| print(position) +//| last_position = position +//| +STATIC mp_obj_t rotaryio_incrementalencoder_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_pin_a, ARG_pin_b }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pin_a, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_pin_b, MP_ARG_REQUIRED | MP_ARG_OBJ }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + assert_pin(args[ARG_pin_a].u_obj, false); + const mcu_pin_obj_t* pin_a = MP_OBJ_TO_PTR(args[ARG_pin_a].u_obj); + assert_pin_free(pin_a); + + assert_pin(args[ARG_pin_b].u_obj, false); + const mcu_pin_obj_t* pin_b = MP_OBJ_TO_PTR(args[ARG_pin_b].u_obj); + assert_pin_free(pin_b); + + rotaryio_incrementalencoder_obj_t *self = m_new_obj(rotaryio_incrementalencoder_obj_t); + self->base.type = &rotaryio_incrementalencoder_type; + + common_hal_rotaryio_incrementalencoder_construct(self, pin_a, pin_b); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitializes the IncrementalEncoder and releases any hardware resources for reuse. +//| +STATIC mp_obj_t rotaryio_incrementalencoder_deinit(mp_obj_t self_in) { + rotaryio_incrementalencoder_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_rotaryio_incrementalencoder_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(rotaryio_incrementalencoder_deinit_obj, rotaryio_incrementalencoder_deinit); + +STATIC void check_for_deinit(rotaryio_incrementalencoder_obj_t *self) { + if (common_hal_rotaryio_incrementalencoder_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t rotaryio_incrementalencoder_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_rotaryio_incrementalencoder_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(rotaryio_incrementalencoder___exit___obj, 4, 4, rotaryio_incrementalencoder_obj___exit__); + + +//| .. attribute:: position +//| +//| The current position in terms of pulses. The number of pulses per rotation is defined by the +//| specific hardware. +//| +STATIC mp_obj_t rotaryio_incrementalencoder_obj_get_position(mp_obj_t self_in) { + rotaryio_incrementalencoder_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + return mp_obj_new_int(common_hal_rotaryio_incrementalencoder_get_position(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(rotaryio_incrementalencoder_get_position_obj, rotaryio_incrementalencoder_obj_get_position); + +STATIC mp_obj_t rotaryio_incrementalencoder_obj_set_position(mp_obj_t self_in, mp_obj_t new_position) { + rotaryio_incrementalencoder_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + common_hal_rotaryio_incrementalencoder_set_position(self, mp_obj_get_int(new_position)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(rotaryio_incrementalencoder_set_position_obj, rotaryio_incrementalencoder_obj_set_position); + +const mp_obj_property_t rotaryio_incrementalencoder_position_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&rotaryio_incrementalencoder_get_position_obj, + (mp_obj_t)&rotaryio_incrementalencoder_set_position_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t rotaryio_incrementalencoder_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&rotaryio_incrementalencoder_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&rotaryio_incrementalencoder___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_position), MP_ROM_PTR(&rotaryio_incrementalencoder_position_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(rotaryio_incrementalencoder_locals_dict, rotaryio_incrementalencoder_locals_dict_table); + +const mp_obj_type_t rotaryio_incrementalencoder_type = { + { &mp_type_type }, + .name = MP_QSTR_IncrementalEncoder, + .make_new = rotaryio_incrementalencoder_make_new, + .locals_dict = (mp_obj_dict_t*)&rotaryio_incrementalencoder_locals_dict, +}; diff --git a/shared-bindings/rotaryio/IncrementalEncoder.h b/shared-bindings/rotaryio/IncrementalEncoder.h new file mode 100644 index 00000000000..f70632aefbe --- /dev/null +++ b/shared-bindings/rotaryio/IncrementalEncoder.h @@ -0,0 +1,43 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ROTARYIO_INCREMENTALENCODER_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ROTARYIO_INCREMENTALENCODER_H + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/rotaryio/IncrementalEncoder.h" + +extern const mp_obj_type_t rotaryio_incrementalencoder_type; + +extern void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t* self, + const mcu_pin_obj_t* pin_a, const mcu_pin_obj_t* pin_b); +extern void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_obj_t* self); +extern bool common_hal_rotaryio_incrementalencoder_deinited(rotaryio_incrementalencoder_obj_t* self); +extern mp_int_t common_hal_rotaryio_incrementalencoder_get_position(rotaryio_incrementalencoder_obj_t* self); +extern void common_hal_rotaryio_incrementalencoder_set_position(rotaryio_incrementalencoder_obj_t* self, + mp_int_t new_position); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ROTARYIO_INCREMENTALENCODER_H diff --git a/shared-bindings/rotaryio/__init__.c b/shared-bindings/rotaryio/__init__.c new file mode 100644 index 00000000000..a0166771abe --- /dev/null +++ b/shared-bindings/rotaryio/__init__.c @@ -0,0 +1,75 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/rotaryio/__init__.h" +#include "shared-bindings/rotaryio/IncrementalEncoder.h" + +//| :mod:`rotaryio` --- Support for reading rotation sensors +//| ======================================================== +//| +//| .. module:: rotaryio +//| :synopsis: Support for reading rotation sensors +//| :platform: SAMD +//| +//| The `rotaryio` module contains classes to read different rotation encoding schemes. See +//| `Wikipedia's Rotary Encoder page `_ for more +//| background. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| IncrementalEncoder +//| + +//| .. warning:: This module is not available in some SAMD21 (aka M0) builds. See the +//| :ref:`module-support-matrix` for more info. +//| + +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed if the program continues after use. To do so, either +//| call :py:meth:`!deinit` or use a context manager. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| + +STATIC const mp_rom_map_elem_t rotaryio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_rotaryio) }, + { MP_ROM_QSTR(MP_QSTR_IncrementalEncoder), MP_ROM_PTR(&rotaryio_incrementalencoder_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(rotaryio_module_globals, rotaryio_module_globals_table); + +const mp_obj_module_t rotaryio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&rotaryio_module_globals, +}; diff --git a/shared-bindings/rotaryio/__init__.h b/shared-bindings/rotaryio/__init__.h new file mode 100644 index 00000000000..5d051d5a1ae --- /dev/null +++ b/shared-bindings/rotaryio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ROTARYIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ROTARYIO___INIT___H + +#include "py/obj.h" + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ROTARYIO___INIT___H diff --git a/shared-bindings/rtc/RTC.c b/shared-bindings/rtc/RTC.c new file mode 100644 index 00000000000..17dccdb03c1 --- /dev/null +++ b/shared-bindings/rtc/RTC.c @@ -0,0 +1,120 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * 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 + +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "lib/timeutils/timeutils.h" +#include "shared-bindings/rtc/__init__.h" +#include "shared-bindings/rtc/RTC.h" +#include "shared-bindings/time/__init__.h" +#include "supervisor/shared/translate.h" + +const rtc_rtc_obj_t rtc_rtc_obj = {{&rtc_rtc_type}}; + +//| .. currentmodule:: rtc +//| +//| :class:`RTC` --- Real Time Clock +//| -------------------------------- +//| +//| .. class:: RTC() +//| +//| This class represents the onboard Real Time Clock. It is a singleton and will always return the same instance. +//| +STATIC mp_obj_t rtc_rtc_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + // No arguments + mp_arg_check_num(n_args, kw_args, 0, 0, false); + + // return constant object + return (mp_obj_t)&rtc_rtc_obj; +} + +//| .. attribute:: datetime +//| +//| The date and time of the RTC. +//| +STATIC mp_obj_t rtc_rtc_obj_get_datetime(mp_obj_t self_in) { + timeutils_struct_time_t tm; + common_hal_rtc_get_time(&tm); + return struct_time_from_tm(&tm); +} +MP_DEFINE_CONST_FUN_OBJ_1(rtc_rtc_get_datetime_obj, rtc_rtc_obj_get_datetime); + +STATIC mp_obj_t rtc_rtc_obj_set_datetime(mp_obj_t self_in, mp_obj_t datetime) { + timeutils_struct_time_t tm; + struct_time_to_tm(datetime, &tm); + common_hal_rtc_set_time(&tm); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(rtc_rtc_set_datetime_obj, rtc_rtc_obj_set_datetime); + +const mp_obj_property_t rtc_rtc_datetime_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&rtc_rtc_get_datetime_obj, + (mp_obj_t)&rtc_rtc_set_datetime_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: calibration +//| +//| The RTC calibration value. +//| A positive value speeds up the clock and a negative value slows it down. +//| Range and value is hardware specific, but one step is often approx. 1 ppm. +//| +STATIC mp_obj_t rtc_rtc_obj_get_calibration(mp_obj_t self_in) { + int calibration = common_hal_rtc_get_calibration(); + return mp_obj_new_int(calibration); +} +MP_DEFINE_CONST_FUN_OBJ_1(rtc_rtc_get_calibration_obj, rtc_rtc_obj_get_calibration); + +STATIC mp_obj_t rtc_rtc_obj_set_calibration(mp_obj_t self_in, mp_obj_t calibration) { + common_hal_rtc_set_calibration(mp_obj_get_int(calibration)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(rtc_rtc_set_calibration_obj, rtc_rtc_obj_set_calibration); + +const mp_obj_property_t rtc_rtc_calibration_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&rtc_rtc_get_calibration_obj, + (mp_obj_t)&rtc_rtc_set_calibration_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t rtc_rtc_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_datetime), MP_ROM_PTR(&rtc_rtc_datetime_obj) }, + { MP_ROM_QSTR(MP_QSTR_calibration), MP_ROM_PTR(&rtc_rtc_calibration_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(rtc_rtc_locals_dict, rtc_rtc_locals_dict_table); + +const mp_obj_type_t rtc_rtc_type = { + { &mp_type_type }, + .name = MP_QSTR_RTC, + .make_new = rtc_rtc_make_new, + .locals_dict = (mp_obj_dict_t*)&rtc_rtc_locals_dict, +}; diff --git a/shared-bindings/rtc/RTC.h b/shared-bindings/rtc/RTC.h new file mode 100644 index 00000000000..76510bd729f --- /dev/null +++ b/shared-bindings/rtc/RTC.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_RTC_RTC_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_RTC_RTC_H + +#include +#include + +#include "lib/timeutils/timeutils.h" + +extern void common_hal_rtc_get_time(timeutils_struct_time_t *tm); +extern void common_hal_rtc_set_time(timeutils_struct_time_t *tm); + +extern int common_hal_rtc_get_calibration(void); +extern void common_hal_rtc_set_calibration(int calibration); + +extern const mp_obj_type_t rtc_rtc_type; + +typedef struct _rtc_rtc_obj_t { + mp_obj_base_t base; +} rtc_rtc_obj_t; + +extern const rtc_rtc_obj_t rtc_rtc_obj; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_RTC_RTC_H diff --git a/shared-bindings/rtc/__init__.c b/shared-bindings/rtc/__init__.c new file mode 100644 index 00000000000..ac67a7131cd --- /dev/null +++ b/shared-bindings/rtc/__init__.c @@ -0,0 +1,100 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * 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 "py/obj.h" +#include "py/runtime.h" +#include "shared-bindings/rtc/__init__.h" +#include "shared-bindings/rtc/RTC.h" +#include "shared-bindings/time/__init__.h" + +//| :mod:`rtc` --- Real Time Clock +//| ======================================================== +//| +//| .. module:: rtc +//| :synopsis: Real Time Clock +//| :platform: SAMD21 +//| +//| The `rtc` module provides support for a Real Time Clock. +//| It also backs the `time.time()` and `time.localtime()` functions using the onboard RTC if present. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| RTC +//| + +void rtc_reset(void) { + MP_STATE_VM(rtc_time_source) = (mp_obj_t)&rtc_rtc_obj; +} + +mp_obj_t rtc_get_time_source_time(void) { + mp_obj_t datetime = mp_load_attr(MP_STATE_VM(rtc_time_source), MP_QSTR_datetime); + timeutils_struct_time_t tm; + struct_time_to_tm(datetime, &tm); + // This sets tm_wday and tm_yday + return struct_time_from_tm(&tm); +} + +//| .. function:: set_time_source(rtc) +//| +//| Sets the rtc time source used by time.localtime(). +//| The default is `rtc.RTC()`. +//| +//| Example usage:: +//| +//| import rtc +//| import time +//| +//| class RTC(object): +//| @property +//| def datetime(self): +//| return time.struct_time((2018, 3, 17, 21, 1, 47, 0, 0, 0)) +//| +//| r = RTC() +//| rtc.set_time_source(r) +//| +STATIC mp_obj_t rtc_set_time_source(mp_obj_t time_source) { + MP_STATE_VM(rtc_time_source) = time_source; + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(rtc_set_time_source_obj, rtc_set_time_source); + +STATIC const mp_rom_map_elem_t rtc_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_rtc) }, + { MP_ROM_QSTR(MP_QSTR_set_time_source), MP_ROM_PTR(&rtc_set_time_source_obj) }, + { MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&rtc_rtc_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(rtc_module_globals, rtc_module_globals_table); + +const mp_obj_module_t rtc_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&rtc_module_globals, +}; diff --git a/shared-bindings/rtc/__init__.h b/shared-bindings/rtc/__init__.h new file mode 100644 index 00000000000..0ee51fba5e4 --- /dev/null +++ b/shared-bindings/rtc/__init__.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_RTC___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_RTC___INIT___H + +extern void rtc_reset(void); +extern mp_obj_t rtc_get_time_source_time(void); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_RTC___INIT___H diff --git a/shared-bindings/socket/__init__.c b/shared-bindings/socket/__init__.c new file mode 100644 index 00000000000..6d04a989367 --- /dev/null +++ b/shared-bindings/socket/__init__.c @@ -0,0 +1,603 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Damien P. George + * 2018 Nick Moore for Adafruit Industries + * + * 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 +#include + +#include "py/objtuple.h" +#include "py/objlist.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "py/mperrno.h" +#include "lib/netutils/netutils.h" + +#include "shared-module/network/__init__.h" + +//| :mod:`socket` --- TCP, UDP and RAW socket support +//| ================================================= +//| +//| .. module:: socket +//| :synopsis: TCP, UDP and RAW sockets +//| :platform: SAMD21, SAMD51 +//| +//| Create TCP, UDP and RAW sockets for communicating over the Internet. +//| + +STATIC const mp_obj_type_t socket_type; + +//| .. currentmodule:: socket +//| +//| .. class:: socket(family, type, proto) +//| +//| Create a new socket +//| +//| :param ~int family: AF_INET or AF_INET6 +//| :param ~int type: SOCK_STREAM, SOCK_DGRAM or SOCK_RAW +//| :param ~int proto: IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW (ignored) +//| + +STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 4, false); + + // create socket object (not bound to any NIC yet) + mod_network_socket_obj_t *s = m_new_obj_with_finaliser(mod_network_socket_obj_t); + s->base.type = &socket_type; + s->nic = MP_OBJ_NULL; + s->nic_type = NULL; + s->u_param.domain = MOD_NETWORK_AF_INET; + s->u_param.type = MOD_NETWORK_SOCK_STREAM; + s->u_param.fileno = -1; + if (n_args >= 1) { + s->u_param.domain = mp_obj_get_int(args[0]); + if (n_args >= 2) { + s->u_param.type = mp_obj_get_int(args[1]); + if (n_args >= 4) { + s->u_param.fileno = mp_obj_get_int(args[3]); + } + } + } + + return MP_OBJ_FROM_PTR(s); +} + +STATIC void socket_select_nic(mod_network_socket_obj_t *self, const byte *ip) { + if (self->nic == MP_OBJ_NULL) { + // select NIC based on IP + self->nic = network_module_find_nic(ip); + self->nic_type = (mod_network_nic_type_t*)mp_obj_get_type(self->nic); + + // call the NIC to open the socket + int _errno; + if (self->nic_type->socket(self, &_errno) != 0) { + mp_raise_OSError(_errno); + } + } +} + +//| .. method:: bind(address) +//| +//| Bind a socket to an address +//| +//| :param ~tuple address: tuple of (remote_address, remote_port) +//| + +STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // get address + uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); + + // check if we need to select a NIC + socket_select_nic(self, ip); + + // call the NIC to bind the socket + int _errno; + if (self->nic_type->bind(self, ip, port, &_errno) != 0) { + mp_raise_OSError(_errno); + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_bind_obj, socket_bind); + +//| .. method:: listen(backlog) +//| +//| Set socket to listen for incoming connections +//| +//| :param ~int backlog: length of backlog queue for waiting connetions +//| + +STATIC mp_obj_t socket_listen(mp_obj_t self_in, mp_obj_t backlog) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (self->nic == MP_OBJ_NULL) { + // not connected + // TODO I think we can listen even if not bound... + mp_raise_OSError(MP_ENOTCONN); + } + + int _errno; + if (self->nic_type->listen(self, mp_obj_get_int(backlog), &_errno) != 0) { + mp_raise_OSError(_errno); + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_listen_obj, socket_listen); + +//| .. method:: accept() +//| +//| Accept a connection on a listening socket of type SOCK_STREAM, +//| creating a new socket of type SOCK_STREAM. +//| Returns a tuple of (new_socket, remote_address) +//| + +STATIC mp_obj_t socket_accept(mp_obj_t self_in) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // create new socket object + // starts with empty NIC so that finaliser doesn't run close() method if accept() fails + mod_network_socket_obj_t *socket2 = m_new_obj_with_finaliser(mod_network_socket_obj_t); + socket2->base.type = &socket_type; + socket2->nic = MP_OBJ_NULL; + socket2->nic_type = NULL; + + // accept incoming connection + uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + mp_uint_t port; + int _errno; + if (self->nic_type->accept(self, socket2, ip, &port, &_errno) != 0) { + mp_raise_OSError(_errno); + } + + // new socket has valid state, so set the NIC to the same as parent + socket2->nic = self->nic; + socket2->nic_type = self->nic_type; + + // make the return value + mp_obj_tuple_t *client = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); + client->items[0] = MP_OBJ_FROM_PTR(socket2); + client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); + + return MP_OBJ_FROM_PTR(client); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_accept_obj, socket_accept); + +//| .. method:: connect(address) +//| +//| Connect a socket to a remote address +//| +//| :param ~tuple address: tuple of (remote_address, remote_port) +//| + +STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // get address + uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); + + // check if we need to select a NIC + socket_select_nic(self, ip); + + // call the NIC to connect the socket + int _errno; + if (self->nic_type->connect(self, ip, port, &_errno) != 0) { + mp_raise_OSError(_errno); + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect); + +//| .. method:: send(bytes) +//| +//| Send some bytes to the connected remote address. +//| Suits sockets of type SOCK_STREAM +//| +//| :param ~bytes bytes: some bytes to send +//| + +STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->nic == MP_OBJ_NULL) { + // not connected + mp_raise_OSError(MP_EPIPE); + } + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); + int _errno; + mp_int_t ret = self->nic_type->send(self, bufinfo.buf, bufinfo.len, &_errno); + if (ret == -1) { + mp_raise_OSError(_errno); + } + return mp_obj_new_int_from_uint(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_send_obj, socket_send); + + +// helper function for socket_recv and socket_recv_into to handle common operations of both +STATIC mp_int_t _socket_recv_into(mod_network_socket_obj_t *sock, byte *buf, mp_int_t len) { + int _errno; + mp_int_t ret = sock->nic_type->recv(sock, buf, len, &_errno); + if (ret == -1) { + mp_raise_OSError(_errno); + } + return ret; +} + + +//| .. method:: recv_into(buffer[, bufsize]) +//| +//| Reads some bytes from the connected remote address, writing +//| into the provided buffer. If bufsize <= len(buffer) is given, +//| a maximum of bufsize bytes will be read into the buffer. If no +//| valid value is given for bufsize, the default is the length of +//| the given buffer. +//| +//| Suits sockets of type SOCK_STREAM +//| Returns an int of number of bytes read. +//| +//| :param bytearray buffer: buffer to receive into +//| :param int bufsize: optionally, a maximum number of bytes to read. + +STATIC mp_obj_t socket_recv_into(size_t n_args, const mp_obj_t *args) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); + if (self->nic == MP_OBJ_NULL) { + // not connected + mp_raise_OSError(MP_ENOTCONN); + } + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE); + mp_int_t len = bufinfo.len; + if (n_args == 3) { + mp_int_t given_len = mp_obj_get_int(args[2]); + if (given_len < len) { + len = given_len; + } + } + + mp_int_t ret = _socket_recv_into(self, (byte*)bufinfo.buf, len); + return mp_obj_new_int_from_uint(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_recv_into_obj, 2, 3, socket_recv_into); + +//| .. method:: recv(bufsize) +//| +//| Reads some bytes from the connected remote address. +//| Suits sockets of type SOCK_STREAM +//| Returns a bytes() of length <= bufsize +//| +//| :param ~int bufsize: maximum number of bytes to receive + +STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->nic == MP_OBJ_NULL) { + // not connected + mp_raise_OSError(MP_ENOTCONN); + } + mp_int_t len = mp_obj_get_int(len_in); + vstr_t vstr; + vstr_init_len(&vstr, len); + mp_int_t ret = _socket_recv_into(self, (byte*)vstr.buf, len); + if (ret == 0) { + return mp_const_empty_bytes; + } + vstr.len = ret; + return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recv_obj, socket_recv); + +//| .. method:: sendto(bytes, address) +//| +//| Send some bytes to a specific address. +//| Suits sockets of type SOCK_DGRAM +//| +//| :param ~bytes bytes: some bytes to send +//| :param ~tuple address: tuple of (remote_address, remote_port) +//| + +STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // get the data + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(data_in, &bufinfo, MP_BUFFER_READ); + + // get address + uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); + + // check if we need to select a NIC + socket_select_nic(self, ip); + + // call the NIC to sendto + int _errno; + mp_int_t ret = self->nic_type->sendto(self, bufinfo.buf, bufinfo.len, ip, port, &_errno); + if (ret == -1) { + mp_raise_OSError(_errno); + } + + return mp_obj_new_int(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(socket_sendto_obj, socket_sendto); + +//| .. method:: recvfrom(bufsize) +//| +//| Reads some bytes from the connected remote address. +//| Suits sockets of type SOCK_STREAM +//| +//| Returns a tuple containing +//| * a bytes() of length <= bufsize +//| * a remote_address, which is a tuple of ip address and port number +//| +//| :param ~int bufsize: maximum number of bytes to receive +//| + +STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->nic == MP_OBJ_NULL) { + // not connected + mp_raise_OSError(MP_ENOTCONN); + } + vstr_t vstr; + vstr_init_len(&vstr, mp_obj_get_int(len_in)); + byte ip[4]; + mp_uint_t port; + int _errno; + mp_int_t ret = self->nic_type->recvfrom(self, (byte*)vstr.buf, vstr.len, ip, &port, &_errno); + if (ret == -1) { + mp_raise_OSError(_errno); + } + mp_obj_t tuple[2]; + if (ret == 0) { + tuple[0] = mp_const_empty_bytes; + } else { + vstr.len = ret; + tuple[0] = mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + } + tuple[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); + return mp_obj_new_tuple(2, tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recvfrom_obj, socket_recvfrom); + +//| .. method:: setsockopt(level, optname, value) +//| +//| Sets socket options +//| + +STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); + + mp_int_t level = mp_obj_get_int(args[1]); + mp_int_t opt = mp_obj_get_int(args[2]); + + const void *optval; + mp_uint_t optlen; + mp_int_t val; + if (mp_obj_is_integer(args[3])) { + val = mp_obj_get_int_truncated(args[3]); + optval = &val; + optlen = sizeof(val); + } else { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); + optval = bufinfo.buf; + optlen = bufinfo.len; + } + + int _errno; + if (self->nic_type->setsockopt(self, level, opt, optval, optlen, &_errno) != 0) { + mp_raise_OSError(_errno); + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_setsockopt_obj, 4, 4, socket_setsockopt); + +//| .. method:: settimeout(value) +//| +//| Set the timeout value for this socket. +//| +//| :param ~int value: timeout in seconds. 0 means non-blocking. None means block indefinitely. +//| + +STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->nic == MP_OBJ_NULL) { + // not connected + mp_raise_OSError(MP_ENOTCONN); + } + mp_uint_t timeout; + if (timeout_in == mp_const_none) { + timeout = -1; + } else { + #if MICROPY_PY_BUILTINS_FLOAT + timeout = 1000 * mp_obj_get_float(timeout_in); + #else + timeout = 1000 * mp_obj_get_int(timeout_in); + #endif + } + int _errno; + if (self->nic_type->settimeout(self, timeout, &_errno) != 0) { + mp_raise_OSError(_errno); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_settimeout_obj, socket_settimeout); + +//| .. method:: setblocking(flag) +//| +//| Set the blocking behaviour of this socket. +//| +//| :param ~bool flag: False means non-blocking, True means block indefinitely. +//| + +// method socket.setblocking(flag) +STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t blocking) { + if (mp_obj_is_true(blocking)) { + return socket_settimeout(self_in, mp_const_none); + } else { + return socket_settimeout(self_in, MP_OBJ_NEW_SMALL_INT(0)); + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking); + +STATIC const mp_rom_map_elem_t socket_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) }, + { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) }, + { MP_ROM_QSTR(MP_QSTR_bind), MP_ROM_PTR(&socket_bind_obj) }, + { MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&socket_listen_obj) }, + { MP_ROM_QSTR(MP_QSTR_accept), MP_ROM_PTR(&socket_accept_obj) }, + { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&socket_connect_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&socket_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&socket_recv_obj) }, + { MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&socket_sendto_obj) }, + { MP_ROM_QSTR(MP_QSTR_recvfrom), MP_ROM_PTR(&socket_recvfrom_obj) }, + { MP_ROM_QSTR(MP_QSTR_recv_into), MP_ROM_PTR(&socket_recv_into_obj) }, + { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&socket_setsockopt_obj) }, + { MP_ROM_QSTR(MP_QSTR_settimeout), MP_ROM_PTR(&socket_settimeout_obj) }, + { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(socket_locals_dict, socket_locals_dict_table); + +mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (request == MP_STREAM_CLOSE) { + if (self->nic != MP_OBJ_NULL) { + self->nic_type->close(self); + self->nic = MP_OBJ_NULL; + } + return 0; + } + return self->nic_type->ioctl(self, request, arg, errcode); +} + +STATIC const mp_stream_p_t socket_stream_p = { + .ioctl = socket_ioctl, + .is_text = false, +}; + +STATIC const mp_obj_type_t socket_type = { + { &mp_type_type }, + .name = MP_QSTR_socket, + .make_new = socket_make_new, + .protocol = &socket_stream_p, + .locals_dict = (mp_obj_dict_t*)&socket_locals_dict, +}; + +//| .. function:: getaddrinfo(host, port) +//| +//| Gets the address information for a hostname and port +//| +//| Returns the appropriate family, socket type, socket protocol and +//| address information to call socket.socket() and socket.connect() with, +//| as a tuple. +//| + +STATIC mp_obj_t socket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) { + size_t hlen; + const char *host = mp_obj_str_get_data(host_in, &hlen); + mp_int_t port = mp_obj_get_int(port_in); + uint8_t out_ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + bool have_ip = false; + + if (hlen > 0) { + // check if host is already in IP form + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + netutils_parse_ipv4_addr(host_in, out_ip, NETUTILS_BIG); + have_ip = true; + nlr_pop(); + } else { + // swallow exception: host was not in IP form so need to do DNS lookup + } + } + + if (!have_ip) { + // find a NIC that can do a name lookup + for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { + mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i]; + mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic); + if (nic_type->gethostbyname != NULL) { + int ret = nic_type->gethostbyname(nic, host, hlen, out_ip); + if (ret != 0) { + mp_raise_OSError(ret); + } + have_ip = true; + break; + } + } + } + + if (!have_ip) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("no available NIC"))); + } + + mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(5, NULL)); + tuple->items[0] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET); + tuple->items[1] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM); + tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0); + tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_); + tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_BIG); + return mp_obj_new_list(1, (mp_obj_t*)&tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_getaddrinfo_obj, socket_getaddrinfo); + +STATIC const mp_rom_map_elem_t socket_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usocket) }, + + { MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&socket_type) }, + { MP_ROM_QSTR(MP_QSTR_getaddrinfo), MP_ROM_PTR(&socket_getaddrinfo_obj) }, + + // class constants + { MP_ROM_QSTR(MP_QSTR_AF_INET), MP_ROM_INT(MOD_NETWORK_AF_INET) }, + { MP_ROM_QSTR(MP_QSTR_AF_INET6), MP_ROM_INT(MOD_NETWORK_AF_INET6) }, + + { MP_ROM_QSTR(MP_QSTR_SOCK_STREAM), MP_ROM_INT(MOD_NETWORK_SOCK_STREAM) }, + { MP_ROM_QSTR(MP_QSTR_SOCK_DGRAM), MP_ROM_INT(MOD_NETWORK_SOCK_DGRAM) }, + { MP_ROM_QSTR(MP_QSTR_SOCK_RAW), MP_ROM_INT(MOD_NETWORK_SOCK_RAW) }, + + /* + { MP_ROM_QSTR(MP_QSTR_IPPROTO_IP), MP_ROM_INT(MOD_NETWORK_IPPROTO_IP) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_ICMP), MP_ROM_INT(MOD_NETWORK_IPPROTO_ICMP) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_IPV4), MP_ROM_INT(MOD_NETWORK_IPPROTO_IPV4) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_TCP), MP_ROM_INT(MOD_NETWORK_IPPROTO_TCP) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_UDP), MP_ROM_INT(MOD_NETWORK_IPPROTO_UDP) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_IPV6), MP_ROM_INT(MOD_NETWORK_IPPROTO_IPV6) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_RAW), MP_ROM_INT(MOD_NETWORK_IPPROTO_RAW) }, + */ +}; + +STATIC MP_DEFINE_CONST_DICT(socket_globals, socket_globals_table); + +const mp_obj_module_t socket_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&socket_globals, +}; diff --git a/shared-bindings/storage/__init__.c b/shared-bindings/storage/__init__.c new file mode 100644 index 00000000000..ba439b951c4 --- /dev/null +++ b/shared-bindings/storage/__init__.c @@ -0,0 +1,231 @@ +/* + * 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 Josef Gajdusek + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "extmod/vfs_fat.h" +#include "py/obj.h" +#include "py/objnamedtuple.h" +#include "py/runtime.h" +#include "shared-bindings/storage/__init__.h" +#include "supervisor/shared/translate.h" + +//| :mod:`storage` --- storage management +//| ======================================================== +//| +//| .. module:: storage +//| :synopsis: storage management +//| :platform: SAMD21, SAMD51 +//| +//| The `storage` provides storage management functionality such as mounting and +//| unmounting which is typically handled by the operating system hosting Python. +//| CircuitPython does not have an OS, so this module provides this functionality +//| directly. +//| + +//| .. function:: mount(filesystem, mount_path, *, readonly=False) +//| +//| Mounts the given filesystem object at the given path. +//| +//| This is the CircuitPython analog to the UNIX ``mount`` command. +//| +//| :param bool readonly: True when the filesystem should be readonly to CircuitPython. +//| +mp_obj_t storage_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_readonly }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_readonly, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + + // parse args + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // get the mount point + const char *mnt_str = mp_obj_str_get_str(pos_args[1]); + + // Make sure we're given an object we can mount. + // TODO(tannewt): Make sure we have all the methods we need to operating it + // as a file system. + mp_obj_t vfs_obj = pos_args[0]; + mp_obj_t dest[2]; + mp_load_method_maybe(vfs_obj, MP_QSTR_mount, dest); + if (dest[0] == MP_OBJ_NULL) { + mp_raise_ValueError(translate("filesystem must provide mount method")); + } + + common_hal_storage_mount(vfs_obj, mnt_str, args[ARG_readonly].u_bool); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(storage_mount_obj, 2, storage_mount); + +//| .. function:: umount(mount) +//| +//| Unmounts the given filesystem object or if *mount* is a path, then unmount +//| the filesystem mounted at that location. +//| +//| This is the CircuitPython analog to the UNIX ``umount`` command. +//| +mp_obj_t storage_umount(mp_obj_t mnt_in) { + if (MP_OBJ_IS_STR(mnt_in)) { + common_hal_storage_umount_path(mp_obj_str_get_str(mnt_in)); + } else { + common_hal_storage_umount_object(mnt_in); + } + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(storage_umount_obj, storage_umount); + +//| .. function:: remount(mount_path, readonly=False, *, disable_concurrent_write_protection=False) +//| +//| Remounts the given path with new parameters. +//| +//| :param bool readonly: True when the filesystem should be readonly to CircuitPython. +//| :param bool disable_concurrent_write_protection: When True, the check that makes sure the +//| underlying filesystem data is written by one computer is disabled. Disabling the protection +//| allows CircuitPython and a host to write to the same filesystem with the risk that the +//| filesystem will be corrupted. +//| +mp_obj_t storage_remount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_readonly, ARG_disable_concurrent_write_protection }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_readonly, MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_disable_concurrent_write_protection, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + + // get the mount point + const char *mnt_str = mp_obj_str_get_str(pos_args[0]); + + // parse args + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + common_hal_storage_remount(mnt_str, args[ARG_readonly].u_bool, args[ARG_disable_concurrent_write_protection].u_bool); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(storage_remount_obj, 1, storage_remount); + +//| .. function:: getmount(mount_path) +//| +//| Retrieves the mount object associated with the mount path +//| +mp_obj_t storage_getmount(const mp_obj_t mnt_in) { + return common_hal_storage_getmount(mp_obj_str_get_str(mnt_in)); +} +MP_DEFINE_CONST_FUN_OBJ_1(storage_getmount_obj, storage_getmount); + +//| .. function:: erase_filesystem() +//| +//| Erase and re-create the ``CIRCUITPY`` filesystem. +//| +//| On boards that present USB-visible ``CIRCUITPY`` drive (e.g., SAMD21 and SAMD51), +//| then call `microcontroller.reset()` to restart CircuitPython and have the +//| host computer remount CIRCUITPY. +//| +//| This function can be called from the REPL when ``CIRCUITPY`` +//| has become corrupted. +//| +//| .. warning:: All the data on ``CIRCUITPY`` will be lost, and +//| CircuitPython will restart on certain boards. + +mp_obj_t storage_erase_filesystem(void) { + common_hal_storage_erase_filesystem(); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(storage_erase_filesystem_obj, storage_erase_filesystem); + +STATIC const mp_rom_map_elem_t storage_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_storage) }, + + { MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&storage_mount_obj) }, + { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&storage_umount_obj) }, + { MP_ROM_QSTR(MP_QSTR_remount), MP_ROM_PTR(&storage_remount_obj) }, + { MP_ROM_QSTR(MP_QSTR_getmount), MP_ROM_PTR(&storage_getmount_obj) }, + { MP_ROM_QSTR(MP_QSTR_erase_filesystem), MP_ROM_PTR(&storage_erase_filesystem_obj) }, + + //| .. class:: VfsFat(block_device) + //| + //| Create a new VfsFat filesystem around the given block device. + //| + //| :param block_device: Block device the the filesystem lives on + //| + //| .. attribute:: label + //| + //| The filesystem label, up to 11 case-insensitive bytes. Note that + //| this property can only be set when the device is writable by the + //| microcontroller. + //| + //| .. method:: mkfs() + //| + //| Format the block device, deleting any data that may have been there + //| + //| .. method:: open(path, mode) + //| + //| Like builtin ``open()`` + //| + //| .. method:: ilistdir([path]) + //| + //| Return an iterator whose values describe files and folders within + //| ``path`` + //| + //| .. method:: mkdir(path) + //| + //| Like `os.mkdir` + //| + //| .. method:: rmdir(path) + //| + //| Like `os.rmdir` + //| + //| .. method:: stat(path) + //| + //| Like `os.stat` + //| + //| .. method:: statvfs(path) + //| + //| Like `os.statvfs` + //| + //| .. method:: mount(readonly, mkfs) + //| + //| Don't call this directly, call `storage.mount`. + //| + //| .. method:: umount() + //| + //| Don't call this directly, call `storage.umount`. + //| + { MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(storage_module_globals, storage_module_globals_table); + +const mp_obj_module_t storage_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&storage_module_globals, +}; diff --git a/shared-bindings/storage/__init__.h b/shared-bindings/storage/__init__.h new file mode 100644 index 00000000000..7851b9e292b --- /dev/null +++ b/shared-bindings/storage/__init__.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_STORAGE___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_STORAGE___INIT___H + +#include +#include + +void common_hal_storage_mount(mp_obj_t vfs_obj, const char* path, bool readonly); +void common_hal_storage_umount_path(const char* path); +void common_hal_storage_umount_object(mp_obj_t vfs_obj); +void common_hal_storage_remount(const char* path, bool readonly, bool disable_concurrent_write_protection); +mp_obj_t common_hal_storage_getmount(const char* path); +void common_hal_storage_erase_filesystem(void); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_STORAGE___INIT___H diff --git a/shared-bindings/struct/__init__.c b/shared-bindings/struct/__init__.c new file mode 100644 index 00000000000..ea14b376371 --- /dev/null +++ b/shared-bindings/struct/__init__.c @@ -0,0 +1,186 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky + * Copyright (c) 2017 Michael McWethy + * + * 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 +#include + +#include "py/runtime.h" +#include "py/builtin.h" +#include "py/objtuple.h" +#include "py/binary.h" +#include "py/parsenum.h" +#include "shared-bindings/struct/__init__.h" +#include "shared-module/struct/__init__.h" +#include "supervisor/shared/translate.h" + +//| :mod:`struct` --- manipulation of c-style data +//| ======================================================== +//| +//| .. module:: struct +//| :synopsis: byte data control +//| :platform: SAMD21 +//| +//| This module implements a subset of the corresponding CPython module, +//| as described below. For more information, refer to the original CPython +//| documentation: struct. +//| +//| Supported size/byte order prefixes: *@*, *<*, *>*, *!*. +//| +//| Supported format codes: *b*, *B*, *x*, *h*, *H*, *i*, *I*, *l*, *L*, *q*, *Q*, +//| *s*, *P*, *f*, *d* (the latter 2 depending on the floating-point support). +//| + + +//| .. function:: calcsize(fmt) +//| +//| Return the number of bytes needed to store the given fmt. +//| + +STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) { + + return MP_OBJ_NEW_SMALL_INT(shared_modules_struct_calcsize(fmt_in)); +} +MP_DEFINE_CONST_FUN_OBJ_1(struct_calcsize_obj, struct_calcsize); + +//| .. function:: pack(fmt, *values) +//| +//| Pack the values according to the format string fmt. +//| The return value is a bytes object encoding the values. +//| + +STATIC mp_obj_t struct_pack(size_t n_args, const mp_obj_t *args) { + mp_int_t size = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0])); + vstr_t vstr; + vstr_init_len(&vstr, size); + byte *p = (byte*)vstr.buf; + memset(p, 0, size); + byte *end_p = &p[size]; + shared_modules_struct_pack_into(args[0], p, end_p, n_args - 1, &args[1]); + return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_obj, 1, MP_OBJ_FUN_ARGS_MAX, struct_pack); + +//| .. function:: pack_into(fmt, buffer, offset, *values) +//| +//| Pack the values according to the format string fmt into a buffer +//| starting at offset. offset may be negative to count from the end of buffer. +//| + +STATIC mp_obj_t struct_pack_into(size_t n_args, const mp_obj_t *args) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE); + mp_int_t offset = mp_obj_get_int(args[2]); + if (offset < 0) { + // negative offsets are relative to the end of the buffer + offset = (mp_int_t)bufinfo.len + offset; + if (offset < 0) { + mp_raise_RuntimeError(translate("buffer too small")); + } + } + byte *p = (byte *)bufinfo.buf; + byte *end_p = &p[bufinfo.len]; + p += offset; + + shared_modules_struct_pack_into(args[0], p, end_p, n_args - 3, &args[3]); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_into_obj, 3, MP_OBJ_FUN_ARGS_MAX, struct_pack_into); + +//| .. function:: unpack(fmt, data) +//| +//| Unpack from the data according to the format string fmt. The return value +//| is a tuple of the unpacked values. The buffer size must match the size +//| required by the format. +//| + +STATIC mp_obj_t struct_unpack(size_t n_args, const mp_obj_t *args) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ); + byte *p = bufinfo.buf; + byte *end_p = &p[bufinfo.len]; + + // true means check the size must be exactly right. + return MP_OBJ_FROM_PTR(shared_modules_struct_unpack_from(args[0] , p, end_p, true)); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_unpack_obj, 2, 3, struct_unpack); + +//| .. function:: unpack_from(fmt, data, offset=0) +//| +//| Unpack from the data starting at offset according to the format string fmt. +//| offset may be negative to count from the end of buffer. The return value is +//| a tuple of the unpacked values. The buffer size must be at least as big +//| as the size required by the form. +//| + +STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_format, ARG_buffer, ARG_offset }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_format, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_offset, MP_ARG_INT, {.u_int = 0} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); + byte *p = bufinfo.buf; + byte *end_p = &p[bufinfo.len]; + + mp_int_t offset = args[ARG_offset].u_int; + if (offset < 0) { + // negative offsets are relative to the end of the buffer + offset = bufinfo.len + offset; + if (offset < 0) { + mp_raise_RuntimeError(translate("buffer too small")); + } + } + p += offset; + + // false means the size doesn't have to be exact. struct.unpack_from() only requires + // that be buffer be big enough. + return MP_OBJ_FROM_PTR(shared_modules_struct_unpack_from(args[ARG_format].u_obj, p, end_p, false)); +} +MP_DEFINE_CONST_FUN_OBJ_KW(struct_unpack_from_obj, 0, struct_unpack_from); + +STATIC const mp_rom_map_elem_t mp_module_struct_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_struct) }, + { MP_ROM_QSTR(MP_QSTR_calcsize), MP_ROM_PTR(&struct_calcsize_obj) }, + { MP_ROM_QSTR(MP_QSTR_pack), MP_ROM_PTR(&struct_pack_obj) }, + { MP_ROM_QSTR(MP_QSTR_pack_into), MP_ROM_PTR(&struct_pack_into_obj) }, + { MP_ROM_QSTR(MP_QSTR_unpack), MP_ROM_PTR(&struct_unpack_obj) }, + { MP_ROM_QSTR(MP_QSTR_unpack_from), MP_ROM_PTR(&struct_unpack_from_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(mp_module_struct_globals, mp_module_struct_globals_table); + +const mp_obj_module_t struct_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mp_module_struct_globals, +}; diff --git a/shared-bindings/struct/__init__.h b/shared-bindings/struct/__init__.h new file mode 100644 index 00000000000..a7e72b11c75 --- /dev/null +++ b/shared-bindings/struct/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_STRUCT___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_STRUCT___INIT___H + +void shared_modules_struct_pack_into(mp_obj_t fmt_in, byte *p, byte* end_p, size_t n_args, const mp_obj_t *args); +mp_uint_t shared_modules_struct_calcsize(mp_obj_t fmt_in); +mp_obj_tuple_t * shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byte *end_p, bool exact_size); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_RANDOM___INIT___H diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c new file mode 100755 index 00000000000..746dfe5ee78 --- /dev/null +++ b/shared-bindings/supervisor/Runtime.c @@ -0,0 +1,116 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Michael Schroeder + * + * 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 +#include "py/objproperty.h" +#include "shared-bindings/supervisor/Runtime.h" + +//TODO: add USB, REPL to description once they're operational +//| .. currentmodule:: supervisor +//| +//| :class:`Runtime` --- Supervisor Runtime information +//| ---------------------------------------------------- +//| +//| Get current status of runtime objects. +//| +//| Usage:: +//| +//| import supervisor +//| if supervisor.runtime.serial_connected: +//| print("Hello World!") +//| + +//| .. class:: Runtime() +//| +//| You cannot create an instance of `supervisor.Runtime`. +//| Use `supervisor.runtime` to access the sole instance available. +//| + +//| .. attribute:: runtime.serial_connected +//| +//| Returns the USB serial communication status (read-only). +//| +//| .. note:: +//| +//| SAMD: Will return ``True`` if the USB serial connection +//| has been established at any point. Will not reset if +//| USB is disconnected but power remains (e.g. battery connected) +//| + +STATIC mp_obj_t supervisor_get_serial_connected(mp_obj_t self){ + if (!common_hal_get_serial_connected()) { + return mp_const_false; + } + else { + return mp_const_true; + } +} +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_get_serial_connected_obj, supervisor_get_serial_connected); + +const mp_obj_property_t supervisor_serial_connected_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&supervisor_get_serial_connected_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +//| .. attribute:: runtime.serial_bytes_available +//| +//| Returns the whether any bytes are available to read +//| on the USB serial input. Allows for polling to see whether +//| to call the built-in input() or wait. (read-only) +//| +STATIC mp_obj_t supervisor_get_serial_bytes_available(mp_obj_t self){ + if (!common_hal_get_serial_bytes_available()) { + return mp_const_false; + } + else { + return mp_const_true; + } +} +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_get_serial_bytes_available_obj, supervisor_get_serial_bytes_available); + +const mp_obj_property_t supervisor_serial_bytes_available_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&supervisor_get_serial_bytes_available_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +STATIC const mp_rom_map_elem_t supervisor_runtime_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_serial_connected), MP_ROM_PTR(&supervisor_serial_connected_obj) }, + { MP_ROM_QSTR(MP_QSTR_serial_bytes_available), MP_ROM_PTR(&supervisor_serial_bytes_available_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(supervisor_runtime_locals_dict, supervisor_runtime_locals_dict_table); + +const mp_obj_type_t supervisor_runtime_type = { + .base = { &mp_type_type }, + .name = MP_QSTR_Runtime, + .locals_dict = (mp_obj_t)&supervisor_runtime_locals_dict, +}; diff --git a/shared-bindings/supervisor/Runtime.h b/shared-bindings/supervisor/Runtime.h new file mode 100755 index 00000000000..864b070cdbb --- /dev/null +++ b/shared-bindings/supervisor/Runtime.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Michael Schroeder + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_RUNTIME_STATUS_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_RUNTIME_STATUS_H + +#include +#include "py/obj.h" + + +const mp_obj_type_t supervisor_runtime_type; + +bool common_hal_get_serial_connected(void); + +bool common_hal_get_serial_bytes_available(void); + +//TODO: placeholders for future functions +//bool common_hal_get_repl_active(void); +//bool common_hal_get_usb_enumerated(void); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SUPERVISOR_RUNTIME_H diff --git a/shared-bindings/supervisor/__init__.c b/shared-bindings/supervisor/__init__.c new file mode 100644 index 00000000000..2705c8e581e --- /dev/null +++ b/shared-bindings/supervisor/__init__.c @@ -0,0 +1,143 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016-2017 Scott Shawcroft for Adafruit Industries + * + * 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 "py/obj.h" +#include "py/runtime.h" +#include "py/reload.h" + +#include "lib/utils/interrupt_char.h" +#include "supervisor/shared/autoreload.h" +#include "supervisor/shared/rgb_led_status.h" +#include "supervisor/shared/stack.h" +#include "supervisor/shared/translate.h" + +#include "shared-bindings/supervisor/__init__.h" +#include "shared-bindings/supervisor/Runtime.h" + +//| :mod:`supervisor` --- Supervisor settings +//| ================================================= +//| +//| .. module:: supervisor +//| :synopsis: Supervisor settings +//| :platform: SAMD21/51 (All), nRF (Runtime only) +//| +//| The `supervisor` module. (TODO: expand description) +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Runtime +//| + +//| .. attribute:: runtime +//| +//| Runtime information, such as `runtime.serial_connected` +//| (USB serial connection status). +//| This object is the sole instance of `supervisor.Runtime`. +//| + +//| .. method:: enable_autoreload() +//| +//| Enable autoreload based on USB file write activity. +//| +STATIC mp_obj_t supervisor_enable_autoreload(void) { + autoreload_enable(); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(supervisor_enable_autoreload_obj, supervisor_enable_autoreload); + +//| .. method:: disable_autoreload() +//| +//| Disable autoreload based on USB file write activity until +//| `enable_autoreload` is called. +//| +STATIC mp_obj_t supervisor_disable_autoreload(void) { + autoreload_disable(); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(supervisor_disable_autoreload_obj, supervisor_disable_autoreload); + +//| .. method:: set_rgb_status_brightness() +//| +//| Set brightness of status neopixel from 0-255 +//| `set_rgb_status_brightness` is called. +//| +STATIC mp_obj_t supervisor_set_rgb_status_brightness(mp_obj_t lvl){ + // This must be int. If cast to uint8_t first, will never raise a ValueError. + int brightness_int = mp_obj_get_int(lvl); + if(brightness_int < 0 || brightness_int > 255){ + mp_raise_ValueError(translate("Brightness must be between 0 and 255")); + } + set_rgb_status_brightness((uint8_t)brightness_int); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_set_rgb_status_brightness_obj, supervisor_set_rgb_status_brightness); + +//| .. method:: reload() +//| +//| Reload the main Python code and run it (equivalent to hitting Ctrl-D at the REPL). +//| +STATIC mp_obj_t supervisor_reload(void) { + reload_requested = true; + mp_raise_reload_exception(); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(supervisor_reload_obj, supervisor_reload); + +//| .. method:: set_next_stack_limit(size) +//| +//| Set the size of the stack for the next vm run. If its too large, the default will be used. +//| +STATIC mp_obj_t supervisor_set_next_stack_limit(mp_obj_t size_obj) { + mp_int_t size = mp_obj_get_int(size_obj); + + if (size < 256) { + mp_raise_ValueError(translate("Stack size must be at least 256")); + } + set_next_stack_size(size); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_set_next_stack_limit_obj, supervisor_set_next_stack_limit); + +STATIC const mp_rom_map_elem_t supervisor_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_supervisor) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_enable_autoreload), MP_ROM_PTR(&supervisor_enable_autoreload_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_disable_autoreload), MP_ROM_PTR(&supervisor_disable_autoreload_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_set_rgb_status_brightness), MP_ROM_PTR(&supervisor_set_rgb_status_brightness_obj) }, + { MP_ROM_QSTR(MP_QSTR_runtime), MP_ROM_PTR(&common_hal_supervisor_runtime_obj) }, + { MP_ROM_QSTR(MP_QSTR_reload), MP_ROM_PTR(&supervisor_reload_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_next_stack_limit), MP_ROM_PTR(&supervisor_set_next_stack_limit_obj) }, + +}; + +STATIC MP_DEFINE_CONST_DICT(supervisor_module_globals, supervisor_module_globals_table); + +const mp_obj_module_t supervisor_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&supervisor_module_globals, +}; diff --git a/shared-bindings/supervisor/__init__.h b/shared-bindings/supervisor/__init__.h new file mode 100755 index 00000000000..d2e5689452d --- /dev/null +++ b/shared-bindings/supervisor/__init__.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Michael Schroeder + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_SUPERVISOR___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_SUPERVISOR___INIT___H + +//#include "py/mpconfig.h" +#include "py/obj.h" + +#include "common-hal/supervisor/Runtime.h" + +extern const super_runtime_obj_t common_hal_supervisor_runtime_obj; + + + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SUPERVISOR___INIT___H \ No newline at end of file diff --git a/shared-bindings/support_matrix.rst b/shared-bindings/support_matrix.rst new file mode 100644 index 00000000000..124f3a81045 --- /dev/null +++ b/shared-bindings/support_matrix.rst @@ -0,0 +1,16 @@ +.. _module-support-matrix: + +Support Matrix +=============== + +The following table lists the available built-in modules for each CircuitPython +capable board. + +.. csv-table:: + :header-rows: 1 + :widths: 7, 50 + + "Board", "Modules Available" + {% for key, value in support_matrix|dictsort -%} + "{{ key }}", "{{ '`' ~ value|join("`, `") ~ '`' }}" + {% endfor -%} diff --git a/shared-bindings/terminalio/Terminal.c b/shared-bindings/terminalio/Terminal.c new file mode 100644 index 00000000000..cdde672d3a8 --- /dev/null +++ b/shared-bindings/terminalio/Terminal.c @@ -0,0 +1,129 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "shared-bindings/terminalio/Terminal.h" +#include "shared-bindings/util.h" + +#include "py/ioctl.h" +#include "py/objproperty.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "shared-bindings/fontio/BuiltinFont.h" +#include "supervisor/shared/translate.h" + + +//| .. currentmodule:: terminalio +//| +//| :class:`Terminal` -- display a character stream with a TileGrid +//| ================================================================ +//| +//| .. class:: Terminal(tilegrid, font) +//| +//| Terminal manages tile indices and cursor position based on VT100 commands. The font should be +//| a `fontio.BuiltinFont` and the TileGrid's bitmap should match the font's bitmap. +//| + +STATIC mp_obj_t terminalio_terminal_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_tilegrid, ARG_font }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_tilegrid, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_font, MP_ARG_REQUIRED | MP_ARG_OBJ }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t tilegrid = args[ARG_tilegrid].u_obj; + if (!MP_OBJ_IS_TYPE(tilegrid, &displayio_tilegrid_type)) { + mp_raise_TypeError_varg(translate("Expected a %q"), displayio_tilegrid_type.name); + } + + mp_obj_t font = args[ARG_font].u_obj; + if (!MP_OBJ_IS_TYPE(font, &fontio_builtinfont_type)) { + mp_raise_TypeError_varg(translate("Expected a %q"), fontio_builtinfont_type.name); + } + terminalio_terminal_obj_t *self = m_new_obj(terminalio_terminal_obj_t); + self->base.type = &terminalio_terminal_type; + common_hal_terminalio_terminal_construct(self, MP_OBJ_TO_PTR(tilegrid), MP_OBJ_TO_PTR(font)); + return MP_OBJ_FROM_PTR(self); +} + +// These are standard stream methods. Code is in py/stream.c. +// +//| .. method:: write(buf) +//| +//| Write the buffer of bytes to the bus. +//| +//| :return: the number of bytes written +//| :rtype: int or None +//| +STATIC mp_uint_t terminalio_terminal_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { + terminalio_terminal_obj_t *self = MP_OBJ_TO_PTR(self_in); + const byte *buf = buf_in; + + return common_hal_terminalio_terminal_write(self, buf, size, errcode); +} + +STATIC mp_uint_t terminalio_terminal_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { + terminalio_terminal_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_uint_t ret; + if (request == MP_IOCTL_POLL) { + mp_uint_t flags = arg; + ret = 0; + if ((flags & MP_IOCTL_POLL_WR) && common_hal_terminalio_terminal_ready_to_tx(self)) { + ret |= MP_IOCTL_POLL_WR; + } + } else { + *errcode = MP_EINVAL; + ret = MP_STREAM_ERROR; + } + return ret; +} + +STATIC const mp_rom_map_elem_t terminalio_terminal_locals_dict_table[] = { + // Standard stream methods. + { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(terminalio_terminal_locals_dict, terminalio_terminal_locals_dict_table); + +STATIC const mp_stream_p_t terminalio_terminal_stream_p = { + .read = NULL, + .write = terminalio_terminal_write, + .ioctl = terminalio_terminal_ioctl, + .is_text = true, +}; + +const mp_obj_type_t terminalio_terminal_type = { + { &mp_type_type }, + .name = MP_QSTR_Terminal, + .make_new = terminalio_terminal_make_new, + .getiter = mp_identity_getiter, + .iternext = mp_stream_unbuffered_iter, + .protocol = &terminalio_terminal_stream_p, + .locals_dict = (mp_obj_dict_t*)&terminalio_terminal_locals_dict, +}; diff --git a/shared-bindings/terminalio/Terminal.h b/shared-bindings/terminalio/Terminal.h new file mode 100644 index 00000000000..7ae0bf1b032 --- /dev/null +++ b/shared-bindings/terminalio/Terminal.h @@ -0,0 +1,45 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_TERMINALIO_TERMINAL_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_TERMINALIO_TERMINAL_H + +#include "shared-module/terminalio/Terminal.h" + +#include "shared-bindings/displayio/TileGrid.h" + +extern const mp_obj_type_t terminalio_terminal_type; + +extern void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, + displayio_tilegrid_t* tilegrid, const fontio_builtinfont_t* font); + +// Write characters. len is in characters NOT bytes! +extern size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, + const uint8_t *data, size_t len, int *errcode); + +extern bool common_hal_terminalio_terminal_ready_to_tx(terminalio_terminal_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_TERMINALIO_TERMINAL_H diff --git a/shared-bindings/terminalio/__init__.c b/shared-bindings/terminalio/__init__.c new file mode 100644 index 00000000000..a9fe20f30b3 --- /dev/null +++ b/shared-bindings/terminalio/__init__.c @@ -0,0 +1,67 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/terminalio/__init__.h" +#include "shared-bindings/terminalio/Terminal.h" +#include "supervisor/shared/display.h" + +#include "py/runtime.h" + +//| :mod:`terminalio` --- Displays text in a TileGrid +//| ================================================= +//| +//| .. module:: terminalio +//| :synopsis: Displays text in a TileGrid +//| +//| The `terminalio` module contains classes to display a character stream on a display. The built +//| in font is available as ``terminalio.FONT``. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Terminal +//| +//| +STATIC const mp_rom_map_elem_t terminalio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_terminalio) }, + { MP_ROM_QSTR(MP_QSTR_Terminal), MP_OBJ_FROM_PTR(&terminalio_terminal_type) }, + { MP_ROM_QSTR(MP_QSTR_FONT), MP_ROM_PTR(&supervisor_terminal_font) }, +}; + + +STATIC MP_DEFINE_CONST_DICT(terminalio_module_globals, terminalio_module_globals_table); + +const mp_obj_module_t terminalio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&terminalio_module_globals, +}; diff --git a/shared-bindings/terminalio/__init__.h b/shared-bindings/terminalio/__init__.h new file mode 100644 index 00000000000..4be14dfc646 --- /dev/null +++ b/shared-bindings/terminalio/__init__.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_TERMINALIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_TERMINALIO___INIT___H + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_TERMINALIO___INIT___H diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c new file mode 100644 index 00000000000..2654de09aaf --- /dev/null +++ b/shared-bindings/time/__init__.c @@ -0,0 +1,315 @@ +/* + * 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 Josef Gajdusek + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "py/obj.h" +#include "py/objnamedtuple.h" +#include "py/runtime.h" +#include "lib/timeutils/timeutils.h" +#include "shared-bindings/rtc/__init__.h" +#include "shared-bindings/time/__init__.h" +#include "supervisor/shared/translate.h" + +//| :mod:`time` --- time and timing related functions +//| ======================================================== +//| +//| .. module:: time +//| :synopsis: time and timing related functions +//| :platform: SAMD21 +//| +//| The `time` module is a strict subset of the CPython `cpython:time` module. So, code +//| written in MicroPython will work in CPython but not necessarily the other +//| way around. +//| +//| .. function:: monotonic() +//| +//| Returns an always increasing value of time with an unknown reference +//| point. Only use it to compare against other values from `monotonic`. +//| +//| :return: the current monotonic time +//| :rtype: float +//| +STATIC mp_obj_t time_monotonic(void) { + uint64_t time64 = common_hal_time_monotonic(); + // 4294967296 = 2^32 + return mp_obj_new_float(((uint32_t) (time64 >> 32) * 4294967296.0f + (uint32_t) (time64 & 0xffffffff)) / 1000.0f); +} +MP_DEFINE_CONST_FUN_OBJ_0(time_monotonic_obj, time_monotonic); + +//| .. function:: sleep(seconds) +//| +//| Sleep for a given number of seconds. +//| +//| :param float seconds: the time to sleep in fractional seconds +//| +STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) { + #if MICROPY_PY_BUILTINS_FLOAT + float seconds = mp_obj_get_float(seconds_o); + #else + int seconds = mp_obj_get_int(seconds_o); + #endif + if (seconds < 0) { + mp_raise_ValueError(translate("sleep length must be non-negative")); + } + common_hal_time_delay_ms(1000 * seconds); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep); + +#if MICROPY_PY_COLLECTIONS +mp_obj_t struct_time_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + if (n_args != 1 || (kw_args != NULL && kw_args->used > 0)) { + mp_raise_TypeError(translate("time.struct_time() takes exactly 1 argument")); + } + if (!MP_OBJ_IS_TYPE(args[0], &mp_type_tuple) || ((mp_obj_tuple_t*) MP_OBJ_TO_PTR(args[0]))->len != 9) { + mp_raise_TypeError(translate("time.struct_time() takes a 9-sequence")); + } + + mp_obj_tuple_t* tuple = MP_OBJ_TO_PTR(args[0]); + return namedtuple_make_new(type, 9, tuple->items, NULL); +} + +//| .. class:: struct_time(time_tuple) +//| +//| Structure used to capture a date and time. Note that it takes a tuple! +//| +//| :param tuple time_tuple: Tuple of time info: ``(tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst)`` +//| +//| * ``tm_year``: the year, 2017 for example +//| * ``tm_month``: the month, range [1, 12] +//| * ``tm_mday``: the day of the month, range [1, 31] +//| * ``tm_hour``: the hour, range [0, 23] +//| * ``tm_minute``: the minute, range [0, 59] +//| * ``tm_sec``: the second, range [0, 61] +//| * ``tm_wday``: the day of the week, range [0, 6], Monday is 0 +//| * ``tm_yday``: the day of the year, range [1, 366], -1 indicates not known +//| * ``tm_isdst``: 1 when in daylight savings, 0 when not, -1 if unknown. +//| +const mp_obj_namedtuple_type_t struct_time_type_obj = { + .base = { + .base = { + .type = &mp_type_type + }, + .name = MP_QSTR_struct_time, + .print = namedtuple_print, + .make_new = struct_time_make_new, + .unary_op = mp_obj_tuple_unary_op, + .binary_op = mp_obj_tuple_binary_op, + .attr = namedtuple_attr, + .subscr = mp_obj_tuple_subscr, + .getiter = mp_obj_tuple_getiter, + .parent = &mp_type_tuple, + }, + .n_fields = 9, + .fields = { + MP_QSTR_tm_year, + MP_QSTR_tm_mon, + MP_QSTR_tm_mday, + MP_QSTR_tm_hour, + MP_QSTR_tm_min, + MP_QSTR_tm_sec, + MP_QSTR_tm_wday, + MP_QSTR_tm_yday, + MP_QSTR_tm_isdst + }, +}; + +mp_obj_t struct_time_from_tm(timeutils_struct_time_t *tm) { + timeutils_struct_time_t tmp; + mp_uint_t secs = timeutils_seconds_since_epoch(tm->tm_year, tm->tm_mon, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + timeutils_seconds_since_epoch_to_struct_time(secs, &tmp); + tm->tm_wday = tmp.tm_wday; + tm->tm_yday = tmp.tm_yday; + + mp_obj_t elems[9] = { + mp_obj_new_int(tm->tm_year), + mp_obj_new_int(tm->tm_mon), + mp_obj_new_int(tm->tm_mday), + mp_obj_new_int(tm->tm_hour), + mp_obj_new_int(tm->tm_min), + mp_obj_new_int(tm->tm_sec), + mp_obj_new_int(tm->tm_wday), + mp_obj_new_int(tm->tm_yday), + mp_obj_new_int(-1), // tm_isdst is not supported + }; + + return namedtuple_make_new((const mp_obj_type_t*)&struct_time_type_obj, 9, elems, NULL); +}; + +void struct_time_to_tm(mp_obj_t t, timeutils_struct_time_t *tm) { + mp_obj_t *elems; + size_t len; + + if (!MP_OBJ_IS_TYPE(t, &mp_type_tuple) && !MP_OBJ_IS_TYPE(t, MP_OBJ_FROM_PTR(&struct_time_type_obj))) { + mp_raise_TypeError(translate("Tuple or struct_time argument required")); + } + + mp_obj_tuple_get(t, &len, &elems); + if (len != 9) { + mp_raise_TypeError(translate("function takes exactly 9 arguments")); + } + + tm->tm_year = mp_obj_get_int(elems[0]); + tm->tm_mon = mp_obj_get_int(elems[1]); + tm->tm_mday = mp_obj_get_int(elems[2]); + tm->tm_hour = mp_obj_get_int(elems[3]); + tm->tm_min = mp_obj_get_int(elems[4]); + tm->tm_sec = mp_obj_get_int(elems[5]); + tm->tm_wday = mp_obj_get_int(elems[6]); + tm->tm_yday = mp_obj_get_int(elems[7]); + // elems[8] tm_isdst is not supported +} + +#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE +mp_obj_t MP_WEAK rtc_get_time_source_time(void) { + mp_raise_RuntimeError(translate("RTC is not supported on this board")); +} + +//| .. function:: time() +//| +//| Return the current time in seconds since since Jan 1, 1970. +//| +//| :return: the current time +//| :rtype: int +//| +STATIC mp_obj_t time_time(void) { + timeutils_struct_time_t tm; + struct_time_to_tm(rtc_get_time_source_time(), &tm); + mp_uint_t secs = timeutils_seconds_since_epoch(tm.tm_year, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + return mp_obj_new_int_from_uint(secs); +} +MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time); + +//| .. function:: monotonic_ns() +//| +//| Return the time of the specified clock clk_id in nanoseconds. +//| +//| :return: the current time +//| :rtype: int +//| +STATIC mp_obj_t time_monotonic_ns(void) { + uint64_t time64 = common_hal_time_monotonic() * 1000000llu; + return mp_obj_new_int_from_ll((long long) time64); +} +MP_DEFINE_CONST_FUN_OBJ_0(time_monotonic_ns_obj, time_monotonic_ns); + +//| .. function:: localtime([secs]) +//| +//| Convert a time expressed in seconds since Jan 1, 1970 to a struct_time in +//| local time. If secs is not provided or None, the current time as returned +//| by time() is used. +//| The earliest date for which it can generate a time is Jan 1, 2000. +//| +//| :return: the current time +//| :rtype: time.struct_time +//| +STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { + if (n_args == 0 || args[0] == mp_const_none) { + return rtc_get_time_source_time(); + } + + mp_obj_t arg = args[0]; + if (mp_obj_is_float(arg)) { + arg = mp_obj_new_int_from_float(mp_obj_get_float(arg)); + } + + mp_int_t secs = mp_obj_get_int(arg); + + if (secs < EPOCH1970_EPOCH2000_DIFF_SECS) { + mp_raise_msg(&mp_type_OverflowError, translate("timestamp out of range for platform time_t")); + } + + timeutils_struct_time_t tm; + timeutils_seconds_since_epoch_to_struct_time(secs, &tm); + + return struct_time_from_tm(&tm); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(time_localtime_obj, 0, 1, time_localtime); + +//| .. function:: mktime(t) +//| +//| This is the inverse function of localtime(). Its argument is the +//| struct_time or full 9-tuple (since the dst flag is needed; use -1 as the +//| dst flag if it is unknown) which expresses the time in local time, not UTC. +//| The earliest date for which it can generate a time is Jan 1, 2000. +//| +//| :return: seconds +//| :rtype: int +//| +STATIC mp_obj_t time_mktime(mp_obj_t t) { + mp_obj_t *elem; + size_t len; + + if (!MP_OBJ_IS_TYPE(t, &mp_type_tuple) && !MP_OBJ_IS_TYPE(t, MP_OBJ_FROM_PTR(&struct_time_type_obj))) { + mp_raise_TypeError(translate("Tuple or struct_time argument required")); + } + + mp_obj_tuple_get(t, &len, &elem); + if (len != 9) { + mp_raise_TypeError(translate("function takes exactly 9 arguments")); + } + + if (mp_obj_get_int(elem[0]) < 2000) { + mp_raise_msg(&mp_type_OverflowError, translate("timestamp out of range for platform time_t")); + } + + mp_uint_t secs = timeutils_mktime(mp_obj_get_int(elem[0]), mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]), + mp_obj_get_int(elem[3]), mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5])); + return mp_obj_new_int_from_uint(secs); +} +MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime); +#endif // MICROPY_LONGINT_IMPL +#endif // MICROPY_PY_COLLECTIONS + +STATIC const mp_rom_map_elem_t time_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_time) }, + + { MP_ROM_QSTR(MP_QSTR_monotonic), MP_ROM_PTR(&time_monotonic_obj) }, + { MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&time_sleep_obj) }, + #if MICROPY_PY_COLLECTIONS + { MP_ROM_QSTR(MP_QSTR_struct_time), MP_ROM_PTR(&struct_time_type_obj) }, + #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE + { MP_ROM_QSTR(MP_QSTR_localtime), MP_ROM_PTR(&time_localtime_obj) }, + { MP_ROM_QSTR(MP_QSTR_mktime), MP_ROM_PTR(&time_mktime_obj) }, + #endif // MICROPY_LONGINT_IMPL + #endif // MICROPY_PY_COLLECTIONS + #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE + { MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&time_time_obj) }, + { MP_ROM_QSTR(MP_QSTR_monotonic_ns), MP_ROM_PTR(&time_monotonic_ns_obj) }, + #endif +}; + +STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table); + +const mp_obj_module_t time_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&time_module_globals, +}; diff --git a/shared-bindings/time/__init__.h b/shared-bindings/time/__init__.h new file mode 100644 index 00000000000..c5a0b47fc13 --- /dev/null +++ b/shared-bindings/time/__init__.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_TIME___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_TIME___INIT___H + +#include +#include + +#include "lib/timeutils/timeutils.h" + +extern mp_obj_t struct_time_from_tm(timeutils_struct_time_t *tm); +extern void struct_time_to_tm(mp_obj_t t, timeutils_struct_time_t *tm); + +extern uint64_t common_hal_time_monotonic(void); +extern void common_hal_time_delay_ms(uint32_t); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_TIME___INIT___H diff --git a/shared-bindings/touchio/TouchIn.c b/shared-bindings/touchio/TouchIn.c new file mode 100644 index 00000000000..33d369c7484 --- /dev/null +++ b/shared-bindings/touchio/TouchIn.c @@ -0,0 +1,213 @@ +/* + * 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 +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/mphal.h" +#include "py/nlr.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/touchio/TouchIn.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: touchio +//| +//| :class:`TouchIn` -- Read the state of a capacitive touch sensor +//| =================================================================== +//| +//| Usage:: +//| +//| import touchio +//| from board import * +//| +//| touch = touchio.TouchIn(A1) +//| while True: +//| if touch.value: +//| print("touched!") +//| + +//| .. class:: TouchIn(pin) +//| +//| Use the TouchIn on the given pin. +//| +//| :param ~microcontroller.Pin pin: the pin to read from +//| +STATIC mp_obj_t touchio_touchin_make_new(const mp_obj_type_t *type, + mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + // check number of arguments + mp_arg_check_num(n_args, kw_args, 1, 1, false); + + // 1st argument is the pin + mp_obj_t pin_obj = args[0]; + assert_pin(pin_obj, false); + const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj); + assert_pin_free(pin); + + touchio_touchin_obj_t *self = m_new_obj(touchio_touchin_obj_t); + self->base.type = &touchio_touchin_type; + common_hal_touchio_touchin_construct(self, pin); + + return (mp_obj_t) self; +} + +//| .. method:: deinit() +//| +//| Deinitialises the TouchIn and releases any hardware resources for reuse. +//| +STATIC mp_obj_t touchio_touchin_deinit(mp_obj_t self_in) { + touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_touchio_touchin_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_deinit_obj, touchio_touchin_deinit); + +STATIC void check_for_deinit(touchio_touchin_obj_t *self) { + if (common_hal_touchio_touchin_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t touchio_touchin_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_touchio_touchin_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(touchio_touchin___exit___obj, 4, 4, touchio_touchin_obj___exit__); + +//| .. attribute:: value +//| +//| Whether the touch pad is being touched or not. (read-only) +//| +//| True when `raw_value` > `threshold`. +//| +STATIC mp_obj_t touchio_touchin_obj_get_value(mp_obj_t self_in) { + touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_touchio_touchin_get_value(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_get_value_obj, touchio_touchin_obj_get_value); + +const mp_obj_property_t touchio_touchin_value_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&touchio_touchin_get_value_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +//| .. attribute:: raw_value +//| +//| The raw touch measurement as an `int`. (read-only) +//| +STATIC mp_obj_t touchio_touchin_obj_get_raw_value(mp_obj_t self_in) { + touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_touchio_touchin_get_raw_value(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_get_raw_value_obj, touchio_touchin_obj_get_raw_value); + +const mp_obj_property_t touchio_touchin_raw_value_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&touchio_touchin_get_raw_value_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, + }; + + +//| .. attribute:: threshold +//| +//| Minimum `raw_value` needed to detect a touch (and for `value` to be `True`). +//| +//| When the **TouchIn** object is created, an initial `raw_value` is read from the pin, +//| and then `threshold` is set to be 100 + that value. +//| +//| You can adjust `threshold` to make the pin more or less sensitive. +//| +STATIC mp_obj_t touchio_touchin_obj_get_threshold(mp_obj_t self_in) { + touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_touchio_touchin_get_threshold(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_get_threshold_obj, touchio_touchin_obj_get_threshold); + +STATIC mp_obj_t touchio_touchin_obj_set_threshold(mp_obj_t self_in, mp_obj_t threshold_obj) { + touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + uint32_t new_threshold = mp_obj_get_int(threshold_obj); + if (new_threshold < 0 || new_threshold > UINT16_MAX) { + // I would use MP_STRINGIFY(UINT16_MAX), but that prints "0xffff" instead of 65536. + mp_raise_ValueError(translate("threshold must be in the range 0-65536")); + } + common_hal_touchio_touchin_set_threshold(self, new_threshold); + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_2(touchio_touchin_set_threshold_obj, touchio_touchin_obj_set_threshold); + +const mp_obj_property_t touchio_touchin_threshold_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&touchio_touchin_get_threshold_obj, + (mp_obj_t)&touchio_touchin_set_threshold_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +STATIC const mp_rom_map_elem_t touchio_touchin_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&touchio_touchin___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&touchio_touchin_deinit_obj) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_value), MP_ROM_PTR(&touchio_touchin_value_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_raw_value), MP_ROM_PTR(&touchio_touchin_raw_value_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_threshold), MP_ROM_PTR(&touchio_touchin_threshold_obj)}, +}; + +STATIC MP_DEFINE_CONST_DICT(touchio_touchin_locals_dict, touchio_touchin_locals_dict_table); + +const mp_obj_type_t touchio_touchin_type = { + { &mp_type_type }, + .name = MP_QSTR_TouchIn, + .make_new = touchio_touchin_make_new, + .locals_dict = (mp_obj_t)&touchio_touchin_locals_dict, +}; diff --git a/shared-bindings/touchio/TouchIn.h b/shared-bindings/touchio/TouchIn.h new file mode 100644 index 00000000000..e04e79c0b64 --- /dev/null +++ b/shared-bindings/touchio/TouchIn.h @@ -0,0 +1,48 @@ +/* + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_TOUCHIO_TOUCHIN_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_TOUCHIO_TOUCHIN_H + +#include "common-hal/microcontroller/Pin.h" + +#if CIRCUITPY_TOUCHIO_USE_NATIVE +#include "common-hal/touchio/TouchIn.h" +#else +#include "shared-module/touchio/TouchIn.h" +#endif + +extern const mp_obj_type_t touchio_touchin_type; + +void common_hal_touchio_touchin_construct(touchio_touchin_obj_t* self, const mcu_pin_obj_t *pin); +void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t* self); +bool common_hal_touchio_touchin_deinited(touchio_touchin_obj_t* self); +bool common_hal_touchio_touchin_get_value(touchio_touchin_obj_t *self); +uint16_t common_hal_touchio_touchin_get_raw_value(touchio_touchin_obj_t *self); +uint16_t common_hal_touchio_touchin_get_threshold(touchio_touchin_obj_t *self); +void common_hal_touchio_touchin_set_threshold(touchio_touchin_obj_t *self, uint16_t new_threshold); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_TOUCHIO_TOUCHIN_H diff --git a/shared-bindings/touchio/__init__.c b/shared-bindings/touchio/__init__.c new file mode 100644 index 00000000000..6adbe09cf87 --- /dev/null +++ b/shared-bindings/touchio/__init__.c @@ -0,0 +1,82 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/touchio/__init__.h" +#include "shared-bindings/touchio/TouchIn.h" + +#include "py/runtime.h" + +//| :mod:`touchio` --- Touch related IO +//| ================================================= +//| +//| .. module:: touchio +//| :synopsis: Hardware accelerated behavior +//| :platform: SAMD21 +//| +//| The `touchio` module contains classes to provide access to touch IO typically +//| accelerated by hardware on the onboard microcontroller. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| TouchIn +//| +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed if the program continues after use. To do so, either +//| call :py:meth:`!deinit` or use a context manager. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +//| For example:: +//| +//| import touchio +//| from board import * +//| +//| touch_pin = touchio.TouchIn(D6) +//| print(touch_pin.value) +//| +//| This example will initialize the the device, and print the +//| :py:data:`~touchio.TouchIn.value`. +//| + +STATIC const mp_rom_map_elem_t touchio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_touchio) }, + { MP_ROM_QSTR(MP_QSTR_TouchIn), MP_ROM_PTR(&touchio_touchin_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(touchio_module_globals, touchio_module_globals_table); + +const mp_obj_module_t touchio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&touchio_module_globals, +}; diff --git a/shared-bindings/touchio/__init__.h b/shared-bindings/touchio/__init__.h new file mode 100644 index 00000000000..f1d3501418c --- /dev/null +++ b/shared-bindings/touchio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_TOUCHIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_TOUCHIO___INIT___H + +#include "py/obj.h" + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_TOUCHIO___INIT___H diff --git a/shared-bindings/uheap/__init__.c b/shared-bindings/uheap/__init__.c new file mode 100644 index 00000000000..0d699cd2826 --- /dev/null +++ b/shared-bindings/uheap/__init__.c @@ -0,0 +1,63 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/uheap/__init__.h" + +//| :mod:`uheap` --- Heap size analysis +//| ================================================================ +//| +//| .. module:: uheap +//| :synopsis: Heap size analysis +//| + +//| .. function:: info(object) +//| +//| Prints memory debugging info for the given object and returns the +//| estimated size. +//| +STATIC mp_obj_t uheap_info(mp_obj_t obj) { + uint32_t size = shared_module_uheap_info(obj); + + return MP_OBJ_NEW_SMALL_INT(size); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(uheap_info_obj, uheap_info); + +STATIC const mp_rom_map_elem_t uheap_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uheap) }, + { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&uheap_info_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(uheap_module_globals, uheap_module_globals_table); + +const mp_obj_module_t uheap_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&uheap_module_globals, +}; diff --git a/shared-bindings/uheap/__init__.h b/shared-bindings/uheap/__init__.h new file mode 100644 index 00000000000..53afb417235 --- /dev/null +++ b/shared-bindings/uheap/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_UHEAP___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_UHEAP___INIT___H + +#include "py/obj.h" + +extern uint32_t shared_module_uheap_info(mp_obj_t obj); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_UHEAP___INIT___H diff --git a/shared-bindings/usb_hid/Device.c b/shared-bindings/usb_hid/Device.c new file mode 100644 index 00000000000..b1097fb24b6 --- /dev/null +++ b/shared-bindings/usb_hid/Device.c @@ -0,0 +1,113 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "py/objproperty.h" +#include "shared-bindings/usb_hid/Device.h" + +//| .. currentmodule:: usb_hid +//| +//| :class:`Device` -- HID Device +//| ============================================ +//| +//| Usage:: +//| +//| import usb_hid +//| +//| mouse = usb_hid.devices[0] +//| +//| mouse.send_report() +//| + +//| .. class:: Device() +//| +//| Not currently dynamically supported. +//| +//| .. method:: send_report(buf) +//| +//| Send a HID report. +//| +STATIC mp_obj_t usb_hid_device_send_report(mp_obj_t self_in, mp_obj_t buffer) { + usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_READ); + + common_hal_usb_hid_device_send_report(self, ((uint8_t*) bufinfo.buf), bufinfo.len); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(usb_hid_device_send_report_obj, usb_hid_device_send_report); + +//| .. attribute:: usage_page +//| +//| The usage page of the device as an `int`. Can be thought of a category. (read-only) +//| +STATIC mp_obj_t usb_hid_device_obj_get_usage_page(mp_obj_t self_in) { + usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_usb_hid_device_get_usage_page(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_hid_device_get_usage_page_obj, usb_hid_device_obj_get_usage_page); + +const mp_obj_property_t usb_hid_device_usage_page_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&usb_hid_device_get_usage_page_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: usage +//| +//| The functionality of the device as an int. (read-only) +//| +//| For example, Keyboard is 0x06 within the generic desktop usage page 0x01. +//| Mouse is 0x02 within the same usage page. +//| +STATIC mp_obj_t usb_hid_device_obj_get_usage(mp_obj_t self_in) { + usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_usb_hid_device_get_usage(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_hid_device_get_usage_obj, + usb_hid_device_obj_get_usage); + +const mp_obj_property_t usb_hid_device_usage_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&usb_hid_device_get_usage_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t usb_hid_device_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_send_report), MP_ROM_PTR(&usb_hid_device_send_report_obj) }, + { MP_ROM_QSTR(MP_QSTR_usage_page), MP_ROM_PTR(&usb_hid_device_usage_page_obj)}, + { MP_ROM_QSTR(MP_QSTR_usage), MP_ROM_PTR(&usb_hid_device_usage_obj)}, +}; + +STATIC MP_DEFINE_CONST_DICT(usb_hid_device_locals_dict, usb_hid_device_locals_dict_table); + +const mp_obj_type_t usb_hid_device_type = { + { &mp_type_type }, + .name = MP_QSTR_Device, + .locals_dict = (mp_obj_t)&usb_hid_device_locals_dict, +}; diff --git a/shared-bindings/usb_hid/Device.h b/shared-bindings/usb_hid/Device.h new file mode 100644 index 00000000000..cb9a64b5ea0 --- /dev/null +++ b/shared-bindings/usb_hid/Device.h @@ -0,0 +1,38 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_HID_DEVICE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_HID_DEVICE_H + +#include "shared-module/usb_hid/Device.h" + +const mp_obj_type_t usb_hid_device_type; + +void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len); +uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self); +uint8_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_HID_DEVICE_H diff --git a/shared-bindings/usb_hid/__init__.c b/shared-bindings/usb_hid/__init__.c new file mode 100644 index 00000000000..3ad5b06e042 --- /dev/null +++ b/shared-bindings/usb_hid/__init__.c @@ -0,0 +1,66 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" + +#include "shared-bindings/usb_hid/__init__.h" +#include "shared-bindings/usb_hid/Device.h" + +//| :mod:`usb_hid` --- USB Human Interface Device +//| =========================================================== +//| +//| .. module:: usb_hid +//| :synopsis: USB Human Interface Device +//| :platform: SAMD21 +//| +//| The `usb_hid` module allows you to output data as a HID device. +//| + +//| .. attribute:: usb_hid.devices +//| +//| Tuple of all active HID device interfaces. +//| + +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Device +STATIC const mp_rom_map_elem_t usb_hid_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid) }, + { MP_ROM_QSTR(MP_QSTR_devices), MP_ROM_PTR(&common_hal_usb_hid_devices) }, + { MP_ROM_QSTR(MP_QSTR_Device), MP_ROM_PTR(&usb_hid_device_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(usb_hid_module_globals, usb_hid_module_globals_table); + +const mp_obj_module_t usb_hid_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&usb_hid_module_globals, +}; diff --git a/shared-bindings/usb_hid/__init__.h b/shared-bindings/usb_hid/__init__.h new file mode 100644 index 00000000000..3d56fbfd024 --- /dev/null +++ b/shared-bindings/usb_hid/__init__.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef SHARED_BINDINGS_USB_HID_H +#define SHARED_BINDINGS_USB_HID_H + +#include +#include + +extern mp_obj_tuple_t common_hal_usb_hid_devices; + +#endif // SHARED_BINDINGS_USB_HID_H diff --git a/shared-bindings/usb_midi/PortIn.c b/shared-bindings/usb_midi/PortIn.c new file mode 100644 index 00000000000..356a81d52c0 --- /dev/null +++ b/shared-bindings/usb_midi/PortIn.c @@ -0,0 +1,123 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "shared-bindings/usb_midi/PortIn.h" +#include "shared-bindings/util.h" + +#include "py/ioctl.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "supervisor/shared/translate.h" + + +//| .. currentmodule:: usb_midi +//| +//| :class:`PortIn` -- receives midi commands over USB +//| =================================================== +//| +//| .. class:: PortIn() +//| +//| You cannot create an instance of `usb_midi.PortIn`. +//| +//| PortIn objects are constructed for every corresponding entry in the USB +//| descriptor and added to the ``usb_midi.ports`` tuple. +//| + +// These are standard stream methods. Code is in py/stream.c. +// +//| .. method:: read(nbytes=None) +//| +//| Read characters. If ``nbytes`` is specified then read at most that many +//| bytes. Otherwise, read everything that arrives until the connection +//| times out. Providing the number of bytes expected is highly recommended +//| because it will be faster. +//| +//| :return: Data read +//| :rtype: bytes or None +//| +//| .. method:: readinto(buf, nbytes=None) +//| +//| Read bytes into the ``buf``. If ``nbytes`` is specified then read at most +//| that many bytes. Otherwise, read at most ``len(buf)`` bytes. +//| +//| :return: number of bytes read and stored into ``buf`` +//| :rtype: bytes or None +//| + +// These three methods are used by the shared stream methods. +STATIC mp_uint_t usb_midi_portin_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { + usb_midi_portin_obj_t *self = MP_OBJ_TO_PTR(self_in); + byte *buf = buf_in; + + // make sure we want at least 1 char + if (size == 0) { + return 0; + } + + return common_hal_usb_midi_portin_read(self, buf, size, errcode); +} + +STATIC mp_uint_t usb_midi_portin_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { + usb_midi_portin_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_uint_t ret; + if (request == MP_IOCTL_POLL) { + mp_uint_t flags = arg; + ret = 0; + if ((flags & MP_IOCTL_POLL_RD) && common_hal_usb_midi_portin_bytes_available(self) > 0) { + ret |= MP_IOCTL_POLL_RD; + } + } else { + *errcode = MP_EINVAL; + ret = MP_STREAM_ERROR; + } + return ret; +} + +STATIC const mp_rom_map_elem_t usb_midi_portin_locals_dict_table[] = { + // Standard stream methods. + { MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(usb_midi_portin_locals_dict, usb_midi_portin_locals_dict_table); + +STATIC const mp_stream_p_t usb_midi_portin_stream_p = { + .read = usb_midi_portin_read, + .write = NULL, + .ioctl = usb_midi_portin_ioctl, + .is_text = false, +}; + +const mp_obj_type_t usb_midi_portin_type = { + { &mp_type_type }, + .name = MP_QSTR_PortIn, + .getiter = mp_identity_getiter, + .iternext = mp_stream_unbuffered_iter, + .protocol = &usb_midi_portin_stream_p, + .locals_dict = (mp_obj_dict_t*)&usb_midi_portin_locals_dict, +}; diff --git a/shared-bindings/usb_midi/PortIn.h b/shared-bindings/usb_midi/PortIn.h new file mode 100644 index 00000000000..58d017fa026 --- /dev/null +++ b/shared-bindings/usb_midi/PortIn.h @@ -0,0 +1,41 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTIN_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTIN_H + +#include "shared-module/usb_midi/PortIn.h" + +extern const mp_obj_type_t usb_midi_portin_type; + +// Read characters. +extern size_t common_hal_usb_midi_portin_read(usb_midi_portin_obj_t *self, + uint8_t *data, size_t len, int *errcode); + +extern uint32_t common_hal_usb_midi_portin_bytes_available(usb_midi_portin_obj_t *self); +extern void common_hal_usb_midi_portin_clear_buffer(usb_midi_portin_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTIN_H diff --git a/shared-bindings/usb_midi/PortOut.c b/shared-bindings/usb_midi/PortOut.c new file mode 100644 index 00000000000..6f4ce67165d --- /dev/null +++ b/shared-bindings/usb_midi/PortOut.c @@ -0,0 +1,105 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "shared-bindings/usb_midi/PortOut.h" +#include "shared-bindings/util.h" + +#include "py/ioctl.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "supervisor/shared/translate.h" + + +//| .. currentmodule:: usb_midi +//| +//| :class:`PortOut` -- sends midi messages to a computer over USB +//| ============================================================== +//| +//| .. class:: PortOut() +//| +//| You cannot create an instance of `usb_midi.PortOut`. +//| +//| PortOut objects are constructed for every corresponding entry in the USB +//| descriptor and added to the ``usb_midi.ports`` tuple. +//| + +// These are standard stream methods. Code is in py/stream.c. +// +//| .. method:: write(buf) +//| +//| Write the buffer of bytes to the bus. +//| +//| :return: the number of bytes written +//| :rtype: int or None +//| + +STATIC mp_uint_t usb_midi_portout_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { + usb_midi_portout_obj_t *self = MP_OBJ_TO_PTR(self_in); + const byte *buf = buf_in; + + return common_hal_usb_midi_portout_write(self, buf, size, errcode); +} + +STATIC mp_uint_t usb_midi_portout_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { + usb_midi_portout_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_uint_t ret; + if (request == MP_IOCTL_POLL) { + mp_uint_t flags = arg; + ret = 0; + if ((flags & MP_IOCTL_POLL_WR) && common_hal_usb_midi_portout_ready_to_tx(self)) { + ret |= MP_IOCTL_POLL_WR; + } + } else { + *errcode = MP_EINVAL; + ret = MP_STREAM_ERROR; + } + return ret; +} + +STATIC const mp_rom_map_elem_t usb_midi_portout_locals_dict_table[] = { + // Standard stream methods. + { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(usb_midi_portout_locals_dict, usb_midi_portout_locals_dict_table); + +STATIC const mp_stream_p_t usb_midi_portout_stream_p = { + .read = NULL, + .write = usb_midi_portout_write, + .ioctl = usb_midi_portout_ioctl, + .is_text = false, +}; + +const mp_obj_type_t usb_midi_portout_type = { + { &mp_type_type }, + .name = MP_QSTR_PortOut, + .getiter = mp_identity_getiter, + .iternext = mp_stream_unbuffered_iter, + .protocol = &usb_midi_portout_stream_p, + .locals_dict = (mp_obj_dict_t*)&usb_midi_portout_locals_dict, +}; diff --git a/shared-bindings/usb_midi/PortOut.h b/shared-bindings/usb_midi/PortOut.h new file mode 100644 index 00000000000..1eac2fa985d --- /dev/null +++ b/shared-bindings/usb_midi/PortOut.h @@ -0,0 +1,40 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTOUT_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTOUT_H + +#include "shared-module/usb_midi/PortOut.h" + +extern const mp_obj_type_t usb_midi_portout_type; + +// Write characters. len is in characters NOT bytes! +extern size_t common_hal_usb_midi_portout_write(usb_midi_portout_obj_t *self, + const uint8_t *data, size_t len, int *errcode); + +extern bool common_hal_usb_midi_portout_ready_to_tx(usb_midi_portout_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTOUT_H diff --git a/shared-bindings/usb_midi/__init__.c b/shared-bindings/usb_midi/__init__.c new file mode 100644 index 00000000000..f57d3631bc4 --- /dev/null +++ b/shared-bindings/usb_midi/__init__.c @@ -0,0 +1,78 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/usb_midi/__init__.h" +#include "shared-bindings/usb_midi/PortIn.h" +#include "shared-bindings/usb_midi/PortOut.h" + +#include "py/runtime.h" + +//| :mod:`usb_midi` --- MIDI over USB +//| ================================================= +//| +//| .. module:: usb_midi +//| :synopsis: MIDI over USB +//| +//| The `usb_midi` module contains classes to transmit and receive MIDI messages over USB +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| PortIn +//| PortOut +//| +//| +mp_map_elem_t usb_midi_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usb_midi) }, + { MP_ROM_QSTR(MP_QSTR_ports), mp_const_empty_tuple }, + { MP_ROM_QSTR(MP_QSTR_PortIn), MP_OBJ_FROM_PTR(&usb_midi_portin_type) }, + { MP_ROM_QSTR(MP_QSTR_PortOut), MP_OBJ_FROM_PTR(&usb_midi_portout_type) }, +}; + +// This isn't const so we can set ports dynamically. +mp_obj_dict_t usb_midi_module_globals = { + .base = {&mp_type_dict}, + .map = { + .all_keys_are_qstrs = 1, + .is_fixed = 1, + .is_ordered = 1, + .used = MP_ARRAY_SIZE(usb_midi_module_globals_table), + .alloc = MP_ARRAY_SIZE(usb_midi_module_globals_table), + .table = usb_midi_module_globals_table, + }, +}; + +const mp_obj_module_t usb_midi_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&usb_midi_module_globals, +}; diff --git a/shared-bindings/usb_midi/__init__.h b/shared-bindings/usb_midi/__init__.h new file mode 100644 index 00000000000..e81818e04cb --- /dev/null +++ b/shared-bindings/usb_midi/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H + +#include "py/obj.h" + +extern mp_obj_dict_t usb_midi_module_globals; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H diff --git a/shared-bindings/ustack/__init__.c b/shared-bindings/ustack/__init__.c new file mode 100644 index 00000000000..08b772e41eb --- /dev/null +++ b/shared-bindings/ustack/__init__.c @@ -0,0 +1,88 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert for Adafruit Industries + * + * 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 + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/ustack/__init__.h" + +//| :mod:`ustack` --- Stack information and analysis +//| ======================================================== +//| +//| .. module:: ustack +//| :synopsis: stack information functions +//| + +#if MICROPY_MAX_STACK_USAGE +//| .. function:: max_stack_usage() +//| +//| Return the maximum excursion of the stack so far. +//| +STATIC mp_obj_t max_stack_usage(void) { + return MP_OBJ_NEW_SMALL_INT(shared_module_ustack_max_stack_usage()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(max_stack_usage_obj, max_stack_usage); + +#endif // MICROPY_MAX_STACK_USAGE + +//| .. function:: stack_size() +//| +//| Return the size of the entire stack. +//| Same as in micropython.mem_info(), but returns a value instead +//| of just printing it. +//| +STATIC mp_obj_t stack_size(void) { + return MP_OBJ_NEW_SMALL_INT(shared_module_ustack_stack_size()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(stack_size_obj, stack_size); + +//| .. function:: stack_usage() +//| +//| Return how much stack is currently in use. +//| Same as micropython.stack_use(); duplicated here for convenience. +//| +STATIC mp_obj_t stack_usage(void) { + return MP_OBJ_NEW_SMALL_INT(shared_module_ustack_stack_usage()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(stack_usage_obj, stack_usage); + +STATIC const mp_rom_map_elem_t ustack_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ustack) }, + #if MICROPY_MAX_STACK_USAGE + { MP_ROM_QSTR(MP_QSTR_max_stack_usage), MP_ROM_PTR(&max_stack_usage_obj) }, + #endif + { MP_ROM_QSTR(MP_QSTR_stack_size), MP_ROM_PTR(&stack_size_obj) }, + { MP_ROM_QSTR(MP_QSTR_stack_usage), MP_ROM_PTR(&stack_usage_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(ustack_module_globals, ustack_module_globals_table); + +const mp_obj_module_t ustack_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&ustack_module_globals, +}; diff --git a/shared-bindings/ustack/__init__.h b/shared-bindings/ustack/__init__.h new file mode 100644 index 00000000000..561d581b28e --- /dev/null +++ b/shared-bindings/ustack/__init__.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USTACK___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_USTACK___INIT___H + +#include "py/obj.h" + +#if MICROPY_MAX_STACK_USAGE +extern uint32_t shared_module_ustack_max_stack_usage(void); +#endif +extern uint32_t shared_module_ustack_stack_size(void); +extern uint32_t shared_module_ustack_stack_usage(void); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USTACK___INIT___H diff --git a/shared-bindings/util.c b/shared-bindings/util.c new file mode 100644 index 00000000000..c1ca01e0ad4 --- /dev/null +++ b/shared-bindings/util.c @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_UTIL_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_UTIL_H + +#include "py/runtime.h" + +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +// If so, deinit() has already been called on the object, so complain. +void raise_deinited_error(void) { + mp_raise_ValueError(translate("Object has been deinitialized and can no longer be used. Create a new object.")); +} + + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_UTIL_H diff --git a/shared-bindings/util.h b/shared-bindings/util.h new file mode 100644 index 00000000000..33454f10ef7 --- /dev/null +++ b/shared-bindings/util.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_UTIL_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_UTIL_H + +void raise_deinited_error(void); + + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_UTIL_H diff --git a/shared-bindings/wiznet/__init__.c b/shared-bindings/wiznet/__init__.c new file mode 100644 index 00000000000..e230deeccc2 --- /dev/null +++ b/shared-bindings/wiznet/__init__.c @@ -0,0 +1,69 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 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 +#include +#include + +#include "py/objlist.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/mphal.h" + +#include "shared-module/network/__init__.h" + +//| :mod:`wiznet` --- Support for WizNet hardware +//| ============================================= +//| +//| .. module:: wiznet +//| :synopsis: Support for WizNet hardware +//| :platform: SAMD +//| +//| Support for WizNet hardware, including the WizNet 5500 Ethernet adaptor. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| wiznet5k +//| + +extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k; + +STATIC const mp_rom_map_elem_t mp_module_wiznet_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_wiznet) }, +#ifdef MICROPY_PY_WIZNET5K + { MP_ROM_QSTR(MP_QSTR_WIZNET5K), MP_ROM_PTR(&mod_network_nic_type_wiznet5k) }, +#endif // MICROPY_PY_WIZNET5K +}; +STATIC MP_DEFINE_CONST_DICT(mp_module_wiznet_globals, mp_module_wiznet_globals_table); + +const mp_obj_module_t wiznet_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mp_module_wiznet_globals, +}; + diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c new file mode 100644 index 00000000000..ac89cc691e6 --- /dev/null +++ b/shared-bindings/wiznet/wiznet5k.c @@ -0,0 +1,210 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 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 +#include +#include + +#include "py/objlist.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "py/mperrno.h" +#include "py/mphal.h" +#include "lib/netutils/netutils.h" + +#if MICROPY_PY_WIZNET5K + +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/microcontroller/Pin.h" + +#include "shared-module/network/__init__.h" +#include "shared-module/wiznet/wiznet5k.h" + +//| .. currentmodule:: wiznet +//| +//| :class:`WIZNET5K` -- wrapper for Wiznet 5500 Ethernet interface +//| =============================================================== +//| +//| .. class:: WIZNET5K(spi, cs, rst, dhcp=True) +//| +//| Create a new WIZNET5500 interface using the specified pins +//| +//| :param ~busio.SPI spi: spi bus to use +//| :param ~microcontroller.Pin cs: pin to use for Chip Select +//| :param ~microcontroller.Pin rst: pin to use for Reset (optional) +//| :param bool dhcp: boolean flag, whether to start DHCP automatically (optional, keyword only, default True) +//| +//| * The reset pin is optional: if supplied it is used to reset the +//| wiznet board before initialization. +//| * The SPI bus will be initialized appropriately by this library. +//| * At present, the WIZNET5K object is a singleton, so only one WizNet +//| interface is supported at a time. +//| + +STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_spi, ARG_cs, ARG_rst, ARG_dhcp }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_spi, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_cs, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_rst, MP_ARG_OBJ, { .u_obj = mp_const_none } }, + { MP_QSTR_dhcp, MP_ARG_KW_ONLY | MP_ARG_BOOL, { .u_bool = true } }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + // TODO check type of ARG_spi? + assert_pin(args[ARG_cs].u_obj, false); + assert_pin(args[ARG_rst].u_obj, true); // may be NULL + + mp_obj_t ret = wiznet5k_create(args[ARG_spi].u_obj, args[ARG_cs].u_obj, args[ARG_rst].u_obj); + if (args[ARG_dhcp].u_bool) wiznet5k_start_dhcp(); + return ret; +} + +//| .. attribute:: connected +//| +//| (boolean, readonly) is this device physically connected? +//| + +STATIC mp_obj_t wiznet5k_connected_get_value(mp_obj_t self_in) { + (void)self_in; + return mp_obj_new_bool(wizphy_getphylink() == PHY_LINK_ON); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_connected_get_value_obj, wiznet5k_connected_get_value); + +const mp_obj_property_t wiznet5k_connected_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&wiznet5k_connected_get_value_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: dhcp +//| +//| (boolean, readwrite) is DHCP active on this device? +//| +//| * set to True to activate DHCP, False to turn it off +//| + +STATIC mp_obj_t wiznet5k_dhcp_get_value(mp_obj_t self_in) { + (void)self_in; + return mp_obj_new_bool(wiznet5k_check_dhcp()); +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_dhcp_get_value_obj, wiznet5k_dhcp_get_value); + +STATIC mp_obj_t wiznet5k_dhcp_set_value(mp_obj_t self_in, mp_obj_t value) { + (void)self_in; + if (mp_obj_is_true(value)) { + int ret = wiznet5k_start_dhcp(); + if (ret) mp_raise_OSError(ret); + } else { + int ret = wiznet5k_stop_dhcp(); + if (ret) mp_raise_OSError(ret); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(wiznet5k_dhcp_set_value_obj, wiznet5k_dhcp_set_value); + +const mp_obj_property_t wiznet5k_dhcp_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&wiznet5k_dhcp_get_value_obj, + (mp_obj_t)&wiznet5k_dhcp_set_value_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: ifconfig(params=None) +//| +//| Called without parameters, returns a tuple of +//| (ip_address, subnet_mask, gateway_address, dns_server) +//| +//| Or can be called with the same tuple to set those parameters. +//| Setting ifconfig parameters turns DHCP off, if it was on. +//| + +STATIC mp_obj_t wiznet5k_ifconfig(size_t n_args, const mp_obj_t *args) { + wiz_NetInfo netinfo; + ctlnetwork(CN_GET_NETINFO, &netinfo); + if (n_args == 1) { + // get + mp_obj_t tuple[4] = { + netutils_format_ipv4_addr(netinfo.ip, NETUTILS_BIG), + netutils_format_ipv4_addr(netinfo.sn, NETUTILS_BIG), + netutils_format_ipv4_addr(netinfo.gw, NETUTILS_BIG), + netutils_format_ipv4_addr(netinfo.dns, NETUTILS_BIG), + }; + return mp_obj_new_tuple(4, tuple); + } else { + // set + wiznet5k_stop_dhcp(); + mp_obj_t *items; + mp_obj_get_array_fixed_n(args[1], 4, &items); + netutils_parse_ipv4_addr(items[0], netinfo.ip, NETUTILS_BIG); + netutils_parse_ipv4_addr(items[1], netinfo.sn, NETUTILS_BIG); + netutils_parse_ipv4_addr(items[2], netinfo.gw, NETUTILS_BIG); + netutils_parse_ipv4_addr(items[3], netinfo.dns, NETUTILS_BIG); + ctlnetwork(CN_SET_NETINFO, &netinfo); + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_ifconfig_obj, 1, 2, wiznet5k_ifconfig); + +STATIC const mp_rom_map_elem_t wiznet5k_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wiznet5k_ifconfig_obj) }, + { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&wiznet5k_connected_obj) }, + { MP_ROM_QSTR(MP_QSTR_dhcp), MP_ROM_PTR(&wiznet5k_dhcp_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table); + +const mod_network_nic_type_t mod_network_nic_type_wiznet5k = { + .base = { + { &mp_type_type }, + .name = MP_QSTR_WIZNET5K, + .make_new = wiznet5k_make_new, + .locals_dict = (mp_obj_dict_t*)&wiznet5k_locals_dict, + }, + .gethostbyname = wiznet5k_gethostbyname, + .socket = wiznet5k_socket_socket, + .close = wiznet5k_socket_close, + .bind = wiznet5k_socket_bind, + .listen = wiznet5k_socket_listen, + .accept = wiznet5k_socket_accept, + .connect = wiznet5k_socket_connect, + .send = wiznet5k_socket_send, + .recv = wiznet5k_socket_recv, + .sendto = wiznet5k_socket_sendto, + .recvfrom = wiznet5k_socket_recvfrom, + .setsockopt = wiznet5k_socket_setsockopt, + .settimeout = wiznet5k_socket_settimeout, + .ioctl = wiznet5k_socket_ioctl, + .timer_tick = wiznet5k_socket_timer_tick, + .deinit = wiznet5k_socket_deinit, +}; + +#endif // MICROPY_PY_WIZNET5K diff --git a/shared-module/_bleio/Address.c b/shared-module/_bleio/Address.c new file mode 100644 index 00000000000..8c8b043fec9 --- /dev/null +++ b/shared-module/_bleio/Address.c @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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 + +#include "py/objstr.h" +#include "shared-bindings/_bleio/Address.h" +#include "shared-module/_bleio/Address.h" + +void common_hal_bleio_address_construct(bleio_address_obj_t *self, uint8_t *bytes, uint8_t address_type) { + self->bytes = mp_obj_new_bytes(bytes, NUM_BLEIO_ADDRESS_BYTES); + self->type = address_type; +} + +mp_obj_t common_hal_bleio_address_get_address_bytes(bleio_address_obj_t *self) { + return self->bytes; +} + +uint8_t common_hal_bleio_address_get_type(bleio_address_obj_t *self) { + return self->type; +} diff --git a/shared-module/_bleio/Address.h b/shared-module/_bleio/Address.h new file mode 100644 index 00000000000..39789842f7b --- /dev/null +++ b/shared-module/_bleio/Address.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADDRESS_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADDRESS_H + +#include "py/obj.h" + +#define NUM_BLEIO_ADDRESS_BYTES 6 + +typedef struct { + mp_obj_base_t base; + uint8_t type; + mp_obj_t bytes; // a bytes() object +} bleio_address_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADDRESS_H diff --git a/shared-module/_bleio/Attribute.c b/shared-module/_bleio/Attribute.c new file mode 100644 index 00000000000..3acfcf1f53e --- /dev/null +++ b/shared-module/_bleio/Attribute.c @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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 + +#include "py/runtime.h" +#include "shared-bindings/_bleio/Attribute.h" + +void common_hal_bleio_attribute_security_mode_check_valid(bleio_attribute_security_mode_t security_mode) { + switch (security_mode) { + case SECURITY_MODE_NO_ACCESS: + case SECURITY_MODE_OPEN: + case SECURITY_MODE_ENC_NO_MITM: + case SECURITY_MODE_ENC_WITH_MITM: + case SECURITY_MODE_LESC_ENC_WITH_MITM: + case SECURITY_MODE_SIGNED_NO_MITM: + case SECURITY_MODE_SIGNED_WITH_MITM: + break; + default: + mp_raise_ValueError(translate("Invalid security_mode")); + break; + } +} diff --git a/shared-module/_bleio/Attribute.h b/shared-module/_bleio/Attribute.h new file mode 100644 index 00000000000..a498a14a51c --- /dev/null +++ b/shared-module/_bleio/Attribute.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ATTRIBUTE_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ATTRIBUTE_H + +// BLE security modes: 0x +typedef enum { + SECURITY_MODE_NO_ACCESS = 0x00, + SECURITY_MODE_OPEN = 0x11, + SECURITY_MODE_ENC_NO_MITM = 0x21, + SECURITY_MODE_ENC_WITH_MITM = 0x31, + SECURITY_MODE_LESC_ENC_WITH_MITM = 0x41, + SECURITY_MODE_SIGNED_NO_MITM = 0x12, + SECURITY_MODE_SIGNED_WITH_MITM = 0x22, +} bleio_attribute_security_mode_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ATTRIBUTE_H diff --git a/shared-module/_bleio/Characteristic.h b/shared-module/_bleio/Characteristic.h new file mode 100644 index 00000000000..409a57c76e1 --- /dev/null +++ b/shared-module/_bleio/Characteristic.h @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H + +typedef enum { + CHAR_PROP_NONE = 0, + CHAR_PROP_BROADCAST = 1u << 0, + CHAR_PROP_INDICATE = 1u << 1, + CHAR_PROP_NOTIFY = 1u << 2, + CHAR_PROP_READ = 1u << 3, + CHAR_PROP_WRITE = 1u << 4, + CHAR_PROP_WRITE_NO_RESPONSE = 1u << 5, + CHAR_PROP_ALL = (CHAR_PROP_BROADCAST | CHAR_PROP_INDICATE | CHAR_PROP_NOTIFY | + CHAR_PROP_READ | CHAR_PROP_WRITE | CHAR_PROP_WRITE_NO_RESPONSE) +} bleio_characteristic_properties_enum_t; +typedef uint8_t bleio_characteristic_properties_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H diff --git a/shared-module/_bleio/ScanEntry.c b/shared-module/_bleio/ScanEntry.c new file mode 100644 index 00000000000..8dfa17f31f5 --- /dev/null +++ b/shared-module/_bleio/ScanEntry.c @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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 + +#include "shared-bindings/_bleio/Address.h" +#include "shared-module/_bleio/Address.h" +#include "shared-module/_bleio/ScanEntry.h" + +mp_obj_t common_hal_bleio_scanentry_get_address(bleio_scanentry_obj_t *self) { + return MP_OBJ_FROM_PTR(self->address); +} + +mp_obj_t common_hal_bleio_scanentry_get_advertisement_bytes(bleio_scanentry_obj_t *self) { + return self->data; +} + +mp_int_t common_hal_bleio_scanentry_get_rssi(bleio_scanentry_obj_t *self) { + return self->rssi; +} diff --git a/shared-module/_bleio/ScanEntry.h b/shared-module/_bleio/ScanEntry.h new file mode 100644 index 00000000000..1e798d78fd2 --- /dev/null +++ b/shared-module/_bleio/ScanEntry.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H + +#include "py/obj.h" +#include "shared-bindings/_bleio/Address.h" + +typedef struct { + mp_obj_base_t base; + bool connectable; + int8_t rssi; + bleio_address_obj_t *address; + mp_obj_t data; +} bleio_scanentry_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H diff --git a/shared-module/_pew/PewPew.c b/shared-module/_pew/PewPew.c new file mode 100644 index 00000000000..568dc6425f6 --- /dev/null +++ b/shared-module/_pew/PewPew.c @@ -0,0 +1,125 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Radomir Dopieralski + * + * 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 + +#include "py/mpstate.h" +#include "py/runtime.h" +#include "__init__.h" +#include "PewPew.h" + +#include "shared-bindings/digitalio/Pull.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/util.h" +#include "samd/timers.h" +#include "supervisor/shared/translate.h" +#include "timer_handler.h" + + +static uint8_t pewpew_tc_index = 0xff; + + +void pewpew_interrupt_handler(uint8_t index) { + if (index != pewpew_tc_index) { + return; + } + Tc* tc = tc_insts[index]; + if (!tc->COUNT16.INTFLAG.bit.MC0) { + return; + } + + pew_tick(); + + // Clear the interrupt bit. + tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC0; +} + +void pew_init() { + pew_obj_t* pew = MP_STATE_VM(pew_singleton); + + common_hal_digitalio_digitalinout_switch_to_input(pew->buttons, PULL_UP); + + for (size_t i = 0; i < pew->rows_size; ++i) { + digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(pew->rows[i]); + common_hal_digitalio_digitalinout_switch_to_output(pin, false, + DRIVE_MODE_PUSH_PULL); + } + for (size_t i = 0; i < pew->cols_size; ++i) { + digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(pew->cols[i]); + common_hal_digitalio_digitalinout_switch_to_output(pin, true, + DRIVE_MODE_OPEN_DRAIN); + } + if (pewpew_tc_index == 0xff) { + // Find a spare timer. + uint8_t index = find_free_timer(); + if (index == 0xff) { + mp_raise_RuntimeError(translate("All timers in use")); + } + Tc *tc = tc_insts[index]; + + pewpew_tc_index = index; + set_timer_handler(true, index, TC_HANDLER_PEW); + + // We use GCLK0 for SAMD21 and GCLK1 for SAMD51 because they both run + // at 48mhz making our math the same across the boards. + #ifdef SAMD21 + turn_on_clocks(true, index, 0); + #endif + #ifdef SAMD51 + turn_on_clocks(true, index, 1); + #endif + + + #ifdef SAMD21 + tc->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 | + TC_CTRLA_PRESCALER_DIV64 | + TC_CTRLA_WAVEGEN_MFRQ; + #endif + #ifdef SAMD51 + tc_reset(tc); + tc_set_enable(tc, false); + tc->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 + | TC_CTRLA_PRESCALER_DIV64; + tc->COUNT16.WAVE.reg = TC_WAVE_WAVEGEN_MFRQ; + #endif + + tc_set_enable(tc, true); + tc->COUNT16.CC[0].reg = 64; + + // Clear our interrupt in case it was set earlier + tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC0; + tc->COUNT16.INTENSET.reg = TC_INTENSET_MC0; + tc_enable_interrupts(pewpew_tc_index); + } +} + +void pew_reset(void) { + if (pewpew_tc_index != 0xff) { + tc_reset(tc_insts[pewpew_tc_index]); + pewpew_tc_index = 0xff; + } + MP_STATE_VM(pew_singleton) = NULL; +} diff --git a/shared-module/_pew/PewPew.h b/shared-module/_pew/PewPew.h new file mode 100644 index 00000000000..da1cae0a2cc --- /dev/null +++ b/shared-module/_pew/PewPew.h @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Radomir Dopieralski + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_PEW_PEWPEW_H +#define MICROPY_INCLUDED_PEW_PEWPEW_H + +#include +#include "shared-bindings/digitalio/DigitalInOut.h" + +typedef struct { + mp_obj_base_t base; + uint8_t* buffer; + mp_obj_t* rows; + mp_obj_t* cols; + digitalio_digitalinout_obj_t *buttons; + uint8_t rows_size; + uint8_t cols_size; + uint8_t pressed; +} pew_obj_t; + +void pew_init(void); +void pewpew_interrupt_handler(uint8_t index); +void pew_reset(void); + +#endif // MICROPY_INCLUDED_PEW_PEWPEW_H diff --git a/shared-module/_pew/__init__.c b/shared-module/_pew/__init__.c new file mode 100644 index 00000000000..f3b23c606c0 --- /dev/null +++ b/shared-module/_pew/__init__.c @@ -0,0 +1,87 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Radomir Dopieralski + * + * 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 + +#include "py/mpstate.h" +#include "__init__.h" +#include "PewPew.h" + +#include "shared-bindings/digitalio/DigitalInOut.h" + + +void pew_tick(void) { + static uint8_t col = 0; + static uint8_t turn = 0; + static uint8_t pressed = 0; + static uint8_t last_pressed = 0; + digitalio_digitalinout_obj_t *pin; + + pew_obj_t* pew = MP_STATE_VM(pew_singleton); + if (!pew) { return; } + + pin = MP_OBJ_TO_PTR(pew->cols[col]); + ++col; + if (col >= pew->cols_size) { + pew->pressed |= last_pressed & pressed; + last_pressed = pressed; + pressed = 0; + col = 0; + ++turn; + if (turn > 11) { + turn = 0; + } + } + if (!common_hal_digitalio_digitalinout_get_value(pew->buttons)) { + pressed |= 1 << col; + } + common_hal_digitalio_digitalinout_set_value(pin, true); + for (size_t x = 0; x < pew->rows_size; ++x) { + pin = MP_OBJ_TO_PTR(pew->rows[x]); + uint8_t color = pew->buffer[col * (pew->rows_size) + x]; + bool value = false; + switch (color & 0x03) { + case 3: + value = true; + break; + case 2: + if (turn == 2 || turn == 5 || turn == 8 || turn == 11) { + value = true; + } + break; + case 1: + if (turn == 0) { + value = true; + } + break; + case 0: + break; + } + common_hal_digitalio_digitalinout_set_value(pin, value); + } + pin = MP_OBJ_TO_PTR(pew->cols[col]); + common_hal_digitalio_digitalinout_set_value(pin, false); +} diff --git a/shared-module/_pew/__init__.h b/shared-module/_pew/__init__.h new file mode 100644 index 00000000000..4f953c61064 --- /dev/null +++ b/shared-module/_pew/__init__.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Radomir Dopieralski + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_PEW_H +#define MICROPY_INCLUDED_PEW_H + +void pew_tick(void); + +#endif // MICROPY_INCLUDED_PEW_H diff --git a/shared-module/_pixelbuf/PixelBuf.c b/shared-module/_pixelbuf/PixelBuf.c new file mode 100644 index 00000000000..d3269723919 --- /dev/null +++ b/shared-module/_pixelbuf/PixelBuf.c @@ -0,0 +1,120 @@ +/* + * This file is part of the Circuit Python project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Roy Hooper + * + * 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 "py/obj.h" +#include "py/objarray.h" +#include "py/runtime.h" +#include "PixelBuf.h" +#include + +void pixelbuf_set_pixel_int(uint8_t *buf, mp_int_t value, pixelbuf_byteorder_obj_t *byteorder) { + buf[byteorder->byteorder.r] = value >> 16 & 0xff; + buf[byteorder->byteorder.g] = (value >> 8) & 0xff; + buf[byteorder->byteorder.b] = value & 0xff; + if (byteorder->bpp == 4 && byteorder->has_white && + (buf[byteorder->byteorder.r] == buf[byteorder->byteorder.g] && + buf[byteorder->byteorder.r] == buf[byteorder->byteorder.b])) { + buf[byteorder->byteorder.w] = buf[byteorder->byteorder.r]; + buf[byteorder->byteorder.r] = buf[byteorder->byteorder.g] = buf[byteorder->byteorder.b] = 0; + } +} + +void pixelbuf_set_pixel(uint8_t *buf, uint8_t *rawbuf, float brightness, mp_obj_t *item, pixelbuf_byteorder_obj_t *byteorder, bool dotstar) { + if (MP_OBJ_IS_INT(item)) { + uint8_t *target = rawbuf ? rawbuf : buf; + pixelbuf_set_pixel_int(target, mp_obj_get_int_truncated(item), byteorder); + if (dotstar) { + buf[0] = DOTSTAR_LED_START_FULL_BRIGHT; + if (rawbuf) + rawbuf[0] = DOTSTAR_LED_START_FULL_BRIGHT; + } + if (rawbuf) { + buf[byteorder->byteorder.r] = rawbuf[byteorder->byteorder.r] * brightness; + buf[byteorder->byteorder.g] = rawbuf[byteorder->byteorder.g] * brightness; + buf[byteorder->byteorder.b] = rawbuf[byteorder->byteorder.b] * brightness; + } else { + buf[byteorder->byteorder.r] *= brightness; + buf[byteorder->byteorder.g] *= brightness; + buf[byteorder->byteorder.b] *= brightness; + } + } else { + mp_obj_t *items; + size_t len; + mp_obj_get_array(item, &len, &items); + if (len != byteorder->bpp && !dotstar) + mp_raise_ValueError_varg(translate("Expected tuple of length %d, got %d"), byteorder->bpp, len); + + buf[byteorder->byteorder.r] = mp_obj_get_int_truncated(items[PIXEL_R]) * brightness; + buf[byteorder->byteorder.g] = mp_obj_get_int_truncated(items[PIXEL_G]) * brightness; + buf[byteorder->byteorder.b] = mp_obj_get_int_truncated(items[PIXEL_B]) * brightness; + if (rawbuf) { + rawbuf[byteorder->byteorder.r] = mp_obj_get_int_truncated(items[PIXEL_R]); + rawbuf[byteorder->byteorder.g] = mp_obj_get_int_truncated(items[PIXEL_G]); + rawbuf[byteorder->byteorder.b] = mp_obj_get_int_truncated(items[PIXEL_B]); + } + if (len > 3) { + if (dotstar) { + buf[byteorder->byteorder.w] = DOTSTAR_LED_START | DOTSTAR_BRIGHTNESS(mp_obj_get_float(items[PIXEL_W])); + if (rawbuf) + rawbuf[byteorder->byteorder.w] = buf[byteorder->byteorder.w]; + } else { + buf[byteorder->byteorder.w] = mp_obj_get_int_truncated(items[PIXEL_W]) * brightness; + if (rawbuf) + rawbuf[byteorder->byteorder.w] = mp_obj_get_int_truncated(items[PIXEL_W]); + } + } else if (dotstar) { + buf[byteorder->byteorder.w] = DOTSTAR_LED_START_FULL_BRIGHT; + if (rawbuf) + rawbuf[byteorder->byteorder.w] = DOTSTAR_LED_START_FULL_BRIGHT; + } + } +} + +mp_obj_t *pixelbuf_get_pixel_array(uint8_t *buf, uint len, pixelbuf_byteorder_obj_t *byteorder, uint8_t step, bool dotstar) { + mp_obj_t elems[len]; + for (uint i = 0; i < len; i++) { + elems[i] = pixelbuf_get_pixel(buf + (i * step), byteorder, dotstar); + } + return mp_obj_new_tuple(len, elems); +} + +mp_obj_t *pixelbuf_get_pixel(uint8_t *buf, pixelbuf_byteorder_obj_t *byteorder, bool dotstar) { + mp_obj_t elems[byteorder->bpp]; + + elems[0] = mp_obj_new_int(buf[byteorder->byteorder.r]); + elems[1] = mp_obj_new_int(buf[byteorder->byteorder.g]); + elems[2] = mp_obj_new_int(buf[byteorder->byteorder.b]); + if (byteorder->bpp > 3) + { + if (dotstar) + elems[3] = mp_obj_new_float(DOTSTAR_GET_BRIGHTNESS(buf[byteorder->byteorder.w])); + else + elems[3] = mp_obj_new_int(buf[byteorder->byteorder.w]); + } + + return mp_obj_new_tuple(byteorder->bpp, elems); +} diff --git a/shared-module/_pixelbuf/PixelBuf.h b/shared-module/_pixelbuf/PixelBuf.h new file mode 100644 index 00000000000..9e115fe0cf0 --- /dev/null +++ b/shared-module/_pixelbuf/PixelBuf.h @@ -0,0 +1,50 @@ +/* + * This file is part of the Circuit Python project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Roy Hooper + * + * 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 "py/obj.h" +#include "py/objarray.h" +#include "../../shared-bindings/_pixelbuf/types.h" + +#ifndef PIXELBUF_SHARED_MODULE_H +#define PIXELBUF_SHARED_MODULE_H + +#define PIXEL_R 0 +#define PIXEL_G 1 +#define PIXEL_B 2 +#define PIXEL_W 3 + +#define DOTSTAR_LED_START 0b11100000 +#define DOTSTAR_BRIGHTNESS(brightness) ((32 - (uint8_t)(32 - brightness * 31)) & 0b00011111) +#define DOTSTAR_GET_BRIGHTNESS(value) ((value & 0b00011111) / 31.0) +#define DOTSTAR_LED_START_FULL_BRIGHT 0xFF + +void pixelbuf_set_pixel(uint8_t *buf, uint8_t *rawbuf, float brightness, mp_obj_t *item, pixelbuf_byteorder_obj_t *byteorder, bool dotstar); +mp_obj_t *pixelbuf_get_pixel(uint8_t *buf, pixelbuf_byteorder_obj_t *byteorder, bool dotstar); +mp_obj_t *pixelbuf_get_pixel_array(uint8_t *buf, uint len, pixelbuf_byteorder_obj_t *byteorder, uint8_t step, bool dotstar); +void pixelbuf_set_pixel_int(uint8_t *buf, mp_int_t value, pixelbuf_byteorder_obj_t *byteorder); + +#endif diff --git a/shared-module/_pixelbuf/__init__.c b/shared-module/_pixelbuf/__init__.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/shared-module/_stage/Layer.c b/shared-module/_stage/Layer.c new file mode 100644 index 00000000000..d958f0d1970 --- /dev/null +++ b/shared-module/_stage/Layer.c @@ -0,0 +1,105 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Radomir Dopieralski + * + * 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 "Layer.h" +#include "__init__.h" + + +// Get the color of the pixel on the layer. +uint16_t get_layer_pixel(layer_obj_t *layer, uint16_t x, uint16_t y) { + + // Shift by the layer's position offset. + x -= layer->x; + y -= layer->y; + + // Bounds check. + if ((x < 0) || (x >= layer->width << 4) || + (y < 0) || (y >= layer->height << 4)) { + return TRANSPARENT; + } + + // Get the tile from the grid location or from sprite frame. + uint8_t frame = layer->frame; + if (layer->map) { + uint8_t tx = x >> 4; + uint8_t ty = y >> 4; + + frame = layer->map[(ty * layer->width + tx) >> 1]; + if (tx & 0x01) { + frame &= 0x0f; + } else { + frame >>= 4; + } + } + + // Get the position within the tile. + x &= 0x0f; + y &= 0x0f; + + // Rotate the image. + uint8_t ty = y; // Temporary variable for swapping. + switch (layer->rotation) { + case 1: // 90 degrees clockwise + y = 15 - x; + x = ty; + break; + case 2: // 180 degrees + y = 15 - ty; + x = 15 - x; + break; + case 3: // 90 degrees counter-clockwise + y = x; + x = 15 - ty; + break; + case 4: // 0 degrees, mirrored + x = 15 - x; + break; + case 5: // 90 degrees clockwise, mirrored + y = x; + x = ty; + break; + case 6: // 180 degrees, mirrored + y = 15 - ty; + break; + case 7: // 90 degrees counter-clockwise, mirrored + y = 15 - x; + x = 15 - ty; + break; + default: // 0 degrees + break; + } + + // Get the value of the pixel. + uint8_t pixel = layer->graphic[(frame << 7) + (y << 3) + (x >> 1)]; + if (x & 0x01) { + pixel &= 0x0f; + } else { + pixel >>= 4; + } + + // Convert to 16-bit color using the palette. + return layer->palette[pixel << 1] | layer->palette[(pixel << 1) + 1] << 8; +} diff --git a/shared-module/_stage/Layer.h b/shared-module/_stage/Layer.h new file mode 100644 index 00000000000..17d101263f7 --- /dev/null +++ b/shared-module/_stage/Layer.h @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Radomir Dopieralski + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE__STAGE_LAYER_H +#define MICROPY_INCLUDED_SHARED_MODULE__STAGE_LAYER_H + +#include +#include + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint8_t *map; + uint8_t *graphic; + uint8_t *palette; + int16_t x, y; + uint8_t width, height; + uint8_t frame; + uint8_t rotation; +} layer_obj_t; + +uint16_t get_layer_pixel(layer_obj_t *layer, uint16_t x, uint16_t y); + +#endif // MICROPY_INCLUDED_SHARED_MODULE__STAGE_LAYER diff --git a/shared-module/_stage/Text.c b/shared-module/_stage/Text.c new file mode 100644 index 00000000000..df5bf80080e --- /dev/null +++ b/shared-module/_stage/Text.c @@ -0,0 +1,67 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Radomir Dopieralski + * + * 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 "Text.h" +#include "__init__.h" + + +// Get the color of the pixel on the text. +uint16_t get_text_pixel(text_obj_t *text, uint16_t x, uint16_t y) { + + // Shift by the text's position offset. + x -= text->x; + y -= text->y; + + // Bounds check. + if ((x < 0) || (x >= text->width << 3) || + (y < 0) || (y >= text->height << 3)) { + return TRANSPARENT; + } + + // Get the tile from the grid location or from sprite frame. + uint8_t tx = x >> 3; + uint8_t ty = y >> 3; + uint8_t c = text->chars[ty * text->width + tx]; + uint8_t color_offset = 0; + if (c & 0x80) { + color_offset = 4; + } + c &= 0x7f; + if (!c) { + return TRANSPARENT; + } + + // Get the position within the char. + x &= 0x07; + y &= 0x07; + + // Get the value of the pixel. + uint8_t pixel = text->font[(c << 4) + (y << 1) + (x >> 2)]; + pixel = ((pixel >> ((x & 0x03) << 1)) & 0x03) + color_offset; + + // Convert to 16-bit color using the palette. + return text->palette[pixel << 1] | text->palette[(pixel << 1) + 1] << 8; +} diff --git a/shared-module/_stage/Text.h b/shared-module/_stage/Text.h new file mode 100644 index 00000000000..b263fc71084 --- /dev/null +++ b/shared-module/_stage/Text.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Radomir Dopieralski + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE__STAGE_TEXT_H +#define MICROPY_INCLUDED_SHARED_MODULE__STAGE_TEXT_H + +#include +#include + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint8_t *chars; + uint8_t *font; + uint8_t *palette; + int16_t x, y; + uint8_t width, height; +} text_obj_t; + +uint16_t get_text_pixel(text_obj_t *text, uint16_t x, uint16_t y); + +#endif // MICROPY_INCLUDED_SHARED_MODULE__STAGE_TEXT diff --git a/shared-module/_stage/__init__.c b/shared-module/_stage/__init__.c new file mode 100644 index 00000000000..2c525be87e4 --- /dev/null +++ b/shared-module/_stage/__init__.c @@ -0,0 +1,72 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Radomir Dopieralski + * + * 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 "Layer.h" +#include "Text.h" +#include "__init__.h" +#include "shared-bindings/_stage/Layer.h" +#include "shared-bindings/_stage/Text.h" + + +void render_stage(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, + mp_obj_t *layers, size_t layers_size, + uint16_t *buffer, size_t buffer_size, + displayio_display_obj_t *display, uint8_t scale) { + + size_t index = 0; + for (uint16_t y = y0; y < y1; ++y) { + for (uint8_t yscale = 0; yscale < scale; ++yscale) { + for (uint16_t x = x0; x < x1; ++x) { + uint16_t c = TRANSPARENT; + for (size_t layer = 0; layer < layers_size; ++layer) { + layer_obj_t *obj = MP_OBJ_TO_PTR(layers[layer]); + if (obj->base.type == &mp_type_layer) { + c = get_layer_pixel(obj, x, y); + } else if (obj->base.type == &mp_type_text) { + c = get_text_pixel((text_obj_t *)obj, x, y); + } + if (c != TRANSPARENT) { + break; + } + } + for (uint8_t xscale = 0; xscale < scale; ++xscale) { + buffer[index] = c; + index += 1; + // The buffer is full, send it. + if (index >= buffer_size) { + display->core.send(display->core.bus, DISPLAY_DATA, CHIP_SELECT_UNTOUCHED, ((uint8_t*)buffer), + buffer_size * 2); + index = 0; + } + } + } + } + } + // Send the remaining data. + if (index) { + display->core.send(display->core.bus, DISPLAY_DATA, CHIP_SELECT_UNTOUCHED, ((uint8_t*)buffer), index * 2); + } +} diff --git a/shared-module/_stage/__init__.h b/shared-module/_stage/__init__.h new file mode 100644 index 00000000000..5af2124aeb0 --- /dev/null +++ b/shared-module/_stage/__init__.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Radomir Dopieralski + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE__STAGE_H +#define MICROPY_INCLUDED_SHARED_MODULE__STAGE_H + +#include "shared-bindings/displayio/Display.h" +#include +#include +#include "py/obj.h" + +#define TRANSPARENT (0x1ff8) + +void render_stage(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, + mp_obj_t *layers, size_t layers_size, + uint16_t *buffer, size_t buffer_size, + displayio_display_obj_t *display, uint8_t scale); + +#endif // MICROPY_INCLUDED_SHARED_MODULE__STAGE diff --git a/shared-module/audiocore/Mixer.c b/shared-module/audiocore/Mixer.c new file mode 100644 index 00000000000..da66bb36ec7 --- /dev/null +++ b/shared-module/audiocore/Mixer.c @@ -0,0 +1,341 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/audiocore/Mixer.h" + +#include + +#include "py/runtime.h" +#include "shared-module/audiocore/__init__.h" +#include "shared-module/audiocore/RawSample.h" + +void common_hal_audioio_mixer_construct(audioio_mixer_obj_t* self, + uint8_t voice_count, + uint32_t buffer_size, + uint8_t bits_per_sample, + bool samples_signed, + uint8_t channel_count, + uint32_t sample_rate) { + self->len = buffer_size / 2 / sizeof(uint32_t) * sizeof(uint32_t); + + self->first_buffer = m_malloc(self->len, false); + if (self->first_buffer == NULL) { + common_hal_audioio_mixer_deinit(self); + mp_raise_msg(&mp_type_MemoryError, translate("Couldn't allocate first buffer")); + } + + self->second_buffer = m_malloc(self->len, false); + if (self->second_buffer == NULL) { + common_hal_audioio_mixer_deinit(self); + mp_raise_msg(&mp_type_MemoryError, translate("Couldn't allocate second buffer")); + } + + self->bits_per_sample = bits_per_sample; + self->samples_signed = samples_signed; + self->channel_count = channel_count; + self->sample_rate = sample_rate; + self->voice_count = voice_count; + + for (uint8_t i = 0; i < self->voice_count; i++) { + self->voice[i].sample = NULL; + } +} + +void common_hal_audioio_mixer_deinit(audioio_mixer_obj_t* self) { + self->first_buffer = NULL; + self->second_buffer = NULL; +} + +bool common_hal_audioio_mixer_deinited(audioio_mixer_obj_t* self) { + return self->first_buffer == NULL; +} + +uint32_t common_hal_audioio_mixer_get_sample_rate(audioio_mixer_obj_t* self) { + return self->sample_rate; +} + +void common_hal_audioio_mixer_play(audioio_mixer_obj_t* self, mp_obj_t sample, uint8_t v, bool loop) { + if (v >= self->voice_count) { + mp_raise_ValueError(translate("Voice index too high")); + } + if (audiosample_sample_rate(sample) != self->sample_rate) { + mp_raise_ValueError(translate("The sample's sample rate does not match the mixer's")); + } + if (audiosample_channel_count(sample) != self->channel_count) { + mp_raise_ValueError(translate("The sample's channel count does not match the mixer's")); + } + if (audiosample_bits_per_sample(sample) != self->bits_per_sample) { + mp_raise_ValueError(translate("The sample's bits_per_sample does not match the mixer's")); + } + bool single_buffer; + bool samples_signed; + uint32_t max_buffer_length; + uint8_t spacing; + audiosample_get_buffer_structure(sample, false, &single_buffer, &samples_signed, + &max_buffer_length, &spacing); + if (samples_signed != self->samples_signed) { + mp_raise_ValueError(translate("The sample's signedness does not match the mixer's")); + } + audioio_mixer_voice_t* voice = &self->voice[v]; + voice->sample = sample; + voice->loop = loop; + + audiosample_reset_buffer(sample, false, 0); + audioio_get_buffer_result_t result = audiosample_get_buffer(sample, false, 0, (uint8_t**) &voice->remaining_buffer, &voice->buffer_length); + // Track length in terms of words. + voice->buffer_length /= sizeof(uint32_t); + voice->more_data = result == GET_BUFFER_MORE_DATA; +} + +void common_hal_audioio_mixer_stop_voice(audioio_mixer_obj_t* self, uint8_t voice) { + self->voice[voice].sample = NULL; +} + +bool common_hal_audioio_mixer_get_playing(audioio_mixer_obj_t* self) { + for (int32_t v = 0; v < self->voice_count; v++) { + if (self->voice[v].sample != NULL) { + return true; + } + } + return false; +} + +void audioio_mixer_reset_buffer(audioio_mixer_obj_t* self, + bool single_channel, + uint8_t channel) { + for (int32_t i = 0; i < self->voice_count; i++) { + self->voice[i].sample = NULL; + } +} + +uint32_t add8signed(uint32_t a, uint32_t b) { + #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + return __QADD8(a, b); + #else + uint32_t result = 0; + for (int8_t i = 0; i < 4; i++) { + int8_t ai = a >> (sizeof(int8_t) * 8 * i); + int8_t bi = b >> (sizeof(int8_t) * 8 * i); + int32_t intermediate = (int32_t) ai + bi; + if (intermediate > CHAR_MAX) { + intermediate = CHAR_MAX; + } else if (intermediate < CHAR_MIN) { + //intermediate = CHAR_MIN; + } + result |= (((uint32_t) intermediate) & 0xff) << (sizeof(int8_t) * 8 * i); + } + return result; + #endif +} + +uint32_t add8unsigned(uint32_t a, uint32_t b) { + #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + // Subtract out the DC offset, add and then shift back. + a = __USUB8(a, 0x80808080); + b = __USUB8(b, 0x80808080); + uint32_t sum = __QADD8(a, b); + return __UADD8(sum, 0x80808080); + #else + uint32_t result = 0; + for (int8_t i = 0; i < 4; i++) { + int8_t ai = (a >> (sizeof(uint8_t) * 8 * i)) - 128; + int8_t bi = (b >> (sizeof(uint8_t) * 8 * i)) - 128; + int32_t intermediate = (int32_t) ai + bi; + if (intermediate > UCHAR_MAX) { + intermediate = UCHAR_MAX; + } + result |= ((uint8_t) intermediate + 128) << (sizeof(uint8_t) * 8 * i); + } + return result; + #endif +} + +uint32_t add16signed(uint32_t a, uint32_t b) { + #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + return __QADD16(a, b); + #else + uint32_t result = 0; + for (int8_t i = 0; i < 2; i++) { + int16_t ai = a >> (sizeof(int16_t) * 8 * i); + int16_t bi = b >> (sizeof(int16_t) * 8 * i); + int32_t intermediate = (int32_t) ai + bi; + if (intermediate > SHRT_MAX) { + intermediate = SHRT_MAX; + } else if (intermediate < SHRT_MIN) { + intermediate = SHRT_MIN; + } + result |= (((uint32_t) intermediate) & 0xffff) << (sizeof(int16_t) * 8 * i); + } + return result; + #endif +} + +uint32_t add16unsigned(uint32_t a, uint32_t b) { + #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + // Subtract out the DC offset, add and then shift back. + a = __USUB16(a, 0x80008000); + b = __USUB16(b, 0x80008000); + uint32_t sum = __QADD16(a, b); + return __UADD16(sum, 0x80008000); + #else + uint32_t result = 0; + for (int8_t i = 0; i < 2; i++) { + int16_t ai = (a >> (sizeof(uint16_t) * 8 * i)) - 0x8000; + int16_t bi = (b >> (sizeof(uint16_t) * 8 * i)) - 0x8000; + int32_t intermediate = (int32_t) ai + bi; + if (intermediate > USHRT_MAX) { + intermediate = USHRT_MAX; + } + result |= ((uint16_t) intermediate + 0x8000) << (sizeof(int16_t) * 8 * i); + } + return result; + #endif +} + +audioio_get_buffer_result_t audioio_mixer_get_buffer(audioio_mixer_obj_t* self, + bool single_channel, + uint8_t channel, + uint8_t** buffer, + uint32_t* buffer_length) { + if (!single_channel) { + channel = 0; + } + + uint32_t channel_read_count = self->left_read_count; + if (channel == 1) { + channel_read_count = self->right_read_count; + } + *buffer_length = self->len; + + bool need_more_data = self->read_count == channel_read_count; + if (need_more_data) { + uint32_t* word_buffer; + if (self->use_first_buffer) { + *buffer = (uint8_t*) self->first_buffer; + word_buffer = self->first_buffer; + } else { + *buffer = (uint8_t*) self->second_buffer; + word_buffer = self->second_buffer; + } + self->use_first_buffer = !self->use_first_buffer; + bool voices_active = false; + for (int32_t v = 0; v < self->voice_count; v++) { + audioio_mixer_voice_t* voice = &self->voice[v]; + + uint32_t j = 0; + bool voice_done = voice->sample == NULL; + for (uint32_t i = 0; i < self->len / sizeof(uint32_t); i++) { + if (!voice_done && j >= voice->buffer_length) { + if (!voice->more_data) { + if (voice->loop) { + audiosample_reset_buffer(voice->sample, false, 0); + } else { + voice->sample = NULL; + voice_done = true; + } + } + if (!voice_done) { + // Load another buffer + audioio_get_buffer_result_t result = audiosample_get_buffer(voice->sample, false, 0, (uint8_t**) &voice->remaining_buffer, &voice->buffer_length); + // Track length in terms of words. + voice->buffer_length /= sizeof(uint32_t); + voice->more_data = result == GET_BUFFER_MORE_DATA; + j = 0; + } + } + // First active voice gets copied over verbatim. + uint32_t sample_value; + if (voice_done) { + // Exit early if another voice already set all samples once. + if (voices_active) { + continue; + } + sample_value = 0; + if (!self->samples_signed) { + if (self->bits_per_sample == 8) { + sample_value = 0x7f7f7f7f; + } else { + sample_value = 0x7fff7fff; + } + } + } else { + sample_value = voice->remaining_buffer[j]; + } + + if (!voices_active) { + word_buffer[i] = sample_value; + } else { + if (self->bits_per_sample == 8) { + if (self->samples_signed) { + word_buffer[i] = add8signed(word_buffer[i], sample_value); + } else { + word_buffer[i] = add8unsigned(word_buffer[i], sample_value); + } + } else { + if (self->samples_signed) { + word_buffer[i] = add16signed(word_buffer[i], sample_value); + } else { + word_buffer[i] = add16unsigned(word_buffer[i], sample_value); + } + } + } + j++; + } + voice->buffer_length -= j; + voice->remaining_buffer += j; + + voices_active = true; + } + + self->read_count += 1; + } else if (!self->use_first_buffer) { + *buffer = (uint8_t*) self->first_buffer; + } else { + *buffer = (uint8_t*) self->second_buffer; + } + + + if (channel == 0) { + self->left_read_count += 1; + } else if (channel == 1) { + self->right_read_count += 1; + *buffer = *buffer + self->bits_per_sample / 8; + } + return GET_BUFFER_MORE_DATA; +} + +void audioio_mixer_get_buffer_structure(audioio_mixer_obj_t* self, bool single_channel, + bool* single_buffer, bool* samples_signed, + uint32_t* max_buffer_length, uint8_t* spacing) { + *single_buffer = false; + *samples_signed = self->samples_signed; + *max_buffer_length = self->len; + if (single_channel) { + *spacing = self->channel_count; + } else { + *spacing = 1; + } +} diff --git a/shared-module/audiocore/Mixer.h b/shared-module/audiocore/Mixer.h new file mode 100644 index 00000000000..22eb6a37fa1 --- /dev/null +++ b/shared-module/audiocore/Mixer.h @@ -0,0 +1,75 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_MIXER_H +#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_MIXER_H + +#include "py/obj.h" + +#include "shared-module/audiocore/__init__.h" + +typedef struct { + mp_obj_t sample; + bool loop; + bool more_data; + uint32_t* remaining_buffer; + uint32_t buffer_length; +} audioio_mixer_voice_t; + +typedef struct { + mp_obj_base_t base; + uint32_t* first_buffer; + uint32_t* second_buffer; + uint32_t len; // in words + uint8_t bits_per_sample; + bool use_first_buffer; + bool samples_signed; + uint8_t channel_count; + uint32_t sample_rate; + + uint32_t read_count; + uint32_t left_read_count; + uint32_t right_read_count; + + uint8_t voice_count; + audioio_mixer_voice_t voice[]; +} audioio_mixer_obj_t; + + +// These are not available from Python because it may be called in an interrupt. +void audioio_mixer_reset_buffer(audioio_mixer_obj_t* self, + bool single_channel, + uint8_t channel); +audioio_get_buffer_result_t audioio_mixer_get_buffer(audioio_mixer_obj_t* self, + bool single_channel, + uint8_t channel, + uint8_t** buffer, + uint32_t* buffer_length); // length in bytes +void audioio_mixer_get_buffer_structure(audioio_mixer_obj_t* self, bool single_channel, + bool* single_buffer, bool* samples_signed, + uint32_t* max_buffer_length, uint8_t* spacing); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_MIXER_H diff --git a/shared-module/audiocore/RawSample.c b/shared-module/audiocore/RawSample.c new file mode 100644 index 00000000000..d6bf3a567a9 --- /dev/null +++ b/shared-module/audiocore/RawSample.c @@ -0,0 +1,94 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/audiocore/RawSample.h" + +#include + +#include "shared-module/audiocore/RawSample.h" + +void common_hal_audioio_rawsample_construct(audioio_rawsample_obj_t* self, + uint8_t* buffer, + uint32_t len, + uint8_t bytes_per_sample, + bool samples_signed, + uint8_t channel_count, + uint32_t sample_rate) { + self->buffer = buffer; + self->bits_per_sample = bytes_per_sample * 8; + self->samples_signed = samples_signed; + self->len = len; + self->channel_count = channel_count; + self->sample_rate = sample_rate; + self->buffer_read = false; +} + +void common_hal_audioio_rawsample_deinit(audioio_rawsample_obj_t* self) { + self->buffer = NULL; +} +bool common_hal_audioio_rawsample_deinited(audioio_rawsample_obj_t* self) { + return self->buffer == NULL; +} + +uint32_t common_hal_audioio_rawsample_get_sample_rate(audioio_rawsample_obj_t* self) { + return self->sample_rate; +} +void common_hal_audioio_rawsample_set_sample_rate(audioio_rawsample_obj_t* self, + uint32_t sample_rate) { + self->sample_rate = sample_rate; +} + +void audioio_rawsample_reset_buffer(audioio_rawsample_obj_t* self, + bool single_channel, + uint8_t channel) { +} + +audioio_get_buffer_result_t audioio_rawsample_get_buffer(audioio_rawsample_obj_t* self, + bool single_channel, + uint8_t channel, + uint8_t** buffer, + uint32_t* buffer_length) { + *buffer_length = self->len; + if (single_channel) { + *buffer = self->buffer + (channel % self->channel_count) * (self->bits_per_sample / 8); + } else { + *buffer = self->buffer; + } + return GET_BUFFER_DONE; +} + +void audioio_rawsample_get_buffer_structure(audioio_rawsample_obj_t* self, bool single_channel, + bool* single_buffer, bool* samples_signed, + uint32_t* max_buffer_length, uint8_t* spacing) { + *single_buffer = true; + *samples_signed = self->samples_signed; + *max_buffer_length = self->len; + if (single_channel) { + *spacing = self->channel_count; + } else { + *spacing = 1; + } +} diff --git a/shared-module/audiocore/RawSample.h b/shared-module/audiocore/RawSample.h new file mode 100644 index 00000000000..6c2c19c9bfc --- /dev/null +++ b/shared-module/audiocore/RawSample.h @@ -0,0 +1,59 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_RAWSAMPLE_H +#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_RAWSAMPLE_H + +#include "py/obj.h" + +#include "shared-module/audiocore/__init__.h" + +typedef struct { + mp_obj_base_t base; + uint8_t* buffer; + uint32_t len; + uint8_t bits_per_sample; + bool samples_signed; + uint8_t channel_count; + uint32_t sample_rate; + bool buffer_read; +} audioio_rawsample_obj_t; + + +// These are not available from Python because it may be called in an interrupt. +void audioio_rawsample_reset_buffer(audioio_rawsample_obj_t* self, + bool single_channel, + uint8_t channel); +audioio_get_buffer_result_t audioio_rawsample_get_buffer(audioio_rawsample_obj_t* self, + bool single_channel, + uint8_t channel, + uint8_t** buffer, + uint32_t* buffer_length); // length in bytes +void audioio_rawsample_get_buffer_structure(audioio_rawsample_obj_t* self, bool single_channel, + bool* single_buffer, bool* samples_signed, + uint32_t* max_buffer_length, uint8_t* spacing); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_RAWSAMPLE_H diff --git a/shared-module/audiocore/WaveFile.c b/shared-module/audiocore/WaveFile.c new file mode 100644 index 00000000000..df5d4b61de4 --- /dev/null +++ b/shared-module/audiocore/WaveFile.c @@ -0,0 +1,279 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/audiocore/WaveFile.h" + +#include +#include + +#include "py/mperrno.h" +#include "py/runtime.h" + +#include "shared-module/audiocore/WaveFile.h" +#include "supervisor/shared/translate.h" + +struct wave_format_chunk { + uint16_t audio_format; + uint16_t num_channels; + uint32_t sample_rate; + uint32_t byte_rate; + uint16_t block_align; + uint16_t bits_per_sample; + uint16_t extra_params; // Assumed to be zero below. +}; + +void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t* self, + pyb_file_obj_t* file, + uint8_t *buffer, + size_t buffer_size) { + // Load the wave + self->file = file; + uint8_t chunk_header[16]; + f_rewind(&self->file->fp); + UINT bytes_read; + if (f_read(&self->file->fp, chunk_header, 16, &bytes_read) != FR_OK) { + mp_raise_OSError(MP_EIO); + } + if (bytes_read != 16 || + memcmp(chunk_header, "RIFF", 4) != 0 || + memcmp(chunk_header + 8, "WAVEfmt ", 8) != 0) { + mp_raise_ValueError(translate("Invalid wave file")); + } + uint32_t format_size; + if (f_read(&self->file->fp, &format_size, 4, &bytes_read) != FR_OK) { + mp_raise_OSError(MP_EIO); + } + if (bytes_read != 4 || + format_size > sizeof(struct wave_format_chunk)) { + mp_raise_ValueError(translate("Invalid format chunk size")); + } + struct wave_format_chunk format; + if (f_read(&self->file->fp, &format, format_size, &bytes_read) != FR_OK) { + mp_raise_OSError(MP_EIO); + } + if (bytes_read != format_size) { + } + + if (format.audio_format != 1 || + format.num_channels > 2 || + format.bits_per_sample > 16 || + (format_size == 18 && + format.extra_params != 0)) { + mp_raise_ValueError(translate("Unsupported format")); + } + // Get the sample_rate + self->sample_rate = format.sample_rate; + self->channel_count = format.num_channels; + self->bits_per_sample = format.bits_per_sample; + + // TODO(tannewt): Skip any extra chunks that occur before the data section. + + uint8_t data_tag[4]; + if (f_read(&self->file->fp, &data_tag, 4, &bytes_read) != FR_OK) { + mp_raise_OSError(MP_EIO); + } + if (bytes_read != 4 || + memcmp((uint8_t *) data_tag, "data", 4) != 0) { + mp_raise_ValueError(translate("Data chunk must follow fmt chunk")); + } + + uint32_t data_length; + if (f_read(&self->file->fp, &data_length, 4, &bytes_read) != FR_OK) { + mp_raise_OSError(MP_EIO); + } + if (bytes_read != 4) { + mp_raise_ValueError(translate("Invalid file")); + } + self->file_length = data_length; + self->data_start = self->file->fp.fptr; + + // Try to allocate two buffers, one will be loaded from file and the other + // DMAed to DAC. + if (buffer_size) { + self->len = buffer_size / 2; + self->buffer = buffer; + self->second_buffer = buffer + self->len; + } else { + self->len = 256; + self->buffer = m_malloc(self->len, false); + if (self->buffer == NULL) { + common_hal_audioio_wavefile_deinit(self); + mp_raise_msg(&mp_type_MemoryError, + translate("Couldn't allocate first buffer")); + } + + self->second_buffer = m_malloc(self->len, false); + if (self->second_buffer == NULL) { + common_hal_audioio_wavefile_deinit(self); + mp_raise_msg(&mp_type_MemoryError, + translate("Couldn't allocate second buffer")); + } + } +} + +void common_hal_audioio_wavefile_deinit(audioio_wavefile_obj_t* self) { + self->buffer = NULL; + self->second_buffer = NULL; +} + +bool common_hal_audioio_wavefile_deinited(audioio_wavefile_obj_t* self) { + return self->buffer == NULL; +} + +uint32_t common_hal_audioio_wavefile_get_sample_rate(audioio_wavefile_obj_t* self) { + return self->sample_rate; +} + +void common_hal_audioio_wavefile_set_sample_rate(audioio_wavefile_obj_t* self, + uint32_t sample_rate) { + self->sample_rate = sample_rate; +} + +uint8_t common_hal_audioio_wavefile_get_bits_per_sample(audioio_wavefile_obj_t* self) { + return self->bits_per_sample; +} + +uint8_t common_hal_audioio_wavefile_get_channel_count(audioio_wavefile_obj_t* self) { + return self->channel_count; +} + +bool audioio_wavefile_samples_signed(audioio_wavefile_obj_t* self) { + return self->bits_per_sample > 8; +} + +uint32_t audioio_wavefile_max_buffer_length(audioio_wavefile_obj_t* self) { + return 512; +} + +void audioio_wavefile_reset_buffer(audioio_wavefile_obj_t* self, + bool single_channel, + uint8_t channel) { + if (single_channel && channel == 1) { + return; + } + // We don't reset the buffer index in case we're looping and we have an odd number of buffer + // loads + self->bytes_remaining = self->file_length; + f_lseek(&self->file->fp, self->data_start); + self->read_count = 0; + self->left_read_count = 0; + self->right_read_count = 0; +} + +audioio_get_buffer_result_t audioio_wavefile_get_buffer(audioio_wavefile_obj_t* self, + bool single_channel, + uint8_t channel, + uint8_t** buffer, + uint32_t* buffer_length) { + if (!single_channel) { + channel = 0; + } + + uint32_t channel_read_count = self->left_read_count; + if (channel == 1) { + channel_read_count = self->right_read_count; + } + + bool need_more_data = self->read_count == channel_read_count; + + if (self->bytes_remaining == 0 && need_more_data) { + *buffer = NULL; + *buffer_length = 0; + return GET_BUFFER_DONE; + } + + if (need_more_data) { + uint16_t num_bytes_to_load = self->len; + if (num_bytes_to_load > self->bytes_remaining) { + num_bytes_to_load = self->bytes_remaining; + } + UINT length_read; + if (self->buffer_index % 2 == 1) { + *buffer = self->second_buffer; + } else { + *buffer = self->buffer; + } + if (f_read(&self->file->fp, *buffer, num_bytes_to_load, &length_read) != FR_OK) { + return GET_BUFFER_ERROR; + } + self->bytes_remaining -= length_read; + // Pad the last buffer to word align it. + if (self->bytes_remaining == 0 && length_read % sizeof(uint32_t) != 0) { + uint32_t pad = length_read % sizeof(uint32_t); + length_read += pad; + if (self->bits_per_sample == 8) { + for (uint32_t i = 0; i < pad; i++) { + ((uint8_t*) (*buffer))[length_read / sizeof(uint8_t) - i - 1] = 0x80; + } + } else if (self->bits_per_sample == 16) { + // We know the buffer is aligned because we allocated it onto the heap ourselves. + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" + ((int16_t*) (*buffer))[length_read / sizeof(int16_t) - 1] = 0; + #pragma GCC diagnostic pop + } + } + *buffer_length = length_read; + if (self->buffer_index % 2 == 1) { + self->second_buffer_length = length_read; + } else { + self->buffer_length = length_read; + } + self->buffer_index += 1; + self->read_count += 1; + } + + uint32_t buffers_back = self->read_count - 1 - channel_read_count; + if ((self->buffer_index - buffers_back) % 2 == 0) { + *buffer = self->second_buffer; + *buffer_length = self->second_buffer_length; + } else { + *buffer = self->buffer; + *buffer_length = self->buffer_length; + } + + if (channel == 0) { + self->left_read_count += 1; + } else if (channel == 1) { + self->right_read_count += 1; + *buffer = *buffer + self->bits_per_sample / 8; + } + + return self->bytes_remaining == 0 ? GET_BUFFER_DONE : GET_BUFFER_MORE_DATA; +} + +void audioio_wavefile_get_buffer_structure(audioio_wavefile_obj_t* self, bool single_channel, + bool* single_buffer, bool* samples_signed, + uint32_t* max_buffer_length, uint8_t* spacing) { + *single_buffer = false; + *samples_signed = self->bits_per_sample > 8; + *max_buffer_length = 512; + if (single_channel) { + *spacing = self->channel_count; + } else { + *spacing = 1; + } +} diff --git a/shared-module/audiocore/WaveFile.h b/shared-module/audiocore/WaveFile.h new file mode 100644 index 00000000000..3eecbf15ce3 --- /dev/null +++ b/shared-module/audiocore/WaveFile.h @@ -0,0 +1,71 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_WAVEFILE_H +#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_WAVEFILE_H + +#include "extmod/vfs_fat.h" +#include "py/obj.h" + +#include "shared-module/audiocore/__init__.h" + +typedef struct { + mp_obj_base_t base; + uint8_t* buffer; + uint32_t buffer_length; + uint8_t* second_buffer; + uint32_t second_buffer_length; + uint32_t file_length; // In bytes + uint16_t data_start; // Where the data values start + uint8_t bits_per_sample; + uint16_t buffer_index; + uint32_t bytes_remaining; + + uint8_t channel_count; + uint32_t sample_rate; + + uint32_t len; + pyb_file_obj_t* file; + + uint32_t read_count; + uint32_t left_read_count; + uint32_t right_read_count; +} audioio_wavefile_obj_t; + +// These are not available from Python because it may be called in an interrupt. +void audioio_wavefile_reset_buffer(audioio_wavefile_obj_t* self, + bool single_channel, + uint8_t channel); +audioio_get_buffer_result_t audioio_wavefile_get_buffer(audioio_wavefile_obj_t* self, + bool single_channel, + uint8_t channel, + uint8_t** buffer, + uint32_t* buffer_length); // length in bytes +void audioio_wavefile_get_buffer_structure(audioio_wavefile_obj_t* self, bool single_channel, + bool* single_buffer, bool* samples_signed, + uint32_t* max_buffer_length, uint8_t* spacing); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_WAVEFILE_H diff --git a/shared-module/audiocore/__init__.c b/shared-module/audiocore/__init__.c new file mode 100644 index 00000000000..067cae5ddbc --- /dev/null +++ b/shared-module/audiocore/__init__.c @@ -0,0 +1,125 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-module/audioio/__init__.h" + +#include "py/obj.h" +#include "shared-bindings/audiocore/Mixer.h" +#include "shared-bindings/audiocore/RawSample.h" +#include "shared-bindings/audiocore/WaveFile.h" +#include "shared-module/audiocore/Mixer.h" +#include "shared-module/audiocore/RawSample.h" +#include "shared-module/audiocore/WaveFile.h" + +uint32_t audiosample_sample_rate(mp_obj_t sample_obj) { + if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { + audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); + return sample->sample_rate; + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { + audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + return file->sample_rate; + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { + audioio_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj); + return mixer->sample_rate; + } + return 16000; +} + +uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj) { + if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { + audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); + return sample->bits_per_sample; + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { + audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + return file->bits_per_sample; + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { + audioio_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj); + return mixer->bits_per_sample; + } + return 8; +} + +uint8_t audiosample_channel_count(mp_obj_t sample_obj) { + if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { + audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); + return sample->channel_count; + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { + audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + return file->channel_count; + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { + audioio_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj); + return mixer->channel_count; + } + return 1; +} + +void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel, uint8_t audio_channel) { + if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { + audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); + audioio_rawsample_reset_buffer(sample, single_channel, audio_channel); + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { + audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + audioio_wavefile_reset_buffer(file, single_channel, audio_channel); + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { + audioio_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + audioio_mixer_reset_buffer(file, single_channel, audio_channel); + } +} + +audioio_get_buffer_result_t audiosample_get_buffer(mp_obj_t sample_obj, + bool single_channel, + uint8_t channel, + uint8_t** buffer, uint32_t* buffer_length) { + if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { + audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); + return audioio_rawsample_get_buffer(sample, single_channel, channel, buffer, buffer_length); + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { + audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + return audioio_wavefile_get_buffer(file, single_channel, channel, buffer, buffer_length); + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { + audioio_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + return audioio_mixer_get_buffer(file, single_channel, channel, buffer, buffer_length); + } + return GET_BUFFER_DONE; +} + +void audiosample_get_buffer_structure(mp_obj_t sample_obj, bool single_channel, + bool* single_buffer, bool* samples_signed, + uint32_t* max_buffer_length, uint8_t* spacing) { + if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { + audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); + audioio_rawsample_get_buffer_structure(sample, single_channel, single_buffer, + samples_signed, max_buffer_length, spacing); + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { + audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + audioio_wavefile_get_buffer_structure(file, single_channel, single_buffer, samples_signed, + max_buffer_length, spacing); + } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { + audioio_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + audioio_mixer_get_buffer_structure(file, single_channel, single_buffer, samples_signed, + max_buffer_length, spacing); + } +} diff --git a/shared-module/audiocore/__init__.h b/shared-module/audiocore/__init__.h new file mode 100644 index 00000000000..7aa0c1824aa --- /dev/null +++ b/shared-module/audiocore/__init__.h @@ -0,0 +1,53 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOCORE__INIT__H +#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOCORE__INIT__H + +#include +#include + +#include "py/obj.h" + +typedef enum { + GET_BUFFER_DONE, // No more data to read + GET_BUFFER_MORE_DATA, // More data to read. + GET_BUFFER_ERROR, // Error while reading data. +} audioio_get_buffer_result_t; + +uint32_t audiosample_sample_rate(mp_obj_t sample_obj); +uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj); +uint8_t audiosample_channel_count(mp_obj_t sample_obj); +void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel, uint8_t audio_channel); +audioio_get_buffer_result_t audiosample_get_buffer(mp_obj_t sample_obj, + bool single_channel, + uint8_t channel, + uint8_t** buffer, uint32_t* buffer_length); +void audiosample_get_buffer_structure(mp_obj_t sample_obj, bool single_channel, + bool* single_buffer, bool* samples_signed, + uint32_t* max_buffer_length, uint8_t* spacing); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOCORE__INIT__H diff --git a/shared-module/audioio/__init__.c b/shared-module/audioio/__init__.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/shared-module/audioio/__init__.h b/shared-module/audioio/__init__.h new file mode 100644 index 00000000000..53b2d4a161b --- /dev/null +++ b/shared-module/audioio/__init__.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO__INIT__H +#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO__INIT__H + +#include "shared-module/audiocore/__init__.h" + +#endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO__INIT__H diff --git a/shared-module/audiopwmio/__init__.c b/shared-module/audiopwmio/__init__.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/shared-module/audiopwmio/__init__.h b/shared-module/audiopwmio/__init__.h new file mode 100644 index 00000000000..964e4aafe2b --- /dev/null +++ b/shared-module/audiopwmio/__init__.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOPWMIO__INIT__H +#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOPWMIO__INIT__H + +#include "shared-module/audiocore/__init__.h" + +#endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOPWMIO__INIT__H diff --git a/shared-module/bitbangio/I2C.c b/shared-module/bitbangio/I2C.c new file mode 100644 index 00000000000..5a9ac9a9917 --- /dev/null +++ b/shared-module/bitbangio/I2C.c @@ -0,0 +1,255 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George, Scott Shawcroft + * + * 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 "shared-bindings/bitbangio/I2C.h" +#include "py/mperrno.h" +#include "py/obj.h" +#include "py/runtime.h" + +#include "common-hal/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-module/bitbangio/types.h" +#include "supervisor/shared/translate.h" + +STATIC void delay(bitbangio_i2c_obj_t *self) { + // We need to use an accurate delay to get acceptable I2C + // speeds (eg 1us should be not much more than 1us). + common_hal_mcu_delay_us(self->us_delay); +} + +STATIC void scl_low(bitbangio_i2c_obj_t *self) { + common_hal_digitalio_digitalinout_set_value(&self->scl, false); +} + +STATIC void scl_release(bitbangio_i2c_obj_t *self) { + common_hal_digitalio_digitalinout_set_value(&self->scl, true); + uint32_t count = self->us_timeout; + delay(self); + // For clock stretching, wait for the SCL pin to be released, with timeout. + for (; !common_hal_digitalio_digitalinout_get_value(&self->scl) && count; --count) { + common_hal_mcu_delay_us(1); + } + // raise exception on timeout + if (count == 0) { + mp_raise_msg(&mp_type_TimeoutError, translate("Clock stretch too long")); + } +} + +STATIC void sda_low(bitbangio_i2c_obj_t *self) { + common_hal_digitalio_digitalinout_set_value(&self->sda, false); +} + +STATIC void sda_release(bitbangio_i2c_obj_t *self) { + common_hal_digitalio_digitalinout_set_value(&self->sda, true); +} + +STATIC bool sda_read(bitbangio_i2c_obj_t *self) { + common_hal_digitalio_digitalinout_switch_to_input(&self->sda, PULL_UP); + bool value = common_hal_digitalio_digitalinout_get_value(&self->sda); + common_hal_digitalio_digitalinout_switch_to_output(&self->sda, true, DRIVE_MODE_OPEN_DRAIN); + return value; +} + +STATIC void start(bitbangio_i2c_obj_t *self) { + sda_release(self); + delay(self); + scl_release(self); + sda_low(self); + delay(self); +} + +STATIC void stop(bitbangio_i2c_obj_t *self) { + delay(self); + sda_low(self); + delay(self); + scl_release(self); + sda_release(self); + delay(self); +} + +STATIC int write_byte(bitbangio_i2c_obj_t *self, uint8_t val) { + delay(self); + scl_low(self); + + for (int i = 7; i >= 0; i--) { + if ((val >> i) & 1) { + sda_release(self); + } else { + sda_low(self); + } + delay(self); + scl_release(self); + scl_low(self); + } + + sda_release(self); + delay(self); + scl_release(self); + + int ret = sda_read(self); + delay(self); + scl_low(self); + + return !ret; +} + +STATIC bool read_byte(bitbangio_i2c_obj_t *self, uint8_t *val, bool ack) { + delay(self); + scl_low(self); + delay(self); + + uint8_t data = 0; + for (int i = 7; i >= 0; i--) { + scl_release(self); + data = (data << 1) | sda_read(self); + scl_low(self); + delay(self); + } + *val = data; + + // send ack/nack bit + if (ack) { + sda_low(self); + } + delay(self); + scl_release(self); + scl_low(self); + sda_release(self); + + return true; +} + +void shared_module_bitbangio_i2c_construct(bitbangio_i2c_obj_t *self, + const mcu_pin_obj_t * scl, + const mcu_pin_obj_t * sda, + uint32_t frequency, + uint32_t us_timeout) { + + self->us_timeout = us_timeout; + self->us_delay = 500000 / frequency; + if (self->us_delay == 0) { + self->us_delay = 1; + } + digitalinout_result_t result = common_hal_digitalio_digitalinout_construct(&self->scl, scl); + if (result != DIGITALINOUT_OK) { + return; + } + result = common_hal_digitalio_digitalinout_construct(&self->sda, sda); + if (result != DIGITALINOUT_OK) { + common_hal_digitalio_digitalinout_deinit(&self->scl); + return; + } + common_hal_digitalio_digitalinout_switch_to_output(&self->scl, true, DRIVE_MODE_OPEN_DRAIN); + common_hal_digitalio_digitalinout_switch_to_output(&self->sda, true, DRIVE_MODE_OPEN_DRAIN); + + stop(self); +} + +bool shared_module_bitbangio_i2c_deinited(bitbangio_i2c_obj_t *self) { + // If one is deinited, both will be. + return common_hal_digitalio_digitalinout_deinited(&self->scl); +} + +void shared_module_bitbangio_i2c_deinit(bitbangio_i2c_obj_t *self) { + if (shared_module_bitbangio_i2c_deinited(self)) { + return; + } + common_hal_digitalio_digitalinout_deinit(&self->scl); + common_hal_digitalio_digitalinout_deinit(&self->sda); +} + +bool shared_module_bitbangio_i2c_try_lock(bitbangio_i2c_obj_t *self) { + bool success = false; + common_hal_mcu_disable_interrupts(); + if (!self->locked) { + self->locked = true; + success = true; + } + common_hal_mcu_enable_interrupts(); + return success; +} + +bool shared_module_bitbangio_i2c_has_lock(bitbangio_i2c_obj_t *self) { + return self->locked; +} + +void shared_module_bitbangio_i2c_unlock(bitbangio_i2c_obj_t *self) { + self->locked = false; +} + +bool shared_module_bitbangio_i2c_probe(bitbangio_i2c_obj_t *self, uint8_t addr) { + start(self); + bool ok = write_byte(self, addr << 1); + stop(self); + return ok; +} + +uint8_t shared_module_bitbangio_i2c_write(bitbangio_i2c_obj_t *self, uint16_t addr, + const uint8_t *data, size_t len, bool transmit_stop_bit) { + // start the I2C transaction + start(self); + uint8_t status = 0; + if (!write_byte(self, addr << 1)) { + status = MP_ENODEV; + } + + if (status == 0) { + for (uint32_t i = 0; i < len; i++) { + if (!write_byte(self, data[i])) { + status = MP_EIO; + break; + } + } + } + + if (transmit_stop_bit) { + stop(self); + } + return status; +} + +uint8_t shared_module_bitbangio_i2c_read(bitbangio_i2c_obj_t *self, uint16_t addr, + uint8_t * data, size_t len) { + // start the I2C transaction + start(self); + uint8_t status = 0; + if (!write_byte(self, (addr << 1) | 1)) { + status = MP_ENODEV; + } + + if (status == 0) { + for (uint32_t i = 0; i < len; i++) { + if (!read_byte(self, data + i, i < len - 1)) { + status = MP_EIO; + break; + } + } + } + + stop(self); + return status; +} diff --git a/shared-module/bitbangio/OneWire.c b/shared-module/bitbangio/OneWire.c new file mode 100644 index 00000000000..f5f4790876f --- /dev/null +++ b/shared-module/bitbangio/OneWire.c @@ -0,0 +1,90 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "common-hal/microcontroller/Pin.h" +#include "shared-bindings/bitbangio/OneWire.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-module/bitbangio/types.h" + +// Durations are taken from here: https://www.maximintegrated.com/en/app-notes/index.mvp/id/126 + +void shared_module_bitbangio_onewire_construct(bitbangio_onewire_obj_t* self, + const mcu_pin_obj_t* pin) { + self->pin.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->pin, pin); +} + +bool shared_module_bitbangio_onewire_deinited(bitbangio_onewire_obj_t* self) { + return common_hal_digitalio_digitalinout_deinited(&self->pin); +} + +void shared_module_bitbangio_onewire_deinit(bitbangio_onewire_obj_t* self) { + if (shared_module_bitbangio_onewire_deinited(self)) { + return; + } + common_hal_digitalio_digitalinout_deinit(&self->pin); +} + +// We use common_hal_mcu_delay_us(). It should not be dependent on interrupts +// to do accurate timekeeping, since we disable interrupts during the delays below. + +bool shared_module_bitbangio_onewire_reset(bitbangio_onewire_obj_t* self) { + common_hal_mcu_disable_interrupts(); + common_hal_digitalio_digitalinout_switch_to_output(&self->pin, false, DRIVE_MODE_OPEN_DRAIN); + common_hal_mcu_delay_us(480); + common_hal_digitalio_digitalinout_switch_to_input(&self->pin, PULL_NONE); + common_hal_mcu_delay_us(70); + bool value = common_hal_digitalio_digitalinout_get_value(&self->pin); + common_hal_mcu_delay_us(410); + common_hal_mcu_enable_interrupts(); + return value; +} + +bool shared_module_bitbangio_onewire_read_bit(bitbangio_onewire_obj_t* self) { + common_hal_mcu_disable_interrupts(); + common_hal_digitalio_digitalinout_switch_to_output(&self->pin, false, DRIVE_MODE_OPEN_DRAIN); + common_hal_mcu_delay_us(6); + common_hal_digitalio_digitalinout_switch_to_input(&self->pin, PULL_NONE); + // TODO(tannewt): Test with more devices and maybe make the delays + // configurable. This should be 9 by the datasheet but all bits read as 1 + // then. + common_hal_mcu_delay_us(6); + bool value = common_hal_digitalio_digitalinout_get_value(&self->pin); + common_hal_mcu_delay_us(55); + common_hal_mcu_enable_interrupts(); + return value; +} + +void shared_module_bitbangio_onewire_write_bit(bitbangio_onewire_obj_t* self, + bool bit) { + common_hal_mcu_disable_interrupts(); + common_hal_digitalio_digitalinout_switch_to_output(&self->pin, false, DRIVE_MODE_OPEN_DRAIN); + common_hal_mcu_delay_us(bit? 6 : 60); + common_hal_digitalio_digitalinout_switch_to_input(&self->pin, PULL_NONE); + common_hal_mcu_delay_us(bit? 64 : 10); + common_hal_mcu_enable_interrupts(); +} diff --git a/shared-module/bitbangio/SPI.c b/shared-module/bitbangio/SPI.c new file mode 100644 index 00000000000..6d3a2852319 --- /dev/null +++ b/shared-module/bitbangio/SPI.c @@ -0,0 +1,300 @@ +/* + * This file is part of the MicroPython 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 "py/mpconfig.h" +#include "py/obj.h" +#include "py/runtime.h" + +#include "common-hal/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-module/bitbangio/types.h" +#include "supervisor/shared/translate.h" + +#define MAX_BAUDRATE (common_hal_mcu_get_clock_frequency() / 48) + +void shared_module_bitbangio_spi_construct(bitbangio_spi_obj_t *self, + const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, + const mcu_pin_obj_t * miso) { + digitalinout_result_t result = common_hal_digitalio_digitalinout_construct(&self->clock, clock); + if (result != DIGITALINOUT_OK) { + mp_raise_ValueError(translate("Clock pin init failed.")); + } + if (mosi != mp_const_none) { + result = common_hal_digitalio_digitalinout_construct(&self->mosi, mosi); + if (result != DIGITALINOUT_OK) { + common_hal_digitalio_digitalinout_deinit(&self->clock); + mp_raise_ValueError(translate("MOSI pin init failed.")); + } + self->has_mosi = true; + } + if (miso != mp_const_none) { + result = common_hal_digitalio_digitalinout_construct(&self->miso, miso); + if (result != DIGITALINOUT_OK) { + common_hal_digitalio_digitalinout_deinit(&self->clock); + if (mosi != mp_const_none) { + common_hal_digitalio_digitalinout_deinit(&self->mosi); + } + mp_raise_ValueError(translate("MISO pin init failed.")); + } + self->has_miso = true; + } + self->delay_half = 5; + self->polarity = 0; + self->phase = 0; +} + +bool shared_module_bitbangio_spi_deinited(bitbangio_spi_obj_t *self) { + return common_hal_digitalio_digitalinout_deinited(&self->clock); +} + +void shared_module_bitbangio_spi_deinit(bitbangio_spi_obj_t *self) { + if (shared_module_bitbangio_spi_deinited(self)) { + return; + } + common_hal_digitalio_digitalinout_deinit(&self->clock); + if (self->has_mosi) { + common_hal_digitalio_digitalinout_deinit(&self->mosi); + } + if (self->has_miso) { + common_hal_digitalio_digitalinout_deinit(&self->miso); + } +} + +void shared_module_bitbangio_spi_configure(bitbangio_spi_obj_t *self, + uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { + self->delay_half = 500000 / baudrate; + // round delay_half up so that: actual_baudrate <= requested_baudrate + if (500000 % baudrate != 0) { + self->delay_half += 1; + } + + self->polarity = polarity; + self->phase = phase; +} + +bool shared_module_bitbangio_spi_try_lock(bitbangio_spi_obj_t *self) { + bool success = false; + common_hal_mcu_disable_interrupts(); + if (!self->locked) { + self->locked = true; + success = true; + } + common_hal_mcu_enable_interrupts(); + return success; +} + +bool shared_module_bitbangio_spi_has_lock(bitbangio_spi_obj_t *self) { + return self->locked; +} + +void shared_module_bitbangio_spi_unlock(bitbangio_spi_obj_t *self) { + self->locked = false; +} + +// Writes out the given data. +bool shared_module_bitbangio_spi_write(bitbangio_spi_obj_t *self, const uint8_t *data, size_t len) { + if (len > 0 && !self->has_mosi) { + mp_raise_ValueError(translate("Cannot write without MOSI pin.")); + } + uint32_t delay_half = self->delay_half; + + // only MSB transfer is implemented + + // If a port defines MICROPY_PY_MACHINE_SPI_MIN_DELAY, and the configured + // delay_half is equal to this value, then the software SPI implementation + // will run as fast as possible, limited only by CPU speed and GPIO time. + #ifdef MICROPY_PY_MACHINE_SPI_MIN_DELAY + if (delay_half <= MICROPY_PY_MACHINE_SPI_MIN_DELAY) { + for (size_t i = 0; i < len; ++i) { + uint8_t data_out = data[i]; + for (int j = 0; j < 8; ++j, data_out <<= 1) { + common_hal_digitalio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); + common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + } + if (dest != NULL) { + dest[i] = data_in; + } + } + return true; + } + #endif + + for (size_t i = 0; i < len; ++i) { + uint8_t data_out = data[i]; + for (int j = 0; j < 8; ++j, data_out <<= 1) { + common_hal_digitalio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); + if (self->phase == 0) { + common_hal_mcu_delay_us(delay_half); + common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + common_hal_mcu_delay_us(delay_half); + common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + } else { + common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + common_hal_mcu_delay_us(delay_half); + common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + common_hal_mcu_delay_us(delay_half); + } + } + + // Some ports need a regular callback, but probably we don't need + // to do this every byte, or even at all. + #ifdef MICROPY_EVENT_POLL_HOOK + MICROPY_EVENT_POLL_HOOK; + #endif + } + return true; +} + +// Reads in len bytes while outputting zeroes. +bool shared_module_bitbangio_spi_read(bitbangio_spi_obj_t *self, uint8_t *data, size_t len) { + if (len > 0 && !self->has_miso) { + mp_raise_ValueError(translate("Cannot read without MISO pin.")); + } + + uint32_t delay_half = self->delay_half; + + // only MSB transfer is implemented + + // If a port defines MICROPY_PY_MACHINE_SPI_MIN_DELAY, and the configured + // delay_half is equal to this value, then the software SPI implementation + // will run as fast as possible, limited only by CPU speed and GPIO time. + #ifdef MICROPY_PY_MACHINE_SPI_MIN_DELAY + if (delay_half <= MICROPY_PY_MACHINE_SPI_MIN_DELAY) { + // Clock out zeroes while we read. + if (self->has_mosi) { + common_hal_digitalio_digitalinout_set_value(&self->mosi, false); + } + for (size_t i = 0; i < len; ++i) { + uint8_t data_in = 0; + for (int j = 0; j < 8; ++j, data_out <<= 1) { + common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + data_in = (data_in << 1) | common_hal_digitalio_digitalinout_get_value(&self->miso); + common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + } + data[i] = data_in; + } + return true; + } + #endif + if (self->has_mosi) { + common_hal_digitalio_digitalinout_set_value(&self->mosi, false); + } + for (size_t i = 0; i < len; ++i) { + uint8_t data_in = 0; + for (int j = 0; j < 8; ++j) { + if (self->phase == 0) { + common_hal_mcu_delay_us(delay_half); + common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + } else { + common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + common_hal_mcu_delay_us(delay_half); + } + data_in = (data_in << 1) | common_hal_digitalio_digitalinout_get_value(&self->miso); + if (self->phase == 0) { + common_hal_mcu_delay_us(delay_half); + common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + } else { + common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + common_hal_mcu_delay_us(delay_half); + } + } + data[i] = data_in; + + // Some ports need a regular callback, but probably we don't need + // to do this every byte, or even at all. + #ifdef MICROPY_EVENT_POLL_HOOK + MICROPY_EVENT_POLL_HOOK; + #endif + } + return true; +} + +// transfer +bool shared_module_bitbangio_spi_transfer(bitbangio_spi_obj_t *self, const uint8_t *dout, uint8_t *din, size_t len) { + if (len > 0 && (!self->has_mosi || !self->has_miso) ) { + mp_raise_ValueError(translate("Cannot transfer without MOSI and MISO pins.")); + } + uint32_t delay_half = self->delay_half; + + // only MSB transfer is implemented + + // If a port defines MICROPY_PY_MACHINE_SPI_MIN_DELAY, and the configured + // delay_half is equal to this value, then the software SPI implementation + // will run as fast as possible, limited only by CPU speed and GPIO time. + #ifdef MICROPY_PY_MACHINE_SPI_MIN_DELAY + if (delay_half <= MICROPY_PY_MACHINE_SPI_MIN_DELAY) { + for (size_t i = 0; i < len; ++i) { + uint8_t data_out = dout[i]; + uint8_t data_in = 0; + for (int j = 0; j < 8; ++j, data_out <<= 1) { + common_hal_digitalio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); + common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + data_in = (data_in << 1) | common_hal_digitalio_digitalinout_get_value(&self->miso); + common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + } + din[i] = data_in; + + if (dest != NULL) { + dest[i] = data_in; + } + } + return true; + } + #endif + + for (size_t i = 0; i < len; ++i) { + uint8_t data_out = dout[i]; + uint8_t data_in = 0; + for (int j = 0; j < 8; ++j, data_out <<= 1) { + common_hal_digitalio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); + if (self->phase == 0) { + common_hal_mcu_delay_us(delay_half); + common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + } else { + common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + common_hal_mcu_delay_us(delay_half); + } + data_in = (data_in << 1) | common_hal_digitalio_digitalinout_get_value(&self->miso); + if (self->phase == 0) { + common_hal_mcu_delay_us(delay_half); + common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + } else { + common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + common_hal_mcu_delay_us(delay_half); + } + } + din[i] = data_in; + + // Some ports need a regular callback, but probably we don't need + // to do this every byte, or even at all. + #ifdef MICROPY_EVENT_POLL_HOOK + MICROPY_EVENT_POLL_HOOK; + #endif + } + return true; +} diff --git a/shared-module/bitbangio/__init__.c b/shared-module/bitbangio/__init__.c new file mode 100644 index 00000000000..674343c5333 --- /dev/null +++ b/shared-module/bitbangio/__init__.c @@ -0,0 +1,27 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +// Nothing now. diff --git a/shared-module/bitbangio/types.h b/shared-module/bitbangio/types.h new file mode 100644 index 00000000000..6d172347418 --- /dev/null +++ b/shared-module/bitbangio/types.h @@ -0,0 +1,61 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BITBANGIO_TYPES_H +#define MICROPY_INCLUDED_SHARED_MODULE_BITBANGIO_TYPES_H + +#include "common-hal/digitalio/DigitalInOut.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + digitalio_digitalinout_obj_t scl; + digitalio_digitalinout_obj_t sda; + uint32_t us_delay; + uint32_t us_timeout; + volatile bool locked; +} bitbangio_i2c_obj_t; + +typedef struct { + mp_obj_base_t base; + digitalio_digitalinout_obj_t pin; +} bitbangio_onewire_obj_t; + +typedef struct { + mp_obj_base_t base; + digitalio_digitalinout_obj_t clock; + digitalio_digitalinout_obj_t mosi; + digitalio_digitalinout_obj_t miso; + uint32_t delay_half; + bool has_miso:1; + bool has_mosi:1; + uint8_t polarity:1; + uint8_t phase:1; + volatile bool locked:1; +} bitbangio_spi_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BITBANGIO_TYPES_H diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c new file mode 100644 index 00000000000..dd07d7190cd --- /dev/null +++ b/shared-module/board/__init__.c @@ -0,0 +1,142 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/microcontroller/Pin.h" +#include "supervisor/shared/translate.h" +#include "mpconfigboard.h" +#include "py/runtime.h" + +#if CIRCUITPY_BUSIO +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/busio/UART.h" +#endif + +#if CIRCUITPY_DISPLAYIO +#include "shared-module/displayio/__init__.h" +#endif + +#if BOARD_I2C +// Statically allocate the I2C object so it can live past the end of the heap and into the next VM. +// That way it can be used by built-in I2CDisplay displays and be accessible through board.I2C(). +STATIC busio_i2c_obj_t i2c_obj; +STATIC mp_obj_t i2c_singleton = NULL; + +mp_obj_t common_hal_board_get_i2c(void) { + return i2c_singleton; +} + +mp_obj_t common_hal_board_create_i2c(void) { + if (i2c_singleton != NULL) { + return i2c_singleton; + } + busio_i2c_obj_t *self = &i2c_obj; + self->base.type = &busio_i2c_type; + + common_hal_busio_i2c_construct(self, DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA, 400000, 0); + i2c_singleton = (mp_obj_t)self; + return i2c_singleton; +} +#endif + + +#if BOARD_SPI +// Statically allocate the SPI object so it can live past the end of the heap and into the next VM. +// That way it can be used by built-in FourWire displays and be accessible through board.SPI(). +STATIC busio_spi_obj_t spi_obj; +STATIC mp_obj_t spi_singleton = NULL; + +mp_obj_t common_hal_board_get_spi(void) { + return spi_singleton; +} + +mp_obj_t common_hal_board_create_spi(void) { + if (spi_singleton != NULL) { + return spi_singleton; + } + busio_spi_obj_t *self = &spi_obj; + self->base.type = &busio_spi_type; + + const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_SCK); + const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MOSI); + const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MISO); + common_hal_busio_spi_construct(self, clock, mosi, miso); + spi_singleton = (mp_obj_t)self; + return spi_singleton; +} +#endif + +#if BOARD_UART +mp_obj_t common_hal_board_get_uart(void) { + return MP_STATE_VM(shared_uart_bus); +} + +mp_obj_t common_hal_board_create_uart(void) { + busio_uart_obj_t *self = m_new_ll_obj(busio_uart_obj_t); + self->base.type = &busio_uart_type; + + const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RX); + const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_TX); + + common_hal_busio_uart_construct(self, tx, rx, 9600, 8, PARITY_NONE, 1, 1000, 64); + MP_STATE_VM(shared_uart_bus) = MP_OBJ_FROM_PTR(self); + return MP_STATE_VM(shared_uart_bus); +} +#endif + +void reset_board_busses(void) { +#if BOARD_I2C + bool display_using_i2c = false; + #if CIRCUITPY_DISPLAYIO + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].i2cdisplay_bus.bus == i2c_singleton) { + display_using_i2c = true; + break; + } + } + #endif + if (!display_using_i2c) { + i2c_singleton = NULL; + } +#endif +#if BOARD_SPI + bool display_using_spi = false; + #if CIRCUITPY_DISPLAYIO + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].fourwire_bus.bus == spi_singleton) { + display_using_spi = true; + break; + } + } + #endif + if (!display_using_spi) { + spi_singleton = NULL; + } +#endif +#if BOARD_UART + MP_STATE_VM(shared_uart_bus) = NULL; +#endif +} diff --git a/shared-module/board/__init__.h b/shared-module/board/__init__.h new file mode 100644 index 00000000000..f7eecd41702 --- /dev/null +++ b/shared-module/board/__init__.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BOARD__INIT__H +#define MICROPY_INCLUDED_SHARED_MODULE_BOARD__INIT__H + +void reset_board_busses(void); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BOARD__INIT__H diff --git a/shared-module/busio/I2C.c b/shared-module/busio/I2C.c new file mode 100644 index 00000000000..06e1af10a1c --- /dev/null +++ b/shared-module/busio/I2C.c @@ -0,0 +1,70 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/busio/I2C.h" +#include "shared-bindings/bitbangio/I2C.h" +#include "py/mperrno.h" +#include "py/nlr.h" + +void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, + const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t freq, uint32_t timeout) { + shared_module_bitbangio_i2c_construct(&self->bitbang, scl, sda, freq, timeout); +} + +bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { + return shared_module_bitbangio_i2c_deinited(&self->bitbang); +} + +void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { + shared_module_bitbangio_i2c_deinit(&self->bitbang); +} + +bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { + return shared_module_bitbangio_i2c_probe(&self->bitbang, addr); +} + +bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) { + return shared_module_bitbangio_i2c_try_lock(&self->bitbang); +} + +bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self) { + return shared_module_bitbangio_i2c_has_lock(&self->bitbang); +} + +void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { + shared_module_bitbangio_i2c_unlock(&self->bitbang); +} + +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, + const uint8_t * data, size_t len, bool transmit_stop_bit) { + return shared_module_bitbangio_i2c_write(&self->bitbang, addr, data, len, + transmit_stop_bit); +} + +uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t * data, size_t len) { + return shared_module_bitbangio_i2c_read(&self->bitbang, addr, data, len); +} diff --git a/shared-module/busio/I2C.h b/shared-module/busio/I2C.h new file mode 100644 index 00000000000..8e3525f196c --- /dev/null +++ b/shared-module/busio/I2C.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BUSIO_I2C_H +#define MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BUSIO_I2C_H + +#include "shared-module/bitbangio/types.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + bitbangio_i2c_obj_t bitbang; +} busio_i2c_obj_t; + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BUSIO_I2C_H diff --git a/shared-module/busio/OneWire.c b/shared-module/busio/OneWire.c new file mode 100644 index 00000000000..6bb7dedcd17 --- /dev/null +++ b/shared-module/busio/OneWire.c @@ -0,0 +1,59 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +// Wraps the bitbangio implementation of OneWire for use in busio. +#include "common-hal/microcontroller/Pin.h" +#include "shared-bindings/bitbangio/OneWire.h" +#include "shared-module/busio/OneWire.h" + +void common_hal_busio_onewire_construct(busio_onewire_obj_t* self, + const mcu_pin_obj_t* pin) { + shared_module_bitbangio_onewire_construct(&self->bitbang, pin); +} + +bool common_hal_busio_onewire_deinited(busio_onewire_obj_t* self) { + return shared_module_bitbangio_onewire_deinited(&self->bitbang); +} + +void common_hal_busio_onewire_deinit(busio_onewire_obj_t* self) { + if (common_hal_busio_onewire_deinited(self)) { + return; + } + shared_module_bitbangio_onewire_deinit(&self->bitbang); +} + +bool common_hal_busio_onewire_reset(busio_onewire_obj_t* self) { + return shared_module_bitbangio_onewire_reset(&self->bitbang); +} + +bool common_hal_busio_onewire_read_bit(busio_onewire_obj_t* self) { + return shared_module_bitbangio_onewire_read_bit(&self->bitbang); +} + +void common_hal_busio_onewire_write_bit(busio_onewire_obj_t* self, + bool bit) { + shared_module_bitbangio_onewire_write_bit(&self->bitbang, bit); +} diff --git a/shared-module/busio/OneWire.h b/shared-module/busio/OneWire.h new file mode 100644 index 00000000000..9ffb89d497d --- /dev/null +++ b/shared-module/busio/OneWire.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BUSIO_ONEWIRE_H +#define MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BUSIO_ONEWIRE_H + +#include "shared-module/bitbangio/types.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + bitbangio_onewire_obj_t bitbang; +} busio_onewire_obj_t; + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BUSIO_ONEWIRE_H diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c new file mode 100644 index 00000000000..59971d25cc8 --- /dev/null +++ b/shared-module/displayio/Bitmap.c @@ -0,0 +1,164 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/Bitmap.h" + +#include + +#include "py/runtime.h" + +void common_hal_displayio_bitmap_construct(displayio_bitmap_t *self, uint32_t width, + uint32_t height, uint32_t bits_per_value) { + uint32_t row_width = width * bits_per_value; + // align to size_t + uint8_t align_bits = 8 * sizeof(size_t); + if (row_width % align_bits != 0) { + self->stride = (row_width / align_bits + 1); + } else { + self->stride = row_width / align_bits; + } + self->width = width; + self->height = height; + self->data = m_malloc(self->stride * height * sizeof(size_t), false); + self->read_only = false; + self->bits_per_value = bits_per_value; + + if (bits_per_value > 8 && bits_per_value != 16 && bits_per_value != 32) { + mp_raise_NotImplementedError(translate("Invalid bits per value")); + } + + // Division and modulus can be slow because it has to handle any integer. We know bits_per_value + // is a power of two. We divide and mod by bits_per_value to compute the offset into the byte + // array. So, we can the offset computation to simplify to a shift for division and mask for mod. + + self->x_shift = 0; // Used to divide the index by the number of pixels per word. Its used in a + // shift which effectively divides by 2 ** x_shift. + uint32_t power_of_two = 1; + while (power_of_two < align_bits / bits_per_value ) { + self->x_shift++; + power_of_two <<= 1; + } + self->x_mask = (1 << self->x_shift) - 1; // Used as a modulus on the x value + self->bitmask = (1 << bits_per_value) - 1; + + self->dirty_area.x1 = 0; + self->dirty_area.x2 = width; + self->dirty_area.y1 = 0; + self->dirty_area.y2 = height; +} + +uint16_t common_hal_displayio_bitmap_get_height(displayio_bitmap_t *self) { + return self->height; +} + +uint16_t common_hal_displayio_bitmap_get_width(displayio_bitmap_t *self) { + return self->width; +} + +uint32_t common_hal_displayio_bitmap_get_bits_per_value(displayio_bitmap_t *self) { + return self->bits_per_value; +} + +uint32_t common_hal_displayio_bitmap_get_pixel(displayio_bitmap_t *self, int16_t x, int16_t y) { + if (x >= self->width || x < 0 || y >= self->height || y < 0) { + return 0; + } + int32_t row_start = y * self->stride; + uint32_t bytes_per_value = self->bits_per_value / 8; + if (bytes_per_value < 1) { + size_t word = self->data[row_start + (x >> self->x_shift)]; + + return (word >> (sizeof(size_t) * 8 - ((x & self->x_mask) + 1) * self->bits_per_value)) & self->bitmask; + } else { + size_t* row = self->data + row_start; + if (bytes_per_value == 1) { + return ((uint8_t*) row)[x]; + } else if (bytes_per_value == 2) { + return ((uint16_t*) row)[x]; + } else if (bytes_per_value == 4) { + return ((uint32_t*) row)[x]; + } + } + return 0; +} + +void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *self, int16_t x, int16_t y, uint32_t value) { + if (self->read_only) { + mp_raise_RuntimeError(translate("Read-only object")); + } + // Update the dirty area. + if (self->dirty_area.x1 == self->dirty_area.x2) { + self->dirty_area.x1 = x; + self->dirty_area.x2 = x + 1; + self->dirty_area.y1 = y; + self->dirty_area.y2 = y + 1; + } else { + if (x < self->dirty_area.x1) { + self->dirty_area.x1 = x; + } else if (x >= self->dirty_area.x2) { + self->dirty_area.x2 = x + 1; + } + if (y < self->dirty_area.y1) { + self->dirty_area.y1 = y; + } else if (y >= self->dirty_area.y2) { + self->dirty_area.y2 = y + 1; + } + } + + // Update our data + int32_t row_start = y * self->stride; + uint32_t bytes_per_value = self->bits_per_value / 8; + if (bytes_per_value < 1) { + uint32_t bit_position = (sizeof(size_t) * 8 - ((x & self->x_mask) + 1) * self->bits_per_value); + uint32_t index = row_start + (x >> self->x_shift); + uint32_t word = self->data[index]; + word &= ~(self->bitmask << bit_position); + word |= (value & self->bitmask) << bit_position; + self->data[index] = word; + } else { + size_t* row = self->data + row_start; + if (bytes_per_value == 1) { + ((uint8_t*) row)[x] = value; + } else if (bytes_per_value == 2) { + ((uint16_t*) row)[x] = value; + } else if (bytes_per_value == 4) { + ((uint32_t*) row)[x] = value; + } + } +} + +displayio_area_t* displayio_bitmap_get_refresh_areas(displayio_bitmap_t *self, displayio_area_t* tail) { + if (self->dirty_area.x1 == self->dirty_area.x2) { + return tail; + } + self->dirty_area.next = tail; + return &self->dirty_area; +} + +void displayio_bitmap_finish_refresh(displayio_bitmap_t *self) { + self->dirty_area.x1 = 0; + self->dirty_area.x2 = 0; +} diff --git a/shared-module/displayio/Bitmap.h b/shared-module/displayio/Bitmap.h new file mode 100644 index 00000000000..f4bd7ce4d32 --- /dev/null +++ b/shared-module/displayio/Bitmap.h @@ -0,0 +1,53 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_BITMAP_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_BITMAP_H + +#include +#include + +#include "py/obj.h" +#include "shared-module/displayio/area.h" + +typedef struct { + mp_obj_base_t base; + uint16_t width; + uint16_t height; + size_t* data; + uint16_t stride; // size_t's + uint8_t bits_per_value; + uint8_t x_shift; + size_t x_mask; + displayio_area_t dirty_area; + uint16_t bitmask; + bool read_only; +} displayio_bitmap_t; + +void displayio_bitmap_finish_refresh(displayio_bitmap_t *self); +displayio_area_t* displayio_bitmap_get_refresh_areas(displayio_bitmap_t *self, displayio_area_t* tail); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_BITMAP_H diff --git a/shared-module/displayio/ColorConverter.c b/shared-module/displayio/ColorConverter.c new file mode 100644 index 00000000000..940aaa1c6d3 --- /dev/null +++ b/shared-module/displayio/ColorConverter.c @@ -0,0 +1,133 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/ColorConverter.h" + +#include "py/misc.h" + +void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t* self) { +} + +uint16_t displayio_colorconverter_compute_rgb565(uint32_t color_rgb888) { + uint32_t r5 = (color_rgb888 >> 19); + uint32_t g6 = (color_rgb888 >> 10) & 0x3f; + uint32_t b5 = (color_rgb888 >> 3) & 0x1f; + uint32_t packed = r5 << 11 | g6 << 5 | b5; + // swap bytes + return __builtin_bswap16(packed); +} + +uint8_t displayio_colorconverter_compute_luma(uint32_t color_rgb888) { + uint32_t r8 = (color_rgb888 >> 16); + uint32_t g8 = (color_rgb888 >> 8) & 0xff; + uint32_t b8 = color_rgb888 & 0xff; + return (r8 * 19) / 255 + (g8 * 182) / 255 + (b8 + 54) / 255; +} + +uint8_t displayio_colorconverter_compute_chroma(uint32_t color_rgb888) { + uint32_t r8 = (color_rgb888 >> 16); + uint32_t g8 = (color_rgb888 >> 8) & 0xff; + uint32_t b8 = color_rgb888 & 0xff; + uint8_t max = MAX(r8, MAX(g8, b8)); + uint8_t min = MIN(r8, MIN(g8, b8)); + return max - min; +} + +uint8_t displayio_colorconverter_compute_hue(uint32_t color_rgb888) { + uint32_t r8 = (color_rgb888 >> 16); + uint32_t g8 = (color_rgb888 >> 8) & 0xff; + uint32_t b8 = color_rgb888 & 0xff; + uint8_t max = MAX(r8, MAX(g8, b8)); + uint8_t min = MIN(r8, MIN(g8, b8)); + uint8_t c = max - min; + if (c == 0) { + return 0; + } + + int32_t hue = 0; + if (max == r8) { + hue = (((int32_t) (g8 - b8) * 40) / c) % 240; + } else if (max == g8) { + hue = (((int32_t) (b8 - r8) + (2 * c)) * 40) / c; + } else if (max == b8) { + hue = (((int32_t) (r8 - g8) + (4 * c)) * 40) / c; + } + if (hue < 0) { + hue += 240; + } + + return hue; +} + +void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t* colorspace, uint8_t pixel_hue, uint8_t pixel_luma, uint32_t* color) { + + int16_t hue_diff = colorspace->tricolor_hue - pixel_hue; + if ((-10 <= hue_diff && hue_diff <= 10) || hue_diff <= -220 || hue_diff >= 220) { + if (colorspace->grayscale) { + *color = 0; + } else { + *color = 1; + } + } else if (!colorspace->grayscale) { + *color = 0; + } +} + +bool displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color) { + if (colorspace->depth == 16) { + *output_color = displayio_colorconverter_compute_rgb565(input_color); + return true; + } else if (colorspace->tricolor) { + uint8_t luma = displayio_colorconverter_compute_luma(input_color); + *output_color = luma >> (8 - colorspace->depth); + if (displayio_colorconverter_compute_chroma(input_color) <= 16) { + if (!colorspace->grayscale) { + *output_color = 0; + } + return true; + } + uint8_t pixel_hue = displayio_colorconverter_compute_hue(input_color); + displayio_colorconverter_compute_tricolor(colorspace, pixel_hue, luma, output_color); + return true; + } else if (colorspace->grayscale && colorspace->depth <= 8) { + uint8_t luma = displayio_colorconverter_compute_luma(input_color); + *output_color = luma >> (8 - colorspace->depth); + return true; + } + return false; +} + +void common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color) { + displayio_colorconverter_convert(self, colorspace, input_color, output_color); +} + +// Currently no refresh logic is needed for a ColorConverter. +bool displayio_colorconverter_needs_refresh(displayio_colorconverter_t *self) { + return false; +} + +void displayio_colorconverter_finish_refresh(displayio_colorconverter_t *self) { +} diff --git a/shared-module/displayio/ColorConverter.h b/shared-module/displayio/ColorConverter.h new file mode 100644 index 00000000000..c79e6a2f7e8 --- /dev/null +++ b/shared-module/displayio/ColorConverter.h @@ -0,0 +1,49 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_COLORCONVERTER_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_COLORCONVERTER_H + +#include +#include + +#include "py/obj.h" +#include "shared-module/displayio/Palette.h" + +typedef struct { + mp_obj_base_t base; +} displayio_colorconverter_t; + +bool displayio_colorconverter_needs_refresh(displayio_colorconverter_t *self); +void displayio_colorconverter_finish_refresh(displayio_colorconverter_t *self); +bool displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color); +uint16_t displayio_colorconverter_compute_rgb565(uint32_t color_rgb888); +uint8_t displayio_colorconverter_compute_luma(uint32_t color_rgb888); +uint8_t displayio_colorconverter_compute_chroma(uint32_t color_rgb888); +uint8_t displayio_colorconverter_compute_hue(uint32_t color_rgb888); +void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t* colorspace, uint8_t pixel_hue, uint8_t pixel_luma, uint32_t* color); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_COLORCONVERTER_H diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c new file mode 100644 index 00000000000..f210a80c3cb --- /dev/null +++ b/shared-module/displayio/Display.c @@ -0,0 +1,387 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/Display.h" + +#include "py/runtime.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/displayio/I2CDisplay.h" +#include "shared-bindings/displayio/ParallelBus.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/time/__init__.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/display_core.h" +#include "supervisor/shared/display.h" +#include "supervisor/usb.h" + +#include +#include + +#include "tick.h" + +void common_hal_displayio_display_construct(displayio_display_obj_t* self, + mp_obj_t bus, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart, + uint16_t rotation, uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, + uint8_t bytes_per_cell, bool reverse_pixels_in_byte, uint8_t set_column_command, + uint8_t set_row_command, uint8_t write_ram_command, uint8_t set_vertical_scroll, + uint8_t* init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t* backlight_pin, + uint16_t brightness_command, mp_float_t brightness, bool auto_brightness, + bool single_byte_bounds, bool data_as_commands, bool auto_refresh, uint16_t native_frames_per_second) { + uint16_t ram_width = 0x100; + uint16_t ram_height = 0x100; + if (single_byte_bounds) { + ram_width = 0xff; + ram_height = 0xff; + } + displayio_display_core_construct(&self->core, bus, width, height, ram_width, ram_height, colstart, rowstart, rotation, + color_depth, grayscale, pixels_in_byte_share_row, bytes_per_cell, reverse_pixels_in_byte); + + self->set_column_command = set_column_command; + self->set_row_command = set_row_command; + self->write_ram_command = write_ram_command; + self->brightness_command = brightness_command; + self->auto_brightness = auto_brightness; + self->auto_refresh = auto_refresh; + self->first_manual_refresh = !auto_refresh; + self->data_as_commands = data_as_commands; + + self->native_frames_per_second = native_frames_per_second; + self->native_ms_per_frame = 1000 / native_frames_per_second; + + uint32_t i = 0; + while (i < init_sequence_len) { + uint8_t *cmd = init_sequence + i; + uint8_t data_size = *(cmd + 1); + bool delay = (data_size & DELAY) != 0; + data_size &= ~DELAY; + uint8_t *data = cmd + 2; + while (!displayio_display_core_begin_transaction(&self->core)) { + RUN_BACKGROUND_TASKS; + } + if (self->data_as_commands) { + uint8_t full_command[data_size + 1]; + full_command[0] = cmd[0]; + memcpy(full_command + 1, data, data_size); + self->core.send(self->core.bus, DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, full_command, data_size + 1); + } else { + self->core.send(self->core.bus, DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, cmd, 1); + self->core.send(self->core.bus, DISPLAY_DATA, CHIP_SELECT_UNTOUCHED, data, data_size); + } + self->core.end_transaction(self->core.bus); + uint16_t delay_length_ms = 10; + if (delay) { + data_size++; + delay_length_ms = *(cmd + 1 + data_size); + if (delay_length_ms == 255) { + delay_length_ms = 500; + } + } + common_hal_time_delay_ms(delay_length_ms); + i += 2 + data_size; + } + + supervisor_start_terminal(width, height); + + // Always set the backlight type in case we're reusing memory. + self->backlight_inout.base.type = &mp_type_NoneType; + if (backlight_pin != NULL && common_hal_mcu_pin_is_free(backlight_pin)) { + pwmout_result_t result = common_hal_pulseio_pwmout_construct(&self->backlight_pwm, backlight_pin, 0, 50000, false); + if (result != PWMOUT_OK) { + self->backlight_inout.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->backlight_inout, backlight_pin); + never_reset_pin_number(backlight_pin->number); + } else { + self->backlight_pwm.base.type = &pulseio_pwmout_type; + common_hal_pulseio_pwmout_never_reset(&self->backlight_pwm); + } + } + if (!self->auto_brightness && (self->backlight_inout.base.type != &mp_type_NoneType || + brightness_command != NO_BRIGHTNESS_COMMAND)) { + common_hal_displayio_display_set_brightness(self, brightness); + } else { + self->current_brightness = -1.0; + } + + // Set the group after initialization otherwise we may send pixels while we delay in + // initialization. + common_hal_displayio_display_show(self, &circuitpython_splash); +} + +bool common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) { + return displayio_display_core_show(&self->core, root_group); +} + +uint16_t common_hal_displayio_display_get_width(displayio_display_obj_t* self){ + return displayio_display_core_get_width(&self->core); +} + +uint16_t common_hal_displayio_display_get_height(displayio_display_obj_t* self){ + return displayio_display_core_get_height(&self->core); +} + +bool common_hal_displayio_display_get_auto_brightness(displayio_display_obj_t* self) { + return self->auto_brightness; +} + +void common_hal_displayio_display_set_auto_brightness(displayio_display_obj_t* self, bool auto_brightness) { + self->auto_brightness = auto_brightness; +} + +mp_float_t common_hal_displayio_display_get_brightness(displayio_display_obj_t* self) { + return self->current_brightness; +} + +bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self, mp_float_t brightness) { + self->updating_backlight = true; + bool ok = false; + if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { + common_hal_pulseio_pwmout_set_duty_cycle(&self->backlight_pwm, (uint16_t) (0xffff * brightness)); + ok = true; + } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { + common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, brightness > 0.99); + ok = true; + } else if (self->brightness_command != NO_BRIGHTNESS_COMMAND) { + ok = displayio_display_core_begin_transaction(&self->core); + if (ok) { + if (self->data_as_commands) { + uint8_t set_brightness[2] = {self->brightness_command, (uint8_t) (0xff * brightness)}; + self->core.send(self->core.bus, DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, set_brightness, 2); + } else { + uint8_t command = self->brightness_command; + uint8_t hex_brightness = 0xff * brightness; + self->core.send(self->core.bus, DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, &command, 1); + self->core.send(self->core.bus, DISPLAY_DATA, CHIP_SELECT_UNTOUCHED, &hex_brightness, 1); + } + displayio_display_core_end_transaction(&self->core); + } + + } + self->updating_backlight = false; + if (ok) { + self->current_brightness = brightness; + } + return ok; +} + +mp_obj_t common_hal_displayio_display_get_bus(displayio_display_obj_t* self) { + return self->core.bus; +} + +STATIC const displayio_area_t* _get_refresh_areas(displayio_display_obj_t *self) { + if (self->core.full_refresh) { + self->core.area.next = NULL; + return &self->core.area; + } else if (self->core.current_group != NULL) { + return displayio_group_get_refresh_areas(self->core.current_group, NULL); + } + return NULL; +} + +STATIC void _send_pixels(displayio_display_obj_t* self, uint8_t* pixels, uint32_t length) { + if (!self->data_as_commands) { + self->core.send(self->core.bus, DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, &self->write_ram_command, 1); + } + self->core.send(self->core.bus, DISPLAY_DATA, CHIP_SELECT_UNTOUCHED, pixels, length); +} + +STATIC bool _refresh_area(displayio_display_obj_t* self, const displayio_area_t* area) { + uint16_t buffer_size = 128; // In uint32_ts + + displayio_area_t clipped; + // Clip the area to the display by overlapping the areas. If there is no overlap then we're done. + if (!displayio_display_core_clip_area(&self->core, area, &clipped)) { + return true; + } + uint16_t subrectangles = 1; + uint16_t rows_per_buffer = displayio_area_height(&clipped); + uint8_t pixels_per_word = (sizeof(uint32_t) * 8) / self->core.colorspace.depth; + uint16_t pixels_per_buffer = displayio_area_size(&clipped); + if (displayio_area_size(&clipped) > buffer_size * pixels_per_word) { + rows_per_buffer = buffer_size * pixels_per_word / displayio_area_width(&clipped); + if (rows_per_buffer == 0) { + rows_per_buffer = 1; + } + // If pixels are packed by column then ensure rows_per_buffer is on a byte boundary. + if (self->core.colorspace.depth < 8 && !self->core.colorspace.pixels_in_byte_share_row) { + uint8_t pixels_per_byte = 8 / self->core.colorspace.depth; + if (rows_per_buffer % pixels_per_byte != 0) { + rows_per_buffer -= rows_per_buffer % pixels_per_byte; + } + } + subrectangles = displayio_area_height(&clipped) / rows_per_buffer; + if (displayio_area_height(&clipped) % rows_per_buffer != 0) { + subrectangles++; + } + pixels_per_buffer = rows_per_buffer * displayio_area_width(&clipped); + buffer_size = pixels_per_buffer / pixels_per_word; + if (pixels_per_buffer % pixels_per_word) { + buffer_size += 1; + } + } + + // Allocated and shared as a uint32_t array so the compiler knows the + // alignment everywhere. + uint32_t buffer[buffer_size]; + uint32_t mask_length = (pixels_per_buffer / 32) + 1; + uint32_t mask[mask_length]; + uint16_t remaining_rows = displayio_area_height(&clipped); + + for (uint16_t j = 0; j < subrectangles; j++) { + displayio_area_t subrectangle = { + .x1 = clipped.x1, + .y1 = clipped.y1 + rows_per_buffer * j, + .x2 = clipped.x2, + .y2 = clipped.y1 + rows_per_buffer * (j + 1) + }; + if (remaining_rows < rows_per_buffer) { + subrectangle.y2 = subrectangle.y1 + remaining_rows; + } + remaining_rows -= rows_per_buffer; + + displayio_display_core_set_region_to_update(&self->core, self->set_column_command, self->set_row_command, NO_COMMAND, NO_COMMAND, self->data_as_commands, false, &subrectangle); + + uint16_t subrectangle_size_bytes; + if (self->core.colorspace.depth >= 8) { + subrectangle_size_bytes = displayio_area_size(&subrectangle) * (self->core.colorspace.depth / 8); + } else { + subrectangle_size_bytes = displayio_area_size(&subrectangle) / (8 / self->core.colorspace.depth); + } + + memset(mask, 0, mask_length * sizeof(mask[0])); + memset(buffer, 0, buffer_size * sizeof(buffer[0])); + + displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer); + + // Can't acquire display bus; skip the rest of the data. + if (!displayio_display_core_bus_free(&self->core)) { + return false; + } + + displayio_display_core_begin_transaction(&self->core); + _send_pixels(self, (uint8_t*) buffer, subrectangle_size_bytes); + displayio_display_core_end_transaction(&self->core); + + // TODO(tannewt): Make refresh displays faster so we don't starve other + // background tasks. + usb_background(); + } + return true; +} + +STATIC void _refresh_display(displayio_display_obj_t* self) { + if (!displayio_display_core_bus_free(&self->core)) { + // Can't acquire display bus; skip updating this display. Try next display. + return; + } + displayio_display_core_start_refresh(&self->core); + const displayio_area_t* current_area = _get_refresh_areas(self); + while (current_area != NULL) { + _refresh_area(self, current_area); + current_area = current_area->next; + } + displayio_display_core_finish_refresh(&self->core); +} + +uint16_t common_hal_displayio_display_get_rotation(displayio_display_obj_t* self){ + return self->core.rotation; +} + +bool common_hal_displayio_display_refresh(displayio_display_obj_t* self, uint32_t target_ms_per_frame, uint32_t maximum_ms_per_real_frame) { + if (!self->auto_refresh && !self->first_manual_refresh) { + uint64_t current_time = ticks_ms; + uint32_t current_ms_since_real_refresh = current_time - self->core.last_refresh; + // Test to see if the real frame time is below our minimum. + if (current_ms_since_real_refresh > maximum_ms_per_real_frame) { + mp_raise_RuntimeError(translate("Below minimum frame rate")); + } + uint32_t current_ms_since_last_call = current_time - self->last_refresh_call; + self->last_refresh_call = current_time; + // Skip the actual refresh to help catch up. + if (current_ms_since_last_call > target_ms_per_frame) { + return false; + } + uint32_t remaining_time = target_ms_per_frame - (current_ms_since_real_refresh % target_ms_per_frame); + // We're ahead of the game so wait until we align with the frame rate. + while (ticks_ms - self->last_refresh_call < remaining_time) { + RUN_BACKGROUND_TASKS; + } + } + self->first_manual_refresh = false; + _refresh_display(self); + return true; +} + +bool common_hal_displayio_display_get_auto_refresh(displayio_display_obj_t* self) { + return self->auto_refresh; +} + +void common_hal_displayio_display_set_auto_refresh(displayio_display_obj_t* self, + bool auto_refresh) { + self->first_manual_refresh = !auto_refresh; + self->auto_refresh = auto_refresh; +} + +STATIC void _update_backlight(displayio_display_obj_t* self) { + if (!self->auto_brightness || self->updating_backlight) { + return; + } + if (ticks_ms - self->last_backlight_refresh < 100) { + return; + } + // TODO(tannewt): Fade the backlight based on it's existing value and a target value. The target + // should account for ambient light when possible. + common_hal_displayio_display_set_brightness(self, 1.0); + + self->last_backlight_refresh = ticks_ms; +} + +void displayio_display_background(displayio_display_obj_t* self) { + _update_backlight(self); + + if (self->auto_refresh && (ticks_ms - self->core.last_refresh) > self->native_ms_per_frame) { + _refresh_display(self); + } +} + +void release_display(displayio_display_obj_t* self) { + release_display_core(&self->core); + if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { + common_hal_pulseio_pwmout_reset_ok(&self->backlight_pwm); + common_hal_pulseio_pwmout_deinit(&self->backlight_pwm); + } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { + common_hal_digitalio_digitalinout_deinit(&self->backlight_inout); + } +} + +void reset_display(displayio_display_obj_t* self) { + self->auto_refresh = true; + self->auto_brightness = true; + common_hal_displayio_display_show(self, NULL); +} + +void displayio_display_collect_ptrs(displayio_display_obj_t* self) { + displayio_display_core_collect_ptrs(&self->core); +} diff --git a/shared-module/displayio/Display.h b/shared-module/displayio/Display.h new file mode 100644 index 00000000000..e5fe0a70885 --- /dev/null +++ b/shared-module/displayio/Display.h @@ -0,0 +1,66 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H + +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/pulseio/PWMOut.h" + +#include "shared-module/displayio/area.h" +#include "shared-module/displayio/display_core.h" + +typedef struct { + mp_obj_base_t base; + displayio_display_core_t core; + union { + digitalio_digitalinout_obj_t backlight_inout; + pulseio_pwmout_obj_t backlight_pwm; + }; + uint64_t last_backlight_refresh; + uint64_t last_refresh_call; + mp_float_t current_brightness; + uint16_t brightness_command; + uint16_t native_frames_per_second; + uint16_t native_ms_per_frame; + uint8_t set_column_command; + uint8_t set_row_command; + uint8_t write_ram_command; + bool auto_refresh; + bool first_manual_refresh; + bool data_as_commands; + bool auto_brightness; + bool updating_backlight; +} displayio_display_obj_t; + +void displayio_display_background(displayio_display_obj_t* self); +void release_display(displayio_display_obj_t* self); +void reset_display(displayio_display_obj_t* self); + +void displayio_display_collect_ptrs(displayio_display_obj_t* self); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H diff --git a/shared-module/displayio/EPaperDisplay.c b/shared-module/displayio/EPaperDisplay.c new file mode 100644 index 00000000000..efbd9f3ddbb --- /dev/null +++ b/shared-module/displayio/EPaperDisplay.c @@ -0,0 +1,385 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/EPaperDisplay.h" + +#include "py/runtime.h" +#include "shared-bindings/displayio/ColorConverter.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/displayio/I2CDisplay.h" +#include "shared-bindings/displayio/ParallelBus.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/time/__init__.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/display.h" +#include "supervisor/usb.h" + +#include +#include + +#include "tick.h" + +void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t* self, + mp_obj_t bus, uint8_t* start_sequence, uint16_t start_sequence_len, uint8_t* stop_sequence, uint16_t stop_sequence_len, + uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height, + int16_t colstart, int16_t rowstart, uint16_t rotation, + uint16_t set_column_window_command, uint16_t set_row_window_command, + uint16_t set_current_column_command, uint16_t set_current_row_command, + uint16_t write_black_ram_command, bool black_bits_inverted, uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, uint16_t refresh_display_command, mp_float_t refresh_time, + const mcu_pin_obj_t* busy_pin, bool busy_state, mp_float_t seconds_per_frame, bool chip_select) { + if (highlight_color != 0x000000) { + self->core.colorspace.tricolor = true; + self->core.colorspace.tricolor_hue = displayio_colorconverter_compute_hue(highlight_color); + self->core.colorspace.tricolor_luma = displayio_colorconverter_compute_luma(highlight_color); + } + + displayio_display_core_construct(&self->core, bus, width, height, ram_width, ram_height, colstart, rowstart, rotation, 1, true, true, 1, true); + + self->set_column_window_command = set_column_window_command; + self->set_row_window_command = set_row_window_command; + self->set_current_column_command = set_current_column_command; + self->set_current_row_command = set_current_row_command; + self->write_black_ram_command = write_black_ram_command; + self->black_bits_inverted = black_bits_inverted; + self->write_color_ram_command = write_color_ram_command; + self->color_bits_inverted = color_bits_inverted; + self->refresh_display_command = refresh_display_command; + self->refresh_time = refresh_time * 1000; + self->busy_state = busy_state; + self->refreshing = false; + self->milliseconds_per_frame = seconds_per_frame * 1000; + self->chip_select = chip_select ? CHIP_SELECT_TOGGLE_EVERY_BYTE : CHIP_SELECT_UNTOUCHED; + + self->start_sequence = start_sequence; + self->start_sequence_len = start_sequence_len; + self->stop_sequence = stop_sequence; + self->stop_sequence_len = stop_sequence_len; + + self->busy.base.type = &mp_type_NoneType; + if (busy_pin != NULL) { + self->busy.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->busy, busy_pin); + never_reset_pin_number(busy_pin->number); + } + + // Clear the color memory if it isn't in use. + if (highlight_color == 0x00 && write_color_ram_command != NO_COMMAND) { + // TODO: Clear + } + + supervisor_start_terminal(width, height); + + // Set the group after initialization otherwise we may send pixels while we delay in + // initialization. + common_hal_displayio_epaperdisplay_show(self, &circuitpython_splash); +} + +bool common_hal_displayio_epaperdisplay_show(displayio_epaperdisplay_obj_t* self, displayio_group_t* root_group) { + return displayio_display_core_show(&self->core, root_group); +} + +const displayio_area_t* displayio_epaperdisplay_get_refresh_areas(displayio_epaperdisplay_obj_t *self) { + if (self->core.full_refresh) { + self->core.area.next = NULL; + return &self->core.area; + } + const displayio_area_t* first_area = NULL; + if (self->core.current_group != NULL) { + first_area = displayio_group_get_refresh_areas(self->core.current_group, NULL); + } + if (first_area != NULL && self->set_row_window_command == NO_COMMAND) { + self->core.area.next = NULL; + return &self->core.area; + } + return first_area; +} + +uint16_t common_hal_displayio_epaperdisplay_get_width(displayio_epaperdisplay_obj_t* self){ + return displayio_display_core_get_width(&self->core); +} + +uint16_t common_hal_displayio_epaperdisplay_get_height(displayio_epaperdisplay_obj_t* self){ + return displayio_display_core_get_height(&self->core); +} + +STATIC void wait_for_busy(displayio_epaperdisplay_obj_t* self) { + if (self->busy.base.type == &mp_type_NoneType) { + return; + } + while (common_hal_digitalio_digitalinout_get_value(&self->busy) == self->busy_state) { + RUN_BACKGROUND_TASKS; + } +} + +STATIC void send_command_sequence(displayio_epaperdisplay_obj_t* self, bool should_wait_for_busy, uint8_t* sequence, uint32_t sequence_len) { + uint32_t i = 0; + while (i < sequence_len) { + uint8_t *cmd = sequence + i; + uint8_t data_size = *(cmd + 1); + bool delay = (data_size & DELAY) != 0; + data_size &= ~DELAY; + uint8_t *data = cmd + 2; + displayio_display_core_begin_transaction(&self->core); + self->core.send(self->core.bus, DISPLAY_COMMAND, self->chip_select, cmd, 1); + self->core.send(self->core.bus, DISPLAY_DATA, self->chip_select, data, data_size); + displayio_display_core_end_transaction(&self->core); + uint16_t delay_length_ms = 0; + if (delay) { + data_size++; + delay_length_ms = *(cmd + 1 + data_size); + if (delay_length_ms == 255) { + delay_length_ms = 500; + } + } + common_hal_time_delay_ms(delay_length_ms); + if (should_wait_for_busy) { + wait_for_busy(self); + } + i += 2 + data_size; + } +} + +void displayio_epaperdisplay_start_refresh(displayio_epaperdisplay_obj_t* self) { + // run start sequence + self->core.bus_reset(self->core.bus); + + send_command_sequence(self, true, self->start_sequence, self->start_sequence_len); + displayio_display_core_start_refresh(&self->core); +} + +uint32_t common_hal_displayio_epaperdisplay_get_time_to_refresh(displayio_epaperdisplay_obj_t* self) { + if (self->core.last_refresh == 0) { + return 0; + } + // Refresh at seconds per frame rate. + uint32_t elapsed_time = ticks_ms - self->core.last_refresh; + if (elapsed_time > self->milliseconds_per_frame) { + return 0; + } + return self->milliseconds_per_frame - elapsed_time; +} + +void displayio_epaperdisplay_finish_refresh(displayio_epaperdisplay_obj_t* self) { + // Actually refresh the display now that all pixel RAM has been updated. + displayio_display_core_begin_transaction(&self->core); + self->core.send(self->core.bus, DISPLAY_COMMAND, self->chip_select, &self->refresh_display_command, 1); + displayio_display_core_end_transaction(&self->core); + self->refreshing = true; + + displayio_display_core_finish_refresh(&self->core); +} + +mp_obj_t common_hal_displayio_epaperdisplay_get_bus(displayio_epaperdisplay_obj_t* self) { + return self->core.bus; +} + +bool displayio_epaperdisplay_refresh_area(displayio_epaperdisplay_obj_t* self, const displayio_area_t* area) { + uint16_t buffer_size = 128; // In uint32_ts + + displayio_area_t clipped; + // Clip the area to the display by overlapping the areas. If there is no overlap then we're done. + if (!displayio_display_core_clip_area(&self->core, area, &clipped)) { + return true; + } + uint16_t subrectangles = 1; + uint16_t rows_per_buffer = displayio_area_height(&clipped); + uint8_t pixels_per_word = (sizeof(uint32_t) * 8) / self->core.colorspace.depth; + uint16_t pixels_per_buffer = displayio_area_size(&clipped); + if (displayio_area_size(&clipped) > buffer_size * pixels_per_word) { + rows_per_buffer = buffer_size * pixels_per_word / displayio_area_width(&clipped); + if (rows_per_buffer == 0) { + rows_per_buffer = 1; + } + subrectangles = displayio_area_height(&clipped) / rows_per_buffer; + if (displayio_area_height(&clipped) % rows_per_buffer != 0) { + subrectangles++; + } + pixels_per_buffer = rows_per_buffer * displayio_area_width(&clipped); + buffer_size = pixels_per_buffer / pixels_per_word; + if (pixels_per_buffer % pixels_per_word) { + buffer_size += 1; + } + } + + // Allocated and shared as a uint32_t array so the compiler knows the + // alignment everywhere. + uint32_t buffer[buffer_size]; + volatile uint32_t mask_length = (pixels_per_buffer / 32) + 1; + uint32_t mask[mask_length]; + + uint8_t passes = 1; + if (self->core.colorspace.tricolor) { + passes = 2; + } + for (uint8_t pass = 0; pass < passes; pass++) { + uint16_t remaining_rows = displayio_area_height(&clipped); + + if (self->set_row_window_command != NO_COMMAND) { + displayio_display_core_set_region_to_update(&self->core, self->set_column_window_command, self->set_row_window_command, self->set_current_column_command, self->set_current_row_command, false, self->chip_select, &clipped); + } + + uint8_t write_command = self->write_black_ram_command; + if (pass == 1) { + write_command = self->write_color_ram_command; + } + displayio_display_core_begin_transaction(&self->core); + self->core.send(self->core.bus, DISPLAY_COMMAND, self->chip_select, &write_command, 1); + displayio_display_core_end_transaction(&self->core); + + for (uint16_t j = 0; j < subrectangles; j++) { + displayio_area_t subrectangle = { + .x1 = clipped.x1, + .y1 = clipped.y1 + rows_per_buffer * j, + .x2 = clipped.x2, + .y2 = clipped.y1 + rows_per_buffer * (j + 1) + }; + if (remaining_rows < rows_per_buffer) { + subrectangle.y2 = subrectangle.y1 + remaining_rows; + } + remaining_rows -= rows_per_buffer; + + + uint16_t subrectangle_size_bytes = displayio_area_size(&subrectangle) / (8 / self->core.colorspace.depth); + + memset(mask, 0, mask_length * sizeof(mask[0])); + memset(buffer, 0, buffer_size * sizeof(buffer[0])); + + self->core.colorspace.grayscale = true; + if (pass == 1) { + self->core.colorspace.grayscale = false; + } + displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer); + + // Invert it all. + if ((pass == 1 && self->color_bits_inverted) || + (pass == 0 && self->black_bits_inverted)) { + for (uint16_t k = 0; k < buffer_size; k++) { + buffer[k] = ~buffer[k]; + } + } + + if (!displayio_display_core_begin_transaction(&self->core)) { + // Can't acquire display bus; skip the rest of the data. Try next display. + return false; + } + self->core.send(self->core.bus, DISPLAY_DATA, self->chip_select, (uint8_t*) buffer, subrectangle_size_bytes); + displayio_display_core_end_transaction(&self->core); + + // TODO(tannewt): Make refresh displays faster so we don't starve other + // background tasks. + usb_background(); + } + } + + return true; +} + +bool common_hal_displayio_epaperdisplay_refresh(displayio_epaperdisplay_obj_t* self) { + + if (self->refreshing && self->busy.base.type == &digitalio_digitalinout_type) { + if (common_hal_digitalio_digitalinout_get_value(&self->busy) != self->busy_state) { + self->refreshing = false; + // Run stop sequence but don't wait for busy because busy is set when sleeping. + send_command_sequence(self, false, self->stop_sequence, self->stop_sequence_len); + } else { + return false; + } + } + if (self->core.current_group == NULL) { + return true; + } + // Refresh at seconds per frame rate. + if (common_hal_displayio_epaperdisplay_get_time_to_refresh(self) > 0) { + return false; + } + if (!displayio_display_core_bus_free(&self->core)) { + // Can't acquire display bus; skip updating this display. Try next display. + return false; + } + const displayio_area_t* current_area = displayio_epaperdisplay_get_refresh_areas(self); + if (current_area == NULL) { + return true; + } + displayio_epaperdisplay_start_refresh(self); + while (current_area != NULL) { + displayio_epaperdisplay_refresh_area(self, current_area); + current_area = current_area->next; + } + displayio_epaperdisplay_finish_refresh(self); + return true; +} + +void displayio_epaperdisplay_background(displayio_epaperdisplay_obj_t* self) { + if (self->refreshing) { + bool refresh_done = false; + if (self->busy.base.type == &digitalio_digitalinout_type) { + bool busy = common_hal_digitalio_digitalinout_get_value(&self->busy); + refresh_done = busy != self->busy_state; + } else { + refresh_done = ticks_ms - self->core.last_refresh > self->refresh_time; + } + if (refresh_done) { + self->refreshing = false; + // Run stop sequence but don't wait for busy because busy is set when sleeping. + send_command_sequence(self, false, self->stop_sequence, self->stop_sequence_len); + } + } +} + +void release_epaperdisplay(displayio_epaperdisplay_obj_t* self) { + if (self->refreshing) { + wait_for_busy(self); + self->refreshing = false; + // Run stop sequence but don't wait for busy because busy is set when sleeping. + send_command_sequence(self, false, self->stop_sequence, self->stop_sequence_len); + } + + release_display_core(&self->core); + if (self->busy.base.type == &digitalio_digitalinout_type) { + common_hal_digitalio_digitalinout_deinit(&self->busy); + } +} + +void displayio_epaperdisplay_collect_ptrs(displayio_epaperdisplay_obj_t* self) { + displayio_display_core_collect_ptrs(&self->core); +} + +bool maybe_refresh_epaperdisplay(void) { + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].epaper_display.base.type != &displayio_epaperdisplay_type || + displays[i].epaper_display.core.current_group != &circuitpython_splash) { + // Skip regular displays and those not showing the splash. + continue; + } + displayio_epaperdisplay_obj_t* display = &displays[i].epaper_display; + if (common_hal_displayio_epaperdisplay_get_time_to_refresh(display) != 0) { + return false; + } + return common_hal_displayio_epaperdisplay_refresh(display); + } + // Return true if no ePaper displays are available to pretend it was updated. + return true; +} diff --git a/shared-module/displayio/EPaperDisplay.h b/shared-module/displayio/EPaperDisplay.h new file mode 100644 index 00000000000..d08bed54626 --- /dev/null +++ b/shared-module/displayio/EPaperDisplay.h @@ -0,0 +1,68 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_EPAPERDISPLAY_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_EPAPERDISPLAY_H + +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/pulseio/PWMOut.h" + +#include "shared-module/displayio/area.h" +#include "shared-module/displayio/display_core.h" + +typedef struct { + mp_obj_base_t base; + displayio_display_core_t core; + digitalio_digitalinout_obj_t busy; + uint32_t milliseconds_per_frame; + uint8_t* start_sequence; + uint32_t start_sequence_len; + uint8_t* stop_sequence; + uint32_t stop_sequence_len; + uint16_t refresh_time; + uint16_t set_column_window_command; + uint16_t set_row_window_command; + uint16_t set_current_column_command; + uint16_t set_current_row_command; + uint16_t write_black_ram_command; + uint16_t write_color_ram_command; + uint8_t refresh_display_command; + uint8_t hue; + bool busy_state; + bool black_bits_inverted; + bool color_bits_inverted; + bool refreshing; + display_chip_select_behavior_t chip_select; +} displayio_epaperdisplay_obj_t; + +void displayio_epaperdisplay_background(displayio_epaperdisplay_obj_t* self); +void release_epaperdisplay(displayio_epaperdisplay_obj_t* self); +bool maybe_refresh_epaperdisplay(void); + +void displayio_epaperdisplay_collect_ptrs(displayio_epaperdisplay_obj_t* self); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_EPAPERDISPLAY_H diff --git a/shared-module/displayio/FourWire.c b/shared-module/displayio/FourWire.c new file mode 100644 index 00000000000..fcc4c1a20a7 --- /dev/null +++ b/shared-module/displayio/FourWire.c @@ -0,0 +1,135 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/FourWire.h" + +#include + +#include "py/gc.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/time/__init__.h" +#include "shared-module/displayio/display_core.h" + +#include "tick.h" + +void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, + busio_spi_obj_t* spi, const mcu_pin_obj_t* command, + const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, uint32_t baudrate) { + + self->bus = spi; + common_hal_busio_spi_never_reset(self->bus); + // Our object is statically allocated off the heap so make sure the bus object lives to the end + // of the heap as well. + gc_never_free(self->bus); + + self->frequency = baudrate; + self->polarity = common_hal_busio_spi_get_polarity(spi); + self->phase = common_hal_busio_spi_get_phase(spi); + + common_hal_digitalio_digitalinout_construct(&self->command, command); + common_hal_digitalio_digitalinout_switch_to_output(&self->command, true, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); + common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL); + + self->reset.base.type = &mp_type_NoneType; + if (reset != NULL) { + self->reset.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->reset, reset); + common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); + never_reset_pin_number(reset->number); + common_hal_displayio_fourwire_reset(self); + } + + never_reset_pin_number(command->number); + never_reset_pin_number(chip_select->number); +} + +void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self) { + if (self->bus == &self->inline_bus) { + common_hal_busio_spi_deinit(self->bus); + } + + reset_pin_number(self->command.pin->number); + reset_pin_number(self->chip_select.pin->number); + reset_pin_number(self->reset.pin->number); +} + +bool common_hal_displayio_fourwire_reset(mp_obj_t obj) { + displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); + if (self->reset.base.type == &mp_type_NoneType) { + return false; + } + common_hal_digitalio_digitalinout_set_value(&self->reset, false); + common_hal_time_delay_ms(1); + common_hal_digitalio_digitalinout_set_value(&self->reset, true); + common_hal_time_delay_ms(1); + return true; +} + +bool common_hal_displayio_fourwire_bus_free(mp_obj_t obj) { + displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); + if (!common_hal_busio_spi_try_lock(self->bus)) { + return false; + } + common_hal_busio_spi_unlock(self->bus); + return true; +} + +bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t obj) { + displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); + if (!common_hal_busio_spi_try_lock(self->bus)) { + return false; + } + common_hal_busio_spi_configure(self->bus, self->frequency, self->polarity, + self->phase, 8); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); + return true; +} + +void common_hal_displayio_fourwire_send(mp_obj_t obj, display_byte_type_t data_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length) { + displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->command, data_type == DISPLAY_DATA); + if (chip_select == CHIP_SELECT_TOGGLE_EVERY_BYTE) { + // Toggle chip select after each command byte in case the display driver + // IC latches commands based on it. + for (size_t i = 0; i < data_length; i++) { + common_hal_busio_spi_write(self->bus, &data[i], 1); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); + common_hal_mcu_delay_us(1); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); + } + } else { + common_hal_busio_spi_write(self->bus, data, data_length); + } +} + +void common_hal_displayio_fourwire_end_transaction(mp_obj_t obj) { + displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); + common_hal_busio_spi_unlock(self->bus); +} diff --git a/shared-module/displayio/FourWire.h b/shared-module/displayio/FourWire.h new file mode 100644 index 00000000000..a4260a3ac50 --- /dev/null +++ b/shared-module/displayio/FourWire.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_FOURWIRE_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_FOURWIRE_H + +#include "common-hal/busio/SPI.h" +#include "common-hal/digitalio/DigitalInOut.h" +#include "shared-module/displayio/Group.h" + +typedef struct { + mp_obj_base_t base; + busio_spi_obj_t* bus; + busio_spi_obj_t inline_bus; + digitalio_digitalinout_obj_t command; + digitalio_digitalinout_obj_t chip_select; + digitalio_digitalinout_obj_t reset; + uint32_t frequency; + uint8_t polarity; + uint8_t phase; +} displayio_fourwire_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_FOURWIRE_H diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c new file mode 100644 index 00000000000..38418a02996 --- /dev/null +++ b/shared-module/displayio/Group.c @@ -0,0 +1,322 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/Group.h" + +#include "py/runtime.h" +#include "shared-bindings/displayio/TileGrid.h" + +void common_hal_displayio_group_construct(displayio_group_t* self, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y) { + displayio_group_child_t* children = m_new(displayio_group_child_t, max_size); + displayio_group_construct(self, children, max_size, scale, x, y); +} + +uint32_t common_hal_displayio_group_get_scale(displayio_group_t* self) { + return self->scale; +} + +bool displayio_group_get_previous_area(displayio_group_t *self, displayio_area_t* area) { + bool first = true; + for (size_t i = 0; i < self->size; i++) { + mp_obj_t layer = self->children[i].native; + displayio_area_t layer_area; + if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + if (!displayio_tilegrid_get_previous_area(layer, &layer_area)) { + continue; + } + } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + if (!displayio_group_get_previous_area(layer, &layer_area)) { + continue; + } + } + if (first) { + displayio_area_copy(&layer_area, area); + first = false; + } else { + displayio_area_expand(area, &layer_area); + } + } + if (self->item_removed) { + if (first) { + displayio_area_copy(&self->dirty_area, area); + first = false; + } else { + displayio_area_expand(area, &self->dirty_area); + } + } + return !first; +} + +static void _update_child_transforms(displayio_group_t* self) { + if (!self->in_group) { + return; + } + for (size_t i = 0; i < self->size; i++) { + mp_obj_t layer = self->children[i].native; + if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + displayio_tilegrid_update_transform(layer, &self->absolute_transform); + } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + displayio_group_update_transform(layer, &self->absolute_transform); + } + } +} + +void displayio_group_update_transform(displayio_group_t *self, + const displayio_buffer_transform_t* parent_transform) { + self->in_group = parent_transform != NULL; + if (self->in_group) { + int16_t x = self->x; + int16_t y = self->y; + if (parent_transform->transpose_xy) { + x = y; + y = self->x; + } + self->absolute_transform.x = parent_transform->x + parent_transform->dx * x; + self->absolute_transform.y = parent_transform->y + parent_transform->dy * y; + self->absolute_transform.dx = parent_transform->dx * self->scale; + self->absolute_transform.dy = parent_transform->dy * self->scale; + self->absolute_transform.transpose_xy = parent_transform->transpose_xy; + self->absolute_transform.mirror_x = parent_transform->mirror_x; + self->absolute_transform.mirror_y = parent_transform->mirror_y; + + self->absolute_transform.scale = parent_transform->scale * self->scale; + } + _update_child_transforms(self); +} + +void common_hal_displayio_group_set_scale(displayio_group_t* self, uint32_t scale) { + if (self->scale == scale) { + return; + } + uint8_t parent_scale = self->absolute_transform.scale / self->scale; + self->absolute_transform.dx = self->absolute_transform.dx / self->scale * scale; + self->absolute_transform.dy = self->absolute_transform.dy / self->scale * scale; + self->absolute_transform.scale = parent_scale * scale; + self->scale = scale; + _update_child_transforms(self); +} + +mp_int_t common_hal_displayio_group_get_x(displayio_group_t* self) { + return self->x; +} + +void common_hal_displayio_group_set_x(displayio_group_t* self, mp_int_t x) { + if (self->x == x) { + return; + } + if (self->absolute_transform.transpose_xy) { + int16_t dy = self->absolute_transform.dy / self->scale; + self->absolute_transform.y += dy * (x - self->x); + } else { + int16_t dx = self->absolute_transform.dx / self->scale; + self->absolute_transform.x += dx * (x - self->x); + } + + self->x = x; + _update_child_transforms(self); +} + +mp_int_t common_hal_displayio_group_get_y(displayio_group_t* self) { + return self->y; +} + +void common_hal_displayio_group_set_y(displayio_group_t* self, mp_int_t y) { + if (self->y == y) { + return; + } + if (self->absolute_transform.transpose_xy) { + int8_t dx = self->absolute_transform.dx / self->scale; + self->absolute_transform.x += dx * (y - self->y); + } else { + int8_t dy = self->absolute_transform.dy / self->scale; + self->absolute_transform.y += dy * (y - self->y); + } + self->y = y; + _update_child_transforms(self); +} + +static mp_obj_t _add_layer(displayio_group_t* self, mp_obj_t layer) { + mp_obj_t native_layer = mp_instance_cast_to_native_base(layer, &displayio_group_type); + if (native_layer == MP_OBJ_NULL) { + native_layer = mp_instance_cast_to_native_base(layer, &displayio_tilegrid_type); + if (native_layer == MP_OBJ_NULL) { + mp_raise_ValueError(translate("Layer must be a Group or TileGrid subclass.")); + } + displayio_tilegrid_t* tilegrid = native_layer; + if (tilegrid->in_group) { + mp_raise_ValueError(translate("Layer already in a group.")); + } else { + tilegrid->in_group = true; + } + displayio_tilegrid_update_transform(tilegrid, &self->absolute_transform); + } else { + displayio_group_t* group = native_layer; + if (group->in_group) { + mp_raise_ValueError(translate("Layer already in a group.")); + } else { + group->in_group = true; + } + displayio_group_update_transform(group, &self->absolute_transform); + } + return native_layer; +} + +static void _remove_layer(displayio_group_t* self, size_t index) { + mp_obj_t layer = self->children[index].native; + displayio_area_t layer_area; + bool rendered_last_frame = false; + if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + displayio_tilegrid_t* tilegrid = layer; + rendered_last_frame = displayio_tilegrid_get_previous_area(tilegrid, &layer_area); + displayio_tilegrid_update_transform(tilegrid, NULL); + } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + displayio_group_t* group = layer; + rendered_last_frame = displayio_group_get_previous_area(group, &layer_area); + displayio_group_update_transform(group, NULL); + } + if (!rendered_last_frame) { + return; + } + if (!self->item_removed) { + displayio_area_copy(&layer_area, &self->dirty_area); + } else { + displayio_area_expand(&self->dirty_area, &layer_area); + } + self->item_removed = true; +} + +void common_hal_displayio_group_insert(displayio_group_t* self, size_t index, mp_obj_t layer) { + if (self->size == self->max_size) { + mp_raise_RuntimeError(translate("Group full")); + } + mp_obj_t native_layer = _add_layer(self, layer); + // Shift everything right. + for (size_t i = self->size; i > index; i--) { + self->children[i] = self->children[i - 1]; + } + self->children[index].native = native_layer; + self->children[index].original = layer; + self->size++; +} + +mp_obj_t common_hal_displayio_group_pop(displayio_group_t* self, size_t index) { + self->size--; + mp_obj_t item = self->children[index].original; + _remove_layer(self, index); + + // Shift everything left. + for (size_t i = index; i < self->size; i++) { + self->children[i] = self->children[i + 1]; + } + self->children[self->size].native = NULL; + self->children[self->size].original = NULL; + return item; +} + +mp_int_t common_hal_displayio_group_index(displayio_group_t* self, mp_obj_t layer) { + for (size_t i = 0; i < self->size; i++) { + if (self->children[i].original == layer) { + return i; + } + } + return -1; +} + +size_t common_hal_displayio_group_get_len(displayio_group_t* self) { + return self->size; +} + +mp_obj_t common_hal_displayio_group_get(displayio_group_t* self, size_t index) { + return self->children[index].original; +} + +void common_hal_displayio_group_set(displayio_group_t* self, size_t index, mp_obj_t layer) { + mp_obj_t native_layer = _add_layer(self, layer); + _remove_layer(self, index); + self->children[index].native = native_layer; + self->children[index].original = layer; +} + +void displayio_group_construct(displayio_group_t* self, displayio_group_child_t* child_array, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y) { + self->x = x; + self->y = y; + self->children = child_array; + self->max_size = max_size; + self->item_removed = false; + self->scale = scale; + self->in_group = false; +} + +bool displayio_group_fill_area(displayio_group_t *self, const _displayio_colorspace_t* colorspace, const displayio_area_t* area, uint32_t* mask, uint32_t* buffer) { + // Track if any of the layers finishes filling in the given area. We can ignore any remaining + // layers at that point. + bool full_coverage = false; + for (int32_t i = self->size - 1; i >= 0 ; i--) { + mp_obj_t layer = self->children[i].native; + if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + if (displayio_tilegrid_fill_area(layer, colorspace, area, mask, buffer)) { + full_coverage = true; + break; + } + } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + if (displayio_group_fill_area(layer, colorspace, area, mask, buffer)) { + full_coverage = true; + break; + } + } + } + return full_coverage; +} + +void displayio_group_finish_refresh(displayio_group_t *self) { + self->item_removed = false; + for (int32_t i = self->size - 1; i >= 0 ; i--) { + mp_obj_t layer = self->children[i].native; + if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + displayio_tilegrid_finish_refresh(layer); + } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + displayio_group_finish_refresh(layer); + } + } +} + +displayio_area_t* displayio_group_get_refresh_areas(displayio_group_t *self, displayio_area_t* tail) { + if (self->item_removed) { + self->dirty_area.next = tail; + tail = &self->dirty_area; + } + + for (int32_t i = self->size - 1; i >= 0 ; i--) { + mp_obj_t layer = self->children[i].native; + if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + tail = displayio_tilegrid_get_refresh_areas(layer, tail); + } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + tail = displayio_group_get_refresh_areas(layer, tail); + } + } + + return tail; +} diff --git a/shared-module/displayio/Group.h b/shared-module/displayio/Group.h new file mode 100644 index 00000000000..4e2308e5653 --- /dev/null +++ b/shared-module/displayio/Group.h @@ -0,0 +1,63 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_GROUP_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_GROUP_H + +#include +#include + +#include "py/obj.h" +#include "shared-module/displayio/area.h" +#include "shared-module/displayio/Palette.h" + +typedef struct { + mp_obj_t native; + mp_obj_t original; +} displayio_group_child_t; + +typedef struct { + mp_obj_base_t base; + displayio_group_child_t* children; + int16_t x; + int16_t y; + uint16_t scale; + uint16_t size; + uint16_t max_size; + bool item_removed; + bool in_group; + displayio_buffer_transform_t absolute_transform; + displayio_area_t dirty_area; // Catch all for changed area +} displayio_group_t; + +void displayio_group_construct(displayio_group_t* self, displayio_group_child_t* child_array, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y); +bool displayio_group_get_previous_area(displayio_group_t *group, displayio_area_t* area); +bool displayio_group_fill_area(displayio_group_t *group, const _displayio_colorspace_t* colorspace, const displayio_area_t* area, uint32_t* mask, uint32_t *buffer); +void displayio_group_update_transform(displayio_group_t *group, const displayio_buffer_transform_t* parent_transform); +void displayio_group_finish_refresh(displayio_group_t *self); +displayio_area_t* displayio_group_get_refresh_areas(displayio_group_t *self, displayio_area_t* tail); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_GROUP_H diff --git a/shared-module/displayio/I2CDisplay.c b/shared-module/displayio/I2CDisplay.c new file mode 100644 index 00000000000..87261dca00e --- /dev/null +++ b/shared-module/displayio/I2CDisplay.c @@ -0,0 +1,121 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/I2CDisplay.h" + +#include +#include + +#include "py/gc.h" +#include "py/runtime.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/time/__init__.h" +#include "shared-module/displayio/display_core.h" + +#include "tick.h" + +void common_hal_displayio_i2cdisplay_construct(displayio_i2cdisplay_obj_t* self, + busio_i2c_obj_t* i2c, uint16_t device_address, const mcu_pin_obj_t* reset) { + + // Probe the bus to see if a device acknowledges the given address. + if (!common_hal_busio_i2c_probe(i2c, device_address)) { + mp_raise_ValueError_varg(translate("Unable to find I2C Display at %x"), device_address); + } + + // Write to the device and return 0 on success or an appropriate error code from mperrno.h + self->bus = i2c; + common_hal_busio_i2c_never_reset(self->bus); + // Our object is statically allocated off the heap so make sure the bus object lives to the end + // of the heap as well. + gc_never_free(self->bus); + + self->address = device_address; + + self->reset.base.type = &mp_type_NoneType; + if (reset != NULL) { + self->reset.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->reset, reset); + common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); + never_reset_pin_number(reset->number); + common_hal_displayio_i2cdisplay_reset(self); + } +} + +void common_hal_displayio_i2cdisplay_deinit(displayio_i2cdisplay_obj_t* self) { + if (self->bus == &self->inline_bus) { + common_hal_busio_i2c_deinit(self->bus); + } + + reset_pin_number(self->reset.pin->number); +} + +bool common_hal_displayio_i2cdisplay_reset(mp_obj_t obj) { + displayio_i2cdisplay_obj_t* self = MP_OBJ_TO_PTR(obj); + if (self->reset.base.type == &mp_type_NoneType) { + return false; + } + + common_hal_digitalio_digitalinout_set_value(&self->reset, false); + common_hal_mcu_delay_us(4); + common_hal_digitalio_digitalinout_set_value(&self->reset, true); + return true; +} + +bool common_hal_displayio_i2cdisplay_bus_free(mp_obj_t obj) { + displayio_i2cdisplay_obj_t* self = MP_OBJ_TO_PTR(obj); + if (!common_hal_busio_i2c_try_lock(self->bus)) { + return false; + } + return true; +} + +bool common_hal_displayio_i2cdisplay_begin_transaction(mp_obj_t obj) { + return common_hal_displayio_i2cdisplay_bus_free(obj); +} + +void common_hal_displayio_i2cdisplay_send(mp_obj_t obj, display_byte_type_t data_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length) { + displayio_i2cdisplay_obj_t* self = MP_OBJ_TO_PTR(obj); + if (data_type == DISPLAY_COMMAND) { + uint8_t command_bytes[2 * data_length]; + for (uint32_t i = 0; i < data_length; i++) { + command_bytes[2 * i] = 0x80; + command_bytes[2 * i + 1] = data[i]; + } + common_hal_busio_i2c_write(self->bus, self->address, command_bytes, 2 * data_length, true); + } else { + uint8_t data_bytes[data_length + 1]; + data_bytes[0] = 0x40; + memcpy(data_bytes + 1, data, data_length); + common_hal_busio_i2c_write(self->bus, self->address, data_bytes, data_length + 1, true); + } +} + +void common_hal_displayio_i2cdisplay_end_transaction(mp_obj_t obj) { + displayio_i2cdisplay_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_busio_i2c_unlock(self->bus); +} diff --git a/shared-module/displayio/I2CDisplay.h b/shared-module/displayio/I2CDisplay.h new file mode 100644 index 00000000000..4636c3f73a4 --- /dev/null +++ b/shared-module/displayio/I2CDisplay.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_I2CDISPLAY_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_I2CDISPLAY_H + +#include "common-hal/busio/I2C.h" +#include "common-hal/digitalio/DigitalInOut.h" + +typedef struct { + mp_obj_base_t base; + busio_i2c_obj_t* bus; + busio_i2c_obj_t inline_bus; + digitalio_digitalinout_obj_t reset; + uint16_t address; +} displayio_i2cdisplay_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_I2CDISPLAY_H diff --git a/shared-module/displayio/OnDiskBitmap.c b/shared-module/displayio/OnDiskBitmap.c new file mode 100644 index 00000000000..993fc03de62 --- /dev/null +++ b/shared-module/displayio/OnDiskBitmap.c @@ -0,0 +1,184 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/OnDiskBitmap.h" + +#include + +#include "py/mperrno.h" +#include "py/runtime.h" + +static uint32_t read_word(uint16_t* bmp_header, uint16_t index) { + return bmp_header[index] | bmp_header[index + 1] << 16; +} + +void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self, pyb_file_obj_t* file) { + // Load the wave + self->file = file; + uint16_t bmp_header[69]; + f_rewind(&self->file->fp); + UINT bytes_read; + if (f_read(&self->file->fp, bmp_header, 138, &bytes_read) != FR_OK) { + mp_raise_OSError(MP_EIO); + } + if (bytes_read != 138 || + memcmp(bmp_header, "BM", 2) != 0) { + mp_raise_ValueError(translate("Invalid BMP file")); + } + + // We can't cast because we're not aligned. + self->data_offset = read_word(bmp_header, 5); + + uint32_t header_size = read_word(bmp_header, 7); + uint16_t bits_per_pixel = bmp_header[14]; + uint32_t compression = read_word(bmp_header, 15); + uint32_t number_of_colors = read_word(bmp_header, 23); + + bool indexed = ((bits_per_pixel <= 8) && (number_of_colors != 0)); + self->bitfield_compressed = (compression == 3); + self->bits_per_pixel = bits_per_pixel; + self->width = read_word(bmp_header, 9); + self->height = read_word(bmp_header, 11); + + if (bits_per_pixel == 16){ + if (((header_size >= 56)) || (self->bitfield_compressed)) { + self->r_bitmask = read_word(bmp_header, 27); + self->g_bitmask = read_word(bmp_header, 29); + self->b_bitmask = read_word(bmp_header, 31); + + } else { // no compression or short header means 5:5:5 + self->r_bitmask = 0x7c00; + self->g_bitmask = 0x3e0; + self->b_bitmask = 0x1f; + } + } else if (indexed && self->bits_per_pixel != 1) { + uint16_t palette_size = number_of_colors * sizeof(uint32_t); + uint16_t palette_offset = 0xe + header_size; + + self->palette_data = m_malloc(palette_size, false); + + f_rewind(&self->file->fp); + f_lseek(&self->file->fp, palette_offset); + + UINT palette_bytes_read; + if (f_read(&self->file->fp, self->palette_data, palette_size, &palette_bytes_read) != FR_OK) { + mp_raise_OSError(MP_EIO); + } + if (palette_bytes_read != palette_size) { + mp_raise_ValueError(translate("Unable to read color palette data")); + } + } else if (!(header_size == 12 || header_size == 40 || header_size == 108 || header_size == 124)) { + mp_raise_ValueError_varg(translate("Only Windows format, uncompressed BMP supported: given header size is %d"), header_size); + } + + if (bits_per_pixel == 8 && number_of_colors == 0) { + mp_raise_ValueError_varg(translate("Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: %d bpp given"), bits_per_pixel); + } + + uint8_t bytes_per_pixel = (self->bits_per_pixel / 8) ? (self->bits_per_pixel /8) : 1; + uint8_t pixels_per_byte = 8 / self->bits_per_pixel; + if (pixels_per_byte == 0){ + self->stride = (self->width * bytes_per_pixel); + // Rows are word aligned. + if (self->stride % 4 != 0) { + self->stride += 4 - self->stride % 4; + } + } else { + uint32_t bit_stride = self->width * self->bits_per_pixel; + if (bit_stride % 32 != 0) { + bit_stride += 32 - bit_stride % 32; + } + self->stride = (bit_stride / 8); + } + +} + + +uint32_t common_hal_displayio_ondiskbitmap_get_pixel(displayio_ondiskbitmap_t *self, + int16_t x, int16_t y) { + if (x < 0 || x >= self->width || y < 0 || y >= self->height) { + return 0; + } + + uint32_t location; + uint8_t bytes_per_pixel = (self->bits_per_pixel / 8) ? (self->bits_per_pixel /8) : 1; + uint8_t pixels_per_byte = 8 / self->bits_per_pixel; + if (pixels_per_byte == 0){ + location = self->data_offset + (self->height - y - 1) * self->stride + x * bytes_per_pixel; + } else { + location = self->data_offset + (self->height - y - 1) * self->stride + x / pixels_per_byte; + } + // We don't cache here because the underlying FS caches sectors. + f_lseek(&self->file->fp, location); + UINT bytes_read; + uint32_t pixel_data = 0; + uint32_t result = f_read(&self->file->fp, &pixel_data, bytes_per_pixel, &bytes_read); + if (result == FR_OK) { + uint32_t tmp = 0; + uint8_t red; + uint8_t green; + uint8_t blue; + if (bytes_per_pixel == 1) { + uint8_t offset = (x % pixels_per_byte) * self->bits_per_pixel; + uint8_t mask = (1 << self->bits_per_pixel) - 1; + + uint8_t index = (pixel_data >> ((8 - self->bits_per_pixel) - offset)) & mask; + if (self->bits_per_pixel == 1) { + if (index == 1) { + return 0xFFFFFF; + } else { + return 0x000000; + } + } + return self->palette_data[index]; + } else if (bytes_per_pixel == 2) { + if (self->g_bitmask == 0x07e0) { // 565 + red =((pixel_data & self->r_bitmask) >>11); + green = ((pixel_data & self->g_bitmask) >>5); + blue = ((pixel_data & self->b_bitmask) >> 0); + } else { // 555 + red =((pixel_data & self->r_bitmask) >>10); + green = ((pixel_data & self->g_bitmask) >>4); + blue = ((pixel_data & self->b_bitmask) >> 0); + } + tmp = (red << 19 | green << 10 | blue << 3); + return tmp; + } else if ((bytes_per_pixel == 4) && (self->bitfield_compressed)) { + return pixel_data & 0x00FFFFFF; + } else { + return pixel_data; + } + } + return 0; +} + +uint16_t common_hal_displayio_ondiskbitmap_get_height(displayio_ondiskbitmap_t *self) { + return self->height; +} + +uint16_t common_hal_displayio_ondiskbitmap_get_width(displayio_ondiskbitmap_t *self) { + return self->width; +} diff --git a/shared-module/displayio/OnDiskBitmap.h b/shared-module/displayio/OnDiskBitmap.h new file mode 100644 index 00000000000..28426f11b87 --- /dev/null +++ b/shared-module/displayio/OnDiskBitmap.h @@ -0,0 +1,52 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_ONDISKBITMAP_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_ONDISKBITMAP_H + +#include +#include + +#include "py/obj.h" + +#include "extmod/vfs_fat.h" + +typedef struct { + mp_obj_base_t base; + uint16_t width; + uint16_t height; + uint16_t data_offset; + uint16_t stride; + uint32_t r_bitmask; + uint32_t g_bitmask; + uint32_t b_bitmask; + bool bitfield_compressed; + pyb_file_obj_t* file; + uint8_t bits_per_pixel; + uint32_t* palette_data; +} displayio_ondiskbitmap_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_ONDISKBITMAP_H diff --git a/shared-module/displayio/Palette.c b/shared-module/displayio/Palette.c new file mode 100644 index 00000000000..3bce86f4843 --- /dev/null +++ b/shared-module/displayio/Palette.c @@ -0,0 +1,98 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/Palette.h" + +#include "shared-module/displayio/ColorConverter.h" + +void common_hal_displayio_palette_construct(displayio_palette_t* self, uint16_t color_count) { + self->color_count = color_count; + self->colors = (_displayio_color_t *) m_malloc(color_count * sizeof(_displayio_color_t), false); +} + +void common_hal_displayio_palette_make_opaque(displayio_palette_t* self, uint32_t palette_index) { + self->colors[palette_index].transparent = false; +} + +void common_hal_displayio_palette_make_transparent(displayio_palette_t* self, uint32_t palette_index) { + self->colors[palette_index].transparent = true; +} + +uint32_t common_hal_displayio_palette_get_len(displayio_palette_t* self) { + return self->color_count; +} + +void common_hal_displayio_palette_set_color(displayio_palette_t* self, uint32_t palette_index, uint32_t color) { + if (self->colors[palette_index].rgb888 == color) { + return; + } + self->colors[palette_index].rgb888 = color; + self->colors[palette_index].luma = displayio_colorconverter_compute_luma(color); + self->colors[palette_index].rgb565 = displayio_colorconverter_compute_rgb565(color); + + uint8_t chroma = displayio_colorconverter_compute_chroma(color); + self->colors[palette_index].chroma = chroma; + self->colors[palette_index].hue = displayio_colorconverter_compute_hue(color); + self->needs_refresh = true; +} + +uint32_t common_hal_displayio_palette_get_color(displayio_palette_t* self, uint32_t palette_index) { + return self->colors[palette_index].rgb888; +} + +bool displayio_palette_get_color(displayio_palette_t *self, const _displayio_colorspace_t* colorspace, uint32_t palette_index, uint32_t* color) { + if (palette_index > self->color_count || self->colors[palette_index].transparent) { + return false; // returns opaque + } + + if (colorspace->tricolor) { + uint8_t luma = self->colors[palette_index].luma; + *color = luma >> (8 - colorspace->depth); + // Chroma 0 means the color is a gray and has no hue so never color based on it. + if (self->colors[palette_index].chroma <= 16) { + if (!colorspace->grayscale) { + *color = 0; + } + return true; + } + uint8_t pixel_hue = self->colors[palette_index].hue; + displayio_colorconverter_compute_tricolor(colorspace, pixel_hue, luma, color); + } else if (colorspace->grayscale) { + *color = self->colors[palette_index].luma >> (8 - colorspace->depth); + } else { + *color = self->colors[palette_index].rgb565; + } + + return true; +} + +bool displayio_palette_needs_refresh(displayio_palette_t *self) { + return self->needs_refresh; +} + +void displayio_palette_finish_refresh(displayio_palette_t *self) { + self->needs_refresh = false; +} diff --git a/shared-module/displayio/Palette.h b/shared-module/displayio/Palette.h new file mode 100644 index 00000000000..1cfdd199a50 --- /dev/null +++ b/shared-module/displayio/Palette.h @@ -0,0 +1,68 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_PALETTE_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_PALETTE_H + +#include +#include + +#include "py/obj.h" + +typedef struct { + uint8_t depth; + uint8_t bytes_per_cell; + uint8_t tricolor_hue; + uint8_t tricolor_luma; + bool grayscale; + bool tricolor; + bool pixels_in_byte_share_row; + bool reverse_pixels_in_byte; +} _displayio_colorspace_t; + +typedef struct { + uint32_t rgb888; + uint16_t rgb565; + uint8_t luma; + uint8_t hue; + uint8_t chroma; + bool transparent; // This may have additional bits added later for blending. +} _displayio_color_t; + +typedef struct { + mp_obj_base_t base; + _displayio_color_t* colors; + uint32_t color_count; + bool needs_refresh; +} displayio_palette_t; + +// Returns false if color fetch did not succeed (out of range or transparent). +// Returns true if color is opaque, and sets color. +bool displayio_palette_get_color(displayio_palette_t *palette, const _displayio_colorspace_t* colorspace, uint32_t palette_index, uint32_t* color); +bool displayio_palette_needs_refresh(displayio_palette_t *self); +void displayio_palette_finish_refresh(displayio_palette_t *self); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_PALLETE_H diff --git a/shared-module/displayio/Shape.c b/shared-module/displayio/Shape.c new file mode 100644 index 00000000000..ab9ca735bc4 --- /dev/null +++ b/shared-module/displayio/Shape.c @@ -0,0 +1,90 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/Shape.h" + +#include + +#include "py/runtime.h" + +void common_hal_displayio_shape_construct(displayio_shape_t *self, uint32_t width, + uint32_t height, bool mirror_x, bool mirror_y) { + self->mirror_x = mirror_x; + self->mirror_y = mirror_y; + self->width = width; + if (self->mirror_x) { + width /= 2; + width += self->width % 2 - 1; + } + self->half_width = width; + + self->height = height; + if (self->mirror_y) { + height /= 2; + height += self->height % 2 - 1; + } + self->half_height = height; + + self->data = m_malloc(height * sizeof(uint32_t), false); + for (uint16_t i = 0; i <= height; i++) { + self->data[2 * i] = 0; + self->data[2 * i + 1] = width; + } +} + +void common_hal_displayio_shape_set_boundary(displayio_shape_t *self, uint16_t y, uint16_t start_x, uint16_t end_x) { + if (y < 0 || y >= self->height || (self->mirror_y && y > self->half_height)) { + mp_raise_ValueError(translate("y value out of bounds")); + } + if (start_x < 0 || start_x > self->width || end_x < 0 || end_x > self->width) { + mp_raise_ValueError(translate("x value out of bounds")); + } + uint16_t half_width = self->width / 2 - 1 + self->width % 2; + if (self->mirror_x && (start_x > half_width || end_x > half_width)) { + mp_raise_ValueError_varg(translate("Maximum x value when mirrored is %d"), half_width); + } + self->data[2 * y] = start_x; + self->data[2 * y + 1] = end_x; +} + +uint32_t common_hal_displayio_shape_get_pixel(void *obj, int16_t x, int16_t y) { + displayio_shape_t *self = obj; + if (x >= self->width || x < 0 || y >= self->height || y < 0) { + return 0; + } + if (self->mirror_x && x > self->half_width) { + x = self->width - 1 - x; + } + if (self->mirror_y && y > self->half_height) { + y = self->height - y - 1; + } + uint16_t start_x = self->data[2 * y]; + uint16_t end_x = self->data[2 * y + 1]; + if (x < start_x || x > end_x) { + return 0; + } + return 1; +} diff --git a/shared-module/displayio/Shape.h b/shared-module/displayio/Shape.h new file mode 100644 index 00000000000..ca054fe0085 --- /dev/null +++ b/shared-module/displayio/Shape.h @@ -0,0 +1,46 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_SHAPE_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_SHAPE_H + +#include +#include + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint16_t width; + uint16_t height; + uint16_t half_width; + uint16_t half_height; + uint16_t* data; + bool mirror_x; + bool mirror_y; +} displayio_shape_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_SHAPE_H diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c new file mode 100644 index 00000000000..f34d2fc52d1 --- /dev/null +++ b/shared-module/displayio/TileGrid.c @@ -0,0 +1,549 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/TileGrid.h" + +#include "py/runtime.h" +#include "shared-bindings/displayio/Bitmap.h" +#include "shared-bindings/displayio/ColorConverter.h" +#include "shared-bindings/displayio/OnDiskBitmap.h" +#include "shared-bindings/displayio/Palette.h" +#include "shared-bindings/displayio/Shape.h" + +void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_t bitmap, + uint16_t bitmap_width_in_tiles, uint16_t bitmap_height_in_tiles, + mp_obj_t pixel_shader, uint16_t width, uint16_t height, + uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint8_t default_tile) { + uint32_t total_tiles = width * height; + // Sprites will only have one tile so save a little memory by inlining values in the pointer. + uint8_t inline_tiles = sizeof(uint8_t*); + if (total_tiles <= inline_tiles) { + self->tiles = 0; + // Pack values into the pointer since there are only a few. + for (uint32_t i = 0; i < inline_tiles; i++) { + ((uint8_t*) &self->tiles)[i] = default_tile; + } + self->inline_tiles = true; + } else { + self->tiles = (uint8_t*) m_malloc(total_tiles, false); + for (uint32_t i = 0; i < total_tiles; i++) { + self->tiles[i] = default_tile; + } + self->inline_tiles = false; + } + self->bitmap_width_in_tiles = bitmap_width_in_tiles; + self->tiles_in_bitmap = bitmap_width_in_tiles * bitmap_height_in_tiles; + self->width_in_tiles = width; + self->height_in_tiles = height; + self->x = x; + self->y = y; + self->pixel_width = width * tile_width; + self->pixel_height = height * tile_height; + self->tile_width = tile_width; + self->tile_height = tile_height; + self->bitmap = bitmap; + self->pixel_shader = pixel_shader; + self->in_group = false; + self->first_draw = true; + self->flip_x = false; + self->flip_y = false; + self->transpose_xy = false; +} + +bool displayio_tilegrid_get_previous_area(displayio_tilegrid_t *self, displayio_area_t* area) { + if (self->first_draw) { + return false; + } + displayio_area_copy(&self->previous_area, area); + return true; +} + +void _update_current_x(displayio_tilegrid_t *self) { + int16_t width; + if (self->transpose_xy) { + width = self->pixel_height; + } else { + width = self->pixel_width; + } + if (self->absolute_transform->transpose_xy) { + self->current_area.y1 = self->absolute_transform->y + self->absolute_transform->dy * self->x; + self->current_area.y2 = self->absolute_transform->y + self->absolute_transform->dy * (self->x + width); + if (self->current_area.y2 < self->current_area.y1) { + int16_t temp = self->current_area.y2; + self->current_area.y2 = self->current_area.y1; + self->current_area.y1 = temp; + } + } else { + self->current_area.x1 = self->absolute_transform->x + self->absolute_transform->dx * self->x; + self->current_area.x2 = self->absolute_transform->x + self->absolute_transform->dx * (self->x + width); + if (self->current_area.x2 < self->current_area.x1) { + int16_t temp = self->current_area.x2; + self->current_area.x2 = self->current_area.x1; + self->current_area.x1 = temp; + } + } +} + +void _update_current_y(displayio_tilegrid_t *self) { + int16_t height; + if (self->transpose_xy) { + height = self->pixel_width; + } else { + height = self->pixel_height; + } + if (self->absolute_transform->transpose_xy) { + self->current_area.x1 = self->absolute_transform->x + self->absolute_transform->dx * self->y; + self->current_area.x2 = self->absolute_transform->x + self->absolute_transform->dx * (self->y + height); + if (self->current_area.x2 < self->current_area.x1) { + int16_t temp = self->current_area.x2; + self->current_area.x2 = self->current_area.x1; + self->current_area.x1 = temp; + } + } else { + self->current_area.y1 = self->absolute_transform->y + self->absolute_transform->dy * self->y; + self->current_area.y2 = self->absolute_transform->y + self->absolute_transform->dy * (self->y + height); + if (self->current_area.y2 < self->current_area.y1) { + int16_t temp = self->current_area.y2; + self->current_area.y2 = self->current_area.y1; + self->current_area.y1 = temp; + } + } +} + +void displayio_tilegrid_update_transform(displayio_tilegrid_t *self, + const displayio_buffer_transform_t* absolute_transform) { + self->in_group = absolute_transform != NULL; + self->absolute_transform = absolute_transform; + if (absolute_transform != NULL) { + self->moved = !self->first_draw; + + _update_current_x(self); + _update_current_y(self); + } else { + self->first_draw = true; + } +} + +mp_int_t common_hal_displayio_tilegrid_get_x(displayio_tilegrid_t *self) { + return self->x; +} +void common_hal_displayio_tilegrid_set_x(displayio_tilegrid_t *self, mp_int_t x) { + if (self->x == x) { + return; + } + + self->moved = !self->first_draw; + + self->x = x; + if (self->absolute_transform != NULL) { + _update_current_x(self); + } +} +mp_int_t common_hal_displayio_tilegrid_get_y(displayio_tilegrid_t *self) { + return self->y; +} + +void common_hal_displayio_tilegrid_set_y(displayio_tilegrid_t *self, mp_int_t y) { + if (self->y == y) { + return; + } + self->moved = !self->first_draw; + self->y = y; + if (self->absolute_transform != NULL) { + _update_current_y(self); + } +} + +mp_obj_t common_hal_displayio_tilegrid_get_pixel_shader(displayio_tilegrid_t *self) { + return self->pixel_shader; +} + +void common_hal_displayio_tilegrid_set_pixel_shader(displayio_tilegrid_t *self, mp_obj_t pixel_shader) { + self->pixel_shader = pixel_shader; + self->full_change = true; +} + +uint16_t common_hal_displayio_tilegrid_get_width(displayio_tilegrid_t *self) { + return self->width_in_tiles; +} + +uint16_t common_hal_displayio_tilegrid_get_height(displayio_tilegrid_t *self) { + return self->height_in_tiles; +} + +uint8_t common_hal_displayio_tilegrid_get_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y) { + uint8_t* tiles = self->tiles; + if (self->inline_tiles) { + tiles = (uint8_t*) &self->tiles; + } + if (tiles == NULL) { + return 0; + } + return tiles[y * self->width_in_tiles + x]; +} + +void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint8_t tile_index) { + if (tile_index >= self->tiles_in_bitmap) { + mp_raise_ValueError(translate("Tile index out of bounds")); + } + uint8_t* tiles = self->tiles; + if (self->inline_tiles) { + tiles = (uint8_t*) &self->tiles; + } + if (tiles == NULL) { + return; + } + tiles[y * self->width_in_tiles + x] = tile_index; + displayio_area_t temp_area; + displayio_area_t* tile_area; + if (!self->partial_change) { + tile_area = &self->dirty_area; + } else { + tile_area = &temp_area; + } + int16_t tx = (x - self->top_left_x) % self->width_in_tiles; + if (tx < 0) { + tx += self->width_in_tiles; + } + tile_area->x1 = tx * self->tile_width; + tile_area->x2 = tile_area->x1 + self->tile_width; + int16_t ty = (y - self->top_left_y) % self->height_in_tiles; + if (ty < 0) { + ty += self->height_in_tiles; + } + tile_area->y1 = ty * self->tile_height; + tile_area->y2 = tile_area->y1 + self->tile_height; + + if (self->partial_change) { + displayio_area_expand(&self->dirty_area, &temp_area); + } + + self->partial_change = true; +} + +bool common_hal_displayio_tilegrid_get_flip_x(displayio_tilegrid_t *self) { + return self->flip_x; +} + +void common_hal_displayio_tilegrid_set_flip_x(displayio_tilegrid_t *self, bool flip_x) { + if (self->flip_x == flip_x) { + return; + } + self->flip_x = flip_x; + self->full_change = true; +} + +bool common_hal_displayio_tilegrid_get_flip_y(displayio_tilegrid_t *self) { + return self->flip_y; +} + +void common_hal_displayio_tilegrid_set_flip_y(displayio_tilegrid_t *self, bool flip_y) { + if (self->flip_y == flip_y) { + return; + } + self->flip_y = flip_y; + self->full_change = true; +} + +bool common_hal_displayio_tilegrid_get_transpose_xy(displayio_tilegrid_t *self) { + return self->transpose_xy; +} + +void common_hal_displayio_tilegrid_set_transpose_xy(displayio_tilegrid_t *self, bool transpose_xy) { + if (self->transpose_xy == transpose_xy) { + return; + } + self->transpose_xy = transpose_xy; + + // Square TileGrids do not change dimensions when transposed. + if (self->pixel_width == self->pixel_height) { + self->full_change = true; + return; + } + + _update_current_x(self); + _update_current_y(self); + + self->moved = true; +} + +void common_hal_displayio_tilegrid_set_top_left(displayio_tilegrid_t *self, uint16_t x, uint16_t y) { + self->top_left_x = x; + self->top_left_y = y; + self->full_change = true; +} + +bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const _displayio_colorspace_t* colorspace, const displayio_area_t* area, uint32_t* mask, uint32_t *buffer) { + // If no tiles are present we have no impact. + uint8_t* tiles = self->tiles; + if (self->inline_tiles) { + tiles = (uint8_t*) &self->tiles; + } + if (tiles == NULL) { + return false; + } + + displayio_area_t overlap; + if (!displayio_area_compute_overlap(area, &self->current_area, &overlap)) { + return false; + } + + int16_t x_stride = 1; + int16_t y_stride = displayio_area_width(area); + + bool flip_x = self->flip_x; + bool flip_y = self->flip_y; + if (self->transpose_xy != self->absolute_transform->transpose_xy) { + bool temp_flip = flip_x; + flip_x = flip_y; + flip_y = temp_flip; + } + + // How many pixels are outside of our area between us and the start of the row. + uint16_t start = 0; + if ((self->absolute_transform->dx < 0) != flip_x) { + start += (area->x2 - area->x1 - 1) * x_stride; + x_stride *= -1; + } + if ((self->absolute_transform->dy < 0) != flip_y) { + start += (area->y2 - area->y1 - 1) * y_stride; + y_stride *= -1; + } + + // Track if this layer finishes filling in the given area. We can ignore any remaining + // layers at that point. + bool full_coverage = displayio_area_equal(area, &overlap); + + // TODO(tannewt): Skip coverage tracking if all pixels outside the overlap have already been + // set and our palette is all opaque. + + // TODO(tannewt): Check to see if the pixel_shader has any transparency. If it doesn't then we + // can either return full coverage or bulk update the mask. + displayio_area_t transformed; + displayio_area_transform_within(flip_x != (self->absolute_transform->dx < 0), flip_y != (self->absolute_transform->dy < 0), self->transpose_xy != self->absolute_transform->transpose_xy, + &overlap, + &self->current_area, + &transformed); + + int16_t start_x = (transformed.x1 - self->current_area.x1); + int16_t end_x = (transformed.x2 - self->current_area.x1); + int16_t start_y = (transformed.y1 - self->current_area.y1); + int16_t end_y = (transformed.y2 - self->current_area.y1); + + int16_t y_shift = 0; + int16_t x_shift = 0; + if ((self->absolute_transform->dx < 0) != flip_x) { + x_shift = area->x2 - overlap.x2; + } else { + x_shift = overlap.x1 - area->x1; + } + if ((self->absolute_transform->dy < 0) != flip_y) { + y_shift = area->y2 - overlap.y2; + } else { + y_shift = overlap.y1 - area->y1; + } + + // This untransposes x and y so it aligns with bitmap rows. + if (self->transpose_xy != self->absolute_transform->transpose_xy) { + int16_t temp_stride = x_stride; + x_stride = y_stride; + y_stride = temp_stride; + int16_t temp_shift = x_shift; + x_shift = y_shift; + y_shift = temp_shift; + } + + uint8_t pixels_per_byte = 8 / colorspace->depth; + for (int16_t y = start_y; y < end_y; y++) { + int16_t row_start = start + (y - start_y + y_shift) * y_stride; // in pixels + int16_t local_y = y / self->absolute_transform->scale; + for (int16_t x = start_x; x < end_x; x++) { + // Compute the destination pixel in the buffer and mask based on the transformations. + int16_t offset = row_start + (x - start_x + x_shift) * x_stride; // in pixels + + // This is super useful for debugging out of range accesses. Uncomment to use. + // if (offset < 0 || offset >= (int32_t) displayio_area_size(area)) { + // asm("bkpt"); + // } + + // Check the mask first to see if the pixel has already been set. + if ((mask[offset / 32] & (1 << (offset % 32))) != 0) { + continue; + } + int16_t local_x = x / self->absolute_transform->scale; + uint16_t tile_location = ((local_y / self->tile_height + self->top_left_y) % self->height_in_tiles) * self->width_in_tiles + (local_x / self->tile_width + self->top_left_x) % self->width_in_tiles; + uint8_t tile = tiles[tile_location]; + uint16_t tile_x = (tile % self->bitmap_width_in_tiles) * self->tile_width + local_x % self->tile_width; + uint16_t tile_y = (tile / self->bitmap_width_in_tiles) * self->tile_height + local_y % self->tile_height; + + uint32_t value = 0; + // We always want to read bitmap pixels by row first and then transpose into the destination + // buffer because most bitmaps are row associated. + if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) { + value = common_hal_displayio_bitmap_get_pixel(self->bitmap, tile_x, tile_y); + } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) { + value = common_hal_displayio_shape_get_pixel(self->bitmap, tile_x, tile_y); + } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type)) { + value = common_hal_displayio_ondiskbitmap_get_pixel(self->bitmap, tile_x, tile_y); + } + + uint32_t pixel; + bool opaque = true; + if (self->pixel_shader == mp_const_none) { + pixel = value; + } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type)) { + opaque = displayio_palette_get_color(self->pixel_shader, colorspace, value, &pixel); + } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) { + opaque = displayio_colorconverter_convert(self->pixel_shader, colorspace, value, &pixel); + } + if (!opaque) { + // A pixel is transparent so we haven't fully covered the area ourselves. + full_coverage = false; + } else { + mask[offset / 32] |= 1 << (offset % 32); + if (colorspace->depth == 16) { + *(((uint16_t*) buffer) + offset) = pixel; + } else if (colorspace->depth == 8) { + *(((uint8_t*) buffer) + offset) = pixel; + } else if (colorspace->depth < 8) { + // Reorder the offsets to pack multiple rows into a byte (meaning they share a column). + if (!colorspace->pixels_in_byte_share_row) { + uint16_t width = displayio_area_width(area); + uint16_t row = offset / width; + uint16_t col = offset % width; + // Dividing by pixels_per_byte does truncated division even if we multiply it back out. + offset = col * pixels_per_byte + (row / pixels_per_byte) * pixels_per_byte * width + row % pixels_per_byte; + // Also useful for validating that the bitpacking worked correctly. + // if (offset > displayio_area_size(area)) { + // asm("bkpt"); + // } + } + uint8_t shift = (offset % pixels_per_byte) * colorspace->depth; + if (colorspace->reverse_pixels_in_byte) { + // Reverse the shift by subtracting it from the leftmost shift. + shift = (pixels_per_byte - 1) * colorspace->depth - shift; + } + ((uint8_t*)buffer)[offset / pixels_per_byte] |= pixel << shift; + } + } + } + } + return full_coverage; +} + +void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self) { + if (self->moved || self->first_draw) { + displayio_area_copy(&self->current_area, &self->previous_area); + } + + self->moved = false; + self->full_change = false; + self->partial_change = false; + self->first_draw = false; + if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type)) { + displayio_palette_finish_refresh(self->pixel_shader); + } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) { + displayio_colorconverter_finish_refresh(self->pixel_shader); + } + if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) { + displayio_bitmap_finish_refresh(self->bitmap); + } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) { + // TODO: Support shape changes. + } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type)) { + // OnDiskBitmap changes will trigger a complete reload so no need to + // track changes. + } + // TODO(tannewt): We could double buffer changes to position and move them over here. + // That way they won't change during a refresh and tear. +} + +displayio_area_t* displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *self, displayio_area_t* tail) { + if (self->moved && !self->first_draw) { + displayio_area_union(&self->previous_area, &self->current_area, &self->dirty_area); + if (displayio_area_size(&self->dirty_area) <= 2U * self->pixel_width * self->pixel_height) { + self->dirty_area.next = tail; + return &self->dirty_area; + } + self->previous_area.next = tail; + self->current_area.next = &self->previous_area; + return &self->current_area; + } + + // If we have an in-memory bitmap, then check it for modifications. + if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) { + displayio_area_t* refresh_area = displayio_bitmap_get_refresh_areas(self->bitmap, tail); + if (refresh_area != tail) { + // Special case a TileGrid that shows a full bitmap and use its + // dirty area. Copy it to ours so we can transform it. + if (self->tiles_in_bitmap == 1) { + displayio_area_copy(refresh_area, &self->dirty_area); + self->partial_change = true; + } else { + self->full_change = true; + } + } + } + + self->full_change = self->full_change || + (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type) && + displayio_palette_needs_refresh(self->pixel_shader)) || + (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type) && + displayio_colorconverter_needs_refresh(self->pixel_shader)); + if (self->full_change || self->first_draw) { + self->current_area.next = tail; + return &self->current_area; + } + + if (self->partial_change) { + if (self->absolute_transform->transpose_xy) { + int16_t x1 = self->dirty_area.x1; + self->dirty_area.x1 = self->absolute_transform->x + self->absolute_transform->dx * (self->y + self->dirty_area.y1); + self->dirty_area.y1 = self->absolute_transform->y + self->absolute_transform->dy * (self->x + x1); + int16_t x2 = self->dirty_area.x2; + self->dirty_area.x2 = self->absolute_transform->x + self->absolute_transform->dx * (self->y + self->dirty_area.y2); + self->dirty_area.y2 = self->absolute_transform->y + self->absolute_transform->dy * (self->x + x2); + } else { + self->dirty_area.x1 = self->absolute_transform->x + self->absolute_transform->dx * (self->x + self->dirty_area.x1); + self->dirty_area.y1 = self->absolute_transform->y + self->absolute_transform->dy * (self->y + self->dirty_area.y1); + self->dirty_area.x2 = self->absolute_transform->x + self->absolute_transform->dx * (self->x + self->dirty_area.x2); + self->dirty_area.y2 = self->absolute_transform->y + self->absolute_transform->dy * (self->y + self->dirty_area.y2); + } + if (self->dirty_area.y2 < self->dirty_area.y1) { + int16_t temp = self->dirty_area.y2; + self->dirty_area.y2 = self->dirty_area.y1; + self->dirty_area.y1 = temp; + } + if (self->dirty_area.x2 < self->dirty_area.x1) { + int16_t temp = self->dirty_area.x2; + self->dirty_area.x2 = self->dirty_area.x1; + self->dirty_area.x1 = temp; + } + + self->dirty_area.next = tail; + return &self->dirty_area; + } + return tail; +} diff --git a/shared-module/displayio/TileGrid.h b/shared-module/displayio/TileGrid.h new file mode 100644 index 00000000000..0a414b06202 --- /dev/null +++ b/shared-module/displayio/TileGrid.h @@ -0,0 +1,84 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_TILEGRID_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_TILEGRID_H + +#include +#include + +#include "py/obj.h" +#include "shared-module/displayio/area.h" +#include "shared-module/displayio/Palette.h" + +typedef struct { + mp_obj_base_t base; + mp_obj_t bitmap; + mp_obj_t pixel_shader; + int16_t x; + int16_t y; + uint16_t pixel_width; + uint16_t pixel_height; + uint16_t bitmap_width_in_tiles;; + uint16_t tiles_in_bitmap; + uint16_t width_in_tiles; + uint16_t height_in_tiles; + uint16_t tile_width; + uint16_t tile_height; + uint16_t top_left_x; + uint16_t top_left_y; + uint8_t* tiles; + const displayio_buffer_transform_t* absolute_transform; + displayio_area_t dirty_area; // Stored as a relative area until the refresh area is fetched. + displayio_area_t previous_area; // Stored as an absolute area. + displayio_area_t current_area; // Stored as an absolute area so it applies across frames. + bool partial_change; + bool full_change; + bool first_draw; + bool moved; + bool inline_tiles; + bool in_group; + bool flip_x; + bool flip_y; + bool transpose_xy; +} displayio_tilegrid_t; + +// Updating the screen is a three stage process. + +// The first stage is used to determine i +displayio_area_t* displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *self, displayio_area_t* tail); + +// Area is always in absolute screen coordinates. Update transform is used to inform TileGrids how +// they relate to it. +bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const _displayio_colorspace_t* colorspace, const displayio_area_t* area, uint32_t* mask, uint32_t *buffer); +void displayio_tilegrid_update_transform(displayio_tilegrid_t *group, const displayio_buffer_transform_t* parent_transform); + +// Fills in area with the maximum bounds of all related pixels in the last rendered frame. Returns +// false if the tilegrid wasn't rendered in the last frame. +bool displayio_tilegrid_get_previous_area(displayio_tilegrid_t *self, displayio_area_t* area); +void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_TILEGRID_H diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c new file mode 100644 index 00000000000..af22cb0df8c --- /dev/null +++ b/shared-module/displayio/__init__.c @@ -0,0 +1,302 @@ + +#include + +#include "shared-module/displayio/__init__.h" + +#include "lib/utils/interrupt_char.h" +#include "py/reload.h" +#include "py/runtime.h" +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/displayio/Bitmap.h" +#include "shared-bindings/displayio/Display.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/displayio/Palette.h" +#include "shared-module/displayio/area.h" +#include "supervisor/shared/autoreload.h" +#include "supervisor/shared/display.h" +#include "supervisor/memory.h" + +primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; + +// Check for recursive calls to displayio_background. +bool displayio_background_in_progress = false; + +void displayio_background(void) { + if (mp_hal_is_interrupted()) { + return; + } + if (reload_requested) { + // Reload is about to happen, so don't redisplay. + return; + } + + if (displayio_background_in_progress) { + // Don't allow recursive calls to this routine. + return; + } + + displayio_background_in_progress = true; + + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].display.base.type == NULL || displays[i].display.base.type == &mp_type_NoneType) { + // Skip null display. + continue; + } + if (displays[i].display.base.type == &displayio_display_type) { + displayio_display_background(&displays[i].display); + } else if (displays[i].epaper_display.base.type == &displayio_epaperdisplay_type) { + displayio_epaperdisplay_background(&displays[i].epaper_display); + } + } + + // All done. + displayio_background_in_progress = false; +} + +void common_hal_displayio_release_displays(void) { + // Release displays before busses so that they can send any final commands to turn the display + // off properly. + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + mp_const_obj_t display_type = displays[i].display.base.type; + if (display_type == NULL || display_type == &mp_type_NoneType) { + continue; + } else if (display_type == &displayio_display_type) { + release_display(&displays[i].display); + } else if (display_type == &displayio_epaperdisplay_type) { + release_epaperdisplay(&displays[i].epaper_display); + } + displays[i].display.base.type = &mp_type_NoneType; + } + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + mp_const_obj_t bus_type = displays[i].fourwire_bus.base.type; + if (bus_type == NULL || bus_type == &mp_type_NoneType) { + continue; + } else if (bus_type == &displayio_fourwire_type) { + common_hal_displayio_fourwire_deinit(&displays[i].fourwire_bus); + } else if (bus_type == &displayio_i2cdisplay_type) { + common_hal_displayio_i2cdisplay_deinit(&displays[i].i2cdisplay_bus); + } else if (bus_type == &displayio_parallelbus_type) { + common_hal_displayio_parallelbus_deinit(&displays[i].parallel_bus); + } + displays[i].fourwire_bus.base.type = &mp_type_NoneType; + } + + supervisor_stop_terminal(); +} + +void reset_displays(void) { + // The SPI buses used by FourWires may be allocated on the heap so we need to move them inline. + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].fourwire_bus.base.type == &displayio_fourwire_type) { + displayio_fourwire_obj_t* fourwire = &displays[i].fourwire_bus; + if (((uint32_t) fourwire->bus) < ((uint32_t) &displays) || + ((uint32_t) fourwire->bus) > ((uint32_t) &displays + CIRCUITPY_DISPLAY_LIMIT)) { + busio_spi_obj_t* original_spi = fourwire->bus; + #if BOARD_SPI + // We don't need to move original_spi if it is the board.SPI object because it is + // statically allocated already. (Doing so would also make it impossible to reference in + // a subsequent VM run.) + if (original_spi == common_hal_board_get_spi()) { + continue; + } + #endif + memcpy(&fourwire->inline_bus, original_spi, sizeof(busio_spi_obj_t)); + fourwire->bus = &fourwire->inline_bus; + // Check for other displays that use the same spi bus and swap them too. + for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) { + if (displays[i].fourwire_bus.base.type == &displayio_fourwire_type && + displays[i].fourwire_bus.bus == original_spi) { + displays[i].fourwire_bus.bus = &fourwire->inline_bus; + } + } + } + } else if (displays[i].i2cdisplay_bus.base.type == &displayio_i2cdisplay_type) { + displayio_i2cdisplay_obj_t* i2c = &displays[i].i2cdisplay_bus; + if (((uint32_t) i2c->bus) < ((uint32_t) &displays) || + ((uint32_t) i2c->bus) > ((uint32_t) &displays + CIRCUITPY_DISPLAY_LIMIT)) { + busio_i2c_obj_t* original_i2c = i2c->bus; + #if BOARD_I2C + // We don't need to move original_i2c if it is the board.I2C object because it is + // statically allocated already. (Doing so would also make it impossible to reference in + // a subsequent VM run.) + if (original_i2c == common_hal_board_get_i2c()) { + continue; + } + #endif + memcpy(&i2c->inline_bus, original_i2c, sizeof(busio_i2c_obj_t)); + i2c->bus = &i2c->inline_bus; + // Check for other displays that use the same i2c bus and swap them too. + for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) { + if (displays[i].i2cdisplay_bus.base.type == &displayio_i2cdisplay_type && + displays[i].i2cdisplay_bus.bus == original_i2c) { + displays[i].i2cdisplay_bus.bus = &i2c->inline_bus; + } + } + } + } else { + // Not an active display bus. + continue; + } + } + + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + // Reset the displayed group. Only the first will get the terminal but + // that's ok. + if (displays[i].display.base.type == &displayio_display_type) { + reset_display(&displays[i].display); + } else if (displays[i].epaper_display.base.type == &displayio_epaperdisplay_type) { + displayio_epaperdisplay_obj_t* display = &displays[i].epaper_display; + common_hal_displayio_epaperdisplay_show(display, NULL); + } + } +} + +void displayio_gc_collect(void) { + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].display.base.type == NULL) { + continue; + } + + // Alternatively, we could use gc_collect_root over the whole object, + // but this is more precise, and is the only field that needs marking. + if (displays[i].display.base.type == &displayio_display_type) { + displayio_display_collect_ptrs(&displays[i].display); + } else if (displays[i].epaper_display.base.type == &displayio_epaperdisplay_type) { + displayio_epaperdisplay_collect_ptrs(&displays[i].epaper_display); + } + } +} + +void displayio_area_expand(displayio_area_t* original, const displayio_area_t* addition) { + if (addition->x1 < original->x1) { + original->x1 = addition->x1; + } + if (addition->y1 < original->y1) { + original->y1 = addition->y1; + } + if (addition->x2 > original->x2) { + original->x2 = addition->x2; + } + if (addition->y2 > original->y2) { + original->y2 = addition->y2; + } +} + +void displayio_area_copy(const displayio_area_t* src, displayio_area_t* dst) { + dst->x1 = src->x1; + dst->y1 = src->y1; + dst->x2 = src->x2; + dst->y2 = src->y2; +} + +void displayio_area_scale(displayio_area_t* area, uint16_t scale) { + area->x1 *= scale; + area->y1 *= scale; + area->x2 *= scale; + area->y2 *= scale; +} + +void displayio_area_shift(displayio_area_t* area, int16_t dx, int16_t dy) { + area->x1 += dx; + area->y1 += dy; + area->x2 += dx; + area->y2 += dy; +} + +bool displayio_area_compute_overlap(const displayio_area_t* a, + const displayio_area_t* b, + displayio_area_t* overlap) { + overlap->x1 = a->x1; + if (b->x1 > overlap->x1) { + overlap->x1 = b->x1; + } + overlap->x2 = a->x2; + if (b->x2 < overlap->x2) { + overlap->x2 = b->x2; + } + if (overlap->x1 >= overlap->x2) { + return false; + } + overlap->y1 = a->y1; + if (b->y1 > overlap->y1) { + overlap->y1 = b->y1; + } + overlap->y2 = a->y2; + if (b->y2 < overlap->y2) { + overlap->y2 = b->y2; + } + if (overlap->y1 >= overlap->y2) { + return false; + } + return true; +} + +void displayio_area_union(const displayio_area_t* a, + const displayio_area_t* b, + displayio_area_t* u) { + u->x1 = a->x1; + if (b->x1 < u->x1) { + u->x1 = b->x1; + } + u->x2 = a->x2; + if (b->x2 > u->x2) { + u->x2 = b->x2; + } + + u->y1 = a->y1; + if (b->y1 < u->y1) { + u->y1 = b->y1; + } + u->y2 = a->y2; + if (b->y2 > u->y2) { + u->y2 = b->y2; + } +} + +uint16_t displayio_area_width(const displayio_area_t* area) { + return area->x2 - area->x1; +} + +uint16_t displayio_area_height(const displayio_area_t* area) { + return area->y2 - area->y1; +} + +uint32_t displayio_area_size(const displayio_area_t* area) { + return displayio_area_width(area) * displayio_area_height(area); +} + +bool displayio_area_equal(const displayio_area_t* a, const displayio_area_t* b) { + return a->x1 == b->x1 && + a->y1 == b->y1 && + a->x2 == b->x2 && + a->y2 == b->y2; +} + +// Original and whole must be in the same coordinate space. +void displayio_area_transform_within(bool mirror_x, bool mirror_y, bool transpose_xy, + const displayio_area_t* original, + const displayio_area_t* whole, + displayio_area_t* transformed) { + if (mirror_x) { + transformed->x1 = whole->x1 + (whole->x2 - original->x2); + transformed->x2 = whole->x2 - (original->x1 - whole->x1); + } else { + transformed->x1 = original->x1; + transformed->x2 = original->x2; + } + if (mirror_y) { + transformed->y1 = whole->y1 + (whole->y2 - original->y2); + transformed->y2 = whole->y2 - (original->y1 - whole->y1); + } else { + transformed->y1 = original->y1; + transformed->y2 = original->y2; + } + if (transpose_xy) { + int16_t y1 = transformed->y1; + int16_t y2 = transformed->y2; + transformed->y1 = whole->y1 + (transformed->x1 - whole->x1); + transformed->y2 = whole->y1 + (transformed->x2 - whole->x1); + transformed->x2 = whole->x1 + (y2 - whole->y1); + transformed->x1 = whole->x1 + (y1 - whole->y1); + } +} diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h new file mode 100644 index 00000000000..e78bc61ce40 --- /dev/null +++ b/shared-module/displayio/__init__.h @@ -0,0 +1,57 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO___INIT___H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO___INIT___H + +#include "shared-bindings/displayio/Display.h" +#include "shared-bindings/displayio/EPaperDisplay.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/displayio/I2CDisplay.h" +#include "shared-bindings/displayio/ParallelBus.h" + +typedef struct { + union { + displayio_fourwire_obj_t fourwire_bus; + displayio_i2cdisplay_obj_t i2cdisplay_bus; + displayio_parallelbus_obj_t parallel_bus; + }; + union { + displayio_display_obj_t display; + displayio_epaperdisplay_obj_t epaper_display; + }; +} primary_display_t; + +extern primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; + +extern displayio_group_t circuitpython_splash; + +void displayio_background(void); +void reset_displays(void); +void displayio_gc_collect(void); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO___INIT___H diff --git a/shared-module/displayio/area.h b/shared-module/displayio/area.h new file mode 100644 index 00000000000..ec7c389b4b5 --- /dev/null +++ b/shared-module/displayio/area.h @@ -0,0 +1,73 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_AREA_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_AREA_H + +// Implementations are in __init__.c +typedef struct _displayio_area_t displayio_area_t; + +struct _displayio_area_t { + int16_t x1; + int16_t y1; + int16_t x2; // Second point is exclusive. + int16_t y2; + const displayio_area_t* next; // Next area in the linked list. +}; + +typedef struct { + uint16_t x; + uint16_t y; + int8_t dx; + int8_t dy; + uint8_t scale; + uint16_t width; + uint16_t height; + bool mirror_x; + bool mirror_y; + bool transpose_xy; +} displayio_buffer_transform_t; + +void displayio_area_union(const displayio_area_t* a, + const displayio_area_t* b, + displayio_area_t* u); +void displayio_area_expand(displayio_area_t* original, const displayio_area_t* addition); +void displayio_area_copy(const displayio_area_t* src, displayio_area_t* dst); +void displayio_area_scale(displayio_area_t* area, uint16_t scale); +void displayio_area_shift(displayio_area_t* area, int16_t dx, int16_t dy); +bool displayio_area_compute_overlap(const displayio_area_t* a, + const displayio_area_t* b, + displayio_area_t* overlap); +uint16_t displayio_area_width(const displayio_area_t* area); +uint16_t displayio_area_height(const displayio_area_t* area); +uint32_t displayio_area_size(const displayio_area_t* area); +bool displayio_area_equal(const displayio_area_t* a, const displayio_area_t* b); +void displayio_area_transform_within(bool mirror_x, bool mirror_y, bool transpose_xy, + const displayio_area_t* original, + const displayio_area_t* whole, + displayio_area_t* transformed); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_AREA_H diff --git a/shared-module/displayio/display_core.c b/shared-module/displayio/display_core.c new file mode 100644 index 00000000000..0f449ea34d6 --- /dev/null +++ b/shared-module/displayio/display_core.c @@ -0,0 +1,325 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/displayio/Display.h" + +#include "py/gc.h" +#include "py/runtime.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/displayio/I2CDisplay.h" +#include "shared-bindings/displayio/ParallelBus.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/time/__init__.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/display.h" + +#include +#include + +#include "tick.h" + +void displayio_display_core_construct(displayio_display_core_t* self, + mp_obj_t bus, uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height, int16_t colstart, int16_t rowstart, uint16_t rotation, + uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte) { + self->colorspace.depth = color_depth; + self->colorspace.grayscale = grayscale; + self->colorspace.pixels_in_byte_share_row = pixels_in_byte_share_row; + self->colorspace.bytes_per_cell = bytes_per_cell; + self->colorspace.reverse_pixels_in_byte = reverse_pixels_in_byte; + self->current_group = NULL; + self->colstart = colstart; + self->rowstart = rowstart; + self->last_refresh = 0; + + if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) { + self->bus_reset = common_hal_displayio_parallelbus_reset; + self->bus_free = common_hal_displayio_parallelbus_bus_free; + self->begin_transaction = common_hal_displayio_parallelbus_begin_transaction; + self->send = common_hal_displayio_parallelbus_send; + self->end_transaction = common_hal_displayio_parallelbus_end_transaction; + } else if (MP_OBJ_IS_TYPE(bus, &displayio_fourwire_type)) { + self->bus_reset = common_hal_displayio_fourwire_reset; + self->bus_free = common_hal_displayio_fourwire_bus_free; + self->begin_transaction = common_hal_displayio_fourwire_begin_transaction; + self->send = common_hal_displayio_fourwire_send; + self->end_transaction = common_hal_displayio_fourwire_end_transaction; + } else if (MP_OBJ_IS_TYPE(bus, &displayio_i2cdisplay_type)) { + self->bus_reset = common_hal_displayio_i2cdisplay_reset; + self->bus_free = common_hal_displayio_i2cdisplay_bus_free; + self->begin_transaction = common_hal_displayio_i2cdisplay_begin_transaction; + self->send = common_hal_displayio_i2cdisplay_send; + self->end_transaction = common_hal_displayio_i2cdisplay_end_transaction; + } else { + mp_raise_ValueError(translate("Unsupported display bus type")); + } + self->bus = bus; + + + supervisor_start_terminal(width, height); + + self->width = width; + self->height = height; + self->ram_width = ram_width; + self->ram_height = ram_height; + rotation = rotation % 360; + self->transform.x = 0; + self->transform.y = 0; + self->transform.scale = 1; + self->transform.mirror_x = false; + self->transform.mirror_y = false; + self->transform.transpose_xy = false; + if (rotation == 0 || rotation == 180) { + if (rotation == 180) { + self->transform.mirror_x = true; + self->transform.mirror_y = true; + } + } else { + self->transform.transpose_xy = true; + if (rotation == 270) { + self->transform.mirror_y = true; + } else { + self->transform.mirror_x = true; + } + } + + self->area.x1 = 0; + self->area.y1 = 0; + self->area.next = NULL; + + self->transform.dx = 1; + self->transform.dy = 1; + if (self->transform.transpose_xy) { + self->area.x2 = height; + self->area.y2 = width; + if (self->transform.mirror_x) { + self->transform.x = height; + self->transform.dx = -1; + } + if (self->transform.mirror_y) { + self->transform.y = width; + self->transform.dy = -1; + } + } else { + self->area.x2 = width; + self->area.y2 = height; + if (self->transform.mirror_x) { + self->transform.x = width; + self->transform.dx = -1; + } + if (self->transform.mirror_y) { + self->transform.y = height; + self->transform.dy = -1; + } + } +} + +bool displayio_display_core_show(displayio_display_core_t* self, displayio_group_t* root_group) { + if (root_group == NULL) { + if (!circuitpython_splash.in_group) { + root_group = &circuitpython_splash; + } else if (self->current_group == &circuitpython_splash) { + return true; + } + } + if (root_group == self->current_group) { + return true; + } + if (root_group != NULL && root_group->in_group) { + return false; + } + if (self->current_group != NULL) { + self->current_group->in_group = false; + } + + if (root_group != NULL) { + displayio_group_update_transform(root_group, &self->transform); + root_group->in_group = true; + } + self->current_group = root_group; + self->full_refresh = true; + return true; +} + +uint16_t displayio_display_core_get_width(displayio_display_core_t* self){ + return self->width; +} + +uint16_t displayio_display_core_get_height(displayio_display_core_t* self){ + return self->height; +} + +bool displayio_display_core_bus_free(displayio_display_core_t *self) { + return self->bus_free(self->bus); +} + +bool displayio_display_core_begin_transaction(displayio_display_core_t* self) { + return self->begin_transaction(self->bus); +} + +void displayio_display_core_end_transaction(displayio_display_core_t* self) { + self->end_transaction(self->bus); +} + +void displayio_display_core_set_region_to_update(displayio_display_core_t* self, uint8_t column_command, uint8_t row_command, uint16_t set_current_column_command, uint16_t set_current_row_command, bool data_as_commands, bool always_toggle_chip_select, displayio_area_t* area) { + uint16_t x1 = area->x1; + uint16_t x2 = area->x2; + uint16_t y1 = area->y1; + uint16_t y2 = area->y2; + // Collapse down the dimension where multiple pixels are in a byte. + if (self->colorspace.depth < 8) { + uint8_t pixels_per_byte = 8 / self->colorspace.depth; + if (self->colorspace.pixels_in_byte_share_row) { + x1 /= pixels_per_byte * self->colorspace.bytes_per_cell; + x2 /= pixels_per_byte * self->colorspace.bytes_per_cell; + } else { + y1 /= pixels_per_byte * self->colorspace.bytes_per_cell; + y2 /= pixels_per_byte * self->colorspace.bytes_per_cell; + } + } + + display_chip_select_behavior_t chip_select = CHIP_SELECT_UNTOUCHED; + if (always_toggle_chip_select || data_as_commands) { + chip_select = CHIP_SELECT_TOGGLE_EVERY_BYTE; + } + + // Set column. + displayio_display_core_begin_transaction(self); + uint8_t data[5]; + data[0] = column_command; + uint8_t data_length = 1; + display_byte_type_t data_type = DISPLAY_DATA; + if (!data_as_commands) { + self->send(self->bus, DISPLAY_COMMAND, CHIP_SELECT_UNTOUCHED, data, 1); + data_length = 0; + } else { + data_type = DISPLAY_COMMAND; + } + if (self->ram_width < 0x100) { + data[data_length++] = x1 + self->colstart; + data[data_length++] = x2 - 1 + self->colstart; + } else { + x1 += self->colstart; + x2 += self->colstart - 1; + data[data_length++] = x1 >> 8; + data[data_length++] = x1 & 0xff; + data[data_length++] = x2 >> 8; + data[data_length++] = x2 & 0xff; + } + self->send(self->bus, data_type, chip_select, data, data_length); + displayio_display_core_end_transaction(self); + if (set_current_column_command != NO_COMMAND) { + uint8_t command = set_current_column_command; + displayio_display_core_begin_transaction(self); + self->send(self->bus, DISPLAY_COMMAND, chip_select, &command, 1); + self->send(self->bus, DISPLAY_DATA, chip_select, data, data_length / 2); + displayio_display_core_end_transaction(self); + } + + + // Set row. + displayio_display_core_begin_transaction(self); + data[0] = row_command; + data_length = 1; + if (!data_as_commands) { + self->send(self->bus, DISPLAY_COMMAND, CHIP_SELECT_UNTOUCHED, data, 1); + data_length = 0; + } + if (self->ram_height < 0x100) { + data[data_length++] = y1 + self->rowstart; + data[data_length++] = y2 - 1 + self->rowstart; + } else { + y1 += self->rowstart; + y2 += self->rowstart - 1; + data[data_length++] = y1 >> 8; + data[data_length++] = y1 & 0xff; + data[data_length++] = y2 >> 8; + data[data_length++] = y2 & 0xff; + } + self->send(self->bus, data_type, chip_select, data, data_length); + displayio_display_core_end_transaction(self); + + if (set_current_row_command != NO_COMMAND) { + uint8_t command = set_current_row_command; + displayio_display_core_begin_transaction(self); + self->send(self->bus, DISPLAY_COMMAND, chip_select, &command, 1); + self->send(self->bus, DISPLAY_DATA, chip_select, data, data_length / 2); + displayio_display_core_end_transaction(self); + } +} + +void displayio_display_core_start_refresh(displayio_display_core_t* self) { + self->last_refresh = ticks_ms; +} + +void displayio_display_core_finish_refresh(displayio_display_core_t* self) { + if (self->current_group != NULL) { + displayio_group_finish_refresh(self->current_group); + } + self->full_refresh = false; + self->last_refresh = ticks_ms; +} + +void release_display_core(displayio_display_core_t* self) { + if (self->current_group != NULL) { + self->current_group->in_group = false; + } +} + +void displayio_display_core_collect_ptrs(displayio_display_core_t* self) { + gc_collect_ptr(self->current_group); +} + +bool displayio_display_core_fill_area(displayio_display_core_t *self, displayio_area_t* area, uint32_t* mask, uint32_t *buffer) { + return displayio_group_fill_area(self->current_group, &self->colorspace, area, mask, buffer); +} + +bool displayio_display_core_clip_area(displayio_display_core_t *self, const displayio_area_t* area, displayio_area_t* clipped) { + bool overlaps = displayio_area_compute_overlap(&self->area, area, clipped); + if (!overlaps) { + return false; + } + // Expand the area if we have multiple pixels per byte and we need to byte + // align the bounds. + if (self->colorspace.depth < 8) { + uint8_t pixels_per_byte = 8 / self->colorspace.depth * self->colorspace.bytes_per_cell; + if (self->colorspace.pixels_in_byte_share_row) { + if (clipped->x1 % pixels_per_byte != 0) { + clipped->x1 -= clipped->x1 % pixels_per_byte; + } + if (clipped->x2 % pixels_per_byte != 0) { + clipped->x2 += pixels_per_byte - clipped->x2 % pixels_per_byte; + } + } else { + if (clipped->y1 % pixels_per_byte != 0) { + clipped->y1 -= clipped->y1 % pixels_per_byte; + } + if (clipped->y2 % pixels_per_byte != 0) { + clipped->y2 += pixels_per_byte - clipped->y2 % pixels_per_byte; + } + } + } + return true; +} diff --git a/shared-module/displayio/display_core.h b/shared-module/displayio/display_core.h new file mode 100644 index 00000000000..e92fdbc9f11 --- /dev/null +++ b/shared-module/displayio/display_core.h @@ -0,0 +1,85 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_CORE_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_CORE_H + +#include "shared-bindings/displayio/__init__.h" +#include "shared-bindings/displayio/Group.h" + +#include "shared-module/displayio/area.h" + +#define NO_COMMAND 0x100 + +typedef struct { + mp_obj_t bus; + displayio_group_t *current_group; + uint64_t last_refresh; + display_bus_bus_reset bus_reset; + display_bus_bus_free bus_free; + display_bus_begin_transaction begin_transaction; + display_bus_send send; + display_bus_end_transaction end_transaction; + displayio_buffer_transform_t transform; + displayio_area_t area; + uint16_t width; + uint16_t height; + uint16_t rotation; + uint16_t ram_width; + uint16_t ram_height; + _displayio_colorspace_t colorspace; + int16_t colstart; + int16_t rowstart; + bool full_refresh; // New group means we need to refresh the whole display. +} displayio_display_core_t; + +void displayio_display_core_construct(displayio_display_core_t* self, + mp_obj_t bus, uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height, int16_t colstart, int16_t rowstart, uint16_t rotation, + uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte); + +bool displayio_display_core_show(displayio_display_core_t* self, displayio_group_t* root_group); + +uint16_t displayio_display_core_get_width(displayio_display_core_t* self); +uint16_t displayio_display_core_get_height(displayio_display_core_t* self); + +bool displayio_display_core_bus_free(displayio_display_core_t *self); +bool displayio_display_core_begin_transaction(displayio_display_core_t* self); +void displayio_display_core_end_transaction(displayio_display_core_t* self); + +void displayio_display_core_set_region_to_update(displayio_display_core_t* self, uint8_t column_command, uint8_t row_command, uint16_t set_current_column_command, uint16_t set_current_row_command, bool data_as_commands, bool always_toggle_chip_select, displayio_area_t* area); + +void release_display_core(displayio_display_core_t* self); + +void displayio_display_core_start_refresh(displayio_display_core_t* self); +void displayio_display_core_finish_refresh(displayio_display_core_t* self); + +void displayio_display_core_collect_ptrs(displayio_display_core_t* self); + +bool displayio_display_core_fill_area(displayio_display_core_t *self, displayio_area_t* area, uint32_t* mask, uint32_t *buffer); + +bool displayio_display_core_clip_area(displayio_display_core_t *self, const displayio_area_t* area, displayio_area_t* clipped); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_CORE_H diff --git a/shared-module/displayio/mipi_constants.h b/shared-module/displayio/mipi_constants.h new file mode 100644 index 00000000000..3cb7e4292fa --- /dev/null +++ b/shared-module/displayio/mipi_constants.h @@ -0,0 +1,37 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_MIPI_CONSTANTS_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_MIPI_CONSTANTS_H + +// More info here: https://www.tonylabs.com/wp-content/uploads/MIPI_DCS_specification_v1.02.00.pdf +enum mipi_command { + MIPI_COMMAND_SET_COLUMN_ADDRESS = 0x2a, + MIPI_COMMAND_SET_PAGE_ADDRESS = 0x2b, + MIPI_COMMAND_WRITE_MEMORY_START = 0x2c, +}; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_MIPI_CONSTANTS_H diff --git a/shared-module/fontio/BuiltinFont.c b/shared-module/fontio/BuiltinFont.c new file mode 100644 index 00000000000..58820d52402 --- /dev/null +++ b/shared-module/fontio/BuiltinFont.c @@ -0,0 +1,79 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/fontio/BuiltinFont.h" + + +#include "shared-bindings/fontio/Glyph.h" + +#include "py/objnamedtuple.h" + +mp_obj_t common_hal_fontio_builtinfont_get_bitmap(const fontio_builtinfont_t *self) { + return MP_OBJ_FROM_PTR(self->bitmap); +} + +mp_obj_t common_hal_fontio_builtinfont_get_bounding_box(const fontio_builtinfont_t *self) { + mp_obj_t *items = m_new(mp_obj_t, 2); + items[0] = MP_OBJ_NEW_SMALL_INT(self->width); + items[1] = MP_OBJ_NEW_SMALL_INT(self->height); + return mp_obj_new_tuple(2, items); +} + +uint8_t fontio_builtinfont_get_glyph_index(const fontio_builtinfont_t *self, mp_uint_t codepoint) { + if (codepoint >= 0x20 && codepoint <= 0x7e) { + return codepoint - 0x20; + } + // Do a linear search of the mapping for unicode. + const byte* j = self->unicode_characters; + uint8_t k = 0; + while (j < self->unicode_characters + self->unicode_characters_len) { + unichar potential_c = utf8_get_char(j); + j = utf8_next_char(j); + if (codepoint == potential_c) { + return 0x7f - 0x20 + k; + } + k++; + } + return 0xff; +} + +mp_obj_t common_hal_fontio_builtinfont_get_glyph(const fontio_builtinfont_t *self, mp_uint_t codepoint) { + uint8_t glyph_index = fontio_builtinfont_get_glyph_index(self, codepoint); + if (glyph_index == 0xff) { + return mp_const_none; + } + mp_obj_t field_values[8] = { + MP_OBJ_FROM_PTR(self->bitmap), + MP_OBJ_NEW_SMALL_INT(glyph_index), + MP_OBJ_NEW_SMALL_INT(self->width), + MP_OBJ_NEW_SMALL_INT(self->height), + MP_OBJ_NEW_SMALL_INT(0), + MP_OBJ_NEW_SMALL_INT(0), + MP_OBJ_NEW_SMALL_INT(self->width), + MP_OBJ_NEW_SMALL_INT(0) + }; + return namedtuple_make_new((const mp_obj_type_t*) &fontio_glyph_type, 8, field_values, NULL); +} diff --git a/shared-module/fontio/BuiltinFont.h b/shared-module/fontio/BuiltinFont.h new file mode 100644 index 00000000000..30b4ade8c6a --- /dev/null +++ b/shared-module/fontio/BuiltinFont.h @@ -0,0 +1,47 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_FONTIO_BUILTINFONT_H +#define MICROPY_INCLUDED_SHARED_MODULE_FONTIO_BUILTINFONT_H + +#include +#include + +#include "py/obj.h" +#include "shared-bindings/displayio/Bitmap.h" + +typedef struct { + mp_obj_base_t base; + const displayio_bitmap_t* bitmap; + uint8_t width; + uint8_t height; + const byte* unicode_characters; + uint16_t unicode_characters_len; +} fontio_builtinfont_t; + +uint8_t fontio_builtinfont_get_glyph_index(const fontio_builtinfont_t *self, mp_uint_t codepoint); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_FONTIO_BUILTINFONT_H diff --git a/shared-module/fontio/__init__.c b/shared-module/fontio/__init__.c new file mode 100644 index 00000000000..674343c5333 --- /dev/null +++ b/shared-module/fontio/__init__.c @@ -0,0 +1,27 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +// Nothing now. diff --git a/shared-module/gamepad/GamePad.c b/shared-module/gamepad/GamePad.c new file mode 100644 index 00000000000..fdce0caab41 --- /dev/null +++ b/shared-module/gamepad/GamePad.c @@ -0,0 +1,57 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski for Adafruit Industries + * + * 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 "py/mpstate.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/gamepad/GamePad.h" + +void common_hal_gamepad_gamepad_init(gamepad_obj_t *gamepad, + const mp_obj_t pins[], size_t n_pins) { + for (size_t i = 0; i < 8; ++i) { + gamepad->pins[i] = NULL; + } + gamepad->pulls = 0; + for (size_t i = 0; i < n_pins; ++i) { + digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(pins[i]); + if (common_hal_digitalio_digitalinout_get_direction(pin) != + DIRECTION_INPUT) { + common_hal_digitalio_digitalinout_switch_to_input(pin, PULL_UP); + } + digitalio_pull_t pull = common_hal_digitalio_digitalinout_get_pull(pin); + if (pull == PULL_NONE) { + common_hal_digitalio_digitalinout_set_pull(pin, PULL_UP); + } + if (pull != PULL_DOWN) { + gamepad->pulls |= 1 << i; + } + gamepad->pins[i] = pin; + } + gamepad->last = 0; +} + +void common_hal_gamepad_gamepad_deinit(gamepad_obj_t *self) { + MP_STATE_VM(gamepad_singleton) = NULL; +} diff --git a/shared-module/gamepad/GamePad.h b/shared-module/gamepad/GamePad.h new file mode 100644 index 00000000000..048fbcd2b22 --- /dev/null +++ b/shared-module/gamepad/GamePad.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_GAMEPAD_GAMEPAD_H +#define MICROPY_INCLUDED_GAMEPAD_GAMEPAD_H + +#include + +#include "shared-bindings/digitalio/DigitalInOut.h" + +typedef struct { + mp_obj_base_t base; + digitalio_digitalinout_obj_t* pins[8]; + volatile uint8_t last; + volatile uint8_t pressed; + uint8_t pulls; +} gamepad_obj_t; + +#endif // MICROPY_INCLUDED_GAMEPAD_GAMEPAD_H diff --git a/shared-module/gamepad/__init__.c b/shared-module/gamepad/__init__.c new file mode 100644 index 00000000000..3e17a0fb5bd --- /dev/null +++ b/shared-module/gamepad/__init__.c @@ -0,0 +1,63 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski for Adafruit Industries + * + * 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 + +#include "py/mpstate.h" +#include "shared-bindings/gamepad/__init__.h" +#include "shared-bindings/gamepad/GamePad.h" + +#include "shared-bindings/digitalio/DigitalInOut.h" + + +void gamepad_tick(void) { + uint8_t current = 0; + uint8_t bit = 1; + + void* singleton = MP_STATE_VM(gamepad_singleton); + if (singleton == NULL || !MP_OBJ_IS_TYPE(MP_OBJ_FROM_PTR(singleton), &gamepad_type)) { + return; + } + + gamepad_obj_t *self = MP_OBJ_TO_PTR(singleton); + for (int i = 0; i < 8; ++i) { + digitalio_digitalinout_obj_t* pin = self->pins[i]; + if (!pin) { + break; + } + if (common_hal_digitalio_digitalinout_get_value(pin)) { + current |= bit; + } + bit <<= 1; + } + current ^= self->pulls; + self->pressed |= self->last & current; + self->last = current; +} + +void gamepad_reset(void) { + MP_STATE_VM(gamepad_singleton) = NULL; +} diff --git a/shared-module/gamepad/__init__.h b/shared-module/gamepad/__init__.h new file mode 100644 index 00000000000..1fae570f98e --- /dev/null +++ b/shared-module/gamepad/__init__.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_GAMEPAD_H +#define MICROPY_INCLUDED_GAMEPAD_H + +void gamepad_tick(void); +void gamepad_reset(void); + +#endif // MICROPY_INCLUDED_GAMEPAD_H diff --git a/shared-module/gamepadshift/GamePadShift.c b/shared-module/gamepadshift/GamePadShift.c new file mode 100644 index 00000000000..b8fb4d3f448 --- /dev/null +++ b/shared-module/gamepadshift/GamePadShift.c @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski for Adafruit Industries + * + * 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 "py/mpstate.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-module/gamepadshift/GamePadShift.h" + +void common_hal_gamepadshift_gamepadshift_init(gamepadshift_obj_t *gamepadshift, + digitalio_digitalinout_obj_t *clock_pin, + digitalio_digitalinout_obj_t *data_pin, + digitalio_digitalinout_obj_t *latch_pin) { + common_hal_digitalio_digitalinout_switch_to_input(data_pin, PULL_NONE); + gamepadshift->data_pin = data_pin; + common_hal_digitalio_digitalinout_switch_to_output(clock_pin, 0, + DRIVE_MODE_PUSH_PULL); + gamepadshift->clock_pin = clock_pin; + common_hal_digitalio_digitalinout_switch_to_output(latch_pin, 1, + DRIVE_MODE_PUSH_PULL); + gamepadshift->latch_pin = latch_pin; + + gamepadshift->last = 0; +} + +void common_hal_gamepadshift_gamepadshift_deinit(gamepadshift_obj_t *gamepadshift) { + MP_STATE_VM(gamepad_singleton) = NULL; +} diff --git a/shared-module/gamepadshift/GamePadShift.h b/shared-module/gamepadshift/GamePadShift.h new file mode 100644 index 00000000000..b4b26b7a98d --- /dev/null +++ b/shared-module/gamepadshift/GamePadShift.h @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Radomir Dopieralski for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_GAMEPADSHIFT_GAMEPADSHIFT_H +#define MICROPY_INCLUDED_GAMEPADSHIFT_GAMEPADSHIFT_H + +#include + +#include "shared-bindings/digitalio/DigitalInOut.h" + +typedef struct { + mp_obj_base_t base; + digitalio_digitalinout_obj_t* data_pin; + digitalio_digitalinout_obj_t* clock_pin; + digitalio_digitalinout_obj_t* latch_pin; + volatile uint8_t pressed; + volatile uint8_t last; +} gamepadshift_obj_t; + +#endif // MICROPY_INCLUDED_GAMEPADSHIFT_GAMEPADSHIFT_H diff --git a/shared-module/gamepadshift/__init__.c b/shared-module/gamepadshift/__init__.c new file mode 100644 index 00000000000..47a008c5032 --- /dev/null +++ b/shared-module/gamepadshift/__init__.c @@ -0,0 +1,57 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft + * + * 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 "shared-module/gamepadshift/__init__.h" + +#include "py/mpstate.h" +#include "shared-bindings/gamepadshift/GamePadShift.h" + +void gamepadshift_tick(void) { + void* singleton = MP_STATE_VM(gamepad_singleton); + if (singleton == NULL || !MP_OBJ_IS_TYPE(MP_OBJ_FROM_PTR(singleton), &gamepadshift_type)) { + return; + } + + gamepadshift_obj_t *self = MP_OBJ_TO_PTR(singleton); + uint8_t current = 0; + uint8_t bit = 1; + common_hal_digitalio_digitalinout_set_value(self->latch_pin, 1); + for (int i = 0; i < 8; ++i) { + common_hal_digitalio_digitalinout_set_value(self->clock_pin, 0); + if (common_hal_digitalio_digitalinout_get_value(self->data_pin)) { + current |= bit; + } + common_hal_digitalio_digitalinout_set_value(self->clock_pin, 1); + bit <<= 1; + } + common_hal_digitalio_digitalinout_set_value(self->latch_pin, 0); + self->pressed |= self->last & current; + self->last = current; +} + +void gamepadshift_reset(void) { + MP_STATE_VM(gamepad_singleton) = NULL; +} diff --git a/shared-module/gamepadshift/__init__.h b/shared-module/gamepadshift/__init__.h new file mode 100644 index 00000000000..225db73361a --- /dev/null +++ b/shared-module/gamepadshift/__init__.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_GAMEPADSHIFT___INIT___H +#define MICROPY_INCLUDED_GAMEPADSHIFT___INIT___H + +void gamepadshift_tick(void); +void gamepadshift_reset(void); + +#endif // MICROPY_INCLUDED_GAMEPADSHIFT___INIT___H diff --git a/shared-module/multiterminal/__init__.c b/shared-module/multiterminal/__init__.c new file mode 100644 index 00000000000..361a6dcc7a9 --- /dev/null +++ b/shared-module/multiterminal/__init__.c @@ -0,0 +1,50 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Paul Sokolovsky + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "py/mpstate.h" + +#include "shared-bindings/multiterminal/__init__.h" + +mp_obj_t shared_module_multiterminal_get_secondary_terminal() { + if (MP_STATE_VM(dupterm_objs[0]) == MP_OBJ_NULL) { + return mp_const_none; + } else { + return MP_STATE_VM(dupterm_objs[0]); + } +} + +void shared_module_multiterminal_set_secondary_terminal(mp_obj_t secondary_terminal) { + MP_STATE_VM(dupterm_objs[0]) = secondary_terminal; + if (MP_STATE_PORT(dupterm_arr_obj) == MP_OBJ_NULL) { + MP_STATE_PORT(dupterm_arr_obj) = mp_obj_new_bytearray(1, ""); + } +} + +void shared_module_multiterminal_clear_secondary_terminal() { + MP_STATE_VM(dupterm_objs[0]) = MP_OBJ_NULL; + MP_STATE_PORT(dupterm_arr_obj) = MP_OBJ_NULL; +} diff --git a/shared-module/multiterminal/__init__.h b/shared-module/multiterminal/__init__.h new file mode 100644 index 00000000000..30044da0657 --- /dev/null +++ b/shared-module/multiterminal/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef SHARED_MODULE_MULTITERMINAL___INIT___H +#define SHARED_MODULE_MULTITERMINAL___INIT___H + +mp_obj_t shared_module_multiterminal_get_secondary_terminal(); +void shared_module_multiterminal_set_secondary_terminal(mp_obj_t secondary_terminal); +void shared_module_multiterminal_clear_secondary_terminal(); + +#endif // SHARED_MODULE_MULTITERMINAL___INIT___H diff --git a/shared-module/network/__init__.c b/shared-module/network/__init__.c new file mode 100644 index 00000000000..96648b260c8 --- /dev/null +++ b/shared-module/network/__init__.c @@ -0,0 +1,105 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Nick Moore + * + * 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 + +#include "py/objlist.h" +#include "py/runtime.h" +#include "py/mphal.h" +#include "py/mperrno.h" + +#include "shared-bindings/random/__init__.h" + +#include "shared-module/network/__init__.h" + +// mod_network_nic_list needs to be declared in mpconfigport.h + + +void network_module_init(void) { + mp_obj_list_init(&MP_STATE_PORT(mod_network_nic_list), 0); +} + +void network_module_deinit(void) { + for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { + mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i]; + mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic); + if (nic_type->deinit != NULL) nic_type->deinit(nic); + } + mp_obj_list_set_len(&MP_STATE_PORT(mod_network_nic_list), 0); +} + +void network_module_background(void) { + static uint32_t next_tick = 0; + uint32_t this_tick = ticks_ms; + if (this_tick < next_tick) return; + next_tick = this_tick + 1000; + + for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { + mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i]; + mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic); + if (nic_type->timer_tick != NULL) nic_type->timer_tick(nic); + } +} + +void network_module_register_nic(mp_obj_t nic) { + for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { + if (MP_STATE_PORT(mod_network_nic_list).items[i] == nic) { + // nic already registered + return; + } + } + // nic not registered so add to list + mp_obj_list_append(MP_OBJ_FROM_PTR(&MP_STATE_PORT(mod_network_nic_list)), nic); +} + +mp_obj_t network_module_find_nic(const uint8_t *ip) { + // find a NIC that is suited to given IP address + for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { + mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i]; + // TODO check IP suitability here + //mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic); + return nic; + } + + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("no available NIC"))); +} + +void network_module_create_random_mac_address(uint8_t *mac) { + uint32_t rb1 = shared_modules_random_getrandbits(24); + uint32_t rb2 = shared_modules_random_getrandbits(24); + // first octet has multicast bit (0) cleared and local bit (1) set + // everything else is just set randomly + mac[0] = ((uint8_t)(rb1 >> 16) & 0xfe) | 0x02; + mac[1] = (uint8_t)(rb1 >> 8); + mac[2] = (uint8_t)(rb1); + mac[3] = (uint8_t)(rb2 >> 16); + mac[4] = (uint8_t)(rb2 >> 8); + mac[5] = (uint8_t)(rb2); +} + +uint16_t network_module_create_random_source_tcp_port(void) { + return 0xc000 | shared_modules_random_getrandbits(14); +} diff --git a/shared-module/network/__init__.h b/shared-module/network/__init__.h new file mode 100644 index 00000000000..f4eb05bb510 --- /dev/null +++ b/shared-module/network/__init__.h @@ -0,0 +1,92 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2018 Nick Moore + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_NETWORK___INIT___H +#define MICROPY_INCLUDED_SHARED_MODULE_NETWORK___INIT___H + +void network_module_create_random_mac_address(uint8_t *mac); +uint16_t network_module_create_random_source_tcp_port(void); + +#define MOD_NETWORK_IPADDR_BUF_SIZE (4) + +#define MOD_NETWORK_AF_INET (2) +#define MOD_NETWORK_AF_INET6 (10) + +#define MOD_NETWORK_SOCK_STREAM (1) +#define MOD_NETWORK_SOCK_DGRAM (2) +#define MOD_NETWORK_SOCK_RAW (3) + +struct _mod_network_socket_obj_t; + +typedef struct _mod_network_nic_type_t { + mp_obj_type_t base; + + // API for non-socket operations + int (*gethostbyname)(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *ip_out); + + // API for socket operations; return -1 on error + int (*socket)(struct _mod_network_socket_obj_t *socket, int *_errno); + void (*close)(struct _mod_network_socket_obj_t *socket); + int (*bind)(struct _mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno); + int (*listen)(struct _mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno); + int (*accept)(struct _mod_network_socket_obj_t *socket, struct _mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno); + int (*connect)(struct _mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno); + mp_uint_t (*send)(struct _mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno); + mp_uint_t (*recv)(struct _mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno); + mp_uint_t (*sendto)(struct _mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno); + mp_uint_t (*recvfrom)(struct _mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno); + int (*setsockopt)(struct _mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno); + int (*settimeout)(struct _mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno); + int (*ioctl)(struct _mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno); + void (*timer_tick)(struct _mod_network_socket_obj_t *socket); + void (*deinit)(struct _mod_network_socket_obj_t *socket); +} mod_network_nic_type_t; + +typedef struct _mod_network_socket_obj_t { + mp_obj_base_t base; + mp_obj_t nic; + mod_network_nic_type_t *nic_type; + union { + struct { + uint8_t domain; + uint8_t type; + int8_t fileno; + } u_param; + mp_uint_t u_state; + }; +} mod_network_socket_obj_t; + +extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k; +extern const mod_network_nic_type_t mod_network_nic_type_cc3k; + +void network_module_init(void); +void network_module_deinit(void); +void network_module_background(void); +void network_module_register_nic(mp_obj_t nic); +mp_obj_t network_module_find_nic(const uint8_t *ip); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_NETWORK___INIT___H diff --git a/shared-module/os/__init__.c b/shared-module/os/__init__.c new file mode 100644 index 00000000000..313893d977f --- /dev/null +++ b/shared-module/os/__init__.c @@ -0,0 +1,211 @@ +/* + * 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 Josef Gajdusek + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "extmod/vfs.h" +#include "py/mperrno.h" +#include "py/mpstate.h" +#include "py/obj.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/os/__init__.h" + +// This provides all VFS related OS functions so that ports can share the code +// as needed. It does not provide uname. + +// Version of mp_vfs_lookup_path that takes and returns uPy string objects. +STATIC mp_vfs_mount_t *lookup_path(const char* path, mp_obj_t *path_out) { + const char *p_out; + mp_vfs_mount_t *vfs = mp_vfs_lookup_path(path, &p_out); + if (vfs != MP_VFS_NONE && vfs != MP_VFS_ROOT) { + *path_out = mp_obj_new_str_of_type(&mp_type_str, + (const byte*)p_out, strlen(p_out)); + } + return vfs; +} + +// Strip off trailing slashes to please underlying libraries +STATIC mp_vfs_mount_t *lookup_dir_path(const char* path, mp_obj_t *path_out) { + const char *p_out; + mp_vfs_mount_t *vfs = mp_vfs_lookup_path(path, &p_out); + if (vfs != MP_VFS_NONE && vfs != MP_VFS_ROOT) { + size_t len = strlen(p_out); + while (len > 1 && p_out[len - 1] == '/') { + len--; + } + *path_out = mp_obj_new_str_of_type(&mp_type_str, (const byte*)p_out, len); + } + return vfs; +} + +STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_args, const mp_obj_t *args) { + if (vfs == MP_VFS_NONE) { + // mount point not found + mp_raise_OSError(MP_ENODEV); + } + if (vfs == MP_VFS_ROOT) { + // can't do operation on root dir + mp_raise_OSError(MP_EPERM); + } + mp_obj_t meth[n_args + 2]; + mp_load_method(vfs->obj, meth_name, meth); + if (args != NULL) { + memcpy(meth + 2, args, n_args * sizeof(*args)); + } + return mp_call_method_n_kw(n_args, 0, meth); +} + +void common_hal_os_chdir(const char* path) { + mp_obj_t path_out; + mp_vfs_mount_t *vfs = lookup_dir_path(path, &path_out); + MP_STATE_VM(vfs_cur) = vfs; + if (vfs == MP_VFS_ROOT) { + // If we change to the root dir and a VFS is mounted at the root then + // we must change that VFS's current dir to the root dir so that any + // subsequent relative paths begin at the root of that VFS. + for (vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) { + if (vfs->len == 1) { + mp_obj_t root = mp_obj_new_str("/", 1); + mp_vfs_proxy_call(vfs, MP_QSTR_chdir, 1, &root); + break; + } + } + } else { + mp_vfs_proxy_call(vfs, MP_QSTR_chdir, 1, &path_out); + } +} + +mp_obj_t common_hal_os_getcwd(void) { + return mp_vfs_getcwd(); +} + +mp_obj_t common_hal_os_listdir(const char* path) { + mp_obj_t path_out; + mp_vfs_mount_t *vfs = lookup_dir_path(path, &path_out); + + mp_vfs_ilistdir_it_t iter; + mp_obj_t iter_obj = MP_OBJ_FROM_PTR(&iter); + + if (vfs == MP_VFS_ROOT) { + // list the root directory + iter.base.type = &mp_type_polymorph_iter; + iter.iternext = mp_vfs_ilistdir_it_iternext; + iter.cur.vfs = MP_STATE_VM(vfs_mount_table); + iter.is_str = true; + iter.is_iter = false; + } else { + iter_obj = mp_vfs_proxy_call(vfs, MP_QSTR_ilistdir, 1, &path_out); + } + + mp_obj_t dir_list = mp_obj_new_list(0, NULL); + mp_obj_t next; + while ((next = mp_iternext(iter_obj)) != MP_OBJ_STOP_ITERATION) { + // next[0] is the filename. + mp_obj_list_append(dir_list, mp_obj_subscr(next, MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_SENTINEL)); + } + return dir_list; +} + +void common_hal_os_mkdir(const char* path) { + mp_obj_t path_out; + mp_vfs_mount_t *vfs = lookup_dir_path(path, &path_out); + if (vfs == MP_VFS_ROOT || (vfs != MP_VFS_NONE && !strcmp(mp_obj_str_get_str(path_out), "/"))) { + mp_raise_OSError(MP_EEXIST); + } + mp_vfs_proxy_call(vfs, MP_QSTR_mkdir, 1, &path_out); +} + +void common_hal_os_remove(const char* path) { + mp_obj_t path_out; + mp_vfs_mount_t *vfs = lookup_path(path, &path_out); + mp_vfs_proxy_call(vfs, MP_QSTR_remove, 1, &path_out); +} + +void common_hal_os_rename(const char* old_path, const char* new_path) { + mp_obj_t args[2]; + mp_vfs_mount_t *old_vfs = lookup_path(old_path, &args[0]); + mp_vfs_mount_t *new_vfs = lookup_path(new_path, &args[1]); + if (old_vfs != new_vfs) { + // can't rename across filesystems + mp_raise_OSError(MP_EPERM); + } + mp_vfs_proxy_call(old_vfs, MP_QSTR_rename, 2, args); +} + +void common_hal_os_rmdir(const char* path) { + mp_obj_t path_out; + mp_vfs_mount_t *vfs = lookup_dir_path(path, &path_out); + mp_vfs_proxy_call(vfs, MP_QSTR_rmdir, 1, &path_out); +} + +mp_obj_t common_hal_os_stat(const char* path) { + mp_obj_t path_out; + mp_vfs_mount_t *vfs = lookup_path(path, &path_out); + if (vfs == MP_VFS_ROOT) { + mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL)); + t->items[0] = MP_OBJ_NEW_SMALL_INT(MP_S_IFDIR); // st_mode + for (int i = 1; i <= 9; ++i) { + t->items[i] = MP_OBJ_NEW_SMALL_INT(0); // dev, nlink, uid, gid, size, atime, mtime, ctime + } + return MP_OBJ_FROM_PTR(t); + } + return mp_vfs_proxy_call(vfs, MP_QSTR_stat, 1, &path_out); +} + +mp_obj_t common_hal_os_statvfs(const char* path) { + mp_obj_t path_out; + mp_vfs_mount_t *vfs = lookup_path(path, &path_out); + if (vfs == MP_VFS_ROOT) { + // statvfs called on the root directory, see if there's anything mounted there + for (vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) { + if (vfs->len == 1) { + break; + } + } + + // If there's nothing mounted at root then return a mostly-empty tuple + if (vfs == NULL) { + mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL)); + + // fill in: bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flags + for (int i = 0; i <= 8; ++i) { + t->items[i] = MP_OBJ_NEW_SMALL_INT(0); + } + + // Put something sensible in f_namemax + t->items[9] = MP_OBJ_NEW_SMALL_INT(MICROPY_ALLOC_PATH_MAX); + + return MP_OBJ_FROM_PTR(t); + } + + // VFS mounted at root so delegate the call to it + path_out = MP_OBJ_NEW_QSTR(MP_QSTR__slash_); + } + return mp_vfs_proxy_call(vfs, MP_QSTR_statvfs, 1, &path_out); +} diff --git a/shared-module/random/__init__.c b/shared-module/random/__init__.c new file mode 100644 index 00000000000..5cc20e5b5d2 --- /dev/null +++ b/shared-module/random/__init__.c @@ -0,0 +1,130 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Paul Sokolovsky + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 +#include + +#include "py/runtime.h" +#include "shared-bindings/os/__init__.h" +#include "shared-bindings/time/__init__.h" + +// Yasmarang random number generator +// by Ilya Levin +// http://www.literatecode.com/yasmarang +// Public Domain + +STATIC uint32_t yasmarang_pad = 0xeda4baba, yasmarang_n = 69, yasmarang_d = 233; +STATIC uint8_t yasmarang_dat = 0; + +STATIC uint32_t yasmarang(void) +{ + if (yasmarang_pad == 0xeda4baba) { + if (!common_hal_os_urandom((uint8_t *)&yasmarang_pad, sizeof(uint32_t))) { + yasmarang_pad = common_hal_time_monotonic() & 0xffffffff; + } + } + yasmarang_pad += yasmarang_dat + yasmarang_d * yasmarang_n; + yasmarang_pad = (yasmarang_pad<<3) + (yasmarang_pad>>29); + yasmarang_n = yasmarang_pad | 2; + yasmarang_d ^= (yasmarang_pad<<31) + (yasmarang_pad>>1); + yasmarang_dat ^= (char) yasmarang_pad ^ (yasmarang_d>>8) ^ 1; + + return (yasmarang_pad^(yasmarang_d<<5)^(yasmarang_pad>>18)^(yasmarang_dat<<1)); +} /* yasmarang */ + +// End of Yasmarang + +// returns an unsigned integer below the given argument +// n must not be zero +STATIC uint32_t yasmarang_randbelow(uint32_t n) { + uint32_t mask = 1; + while ((n & mask) < n) { + mask = (mask << 1) | 1; + } + uint32_t r; + do { + r = yasmarang() & mask; + } while (r >= n); + return r; +} + +void shared_modules_random_seed(mp_uint_t seed) { + yasmarang_pad = seed; + yasmarang_n = 69; + yasmarang_d = 233; + yasmarang_dat = 0; +} + +mp_uint_t shared_modules_random_getrandbits(uint8_t n) { + uint32_t mask = ~0; + // Beware of C undefined behavior when shifting by >= than bit size + mask >>= (32 - n); + return yasmarang() & mask; +} + +mp_int_t shared_modules_random_randrange(mp_int_t start, mp_int_t stop, mp_int_t step) { + mp_int_t n; + if (step > 0) { + n = (stop - start + step - 1) / step; + } else { + n = (stop - start + step + 1) / step; + } + return start + step * yasmarang_randbelow(n); +} + +// returns a number in the range [0..1) using Yasmarang to fill in the fraction bits +STATIC mp_float_t yasmarang_float(void) { + #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE + typedef uint64_t mp_float_int_t; + #elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT + typedef uint32_t mp_float_int_t; + #endif + union { + mp_float_t f; + #if MP_ENDIANNESS_LITTLE + struct { mp_float_int_t frc:MP_FLOAT_FRAC_BITS, exp:MP_FLOAT_EXP_BITS, sgn:1; } p; + #else + struct { mp_float_int_t sgn:1, exp:MP_FLOAT_EXP_BITS, frc:MP_FLOAT_FRAC_BITS; } p; + #endif + } u; + u.p.sgn = 0; + u.p.exp = (1 << (MP_FLOAT_EXP_BITS - 1)) - 1; + if (MP_FLOAT_FRAC_BITS <= 32) { + u.p.frc = yasmarang(); + } else { + u.p.frc = ((uint64_t)yasmarang() << 32) | (uint64_t)yasmarang(); + } + return u.f - 1; +} + +mp_float_t shared_modules_random_random(void) { + return yasmarang_float(); +} + +mp_float_t shared_modules_random_uniform(mp_float_t a, mp_float_t b) { + return a + (b - a) * yasmarang_float(); +} diff --git a/shared-module/socket/__init__.c b/shared-module/socket/__init__.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/shared-module/storage/__init__.c b/shared-module/storage/__init__.c new file mode 100644 index 00000000000..215e1356a38 --- /dev/null +++ b/shared-module/storage/__init__.c @@ -0,0 +1,167 @@ +/* + * 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 Josef Gajdusek + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "extmod/vfs.h" +#include "py/mperrno.h" +#include "py/obj.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/os/__init__.h" +#include "shared-bindings/storage/__init__.h" +#include "supervisor/filesystem.h" +#include "supervisor/flash.h" +#include "supervisor/usb.h" + +STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_args, const mp_obj_t *args) { + if (vfs == MP_VFS_NONE) { + // mount point not found + mp_raise_OSError(MP_ENODEV); + } + if (vfs == MP_VFS_ROOT) { + // can't do operation on root dir + mp_raise_OSError(MP_EPERM); + } + mp_obj_t meth[n_args + 2]; + mp_load_method(vfs->obj, meth_name, meth); + if (args != NULL) { + memcpy(meth + 2, args, n_args * sizeof(*args)); + } + return mp_call_method_n_kw(n_args, 0, meth); +} + +void common_hal_storage_mount(mp_obj_t vfs_obj, const char* mount_path, bool readonly) { + // create new object + mp_vfs_mount_t *vfs = m_new_obj(mp_vfs_mount_t); + vfs->str = mount_path; + vfs->len = strlen(mount_path); + vfs->obj = vfs_obj; + vfs->next = NULL; + + mp_obj_t args[2]; + args[0] = readonly ? mp_const_true : mp_const_false; + args[1] = mp_const_false; // Don't make the file system automatically when mounting. + + // Check that there's no file or directory with the same name as the mount point. + // But it's ok to mount '/' in any case. + if (strcmp(vfs->str, "/") != 0) { + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + common_hal_os_stat(mount_path); + nlr_pop(); + // Something with the same name exists. + mp_raise_OSError(MP_EEXIST); + } + } + + // check that the destination mount point is unused + const char *path_out; + mp_vfs_mount_t *existing_mount = mp_vfs_lookup_path(mount_path, &path_out); + if (existing_mount != MP_VFS_NONE && existing_mount != MP_VFS_ROOT) { + if (vfs->len != 1 && existing_mount->len == 1) { + // if root dir is mounted, still allow to mount something within a subdir of root + } else { + // mount point in use + mp_raise_OSError(MP_EPERM); + } + } + + // call the underlying object to do any mounting operation + mp_vfs_proxy_call(vfs, MP_QSTR_mount, 2, (mp_obj_t*)&args); + + // Insert the vfs into the mount table by pushing it onto the front of the + // mount table. + mp_vfs_mount_t **vfsp = &MP_STATE_VM(vfs_mount_table); + vfs->next = *vfsp; + *vfsp = vfs; +} + +void common_hal_storage_umount_object(mp_obj_t vfs_obj) { + // remove vfs from the mount table + mp_vfs_mount_t *vfs = NULL; + for (mp_vfs_mount_t **vfsp = &MP_STATE_VM(vfs_mount_table); *vfsp != NULL; vfsp = &(*vfsp)->next) { + if ((*vfsp)->obj == vfs_obj) { + vfs = *vfsp; + *vfsp = (*vfsp)->next; + break; + } + } + + if (vfs == NULL) { + mp_raise_OSError(MP_EINVAL); + } + + // if we unmounted the current device then set current to root + if (MP_STATE_VM(vfs_cur) == vfs) { + MP_STATE_VM(vfs_cur) = MP_VFS_ROOT; + } + + // call the underlying object to do any unmounting operation + mp_vfs_proxy_call(vfs, MP_QSTR_umount, 0, NULL); +} + +STATIC mp_obj_t storage_object_from_path(const char* mount_path) { + for (mp_vfs_mount_t **vfsp = &MP_STATE_VM(vfs_mount_table); *vfsp != NULL; vfsp = &(*vfsp)->next) { + if (strcmp(mount_path, (*vfsp)->str) == 0) { + return (*vfsp)->obj; + } + } + mp_raise_OSError(MP_EINVAL); +} + +void common_hal_storage_umount_path(const char* mount_path) { + common_hal_storage_umount_object(storage_object_from_path(mount_path)); +} + +mp_obj_t common_hal_storage_getmount(const char *mount_path) { + return storage_object_from_path(mount_path); +} + +void common_hal_storage_remount(const char *mount_path, bool readonly, bool disable_concurrent_write_protection) { + if (strcmp(mount_path, "/") != 0) { + mp_raise_OSError(MP_EINVAL); + } + + #ifdef USB_AVAILABLE + // TODO(dhalbert): is this is a good enough check? It checks for + // CDC enabled. There is no "MSC enabled" check. + if (usb_enabled()) { + mp_raise_RuntimeError(translate("Cannot remount '/' when USB is active.")); + } + #endif + + filesystem_set_internal_writable_by_usb(readonly); + filesystem_set_internal_concurrent_write_protection(!disable_concurrent_write_protection); +} + +void common_hal_storage_erase_filesystem(void) { + filesystem_init(false, true); // Force a re-format. + common_hal_mcu_reset(); + // We won't actually get here, since we're resetting. +} diff --git a/shared-module/struct/__init__.c b/shared-module/struct/__init__.c new file mode 100644 index 00000000000..245dbbda97c --- /dev/null +++ b/shared-module/struct/__init__.c @@ -0,0 +1,213 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Paul Sokolovsky + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2017 Michael McWethy + * + * 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 +#include + +#include "py/runtime.h" +#include "py/binary.h" +#include "py/parsenum.h" +#include "supervisor/shared/translate.h" + +void struct_validate_format(char fmt) { +#if MICROPY_NONSTANDARD_TYPECODES + if( fmt == 'S' || fmt == 'O') { + mp_raise_RuntimeError(translate("'S' and 'O' are not supported format types")); + } +#endif +} + +char get_fmt_type(const char **fmt) { + char t = **fmt; + switch (t) { + case '!': + t = '>'; + break; + case '@': + case '=': + case '<': + case '>': + break; + default: + return '@'; + } + // Skip type char + (*fmt)++; + return t; +} + +mp_uint_t get_fmt_num(const char **p) { + const char *num = *p; + uint len = 1; + while (unichar_isdigit(*++num)) { + len++; + } + mp_uint_t val = (mp_uint_t)MP_OBJ_SMALL_INT_VALUE(mp_parse_num_integer(*p, len, 10, NULL)); + *p = num; + return val; +} + +mp_uint_t calcsize_items(const char *fmt) { + mp_uint_t cnt = 0; + while (*fmt) { + int num = 1; + if (unichar_isdigit(*fmt)) { + num = get_fmt_num(&fmt); + if (*fmt == 's') { + num = 1; + } + } + // Pad bytes are skipped and don't get included in the item count. + if (*fmt != 'x') { + cnt += num; + } + fmt++; + } + return cnt; +} + +mp_uint_t shared_modules_struct_calcsize(mp_obj_t fmt_in) { + const char *fmt = mp_obj_str_get_str(fmt_in); + char fmt_type = get_fmt_type(&fmt); + + mp_uint_t size; + for (size = 0; *fmt; fmt++) { + + struct_validate_format(*fmt); + + mp_uint_t cnt = 1; + if (unichar_isdigit(*fmt)) { + cnt = get_fmt_num(&fmt); + } + + if (*fmt == 's') { + size += cnt; + } else { + mp_uint_t align; + size_t sz = mp_binary_get_size(fmt_type, *fmt, &align); + while (cnt--) { + // Apply alignment + size = (size + align - 1) & ~(align - 1); + size += sz; + } + } + } + return size; +} + +void shared_modules_struct_pack_into(mp_obj_t fmt_in, byte *p, byte* end_p, size_t n_args, const mp_obj_t *args) { + const char *fmt = mp_obj_str_get_str(fmt_in); + char fmt_type = get_fmt_type(&fmt); + const mp_uint_t total_sz = shared_modules_struct_calcsize(fmt_in); + + if (p + total_sz > end_p) { + mp_raise_RuntimeError(translate("buffer too small")); + } + + size_t i; + for (i = 0; i < n_args;) { + mp_uint_t sz = 1; + if (*fmt == '\0') { + // more arguments given than used by format string; CPython raises struct.error here + mp_raise_RuntimeError(translate("too many arguments provided with the given format")); + } + struct_validate_format(*fmt); + + if (unichar_isdigit(*fmt)) { + sz = get_fmt_num(&fmt); + } + + if (*fmt == 's') { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[i++], &bufinfo, MP_BUFFER_READ); + mp_uint_t to_copy = sz; + if (bufinfo.len < to_copy) { + to_copy = bufinfo.len; + } + memcpy(p, bufinfo.buf, to_copy); + memset(p + to_copy, 0, sz - to_copy); + p += sz; + } else { + while (sz--) { + mp_binary_set_val(fmt_type, *fmt, args[i], &p); + // Pad bytes don't have a corresponding argument. + if (*fmt != 'x') { + i++; + } + } + } + fmt++; + } +} + +mp_obj_tuple_t * shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byte *end_p, bool exact_size) { + + const char *fmt = mp_obj_str_get_str(fmt_in); + char fmt_type = get_fmt_type(&fmt); + const mp_uint_t num_items = calcsize_items(fmt); + const mp_uint_t total_sz = shared_modules_struct_calcsize(fmt_in); + mp_obj_tuple_t *res = MP_OBJ_TO_PTR(mp_obj_new_tuple(num_items, NULL)); + + // If exact_size, make sure the buffer is exactly the right size. + // Otherwise just make sure it's big enough. + if (exact_size) { + if (p + total_sz != end_p) { + mp_raise_RuntimeError(translate("buffer size must match format")); + } + } else { + if (p + total_sz > end_p) { + mp_raise_RuntimeError(translate("buffer too small")); + } + } + + for (uint i = 0; i < num_items;) { + mp_uint_t sz = 1; + + struct_validate_format(*fmt); + + if (unichar_isdigit(*fmt)) { + sz = get_fmt_num(&fmt); + } + mp_obj_t item; + if (*fmt == 's') { + item = mp_obj_new_bytes(p, sz); + p += sz; + res->items[i++] = item; + } else { + while (sz--) { + item = mp_binary_get_val(fmt_type, *fmt, &p); + // Pad bytes are not stored. + if (*fmt != 'x') { + res->items[i++] = item; + } + } + } + fmt++; + } + return res; + +} diff --git a/shared-module/struct/__init__.h b/shared-module/struct/__init__.h new file mode 100644 index 00000000000..637080b2920 --- /dev/null +++ b/shared-module/struct/__init__.h @@ -0,0 +1,34 @@ + +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ +#ifndef MICROPY_INCLUDED_SHARED_MODULE_STRUCT___INIT___H +#define MICROPY_INCLUDED_SHARED_MODULE_STRUCT___INIT___H + +char get_fmt_type(const char **fmt); +mp_uint_t get_fmt_num(const char **p); +mp_uint_t calcsize_items(const char *fmt); + +#endif diff --git a/shared-module/terminalio/Terminal.c b/shared-module/terminalio/Terminal.c new file mode 100644 index 00000000000..df92a5dc486 --- /dev/null +++ b/shared-module/terminalio/Terminal.c @@ -0,0 +1,130 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-module/terminalio/Terminal.h" + +#include "shared-module/fontio/BuiltinFont.h" +#include "shared-bindings/displayio/TileGrid.h" + +void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, displayio_tilegrid_t* tilegrid, const fontio_builtinfont_t* font) { + self->cursor_x = 0; + self->cursor_y = 0; + self->font = font; + self->tilegrid = tilegrid; + self->first_row = 0; + + for (uint16_t x = 0; x < self->tilegrid->width_in_tiles; x++) { + for (uint16_t y = 0; y < self->tilegrid->height_in_tiles; y++) { + common_hal_displayio_tilegrid_set_tile(self->tilegrid, x, y, 0); + } + } + + common_hal_displayio_tilegrid_set_top_left(self->tilegrid, 0, 1); +} + +size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, const byte *data, size_t len, int *errcode) { + const byte* i = data; + uint16_t start_y = self->cursor_y; + while (i < data + len) { + unichar c = utf8_get_char(i); + i = utf8_next_char(i); + // Always handle ASCII. + if (c < 128) { + if (c >= 0x20 && c <= 0x7e) { + uint8_t tile_index = fontio_builtinfont_get_glyph_index(self->font, c); + common_hal_displayio_tilegrid_set_tile(self->tilegrid, self->cursor_x, self->cursor_y, tile_index); + self->cursor_x++; + } else if (c == '\r') { + self->cursor_x = 0; + } else if (c == '\n') { + self->cursor_y++; + // Commands below are used by MicroPython in the REPL + } else if (c == '\b') { + if (self->cursor_x > 0) { + self->cursor_x--; + } + } else if (c == 0x1b) { + if (i[0] == '[') { + if (i[1] == 'K') { + // Clear the rest of the line. + for (uint16_t j = self->cursor_x; j < self->tilegrid->width_in_tiles; j++) { + common_hal_displayio_tilegrid_set_tile(self->tilegrid, j, self->cursor_y, 0); + } + i += 2; + } else { + // Handle commands of the form \x1b[####D + uint16_t n = 0; + uint8_t j = 1; + for (; j < 6; j++) { + if ('0' <= i[j] && i[j] <= '9') { + n = n * 10 + (i[j] - '0'); + } else { + c = i[j]; + break; + } + } + if (c == 'D') { + if (n > self->cursor_x) { + self->cursor_x = 0; + } else { + self->cursor_x -= n; + } + } + i += j + 1; + continue; + } + } + } + } else { + uint8_t tile_index = fontio_builtinfont_get_glyph_index(self->font, c); + if (tile_index != 0xff) { + common_hal_displayio_tilegrid_set_tile(self->tilegrid, self->cursor_x, self->cursor_y, tile_index); + self->cursor_x++; + + } + } + if (self->cursor_x >= self->tilegrid->width_in_tiles) { + self->cursor_y++; + self->cursor_x %= self->tilegrid->width_in_tiles; + } + if (self->cursor_y >= self->tilegrid->height_in_tiles) { + self->cursor_y %= self->tilegrid->height_in_tiles; + } + if (self->cursor_y != start_y) { + // clear the new row + for (uint16_t j = 0; j < self->tilegrid->width_in_tiles; j++) { + common_hal_displayio_tilegrid_set_tile(self->tilegrid, j, self->cursor_y, 0); + start_y = self->cursor_y; + } + common_hal_displayio_tilegrid_set_top_left(self->tilegrid, 0, (start_y + self->tilegrid->height_in_tiles + 1) % self->tilegrid->height_in_tiles); + } + } + return i - data; +} + +bool common_hal_terminalio_terminal_ready_to_tx(terminalio_terminal_obj_t *self) { + return true; +} diff --git a/shared-module/terminalio/Terminal.h b/shared-module/terminalio/Terminal.h new file mode 100644 index 00000000000..c31392cc4ff --- /dev/null +++ b/shared-module/terminalio/Terminal.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef SHARED_MODULE_TERMINALIO_TERMINAL_H +#define SHARED_MODULE_TERMINALIO_TERMINAL_H + +#include +#include + +#include "py/obj.h" +#include "shared-module/fontio/BuiltinFont.h" +#include "shared-module/displayio/TileGrid.h" + +typedef struct { + mp_obj_base_t base; + const fontio_builtinfont_t* font; + uint16_t cursor_x; + uint16_t cursor_y; + displayio_tilegrid_t* tilegrid; + uint16_t first_row; +} terminalio_terminal_obj_t; + +#endif /* SHARED_MODULE_TERMINALIO_TERMINAL_H */ diff --git a/shared-module/terminalio/__init__.c b/shared-module/terminalio/__init__.c new file mode 100644 index 00000000000..3f61f482344 --- /dev/null +++ b/shared-module/terminalio/__init__.c @@ -0,0 +1,27 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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 "shared-bindings/terminalio/__init__.h" diff --git a/shared-module/terminalio/__init__.h b/shared-module/terminalio/__init__.h new file mode 100644 index 00000000000..e925dd429a9 --- /dev/null +++ b/shared-module/terminalio/__init__.h @@ -0,0 +1,30 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef SHARED_MODULE_TERMINALIO___INIT___H +#define SHARED_MODULE_TERMINALIO___INIT___H + +#endif /* SHARED_MODULE_TERMINALIO___INIT___H */ diff --git a/shared-module/touchio/TouchIn.c b/shared-module/touchio/TouchIn.c new file mode 100644 index 00000000000..88d12b8b811 --- /dev/null +++ b/shared-module/touchio/TouchIn.c @@ -0,0 +1,115 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2018 Nick Moore for Adafruit Industries + * + * 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 +#include + +#include "py/runtime.h" +#include "py/mphal.h" +#include "shared-bindings/touchio/TouchIn.h" + +// This is a capacitive touch sensing routine using a single digital +// pin. The pin should be connected to the sensing pad, and to ground +// via a 1Mohm or thereabout drain resistor. When a reading is taken, +// the pin's capacitance is charged by setting it to a digital output +// 'high' for a few microseconds, and then it is changed to a high +// impedance input. We measure how long it takes to discharge through +// the resistor (around 50us), using a busy-waiting loop, and average +// over N_SAMPLES cycles to reduce the effects of noise. + +#define N_SAMPLES 10 +#define TIMEOUT_TICKS 10000 + +static uint16_t get_raw_reading(touchio_touchin_obj_t *self) { + + uint16_t ticks = 0; + + for (uint16_t i = 0; i < N_SAMPLES; i++) { + // set pad to digital output high for 10us to charge it + + common_hal_digitalio_digitalinout_switch_to_output(self->digitalinout, true, DRIVE_MODE_PUSH_PULL); + mp_hal_delay_us(10); + + // set pad back to an input and take some samples + + common_hal_digitalio_digitalinout_switch_to_input(self->digitalinout, PULL_NONE); + + while(common_hal_digitalio_digitalinout_get_value(self->digitalinout)) { + if (ticks >= TIMEOUT_TICKS) return TIMEOUT_TICKS; + ticks++; + } + } + return ticks; +} + +void common_hal_touchio_touchin_construct(touchio_touchin_obj_t* self, const mcu_pin_obj_t *pin) { + claim_pin(pin); + self->digitalinout = m_new_obj(digitalio_digitalinout_obj_t); + self->digitalinout->base.type = &digitalio_digitalinout_type; + + common_hal_digitalio_digitalinout_construct(self->digitalinout, pin); + + uint16_t raw_reading = get_raw_reading(self); + if (raw_reading == TIMEOUT_TICKS) { + mp_raise_ValueError(translate("No pulldown on pin; 1Mohm recommended")); + } + self->threshold = raw_reading * 1.05 + 100; +} + +bool common_hal_touchio_touchin_deinited(touchio_touchin_obj_t* self) { + return self->digitalinout == MP_OBJ_NULL; +} + +void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t* self) { + if (common_hal_touchio_touchin_deinited(self)) { + return; + } + + common_hal_digitalio_digitalinout_deinit(self->digitalinout); + self->digitalinout = MP_OBJ_NULL; +} + +void touchin_reset() { +} + +bool common_hal_touchio_touchin_get_value(touchio_touchin_obj_t *self) { + uint16_t reading = get_raw_reading(self); + return reading > self->threshold; +} + +uint16_t common_hal_touchio_touchin_get_raw_value(touchio_touchin_obj_t *self) { + return get_raw_reading(self); +} + +uint16_t common_hal_touchio_touchin_get_threshold(touchio_touchin_obj_t *self) { + return self->threshold; +} + +void common_hal_touchio_touchin_set_threshold(touchio_touchin_obj_t *self, + uint16_t new_threshold) { + self->threshold = new_threshold; +} diff --git a/shared-module/touchio/TouchIn.h b/shared-module/touchio/TouchIn.h new file mode 100644 index 00000000000..8ff6fda8f4d --- /dev/null +++ b/shared-module/touchio/TouchIn.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * Copyright (c) 2018 Nick Moore for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_TOUCHIO_TOUCHIN_H +#define MICROPY_INCLUDED_SHARED_MODULE_TOUCHIO_TOUCHIN_H + +#include "common-hal/microcontroller/Pin.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + digitalio_digitalinout_obj_t *digitalinout; + uint16_t threshold; +} touchio_touchin_obj_t; + +void touchin_reset(void); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_TOUCHIO_TOUCHIN_H diff --git a/shared-module/touchio/__init__.c b/shared-module/touchio/__init__.c new file mode 100644 index 00000000000..d2290447c95 --- /dev/null +++ b/shared-module/touchio/__init__.c @@ -0,0 +1 @@ +// No touchio module functions. diff --git a/shared-module/uheap/__init__.c b/shared-module/uheap/__init__.c new file mode 100644 index 00000000000..5ef15dce422 --- /dev/null +++ b/shared-module/uheap/__init__.c @@ -0,0 +1,292 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * 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 + +#include "py/bc.h" +#include "py/binary.h" +#include "py/gc.h" +#include "py/obj.h" +#include "py/objarray.h" +#include "py/objfun.h" +#include "py/objint.h" +#include "py/objstr.h" +#include "py/objtype.h" +#include "py/runtime.h" + +#include "shared-bindings/uheap/__init__.h" + +#define VERIFY_PTR(ptr) ( \ + (void *) ptr >= (void*)MP_STATE_MEM(gc_pool_start) /* must be above start of pool */ \ + && (void *) ptr < (void*)MP_STATE_MEM(gc_pool_end) /* must be below end of pool */ \ + ) + +static void indent(uint8_t levels) { + for (int i = 0; i < levels; i++) { + mp_printf(&mp_plat_print, " "); + } +} + +static uint32_t object_size(uint8_t indent_level, mp_obj_t obj); + +static uint32_t int_size(uint8_t indent_level, mp_obj_t obj) { + if (MP_OBJ_IS_SMALL_INT(obj)) { + return 0; + } + if (!VERIFY_PTR(obj)) { + return 0; + } + #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_MPZ + mp_obj_int_t* i = MP_OBJ_TO_PTR(obj); + return gc_nbytes(obj) + gc_nbytes(i->mpz.dig); + #else + return gc_nbytes(obj); + #endif +} + +static uint32_t string_size(uint8_t indent_level, mp_obj_t obj) { + if (MP_OBJ_IS_QSTR(obj)) { + qstr qs = MP_OBJ_QSTR_VALUE(obj); + const char* s = qstr_str(qs); + if (!VERIFY_PTR(s)) { + return 0; + } + indent(indent_level); + mp_printf(&mp_plat_print, "%s\n", s); + return 0; + } else { // MP_OBJ_IS_TYPE(o, &mp_type_str) + mp_obj_str_t* s = MP_OBJ_TO_PTR(obj); + return gc_nbytes(s) + gc_nbytes(s->data); + } +} + +static uint32_t map_size(uint8_t indent_level, const mp_map_t *map) { + uint32_t total_size = gc_nbytes(map->table); + for (int i = 0; i < map->used; i++) { + uint32_t this_size = 0; + indent(indent_level); + if (map->table[i].key != NULL) { + mp_print_str(&mp_plat_print, "key: "); + mp_obj_print_helper(&mp_plat_print, map->table[i].key, PRINT_STR); + mp_print_str(&mp_plat_print, "\n"); + } else { + mp_print_str(&mp_plat_print, "null key\n"); + } + this_size += object_size(indent_level + 1, map->table[i].key); + this_size += object_size(indent_level + 1, map->table[i].value); + + indent(indent_level); + mp_printf(&mp_plat_print, "Entry size: %u\n\n", this_size); + total_size += this_size; + } + + return total_size; +} + +static uint32_t dict_size(uint8_t indent_level, mp_obj_dict_t *dict) { + uint32_t total_size = gc_nbytes(dict); + + indent(indent_level); + mp_printf(&mp_plat_print, "Dictionary @%x\n", dict); + + total_size += map_size(indent_level, &dict->map); + + return total_size; +} + +static uint32_t function_size(uint8_t indent_level, mp_obj_t obj) { + //indent(indent_level); + //mp_print_str(&mp_plat_print, "function\n"); + if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_builtin_0)) { + return 0; + } else if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_builtin_1)) { + return 0; + } else if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_builtin_2)) { + return 0; + } else if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_builtin_3)) { + return 0; + } else if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_builtin_var)) { + return 0; + } else if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_bc)) { + mp_obj_fun_bc_t* fn = MP_OBJ_TO_PTR(obj); + uint32_t total_size = gc_nbytes(fn) + gc_nbytes(fn->bytecode) + gc_nbytes(fn->const_table); + #if MICROPY_DEBUG_PRINTERS + mp_printf(&mp_plat_print, "BYTECODE START\n"); + mp_bytecode_print(fn, fn->bytecode, gc_nbytes(fn->bytecode), fn->const_table); + mp_printf(&mp_plat_print, "BYTECODE END\n"); + #endif + return total_size; + #if MICROPY_EMIT_NATIVE + } else if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_native)) { + return 0; + #endif + #if MICROPY_EMIT_NATIVE + } else if (MP_OBJ_IS_TYPE(obj, &mp_obj_fun_viper_t)) { + return 0; + #endif + #if MICROPY_EMIT_THUMB + } else if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_asm)) { + return 0; + #endif + } + return 0; +} + +static uint32_t array_size(uint8_t indent_level, mp_obj_array_t *array) { + uint32_t total_size = gc_nbytes(array); + + uint32_t item_size = gc_nbytes(array->items); + total_size += item_size; + indent(indent_level); + mp_printf(&mp_plat_print, "Array of size: %u\n\n", item_size); + + return total_size; +} + +static uint32_t memoryview_size(uint8_t indent_level, mp_obj_array_t *array) { + uint32_t total_size = gc_nbytes(array); + + indent(indent_level); + mp_printf(&mp_plat_print, "memoryview\n"); + + return total_size; +} + +static uint32_t type_size(uint8_t indent_level, mp_obj_type_t *type) { + uint32_t total_size = gc_nbytes(type); + + // mp_obj_base_t base; + // qstr name; + //total_size += string_size(indent_level, MP_OBJ_TO_PTR(type->name)); + // mp_print_fun_t print; + // mp_make_new_fun_t make_new; // to make an instance of the type + // + // mp_call_fun_t call; + // mp_unary_op_fun_t unary_op; // can return MP_OBJ_NULL if op not supported + // mp_binary_op_fun_t binary_op; // can return MP_OBJ_NULL if op not supported + // + // // implements load, store and delete attribute + // // + // // dest[0] = MP_OBJ_NULL means load + // // return: for fail, do nothing + // // for attr, dest[0] = value + // // for method, dest[0] = method, dest[1] = self + // // + // // dest[0,1] = {MP_OBJ_SENTINEL, MP_OBJ_NULL} means delete + // // dest[0,1] = {MP_OBJ_SENTINEL, object} means store + // // return: for fail, do nothing + // // for success set dest[0] = MP_OBJ_NULL + // mp_attr_fun_t attr; + // + // mp_subscr_fun_t subscr; // implements load, store, delete subscripting + // // value=MP_OBJ_NULL means delete, value=MP_OBJ_SENTINEL means load, else store + // // can return MP_OBJ_NULL if op not supported + // + // mp_fun_1_t getiter; // corresponds to __iter__ special method + // mp_fun_1_t iternext; // may return MP_OBJ_STOP_ITERATION as an optimisation instead of raising StopIteration() (with no args) + // + // mp_buffer_p_t buffer_p; + // // One of disjoint protocols (interfaces), like mp_stream_p_t, etc. + // const void *protocol; + // + // // these are for dynamically created types (classes) + // struct _mp_obj_tuple_t *bases_tuple; + // struct _mp_obj_dict_t *locals_dict; + if (type->locals_dict != NULL) { + total_size += dict_size(indent_level, type->locals_dict); + } + + indent(indent_level); + mp_printf(&mp_plat_print, "TYPE\n"); + return total_size; +} + + +static uint32_t instance_size(uint8_t indent_level, mp_obj_instance_t *instance) { + uint32_t total_size = gc_nbytes(instance); + + total_size += map_size(indent_level, &instance->members); + + return total_size; +} + +static uint32_t module_size(uint8_t indent_level, mp_obj_module_t *module) { + uint32_t total_size = gc_nbytes(module); + + indent(indent_level); + mp_printf(&mp_plat_print, ".globals\n"); + + total_size += dict_size(indent_level + 1, module->globals); + + indent(indent_level); + mp_printf(&mp_plat_print, "Module size: %u\n", total_size); + return total_size; +} + +static uint32_t object_size(uint8_t indent_level, mp_obj_t obj) { + if (obj == NULL) { + return 0; + } + if (MP_OBJ_IS_INT(obj)) { + return int_size(indent_level, MP_OBJ_TO_PTR(obj)); + } else if (MP_OBJ_IS_STR(obj)) { + return string_size(indent_level, MP_OBJ_TO_PTR(obj)); + } else if (MP_OBJ_IS_FUN(obj)) { + return function_size(indent_level, MP_OBJ_TO_PTR(obj)); + } + if (!VERIFY_PTR(obj)) { + //indent(indent_level); + //mp_printf(&mp_plat_print, "In ROM\n"); + return 0; + } + mp_obj_t type = MP_OBJ_FROM_PTR(mp_obj_get_type(obj)); + + if (type == &mp_type_module) { + return module_size(indent_level, MP_OBJ_TO_PTR(obj)); + } else if (type == &mp_type_dict) { + return dict_size(indent_level, MP_OBJ_TO_PTR(obj)); + } else if (type == &mp_type_type) { + return type_size(indent_level, MP_OBJ_TO_PTR(obj)); + } else if (type == &mp_type_bytearray || type == &mp_type_array) { + return array_size(indent_level, MP_OBJ_TO_PTR(obj)); + } else if (type == &mp_type_memoryview) { + return memoryview_size(indent_level, MP_OBJ_TO_PTR(obj)); + } else if (MP_OBJ_IS_OBJ(obj) && VERIFY_PTR(type)) { + return instance_size(indent_level, MP_OBJ_TO_PTR(obj)); + } + + indent(indent_level); + mp_printf(&mp_plat_print, "unknown type %x\n", type); + return 0; +} + +uint32_t shared_module_uheap_info(mp_obj_t obj) { + if (!VERIFY_PTR(obj)) { + mp_printf(&mp_plat_print, "Object not on heap.\n"); + return 0; + } + return object_size(0, obj); +} diff --git a/shared-module/usb_hid/Device.c b/shared-module/usb_hid/Device.c new file mode 100644 index 00000000000..26d70cb8229 --- /dev/null +++ b/shared-module/usb_hid/Device.c @@ -0,0 +1,98 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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 +#include "tick.h" +#include "py/runtime.h" +#include "shared-bindings/usb_hid/Device.h" +#include "shared-module/usb_hid/Device.h" +#include "supervisor/shared/translate.h" +#include "tusb.h" + +uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self) { + return self->usage_page; +} + +uint8_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self) { + return self->usage; +} + +void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len) { + if (len != self->report_length) { + mp_raise_ValueError_varg(translate("Buffer incorrect size. Should be %d bytes."), self->report_length); + } + + // Wait until interface is ready, timeout = 2 seconds + uint64_t end_ticks = ticks_ms + 2000; + while ( (ticks_ms < end_ticks) && !tud_hid_ready() ) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP; +#endif + } + + if ( !tud_hid_ready() ) { + mp_raise_msg(&mp_type_OSError, translate("USB Busy")); + } + + memcpy(self->report_buffer, report, len); + + if ( !tud_hid_report(self->report_id, self->report_buffer, len) ) { + mp_raise_msg(&mp_type_OSError, translate("USB Error")); + } +} + +static usb_hid_device_obj_t* get_hid_device(uint8_t report_id) { + for (uint8_t i = 0; i < USB_HID_NUM_DEVICES; i++) { + if (usb_hid_devices[i].report_id == report_id) { + return &usb_hid_devices[i]; + } + } + return NULL; +} + +// Callbacks invoked when receive Get_Report request through control endpoint +uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) { + // only support Input Report + if ( report_type != HID_REPORT_TYPE_INPUT ) return 0; + + // fill buffer with current report + memcpy(buffer, get_hid_device(report_id)->report_buffer, reqlen); + return reqlen; +} + +// Callbacks invoked when receive Set_Report request through control endpoint +void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) { + usb_hid_device_obj_t* hid_device = get_hid_device(report_id); + + if ( report_type == HID_REPORT_TYPE_OUTPUT ) { + // Check if it is Keyboard device + if (hid_device->usage_page == HID_USAGE_PAGE_DESKTOP && + hid_device->usage == HID_USAGE_DESKTOP_KEYBOARD) { + // This is LED indicator (CapsLock, NumLock) + // TODO Light up some LED here + } + } +} diff --git a/shared-module/usb_hid/Device.h b/shared-module/usb_hid/Device.h new file mode 100644 index 00000000000..10f2ee897df --- /dev/null +++ b/shared-module/usb_hid/Device.h @@ -0,0 +1,55 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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. + */ + +#ifndef SHARED_MODULE_USB_HID_DEVICE_H +#define SHARED_MODULE_USB_HID_DEVICE_H + +#include +#include + +#include "py/obj.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct { + mp_obj_base_t base; + uint8_t* report_buffer; + uint8_t report_id; + uint8_t report_length; + uint8_t usage_page; + uint8_t usage; +} usb_hid_device_obj_t; + + +extern usb_hid_device_obj_t usb_hid_devices[]; + +#ifdef __cplusplus + } +#endif + +#endif /* SHARED_MODULE_USB_HID_DEVICE_H */ diff --git a/shared-module/usb_hid/__init__.c b/shared-module/usb_hid/__init__.c new file mode 100644 index 00000000000..f14fdd41e3b --- /dev/null +++ b/shared-module/usb_hid/__init__.c @@ -0,0 +1,154 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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 "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" + +#include "genhdr/autogen_usb_descriptor.h" +#include "shared-module/usb_hid/Device.h" +#include "shared-bindings/usb_hid/Device.h" +#include "tusb.h" + +#ifdef USB_HID_REPORT_ID_KEYBOARD +static uint8_t keyboard_report_buffer[USB_HID_REPORT_LENGTH_KEYBOARD]; +#endif + +#ifdef USB_HID_REPORT_ID_MOUSE +static uint8_t mouse_report_buffer[USB_HID_REPORT_LENGTH_MOUSE]; +#endif + +#ifdef USB_HID_REPORT_ID_CONSUMER +static uint8_t consumer_report_buffer[USB_HID_REPORT_LENGTH_CONSUMER]; +#endif + +#ifdef USB_HID_REPORT_ID_SYS_CONTROL +static uint8_t sys_control_report_buffer[USB_HID_REPORT_LENGTH_SYS_CONTROL]; +#endif + +#ifdef USB_HID_REPORT_ID_GAMEPAD +static uint8_t gamepad_report_buffer[USB_HID_REPORT_LENGTH_GAMEPAD]; +#endif + +#ifdef USB_HID_REPORT_ID_DIGITIZER +static uint8_t digitizer_report_buffer[USB_HID_REPORT_LENGTH_DIGITIZER]; +#endif + +usb_hid_device_obj_t usb_hid_devices[] = { +#ifdef USB_HID_REPORT_ID_KEYBOARD + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = keyboard_report_buffer , + .report_id = USB_HID_REPORT_ID_KEYBOARD , + .report_length = USB_HID_REPORT_LENGTH_KEYBOARD , + .usage_page = HID_USAGE_PAGE_DESKTOP , + .usage = HID_USAGE_DESKTOP_KEYBOARD , + }, +#endif + +#ifdef USB_HID_REPORT_ID_MOUSE + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = mouse_report_buffer , + .report_id = USB_HID_REPORT_ID_MOUSE , + .report_length = USB_HID_REPORT_LENGTH_MOUSE , + .usage_page = HID_USAGE_PAGE_DESKTOP , + .usage = HID_USAGE_DESKTOP_MOUSE , + }, +#endif + +#ifdef USB_HID_REPORT_ID_CONSUMER + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = consumer_report_buffer , + .report_id = USB_HID_REPORT_ID_CONSUMER , + .report_length = USB_HID_REPORT_LENGTH_CONSUMER , + .usage_page = HID_USAGE_PAGE_CONSUMER , + .usage = HID_USAGE_CONSUMER_CONTROL , + }, +#endif + +#ifdef USB_HID_REPORT_ID_SYS_CONTROL + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = sys_control_report_buffer , + .report_id = USB_HID_REPORT_ID_SYS_CONTROL , + .report_length = USB_HID_REPORT_LENGTH_SYS_CONTROL , + .usage_page = HID_USAGE_PAGE_DESKTOP , + .usage = HID_USAGE_DESKTOP_SYSTEM_CONTROL , + }, +#endif + +#ifdef USB_HID_REPORT_ID_GAMEPAD + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = gamepad_report_buffer , + .report_id = USB_HID_REPORT_ID_GAMEPAD , + .report_length = USB_HID_REPORT_LENGTH_GAMEPAD , + .usage_page = HID_USAGE_PAGE_DESKTOP , + .usage = HID_USAGE_DESKTOP_GAMEPAD , + }, +#endif + +#ifdef USB_HID_REPORT_ID_DIGITIZER + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = digitizer_report_buffer , + .report_id = USB_HID_REPORT_ID_DIGITIZER , + .report_length = USB_HID_REPORT_LENGTH_DIGITIZER , + .usage_page = 0x0D , + .usage = 0x02 , + }, +#endif +}; + + +mp_obj_tuple_t common_hal_usb_hid_devices = { + .base = { + .type = &mp_type_tuple, + }, + .len = USB_HID_NUM_DEVICES, + .items = { +#if USB_HID_NUM_DEVICES >= 1 + (mp_obj_t) &usb_hid_devices[0], +#endif +#if USB_HID_NUM_DEVICES >= 2 + (mp_obj_t) &usb_hid_devices[1], +#endif +#if USB_HID_NUM_DEVICES >= 3 + (mp_obj_t) &usb_hid_devices[2], +#endif +#if USB_HID_NUM_DEVICES >= 4 + (mp_obj_t) &usb_hid_devices[3], +#endif +#if USB_HID_NUM_DEVICES >= 5 + (mp_obj_t) &usb_hid_devices[4], +#endif +#if USB_HID_NUM_DEVICES >= 6 + (mp_obj_t) &usb_hid_devices[5], +#endif + } +}; diff --git a/shared-module/usb_midi/PortIn.c b/shared-module/usb_midi/PortIn.c new file mode 100644 index 00000000000..31e320baab7 --- /dev/null +++ b/shared-module/usb_midi/PortIn.c @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-module/usb_midi/PortIn.h" +#include "supervisor/shared/translate.h" +#include "tusb.h" + +size_t common_hal_usb_midi_portin_read(usb_midi_portin_obj_t *self, uint8_t *data, size_t len, int *errcode) { + return tud_midi_read(data, len); +} + +uint32_t common_hal_usb_midi_portin_bytes_available(usb_midi_portin_obj_t *self) { + return tud_midi_available(); +} diff --git a/shared-module/usb_midi/PortIn.h b/shared-module/usb_midi/PortIn.h new file mode 100644 index 00000000000..2f72aa4c211 --- /dev/null +++ b/shared-module/usb_midi/PortIn.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef SHARED_MODULE_USB_MIDI_PORTIN_H +#define SHARED_MODULE_USB_MIDI_PORTIN_H + +#include +#include + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} usb_midi_portin_obj_t; + +#endif /* SHARED_MODULE_USB_MIDI_PORTIN_H */ diff --git a/shared-module/usb_midi/PortOut.c b/shared-module/usb_midi/PortOut.c new file mode 100644 index 00000000000..0b37dcfd41b --- /dev/null +++ b/shared-module/usb_midi/PortOut.c @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-module/usb_midi/PortOut.h" +#include "supervisor/shared/translate.h" +#include "tusb.h" + +size_t common_hal_usb_midi_portout_write(usb_midi_portout_obj_t *self, const uint8_t *data, size_t len, int *errcode) { + return tud_midi_write(0, data, len); +} + +bool common_hal_usb_midi_portout_ready_to_tx(usb_midi_portout_obj_t *self) { + return tud_midi_mounted(); +} diff --git a/shared-module/usb_midi/PortOut.h b/shared-module/usb_midi/PortOut.h new file mode 100644 index 00000000000..6b1b8846474 --- /dev/null +++ b/shared-module/usb_midi/PortOut.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef SHARED_MODULE_USB_MIDI_PORTOUT_H +#define SHARED_MODULE_USB_MIDI_PORTOUT_H + +#include +#include + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} usb_midi_portout_obj_t; + +#endif /* SHARED_MODULE_USB_MIDI_PORTOUT_H */ diff --git a/shared-module/usb_midi/__init__.c b/shared-module/usb_midi/__init__.c new file mode 100644 index 00000000000..73a314b9972 --- /dev/null +++ b/shared-module/usb_midi/__init__.c @@ -0,0 +1,63 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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 "shared-bindings/usb_midi/__init__.h" + +#include "genhdr/autogen_usb_descriptor.h" +#include "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "py/objtuple.h" +#include "shared-bindings/usb_midi/PortIn.h" +#include "shared-bindings/usb_midi/PortOut.h" +#include "supervisor/memory.h" +#include "tusb.h" + +supervisor_allocation* usb_midi_allocation; + +void usb_midi_init(void) { + // TODO(tannewt): Make this dynamic. + uint16_t tuple_size = align32_size(sizeof(mp_obj_tuple_t) + sizeof(mp_obj_t*) * 2); + uint16_t portin_size = align32_size(sizeof(usb_midi_portin_obj_t)); + uint16_t portout_size = align32_size(sizeof(usb_midi_portout_obj_t)); + + // For each embedded MIDI Jack in the descriptor we create a Port + usb_midi_allocation = allocate_memory(tuple_size + portin_size + portout_size, false); + + mp_obj_tuple_t *ports = (mp_obj_tuple_t *) usb_midi_allocation->ptr; + ports->base.type = &mp_type_tuple; + ports->len = 2; + + usb_midi_portin_obj_t* in = (usb_midi_portin_obj_t *) (usb_midi_allocation->ptr + tuple_size / 4); + in->base.type = &usb_midi_portin_type; + ports->items[0] = MP_OBJ_FROM_PTR(in); + + usb_midi_portout_obj_t* out = (usb_midi_portout_obj_t *) (usb_midi_allocation->ptr + tuple_size / 4 + portin_size / 4); + out->base.type = &usb_midi_portout_type; + ports->items[1] = MP_OBJ_FROM_PTR(out); + + mp_map_lookup(&usb_midi_module_globals.map, MP_ROM_QSTR(MP_QSTR_ports), MP_MAP_LOOKUP)->value = MP_OBJ_FROM_PTR(ports); +} diff --git a/shared-module/usb_midi/__init__.h b/shared-module/usb_midi/__init__.h new file mode 100644 index 00000000000..e1ad1fbafbd --- /dev/null +++ b/shared-module/usb_midi/__init__.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef SHARED_MODULE_USB_MIDI___INIT___H +#define SHARED_MODULE_USB_MIDI___INIT___H + +void usb_midi_init(void); + +#endif /* SHARED_MODULE_USB_MIDI___INIT___H */ diff --git a/shared-module/ustack/__init__.c b/shared-module/ustack/__init__.c new file mode 100644 index 00000000000..947f81f8e52 --- /dev/null +++ b/shared-module/ustack/__init__.c @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert + * + * 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 + +#include "py/mpstate.h" +#include "py/stackctrl.h" + +#include "shared-bindings/ustack/__init__.h" + +#if MICROPY_MAX_STACK_USAGE +uint32_t shared_module_ustack_max_stack_usage(void) { + // Start at stack limit and move up. + // Untouched stack was filled with a sentinel value. + // Stop at first non-sentinel byte. + char* p = MP_STATE_THREAD(stack_bottom); + while (*p++ == MP_MAX_STACK_USAGE_SENTINEL_BYTE) { } + return MP_STATE_THREAD(stack_top) - p; +} +#endif + +uint32_t shared_module_ustack_stack_size() { + return MP_STATE_THREAD(stack_limit); +} + +uint32_t shared_module_ustack_stack_usage() { + return mp_stack_usage(); +} + diff --git a/shared-module/wiznet/__init__.c b/shared-module/wiznet/__init__.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/shared-module/wiznet/wiznet5k.c b/shared-module/wiznet/wiznet5k.c new file mode 100644 index 00000000000..3c5c5f0c83d --- /dev/null +++ b/shared-module/wiznet/wiznet5k.c @@ -0,0 +1,432 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 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 +#include +#include + +#include "py/objlist.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "py/mperrno.h" +#include "py/mphal.h" +#include "lib/netutils/netutils.h" + +#if MICROPY_PY_WIZNET5K + +#include "shared-module/network/__init__.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "shared-bindings/busio/SPI.h" + +#include "shared-module/network/__init__.h" + +#include "ethernet/wizchip_conf.h" +#include "ethernet/socket.h" +#include "internet/dns/dns.h" +#include "internet/dhcp/dhcp.h" + +#include "shared-module/wiznet/wiznet5k.h" + +STATIC wiznet5k_obj_t wiznet5k_obj; + +STATIC void wiz_cris_enter(void) { + wiznet5k_obj.cris_state = MICROPY_BEGIN_ATOMIC_SECTION(); +} + +STATIC void wiz_cris_exit(void) { + MICROPY_END_ATOMIC_SECTION(wiznet5k_obj.cris_state); +} + +STATIC void wiz_cs_select(void) { + common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.cs, 0); +} + +STATIC void wiz_cs_deselect(void) { + common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.cs, 1); +} + +STATIC void wiz_spi_read(uint8_t *buf, uint32_t len) { + (void)common_hal_busio_spi_read(wiznet5k_obj.spi, buf, len, 0); +} + +STATIC void wiz_spi_write(const uint8_t *buf, uint32_t len) { + (void)common_hal_busio_spi_write(wiznet5k_obj.spi, buf, len); +} + +int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) { + uint8_t dns_ip[MOD_NETWORK_IPADDR_BUF_SIZE] = {8, 8, 8, 8}; + uint8_t *buf = m_new(uint8_t, MAX_DNS_BUF_SIZE); + DNS_init(0, buf); + mp_int_t ret = DNS_run(dns_ip, (uint8_t*)name, out_ip); + m_del(uint8_t, buf, MAX_DNS_BUF_SIZE); + if (ret == 1) { + // success + return 0; + } else { + // failure + return -2; + } +} + +int get_available_socket(wiznet5k_obj_t *wiz) { + for (uint8_t sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++) { + if ((wiz->socket_used & (1 << sn)) == 0) { + wiz->socket_used |= (1 << sn); + return sn; + } + } + return -1; +} + +int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) { + if (socket->u_param.domain != MOD_NETWORK_AF_INET) { + *_errno = MP_EAFNOSUPPORT; + return -1; + } + + switch (socket->u_param.type) { + case MOD_NETWORK_SOCK_STREAM: socket->u_param.type = Sn_MR_TCP; break; + case MOD_NETWORK_SOCK_DGRAM: socket->u_param.type = Sn_MR_UDP; break; + default: *_errno = MP_EINVAL; return -1; + } + + if (socket->u_param.fileno == -1) { + // get first unused socket number + socket->u_param.fileno = get_available_socket(&wiznet5k_obj); + if (socket->u_param.fileno == -1) { + // too many open sockets + *_errno = MP_EMFILE; + return -1; + } + } + + // WIZNET does not have a concept of pure "open socket". You need to know + // if it's a server or client at the time of creation of the socket. + // So, we defer the open until we know what kind of socket we want. + + // use "domain" to indicate that this socket has not yet been opened + socket->u_param.domain = 0; + + return 0; +} + +void wiznet5k_socket_close(mod_network_socket_obj_t *socket) { + uint8_t sn = (uint8_t)socket->u_param.fileno; + if (sn < _WIZCHIP_SOCK_NUM_) { + wiznet5k_obj.socket_used &= ~(1 << sn); + WIZCHIP_EXPORT(close)(sn); + } +} + +int wiznet5k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { + // open the socket in server mode (if port != 0) + mp_int_t ret = WIZCHIP_EXPORT(socket)(socket->u_param.fileno, socket->u_param.type, port, 0); + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + + // indicate that this socket has been opened + socket->u_param.domain = 1; + + // success + return 0; +} + +int wiznet5k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno) { + mp_int_t ret = WIZCHIP_EXPORT(listen)(socket->u_param.fileno); + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return 0; +} + +int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno) { + for (;;) { + int sr = getSn_SR((uint8_t)socket->u_param.fileno); + if (sr == SOCK_ESTABLISHED) { + socket2->u_param = socket->u_param; + getSn_DIPR((uint8_t)socket2->u_param.fileno, ip); + *port = getSn_PORT(socket2->u_param.fileno); + + // WIZnet turns the listening socket into the client socket, so we + // need to re-bind and re-listen on another socket for the server. + // TODO handle errors, especially no-more-sockets error + socket->u_param.domain = MOD_NETWORK_AF_INET; + socket->u_param.fileno = -1; + int _errno2; + if (wiznet5k_socket_socket(socket, &_errno2) != 0) { + //printf("(bad resocket %d)\n", _errno2); + } else if (wiznet5k_socket_bind(socket, NULL, *port, &_errno2) != 0) { + //printf("(bad rebind %d)\n", _errno2); + } else if (wiznet5k_socket_listen(socket, 0, &_errno2) != 0) { + //printf("(bad relisten %d)\n", _errno2); + } + + return 0; + } + if (sr == SOCK_CLOSED || sr == SOCK_CLOSE_WAIT) { + wiznet5k_socket_close(socket); + *_errno = MP_ENOTCONN; // ?? + return -1; + } + mp_hal_delay_ms(1); + } +} + +int wiznet5k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { + uint16_t src_port = network_module_create_random_source_tcp_port(); + // make sure same outgoing port number can't be in use by two different sockets. + src_port = (src_port & ~(_WIZCHIP_SOCK_NUM_ - 1)) | socket->u_param.fileno; + + // use "bind" function to open the socket in client mode + if (wiznet5k_socket_bind(socket, NULL, src_port, _errno) != 0) { + return -1; + } + + // now connect + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(connect)(socket->u_param.fileno, ip, port); + MP_THREAD_GIL_ENTER(); + + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + + // success + return 0; +} + +mp_uint_t wiznet5k_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno) { + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(send)(socket->u_param.fileno, (byte*)buf, len); + MP_THREAD_GIL_ENTER(); + + // TODO convert Wiz errno's to POSIX ones + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return ret; +} + +mp_uint_t wiznet5k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) { + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(recv)(socket->u_param.fileno, buf, len); + MP_THREAD_GIL_ENTER(); + + // TODO convert Wiz errno's to POSIX ones + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return ret; +} + +mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) { + if (socket->u_param.domain == 0) { + // socket not opened; use "bind" function to open the socket in client mode + if (wiznet5k_socket_bind(socket, ip, 0, _errno) != 0) { + return -1; + } + } + + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(sendto)(socket->u_param.fileno, (byte*)buf, len, ip, port); + MP_THREAD_GIL_ENTER(); + + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return ret; +} + +mp_uint_t wiznet5k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) { + uint16_t port2; + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(recvfrom)(socket->u_param.fileno, buf, len, ip, &port2); + MP_THREAD_GIL_ENTER(); + *port = port2; + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + return ret; +} + +int wiznet5k_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) { + // TODO + *_errno = MP_EINVAL; + return -1; +} + +int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno) { + // TODO + *_errno = MP_EINVAL; + return -1; + + /* + if (timeout_ms == 0) { + // set non-blocking mode + uint8_t arg = SOCK_IO_NONBLOCK; + WIZCHIP_EXPORT(ctlsocket)(socket->u_param.fileno, CS_SET_IOMODE, &arg); + } + */ +} + +int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno) { + if (request == MP_STREAM_POLL) { + int ret = 0; + if (arg & MP_STREAM_POLL_RD && getSn_RX_RSR(socket->u_param.fileno) != 0) { + ret |= MP_STREAM_POLL_RD; + } + if (arg & MP_STREAM_POLL_WR && getSn_TX_FSR(socket->u_param.fileno) != 0) { + ret |= MP_STREAM_POLL_WR; + } + return ret; + } else { + *_errno = MP_EINVAL; + return MP_STREAM_ERROR; + } +} + +void wiznet5k_socket_timer_tick(mod_network_socket_obj_t *socket) { + if (wiznet5k_obj.dhcp_socket >= 0) { + DHCP_time_handler(); + DHCP_run(); + } +} + +int wiznet5k_start_dhcp(void) { + // XXX this should throw an error if DHCP fails + static DHCP_INIT_BUFFER_TYPE dhcp_buf[DHCP_INIT_BUFFER_SIZE]; + + if (wiznet5k_obj.dhcp_socket < 0) { + // Set up the socket to listen on UDP 68 before calling DHCP_init + wiznet5k_obj.dhcp_socket = get_available_socket(&wiznet5k_obj); + if (wiznet5k_obj.dhcp_socket < 0) return MP_EMFILE; + + WIZCHIP_EXPORT(socket)(wiznet5k_obj.dhcp_socket, MOD_NETWORK_SOCK_DGRAM, DHCP_CLIENT_PORT, 0); + DHCP_init(wiznet5k_obj.dhcp_socket, dhcp_buf); + } + return 0; +} + +int wiznet5k_stop_dhcp(void) { + if (wiznet5k_obj.dhcp_socket >= 0) { + DHCP_stop(); + WIZCHIP_EXPORT(close)(wiznet5k_obj.dhcp_socket); + wiznet5k_obj.socket_used &= ~(1 << wiznet5k_obj.dhcp_socket); + wiznet5k_obj.dhcp_socket = -1; + } + return 0; +} + +bool wiznet5k_check_dhcp(void) { + return wiznet5k_obj.dhcp_socket >= 0; +} + +void wiznet5k_reset(void) { + if (wiznet5k_obj.rst.pin) { + // hardware reset if using RST pin + common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 0); + mp_hal_delay_us(10); // datasheet says 2us + common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 1); + mp_hal_delay_ms(150); // datasheet says 150ms + } else { + // otherwise, software reset + wizchip_sw_reset(); + } +} + +void wiznet5k_socket_deinit(mod_network_socket_obj_t *socket) { + wiznet5k_reset(); +} + +/// Create and return a WIZNET5K object. +mp_obj_t wiznet5k_create(mp_obj_t spi_in, mp_obj_t cs_in, mp_obj_t rst_in) { + + // init the wiznet5k object + wiznet5k_obj.base.type = (mp_obj_type_t*)&mod_network_nic_type_wiznet5k; + wiznet5k_obj.cris_state = 0; + wiznet5k_obj.spi = MP_OBJ_TO_PTR(spi_in); + wiznet5k_obj.socket_used = 0; + wiznet5k_obj.dhcp_socket = -1; + + /*!< SPI configuration */ + // XXX probably should check if the provided SPI is already configured, and + // if so skip configuration? + + common_hal_busio_spi_configure(wiznet5k_obj.spi, + 10000000, // BAUDRATE 10MHz + 1, // HIGH POLARITY + 1, // SECOND PHASE TRANSITION + 8 // 8 BITS + ); + + common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.cs, cs_in); + common_hal_digitalio_digitalinout_switch_to_output(&wiznet5k_obj.cs, 1, DRIVE_MODE_PUSH_PULL); + + if (rst_in) common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.rst, rst_in); + wiznet5k_reset(); + + reg_wizchip_cris_cbfunc(wiz_cris_enter, wiz_cris_exit); + reg_wizchip_cs_cbfunc(wiz_cs_select, wiz_cs_deselect); + reg_wizchip_spi_cbfunc(wiz_spi_read, wiz_spi_write); + + // 2k buffer for each socket + uint8_t sn_size[16] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; + ctlwizchip(CW_INIT_WIZCHIP, sn_size); + + wiz_NetInfo netinfo = { + .dhcp = NETINFO_DHCP, + }; + network_module_create_random_mac_address(netinfo.mac); + ctlnetwork(CN_SET_NETINFO, (void*)&netinfo); + + // seems we need a small delay after init + mp_hal_delay_ms(250); + + // register with network module + network_module_register_nic(&wiznet5k_obj); + + // return wiznet5k object + return &wiznet5k_obj; +} + +#endif // MICROPY_PY_WIZNET5K diff --git a/shared-module/wiznet/wiznet5k.h b/shared-module/wiznet/wiznet5k.h new file mode 100644 index 00000000000..0154831c718 --- /dev/null +++ b/shared-module/wiznet/wiznet5k.h @@ -0,0 +1,70 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_WIZNET_WIZNET5K_H +#define MICROPY_INCLUDED_SHARED_MODULE_WIZNET_WIZNET5K_H + +#include "ethernet/wizchip_conf.h" +#include "ethernet/socket.h" +#include "internet/dns/dns.h" +#include "internet/dhcp/dhcp.h" + +typedef struct _wiznet5k_obj_t { + mp_obj_base_t base; + mp_uint_t cris_state; + busio_spi_obj_t *spi; + digitalio_digitalinout_obj_t cs; + digitalio_digitalinout_obj_t rst; + uint8_t socket_used; + int8_t dhcp_socket; // -1 for DHCP not in use +} wiznet5k_obj_t; + +int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip); +int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno); +void wiznet5k_socket_close(mod_network_socket_obj_t *socket); +int wiznet5k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno); +int wiznet5k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno); +int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno); +int wiznet5k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno); +mp_uint_t wiznet5k_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno); +mp_uint_t wiznet5k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno); +mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno); +mp_uint_t wiznet5k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno); +int wiznet5k_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno); +int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno); +int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno); +void wiznet5k_socket_timer_tick(mod_network_socket_obj_t *socket); +void wiznet5k_socket_deinit(mod_network_socket_obj_t *socket); +mp_obj_t wiznet5k_socket_disconnect(mp_obj_t self_in); +mp_obj_t wiznet5k_create(mp_obj_t spi_in, mp_obj_t cs_in, mp_obj_t rst_in); + +int wiznet5k_start_dhcp(void); +int wiznet5k_stop_dhcp(void); +bool wiznet5k_check_dhcp(void); + +extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_WIZNET_WIZNET5K_H diff --git a/supervisor/cpu.h b/supervisor/cpu.h new file mode 100755 index 00000000000..c4f81316c74 --- /dev/null +++ b/supervisor/cpu.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SUPERVISOR_CPU_H +#define MICROPY_INCLUDED_SUPERVISOR_CPU_H + +// Adds up to 10 pointers from the CPUs registers to regs. This is used to make sure no actively +// used heap memory is freed. Its usually implemented in assembly. +mp_uint_t cpu_get_regs_and_sp(mp_uint_t *regs); + +#endif // MICROPY_INCLUDED_SUPERVISOR_CPU_H diff --git a/supervisor/filesystem.h b/supervisor/filesystem.h new file mode 100644 index 00000000000..c7c951a5e6e --- /dev/null +++ b/supervisor/filesystem.h @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SUPERVISOR_FILESYSTEM_H +#define MICROPY_INCLUDED_SUPERVISOR_FILESYSTEM_H + +#include + +#include "extmod/vfs_fat.h" + +extern volatile bool filesystem_flush_requested; + +void filesystem_background(void); +void filesystem_tick(void); +void filesystem_init(bool create_allowed, bool force_create); +void filesystem_flush(void); +bool filesystem_present(void); +void filesystem_set_internal_writable_by_usb(bool usb_writable); +void filesystem_set_internal_concurrent_write_protection(bool concurrent_write_protection); +void filesystem_set_writable_by_usb(fs_user_mount_t *vfs, bool usb_writable); +void filesystem_set_concurrent_write_protection(fs_user_mount_t *vfs, bool concurrent_write_protection); +bool filesystem_is_writable_by_python(fs_user_mount_t *vfs); +bool filesystem_is_writable_by_usb(fs_user_mount_t *vfs); + +#endif // MICROPY_INCLUDED_SUPERVISOR_FILESYSTEM_H diff --git a/supervisor/flash.h b/supervisor/flash.h new file mode 100644 index 00000000000..0a124353e6c --- /dev/null +++ b/supervisor/flash.h @@ -0,0 +1,53 @@ +/* + * This file is part of the MicroPython 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. + */ +#ifndef MICROPY_INCLUDED_SUPERVISOR_FLASH_H +#define MICROPY_INCLUDED_SUPERVISOR_FLASH_H + +#include +#include + +#include "py/mpconfig.h" + +#ifdef EXTERNAL_FLASH_DEVICE_COUNT +#include "supervisor/shared/external_flash/external_flash.h" +#else +#include "supervisor/internal_flash.h" +#endif + +void supervisor_flash_init(void); +uint32_t supervisor_flash_get_block_size(void); +uint32_t supervisor_flash_get_block_count(void); + +// these return 0 on success, non-zero on error +mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks); +mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks); + +struct _fs_user_mount_t; +void supervisor_flash_init_vfs(struct _fs_user_mount_t *vfs); +void supervisor_flash_flush(void); +void supervisor_flash_release_cache(void); + +#endif // MICROPY_INCLUDED_SUPERVISOR_FLASH_H diff --git a/supervisor/flash_root_pointers.h b/supervisor/flash_root_pointers.h new file mode 100644 index 00000000000..634ae58d3fb --- /dev/null +++ b/supervisor/flash_root_pointers.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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. + */ +#ifndef MICROPY_INCLUDED_SUPERVISOR_FLASH_ROOT_POINTERS_H +#define MICROPY_INCLUDED_SUPERVISOR_FLASH_ROOT_POINTERS_H + +#ifdef EXTERNAL_FLASH_DEVICE_COUNT +#include "supervisor/shared/external_flash/external_flash_root_pointers.h" +#else +#include "supervisor/internal_flash_root_pointers.h" +#endif + +#endif // MICROPY_INCLUDED_SUPERVISOR_FLASH_ROOT_POINTERS_H diff --git a/supervisor/memory.h b/supervisor/memory.h new file mode 100755 index 00000000000..f557744ae5e --- /dev/null +++ b/supervisor/memory.h @@ -0,0 +1,63 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +// Basic allocations outside them for areas such as the VM heap and stack. +// supervisor/shared/memory.c has a basic implementation for a continuous chunk of memory. Add it +// to a SRC_ in a Makefile to use it. + +#ifndef MICROPY_INCLUDED_SUPERVISOR_MEMORY_H +#define MICROPY_INCLUDED_SUPERVISOR_MEMORY_H + +#include +#include + +typedef struct { + uint32_t* ptr; + uint32_t length; // in bytes +} supervisor_allocation; + + + +void memory_init(void); +void free_memory(supervisor_allocation* allocation); +supervisor_allocation* allocate_remaining_memory(void); + +// Allocate a piece of a given length in bytes. If high_address is true then it should be allocated +// at a lower address from the top of the stack. Otherwise, addresses will increase starting after +// statically allocated memory. +supervisor_allocation* allocate_memory(uint32_t length, bool high_address); + +static inline uint16_t align32_size(uint16_t size) { + if (size % 4 != 0) { + return (size & 0xfffc) + 0x4; + } + return size; +} + +// Called after the heap is freed in case the supervisor wants to save some values. +void supervisor_move_memory(void); + +#endif // MICROPY_INCLUDED_SUPERVISOR_MEMORY_H diff --git a/supervisor/messages/default.h b/supervisor/messages/default.h new file mode 100644 index 00000000000..8cdd671b311 --- /dev/null +++ b/supervisor/messages/default.h @@ -0,0 +1,99 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_SUPERVISOR_MESSAGES_DEFAULT_H +#define MICROPY_SUPERVISOR_MESSAGES_DEFAULT_H + +#ifndef MSG_OUTPUT_SUFFIX +#define MSG_OUTPUT_SUFFIX " output:\r\n" +#endif + +#ifndef MSG_NEWLINE +#define MSG_NEWLINE "\r\n" +#endif + +#ifndef MSG_AUTORELOAD_ON +#define MSG_AUTORELOAD_ON "Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\r\n" +#endif + +#ifndef MSG_AUTORELOAD_OFF +#define MSG_AUTORELOAD_OFF "Auto-reload is off.\r\n" +#endif + +#ifndef MSG_SAFE_MODE_ON +#define MSG_SAFE_MODE_ON "Running in safe mode! Auto-reload is off.\r\n" +#endif + +#ifndef MSG_SAFE_MODE_NO_MAIN +#define MSG_SAFE_MODE_NO_MAIN "Running in safe mode! Not running saved code.\r\n" +#endif + +#ifndef MSG_SAFE_MODE_USER_REQUESTED +#define MSG_SAFE_MODE_USER_REQUESTED "You requested starting safe mode by " +#endif + +#ifndef MSG_SAFE_MODE_USER_EXIT +#define MSG_SAFE_MODE_USER_EXIT "To exit, please reset the board without " +#endif + +#ifndef MSG_BAD_SAFE_MODE +#define MSG_BAD_SAFE_MODE "You are running in safe mode which means something really bad happened." +#endif + +#ifndef MSG_SAFE_MODE_CRASH +#define MSG_SAFE_MODE_CRASH "Looks like our core CircuitPython code crashed hard. Whoops!" +#endif + +#ifndef MSG_SAFE_MODE_FILE_ISSUE +#define MSG_SAFE_MODE_FILE_ISSUE "Please file an issue here with the contents of your CIRCUITPY drive:" +#endif + +#ifndef MSG_SAFE_MODE_ISSUE_LINK +#define MSG_SAFE_MODE_ISSUE_LINK "https://github.com/adafruit/circuitpython/issues" +#endif + +#ifndef MSG_SAFE_MODE_BROWN_OUT_LINE_1 +#define MSG_SAFE_MODE_BROWN_OUT_LINE_1 "The microcontroller's power dipped. Please make sure your power supply provides" +#endif + +#ifndef MSG_SAFE_MODE_BROWN_OUT_LINE_2 +#define MSG_SAFE_MODE_BROWN_OUT_LINE_2 "enough power for the whole circuit and press reset (after ejecting CIRCUITPY)." +#endif + +#ifndef MSG_WAIT_BEFORE_REPL +#define MSG_WAIT_BEFORE_REPL "Press any key to enter the REPL. Use CTRL-D to reload." +#endif + +// Be careful, some tools depend on this. +#ifndef MSG_SOFT_REBOOT +#define MSG_SOFT_REBOOT "soft reboot" +#endif + +#ifndef MSG_DOUBLE_FILE_EXTENSION +#define MSG_DOUBLE_FILE_EXTENSION "WARNING: Your code filename has two extensions\r\n" +#endif + +#endif // MICROPY_SUPERVISOR_MESSAGES_DEFAULT_H diff --git a/supervisor/port.h b/supervisor/port.h new file mode 100644 index 00000000000..1430c6a5050 --- /dev/null +++ b/supervisor/port.h @@ -0,0 +1,61 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016-2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SUPERVISOR_PORT_H +#define MICROPY_INCLUDED_SUPERVISOR_PORT_H + +#include "py/mpconfig.h" + +#include "supervisor/shared/safe_mode.h" + +// Provided by the linker; +extern uint32_t _ezero; + +// This file defines core methods that must be implemented by a port. +extern uint32_t _estack; + +// Stored at the end of the bss section (which includes the heap). +extern uint32_t _ebss; + +safe_mode_t port_init(void); + +// Reset the microcontroller completely. +void reset_cpu(void); + +// Reset the microcontroller state. +void reset_port(void); + +// Reset the rest of the board. +void reset_board(void); + +// Reset to the bootloader +void reset_to_bootloader(void); + +// Save and retrieve a word from memory that is preserved over reset. Used for safe mode. +void port_set_saved_word(uint32_t); +uint32_t port_get_saved_word(void); + +#endif // MICROPY_INCLUDED_SUPERVISOR_PORT_H diff --git a/supervisor/serial.h b/supervisor/serial.h new file mode 100644 index 00000000000..84b3062a3b7 --- /dev/null +++ b/supervisor/serial.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SUPERVISOR_SERIAL_H +#define MICROPY_INCLUDED_SUPERVISOR_SERIAL_H + +#include +#include + +#include "py/mpconfig.h" + +#ifdef CIRCUITPY_BOOT_OUTPUT_FILE +#include "lib/oofatfs/ff.h" + +FIL* boot_output_file; +#endif + +void serial_init(void); +void serial_write(const char* text); +// Only writes up to given length. Does not check for null termination at all. +void serial_write_substring(const char* text, uint32_t length); +char serial_read(void); +bool serial_bytes_available(void); +bool serial_connected(void); + +#endif // MICROPY_INCLUDED_SUPERVISOR_SERIAL_H diff --git a/supervisor/shared/autoreload.c b/supervisor/shared/autoreload.c new file mode 100644 index 00000000000..14b21902cde --- /dev/null +++ b/supervisor/shared/autoreload.c @@ -0,0 +1,78 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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 "autoreload.h" + +#include "py/mphal.h" +#include "py/reload.h" + +static volatile uint32_t autoreload_delay_ms = 0; +static bool autoreload_enabled = false; +static bool autoreload_suspended = false; + +volatile bool reload_requested = false; + +inline void autoreload_tick() { + if (autoreload_delay_ms == 0) { + return; + } + if (autoreload_delay_ms == 1 && autoreload_enabled && + !autoreload_suspended && !reload_requested) { + mp_raise_reload_exception(); + reload_requested = true; + } + autoreload_delay_ms--; +} + +void autoreload_enable() { + autoreload_enabled = true; + reload_requested = false; +} + +void autoreload_disable() { + autoreload_enabled = false; +} + +void autoreload_suspend() { + autoreload_suspended = true; +} + +void autoreload_resume() { + autoreload_suspended = false; +} + +inline bool autoreload_is_enabled() { + return autoreload_enabled; +} + +void autoreload_start() { + autoreload_delay_ms = CIRCUITPY_AUTORELOAD_DELAY_MS; +} + +void autoreload_stop() { + autoreload_delay_ms = 0; + reload_requested = false; +} diff --git a/supervisor/shared/autoreload.h b/supervisor/shared/autoreload.h new file mode 100644 index 00000000000..bcb1001513d --- /dev/null +++ b/supervisor/shared/autoreload.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SUPERVISOR_AUTORELOAD_H +#define MICROPY_INCLUDED_SUPERVISOR_AUTORELOAD_H + +#include + +extern volatile bool reload_requested; + +void autoreload_tick(void); + +void autoreload_start(void); +void autoreload_stop(void); +void autoreload_enable(void); +void autoreload_disable(void); +bool autoreload_is_enabled(void); + +// Temporarily turn it off. Used during the REPL. +void autoreload_suspend(void); +void autoreload_resume(void); + +#endif // MICROPY_INCLUDED_SUPERVISOR_AUTORELOAD_H diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c new file mode 100644 index 00000000000..586b6f8be48 --- /dev/null +++ b/supervisor/shared/display.c @@ -0,0 +1,246 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/shared/display.h" + +#include + +#include "py/mpstate.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/displayio/Palette.h" +#include "shared-bindings/displayio/TileGrid.h" +#include "supervisor/memory.h" + +extern size_t blinka_bitmap_data[]; +extern displayio_bitmap_t blinka_bitmap; +extern displayio_group_t circuitpython_splash; + +static supervisor_allocation* tilegrid_tiles = NULL; + +void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) { + displayio_tilegrid_t* grid = &supervisor_terminal_text_grid; + uint16_t width_in_tiles = (width_px - blinka_bitmap.width) / grid->tile_width; + // determine scale based on h + uint8_t scale = 1; + if (width_in_tiles > 80) { + scale = 2; + } + width_in_tiles = (width_px - blinka_bitmap.width * scale) / (grid->tile_width * scale); + uint16_t height_in_tiles = height_px / (grid->tile_height * scale); + uint16_t remaining_pixels = height_px % (grid->tile_height * scale); + if (remaining_pixels > 0) { + height_in_tiles += 1; + } + circuitpython_splash.scale = scale; + + uint16_t total_tiles = width_in_tiles * height_in_tiles; + + // First try to allocate outside the heap. This will fail when the VM is running. + tilegrid_tiles = allocate_memory(align32_size(total_tiles), false); + uint8_t* tiles; + if (tilegrid_tiles == NULL) { + tiles = m_malloc(total_tiles, true); + MP_STATE_VM(terminal_tilegrid_tiles) = tiles; + } else { + tiles = (uint8_t*) tilegrid_tiles->ptr; + } + + if (tiles == NULL) { + return; + } + grid->y = 0; + grid->top_left_y = 0; + if (remaining_pixels > 0) { + grid->y -= (grid->tile_height - remaining_pixels); + } + grid->width_in_tiles = width_in_tiles; + grid->height_in_tiles = height_in_tiles; + grid->pixel_width = width_in_tiles * grid->tile_width; + grid->pixel_height = height_in_tiles * grid->tile_height; + grid->tiles = tiles; + + common_hal_terminalio_terminal_construct(&supervisor_terminal, grid, &supervisor_terminal_font); +} + +void supervisor_stop_terminal(void) { + if (tilegrid_tiles != NULL) { + free_memory(tilegrid_tiles); + tilegrid_tiles = NULL; + supervisor_terminal_text_grid.inline_tiles = false; + supervisor_terminal_text_grid.tiles = NULL; + } +} + +void supervisor_display_move_memory(void) { + #if CIRCUITPY_DISPLAYIO + displayio_tilegrid_t* grid = &supervisor_terminal_text_grid; + if (MP_STATE_VM(terminal_tilegrid_tiles) == NULL || grid->tiles != MP_STATE_VM(terminal_tilegrid_tiles)) { + return; + } + uint16_t total_tiles = grid->width_in_tiles * grid->height_in_tiles; + + tilegrid_tiles = allocate_memory(align32_size(total_tiles), false); + if (tilegrid_tiles != NULL) { + memcpy(tilegrid_tiles->ptr, grid->tiles, total_tiles); + grid->tiles = (uint8_t*) tilegrid_tiles->ptr; + } else { + grid->tiles = NULL; + grid->inline_tiles = false; + } + MP_STATE_VM(terminal_tilegrid_tiles) = NULL; + #endif +} + +size_t blinka_bitmap_data[32] = { + 0x00000011, 0x11000000, + 0x00000111, 0x53100000, + 0x00000111, 0x56110000, + 0x00000111, 0x11140000, + 0x00000111, 0x20002000, + 0x00000011, 0x13000000, + 0x00000001, 0x11200000, + 0x00000000, 0x11330000, + 0x00000000, 0x01122000, + 0x00001111, 0x44133000, + 0x00032323, 0x24112200, + 0x00111114, 0x44113300, + 0x00323232, 0x34112200, + 0x11111144, 0x44443300, + 0x11111111, 0x11144401, + 0x23232323, 0x21111110 +}; + +displayio_bitmap_t blinka_bitmap = { + .base = {.type = &displayio_bitmap_type }, + .width = 16, + .height = 16, + .data = blinka_bitmap_data, + .stride = 2, + .bits_per_value = 4, + .x_shift = 3, + .x_mask = 0x7, + .bitmask = 0xf, + .read_only = true +}; + +_displayio_color_t blinka_colors[7] = { + { + .rgb888 = 0x000000, + .rgb565 = 0x0000, + .luma = 0x00, + .chroma = 0, + .transparent = true + }, + { + .rgb888 = 0x8428bc, + .rgb565 = 0x7889, + .luma = 0xff, // We cheat the luma here. It is actually 0x60 + .hue = 184, + .chroma = 148 + }, + { + .rgb888 = 0xff89bc, + .rgb565 = 0xB8FC, + .luma = 0xb5, + .hue = 222, + .chroma = 118 + }, + { + .rgb888 = 0x7beffe, + .rgb565 = 0x9F86, + .luma = 0xe0, + .hue = 124, + .chroma = 131 + }, + { + .rgb888 = 0x51395f, + .rgb565 = 0x0D5A, + .luma = 0x47, + .hue = 185, + .chroma = 38 + }, + { + .rgb888 = 0xffffff, + .rgb565 = 0xffff, + .luma = 0xff, + .chroma = 0 + }, + { + .rgb888 = 0x0736a0, + .rgb565 = 0xf501, + .luma = 0x44, + .hue = 147, + .chroma = 153 + }, +}; + +displayio_palette_t blinka_palette = { + .base = {.type = &displayio_palette_type }, + .colors = blinka_colors, + .color_count = 7, + .needs_refresh = false +}; + +displayio_tilegrid_t blinka_sprite = { + .base = {.type = &displayio_tilegrid_type }, + .bitmap = &blinka_bitmap, + .pixel_shader = &blinka_palette, + .x = 0, + .y = 0, + .pixel_width = 16, + .pixel_height = 16, + .bitmap_width_in_tiles = 1, + .width_in_tiles = 1, + .height_in_tiles = 1, + .tile_width = 16, + .tile_height = 16, + .top_left_x = 16, + .top_left_y = 16, + .tiles = 0, + .partial_change = false, + .full_change = false, + .first_draw = true, + .moved = false, + .inline_tiles = true, + .in_group = true +}; + +displayio_group_child_t splash_children[2] = { + {&blinka_sprite, &blinka_sprite}, + {&supervisor_terminal_text_grid, &supervisor_terminal_text_grid} +}; + +displayio_group_t circuitpython_splash = { + .base = {.type = &displayio_group_type }, + .x = 0, + .y = 0, + .scale = 2, + .size = 2, + .max_size = 2, + .children = splash_children, + .item_removed = false, + .in_group = false +}; diff --git a/supervisor/shared/display.h b/supervisor/shared/display.h new file mode 100644 index 00000000000..2a2ccf46df9 --- /dev/null +++ b/supervisor/shared/display.h @@ -0,0 +1,50 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SUPERVISOR_SHARED_DISPLAY_H +#define MICROPY_INCLUDED_SUPERVISOR_SHARED_DISPLAY_H + +#include "shared-bindings/displayio/Bitmap.h" +#include "shared-bindings/displayio/TileGrid.h" +#include "shared-bindings/fontio/BuiltinFont.h" +#include "shared-bindings/terminalio/Terminal.h" + +// These are autogenerated resources. + +// This is fixed so it doesn't need to be in RAM. +extern const fontio_builtinfont_t supervisor_terminal_font; + +// These will change so they must live in RAM. +extern displayio_bitmap_t supervisor_terminal_font_bitmap; +extern displayio_tilegrid_t supervisor_terminal_text_grid; +extern terminalio_terminal_obj_t supervisor_terminal; + +void supervisor_start_terminal(uint16_t width_px, uint16_t height_px); +void supervisor_stop_terminal(void); + +void supervisor_display_move_memory(void); + +#endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_DISPLAY_H diff --git a/supervisor/shared/external_flash/common_commands.h b/supervisor/shared/external_flash/common_commands.h new file mode 100644 index 00000000000..cc0da217599 --- /dev/null +++ b/supervisor/shared/external_flash/common_commands.h @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython 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. + */ +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_COMMON_COMMANDS_H +#define MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_COMMON_COMMANDS_H + +#define CMD_READ_JEDEC_ID 0x9f +#define CMD_READ_DATA 0x03 +#define CMD_FAST_READ_DATA 0x0B +#define CMD_SECTOR_ERASE 0x20 +// #define CMD_SECTOR_ERASE CMD_READ_JEDEC_ID +#define CMD_DISABLE_WRITE 0x04 +#define CMD_ENABLE_WRITE 0x06 +#define CMD_PAGE_PROGRAM 0x02 +// #define CMD_PAGE_PROGRAM CMD_READ_JEDEC_ID +#define CMD_READ_STATUS 0x05 +#define CMD_READ_STATUS2 0x35 +#define CMD_WRITE_STATUS_BYTE1 0x01 +#define CMD_WRITE_STATUS_BYTE2 0x31 +#define CMD_DUAL_READ 0x3b +#define CMD_QUAD_READ 0x6b +#define CMD_ENABLE_RESET 0x66 +#define CMD_RESET 0x99 + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_COMMON_COMMANDS_H diff --git a/supervisor/shared/external_flash/devices.h b/supervisor/shared/external_flash/devices.h new file mode 100644 index 00000000000..e787ba739ac --- /dev/null +++ b/supervisor/shared/external_flash/devices.h @@ -0,0 +1,445 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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. + */ +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_DEVICES_H +#define MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_DEVICES_H + +#include +#include + +typedef struct { + uint32_t total_size; + uint16_t start_up_time_us; + + // Three response bytes to 0x9f JEDEC ID command. + uint8_t manufacturer_id; + uint8_t memory_type; + uint8_t capacity; + + // Max clock speed for all operations and the fastest read mode. + uint8_t max_clock_speed_mhz; + + // Bitmask for Quad Enable bit if present. 0x00 otherwise. This is for the highest byte in the + // status register. + uint8_t quad_enable_bit_mask; + + bool has_sector_protection : 1; + + // Supports the 0x0b fast read command with 8 dummy cycles. + bool supports_fast_read : 1; + + // Supports the fast read, quad output command 0x6b with 8 dummy cycles. + bool supports_qspi : 1; + + // Supports the quad input page program command 0x32. This is known as 1-1-4 because it only + // uses all four lines for data. + bool supports_qspi_writes: 1; + + // Requires a separate command 0x31 to write to the second byte of the status register. + // Otherwise two byte are written via 0x01. + bool write_status_register_split: 1; + + // True when the status register is a single byte. This implies the Quad Enable bit is in the + // first byte and the Read Status Register 2 command (0x35) is unsupported. + bool single_status_byte: 1; +} external_flash_device; + +// Settings for the Adesto Tech AT25DF081A 1MiB SPI flash. It's on the SAMD21 +// Xplained board. +// Datasheet: https://www.adestotech.com/wp-content/uploads/doc8715.pdf +#define AT25DF081A {\ + .total_size = (1 << 20), /* 1 MiB */ \ + .start_up_time_us = 10000, \ + .manufacturer_id = 0x1f, \ + .memory_type = 0x45, \ + .capacity = 0x01, \ + .max_clock_speed_mhz = 85, \ + .quad_enable_bit_mask = 0x00, \ + .has_sector_protection = true, \ + .supports_fast_read = true, \ + .supports_qspi = false, \ + .supports_qspi_writes = false, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Gigadevice GD25Q16C 2MiB SPI flash. +// Datasheet: http://www.gigadevice.com/datasheet/gd25q16c/ +#define GD25Q16C {\ + .total_size = (1 << 21), /* 2 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xc8, \ + .memory_type = 0x40, \ + .capacity = 0x15, \ + .max_clock_speed_mhz = 104, /* if we need 120 then we can turn on high performance mode */ \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Gigadevice GD25Q32C 4MiB SPI flash. +// Datasheet: http://www.elm-tech.com/en/products/spi-flash-memory/gd25q32/gd25q32.pdf +#define GD25Q32C {\ + .total_size = (1 << 22), /* 4 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xc8, \ + .memory_type = 0x40, \ + .capacity = 0x16, \ + .max_clock_speed_mhz = 104, /* if we need 120 then we can turn on high performance mode */ \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = true, \ + .single_status_byte = false, \ +} + +// Settings for the Gigadevice GD25Q64C 8MiB SPI flash. +// Datasheet: http://www.elm-tech.com/en/products/spi-flash-memory/gd25q64/gd25q64.pdf +#define GD25Q64C {\ + .total_size = (1 << 23), /* 8 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xc8, \ + .memory_type = 0x40, \ + .capacity = 0x17, \ + .max_clock_speed_mhz = 104, /* if we need 120 then we can turn on high performance mode */ \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = true, \ + .single_status_byte = false, \ +} + +// Settings for the Cypress (was Spansion) S25FL064L 8MiB SPI flash. +// Datasheet: http://www.cypress.com/file/316661/download +#define S25FL064L {\ + .total_size = (1 << 23), /* 8 MiB */ \ + .start_up_time_us = 300, \ + .manufacturer_id = 0x01, \ + .memory_type = 0x60, \ + .capacity = 0x17, \ + .max_clock_speed_mhz = 108, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Cypress (was Spansion) S25FL116K 2MiB SPI flash. +// Datasheet: http://www.cypress.com/file/196886/download +#define S25FL116K {\ + .total_size = (1 << 21), /* 2 MiB */ \ + .start_up_time_us = 10000, \ + .manufacturer_id = 0x01, \ + .memory_type = 0x40, \ + .capacity = 0x15, \ + .max_clock_speed_mhz = 108, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = false, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Cypress (was Spansion) S25FL216K 2MiB SPI flash. +// Datasheet: http://www.cypress.com/file/197346/download +#define S25FL216K {\ + .total_size = (1 << 21), /* 2 MiB */ \ + .start_up_time_us = 10000, \ + .manufacturer_id = 0x01, \ + .memory_type = 0x40, \ + .capacity = 0x15, \ + .max_clock_speed_mhz = 65, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = false, \ + .supports_qspi_writes = false, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Winbond W25Q16FW 2MiB SPI flash. +// Datasheet: https://www.winbond.com/resource-files/w25q16fw%20revj%2005182017%20sfdp.pdf +#define W25Q16FW {\ + .total_size = (1 << 21), /* 2 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x60, \ + .capacity = 0x15, \ + .max_clock_speed_mhz = 133, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Winbond W25Q16JV-IQ 2MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) +// Datasheet: https://www.winbond.com/resource-files/w25q16jv%20spi%20revf%2005092017.pdf +#define W25Q16JV_IQ {\ + .total_size = (1 << 21), /* 2 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x40, \ + .capacity = 0x15, \ + .max_clock_speed_mhz = 133, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Winbond W25Q16JV-IM 2MiB SPI flash. Note that JV-IQ has a different .memory_type (0x40) +// Datasheet: https://www.winbond.com/resource-files/w25q16jv%20spi%20revf%2005092017.pdf +#define W25Q16JV_IM {\ + .total_size = (1 << 21), /* 2 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x70, \ + .capacity = 0x15, \ + .max_clock_speed_mhz = 133, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ +} + +// Settings for the Winbond W25Q32BV 4MiB SPI flash. +// Datasheet: https://www.winbond.com/resource-files/w25q32bv_revi_100413_wo_automotive.pdf +#define W25Q32BV {\ + .total_size = (1 << 22), /* 4 MiB */ \ + .start_up_time_us = 10000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x60, \ + .capacity = 0x16, \ + .max_clock_speed_mhz = 104, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = false, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} +// Settings for the Winbond W25Q32JV-IM 4MiB SPI flash. +// Datasheet: https://www.winbond.com/resource-files/w25q32jv%20revg%2003272018%20plus.pdf +#define W25Q32JV_IM {\ + .total_size = (1 << 22), /* 4 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x70, \ + .capacity = 0x16, \ + .max_clock_speed_mhz = 133, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ +} + +// Settings for the Winbond W25Q64JV-IM 8MiB SPI flash. Note that JV-IQ has a different .memory_type (0x40) +// Datasheet: http://www.winbond.com/resource-files/w25q64jv%20revj%2003272018%20plus.pdf +#define W25Q64JV_IM {\ + .total_size = (1 << 23), /* 8 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x70, \ + .capacity = 0x17, \ + .max_clock_speed_mhz = 133, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Winbond W25Q64JV-IQ 8MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) +// Datasheet: http://www.winbond.com/resource-files/w25q64jv%20revj%2003272018%20plus.pdf +#define W25Q64JV_IQ {\ + .total_size = (1 << 23), /* 8 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x40, \ + .capacity = 0x17, \ + .max_clock_speed_mhz = 133, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Winbond W25Q80DL 1MiB SPI flash. +// Datasheet: https://www.winbond.com/resource-files/w25q80dv%20dl_revh_10022015.pdf +#define W25Q80DL {\ + .total_size = (1 << 20), /* 1 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x60, \ + .capacity = 0x14, \ + .max_clock_speed_mhz = 104, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = false, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + + +// Settings for the Winbond W25Q128JV-SQ 16MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) +// Datasheet: https://www.winbond.com/resource-files/w25q128jv%20revf%2003272018%20plus.pdf +#define W25Q128JV_SQ {\ + .total_size = (1 << 24), /* 16 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x40, \ + .capacity = 0x18, \ + .max_clock_speed_mhz = 133, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} + +// Settings for the Macronix MX25L1606 2MiB SPI flash. +// Datasheet: +#define MX25L1606 {\ + .total_size = (1 << 21), /* 2 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xc2, \ + .memory_type = 0x20, \ + .capacity = 0x15, \ + .max_clock_speed_mhz = 8, \ + .quad_enable_bit_mask = 0x40, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = true, \ +} + +// Settings for the Macronix MX25L3233F 4MiB SPI flash. +// Datasheet: http://www.macronix.com/Lists/Datasheet/Attachments/7426/MX25L3233F,%203V,%2032Mb,%20v1.6.pdf +#define MX25L3233F {\ + .total_size = (1 << 22), /* 4 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xc2, \ + .memory_type = 0x20, \ + .capacity = 0x16, \ + .max_clock_speed_mhz = 133, \ + .quad_enable_bit_mask = 0x40, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = true, \ +} + +// Settings for the Macronix MX25R6435F 8MiB SPI flash. +// Datasheet: http://www.macronix.com/Lists/Datasheet/Attachments/7428/MX25R6435F,%20Wide%20Range,%2064Mb,%20v1.4.pdf +// By default its in lower power mode which can only do 8mhz. In high power mode it can do 80mhz. +#define MX25R6435F {\ + .total_size = (1 << 23), /* 8 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xc2, \ + .memory_type = 0x28, \ + .capacity = 0x17, \ + .max_clock_speed_mhz = 8, \ + .quad_enable_bit_mask = 0x40, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ + .single_status_byte = true, \ +} + +// Settings for the Winbond W25Q128JV-PM 16MiB SPI flash. Note that JV-IM has a different .memory_type (0x70) +// Datasheet: https://www.winbond.com/resource-files/w25q128jv%20revf%2003272018%20plus.pdf +#define W25Q128JV_PM {\ + .total_size = (1 << 24), /* 16 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x70, \ + .capacity = 0x18, \ + .max_clock_speed_mhz = 133, \ + .quad_enable_bit_mask = 0x02, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = true, \ + .supports_qspi_writes = true, \ + .write_status_register_split = false, \ +} + +// Settings for the Winbond W25Q32FV 4MiB SPI flash. +// Datasheet:http://www.winbond.com/resource-files/w25q32fv%20revj%2006032016.pdf?__locale=en +#define W25Q32FV {\ + .total_size = (1 << 22), /* 4 MiB */ \ + .start_up_time_us = 5000, \ + .manufacturer_id = 0xef, \ + .memory_type = 0x40, \ + .capacity = 0x16, \ + .max_clock_speed_mhz = 104, \ + .quad_enable_bit_mask = 0x00, \ + .has_sector_protection = false, \ + .supports_fast_read = true, \ + .supports_qspi = false, \ + .supports_qspi_writes = false, \ + .write_status_register_split = false, \ + .single_status_byte = false, \ +} +#endif // MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_DEVICES_H diff --git a/supervisor/shared/external_flash/external_flash.c b/supervisor/shared/external_flash/external_flash.c new file mode 100644 index 00000000000..ad10bab516d --- /dev/null +++ b/supervisor/shared/external_flash/external_flash.c @@ -0,0 +1,558 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016, 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "external_flash.h" + +#include +#include + +#include "supervisor/spi_flash_api.h" +#include "supervisor/shared/external_flash/common_commands.h" +#include "extmod/vfs.h" +#include "extmod/vfs_fat.h" +#include "py/misc.h" +#include "py/obj.h" +#include "py/runtime.h" +#include "lib/oofatfs/ff.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "supervisor/memory.h" +#include "supervisor/shared/rgb_led_status.h" + +#define NO_SECTOR_LOADED 0xFFFFFFFF + +// The currently cached sector in the cache, ram or flash based. +static uint32_t current_sector; + +const external_flash_device possible_devices[EXTERNAL_FLASH_DEVICE_COUNT] = {EXTERNAL_FLASH_DEVICES}; + +static const external_flash_device* flash_device = NULL; + +// Track which blocks (up to 32) in the current sector currently live in the +// cache. +static uint32_t dirty_mask; + +static supervisor_allocation* supervisor_cache = NULL; + +// Wait until both the write enable and write in progress bits have cleared. +static bool wait_for_flash_ready(void) { + uint8_t read_status_response[1] = {0x00}; + bool ok = true; + // Both the write enable and write in progress bits should be low. + do { + ok = spi_flash_read_command(CMD_READ_STATUS, read_status_response, 1); + } while (ok && (read_status_response[0] & 0x3) != 0); + return ok; +} + +// Turn on the write enable bit so we can program and erase the flash. +static bool write_enable(void) { + return spi_flash_command(CMD_ENABLE_WRITE); +} + +// Read data_length's worth of bytes starting at address into data. +static bool read_flash(uint32_t address, uint8_t* data, uint32_t data_length) { + if (flash_device == NULL) { + return false; + } + if (!wait_for_flash_ready()) { + return false; + } + return spi_flash_read_data(address, data, data_length); +} + +// Writes data_length's worth of bytes starting at address from data. Assumes +// that the sector that address resides in has already been erased. So make sure +// to run erase_sector. +static bool write_flash(uint32_t address, const uint8_t* data, uint32_t data_length) { + if (flash_device == NULL) { + return false; + } + // Don't bother writing if the data is all 1s. Thats equivalent to the flash + // state after an erase. + bool all_ones = true; + for (uint16_t i = 0; i < data_length; i++) { + if (data[i] != 0xff) { + all_ones = false; + break; + } + } + if (all_ones) { + return true; + } + + for (uint32_t bytes_written = 0; + bytes_written < data_length; + bytes_written += SPI_FLASH_PAGE_SIZE) { + if (!wait_for_flash_ready() || !write_enable()) { + return false; + } + + if (!spi_flash_write_data(address + bytes_written, (uint8_t*) data + bytes_written, + SPI_FLASH_PAGE_SIZE)) { + return false; + } + } + return true; +} + +static bool page_erased(uint32_t sector_address) { + // Check the first few bytes to catch the common case where there is data + // without using a bunch of memory. + uint8_t short_buffer[4]; + if (read_flash(sector_address, short_buffer, 4)) { + for (uint16_t i = 0; i < 4; i++) { + if (short_buffer[i] != 0xff) { + return false; + } + } + } else { + return false; + } + + // Now check the full length. + uint8_t full_buffer[FILESYSTEM_BLOCK_SIZE]; + if (read_flash(sector_address, full_buffer, FILESYSTEM_BLOCK_SIZE)) { + for (uint16_t i = 0; i < FILESYSTEM_BLOCK_SIZE; i++) { + if (short_buffer[i] != 0xff) { + return false; + } + } + } else { + return false; + } + return true; +} + +// Erases the given sector. Make sure you copied all of the data out of it you +// need! Also note, sector_address is really 24 bits. +static bool erase_sector(uint32_t sector_address) { + // Before we erase the sector we need to wait for any writes to finish and + // and then enable the write again. + if (!wait_for_flash_ready() || !write_enable()) { + return false; + } + + spi_flash_sector_command(CMD_SECTOR_ERASE, sector_address); + return true; +} + +// Sector is really 24 bits. +static bool copy_block(uint32_t src_address, uint32_t dest_address) { + // Copy page by page to minimize RAM buffer. + uint16_t page_size = SPI_FLASH_PAGE_SIZE; + uint8_t buffer[page_size]; + for (uint32_t i = 0; i < FILESYSTEM_BLOCK_SIZE / page_size; i++) { + if (!read_flash(src_address + i * page_size, buffer, page_size)) { + return false; + } + if (!write_flash(dest_address + i * page_size, buffer, page_size)) { + return false; + } + } + return true; +} + +void supervisor_flash_init(void) { + if (flash_device != NULL) { + return; + } + + // Delay to give the SPI Flash time to get going. + // TODO(tannewt): Only do this when we know power was applied vs a reset. + uint16_t max_start_up_delay_us = 0; + for (uint8_t i = 0; i < EXTERNAL_FLASH_DEVICE_COUNT; i++) { + if (possible_devices[i].start_up_time_us > max_start_up_delay_us) { + max_start_up_delay_us = possible_devices[i].start_up_time_us; + } + } + common_hal_mcu_delay_us(max_start_up_delay_us); + + spi_flash_init(); + + // The response will be 0xff if the flash needs more time to start up. + uint8_t jedec_id_response[3] = {0xff, 0xff, 0xff}; + while (jedec_id_response[0] == 0xff) { + spi_flash_read_command(CMD_READ_JEDEC_ID, jedec_id_response, 3); + } + + for (uint8_t i = 0; i < EXTERNAL_FLASH_DEVICE_COUNT; i++) { + const external_flash_device* possible_device = &possible_devices[i]; + if (jedec_id_response[0] == possible_device->manufacturer_id && + jedec_id_response[1] == possible_device->memory_type && + jedec_id_response[2] == possible_device->capacity) { + flash_device = possible_device; + break; + } + } + + if (flash_device == NULL) { + return; + } + + // We don't know what state the flash is in so wait for any remaining writes and then reset. + uint8_t read_status_response[1] = {0x00}; + // The write in progress bit should be low. + do { + spi_flash_read_command(CMD_READ_STATUS, read_status_response, 1); + } while ((read_status_response[0] & 0x1) != 0); + // The suspended write/erase bit should be low. + do { + spi_flash_read_command(CMD_READ_STATUS2, read_status_response, 1); + } while ((read_status_response[0] & 0x80) != 0); + + + spi_flash_command(CMD_ENABLE_RESET); + spi_flash_command(CMD_RESET); + + // Wait 30us for the reset + common_hal_mcu_delay_us(30); + + spi_flash_init_device(flash_device); + + // Activity LED for flash writes. +#ifdef MICROPY_HW_LED_MSC + gpio_set_pin_function(SPI_FLASH_CS_PIN, GPIO_PIN_FUNCTION_OFF); + gpio_set_pin_direction(MICROPY_HW_LED_MSC, GPIO_DIRECTION_OUT); + // There's already a pull-up on the board. + gpio_set_pin_level(MICROPY_HW_LED_MSC, false); +#endif + + if (flash_device->has_sector_protection) { + write_enable(); + + // Turn off sector protection + uint8_t data[1] = {0x00}; + spi_flash_write_command(CMD_WRITE_STATUS_BYTE1, data, 1); + } + + // Turn off writes in case this is a microcontroller only reset. + spi_flash_command(CMD_DISABLE_WRITE); + + wait_for_flash_ready(); + + current_sector = NO_SECTOR_LOADED; + dirty_mask = 0; + MP_STATE_VM(flash_ram_cache) = NULL; +} + +// The size of each individual block. +uint32_t supervisor_flash_get_block_size(void) { + return FILESYSTEM_BLOCK_SIZE; +} + +// The total number of available blocks. +uint32_t supervisor_flash_get_block_count(void) { + // We subtract one erase sector size because we may use it as a staging area + // for writes. + return (flash_device->total_size - SPI_FLASH_ERASE_SIZE) / FILESYSTEM_BLOCK_SIZE; +} + +// Flush the cache that was written to the scratch portion of flash. Only used +// when ram is tight. +static bool flush_scratch_flash(void) { + if (current_sector == NO_SECTOR_LOADED) { + return true; + } + // First, copy out any blocks that we haven't touched from the sector we've + // cached. + bool copy_to_scratch_ok = true; + uint32_t scratch_sector = flash_device->total_size - SPI_FLASH_ERASE_SIZE; + for (uint8_t i = 0; i < SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE; i++) { + if ((dirty_mask & (1 << i)) == 0) { + copy_to_scratch_ok = copy_to_scratch_ok && + copy_block(current_sector + i * FILESYSTEM_BLOCK_SIZE, + scratch_sector + i * FILESYSTEM_BLOCK_SIZE); + } + } + if (!copy_to_scratch_ok) { + // TODO(tannewt): Do more here. We opted to not erase and copy bad data + // in. We still risk losing the data written to the scratch sector. + return false; + } + // Second, erase the current sector. + erase_sector(current_sector); + // Finally, copy the new version into it. + for (uint8_t i = 0; i < SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE; i++) { + copy_block(scratch_sector + i * FILESYSTEM_BLOCK_SIZE, + current_sector + i * FILESYSTEM_BLOCK_SIZE); + } + return true; +} + +// Attempts to allocate a new set of page buffers for caching a full sector in +// ram. Each page is allocated separately so that the GC doesn't need to provide +// one huge block. We can free it as we write if we want to also. +static bool allocate_ram_cache(void) { + uint8_t blocks_per_sector = SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE; + uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE; + + uint32_t table_size = blocks_per_sector * pages_per_block * sizeof(uint32_t); + // Attempt to allocate outside the heap first. + supervisor_cache = allocate_memory(table_size + SPI_FLASH_ERASE_SIZE, false); + if (supervisor_cache != NULL) { + MP_STATE_VM(flash_ram_cache) = (uint8_t **) supervisor_cache->ptr; + uint8_t* page_start = (uint8_t *) supervisor_cache->ptr + table_size; + + for (uint8_t i = 0; i < blocks_per_sector; i++) { + for (uint8_t j = 0; j < pages_per_block; j++) { + uint32_t offset = i * pages_per_block + j; + MP_STATE_VM(flash_ram_cache)[offset] = page_start + offset * SPI_FLASH_PAGE_SIZE; + } + } + return true; + } + + MP_STATE_VM(flash_ram_cache) = m_malloc_maybe(blocks_per_sector * pages_per_block * sizeof(uint32_t), false); + if (MP_STATE_VM(flash_ram_cache) == NULL) { + return false; + } + // Declare i and j outside the loops in case we fail to allocate everything + // we need. In that case we'll give it back. + uint8_t i = 0; + uint8_t j = 0; + bool success = true; + for (i = 0; i < blocks_per_sector; i++) { + for (j = 0; j < pages_per_block; j++) { + uint8_t *page_cache = m_malloc_maybe(SPI_FLASH_PAGE_SIZE, false); + if (page_cache == NULL) { + success = false; + break; + } + MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j] = page_cache; + } + if (!success) { + break; + } + } + // We couldn't allocate enough so give back what we got. + if (!success) { + // We add 1 so that we delete 0 when i is 1. Going to zero (i >= 0) + // would never stop because i is unsigned. + i++; + for (; i > 0; i--) { + for (; j > 0; j--) { + m_free(MP_STATE_VM(flash_ram_cache)[(i - 1) * pages_per_block + (j - 1)]); + } + j = pages_per_block; + } + m_free(MP_STATE_VM(flash_ram_cache)); + MP_STATE_VM(flash_ram_cache) = NULL; + } + return success; +} + +static void release_ram_cache(void) { + if (supervisor_cache != NULL) { + free_memory(supervisor_cache); + supervisor_cache = NULL; + } else { + m_free(MP_STATE_VM(flash_ram_cache)); + } + MP_STATE_VM(flash_ram_cache) = NULL; +} + +// Flush the cached sector from ram onto the flash. We'll free the cache unless +// keep_cache is true. +static bool flush_ram_cache(bool keep_cache) { + if (current_sector == NO_SECTOR_LOADED) { + if (!keep_cache) { + release_ram_cache(); + } + return true; + } + // First, copy out any blocks that we haven't touched from the sector + // we've cached. If we don't do this we'll erase the data during the sector + // erase below. + bool copy_to_ram_ok = true; + uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE; + for (uint8_t i = 0; i < SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE; i++) { + if ((dirty_mask & (1 << i)) == 0) { + for (uint8_t j = 0; j < pages_per_block; j++) { + copy_to_ram_ok = read_flash( + current_sector + (i * pages_per_block + j) * SPI_FLASH_PAGE_SIZE, + MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j], + SPI_FLASH_PAGE_SIZE); + if (!copy_to_ram_ok) { + break; + } + } + } + if (!copy_to_ram_ok) { + break; + } + } + + if (!copy_to_ram_ok) { + return false; + } + // Second, erase the current sector. + erase_sector(current_sector); + // Lastly, write all the data in ram that we've cached. + for (uint8_t i = 0; i < SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE; i++) { + for (uint8_t j = 0; j < pages_per_block; j++) { + write_flash(current_sector + (i * pages_per_block + j) * SPI_FLASH_PAGE_SIZE, + MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j], + SPI_FLASH_PAGE_SIZE); + if (!keep_cache && supervisor_cache == NULL) { + m_free(MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j]); + } + } + } + // We're done with the cache for now so give it back. + if (!keep_cache) { + release_ram_cache(); + } + return true; +} + +// Delegates to the correct flash flush method depending on the existing cache. +static void spi_flash_flush_keep_cache(bool keep_cache) { + #ifdef MICROPY_HW_LED_MSC + port_pin_set_output_level(MICROPY_HW_LED_MSC, true); + #endif + temp_status_color(ACTIVE_WRITE); + // If we've cached to the flash itself flush from there. + if (MP_STATE_VM(flash_ram_cache) == NULL) { + flush_scratch_flash(); + } else { + flush_ram_cache(keep_cache); + } + current_sector = NO_SECTOR_LOADED; + clear_temp_status(); + #ifdef MICROPY_HW_LED_MSC + port_pin_set_output_level(MICROPY_HW_LED_MSC, false); + #endif +} + +void supervisor_flash_flush(void) { + spi_flash_flush_keep_cache(true); +} + +void supervisor_flash_release_cache(void) { + spi_flash_flush_keep_cache(false); +} + +static int32_t convert_block_to_flash_addr(uint32_t block) { + if (0 <= block && block < supervisor_flash_get_block_count()) { + // a block in partition 1 + return block * FILESYSTEM_BLOCK_SIZE; + } + // bad block + return -1; +} + +bool external_flash_read_block(uint8_t *dest, uint32_t block) { + int32_t address = convert_block_to_flash_addr(block); + if (address == -1) { + // bad block number + return false; + } + + // Mask out the lower bits that designate the address within the sector. + uint32_t this_sector = address & (~(SPI_FLASH_ERASE_SIZE - 1)); + uint8_t block_index = (address / FILESYSTEM_BLOCK_SIZE) % (SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE); + uint8_t mask = 1 << (block_index); + // We're reading from the currently cached sector. + if (current_sector == this_sector && (mask & dirty_mask) > 0) { + if (MP_STATE_VM(flash_ram_cache) != NULL) { + uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE; + for (int i = 0; i < pages_per_block; i++) { + memcpy(dest + i * SPI_FLASH_PAGE_SIZE, + MP_STATE_VM(flash_ram_cache)[block_index * pages_per_block + i], + SPI_FLASH_PAGE_SIZE); + } + return true; + } else { + uint32_t scratch_address = flash_device->total_size - SPI_FLASH_ERASE_SIZE + block_index * FILESYSTEM_BLOCK_SIZE; + return read_flash(scratch_address, dest, FILESYSTEM_BLOCK_SIZE); + } + } + return read_flash(address, dest, FILESYSTEM_BLOCK_SIZE); +} + +bool external_flash_write_block(const uint8_t *data, uint32_t block) { + // Non-MBR block, copy to cache + int32_t address = convert_block_to_flash_addr(block); + if (address == -1) { + // bad block number + return false; + } + // Wait for any previous writes to finish. + wait_for_flash_ready(); + // Mask out the lower bits that designate the address within the sector. + uint32_t this_sector = address & (~(SPI_FLASH_ERASE_SIZE - 1)); + uint8_t block_index = (address / FILESYSTEM_BLOCK_SIZE) % (SPI_FLASH_ERASE_SIZE / FILESYSTEM_BLOCK_SIZE); + uint8_t mask = 1 << (block_index); + // Flush the cache if we're moving onto a sector or we're writing the + // same block again. + if (current_sector != this_sector || (mask & dirty_mask) > 0) { + // Check to see if we'd write to an erased page. In that case we + // can write directly. + if (page_erased(address)) { + return write_flash(address, data, FILESYSTEM_BLOCK_SIZE); + } + if (current_sector != NO_SECTOR_LOADED) { + supervisor_flash_flush(); + } + if (MP_STATE_VM(flash_ram_cache) == NULL && !allocate_ram_cache()) { + erase_sector(flash_device->total_size - SPI_FLASH_ERASE_SIZE); + wait_for_flash_ready(); + } + current_sector = this_sector; + dirty_mask = 0; + } + dirty_mask |= mask; + // Copy the block to the appropriate cache. + if (MP_STATE_VM(flash_ram_cache) != NULL) { + uint8_t pages_per_block = FILESYSTEM_BLOCK_SIZE / SPI_FLASH_PAGE_SIZE; + for (int i = 0; i < pages_per_block; i++) { + memcpy(MP_STATE_VM(flash_ram_cache)[block_index * pages_per_block + i], + data + i * SPI_FLASH_PAGE_SIZE, + SPI_FLASH_PAGE_SIZE); + } + return true; + } else { + uint32_t scratch_address = flash_device->total_size - SPI_FLASH_ERASE_SIZE + block_index * FILESYSTEM_BLOCK_SIZE; + return write_flash(scratch_address, data, FILESYSTEM_BLOCK_SIZE); + } +} + +mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) { + for (size_t i = 0; i < num_blocks; i++) { + if (!external_flash_read_block(dest + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) { + return 1; // error + } + } + return 0; // success +} + +mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) { + for (size_t i = 0; i < num_blocks; i++) { + if (!external_flash_write_block(src + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) { + return 1; // error + } + } + return 0; // success +} diff --git a/supervisor/shared/external_flash/external_flash.h b/supervisor/shared/external_flash/external_flash.h new file mode 100644 index 00000000000..72b619a2a8b --- /dev/null +++ b/supervisor/shared/external_flash/external_flash.h @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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. + */ +#ifndef MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_H +#define MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_H + +#include +#include + +#include "py/mpconfig.h" + +// Erase sector size. +#define SPI_FLASH_SECTOR_SIZE (0x1000 - 100) + +// These are common across all NOR Flash. +#define SPI_FLASH_ERASE_SIZE (1 << 12) +#define SPI_FLASH_PAGE_SIZE (256) + +#define SPI_FLASH_SYSTICK_MASK (0x1ff) // 512ms +#define SPI_FLASH_IDLE_TICK(tick) (((tick) & SPI_FLASH_SYSTICK_MASK) == 2) + +#ifndef SPI_FLASH_MAX_BAUDRATE +#define SPI_FLASH_MAX_BAUDRATE 8000000 +#endif + +#endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_H diff --git a/supervisor/shared/external_flash/external_flash_root_pointers.h b/supervisor/shared/external_flash/external_flash_root_pointers.h new file mode 100644 index 00000000000..cb1b86d1935 --- /dev/null +++ b/supervisor/shared/external_flash/external_flash_root_pointers.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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. + */ +#ifndef MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_ROOT_POINTERS_H +#define MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_ROOT_POINTERS_H + +#include + +// We use this when we can allocate the whole cache in RAM. +#define FLASH_ROOT_POINTERS \ + uint8_t** flash_ram_cache; \ + +#endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_EXTERNAL_FLASH_ROOT_POINTERS_H diff --git a/supervisor/shared/external_flash/qspi_flash.c b/supervisor/shared/external_flash/qspi_flash.c new file mode 100644 index 00000000000..48266540c42 --- /dev/null +++ b/supervisor/shared/external_flash/qspi_flash.c @@ -0,0 +1,56 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016, 2017, 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/spi_flash_api.h" + +#include "supervisor/shared/external_flash/common_commands.h" + +void check_quad_enable(const external_flash_device* device) { + if (device->quad_enable_bit_mask == 0x00) { + return; + } + + // Verify that QSPI mode is enabled. + uint8_t status; + if (device->single_status_byte) { + spi_flash_read_command(CMD_READ_STATUS, &status, 1); + } else { + spi_flash_read_command(CMD_READ_STATUS2, &status, 1); + } + + // Check the quad enable bit. + if ((status & device->quad_enable_bit_mask) == 0) { + uint8_t full_status[2] = {0x00, device->quad_enable_bit_mask}; + spi_flash_command(CMD_ENABLE_WRITE); + if (device->write_status_register_split) { + spi_flash_write_command(CMD_WRITE_STATUS_BYTE2, full_status + 1, 1); + } else if (device->single_status_byte) { + spi_flash_write_command(CMD_WRITE_STATUS_BYTE1, full_status + 1, 1); + } else { + spi_flash_write_command(CMD_WRITE_STATUS_BYTE1, full_status, 2); + } + } +} diff --git a/supervisor/shared/external_flash/qspi_flash.h b/supervisor/shared/external_flash/qspi_flash.h new file mode 100644 index 00000000000..b72e37b268c --- /dev/null +++ b/supervisor/shared/external_flash/qspi_flash.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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. + */ +#ifndef MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_QSPI_FLASH_H +#define MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_QSPI_FLASH_H + +void check_quad_enable(const external_flash_device* device); + +#endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_EXTERNAL_FLASH_QSPI_FLASH_H diff --git a/supervisor/shared/external_flash/spi_flash.c b/supervisor/shared/external_flash/spi_flash.c new file mode 100644 index 00000000000..12888f2d334 --- /dev/null +++ b/supervisor/shared/external_flash/spi_flash.c @@ -0,0 +1,154 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016, 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/spi_flash_api.h" + +#include +#include + +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "supervisor/shared/external_flash/common_commands.h" +#include "supervisor/shared/external_flash/external_flash.h" +#include "py/mpconfig.h" + +digitalio_digitalinout_obj_t cs_pin; +busio_spi_obj_t spi; + +const external_flash_device* flash_device; +uint32_t spi_flash_baudrate; + +// Enable the flash over SPI. +static void flash_enable(void) { + while (!common_hal_busio_spi_try_lock(&spi)) {} + common_hal_digitalio_digitalinout_set_value(&cs_pin, false); +} + +// Disable the flash over SPI. +static void flash_disable(void) { + common_hal_digitalio_digitalinout_set_value(&cs_pin, true); + common_hal_busio_spi_unlock(&spi); +} + +static bool transfer(uint8_t* command, uint32_t command_length, uint8_t* data_in, uint8_t* data_out, uint32_t data_length) { + flash_enable(); + bool status = common_hal_busio_spi_write(&spi, command, command_length); + if (status) { + if (data_in != NULL && data_out != NULL) { + status = common_hal_busio_spi_transfer(&spi, data_out, data_in, data_length); + } else if (data_out != NULL) { + status = common_hal_busio_spi_read(&spi, data_out, data_length, 0xff); + } else if (data_in != NULL) { + status = common_hal_busio_spi_write(&spi, data_in, data_length); + } + } + flash_disable(); + return status; +} + +static bool transfer_command(uint8_t command, uint8_t* data_in, uint8_t* data_out, uint32_t data_length) { + return transfer(&command, 1, data_in, data_out, data_length); +} + +bool spi_flash_command(uint8_t command) { + return transfer_command(command, NULL, NULL, 0); +} + +bool spi_flash_read_command(uint8_t command, uint8_t* data, uint32_t data_length) { + return transfer_command(command, NULL, data, data_length); +} + +bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t data_length) { + return transfer_command(command, data, NULL, data_length); +} + +// Pack the low 24 bits of the address into a uint8_t array. +static void address_to_bytes(uint32_t address, uint8_t* bytes) { + bytes[0] = (address >> 16) & 0xff; + bytes[1] = (address >> 8) & 0xff; + bytes[2] = address & 0xff; +} + +bool spi_flash_sector_command(uint8_t command, uint32_t address) { + uint8_t request[4] = {command, 0x00, 0x00, 0x00}; + address_to_bytes(address, request + 1); + return transfer(request, 4, NULL, NULL, 0); +} + +bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t data_length) { + uint8_t request[4] = {CMD_PAGE_PROGRAM, 0x00, 0x00, 0x00}; + // Write the SPI flash write address into the bytes following the command byte. + address_to_bytes(address, request + 1); + flash_enable(); + common_hal_busio_spi_configure(&spi, spi_flash_baudrate, 0, 0, 8); + bool status = common_hal_busio_spi_write(&spi, request, 4); + if (status) { + status = common_hal_busio_spi_write(&spi, data, data_length); + } + flash_disable(); + return status; +} + +bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t data_length) { + uint8_t request[5] = {CMD_READ_DATA, 0x00, 0x00, 0x00}; + uint8_t command_length = 4; + if (flash_device->supports_fast_read) { + request[0] = CMD_FAST_READ_DATA; + command_length = 5; + } + // Write the SPI flash write address into the bytes following the command byte. + address_to_bytes(address, request + 1); + flash_enable(); + common_hal_busio_spi_configure(&spi, spi_flash_baudrate, 0, 0, 8); + bool status = common_hal_busio_spi_write(&spi, request, command_length); + if (status) { + status = common_hal_busio_spi_read(&spi, data, data_length, 0xff); + } + flash_disable(); + return status; +} + +void spi_flash_init(void) { + cs_pin.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&cs_pin, SPI_FLASH_CS_PIN); + + + // Set CS high (disabled). + common_hal_digitalio_digitalinout_switch_to_output(&cs_pin, true, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_never_reset(&cs_pin); + + spi.base.type = &busio_spi_type; + common_hal_busio_spi_construct(&spi, SPI_FLASH_SCK_PIN, SPI_FLASH_MOSI_PIN, SPI_FLASH_MISO_PIN); + common_hal_busio_spi_never_reset(&spi); +} + +void spi_flash_init_device(const external_flash_device* device) { + flash_device = device; + spi_flash_baudrate = device->max_clock_speed_mhz * 1000000; + if (spi_flash_baudrate > SPI_FLASH_MAX_BAUDRATE) { + spi_flash_baudrate = SPI_FLASH_MAX_BAUDRATE; + } +} diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c new file mode 100644 index 00000000000..c50d7f4eeb2 --- /dev/null +++ b/supervisor/shared/filesystem.c @@ -0,0 +1,168 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/filesystem.h" + +#include "extmod/vfs_fat.h" +#include "lib/oofatfs/ff.h" +#include "lib/oofatfs/diskio.h" + +#include "py/mpstate.h" + +#include "supervisor/flash.h" + +static mp_vfs_mount_t _mp_vfs; +static fs_user_mount_t _internal_vfs; + +static volatile uint32_t filesystem_flush_interval_ms = CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS; +volatile bool filesystem_flush_requested = false; + +void filesystem_background(void) { + if (filesystem_flush_requested) { + filesystem_flush_interval_ms = CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS; + // Flush but keep caches + supervisor_flash_flush(); + filesystem_flush_requested = false; + } +} + +inline void filesystem_tick(void) { + if (filesystem_flush_interval_ms == 0) { + // 0 means not turned on. + return; + } + if (filesystem_flush_interval_ms == 1) { + filesystem_flush_requested = true; + filesystem_flush_interval_ms = CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS; + } else { + filesystem_flush_interval_ms--; + } +} + + +static void make_empty_file(FATFS *fatfs, const char *path) { + FIL fp; + f_open(fatfs, &fp, path, FA_WRITE | FA_CREATE_ALWAYS); + f_close(&fp); +} + +// we don't make this function static because it needs a lot of stack and we +// want it to be executed without using stack within main() function +void filesystem_init(bool create_allowed, bool force_create) { + // init the vfs object + fs_user_mount_t *vfs_fat = &_internal_vfs; + vfs_fat->flags = 0; + supervisor_flash_init_vfs(vfs_fat); + + // try to mount the flash + FRESULT res = f_mount(&vfs_fat->fatfs); + + if ((res == FR_NO_FILESYSTEM && create_allowed) || force_create) { + // No filesystem so create a fresh one, or reformat has been requested. + uint8_t working_buf[_MAX_SS]; + res = f_mkfs(&vfs_fat->fatfs, FM_FAT, 0, working_buf, sizeof(working_buf)); + // Flush the new file system to make sure it's repaired immediately. + supervisor_flash_flush(); + if (res != FR_OK) { + return; + } + + // set label + f_setlabel(&vfs_fat->fatfs, "CIRCUITPY"); + + // inhibit file indexing on MacOS + f_mkdir(&vfs_fat->fatfs, "/.fseventsd"); + make_empty_file(&vfs_fat->fatfs, "/.metadata_never_index"); + make_empty_file(&vfs_fat->fatfs, "/.Trashes"); + make_empty_file(&vfs_fat->fatfs, "/.fseventsd/no_log"); + + // create empty lib directory + f_mkdir(&vfs_fat->fatfs, "/lib"); + + // and ensure everything is flushed + supervisor_flash_flush(); + } else if (res != FR_OK) { + return; + } + mp_vfs_mount_t *vfs = &_mp_vfs; + vfs->str = "/"; + vfs->len = 1; + vfs->obj = MP_OBJ_FROM_PTR(vfs_fat); + vfs->next = NULL; + MP_STATE_VM(vfs_mount_table) = vfs; + + // The current directory is used as the boot up directory. + // It is set to the internal flash filesystem by default. + MP_STATE_PORT(vfs_cur) = vfs; +} + +void filesystem_flush(void) { + // Reset interval before next flush. + filesystem_flush_interval_ms = CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS; + supervisor_flash_flush(); + // Don't keep caches because this is called when starting or stopping the VM. + supervisor_flash_release_cache(); +} + +void filesystem_set_internal_writable_by_usb(bool writable) { + fs_user_mount_t *vfs = &_internal_vfs; + + filesystem_set_writable_by_usb(vfs, writable); +} + +void filesystem_set_writable_by_usb(fs_user_mount_t *vfs, bool usb_writable) { + if (usb_writable) { + vfs->flags |= FSUSER_USB_WRITABLE; + } else { + vfs->flags &= ~FSUSER_USB_WRITABLE; + } +} + +bool filesystem_is_writable_by_python(fs_user_mount_t *vfs) { + return (vfs->flags & FSUSER_CONCURRENT_WRITE_PROTECTED) == 0 || + (vfs->flags & FSUSER_USB_WRITABLE) == 0; +} + +bool filesystem_is_writable_by_usb(fs_user_mount_t *vfs) { + return (vfs->flags & FSUSER_CONCURRENT_WRITE_PROTECTED) == 0 || + (vfs->flags & FSUSER_USB_WRITABLE) != 0; +} + +void filesystem_set_internal_concurrent_write_protection(bool concurrent_write_protection) { + filesystem_set_concurrent_write_protection(&_internal_vfs, concurrent_write_protection); +} + +void filesystem_set_concurrent_write_protection(fs_user_mount_t *vfs, bool concurrent_write_protection) { + if (concurrent_write_protection) { + vfs->flags |= FSUSER_CONCURRENT_WRITE_PROTECTED; + } else { + vfs->flags &= ~FSUSER_CONCURRENT_WRITE_PROTECTED; + } +} + +bool filesystem_present(void) { + return true; +} diff --git a/supervisor/shared/flash.c b/supervisor/shared/flash.c new file mode 100644 index 00000000000..6b1f24b4bcc --- /dev/null +++ b/supervisor/shared/flash.c @@ -0,0 +1,182 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft + * + * 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 "supervisor/flash.h" + +#include "extmod/vfs_fat.h" +#include "py/runtime.h" +#include "lib/oofatfs/ff.h" + +#define VFS_INDEX 0 + +#define PART1_START_BLOCK (0x1) + +// there is a singleton Flash object +const mp_obj_type_t supervisor_flash_type; +STATIC const mp_obj_base_t supervisor_flash_obj = {&supervisor_flash_type}; + +STATIC mp_obj_t supervisor_flash_obj_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + // check arguments + mp_arg_check_num(n_args, kw_args, 0, 0, false); + + // return singleton object + return (mp_obj_t)&supervisor_flash_obj; +} + +uint32_t flash_get_block_count(void) { + return PART1_START_BLOCK + supervisor_flash_get_block_count(); +} + +static void build_partition(uint8_t *buf, int boot, int type, uint32_t start_block, uint32_t num_blocks) { + buf[0] = boot; + + if (num_blocks == 0) { + buf[1] = 0; + buf[2] = 0; + buf[3] = 0; + } else { + buf[1] = 0xff; + buf[2] = 0xff; + buf[3] = 0xff; + } + + buf[4] = type; + + if (num_blocks == 0) { + buf[5] = 0; + buf[6] = 0; + buf[7] = 0; + } else { + buf[5] = 0xff; + buf[6] = 0xff; + buf[7] = 0xff; + } + + buf[8] = start_block; + buf[9] = start_block >> 8; + buf[10] = start_block >> 16; + buf[11] = start_block >> 24; + + buf[12] = num_blocks; + buf[13] = num_blocks >> 8; + buf[14] = num_blocks >> 16; + buf[15] = num_blocks >> 24; +} + +mp_uint_t flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) { + if (block_num == 0) { + if (block_num > 1) { + return 1; // error + } + // fake the MBR so we can decide on our own partition table + + for (int i = 0; i < 446; i++) { + dest[i] = 0; + } + + build_partition(dest + 446, 0, 0x01 /* FAT12 */, PART1_START_BLOCK, supervisor_flash_get_block_count()); + build_partition(dest + 462, 0, 0, 0, 0); + build_partition(dest + 478, 0, 0, 0, 0); + build_partition(dest + 494, 0, 0, 0, 0); + + dest[510] = 0x55; + dest[511] = 0xaa; + + return 0; // ok + + } + return supervisor_flash_read_blocks(dest, block_num - PART1_START_BLOCK, num_blocks); +} + +mp_uint_t flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) { + if (block_num == 0) { + if (num_blocks > 1) { + return 1; // error + } + // can't write MBR, but pretend we did + return 0; + } else { + return supervisor_flash_write_blocks(src, block_num - PART1_START_BLOCK, num_blocks); + } +} + +STATIC mp_obj_t supervisor_flash_obj_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE); + mp_uint_t ret = flash_read_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE); + return MP_OBJ_NEW_SMALL_INT(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_readblocks_obj, supervisor_flash_obj_readblocks); + +STATIC mp_obj_t supervisor_flash_obj_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ); + mp_uint_t ret = flash_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE); + return MP_OBJ_NEW_SMALL_INT(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_writeblocks_obj, supervisor_flash_obj_writeblocks); + +STATIC mp_obj_t supervisor_flash_obj_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) { + mp_int_t cmd = mp_obj_get_int(cmd_in); + switch (cmd) { + case BP_IOCTL_INIT: supervisor_flash_init(); return MP_OBJ_NEW_SMALL_INT(0); + case BP_IOCTL_DEINIT: supervisor_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0); // TODO properly + case BP_IOCTL_SYNC: supervisor_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0); + case BP_IOCTL_SEC_COUNT: return MP_OBJ_NEW_SMALL_INT(flash_get_block_count()); + case BP_IOCTL_SEC_SIZE: return MP_OBJ_NEW_SMALL_INT(supervisor_flash_get_block_size()); + default: return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_ioctl_obj, supervisor_flash_obj_ioctl); + +STATIC const mp_rom_map_elem_t supervisor_flash_obj_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&supervisor_flash_obj_readblocks_obj) }, + { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&supervisor_flash_obj_writeblocks_obj) }, + { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&supervisor_flash_obj_ioctl_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(supervisor_flash_obj_locals_dict, supervisor_flash_obj_locals_dict_table); + +const mp_obj_type_t supervisor_flash_type = { + { &mp_type_type }, + .name = MP_QSTR_Flash, + .make_new = supervisor_flash_obj_make_new, + .locals_dict = (mp_obj_t)&supervisor_flash_obj_locals_dict, +}; + +void supervisor_flash_init_vfs(fs_user_mount_t *vfs) { + vfs->base.type = &mp_fat_vfs_type; + vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL; + vfs->fatfs.drv = vfs; + vfs->fatfs.part = 1; // flash filesystem lives on first partition + vfs->readblocks[0] = (mp_obj_t)&supervisor_flash_obj_readblocks_obj; + vfs->readblocks[1] = (mp_obj_t)&supervisor_flash_obj; + vfs->readblocks[2] = (mp_obj_t)flash_read_blocks; // native version + vfs->writeblocks[0] = (mp_obj_t)&supervisor_flash_obj_writeblocks_obj; + vfs->writeblocks[1] = (mp_obj_t)&supervisor_flash_obj; + vfs->writeblocks[2] = (mp_obj_t)flash_write_blocks; // native version + vfs->u.ioctl[0] = (mp_obj_t)&supervisor_flash_obj_ioctl_obj; + vfs->u.ioctl[1] = (mp_obj_t)&supervisor_flash_obj; +} diff --git a/supervisor/shared/memory.c b/supervisor/shared/memory.c new file mode 100755 index 00000000000..11133415d1b --- /dev/null +++ b/supervisor/shared/memory.c @@ -0,0 +1,122 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/memory.h" + +#include + +#include "supervisor/shared/display.h" + +#define CIRCUITPY_SUPERVISOR_ALLOC_COUNT 8 + +static supervisor_allocation allocations[CIRCUITPY_SUPERVISOR_ALLOC_COUNT]; +// We use uint32_t* to ensure word (4 byte) alignment. +uint32_t* low_address; +uint32_t* high_address; +extern uint32_t _ebss; +extern uint32_t _estack; + +void memory_init(void) { + low_address = &_ebss; + high_address = &_estack; +} + +void free_memory(supervisor_allocation* allocation) { + int32_t index = 0; + bool found = false; + for (index = 0; index < CIRCUITPY_SUPERVISOR_ALLOC_COUNT; index++) { + found = allocation == &allocations[index]; + if (found) { + break; + } + } + if (!found) { + // Bad! + // TODO(tannewt): Add a way to escape into safe mode on error. + } + if (allocation->ptr == high_address) { + high_address += allocation->length / 4; + for (index++; index < CIRCUITPY_SUPERVISOR_ALLOC_COUNT; index++) { + if (allocations[index].ptr != NULL) { + break; + } + high_address += allocations[index].length / 4; + } + } else if (allocation->ptr + allocation->length / 4 == low_address) { + low_address = allocation->ptr; + for (index--; index >= 0; index--) { + if (allocations[index].ptr != NULL) { + break; + } + low_address -= allocations[index].length / 4; + } + } else { + // Freed memory isn't in the middle so skip updating bounds. The memory will be added to the + // middle when the memory to the inside is freed. + } + allocation->ptr = NULL; +} + +supervisor_allocation* allocate_remaining_memory(void) { + if (low_address == high_address) { + return NULL; + } + return allocate_memory((high_address - low_address) * 4, false); +} + +supervisor_allocation* allocate_memory(uint32_t length, bool high) { + if ((high_address - low_address) * 4 < (int32_t) length || length % 4 != 0) { + return NULL; + } + uint8_t index = 0; + int8_t direction = 1; + if (high) { + index = CIRCUITPY_SUPERVISOR_ALLOC_COUNT - 1; + direction = -1; + } + for (; index < CIRCUITPY_SUPERVISOR_ALLOC_COUNT; index += direction) { + if (allocations[index].ptr == NULL) { + break; + } + } + if (index >= CIRCUITPY_SUPERVISOR_ALLOC_COUNT) { + return NULL; + } + supervisor_allocation* alloc = &allocations[index]; + if (high) { + high_address -= length / 4; + alloc->ptr = high_address; + } else { + alloc->ptr = low_address; + low_address += length / 4; + } + alloc->length = length; + return alloc; +} + +void supervisor_move_memory(void) { + supervisor_display_move_memory(); +} diff --git a/supervisor/shared/micropython.c b/supervisor/shared/micropython.c new file mode 100644 index 00000000000..245db11d421 --- /dev/null +++ b/supervisor/shared/micropython.c @@ -0,0 +1,58 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "supervisor/serial.h" +#include "lib/oofatfs/ff.h" +#include "py/mpconfig.h" + +#include "supervisor/shared/status_leds.h" + +int mp_hal_stdin_rx_chr(void) { + for (;;) { + #ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP + #endif + if (serial_bytes_available()) { + toggle_rx_led(); + return serial_read(); + } + } +} + +void mp_hal_stdout_tx_strn(const char *str, size_t len) { + toggle_tx_led(); + + #ifdef CIRCUITPY_BOOT_OUTPUT_FILE + if (boot_output_file != NULL) { + UINT bytes_written = 0; + f_write(boot_output_file, str, len, &bytes_written); + } + #endif + + serial_write_substring(str, len); +} diff --git a/supervisor/shared/rgb_led_colors.h b/supervisor/shared/rgb_led_colors.h new file mode 100644 index 00000000000..48994ad62cb --- /dev/null +++ b/supervisor/shared/rgb_led_colors.h @@ -0,0 +1,35 @@ +#define BLACK 0x000000 +#define GREEN 0x003000 +#define BLUE 0x000030 +#define CYAN 0x003030 +#define RED 0x300000 +#define ORANGE 0x302000 +#define YELLOW 0x303000 +#define PURPLE 0x300030 +#define WHITE 0x303030 + +#define BOOT_RUNNING BLUE +#define MAIN_RUNNING GREEN +#define SAFE_MODE YELLOW +#define ALL_DONE GREEN +#define REPL_RUNNING WHITE + +#define ACTIVE_WRITE 0x200000 + +#define ALL_GOOD_CYCLE_MS 2000u + +#define LINE_NUMBER_TOGGLE_LENGTH 300u +#define EXCEPTION_TYPE_LENGTH_MS 1000u + +#define THOUSANDS WHITE +#define HUNDREDS BLUE +#define TENS YELLOW +#define ONES CYAN + +#define INDENTATION_ERROR GREEN +#define SYNTAX_ERROR CYAN +#define NAME_ERROR WHITE +#define OS_ERROR ORANGE +#define VALUE_ERROR PURPLE +#define MPY_ERROR BLUE +#define OTHER_ERROR YELLOW diff --git a/supervisor/shared/rgb_led_status.c b/supervisor/shared/rgb_led_status.c new file mode 100644 index 00000000000..fd356cb48f2 --- /dev/null +++ b/supervisor/shared/rgb_led_status.c @@ -0,0 +1,443 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "mphalport.h" +#include "common-hal/microcontroller/Pin.h" +#include "rgb_led_status.h" + +#ifdef MICROPY_HW_NEOPIXEL +uint8_t rgb_status_brightness = 63; +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/neopixel_write/__init__.h" +static uint8_t status_neopixel_color[3]; +static digitalio_digitalinout_obj_t status_neopixel; +#endif + + +#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK) +uint8_t rgb_status_brightness = 255; + +#define APA102_BUFFER_LENGTH 12 +static uint8_t status_apa102_color[APA102_BUFFER_LENGTH] = {0, 0, 0, 0, 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0xff}; + +#if CIRCUITPY_BITBANG_APA102 +#include "shared-bindings/bitbangio/SPI.h" +#include "shared-module/bitbangio/types.h" +static bitbangio_spi_obj_t status_apa102; +#else +#include "shared-bindings/busio/SPI.h" +busio_spi_obj_t status_apa102; +#endif +#endif + +#if defined(CP_RGB_STATUS_R) || defined(CP_RGB_STATUS_G) || defined(CP_RGB_STATUS_B) +#define CP_RGB_STATUS_LED + +#include "shared-bindings/pulseio/PWMOut.h" +#include "shared-bindings/microcontroller/Pin.h" + +pulseio_pwmout_obj_t rgb_status_r; +pulseio_pwmout_obj_t rgb_status_g; +pulseio_pwmout_obj_t rgb_status_b; + +uint8_t rgb_status_brightness = 0xFF; + +uint16_t status_rgb_color[3] = { + 0 /* red */, 0 /* green */, 0 /* blue */ +}; +#endif + +#if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED)) +static uint32_t current_status_color = 0; +#endif + + +void rgb_led_status_init() { + #ifdef MICROPY_HW_NEOPIXEL + common_hal_digitalio_digitalinout_construct(&status_neopixel, MICROPY_HW_NEOPIXEL); + // Pretend we aren't using the pins. digitalio.DigitalInOut + // will mark them as used. + neopixel_in_use = false; + common_hal_digitalio_digitalinout_switch_to_output(&status_neopixel, false, DRIVE_MODE_PUSH_PULL); + #endif + #if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK) + #if CIRCUITPY_BITBANG_APA102 + shared_module_bitbangio_spi_construct(&status_apa102, + MICROPY_HW_APA102_SCK, + MICROPY_HW_APA102_MOSI, + mp_const_none); + #else + if (!common_hal_busio_spi_deinited(&status_apa102)) { + // Don't use spi_deinit because that leads to infinite + // recursion because reset_pin_number may call + // rgb_led_status_init. + spi_m_sync_disable(&status_apa102.spi_desc); + } + common_hal_busio_spi_construct(&status_apa102, + MICROPY_HW_APA102_SCK, + MICROPY_HW_APA102_MOSI, + mp_const_none); + #endif + // Pretend we aren't using the pins. bitbangio.SPI will + // mark them as used. + apa102_mosi_in_use = false; + apa102_sck_in_use = false; + #if CIRCUITPY_BITBANG_APA102 + shared_module_bitbangio_spi_try_lock(&status_apa102); + // Use 1MHz for clock rate. Some APA102's are spec'd 800kHz-1200kHz, + // though many can run much faster. bitbang will probably run slower. + shared_module_bitbangio_spi_configure(&status_apa102, 1000000, 0, 0, 8); + #else + common_hal_busio_spi_try_lock(&status_apa102); + common_hal_busio_spi_configure(&status_apa102, 1000000, 0, 0, 8); + #endif + #endif + + + #if defined(CP_RGB_STATUS_LED) + if (common_hal_mcu_pin_is_free(CP_RGB_STATUS_R)) { + pwmout_result_t red_result = common_hal_pulseio_pwmout_construct(&rgb_status_r, CP_RGB_STATUS_R, 0, 50000, false); + + if (PWMOUT_OK == red_result) { + common_hal_pulseio_pwmout_never_reset(&rgb_status_r); + } + } + + if (common_hal_mcu_pin_is_free(CP_RGB_STATUS_G)) { + pwmout_result_t green_result = common_hal_pulseio_pwmout_construct(&rgb_status_g, CP_RGB_STATUS_G, 0, 50000, false); + + if (PWMOUT_OK == green_result) { + common_hal_pulseio_pwmout_never_reset(&rgb_status_g); + } + } + + if (common_hal_mcu_pin_is_free(CP_RGB_STATUS_B)) { + pwmout_result_t blue_result = common_hal_pulseio_pwmout_construct(&rgb_status_b, CP_RGB_STATUS_B, 0, 50000, false); + + if (PWMOUT_OK == blue_result) { + common_hal_pulseio_pwmout_never_reset(&rgb_status_b); + } + } + #endif + + #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED)) + // Force a write of the current status color. + uint32_t rgb = current_status_color; + current_status_color = 0x1000000; // Not a valid color + new_status_color(rgb); + #endif +} + +void reset_status_led() { + #ifdef MICROPY_HW_NEOPIXEL + reset_pin_number(MICROPY_HW_NEOPIXEL->number); + #endif + #if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK) + reset_pin_number(MICROPY_HW_APA102_MOSI->number); + reset_pin_number(MICROPY_HW_APA102_SCK->number); + #endif + #if defined(CP_RGB_STATUS_LED) + // TODO: Support sharing status LED with user. + #endif +} + +void new_status_color(uint32_t rgb) { + #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED)) + if (current_status_color == rgb) { + return; + } + uint32_t rgb_adjusted = color_brightness(rgb, rgb_status_brightness); + current_status_color = rgb; + #endif + + #ifdef MICROPY_HW_NEOPIXEL + if (neopixel_in_use) { + return; + } + status_neopixel_color[0] = (rgb_adjusted >> 8) & 0xff; + status_neopixel_color[1] = (rgb_adjusted >> 16) & 0xff; + status_neopixel_color[2] = rgb_adjusted & 0xff; + common_hal_neopixel_write(&status_neopixel, status_neopixel_color, 3); + #endif + #if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK) + if (apa102_mosi_in_use || apa102_sck_in_use) { + return; + } + status_apa102_color[5] = rgb_adjusted & 0xff; + status_apa102_color[6] = (rgb_adjusted >> 8) & 0xff; + status_apa102_color[7] = (rgb_adjusted >> 16) & 0xff; + + #if CIRCUITPY_BITBANG_APA102 + shared_module_bitbangio_spi_write(&status_apa102, status_apa102_color, APA102_BUFFER_LENGTH); + #else + common_hal_busio_spi_write(&status_apa102, status_apa102_color, APA102_BUFFER_LENGTH); + #endif + #endif + + #if defined(CP_RGB_STATUS_LED) + uint8_t red_u8 = (rgb_adjusted >> 16) & 0xFF; + uint8_t green_u8 = (rgb_adjusted >> 8) & 0xFF; + uint8_t blue_u8 = rgb_adjusted & 0xFF; + + #if defined(CP_RGB_STATUS_INVERTED_PWM) + status_rgb_color[0] = (1 << 16) - 1 - ((uint16_t) (red_u8 << 8) + red_u8); + status_rgb_color[1] = (1 << 16) - 1 - ((uint16_t) (green_u8 << 8) + green_u8); + status_rgb_color[2] = (1 << 16) - 1 - ((uint16_t) (blue_u8 << 8) + blue_u8); + #else + status_rgb_color[0] = (uint16_t) (red_u8 << 8) + red_u8; + status_rgb_color[1] = (uint16_t) (green_u8 << 8) + green_u8; + status_rgb_color[2] = (uint16_t) (blue_u8 << 8) + blue_u8; + #endif + + common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_r, status_rgb_color[0]); + common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_g, status_rgb_color[1]); + common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_b, status_rgb_color[2]); + #endif +} + +void temp_status_color(uint32_t rgb) { + #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED)) + uint32_t rgb_adjusted = rgb; + rgb_adjusted = color_brightness(rgb, rgb_status_brightness); + #endif + #ifdef MICROPY_HW_NEOPIXEL + if (neopixel_in_use) { + return; + } + uint8_t colors[3] = {(rgb_adjusted >> 8) & 0xff, (rgb_adjusted >> 16) & 0xff, rgb_adjusted & 0xff}; + common_hal_neopixel_write(&status_neopixel, colors, 3); + #endif + #if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK) + if (apa102_mosi_in_use || apa102_sck_in_use) { + return; + } + uint8_t colors[APA102_BUFFER_LENGTH] = {0, 0, 0, 0, 0xff, rgb_adjusted & 0xff, (rgb_adjusted >> 8) & 0xff, (rgb_adjusted >> 16) & 0xff, 0xff, 0xff, 0xff, 0xff}; + #if CIRCUITPY_BITBANG_APA102 + shared_module_bitbangio_spi_write(&status_apa102, colors, APA102_BUFFER_LENGTH); + #else + common_hal_busio_spi_write(&status_apa102, colors, APA102_BUFFER_LENGTH); + #endif + #endif + #if defined(CP_RGB_STATUS_LED) + uint8_t red_u8 = (rgb_adjusted >> 16) & 0xFF; + uint8_t green_u8 = (rgb_adjusted >> 8) & 0xFF; + uint8_t blue_u8 = rgb_adjusted & 0xFF; + + uint16_t temp_status_color_rgb[3] = {0}; + + #if defined(CP_RGB_STATUS_INVERTED_PWM) + temp_status_color_rgb[0] = (1 << 16) - 1 - ((uint16_t) (red_u8 << 8) + red_u8); + temp_status_color_rgb[1] = (1 << 16) - 1 - ((uint16_t) (green_u8 << 8) + green_u8); + temp_status_color_rgb[2] = (1 << 16) - 1 - ((uint16_t) (blue_u8 << 8) + blue_u8); + #else + temp_status_color_rgb[0] = (uint16_t) (red_u8 << 8) + red_u8; + temp_status_color_rgb[1] = (uint16_t) (green_u8 << 8) + green_u8; + temp_status_color_rgb[2] = (uint16_t) (blue_u8 << 8) + blue_u8; + #endif + + common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_r, temp_status_color_rgb[0]); + common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_g, temp_status_color_rgb[1]); + common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_b, temp_status_color_rgb[2]); + #endif +} + +void clear_temp_status() { + #ifdef MICROPY_HW_NEOPIXEL + common_hal_neopixel_write(&status_neopixel, status_neopixel_color, 3); + #endif + #if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK) + #if CIRCUITPY_BITBANG_APA102 + shared_module_bitbangio_spi_write(&status_apa102, status_apa102_color, APA102_BUFFER_LENGTH); + #else + common_hal_busio_spi_write(&status_apa102, status_apa102_color, APA102_BUFFER_LENGTH); + #endif + #endif + #if defined(CP_RGB_STATUS_LED) + + uint16_t red = 0; + uint16_t green = 0; + uint16_t blue = 0; + + #if defined(CP_RGB_STATUS_INVERTED_PWM) + red = (1 << 16) - 1 - status_rgb_color[0]; + green = (1 << 16) - 1 - status_rgb_color[1]; + blue = (1 << 16) - 1 - status_rgb_color[2]; + #else + red = status_rgb_color[0]; + green = status_rgb_color[1]; + blue = status_rgb_color[2]; + #endif + + common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_r, red); + common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_g, green); + common_hal_pulseio_pwmout_set_duty_cycle(&rgb_status_b, blue); + #endif +} + +uint32_t color_brightness(uint32_t color, uint8_t brightness) { + #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED)) + uint32_t result = ((color & 0xff0000) * brightness / 255) & 0xff0000; + result += ((color & 0xff00) * brightness / 255) & 0xff00; + result += ((color & 0xff) * brightness / 255) & 0xff; + return result; + #else + return color; + #endif +} + +void set_rgb_status_brightness(uint8_t level){ + #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED)) + rgb_status_brightness = level; + uint32_t current_color = current_status_color; + // Temporarily change the current color global to force the new_status_color call to update the + // LED. Usually duplicate calls of the same color are ignored without regard to brightness + // changes. + current_status_color = 0; + new_status_color(current_color); + #endif +} + +void prep_rgb_status_animation(const pyexec_result_t* result, + bool found_main, + safe_mode_t safe_mode, + rgb_status_animation_t* status) { + #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED)) + new_status_color(ALL_DONE); + status->pattern_start = ticks_ms; + status->safe_mode = safe_mode; + status->found_main = found_main; + status->total_exception_cycle = 0; + status->ones = result->exception_line % 10; + status->ones += status->ones > 0 ? 1 : 0; + status->tens = (result->exception_line / 10) % 10; + status->tens += status->tens > 0 ? 1 : 0; + status->hundreds = (result->exception_line / 100) % 10; + status->hundreds += status->hundreds > 0 ? 1 : 0; + status->thousands = (result->exception_line / 1000) % 10; + status->thousands += status->thousands > 0 ? 1 : 0; + status->digit_sum = status->ones + status->tens + status->hundreds + status->thousands; + uint8_t num_places = 0; + uint16_t line = result->exception_line; + for (int i = 0; i < 4; i++) { + if ((line % 10) > 0) { + num_places++; + } + line /= 10; + } + status->ok = result->return_code != PYEXEC_EXCEPTION; + if (!status->ok) { + status->total_exception_cycle = EXCEPTION_TYPE_LENGTH_MS * 3 + LINE_NUMBER_TOGGLE_LENGTH * status->digit_sum + LINE_NUMBER_TOGGLE_LENGTH * num_places; + } + if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_IndentationError)) { + status->exception_color = INDENTATION_ERROR; + } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_SyntaxError)) { + status->exception_color = SYNTAX_ERROR; + } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_NameError)) { + status->exception_color = NAME_ERROR; + } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_OSError)) { + status->exception_color = OS_ERROR; + } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_ValueError)) { + status->exception_color = VALUE_ERROR; + } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_MpyError)) { + status->exception_color = MPY_ERROR; + } else { + status->exception_color = OTHER_ERROR; + } + #endif +} + +void tick_rgb_status_animation(rgb_status_animation_t* status) { + #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED)) + uint32_t tick_diff = ticks_ms - status->pattern_start; + if (status->ok) { + // All is good. Ramp ALL_DONE up and down. + if (tick_diff > ALL_GOOD_CYCLE_MS) { + status->pattern_start = ticks_ms; + tick_diff = 0; + } + + uint16_t brightness = tick_diff * 255 / (ALL_GOOD_CYCLE_MS / 2); + if (brightness > 255) { + brightness = 511 - brightness; + } + if (status->safe_mode == NO_SAFE_MODE) { + new_status_color(color_brightness(ALL_DONE, brightness)); + } else { + new_status_color(color_brightness(SAFE_MODE, brightness)); + } + } else { + if (tick_diff > status->total_exception_cycle) { + status->pattern_start = ticks_ms; + tick_diff = 0; + } + // First flash the file color. + if (tick_diff < EXCEPTION_TYPE_LENGTH_MS) { + if (status->found_main) { + new_status_color(MAIN_RUNNING); + } else { + new_status_color(BOOT_RUNNING); + } + // Next flash the exception color. + } else if (tick_diff < EXCEPTION_TYPE_LENGTH_MS * 2) { + new_status_color(status->exception_color); + // Finally flash the line number digits from highest to lowest. + // Zeroes will not produce a flash but can be read by the absence of + // a color from the sequence. + } else if (tick_diff < (EXCEPTION_TYPE_LENGTH_MS * 2 + LINE_NUMBER_TOGGLE_LENGTH * status->digit_sum)) { + uint32_t digit_diff = tick_diff - EXCEPTION_TYPE_LENGTH_MS * 2; + if ((digit_diff % LINE_NUMBER_TOGGLE_LENGTH) < (LINE_NUMBER_TOGGLE_LENGTH / 2)) { + new_status_color(BLACK); + } else if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * status->thousands) { + if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH) { + new_status_color(BLACK); + } else { + new_status_color(THOUSANDS); + } + } else if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * (status->thousands + status->hundreds)) { + if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * (status->thousands + 1)) { + new_status_color(BLACK); + } else { + new_status_color(HUNDREDS); + } + } else if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * (status->thousands + status->hundreds + status->tens)) { + if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * (status->thousands + status->hundreds + 1)) { + new_status_color(BLACK); + } else { + new_status_color(TENS); + } + } else { + if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * (status->thousands + status->hundreds + status->tens + 1)) { + new_status_color(BLACK); + } else { + new_status_color(ONES); + } + } + } else { + new_status_color(BLACK); + } + } + #endif +} diff --git a/supervisor/shared/rgb_led_status.h b/supervisor/shared/rgb_led_status.h new file mode 100644 index 00000000000..e4e1981a21f --- /dev/null +++ b/supervisor/shared/rgb_led_status.h @@ -0,0 +1,81 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SUPERVISOR_RGB_LED_STATUS_H +#define MICROPY_INCLUDED_SUPERVISOR_RGB_LED_STATUS_H + +#include +#include + +#include "lib/utils/pyexec.h" +#include "supervisor/port.h" + +#include "py/mpconfig.h" +#include "rgb_led_colors.h" + +#include "supervisor/shared/safe_mode.h" + +// Overall, the time module must be implemented. +// To work with a DotStar, one must have MICROPY_HW_APA102_SCK and +// MICROPY_HW_APA102_MOSI defined and bitbangio.SPI or busio.SPI implemented. +// To work with a NeoPixel, one must have MICROPY_HW_NEOPIXEL defined and +// neopixel_write implemented. + +#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK) && !CIRCUITPY_BITBANG_APA102 +#include "common-hal/busio/SPI.h" +extern busio_spi_obj_t status_apa102; +#endif + +void rgb_led_status_init(void); +void reset_status_led(void); +void new_status_color(uint32_t rgb); +void temp_status_color(uint32_t rgb); +void clear_temp_status(void); + +uint32_t color_brightness(uint32_t color, uint8_t brightness); +void set_rgb_status_brightness(uint8_t level); + +typedef struct { + bool ok; + uint32_t pattern_start; + uint32_t total_exception_cycle; + safe_mode_t safe_mode; + uint8_t digit_sum; + uint8_t ones; + uint8_t tens; + uint8_t hundreds; + uint8_t thousands; + uint32_t exception_color; + bool found_main; +} rgb_status_animation_t; + +void prep_rgb_status_animation(const pyexec_result_t* result, + bool found_main, + safe_mode_t safe_mode, + rgb_status_animation_t* status); +void tick_rgb_status_animation(rgb_status_animation_t* status); + +#endif // MICROPY_INCLUDED_SUPERVISOR_RGB_LED_STATUS_H diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c new file mode 100644 index 00000000000..d8d3ab379c4 --- /dev/null +++ b/supervisor/shared/safe_mode.c @@ -0,0 +1,136 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/shared/safe_mode.h" + +#include "mphalport.h" + +#include "shared-bindings/digitalio/DigitalInOut.h" + +#include "supervisor/serial.h" +#include "supervisor/shared/rgb_led_colors.h" +#include "supervisor/shared/rgb_led_status.h" +#include "supervisor/shared/translate.h" + +#define SAFE_MODE_DATA_GUARD 0xad0000af +#define SAFE_MODE_DATA_GUARD_MASK 0xff0000ff + +static safe_mode_t current_safe_mode; + +safe_mode_t wait_for_safe_mode_reset(void) { + uint32_t reset_state = port_get_saved_word(); + safe_mode_t safe_mode = NO_SAFE_MODE; + if ((reset_state & SAFE_MODE_DATA_GUARD_MASK) == SAFE_MODE_DATA_GUARD) { + safe_mode = (reset_state & ~SAFE_MODE_DATA_GUARD_MASK) >> 8; + } + if (safe_mode != NO_SAFE_MODE) { + port_set_saved_word(SAFE_MODE_DATA_GUARD); + current_safe_mode = safe_mode; + return safe_mode; + } + port_set_saved_word(SAFE_MODE_DATA_GUARD | (MANUAL_SAFE_MODE << 8)); + // Wait for a while to allow for reset. + temp_status_color(SAFE_MODE); + #ifdef MICROPY_HW_LED_STATUS + digitalio_digitalinout_obj_t status_led; + common_hal_digitalio_digitalinout_construct(&status_led, MICROPY_HW_LED_STATUS); + common_hal_digitalio_digitalinout_switch_to_output(&status_led, true, DRIVE_MODE_PUSH_PULL); + #endif + uint64_t start_ticks = ticks_ms; + uint64_t diff = 0; + while (diff < 700) { + #ifdef MICROPY_HW_LED_STATUS + // Blink on for 100, off for 100, on for 100, off for 100 and on for 200 + common_hal_digitalio_digitalinout_set_value(&status_led, diff > 100 && diff / 100 != 2 && diff / 100 != 4); + #endif + diff = ticks_ms - start_ticks; + } + #ifdef MICROPY_HW_LED_STATUS + common_hal_digitalio_digitalinout_deinit(&status_led); + #endif + clear_temp_status(); + port_set_saved_word(SAFE_MODE_DATA_GUARD); + return NO_SAFE_MODE; +} + +void safe_mode_on_next_reset(safe_mode_t reason) { + port_set_saved_word(SAFE_MODE_DATA_GUARD | (reason << 8)); +} + +// Don't inline this so it's easy to break on it from GDB. +void __attribute__((noinline,)) reset_into_safe_mode(safe_mode_t reason) { + if (current_safe_mode > BROWNOUT && reason > BROWNOUT) { + while (true) { + // This very bad because it means running in safe mode didn't save us. Only ignore brownout + // because it may be due to a switch bouncing. + } + } + + safe_mode_on_next_reset(reason); + reset_cpu(); +} + +void print_safe_mode_message(safe_mode_t reason) { + if (reason == NO_SAFE_MODE) { + return; + } + serial_write("\r\n"); + // Output a user safe mode string if its set. + #ifdef BOARD_USER_SAFE_MODE + if (reason == USER_SAFE_MODE) { + serial_write_compressed(translate("You requested starting safe mode by ")); + serial_write(BOARD_USER_SAFE_MODE_ACTION); + serial_write("\r\n"); + serial_write_compressed(translate("To exit, please reset the board without ")); + serial_write(BOARD_USER_SAFE_MODE_ACTION); + serial_write("\r\n"); + } else + #endif + if (reason == MANUAL_SAFE_MODE) { + serial_write_compressed(translate("The reset button was pressed while booting CircuitPython. Press again to exit safe mode.\n")); + } else if (reason == PROGRAMMATIC_SAFE_MODE) { + serial_write_compressed(translate("The `microcontroller` module was used to boot into safe mode. Press reset to exit safe mode.\n")); + } else { + serial_write_compressed(translate("You are running in safe mode which means something unanticipated happened.\n")); + if (reason == HARD_CRASH || reason == MICROPY_NLR_JUMP_FAIL || reason == MICROPY_FATAL_ERROR || reason == GC_ALLOC_OUTSIDE_VM) { + serial_write_compressed(translate("Looks like our core CircuitPython code crashed hard. Whoops!\nPlease file an issue at https://github.com/adafruit/circuitpython/issues\n with the contents of your CIRCUITPY drive and this message:\n")); + if (reason == HARD_CRASH) { + serial_write_compressed(translate("Crash into the HardFault_Handler.\n")); + } else if (reason == MICROPY_NLR_JUMP_FAIL) { + serial_write_compressed(translate("MicroPython NLR jump failed. Likely memory corruption.\n")); + } else if (reason == MICROPY_FATAL_ERROR) { + serial_write_compressed(translate("MicroPython fatal error.\n")); + } else if (reason == GC_ALLOC_OUTSIDE_VM) { + serial_write_compressed(translate("Attempted heap allocation when MicroPython VM not running.\n")); + } + } else if (reason == BROWNOUT) { + serial_write_compressed(translate("The microcontroller's power dipped. Please make sure your power supply provides\nenough power for the whole circuit and press reset (after ejecting CIRCUITPY).\n")); + } else if (reason == HEAP_OVERWRITTEN) { + serial_write_compressed(translate("The CircuitPython heap was corrupted because the stack was too small.\nPlease increase stack size limits and press reset (after ejecting CIRCUITPY).\nIf you didn't change the stack, then file an issue here with the contents of your CIRCUITPY drive:\n")); + serial_write("https://github.com/adafruit/circuitpython/issues\r\n"); + } + } +} diff --git a/supervisor/shared/safe_mode.h b/supervisor/shared/safe_mode.h new file mode 100644 index 00000000000..ee0723cff16 --- /dev/null +++ b/supervisor/shared/safe_mode.h @@ -0,0 +1,50 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SUPERVISOR_SAFE_MODE_H +#define MICROPY_INCLUDED_SUPERVISOR_SAFE_MODE_H + +typedef enum { + NO_SAFE_MODE = 0, + BROWNOUT, + HARD_CRASH, + USER_SAFE_MODE, + HEAP_OVERWRITTEN, + MANUAL_SAFE_MODE, + MICROPY_NLR_JUMP_FAIL, + MICROPY_FATAL_ERROR, + GC_ALLOC_OUTSIDE_VM, + PROGRAMMATIC_SAFE_MODE +} safe_mode_t; + +safe_mode_t wait_for_safe_mode_reset(void); + +void safe_mode_on_next_reset(safe_mode_t reason); +void reset_into_safe_mode(safe_mode_t reason); + +void print_safe_mode_message(safe_mode_t reason); + +#endif // MICROPY_INCLUDED_SUPERVISOR_SAFE_MODE_H diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c new file mode 100644 index 00000000000..a61899576f5 --- /dev/null +++ b/supervisor/shared/serial.c @@ -0,0 +1,69 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 + +#include "py/mpconfig.h" + +#include "supervisor/shared/display.h" +#include "shared-bindings/terminalio/Terminal.h" +#include "supervisor/serial.h" +#include "supervisor/usb.h" + +#include "tusb.h" + +void serial_init(void) { + usb_init(); +} + +bool serial_connected(void) { + return tud_cdc_connected(); +} + +char serial_read(void) { + return (char) tud_cdc_read_char(); +} + +bool serial_bytes_available(void) { + return tud_cdc_available() > 0; +} + +void serial_write_substring(const char* text, uint32_t length) { +#if CIRCUITPY_DISPLAYIO + int errcode; + common_hal_terminalio_terminal_write(&supervisor_terminal, (const uint8_t*) text, length, &errcode); +#endif + + uint32_t count = 0; + while (count < length && tud_cdc_connected()) { + count += tud_cdc_write(text + count, length - count); + usb_background(); + } +} + +void serial_write(const char* text) { + serial_write_substring(text, strlen(text)); +} diff --git a/supervisor/shared/stack.c b/supervisor/shared/stack.c new file mode 100755 index 00000000000..311fa31b226 --- /dev/null +++ b/supervisor/shared/stack.c @@ -0,0 +1,88 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "stack.h" + +#include "py/mpconfig.h" +#include "py/runtime.h" +#include "supervisor/cpu.h" +#include "supervisor/shared/safe_mode.h" + +extern uint32_t _estack; + +static uint32_t next_stack_size = CIRCUITPY_DEFAULT_STACK_SIZE; +static uint32_t current_stack_size = 0; +supervisor_allocation* stack_alloc = NULL; + +#define EXCEPTION_STACK_SIZE 1024 + +void allocate_stack(void) { + mp_uint_t regs[10]; + mp_uint_t sp = cpu_get_regs_and_sp(regs); + + mp_uint_t c_size = (uint32_t) &_estack - sp; + + stack_alloc = allocate_memory(c_size + next_stack_size + EXCEPTION_STACK_SIZE, true); + if (stack_alloc == NULL) { + stack_alloc = allocate_memory(c_size + CIRCUITPY_DEFAULT_STACK_SIZE + EXCEPTION_STACK_SIZE, true); + current_stack_size = CIRCUITPY_DEFAULT_STACK_SIZE; + } else { + current_stack_size = next_stack_size; + } + *stack_alloc->ptr = STACK_CANARY_VALUE; +} + +inline bool stack_ok(void) { + return stack_alloc == NULL || *stack_alloc->ptr == STACK_CANARY_VALUE; +} + +inline void assert_heap_ok(void) { + if (!stack_ok()) { + reset_into_safe_mode(HEAP_OVERWRITTEN); + } +} + +void stack_init(void) { + allocate_stack(); +} + +void stack_resize(void) { + if (next_stack_size == current_stack_size) { + *stack_alloc->ptr = STACK_CANARY_VALUE; + return; + } + free_memory(stack_alloc); + stack_alloc = NULL; + allocate_stack(); +} + +void set_next_stack_size(uint32_t size) { + next_stack_size = size; +} + +uint32_t get_current_stack_size(void) { + return current_stack_size; +} diff --git a/supervisor/shared/stack.h b/supervisor/shared/stack.h new file mode 100755 index 00000000000..1fb43be573b --- /dev/null +++ b/supervisor/shared/stack.h @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SUPERVISOR_STACK_H +#define MICROPY_INCLUDED_SUPERVISOR_STACK_H + +#include + +#include "supervisor/memory.h" + +extern supervisor_allocation* stack_alloc; + +void stack_init(void); +void stack_resize(void); +void set_next_stack_size(uint32_t size); +uint32_t get_current_stack_size(void); +bool stack_ok(void); + +// Use this after any calls into a library which may use a lot of stack. This will raise a Python +// exception when the stack has likely overwritten a portion of the heap. +void assert_heap_ok(void); + +#define STACK_CANARY_VALUE 0x017829ef + +#endif // MICROPY_INCLUDED_SUPERVISOR_STACK_H diff --git a/supervisor/shared/status_leds.c b/supervisor/shared/status_leds.c new file mode 100644 index 00000000000..672242a9636 --- /dev/null +++ b/supervisor/shared/status_leds.c @@ -0,0 +1,64 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/shared/status_leds.h" + +#if CIRCUITPY_DIGITALIO +#include "common-hal/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#endif + +#ifdef MICROPY_HW_LED_RX +digitalio_digitalinout_obj_t rx_led; +#endif + +#ifdef MICROPY_HW_LED_TX +digitalio_digitalinout_obj_t tx_led; +#endif + +void init_status_leds(void) { + #ifdef MICROPY_HW_LED_RX + common_hal_digitalio_digitalinout_construct(&rx_led, MICROPY_HW_LED_RX); + common_hal_digitalio_digitalinout_switch_to_output(&rx_led, true, DRIVE_MODE_PUSH_PULL); + #endif + #ifdef MICROPY_HW_LED_TX + common_hal_digitalio_digitalinout_construct(&tx_led, MICROPY_HW_LED_TX); + common_hal_digitalio_digitalinout_switch_to_output(&tx_led, true, DRIVE_MODE_PUSH_PULL); + #endif +} + +void toggle_rx_led(void) { + #ifdef MICROPY_HW_LED_RX + common_hal_digitalio_digitalinout_set_value(&rx_led, !common_hal_digitalio_digitalinout_get_value(&rx_led)); + #endif +} + + +void toggle_tx_led(void) { + #ifdef MICROPY_HW_LED_TX + common_hal_digitalio_digitalinout_set_value(&tx_led, !common_hal_digitalio_digitalinout_get_value(&tx_led)); + #endif +} diff --git a/supervisor/shared/status_leds.h b/supervisor/shared/status_leds.h new file mode 100644 index 00000000000..30132753f39 --- /dev/null +++ b/supervisor/shared/status_leds.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SUPERVISOR_STATUS_LEDS_H +#define MICROPY_INCLUDED_SUPERVISOR_STATUS_LEDS_H + +void init_status_leds(void); + +void toggle_rx_led(void); + +void toggle_tx_led(void); + +#endif // MICROPY_INCLUDED_SUPERVISOR_STATUS_LEDS_H diff --git a/supervisor/shared/translate.c b/supervisor/shared/translate.c new file mode 100644 index 00000000000..aa5e4517c25 --- /dev/null +++ b/supervisor/shared/translate.c @@ -0,0 +1,91 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/shared/translate.h" + +#include +#include +#include + +#ifndef NO_QSTR +#include "genhdr/compression.generated.h" +#endif + +#include "supervisor/serial.h" + +void serial_write_compressed(const compressed_string_t* compressed) { + char decompressed[compressed->length]; + decompress(compressed, decompressed); + serial_write(decompressed); +} + +char* decompress(const compressed_string_t* compressed, char* decompressed) { + uint8_t this_byte = 0; + uint8_t this_bit = 7; + uint8_t b = compressed->data[this_byte]; + // Stop one early because the last byte is always NULL. + for (uint16_t i = 0; i < compressed->length - 1; i++) { + uint32_t bits = 0; + uint8_t bit_length = 0; + uint32_t max_code = lengths[0]; + uint32_t searched_length = lengths[0]; + while (true) { + bits <<= 1; + if ((0x80 & b) != 0) { + bits |= 1; + } + b <<= 1; + bit_length += 1; + if (this_bit == 0) { + this_bit = 7; + this_byte += 1; + b = compressed->data[this_byte]; // This may read past the end but its never used. + } else { + this_bit -= 1; + } + if (max_code > 0 && bits < max_code) { + break; + } + max_code = (max_code << 1) + lengths[bit_length]; + searched_length += lengths[bit_length]; + } + decompressed[i] = values[searched_length + bits - max_code]; + } + + decompressed[compressed->length-1] = '\0'; + return decompressed; +} + +inline __attribute__((always_inline)) const compressed_string_t* translate(const char* original) { + #ifndef NO_QSTR + #define QDEF(id, str) + #define TRANSLATION(id, len, compressed...) if (strcmp(original, id) == 0) { static const compressed_string_t v = {.length = len, .data = compressed}; return &v; } else + #include "genhdr/qstrdefs.generated.h" + #undef TRANSLATION + #undef QDEF + #endif + return NULL; +} diff --git a/supervisor/shared/translate.h b/supervisor/shared/translate.h new file mode 100644 index 00000000000..5e8acbb6afa --- /dev/null +++ b/supervisor/shared/translate.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SUPERVISOR_TRANSLATE_H +#define MICROPY_INCLUDED_SUPERVISOR_TRANSLATE_H + +#include + +typedef struct { + uint16_t length; + const uint8_t data[]; +} compressed_string_t; + +const compressed_string_t* translate(const char* c); +void serial_write_compressed(const compressed_string_t* compressed); +char* decompress(const compressed_string_t* compressed, char* decompressed); + +#endif // MICROPY_INCLUDED_SUPERVISOR_TRANSLATE_H diff --git a/supervisor/shared/usb/tusb_config.h b/supervisor/shared/usb/tusb_config.h new file mode 100644 index 00000000000..ad5825b6c93 --- /dev/null +++ b/supervisor/shared/usb/tusb_config.h @@ -0,0 +1,117 @@ +/**************************************************************************/ +/*! + @file tusb_config.h + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2013, hathach (tinyusb.org) + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +/**************************************************************************/ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#include "genhdr/autogen_usb_descriptor.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// COMMON CONFIGURATION +//--------------------------------------------------------------------+ +#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE + +#define CFG_TUSB_DEBUG 0 + +/*------------- RTOS -------------*/ +#define CFG_TUSB_OS OPT_OS_NONE +//#define CFG_TUD_TASK_QUEUE_SZ 16 +//#define CFG_TUD_TASK_PRIO 0 +//#define CFG_TUD_TASK_STACK_SZ 150 + +//--------------------------------------------------------------------+ +// DEVICE CONFIGURATION +//--------------------------------------------------------------------+ + +#define CFG_TUD_ENDOINT0_SIZE 64 + +/*------------- Descriptors -------------*/ +/* Enable auto generated descriptor, tinyusb will try its best to create + * descriptor ( device, configuration, hid ) that matches enabled CFG_* in this file + * + * Note: All CFG_TUD_DESC_* are relevant only if CFG_TUD_DESC_AUTO is enabled + */ +#define CFG_TUD_DESC_AUTO 0 + +//------------- CLASS -------------// +#define CFG_TUD_CDC 1 +#define CFG_TUD_MSC 1 +#define CFG_TUD_HID 1 +#define CFG_TUD_MIDI 1 +#define CFG_TUD_CUSTOM_CLASS 0 + +/*------------------------------------------------------------------*/ +/* CLASS DRIVER + *------------------------------------------------------------------*/ + +/* TX is sent automatically on every Start of Frame event ~ 1ms. + * If not enabled, application must call tud_cdc_flush() periodically + * Note: Enabled this could overflow device task, if it does, define + * CFG_TUD_TASK_QUEUE_SZ with large value + */ +#define CFG_TUD_CDC_FLUSH_ON_SOF 0 + + +/*------------- MSC -------------*/ +// Number of supported Logical Unit Number (At least 1) +#define CFG_TUD_MSC_MAXLUN 1 + +// Number of Blocks +#define CFG_TUD_MSC_BLOCK_NUM (256*1024)/512 + + + +// Product revision string included in Inquiry response, max 4 bytes +#define CFG_TUD_MSC_PRODUCT_REV "1.0" + + +//--------------------------------------------------------------------+ +// USB RAM PLACEMENT +//--------------------------------------------------------------------+ +#define CFG_TUSB_ATTR_USBRAM +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) + + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c new file mode 100644 index 00000000000..c1d70c5b0f8 --- /dev/null +++ b/supervisor/shared/usb/usb.c @@ -0,0 +1,143 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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 "tick.h" +#include "py/objstr.h" +#include "shared-bindings/microcontroller/Processor.h" +#include "shared-module/usb_midi/__init__.h" +#include "supervisor/port.h" +#include "supervisor/usb.h" +#include "lib/utils/interrupt_char.h" +#include "lib/mp-readline/readline.h" + +#include "tusb.h" + +// Serial number as hex characters. This writes directly to the USB +// descriptor. +extern uint16_t usb_serial_number[1 + COMMON_HAL_MCU_PROCESSOR_UID_LENGTH * 2]; + +void load_serial_number(void) { + // create serial number based on device unique id + uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH]; + common_hal_mcu_processor_get_uid(raw_id); + + for (int i = 0; i < COMMON_HAL_MCU_PROCESSOR_UID_LENGTH; i++) { + for (int j = 0; j < 2; j++) { + uint8_t nibble = (raw_id[i] >> (j * 4)) & 0xf; + // Strings are UTF-16-LE encoded. + usb_serial_number[1 + i * 2 + j] = nibble_to_hex_upper[nibble]; + } + } +} + +bool usb_enabled(void) { + return tusb_inited(); +} + +void usb_init(void) { + init_usb_hardware(); + load_serial_number(); + + tusb_init(); + +#if MICROPY_KBD_EXCEPTION + // Set Ctrl+C as wanted char, tud_cdc_rx_wanted_cb() callback will be invoked when Ctrl+C is received + // This callback always got invoked regardless of mp_interrupt_char value since we only set it once here + tud_cdc_set_wanted_char(CHAR_CTRL_C); +#endif + +#if CIRCUITPY_USB_MIDI + usb_midi_init(); +#endif +} + +void usb_background(void) { + if (usb_enabled()) { + tud_task(); + tud_cdc_write_flush(); + } +} + +//--------------------------------------------------------------------+ +// tinyusb callbacks +//--------------------------------------------------------------------+ + +// Invoked when device is mounted +void tud_mount_cb(void) { +} + +// Invoked when device is unmounted +void tud_umount_cb(void) { +} + +// Invoked when usb bus is suspended +// remote_wakeup_en : if host allows us to perform remote wakeup +// USB Specs: Within 7ms, device must draw an average current less than 2.5 mA from bus +void tud_suspend_cb(bool remote_wakeup_en) { +} + +// Invoked when usb bus is resumed +void tud_resume_cb(void) { +} + +// Invoked when cdc when line state changed e.g connected/disconnected +// Use to reset to DFU when disconnect with 1200 bps +void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { + (void) itf; // interface ID, not used + + // DTR = false is counted as disconnected + if ( !dtr ) + { + cdc_line_coding_t coding; + tud_cdc_get_line_coding(&coding); + + if ( coding.bit_rate == 1200 ) + { + reset_to_bootloader(); + } + } +} + +#if MICROPY_KBD_EXCEPTION + +/** + * Callback invoked when received an "wanted" char. + * @param itf Interface index (for multiple cdc interfaces) + * @param wanted_char The wanted char (set previously) + */ +void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) +{ + (void) itf; // not used + + // Workaround for using lib/utils/interrupt_char.c + // Compare mp_interrupt_char with wanted_char and ignore if not matched + if (mp_interrupt_char == wanted_char) { + tud_cdc_read_flush(); // flush read fifo + mp_keyboard_interrupt(); + } +} + +#endif diff --git a/supervisor/shared/usb/usb_desc.c b/supervisor/shared/usb/usb_desc.c new file mode 100644 index 00000000000..9b333d6fea3 --- /dev/null +++ b/supervisor/shared/usb/usb_desc.c @@ -0,0 +1,58 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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 "lib/tinyusb/src/tusb.h" +#include "shared-module/usb_hid/Device.h" + +#include "genhdr/autogen_usb_descriptor.h" + +// Invoked when received GET DEVICE DESCRIPTOR +// Application return pointer to descriptor +uint8_t const * tud_descriptor_device_cb(void) { + return usb_desc_dev; +} + +// Invoked when received GET CONFIGURATION DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { + (void) index; // for multiple configurations + return usb_desc_cfg; +} + +// Invoked when received GET HID REPORT DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_hid_descriptor_report_cb(void) { + return hid_report_descriptor; +} + +// Invoked when received GET STRING DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +uint16_t const* tud_descriptor_string_cb(uint8_t index) { + uint8_t const max_index = sizeof(string_desc_arr)/sizeof(string_desc_arr[0]); + return (index < max_index) ? string_desc_arr[index] : NULL; +} diff --git a/supervisor/shared/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c new file mode 100644 index 00000000000..205cb7b5001 --- /dev/null +++ b/supervisor/shared/usb/usb_msc_flash.c @@ -0,0 +1,218 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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 "tusb.h" +// // #include "supervisor/flash.h" + +// For updating fatfs's cache +#include "extmod/vfs.h" +#include "extmod/vfs_fat.h" +#include "lib/oofatfs/diskio.h" +#include "lib/oofatfs/ff.h" +#include "py/mpstate.h" + +#include "supervisor/filesystem.h" +#include "supervisor/shared/autoreload.h" + +#define MSC_FLASH_BLOCK_SIZE 512 + +static bool ejected[1]; + +// The root FS is always at the end of the list. +static fs_user_mount_t* get_vfs(int lun) { + // TODO(tannewt): Return the mount which matches the lun where 0 is the end + // and is counted in reverse. + if (lun > 0) { + return NULL; + } + mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table); + if (current_mount == NULL) { + return NULL; + } + while (current_mount->next != NULL) { + current_mount = current_mount->next; + } + return current_mount->obj; +} + +// Callback invoked when received an SCSI command not in built-in list below +// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, TEST_UNIT_READY, START_STOP_UNIT, MODE_SENSE6, REQUEST_SENSE +// - READ10 and WRITE10 have their own callbacks +int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer, uint16_t bufsize) { + const void* response = NULL; + int32_t resplen = 0; + + switch ( scsi_cmd[0] ) { + case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: + // Host is about to read/write etc ... better not to disconnect disk + resplen = 0; + break; + + default: + // Set Sense = Invalid Command Operation + tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); + + // negative means error -> tinyusb could stall and/or response with failed status + resplen = -1; + break; + } + + // return len must not larger than bufsize + if ( resplen > bufsize ) { + resplen = bufsize; + } + + // copy response to stack's buffer if any + if ( response && (resplen > 0) ) { + memcpy(buffer, response, resplen); + } + + return resplen; +} + +void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) { + fs_user_mount_t * vfs = get_vfs(lun); + disk_ioctl(vfs, GET_SECTOR_COUNT, block_count); + disk_ioctl(vfs, GET_SECTOR_SIZE, block_size); +} + +bool tud_msc_is_writable_cb(uint8_t lun) { + if (lun > 1) { + return false; + } + + fs_user_mount_t* vfs = get_vfs(lun); + if (vfs == NULL) { + return false; + } + if (vfs->writeblocks[0] == MP_OBJ_NULL || !filesystem_is_writable_by_usb(vfs)) { + return false; + } + return true; +} + +// Callback invoked when received READ10 command. +// Copy disk's data to buffer (up to bufsize) and return number of copied bytes. +int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) { + (void) lun; + (void) offset; + + const uint32_t block_count = bufsize / MSC_FLASH_BLOCK_SIZE; + + fs_user_mount_t * vfs = get_vfs(lun); + disk_read(vfs, buffer, lba, block_count); + + return block_count * MSC_FLASH_BLOCK_SIZE; +} + +// Callback invoked when received WRITE10 command. +// Process data in buffer to disk's storage and return number of written bytes +int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) { + (void) lun; + (void) offset; + + const uint32_t block_count = bufsize / MSC_FLASH_BLOCK_SIZE; + + fs_user_mount_t * vfs = get_vfs(lun); + disk_write(vfs, buffer, lba, block_count); + // Since by getting here we assume the mount is read-only to + // MicroPython let's update the cached FatFs sector if it's the one + // we just wrote. + #if _MAX_SS != _MIN_SS + if (vfs->ssize == MSC_FLASH_BLOCK_SIZE) { + #else + // The compiler can optimize this away. + if (_MAX_SS == FILESYSTEM_BLOCK_SIZE) { + #endif + if (lba == vfs->fatfs.winsect && lba > 0) { + memcpy(vfs->fatfs.win, + buffer + MSC_FLASH_BLOCK_SIZE * (vfs->fatfs.winsect - lba), + MSC_FLASH_BLOCK_SIZE); + } + } + + return block_count * MSC_FLASH_BLOCK_SIZE; +} + +// Callback invoked when WRITE10 command is completed (status received and accepted by host). +// used to flush any pending cache. +void tud_msc_write10_complete_cb (uint8_t lun) { + (void) lun; + + // This write is complete, start the autoreload clock. + autoreload_start(); +} + +// Invoked when received SCSI_CMD_INQUIRY +// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively +void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) { + (void) lun; + + memcpy(vendor_id , CFG_TUD_MSC_VENDOR , strlen(CFG_TUD_MSC_VENDOR)); + memcpy(product_id , CFG_TUD_MSC_PRODUCT , strlen(CFG_TUD_MSC_PRODUCT)); + memcpy(product_rev, CFG_TUD_MSC_PRODUCT_REV, strlen(CFG_TUD_MSC_PRODUCT_REV)); +} + +// Invoked when received Test Unit Ready command. +// return true allowing host to read/write this LUN e.g SD card inserted +bool tud_msc_test_unit_ready_cb(uint8_t lun) { + if (lun > 1) { + return false; + } + + fs_user_mount_t* current_mount = get_vfs(lun); + if (current_mount == NULL) { + return false; + } + if (ejected[lun]) { + return false; + } + + return true; +} + +// Invoked when received Start Stop Unit command +// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage +// - Start = 1 : active mode, if load_eject = 1 : load disk storage +bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) { + if (load_eject) { + if (lun > 1) { + return false; + } else { + fs_user_mount_t* current_mount = get_vfs(lun); + if (current_mount == NULL) { + return false; + } + if (disk_ioctl(current_mount, CTRL_SYNC, NULL) != RES_OK) { + return false; + } else { + ejected[lun] = true; + } + } + } + + return true; +} diff --git a/supervisor/spi_flash_api.h b/supervisor/spi_flash_api.h new file mode 100644 index 00000000000..28cccb1b1ac --- /dev/null +++ b/supervisor/spi_flash_api.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * + * 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. + */ +#ifndef MICROPY_INCLUDED_SUPERVISOR_SPI_FLASH_H +#define MICROPY_INCLUDED_SUPERVISOR_SPI_FLASH_H + +#include +#include + +#include "supervisor/shared/external_flash/devices.h" + +// This API is implemented for both normal SPI peripherals and QSPI peripherals. + +bool spi_flash_command(uint8_t command); +bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length); +bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length); +bool spi_flash_sector_command(uint8_t command, uint32_t address); +bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t data_length); +bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t data_length); +void spi_flash_init(void); +void spi_flash_init_device(const external_flash_device* device); + +#endif // MICROPY_INCLUDED_SUPERVISOR_SPI_FLASH_H diff --git a/supervisor/stub/filesystem.c b/supervisor/stub/filesystem.c new file mode 100644 index 00000000000..1c4a3e12dda --- /dev/null +++ b/supervisor/stub/filesystem.c @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/filesystem.h" + +void filesystem_init(bool create_allowed, bool force_create) { + (void) create_allowed; + (void) force_create; +} + +void filesystem_flush(void) { +} + +bool filesystem_is_writable_by_python(fs_user_mount_t *vfs) { + (void) vfs; + return true; +} + +bool filesystem_present(void) { + return false; +} diff --git a/supervisor/stub/safe_mode.c b/supervisor/stub/safe_mode.c new file mode 100644 index 00000000000..1a792becd91 --- /dev/null +++ b/supervisor/stub/safe_mode.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/shared/safe_mode.h" + +safe_mode_t wait_for_safe_mode_reset(void) { + return NO_SAFE_MODE; +} + +void reset_into_safe_mode(safe_mode_t reason) { + (void) reason; +} + +void print_safe_mode_message(safe_mode_t reason) { + (void) reason; +} diff --git a/supervisor/stub/serial.c b/supervisor/stub/serial.c new file mode 100644 index 00000000000..9565519141c --- /dev/null +++ b/supervisor/stub/serial.c @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/serial.h" + +void serial_init(void) { + +} + +bool serial_connected(void) { + return false; +} + +char serial_read(void) { + return 0; +} + +bool serial_bytes_available(void) { + return false; +} + +void serial_write(const char* text) { + (void) text; +} diff --git a/supervisor/stub/stack.c b/supervisor/stub/stack.c new file mode 100644 index 00000000000..9a9ecd32f6f --- /dev/null +++ b/supervisor/stub/stack.c @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/shared/stack.h" + +bool stack_ok(void) { + return true; +} + +void assert_heap_ok(void) { +} + +void stack_init(void) { +} + +void stack_resize(void) { +} + +void set_next_stack_size(uint32_t size) { + (void) size; +} + +uint32_t get_current_stack_size(void) { + return 0; +} diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk new file mode 100644 index 00000000000..2d50e7a8b16 --- /dev/null +++ b/supervisor/supervisor.mk @@ -0,0 +1,112 @@ +SRC_SUPERVISOR = \ + main.c \ + supervisor/port.c \ + supervisor/shared/autoreload.c \ + supervisor/shared/display.c \ + supervisor/shared/filesystem.c \ + supervisor/shared/flash.c \ + supervisor/shared/micropython.c \ + supervisor/shared/rgb_led_status.c \ + supervisor/shared/safe_mode.c \ + supervisor/shared/stack.c \ + supervisor/shared/status_leds.c \ + supervisor/shared/translate.c + +ifndef $(NO_USB) +NO_USB = $(wildcard supervisor/usb.c) +endif + +ifneq ($(INTERNAL_FLASH_FILESYSTEM),) + CFLAGS += -DINTERNAL_FLASH_FILESYSTEM=$(INTERNAL_FLASH_FILESYSTEM) +endif +ifneq ($(QSPI_FLASH_FILESYSTEM),) +# EXPRESS_BOARD is obsolete and should be removed when samd-peripherals is updated. + CFLAGS += -DQSPI_FLASH_FILESYSTEM=$(QSPI_FLASH_FILESYSTEM) -DEXPRESS_BOARD +endif +ifneq ($(SPI_FLASH_FILESYSTEM),) +# EXPRESS_BOARD is obsolete and should be removed when samd-peripherals is updated. + CFLAGS += -DSPI_FLASH_FILESYSTEM=$(SPI_FLASH_FILESYSTEM) -DEXPRESS_BOARD +endif + +# Choose which flash filesystem impl to use. +# (Right now INTERNAL_FLASH_FILESYSTEM and SPI_FLASH_FILESYSTEM are mutually exclusive. +# But that might not be true in the future.) +ifdef EXTERNAL_FLASH_DEVICES + CFLAGS += -DEXTERNAL_FLASH_DEVICES=$(EXTERNAL_FLASH_DEVICES) \ + -DEXTERNAL_FLASH_DEVICE_COUNT=$(EXTERNAL_FLASH_DEVICE_COUNT) + + SRC_SUPERVISOR += supervisor/shared/external_flash/external_flash.c + ifeq ($(SPI_FLASH_FILESYSTEM),1) + SRC_SUPERVISOR += supervisor/shared/external_flash/spi_flash.c + else + endif + ifeq ($(QSPI_FLASH_FILESYSTEM),1) + SRC_SUPERVISOR += supervisor/qspi_flash.c supervisor/shared/external_flash/qspi_flash.c + endif +else + SRC_SUPERVISOR += supervisor/internal_flash.c +endif + +ifeq ($(USB),FALSE) + ifeq ($(wildcard supervisor/serial.c),) + SRC_SUPERVISOR += supervisor/stub/serial.c + else + SRC_SUPERVISOR += supervisor/serial.c + endif +else + SRC_SUPERVISOR += lib/tinyusb/src/common/tusb_fifo.c \ + lib/tinyusb/src/device/usbd.c \ + lib/tinyusb/src/device/usbd_control.c \ + lib/tinyusb/src/class/msc/msc_device.c \ + lib/tinyusb/src/class/cdc/cdc_device.c \ + lib/tinyusb/src/class/hid/hid_device.c \ + lib/tinyusb/src/class/midi/midi_device.c \ + lib/tinyusb/src/tusb.c \ + supervisor/shared/serial.c \ + supervisor/usb.c \ + supervisor/shared/usb/usb_desc.c \ + supervisor/shared/usb/usb.c \ + supervisor/shared/usb/usb_msc_flash.c \ + shared-bindings/usb_hid/__init__.c \ + shared-bindings/usb_hid/Device.c \ + shared-bindings/usb_midi/__init__.c \ + shared-bindings/usb_midi/PortIn.c \ + shared-bindings/usb_midi/PortOut.c \ + shared-module/usb_hid/__init__.c \ + shared-module/usb_hid/Device.c \ + shared-module/usb_midi/__init__.c \ + shared-module/usb_midi/PortIn.c \ + shared-module/usb_midi/PortOut.c \ + $(BUILD)/autogen_usb_descriptor.c + CFLAGS += -DUSB_AVAILABLE +endif + +SUPERVISOR_O = $(addprefix $(BUILD)/, $(SRC_SUPERVISOR:.c=.o)) $(BUILD)/autogen_display_resources.o + +$(BUILD)/supervisor/shared/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h + +$(BUILD)/autogen_usb_descriptor.c $(BUILD)/genhdr/autogen_usb_descriptor.h: autogen_usb_descriptor.intermediate + +.INTERMEDIATE: autogen_usb_descriptor.intermediate + +autogen_usb_descriptor.intermediate: ../../tools/gen_usb_descriptor.py Makefile | $(HEADER_BUILD) + $(STEPECHO) "GEN $@" + $(Q)install -d $(BUILD)/genhdr + $(Q)$(PYTHON3) ../../tools/gen_usb_descriptor.py \ + --manufacturer $(USB_MANUFACTURER)\ + --product $(USB_PRODUCT)\ + --vid $(USB_VID)\ + --pid $(USB_PID)\ + --serial_number_length $(USB_SERIAL_NUMBER_LENGTH)\ + --output_c_file $(BUILD)/autogen_usb_descriptor.c\ + --output_h_file $(BUILD)/genhdr/autogen_usb_descriptor.h + +CIRCUITPY_DISPLAY_FONT ?= "../../tools/fonts/ter-u12n.bdf" + +$(BUILD)/autogen_display_resources.c: ../../tools/gen_display_resources.py $(HEADER_BUILD)/qstrdefs.generated.h Makefile | $(HEADER_BUILD) + $(STEPECHO) "GEN $@" + $(Q)install -d $(BUILD)/genhdr + $(Q)$(PYTHON3) ../../tools/gen_display_resources.py \ + --font $(CIRCUITPY_DISPLAY_FONT) \ + --sample_file $(HEADER_BUILD)/qstrdefs.generated.h \ + --output_c_file $(BUILD)/autogen_display_resources.c diff --git a/supervisor/usb.h b/supervisor/usb.h new file mode 100644 index 00000000000..c87540d4087 --- /dev/null +++ b/supervisor/usb.h @@ -0,0 +1,44 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach for Adafruit Industries + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SUPERVISOR_USB_H +#define MICROPY_INCLUDED_SUPERVISOR_USB_H + +#include + +// Ports must call this as frequently as they can in order to keep the USB connection +// alive and responsive. +void usb_background(void); + +// Only inits the USB peripheral clocks and pins. The peripheral will be initialized by +// TinyUSB. +void init_usb_hardware(void); + +// Shared implementation. +bool usb_enabled(void); +void usb_init(void); + +#endif // MICROPY_INCLUDED_SUPERVISOR_USB_H diff --git a/tests/basics/array_intbig.py b/tests/basics/array_intbig.py index 5702a8ae635..ef3b567935d 100644 --- a/tests/basics/array_intbig.py +++ b/tests/basics/array_intbig.py @@ -1,4 +1,6 @@ # test array types QqLl that require big-ints +import skip_if +skip_if.no_bigint() try: from array import array diff --git a/tests/basics/array_micropython.py b/tests/basics/array_micropython.py index e26ad7ae969..b92c5a9b938 100644 --- a/tests/basics/array_micropython.py +++ b/tests/basics/array_micropython.py @@ -5,6 +5,12 @@ print("SKIP") raise SystemExit +try: + array.array('O') +except ValueError: + print("SKIP") + raise SystemExit + # arrays of objects a = array.array('O') a.append(1) diff --git a/tests/basics/array_mul.py b/tests/basics/array_mul.py new file mode 100644 index 00000000000..bb5f3aa6b14 --- /dev/null +++ b/tests/basics/array_mul.py @@ -0,0 +1,28 @@ +try: + import array +except ImportError: + print("SKIP") + raise SystemExit + +a1 = array.array('I', [1]) +a2 = array.array('I', [2]) * 2 +a3 = (a1 + a2) +print(a3) + +a3 *= 5 +print(a3) + +a3 *= 0 +print(a3) + +a4 = a2 * 0 +print(a4) + +a4 *= 0 +print(a4) + +a4 = a4 * 2 +print(a4) + +a4 *= 2 +print(a4) diff --git a/tests/basics/async_await2.py b/tests/basics/async_await2.py index 129d3751a59..7097ce85a6a 100644 --- a/tests/basics/async_await2.py +++ b/tests/basics/async_await2.py @@ -1,7 +1,7 @@ # test await expression import sys -if sys.implementation.name == 'micropython': +if sys.implementation.name in ('micropython', 'circuitpython'): # uPy allows normal generators to be awaitables coroutine = lambda f: f else: diff --git a/tests/basics/async_for2.py b/tests/basics/async_for2.py index 89584fcb100..025ff9c4daf 100644 --- a/tests/basics/async_for2.py +++ b/tests/basics/async_for2.py @@ -1,7 +1,7 @@ # test waiting within "async for" aiter/anext functions import sys -if sys.implementation.name == 'micropython': +if sys.implementation.name in ('micropython', 'circuitpython'): # uPy allows normal generators to be awaitables coroutine = lambda f: f else: diff --git a/tests/basics/async_with2.py b/tests/basics/async_with2.py index 44421ae9179..5fb06ba6045 100644 --- a/tests/basics/async_with2.py +++ b/tests/basics/async_with2.py @@ -1,7 +1,7 @@ # test waiting within async with enter/exit functions import sys -if sys.implementation.name == 'micropython': +if sys.implementation.name in ('micropython', 'circuitpython'): # uPy allows normal generators to be awaitables coroutine = lambda f: f else: diff --git a/tests/basics/bigint_array_overflow.py b/tests/basics/bigint_array_overflow.py new file mode 100644 index 00000000000..0dd79c23d59 --- /dev/null +++ b/tests/basics/bigint_array_overflow.py @@ -0,0 +1,28 @@ +import skip_if +skip_if.no_bigint() + +try: + from array import array +except ImportError: + print("SKIP") + raise SystemExit + +def test_array_overflow(typecode, val): + try: + print(array(typecode, [val])) + except OverflowError: + print('OverflowError') + +# big int -1 +test_array_overflow('Q', -2**64 // 2**64) +test_array_overflow('L', -2**64 // 2**64) +test_array_overflow('I', -2**64 // 2**64) +test_array_overflow('H', -2**64 // 2**64) +test_array_overflow('B', -2**64 // 2**64) + +# big int 2**63 +test_array_overflow('q', 2**63) +test_array_overflow('l', 2**63) +test_array_overflow('i', 2**63) +test_array_overflow('h', 2**63) +test_array_overflow('b', 2**63) diff --git a/tests/basics/builtin_enumerate.py b/tests/basics/builtin_enumerate.py index fcbf8697672..29b1dd46c40 100644 --- a/tests/basics/builtin_enumerate.py +++ b/tests/basics/builtin_enumerate.py @@ -1,9 +1,3 @@ -try: - enumerate -except: - print("SKIP") - raise SystemExit - print(list(enumerate([]))) print(list(enumerate([1, 2, 3]))) print(list(enumerate([1, 2, 3], 5))) diff --git a/tests/basics/builtin_pow3.py b/tests/basics/builtin_pow3.py index 94e657bc441..b9e0b8e0460 100644 --- a/tests/basics/builtin_pow3.py +++ b/tests/basics/builtin_pow3.py @@ -28,3 +28,8 @@ print(pow(4, 5, "z")) except TypeError: print("TypeError expected") + +try: + print(pow(4, 5, 0)) +except ValueError: + print("ValueError expected") diff --git a/tests/basics/builtin_print.py b/tests/basics/builtin_print.py index 880aaf44f9b..8b53e32c95b 100644 --- a/tests/basics/builtin_print.py +++ b/tests/basics/builtin_print.py @@ -1,5 +1,6 @@ # test builtin print function +print("break the test") print() print(None) print('') diff --git a/tests/basics/builtin_reversed.py b/tests/basics/builtin_reversed.py index f43505a8bf4..6f07beaadd6 100644 --- a/tests/basics/builtin_reversed.py +++ b/tests/basics/builtin_reversed.py @@ -1,9 +1,5 @@ -# test the builtin reverse() function -try: - reversed -except: - print("SKIP") - raise SystemExit +import skip_if +skip_if.no_reversed() # list print(list(reversed([]))) diff --git a/tests/basics/builtin_slice.py b/tests/basics/builtin_slice.py index df84d5c57bb..68a6635b353 100644 --- a/tests/basics/builtin_slice.py +++ b/tests/basics/builtin_slice.py @@ -9,3 +9,35 @@ def __getitem__(self, idx): # check type print(type(s) is slice) + +s = slice(10) +print(s) + +s = slice(0, 4) +print(s) + +s = slice(0, 4, 2) +print(s) + +s = slice(-1) +print(s) +print(s.indices(10)) + +s = slice(-5, -1) +print(s) +print(s.indices(10)) + +s = slice(-100, -2, -1) +print(s) +print(s.indices(10)) + +s = slice(None, None, -2) +print(s) +print(s.indices(10)) + +s = slice(-100, -2, 0) +print(s) +try: + print(s.indices(10)) +except Exception as e: + print(e) diff --git a/tests/basics/bytearray_intbig.py b/tests/basics/bytearray_intbig.py index 334eabe1224..77bcf222544 100644 --- a/tests/basics/bytearray_intbig.py +++ b/tests/basics/bytearray_intbig.py @@ -1 +1,12 @@ +# Skip if long ints are not supported. +try: + # We have to use variables because 1 << 40 causes an exception on parse and + # cannot be caught. + x = 40 + x = 1 << x +except OverflowError: + print("SKIP") + import sys + sys.exit(1) + print(bytearray(2**65 - (2**65 - 1))) diff --git a/tests/basics/class_reverse_op.py b/tests/basics/class_reverse_op.py index d41c55c9d76..1a047e44845 100644 --- a/tests/basics/class_reverse_op.py +++ b/tests/basics/class_reverse_op.py @@ -1,3 +1,6 @@ +import skip_if +skip_if.no_reverse_ops() + class A: def __init__(self, v): diff --git a/tests/basics/class_store_class.py b/tests/basics/class_store_class.py index 797f88f8526..504f460a7d2 100644 --- a/tests/basics/class_store_class.py +++ b/tests/basics/class_store_class.py @@ -5,11 +5,11 @@ try: from collections import namedtuple except ImportError: - try: - from ucollections import namedtuple - except ImportError: - print("SKIP") - raise SystemExit + print("SKIP") + raise SystemExit + +import skip_if +skip_if.no_cpython_compat() _DefragResultBase = namedtuple('DefragResult', [ 'foo', 'bar' ]) diff --git a/tests/basics/class_super.py b/tests/basics/class_super.py index b6ee68308a7..629b7ddb486 100644 --- a/tests/basics/class_super.py +++ b/tests/basics/class_super.py @@ -35,6 +35,13 @@ def foo(self): return super().foo().count(2) # calling a subsequent method print(B().foo()) +try: + super(1, 1).x +except TypeError: + print(True) +else: + print(False) + # first arg to super must be a type try: super(1, 1) diff --git a/tests/basics/core_class_superproperty.py b/tests/basics/core_class_superproperty.py new file mode 100644 index 00000000000..69db10046a2 --- /dev/null +++ b/tests/basics/core_class_superproperty.py @@ -0,0 +1,15 @@ +""" +test that calling super() getter property in subclass will return the value +""" +class A: + @property + def p(self): + return {"a":10} + +class AA(A): + @property + def p(self): + return super().p + +a = AA() +print(a.p) diff --git a/tests/basics/dict_fromkeys2.py b/tests/basics/dict_fromkeys2.py index dce1e8ef5af..a5371bc5385 100644 --- a/tests/basics/dict_fromkeys2.py +++ b/tests/basics/dict_fromkeys2.py @@ -1,8 +1,5 @@ -try: - reversed -except: - print("SKIP") - raise SystemExit +import skip_if +skip_if.no_reversed() # argument to fromkeys has no __len__ d = dict.fromkeys(reversed(range(1))) diff --git a/tests/basics/dict_fromkeys_reversed.py b/tests/basics/dict_fromkeys_reversed.py new file mode 100644 index 00000000000..34b0ed129c0 --- /dev/null +++ b/tests/basics/dict_fromkeys_reversed.py @@ -0,0 +1,7 @@ +# Skip this test if reversed() isn't built in. +import skip_if +skip_if.no_reversed() + +# argument to fromkeys has no __len__ +d = dict.fromkeys(reversed(range(1))) +print(d) diff --git a/tests/basics/errno1.py b/tests/basics/errno1.py index d7a5ccd542a..cef5326b4a6 100644 --- a/tests/basics/errno1.py +++ b/tests/basics/errno1.py @@ -11,7 +11,10 @@ # check that errors are rendered in a nice way msg = str(OSError(uerrno.EIO)) -print(msg[:7], msg[-5:]) +print(msg[:7], msg[msg.find(']'):]) + +msg = str(OSError(uerrno.ENOBUFS)) +print(msg[:7], msg[msg.find(']'):]) # check that unknown errno is still rendered print(str(OSError(9999))) diff --git a/tests/basics/errno1.py.exp b/tests/basics/errno1.py.exp index 7dd22757ddd..b550468985f 100644 --- a/tests/basics/errno1.py.exp +++ b/tests/basics/errno1.py.exp @@ -1,4 +1,5 @@ -[Errno ] EIO +[Errno ] Input/output error +[Errno ] ENOBUFS 9999 uerrno diff --git a/tests/basics/fun_calldblstar.py b/tests/basics/fun_calldblstar.py index 4a503698ff7..d4816c5cd3d 100644 --- a/tests/basics/fun_calldblstar.py +++ b/tests/basics/fun_calldblstar.py @@ -20,3 +20,10 @@ def f(self, a, b): a = A() a.f(1, **{'b':2}) a.f(1, **{'b':val for val in range(1)}) + +try: + f(1, **{len: 1}) +except TypeError: + print(True) +else: + print(False) diff --git a/tests/basics/gen_stack_overflow.py b/tests/basics/gen_stack_overflow.py new file mode 100644 index 00000000000..5cba0e0549b --- /dev/null +++ b/tests/basics/gen_stack_overflow.py @@ -0,0 +1,7 @@ +def gen(): + yield from gen() + +try: + print(list(gen())) +except RuntimeError: + print("RuntimeError") diff --git a/tests/basics/int_big_zeroone.py b/tests/basics/int_big_zeroone.py index 7e0b7a720ec..81636724a5f 100644 --- a/tests/basics/int_big_zeroone.py +++ b/tests/basics/int_big_zeroone.py @@ -1,5 +1,8 @@ # test [0,-0,1,-1] edge cases of bignum +import skip_if +skip_if.no_bigint() + long_zero = (2**64) >> 65 long_neg_zero = -long_zero long_one = long_zero + 1 diff --git a/tests/basics/int_bytes.py b/tests/basics/int_bytes.py index d1837ea75ca..aaf44008156 100644 --- a/tests/basics/int_bytes.py +++ b/tests/basics/int_bytes.py @@ -1,9 +1,8 @@ print((10).to_bytes(1, "little")) +# Test fitting in length that's not a power of two. +print((0x10000).to_bytes(3, 'little')) print((111111).to_bytes(4, "little")) print((100).to_bytes(10, "little")) -print(int.from_bytes(b"\x00\x01\0\0\0\0\0\0", "little")) -print(int.from_bytes(b"\x01\0\0\0\0\0\0\0", "little")) -print(int.from_bytes(b"\x00\x01\0\0\0\0\0\0", "little")) # check that extra zero bytes don't change the internal int value print(int.from_bytes(bytes(20), "little") == 0) @@ -20,3 +19,15 @@ (1).to_bytes(-1, "little") except ValueError: print("ValueError") + +# too small buffer should raise an error +try: + (256).to_bytes(1, "little") +except OverflowError: + print("OverflowError") + +# negative numbers should raise an error +try: + (-256).to_bytes(2, "little") +except OverflowError: + print("OverflowError") diff --git a/tests/basics/int_bytes_intbig.py b/tests/basics/int_bytes_intbig.py index 147362bef13..b19c8ae53ee 100644 --- a/tests/basics/int_bytes_intbig.py +++ b/tests/basics/int_bytes_intbig.py @@ -1,3 +1,6 @@ +import skip_if +skip_if.no_bigint() + print((2**64).to_bytes(9, "little")) print((2**64).to_bytes(9, "big")) @@ -12,3 +15,15 @@ # check that extra zero bytes don't change the internal int value print(int.from_bytes(b + bytes(10), "little") == int.from_bytes(b, "little")) + +# too small buffer should raise an error +try: + (2**64).to_bytes(8, "little") +except OverflowError: + print("OverflowError") + +# negative numbers should raise an error +try: + (-2**64).to_bytes(9, "little") +except OverflowError: + print("OverflowError") diff --git a/tests/basics/int_longint_bytes.py b/tests/basics/int_longint_bytes.py new file mode 100644 index 00000000000..42e445f539d --- /dev/null +++ b/tests/basics/int_longint_bytes.py @@ -0,0 +1,8 @@ +# Skip if long ints are not supported. +import skip_if +skip_if.no_bigint() + +print((2**64).to_bytes(9, "little")) +print(int.from_bytes(b"\x00\x01\0\0\0\0\0\0", "little")) +print(int.from_bytes(b"\x01\0\0\0\0\0\0\0", "little")) +print(int.from_bytes(b"\x00\x01\0\0\0\0\0\0", "little")) diff --git a/tests/basics/memoryview1.py b/tests/basics/memoryview1.py index c4cc6ffab72..3e5c86768c7 100644 --- a/tests/basics/memoryview1.py +++ b/tests/basics/memoryview1.py @@ -46,51 +46,3 @@ print(list(m[1:-1])) m[2] = 6 print(a) - -# test slice assignment between memoryviews -b1 = bytearray(b'1234') -b2 = bytearray(b'5678') -b3 = bytearray(b'5678') -m1 = memoryview(b1) -m2 = memoryview(b2) -m3 = memoryview(b3) -m2[1:3] = m1[0:2] -print(b2) -b3[1:3] = m1[0:2] -print(b3) -m1[2:4] = b3[1:3] -print(b1) - -try: - m2[1:3] = b1[0:4] -except ValueError: - print("ValueError") - -try: - m2[1:3] = m1[0:4] -except ValueError: - print("ValueError") - -try: - m2[0:4] = m1[1:3] -except ValueError: - print("ValueError") - -# test memoryview of arrays with items sized larger than 1 -a1 = array.array('i', [0]*5) -m4 = memoryview(a1) -a2 = array.array('i', [3]*5) -m5 = memoryview(a2) -m4[1:3] = m5[1:3] -print(a1) - -try: - m4[1:3] = m2[1:3] -except ValueError: - print("ValueError") - -# invalid assignment on RHS -try: - memoryview(array.array('i'))[0:2] = b'1234' -except ValueError: - print('ValueError') diff --git a/tests/basics/memoryview1_slice_assign.py b/tests/basics/memoryview1_slice_assign.py new file mode 100644 index 00000000000..f272fd392f4 --- /dev/null +++ b/tests/basics/memoryview1_slice_assign.py @@ -0,0 +1,58 @@ +import skip_if + +try: + memoryview +except: + skip_if.skip() + +skip_if.no_slice_assign() + +# test slice assignment between memoryviews +b1 = bytearray(b'1234') +b2 = bytearray(b'5678') +b3 = bytearray(b'5678') +m1 = memoryview(b1) +m2 = memoryview(b2) +m3 = memoryview(b3) +m2[1:3] = m1[0:2] +print(b2) +b3[1:3] = m1[0:2] +print(b3) +m1[2:4] = b3[1:3] +print(b1) + +try: + m2[1:3] = b1[0:4] +except ValueError: + print("ValueError") + +try: + m2[1:3] = m1[0:4] +except ValueError: + print("ValueError") + +try: + m2[0:4] = m1[1:3] +except ValueError: + print("ValueError") + +import array + +# test memoryview of arrays with items sized larger than 1 +a1 = array.array('i', [0]*5) +m4 = memoryview(a1) +a2 = array.array('i', [3]*5) +m5 = memoryview(a2) +m4[1:3] = m5[1:3] +print(a1) + +try: + m4[1:3] = m2[1:3] +except ValueError: + print("ValueError") + +# invalid assignment on RHS +try: + memoryview(array.array('i'))[0:2] = b'1234' +except ValueError: + print('ValueError') diff --git a/tests/basics/namedtuple1.py b/tests/basics/namedtuple1.py index 15e3b785edd..63d9eddd4e3 100644 --- a/tests/basics/namedtuple1.py +++ b/tests/basics/namedtuple1.py @@ -1,8 +1,5 @@ try: - try: - from collections import namedtuple - except ImportError: - from ucollections import namedtuple + from collections import namedtuple except ImportError: print("SKIP") raise SystemExit @@ -68,11 +65,6 @@ except TypeError: print("TypeError") -# Try single string -T3 = namedtuple("TupComma", "foo bar") -t = T3(1, 2) -print(t.foo, t.bar) - # Try tuple T4 = namedtuple("TupTuple", ("foo", "bar")) t = T4(1, 2) diff --git a/tests/basics/namedtuple1_cpython_compat.py b/tests/basics/namedtuple1_cpython_compat.py new file mode 100644 index 00000000000..061ae94e587 --- /dev/null +++ b/tests/basics/namedtuple1_cpython_compat.py @@ -0,0 +1,17 @@ +import skip_if +skip_if.no_cpython_compat() + +try: + from collections import namedtuple +except ImportError: + skip_if.skip() + +# Try single string +T3 = namedtuple("TupComma", "foo bar") +t = T3(1, 2) +print(t.foo, t.bar) + +# Try single string with comma field separator +# Not implemented so far +#T2 = namedtuple("TupComma", "foo,bar") +#t = T2(1, 2) diff --git a/tests/basics/ordereddict1.py b/tests/basics/ordereddict1.py index d1633f0bb0e..9c62b2d6233 100644 --- a/tests/basics/ordereddict1.py +++ b/tests/basics/ordereddict1.py @@ -1,11 +1,8 @@ try: from collections import OrderedDict except ImportError: - try: - from ucollections import OrderedDict - except ImportError: - print("SKIP") - raise SystemExit + print("SKIP") + raise SystemExit d = OrderedDict([(10, 20), ("b", 100), (1, 2)]) print(len(d)) diff --git a/tests/basics/ordereddict_eq.py b/tests/basics/ordereddict_eq.py index c69daf8802c..e103c867e23 100644 --- a/tests/basics/ordereddict_eq.py +++ b/tests/basics/ordereddict_eq.py @@ -1,11 +1,8 @@ try: from collections import OrderedDict except ImportError: - try: - from ucollections import OrderedDict - except ImportError: - print("SKIP") - raise SystemExit + print("SKIP") + raise SystemExit x = OrderedDict() y = OrderedDict() diff --git a/tests/basics/self_type_check.py b/tests/basics/self_type_check.py index 947e362cdbd..206678e25d1 100644 --- a/tests/basics/self_type_check.py +++ b/tests/basics/self_type_check.py @@ -1,4 +1,6 @@ # make sure type of first arg (self) to a builtin method is checked +import skip_if +skip_if.board_in("gemma_m0", "trinket_m0") list.append diff --git a/tests/basics/smallint_array_overflow.py b/tests/basics/smallint_array_overflow.py new file mode 100644 index 00000000000..25b457cca1d --- /dev/null +++ b/tests/basics/smallint_array_overflow.py @@ -0,0 +1,52 @@ +try: + from array import array +except ImportError: + print("SKIP") + raise SystemExit + +def test_array_overflow(typecode, val): + try: + print(array(typecode, [val])) + except OverflowError: + print('OverflowError') + +def test_bytearray_overflow(val): + try: + print(bytearray([val])) + except (OverflowError, ValueError): + # CircuitPython always does OverflowError + print('(OverflowError, ValueError)') + + +# small int -1 +test_array_overflow('Q', -1) +test_array_overflow('L', -1) +test_array_overflow('I', -1) +test_array_overflow('H', -1) +test_array_overflow('B', -1) + +# 0 ok +test_array_overflow('Q', 0) +test_array_overflow('L', 0) +test_array_overflow('I', 0) +test_array_overflow('H', 0) +test_array_overflow('B', 0) + +# 1 ok +test_array_overflow('Q', 1) +test_array_overflow('L', 1) +test_array_overflow('I', 1) +test_array_overflow('H', 1) +test_array_overflow('B', 1) + +# truth value conversions +test_array_overflow('b', True) +test_array_overflow('b', False) + +# similar tests for bytearrays +test_bytearray_overflow(0) +test_bytearray_overflow(1) +test_bytearray_overflow(-1) +test_bytearray_overflow(256) +test_bytearray_overflow(True) +test_bytearray_overflow(False) diff --git a/tests/basics/struct_micropython.py b/tests/basics/struct_micropython.py index f203a4666f8..e721530714d 100644 --- a/tests/basics/struct_micropython.py +++ b/tests/basics/struct_micropython.py @@ -9,6 +9,12 @@ print("SKIP") raise SystemExit +try: + struct.pack('O', None) +except ValueError: + print("SKIP") + raise SystemExit + class A(): pass diff --git a/tests/basics/struct_overflow.py b/tests/basics/struct_overflow.py new file mode 100644 index 00000000000..aee0c6b9dbf --- /dev/null +++ b/tests/basics/struct_overflow.py @@ -0,0 +1,47 @@ +import skip_if +skip_if.no_bigint() + +try: + import ustruct as struct +except: + try: + import struct + except ImportError: + print("SKIP") + raise SystemExit + +def test_struct_overflow(typecode, val): + try: + print(struct.pack(typecode, val)) + except OverflowError: + print('OverflowError') + except struct.error: + print('OverflowError') + +# small int -1 +test_struct_overflow('>Q', -1) +test_struct_overflow('>L', -1) +test_struct_overflow('>I', -1) +test_struct_overflow('>H', -1) +test_struct_overflow('>B', -1) + +# big int -1 +test_struct_overflow('>Q', -2**64 // 2**64) +test_struct_overflow('>L', -2**64 // 2**64) +test_struct_overflow('>I', -2**64 // 2**64) +test_struct_overflow('>H', -2**64 // 2**64) +test_struct_overflow('>B', -2**64 // 2**64) + +# possibly small ints +test_struct_overflow('>q', 2**63) +test_struct_overflow('>l', 2**31) +test_struct_overflow('>i', 2**31) +test_struct_overflow('>h', 2**15) +test_struct_overflow('>b', 2**7) + +# definitely big ints +test_struct_overflow('>q', 2**64 // 2**1) +test_struct_overflow('>l', 2**64 // 2**33) +test_struct_overflow('>i', 2**64 // 2**33) +test_struct_overflow('>h', 2**64 // 2**49) +test_struct_overflow('>b', 2**64 // 2**57) diff --git a/tests/basics/sys1.py b/tests/basics/sys1.py index 0d74a1292b1..da11c88d3e9 100644 --- a/tests/basics/sys1.py +++ b/tests/basics/sys1.py @@ -14,7 +14,7 @@ print(True) try: - print(sys.implementation.name in ('cpython', 'micropython')) + print(sys.implementation.name in ('cpython', 'micropython', 'circuitpython')) except AttributeError: # Effectively skip subtests print(True) diff --git a/tests/basics/types3.py b/tests/basics/types3.py new file mode 100644 index 00000000000..71f7906923b --- /dev/null +++ b/tests/basics/types3.py @@ -0,0 +1,20 @@ +try: + type('abc', None, None) +except TypeError: + print(True) +else: + print(False) + +try: + type('abc', (), None) +except TypeError: + print(True) +else: + print(False) + +try: + type('abc', (1,), {}) +except TypeError: + print(True) +else: + print(False) diff --git a/tests/bench/var-8-namedtuple-1st.py b/tests/bench/var-8-namedtuple-1st.py index d862480a517..90ae7209d88 100644 --- a/tests/bench/var-8-namedtuple-1st.py +++ b/tests/bench/var-8-namedtuple-1st.py @@ -1,5 +1,5 @@ import bench -from ucollections import namedtuple +from collections import namedtuple T = namedtuple("Tup", ["num", "bar"]) diff --git a/tests/bench/var-8.1-namedtuple-5th.py b/tests/bench/var-8.1-namedtuple-5th.py index 0bcf6618032..0d5789d2ed0 100644 --- a/tests/bench/var-8.1-namedtuple-5th.py +++ b/tests/bench/var-8.1-namedtuple-5th.py @@ -1,5 +1,5 @@ import bench -from ucollections import namedtuple +from collections import namedtuple T = namedtuple("Tup", ["foo1", "foo2", "foo3", "foo4", "num"]) diff --git a/tests/circuitpython/blinky.py b/tests/circuitpython/blinky.py new file mode 100644 index 00000000000..a9412b07c6e --- /dev/null +++ b/tests/circuitpython/blinky.py @@ -0,0 +1,2 @@ +import digitalio +import board diff --git a/tests/circuitpython/nvm_not_present.py b/tests/circuitpython/nvm_not_present.py new file mode 100644 index 00000000000..141e60b01e3 --- /dev/null +++ b/tests/circuitpython/nvm_not_present.py @@ -0,0 +1,6 @@ +import skip_if +skip_if.board_not_in("gemma_m0", "trinket_m0") + +import microcontroller + +assert(microcontroller.nvm == None) diff --git a/tests/circuitpython/nvm_present.py b/tests/circuitpython/nvm_present.py new file mode 100644 index 00000000000..bef80dcc614 --- /dev/null +++ b/tests/circuitpython/nvm_present.py @@ -0,0 +1,24 @@ +import skip_if +# TODO(tannewt): Remove this when we add nvm support to 3.x +skip_if.always() +skip_if.board_not_in("metro_m0_express", "feather_m0_express", "circuitplayground_express") + +import microcontroller +import random +nvm = microcontroller.nvm + +len(nvm) + +single = random.randint(0, 255) +nvm[1] = single +assert(nvm[1] == single) + +nvm[0] = single +assert(nvm[0] == single) + +b = bytearray() +for i in range(10): + b.append(random.randint(0, 255)) + +microcontroller.nvm[10:20] = b +assert(microcontroller.nvm[10:20] == b) diff --git a/tests/cmdline/repl_autocomplete.py b/tests/cmdline/repl_autocomplete.py index 27cad428f73..43c49cdc25e 100644 --- a/tests/cmdline/repl_autocomplete.py +++ b/tests/cmdline/repl_autocomplete.py @@ -6,4 +6,7 @@ 1, x.isdi () i = str i.lowe ('ABC') +x = 5 +x.  +x._ None.  diff --git a/tests/cmdline/repl_autocomplete.py.exp b/tests/cmdline/repl_autocomplete.py.exp index 75002985e3c..7d160e7bf9b 100644 --- a/tests/cmdline/repl_autocomplete.py.exp +++ b/tests/cmdline/repl_autocomplete.py.exp @@ -10,5 +10,11 @@ Use \.\+ >>> i = str >>> i.lower('ABC') 'abc' +>>> x = 5 +>>> x. +from_bytes to_bytes +>>> x. +>>> x.__class__ + >>> None. >>> diff --git a/tests/cpydiff/core_class_superproperty.py b/tests/cpydiff/core_class_superproperty.py deleted file mode 100644 index 1ec210550ef..00000000000 --- a/tests/cpydiff/core_class_superproperty.py +++ /dev/null @@ -1,18 +0,0 @@ -""" -categories: Core,Classes -description: Calling super() getter property in subclass will return a property object, not the value -cause: Unknown -workaround: Unknown -""" -class A: - @property - def p(self): - return {"a":10} - -class AA(A): - @property - def p(self): - return super().p - -a = AA() -print(a.p) diff --git a/tests/extmod/ubinascii_a2b_base64.py b/tests/extmod/ubinascii_a2b_base64.py index 05a3169f3a8..5e642ec515a 100644 --- a/tests/extmod/ubinascii_a2b_base64.py +++ b/tests/extmod/ubinascii_a2b_base64.py @@ -28,6 +28,9 @@ print(binascii.a2b_base64(b'Zm9v===')) print(binascii.a2b_base64(b'Zm9v===YmFy')) +# Unicode strings can be decoded +print(binascii.a2b_base64(u'Zm9v===YmFy')) + try: print(binascii.a2b_base64(b'abc')) except ValueError: diff --git a/tests/extmod/ubinascii_b2a_base64.py b/tests/extmod/ubinascii_b2a_base64.py index f4bb69fe0c9..283c3936d3d 100644 --- a/tests/extmod/ubinascii_b2a_base64.py +++ b/tests/extmod/ubinascii_b2a_base64.py @@ -20,3 +20,7 @@ print(binascii.b2a_base64(b'\x7f\x80\xff')) print(binascii.b2a_base64(b'1234ABCDabcd')) print(binascii.b2a_base64(b'\x00\x00>')) # convert into '+' +try: + print(binascii.b2a_base64('')) +except TypeError: + print("TypeError") diff --git a/tests/extmod/ubinascii_crc32.py b/tests/extmod/ubinascii_crc32.py index 89664a9b365..a826662f116 100644 --- a/tests/extmod/ubinascii_crc32.py +++ b/tests/extmod/ubinascii_crc32.py @@ -22,3 +22,7 @@ print(hex(binascii.crc32(b'\x00' * 16, binascii.crc32(b'\x00' * 16)))) print(hex(binascii.crc32(b'\xff' * 16, binascii.crc32(b'\xff' * 16)))) print(hex(binascii.crc32(bytes(range(16, 32)), binascii.crc32(bytes(range(16)))))) +try: + binascii.crc32('') +except TypeError: + print("TypeError") diff --git a/tests/extmod/ubinascii_hexlify.py b/tests/extmod/ubinascii_hexlify.py index bc99287476f..dabc3c7e4ca 100644 --- a/tests/extmod/ubinascii_hexlify.py +++ b/tests/extmod/ubinascii_hexlify.py @@ -11,3 +11,7 @@ print(binascii.hexlify(b'\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f')) print(binascii.hexlify(b'\x7f\x80\xff')) print(binascii.hexlify(b'1234ABCDabcd')) +try: + binascii.hexlify('') +except TypeError: + print("TypeError") diff --git a/tests/extmod/ubinascii_unhexlify.py b/tests/extmod/ubinascii_unhexlify.py index 865abfe3a82..41a1bd1b8f4 100644 --- a/tests/extmod/ubinascii_unhexlify.py +++ b/tests/extmod/ubinascii_unhexlify.py @@ -12,6 +12,9 @@ print(binascii.unhexlify(b'7f80ff')) print(binascii.unhexlify(b'313233344142434461626364')) +# Unicode strings can be decoded +print(binascii.unhexlify('313233344142434461626364')) + try: a = binascii.unhexlify(b'0') # odd buffer length except ValueError: diff --git a/tests/extmod/uhashlib_sha1.py b/tests/extmod/uhashlib_sha1.py index 4f7066899aa..9d6427b33ff 100644 --- a/tests/extmod/uhashlib_sha1.py +++ b/tests/extmod/uhashlib_sha1.py @@ -19,3 +19,10 @@ sha1 = hashlib.sha1(b'hello') sha1.update(b'world') print(sha1.digest()) + +sha1 = hashlib.sha1(b'hello') +try: + sha1.update(u'world') +except TypeError as e: + print("TypeError") +print(sha1.digest()) diff --git a/tests/extmod/uhashlib_sha256.py b/tests/extmod/uhashlib_sha256.py index 676d4797949..a793ea49306 100644 --- a/tests/extmod/uhashlib_sha256.py +++ b/tests/extmod/uhashlib_sha256.py @@ -26,6 +26,13 @@ # 56 bytes is a boundary case in the algorithm print(hashlib.sha256(b"\xff" * 56).digest()) +sha256 = hashlib.sha256(b'hello') +try: + sha256.update(u'world') +except TypeError as e: + print("TypeError") +print(sha256.digest()) + # TODO: running .digest() several times in row is not supported() #h = hashlib.sha256(b'123') #print(h.digest()) diff --git a/tests/extmod/ure1.py b/tests/extmod/ure1.py index 54471ed4f97..710720c8b65 100644 --- a/tests/extmod/ure1.py +++ b/tests/extmod/ure1.py @@ -28,6 +28,19 @@ except IndexError: print("IndexError") +r = re.compile(r"\n") +m = r.match("\n") +print(m.group(0)) +m = r.match("\\") +print(m) +r = re.compile(r"[\n-\r]") +m = r.match("\n") +print(m.group(0)) +r = re.compile(r"[\]]") +m = r.match("]") +print(m.group(0)) +print("===") + r = re.compile("[a-cu-z]") m = r.match("a") print(m.group(0)) diff --git a/tests/extmod/ure_groups.py b/tests/extmod/ure_groups.py new file mode 100644 index 00000000000..4fac896d7fd --- /dev/null +++ b/tests/extmod/ure_groups.py @@ -0,0 +1,33 @@ +# test match.groups() + +try: + import ure as re +except ImportError: + try: + import re + except ImportError: + print("SKIP") + raise SystemExit + +try: + m = re.match(".", "a") + m.groups +except AttributeError: + print('SKIP') + raise SystemExit + + +m = re.match(r'(([0-9]*)([a-z]*)[0-9]*)','1234hello567') +print(m.groups()) + +m = re.match(r'([0-9]*)(([a-z]*)([0-9]*))','1234hello567') +print(m.groups()) + +# optional group that matches +print(re.match(r'(a)?b(c)', 'abc').groups()) + +# optional group that doesn't match +print(re.match(r'(a)?b(c)', 'bc').groups()) + +# only a single match +print(re.match(r'abc', 'abc').groups()) diff --git a/tests/extmod/ure_span.py b/tests/extmod/ure_span.py new file mode 100644 index 00000000000..50f44399ce7 --- /dev/null +++ b/tests/extmod/ure_span.py @@ -0,0 +1,40 @@ +# test match.span(), and nested spans + +try: + import ure as re +except ImportError: + try: + import re + except ImportError: + print("SKIP") + raise SystemExit + +try: + m = re.match(".", "a") + m.span +except AttributeError: + print('SKIP') + raise SystemExit + + +def print_spans(match): + print('----') + try: + i = 0 + while True: + print(match.span(i), match.start(i), match.end(i)) + i += 1 + except IndexError: + pass + +m = re.match(r'(([0-9]*)([a-z]*)[0-9]*)','1234hello567') +print_spans(m) + +m = re.match(r'([0-9]*)(([a-z]*)([0-9]*))','1234hello567') +print_spans(m) + +# optional span that matches +print_spans(re.match(r'(a)?b(c)', 'abc')) + +# optional span that doesn't match +print_spans(re.match(r'(a)?b(c)', 'bc')) diff --git a/tests/extmod/ure_sub.py b/tests/extmod/ure_sub.py new file mode 100644 index 00000000000..4aeb8650a18 --- /dev/null +++ b/tests/extmod/ure_sub.py @@ -0,0 +1,61 @@ +try: + import ure as re +except ImportError: + try: + import re + except ImportError: + print('SKIP') + raise SystemExit + +try: + re.sub +except AttributeError: + print('SKIP') + raise SystemExit + + +def multiply(m): + return str(int(m.group(0)) * 2) + +print(re.sub("\d+", multiply, "10 20 30 40 50")) + +print(re.sub("\d+", lambda m: str(int(m.group(0)) // 2), "10 20 30 40 50")) + +def A(): + return "A" +print(re.sub('a', A(), 'aBCBABCDabcda.')) + +print( + re.sub( + r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):', + 'static PyObject*\npy_\\1(void){\n return;\n}\n', + '\n\ndef myfunc():\n\ndef myfunc1():\n\ndef myfunc2():' + ) +) + +print( + re.compile( + '(calzino) (blu|bianco|verde) e (scarpa) (blu|bianco|verde)' + ).sub( + r'\g<1> colore \2 con \g<3> colore \4? ...', + 'calzino blu e scarpa verde' + ) +) + +# no matches at all +print(re.sub('a', 'b', 'c')) + +# with maximum substitution count specified +print(re.sub('a', 'b', '1a2a3a', 2)) + +# invalid group +try: + re.sub('(a)', 'b\\2', 'a') +except: + print('invalid group') + +# invalid group with very large number (to test overflow in uPy) +try: + re.sub('(a)', 'b\\199999999999999999999999999999999999999', 'a') +except: + print('invalid group') diff --git a/tests/extmod/ure_sub_unmatched.py b/tests/extmod/ure_sub_unmatched.py new file mode 100644 index 00000000000..4795b3196f4 --- /dev/null +++ b/tests/extmod/ure_sub_unmatched.py @@ -0,0 +1,19 @@ +# test re.sub with unmatched groups, behaviour changed in CPython 3.5 + +try: + import ure as re +except ImportError: + try: + import re + except ImportError: + print('SKIP') + raise SystemExit + +try: + re.sub +except AttributeError: + print('SKIP') + raise SystemExit + +# first group matches, second optional group doesn't so is replaced with a blank +print(re.sub(r'(a)(b)?', r'\2-\1', '1a2')) diff --git a/tests/extmod/ure_sub_unmatched.py.exp b/tests/extmod/ure_sub_unmatched.py.exp new file mode 100644 index 00000000000..1e5f0fda055 --- /dev/null +++ b/tests/extmod/ure_sub_unmatched.py.exp @@ -0,0 +1 @@ +1-a2 diff --git a/tests/extmod/vfs_fat_fileio1.py b/tests/extmod/vfs_fat_fileio1.py index 51cd765222c..4635ca84b53 100644 --- a/tests/extmod/vfs_fat_fileio1.py +++ b/tests/extmod/vfs_fat_fileio1.py @@ -23,11 +23,13 @@ def readblocks(self, n, buf): #print("readblocks(%s, %x(%d))" % (n, id(buf), len(buf))) for i in range(len(buf)): buf[i] = self.data[n * self.SEC_SIZE + i] + return 0 def writeblocks(self, n, buf): #print("writeblocks(%s, %x)" % (n, id(buf))) for i in range(len(buf)): self.data[n * self.SEC_SIZE + i] = buf[i] + return 0 def ioctl(self, op, arg): #print("ioctl(%d, %r)" % (op, arg)) diff --git a/tests/extmod/vfs_fat_fileio2.py b/tests/extmod/vfs_fat_fileio2.py index 9b9a11e435b..ab9623ddf8c 100644 --- a/tests/extmod/vfs_fat_fileio2.py +++ b/tests/extmod/vfs_fat_fileio2.py @@ -23,11 +23,13 @@ def readblocks(self, n, buf): #print("readblocks(%s, %x(%d))" % (n, id(buf), len(buf))) for i in range(len(buf)): buf[i] = self.data[n * self.SEC_SIZE + i] + return 0 def writeblocks(self, n, buf): #print("writeblocks(%s, %x)" % (n, id(buf))) for i in range(len(buf)): self.data[n * self.SEC_SIZE + i] = buf[i] + return 0 def ioctl(self, op, arg): #print("ioctl(%d, %r)" % (op, arg)) diff --git a/tests/extmod/vfs_fat_more.py b/tests/extmod/vfs_fat_more.py index 4384e55cbab..8ddaf49fc25 100644 --- a/tests/extmod/vfs_fat_more.py +++ b/tests/extmod/vfs_fat_more.py @@ -23,11 +23,13 @@ def readblocks(self, n, buf): #print("readblocks(%s, %x(%d))" % (n, id(buf), len(buf))) for i in range(len(buf)): buf[i] = self.data[n * self.SEC_SIZE + i] + return 0 def writeblocks(self, n, buf): #print("writeblocks(%s, %x)" % (n, id(buf))) for i in range(len(buf)): self.data[n * self.SEC_SIZE + i] = buf[i] + return 0 def ioctl(self, op, arg): #print("ioctl(%d, %r)" % (op, arg)) diff --git a/tests/extmod/vfs_fat_oldproto.py b/tests/extmod/vfs_fat_oldproto.py index 3caaa368db0..b671f3db2b5 100644 --- a/tests/extmod/vfs_fat_oldproto.py +++ b/tests/extmod/vfs_fat_oldproto.py @@ -22,11 +22,13 @@ def readblocks(self, n, buf): #print("readblocks(%s, %x(%d))" % (n, id(buf), len(buf))) for i in range(len(buf)): buf[i] = self.data[n * self.SEC_SIZE + i] + return 0 def writeblocks(self, n, buf): #print("writeblocks(%s, %x)" % (n, id(buf))) for i in range(len(buf)): self.data[n * self.SEC_SIZE + i] = buf[i] + return 0 def sync(self): pass diff --git a/tests/extmod/vfs_fat_ramdisk.py b/tests/extmod/vfs_fat_ramdisk.py index f6e5c64df05..30a94ec4e11 100644 --- a/tests/extmod/vfs_fat_ramdisk.py +++ b/tests/extmod/vfs_fat_ramdisk.py @@ -23,11 +23,13 @@ def readblocks(self, n, buf): #print("readblocks(%s, %x(%d))" % (n, id(buf), len(buf))) for i in range(len(buf)): buf[i] = self.data[n * self.SEC_SIZE + i] + return 0 def writeblocks(self, n, buf): #print("writeblocks(%s, %x)" % (n, id(buf))) for i in range(len(buf)): self.data[n * self.SEC_SIZE + i] = buf[i] + return 0 def ioctl(self, op, arg): #print("ioctl(%d, %r)" % (op, arg)) @@ -51,6 +53,8 @@ def ioctl(self, op, arg): vfs = uos.VfsFat(bdev) uos.mount(vfs, "/ramdisk") +vfs.label = 'label test' +print("label:", vfs.label) print("statvfs:", vfs.statvfs("/ramdisk")) print("getcwd:", vfs.getcwd()) diff --git a/tests/extmod/vfs_fat_ramdisk.py.exp b/tests/extmod/vfs_fat_ramdisk.py.exp index ef6cf1e72b6..704408cd0b2 100644 --- a/tests/extmod/vfs_fat_ramdisk.py.exp +++ b/tests/extmod/vfs_fat_ramdisk.py.exp @@ -1,10 +1,11 @@ True True +label: LABEL TEST statvfs: (512, 512, 16, 16, 16, 0, 0, 0, 0, 255) getcwd: / True [('foo_file.txt', 32768, 0, 6)] -stat root: (16384, 0, 0, 0, 0, 0, 0, 0, 0, 0) +stat root: (16384, 0, 0, 0, 0, 0, 0, 946684800, 946684800, 946684800) stat file: (32768, 0, 0, 0, 0, 0, 6) True True diff --git a/tests/import/mpy_invalid.py b/tests/import/mpy_invalid.py index 6a4e116e784..b9dd99a4408 100644 --- a/tests/import/mpy_invalid.py +++ b/tests/import/mpy_invalid.py @@ -59,8 +59,8 @@ def open(self, path, mode): mod = 'mod%u' % i try: __import__(mod) - except ValueError as er: - print(mod, 'ValueError', er) + except Exception as e: + print(mod, type(e).__name__, e) # unmount and undo path addition uos.umount('/userfs') diff --git a/tests/import/mpy_invalid.py.exp b/tests/import/mpy_invalid.py.exp index 1727ea1cea5..197eb4f7b2f 100644 --- a/tests/import/mpy_invalid.py.exp +++ b/tests/import/mpy_invalid.py.exp @@ -1,3 +1,3 @@ -mod0 ValueError incompatible .mpy file -mod1 ValueError incompatible .mpy file -mod2 ValueError incompatible .mpy file +mod0 RuntimeError Corrupt .mpy file +mod1 RuntimeError Corrupt .mpy file +mod2 MpyError Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info. diff --git a/tests/misc/non_compliant.py b/tests/misc/non_compliant.py index 580583bf39c..99633416a4c 100644 --- a/tests/misc/non_compliant.py +++ b/tests/misc/non_compliant.py @@ -2,7 +2,7 @@ try: import array - import ustruct + import struct except ImportError: print("SKIP") raise SystemExit @@ -106,10 +106,10 @@ print('NotImplementedError') # struct pack with too many args, not checked by uPy -print(ustruct.pack('bb', 1, 2, 3)) +print(struct.pack('bb', 1, 2, 3)) # struct pack with too few args, not checked by uPy -print(ustruct.pack('bb', 1)) +print(struct.pack('bb', 1)) # array slice assignment with unsupported RHS try: diff --git a/tests/pyboard.py b/tests/pyboard.py index 3a82f6a6a36..616773a313a 120000 --- a/tests/pyboard.py +++ b/tests/pyboard.py @@ -1 +1 @@ -../tools/pyboard.py \ No newline at end of file +../tools/cpboard.py \ No newline at end of file diff --git a/tests/run-tests b/tests/run-tests index cfd7c40379a..94e1591e8a6 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -6,6 +6,9 @@ import sys import platform import argparse import re +import threading +import multiprocessing +from multiprocessing.pool import ThreadPool from glob import glob # Tests require at least CPython 3.3. If your default python3 executable @@ -127,11 +130,14 @@ def run_micropython(pyb, args, test_file, is_special=False): cmdlist.append(test_file) # run the actual test - try: - output_mupy = subprocess.check_output(cmdlist, stderr=subprocess.STDOUT) - except subprocess.CalledProcessError as er: - had_crash = True - output_mupy = er.output + b'CRASH' + e = {"MICROPYPATH": os.getcwd() + ":", "LANG": "en_US.UTF-8"} + p = subprocess.Popen(cmdlist, env=e, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + output_mupy = b'' + while p.poll() is None: + output_mupy += p.stdout.read() + output_mupy += p.stdout.read() + if p.returncode != 0: + output_mupy = b'CRASH' # clean up if we had an intermediate .mpy file if args.via_mpy: @@ -199,13 +205,27 @@ def run_micropython(pyb, args, test_file, is_special=False): def run_feature_check(pyb, args, base_path, test_file): return run_micropython(pyb, args, base_path + "/feature_check/" + test_file, is_special=True) +class ThreadSafeCounter: + def __init__(self, start=0): + self._value = start + self._lock = threading.Lock() + + def add(self, to_add): + with self._lock: self._value += to_add + + def append(self, arg): + self.add([arg]) + + @property + def value(self): + return self._value -def run_tests(pyb, tests, args, base_path="."): - test_count = 0 - testcase_count = 0 - passed_count = 0 - failed_tests = [] - skipped_tests = [] +def run_tests(pyb, tests, args, base_path=".", num_threads=1): + test_count = ThreadSafeCounter() + testcase_count = ThreadSafeCounter() + passed_count = ThreadSafeCounter() + failed_tests = ThreadSafeCounter([]) + skipped_tests = ThreadSafeCounter([]) skip_tests = set() skip_native = False @@ -337,7 +357,7 @@ def run_tests(pyb, tests, args, base_path="."): # Remove them from the below when they work if args.emit == 'native': skip_tests.update({'basics/%s.py' % t for t in 'gen_yield_from gen_yield_from_close gen_yield_from_ducktype gen_yield_from_exc gen_yield_from_executing gen_yield_from_iter gen_yield_from_send gen_yield_from_stopped gen_yield_from_throw gen_yield_from_throw2 gen_yield_from_throw3 generator1 generator2 generator_args generator_close generator_closure generator_exc generator_pend_throw generator_return generator_send'.split()}) # require yield - skip_tests.update({'basics/%s.py' % t for t in 'bytes_gen class_store_class globals_del string_join'.split()}) # require yield + skip_tests.update({'basics/%s.py' % t for t in 'bytes_gen class_store_class globals_del string_join gen_stack_overflow'.split()}) # require yield skip_tests.update({'basics/async_%s.py' % t for t in 'def await await2 for for2 with with2'.split()}) # require yield skip_tests.update({'basics/%s.py' % t for t in 'try_reraise try_reraise2'.split()}) # require raise_varargs skip_tests.update({'basics/%s.py' % t for t in 'with_break with_continue with_return'.split()}) # require complete with support @@ -366,7 +386,7 @@ def run_tests(pyb, tests, args, base_path="."): skip_tests.add('stress/recursive_gen.py') # requires yield skip_tests.add('extmod/vfs_userfs.py') # because native doesn't properly handle globals across different modules - for test_file in tests: + def run_one_test(test_file): test_file = test_file.replace('\\', '/') if args.filters: @@ -376,7 +396,7 @@ def run_tests(pyb, tests, args, base_path="."): if pat.search(test_file): verdict = action if verdict == "exclude": - continue + return test_basename = os.path.basename(test_file) test_name = os.path.splitext(test_basename)[0] @@ -399,12 +419,12 @@ def run_tests(pyb, tests, args, base_path="."): if args.list_tests: if not skip_it: print(test_file) - continue + return if skip_it: print("skip ", test_file) skipped_tests.append(test_name) - continue + return # get expected output test_file_expected = test_file + '.exp' @@ -414,19 +434,25 @@ def run_tests(pyb, tests, args, base_path="."): output_expected = f.read() else: # run CPython to work out expected output - try: - output_expected = subprocess.check_output([CPYTHON3, '-B', test_file]) - if args.write_exp: - with open(test_file_expected, 'wb') as f: - f.write(output_expected) - except subprocess.CalledProcessError: + e = {"PYTHONPATH": os.getcwd(), + "PATH": os.environ["PATH"], + "LANG": "en_US.UTF-8"} + p = subprocess.Popen([CPYTHON3, '-B', test_file], env=e, stdout=subprocess.PIPE) + output_expected = b'' + while p.poll() is None: + output_expected += p.stdout.read() + output_expected += p.stdout.read() + if p.returncode != 0: output_expected = b'CPYTHON3 CRASH' + elif args.write_exp: + with open(test_file_expected, 'wb') as f: + f.write(output_expected) # canonical form for all host platforms is to use \n for end-of-line output_expected = output_expected.replace(b'\r\n', b'\n') if args.write_exp: - continue + return # run MicroPython output_mupy = run_micropython(pyb, args, test_file) @@ -434,16 +460,16 @@ def run_tests(pyb, tests, args, base_path="."): if output_mupy == b'SKIP\n': print("skip ", test_file) skipped_tests.append(test_name) - continue + return - testcase_count += len(output_expected.splitlines()) + testcase_count.add(len(output_expected.splitlines())) filename_expected = test_basename + ".exp" filename_mupy = test_basename + ".out" if output_expected == output_mupy: print("pass ", test_file) - passed_count += 1 + passed_count.add(1) rm_f(filename_expected) rm_f(filename_mupy) else: @@ -451,21 +477,32 @@ def run_tests(pyb, tests, args, base_path="."): f.write(output_expected) with open(filename_mupy, "wb") as f: f.write(output_mupy) + print("### Expected") + print(output_expected) + print("### Actual") + print(output_mupy) print("FAIL ", test_file) failed_tests.append(test_name) - test_count += 1 + test_count.add(1) if args.list_tests: return True - print("{} tests performed ({} individual testcases)".format(test_count, testcase_count)) - print("{} tests passed".format(passed_count)) + if num_threads > 1: + pool = ThreadPool(num_threads) + pool.map(run_one_test, tests) + else: + for test in tests: + run_one_test(test) + + print("{} tests performed ({} individual testcases)".format(test_count.value, testcase_count.value)) + print("{} tests passed".format(passed_count.value)) - if len(skipped_tests) > 0: - print("{} tests skipped: {}".format(len(skipped_tests), ' '.join(skipped_tests))) - if len(failed_tests) > 0: - print("{} tests failed: {}".format(len(failed_tests), ' '.join(failed_tests))) + if len(skipped_tests.value) > 0: + print("{} tests skipped: {}".format(len(skipped_tests.value), ' '.join(sorted(skipped_tests.value)))) + if len(failed_tests.value) > 0: + print("{} tests failed: {}".format(len(failed_tests.value), ' '.join(sorted(failed_tests.value)))) return False # all tests succeeded @@ -513,6 +550,8 @@ the last matching regex is used: cmd_parser.add_argument('--heapsize', help='heapsize to use (use default if not specified)') cmd_parser.add_argument('--via-mpy', action='store_true', help='compile .py files to .mpy first') cmd_parser.add_argument('--keep-path', action='store_true', help='do not clear MICROPYPATH when running tests') + cmd_parser.add_argument('-j', '--jobs', default=1, metavar='N', type=int, help='Number of tests to run simultaneously') + cmd_parser.add_argument('--auto-jobs', action='store_const', dest='jobs', const=multiprocessing.cpu_count(), help='Set the -j values to the CPU (thread) count') cmd_parser.add_argument('files', nargs='*', help='input test files') args = cmd_parser.parse_args() @@ -559,7 +598,7 @@ the last matching regex is used: # run-tests script itself. base_path = os.path.dirname(sys.argv[0]) or "." try: - res = run_tests(pyb, tests, args, base_path) + res = run_tests(pyb, tests, args, base_path, args.jobs) finally: if pyb: pyb.close() diff --git a/tests/skip_if.py b/tests/skip_if.py new file mode 100644 index 00000000000..7d6c5b20753 --- /dev/null +++ b/tests/skip_if.py @@ -0,0 +1,101 @@ +# The MIT License (MIT) +# +# Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +# +# 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. + +# This must be on one line so its skipped when built into tests. +"""This file provides helpers to detect particular running conditions and skip the test when appropriate.""" + +def skip(): + print("SKIP") + raise SystemExit + +def always(): + skip() + +def no_reversed(): + import builtins + if "reversed" not in dir(builtins): + skip() + +def no_bigint(): + try: + # We have to use variables because 1 << 40 causes an exception on parse and + # cannot be caught. + x = 40 + x = 1 << x + except OverflowError: + skip() + +def board_in(*board): + try: + import test_env + except ImportError: + class Env: + def __init__(self, board): + self.board = board + test_env = Env("unknown") + if test_env.board in board: + skip() + +def board_not_in(*board): + try: + import test_env + except ImportError: + class Env: + def __init__(self, board): + self.board = board + test_env = Env("unknown") + if test_env.board not in board: + skip() + +def no_cpython_compat(): + try: + from collections import namedtuple + except ImportError: + skip() + try: + T3 = namedtuple("TupComma", "foo bar") + except TypeError: + skip() + +def no_slice_assign(): + try: + memoryview + except: + skip() + b1 = bytearray(b'1234') + b2 = bytearray(b'5678') + m1 = memoryview(b1) + m2 = memoryview(b2) + try: + m2[1:3] = m1[0:2] + except TypeError: + skip() + + +def no_reverse_ops(): + class Foo: + def __radd__(self, other): + pass + try: + 5 + Foo() + except TypeError: + skip() diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp index 9df85275774..06b5d379035 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -27,11 +27,11 @@ RuntimeError: # repl ame__ -__class__ __name__ argv byteorder -exc_info exit getsizeof implementation -maxsize modules path platform -print_exception stderr stdin -stdout version version_info +argv byteorder exc_info exit +getsizeof implementation maxsize modules +path platform print_exception +stderr stdin stdout version +version_info ementation # attrtuple (start=1, stop=2, step=3) diff --git a/tools/Tecate-bitmap-fonts b/tools/Tecate-bitmap-fonts new file mode 160000 index 00000000000..6f52a7ca083 --- /dev/null +++ b/tools/Tecate-bitmap-fonts @@ -0,0 +1 @@ +Subproject commit 6f52a7ca0838967cc57e9a44d76c6e1f60e62842 diff --git a/tools/adabot b/tools/adabot new file mode 160000 index 00000000000..393c2756714 --- /dev/null +++ b/tools/adabot @@ -0,0 +1 @@ +Subproject commit 393c2756714b5cccf028a82c23b873d36b2d9e8b diff --git a/tools/analyze_heap_dump.py b/tools/analyze_heap_dump.py new file mode 100755 index 00000000000..b8f2bd0112e --- /dev/null +++ b/tools/analyze_heap_dump.py @@ -0,0 +1,649 @@ +# This script renders a graph of the MicroPython heap at the given point it was dumped. +# It takes three files, the binary dump of ram, the binary for CircuitPython and the linker map file. + +# To dump ram do this in GDB: dump binary memory ram.bin &_srelocate &_estack + +import binascii +import struct +import sys +import pygraphviz as pgv +import io +import html +import os.path +import string + +import click + +from analyze_mpy import Prelude + +BITS_PER_BYTE = 8 +BLOCKS_PER_ATB = 4 +BLOCKS_PER_FTB = 8 +BYTES_PER_BLOCK = 16 + +AT_FREE = 0 +AT_HEAD = 1 +AT_TAIL = 2 +AT_MARK = 3 + +MICROPY_QSTR_BYTES_IN_HASH = 1 +MICROPY_QSTR_BYTES_IN_LEN = 1 + +MP_OBJ_NULL = 0 +MP_OBJ_SENTINEL = 4 + +READLINE_HIST_SIZE = 8 + +SKIP_SYMBOLS = [".debug_ranges", ".debug_frame", ".debug_loc", ".comment", ".debug_str", ".debug_line", ".debug_abbrev", ".debug_info", "COMMON"] + +@click.command() +@click.argument("ram_filename") +@click.argument("bin_filename") +@click.argument("map_filename") +@click.option("--print_block_contents", default=False, + help="Prints the contents of each allocated block") +@click.option("--print_unknown_types", default=False, + help="Prints the micropython base type if we don't understand it.") +@click.option("--print_block_state", default=False, + help="Prints the heap block states (allocated or free)") +@click.option("--print_conflicting_symbols", default=False, + help="Prints conflicting symbols from the map") +@click.option("--print-heap-structure/--no-print-heap-structure", default=False, + help="Print heap structure") +@click.option("--output_directory", default="heapvis", + help="Destination for rendered output") +@click.option("--draw-heap-layout/--no-draw-heap-layout", default=True, + help="Draw the heap layout") +@click.option("--draw-heap-ownership/--no-draw-heap-ownership", default=False, + help="Draw the ownership graph of blocks on the heap") +@click.option("--analyze-snapshots", default="last", type=click.Choice(['all', 'last'])) +def do_all_the_things(ram_filename, bin_filename, map_filename, print_block_contents, + print_unknown_types, print_block_state, print_conflicting_symbols, + print_heap_structure, output_directory, draw_heap_layout, + draw_heap_ownership, analyze_snapshots): + with open(ram_filename, "rb") as f: + ram_dump = f.read() + + with open(bin_filename, "rb") as f: + rom = f.read() + + symbols = {} # name -> address, size + symbol_lookup = {} # address -> name + manual_symbol_map = {} # autoname -> name + + def add_symbol(name, address=None, size=None): + if "lto_priv" in name: + name = name.split(".")[0] + if address: + address = int(address, 0) + if size: + size = int(size, 0) + if name in symbols: + if address and symbols[name][0] and symbols[name][0] != address: + if print_conflicting_symbols: + print("Conflicting symbol: {} at addresses 0x{:08x} and 0x{:08x}".format(name, address, symbols[name][0])) + return + if not address: + address = symbols[name][0] + if not size: + size = symbols[name][1] + symbols[name] = (address, size) + if address: + if not size: + size = 4 + for offset in range(0, size, 4): + symbol_lookup[address + offset] = "{}+{}".format(name, offset) + + with open(map_filename, "r") as f: + common_symbols = False + name = None + for line in f: + line = line.strip() + parts = line.split() + if line.startswith("Common symbol"): + common_symbols = True + if line == "Discarded input sections": + common_symbols = False + if common_symbols: + if len(parts) == 1: + name = parts[0] + elif len(parts) == 2 and name: + add_symbol(name, size=parts[0]) + name = None + elif len(parts) == 3: + add_symbol(parts[0], size=parts[1]) + name = None + else: + if len(parts) == 1 and parts[0].startswith((".text", ".rodata", ".bss")) and parts[0].count(".") > 1 and not parts[0].isnumeric() and ".str" not in parts[0]: + name = parts[0].split(".")[2] + if len(parts) == 3 and parts[0].startswith("0x") and parts[1].startswith("0x") and name: + add_symbol(name, parts[0], parts[1]) + name = None + if len(parts) == 2 and parts[0].startswith("0x") and not parts[1].startswith("0x"): + add_symbol(parts[1], parts[0]) + if len(parts) == 4 and parts[0] not in SKIP_SYMBOLS and parts[1].startswith("0x") and parts[2].startswith("0x"): + name, address, size, source = parts + if name.startswith((".text", ".rodata", ".bss")) and name.count(".") > 1: + name = name.split(".")[-1] + add_symbol(name, address, size) + name = None + # Linker symbols + if len(parts) >= 4 and parts[0].startswith("0x") and parts[2] == "=" and parts[1] != ".": + add_symbol(parts[1], parts[0]) + + rom_start = symbols["_sfixed"][0] + ram_start = symbols["_srelocate"][0] + ram_end = symbols["_estack"][0] + ram_length = ram_end - ram_start + # print(ram_length, "ram length") + # print(len(ram_dump) // ram_length, "snapshots") + if analyze_snapshots == "all": + snapshots = range(len(ram_dump) // ram_length - 1, -1, -1) + #snapshots = range(4576, -1, -1) + elif analyze_snapshots == "last": + snapshots = range(len(ram_dump) // ram_length - 1, len(ram_dump) // ram_length - 2, -1) + for snapshot_num in snapshots: + ram = ram_dump[ram_length*snapshot_num:ram_length*(snapshot_num + 1)] + + ownership_graph = pgv.AGraph(directed=True) + def load(address, size=4): + if size is None: + raise ValueError("You must provide a size") + if address > ram_start: + ram_address = address - ram_start + if (ram_address + size) > len(ram): + raise ValueError("Unable to read 0x{:08x} from ram.".format(address)) + return ram[ram_address:ram_address+size] + elif address < len(rom): + if (address + size) > len(rom): + raise ValueError("Unable to read 0x{:08x} from rom.".format(address)) + return rom[address:address+size] + + def load_pointer(address): + return struct.unpack(" ram_start: + qstr_pools.append(prev_pool) + prev_pool = load_pointer(prev_pool) + + def save_allocated_block(end, current_allocation): + allocation_length = current_allocation * BYTES_PER_BLOCK + start = end - allocation_length + address = pool_start + start + data = pool[start:end] + if print_block_state: + print("0x{:x} {} bytes allocated".format(address, allocation_length)) + if print_block_contents: + print(data) + + rows = "" + for k in range(current_allocation - 1): + rows += "" + for l in range(4): + rows += "".format(4 * (k + 1) + l) + rows += "" + table = "<{}
0x{:08x}
>".format(address, rows) + + ownership_graph.add_node(address, label=table, style="invisible", shape="plaintext") + print("add 0x{:08x}".format(address)) + potential_type = None + node = ownership_graph.get_node(address) + node.attr["height"] = 0.25 * current_allocation + if address >= long_lived_start: + node.attr["fontcolor"] = "hotpink" + else: + node.attr["fontcolor"] = "black" + block_data[address] = data + for k in range(len(data) // 4): + word = struct.unpack_from("" + + if potential_type == str_type and k == 3: + string_blocks.append(word) + + + if potential_type == dict_type: + if k == 3: + map_element_blocks.append(word) + + if ram_start < word < (ram_start + len(ram)) and word % 16 == 0: + port = k + if k < 4: + port = 0 + ownership_graph.add_edge(address, word, tailport=str(port)+":_") + print(" 0x{:08x}".format(word)) + if address in qstr_pools: + if k > 0: + qstr_chunks.append(word) + if k == 0: + potential_type = dynamic_type + + + if potential_type == dynamic_type: + if k == 0: + node.attr["fillcolor"] = "plum" + if k == 3 and ram_start < word < ram_end: + map_element_blocks.append(word) + + if potential_type in function_types: + if k == 2 and ram_start < word < ram_end: + bytecode_blocks.append(word) + + + longest_free = 0 + current_free = 0 + current_allocation = 0 + total_free = 0 + for i in range(atb_length): + # Each atb byte is four blocks worth of info + atb = heap[i] + for j in range(4): + block_state = (atb >> (j * 2)) & 0x3 + if block_state != AT_FREE and current_free > 0: + if print_block_state: + print("{} bytes free".format(current_free * BYTES_PER_BLOCK)) + current_free = 0 + if block_state != AT_TAIL and current_allocation > 0: + save_allocated_block((i * BLOCKS_PER_ATB + j) * BYTES_PER_BLOCK, current_allocation) + current_allocation = 0 + if block_state == AT_FREE: + current_free += 1 + total_free += 1 + elif block_state == AT_HEAD or block_state == AT_MARK: + current_allocation = 1 + elif block_state == AT_TAIL and current_allocation > 0: + # In gc_free the logging happens before the tail is freed. So checking + # current_allocation > 0 ensures we only extend an allocation thats started. + current_allocation += 1 + longest_free = max(longest_free, current_free) + #if current_free > 0: + # print("{} bytes free".format(current_free * BYTES_PER_BLOCK)) + if current_allocation > 0: + save_allocated_block(pool_length, current_allocation) + + def is_qstr(obj): + return obj & 0xff800007 == 0x00000006 + + def find_qstr(qstr_index): + pool_ptr = last_pool + if not is_qstr(qstr_index): + return "object" + + pool = block_data[pool_ptr] + prev, total_prev_len, alloc, length = struct.unpack_from(">= 3 + if qstr_index > total_prev_len + alloc: + return "invalid" + while pool_ptr != 0: + if pool_ptr > ram_start: + if pool_ptr in block_data: + pool = block_data[pool_ptr] + prev, total_prev_len, alloc, length = struct.unpack_from("= total_prev_len: + offset = (qstr_index - total_prev_len) * 4 + 16 + start = struct.unpack_from(" len(rom): + return "more than rom: {:x}".format(start + rom_start) + qstr_hash, qstr_len = struct.unpack(" heap_start + len(heap): + return "out of range: {:x}".format(start) + local = start - heap_start + qstr_hash, qstr_len = struct.unpack("> 1 + if is_qstr(obj): + return find_qstr(obj) + else: + return "0x{:08x}".format(obj) + + for block in sorted(map_element_blocks): + if block == 0: + continue + try: + node = ownership_graph.get_node(block) + except KeyError: + print("Unable to find memory block for 0x{:08x}. Is there something running?".format(block)) + continue + if block not in block_data: + continue + data = block_data[block] + cells = [] + for i in range(len(data) // 8): + key, value = struct.unpack_from("{}{}".format( + cells[2*i][0], + cells[2*i][1], + cells[2*i+1][0], + cells[2*i+1][1]) + node.attr["shape"] = "plaintext" + node.attr["style"] = "invisible" + node.attr["label"] = "<{}
0x{:08x}
>".format(block, rows) + + for node, degree in ownership_graph.in_degree_iter(): + print(node, degree) + if degree == 0: + address_bytes = struct.pack(" heap_start + heap_size: + source = "stack " + source + ownership_graph.add_edge(source, node) + + for block in string_blocks: + if block == 0: + continue + node = ownership_graph.get_node(block) + node.attr["fillcolor"] = "hotpink" + if block in block_data: + raw_string = block_data[block] + else: + print("Unable to find memory block for string at 0x{:08x}.".format(block)) + continue + try: + raw_string = block_data[block].decode('utf-8') + except: + raw_string = str(block_data[block]) + wrapped = [] + for i in range(0, len(raw_string), 16): + wrapped.append(raw_string[i:i+16]) + node.attr["label"] = "\n".join(wrapped) + node.attr["style"] = "filled" + node.attr["fontname"] = "FiraCode-Medium" + node.attr["fontpath"] = "/Users/tannewt/Library/Fonts/" + node.attr["fontsize"] = 8 + node.attr["height"] = len(wrapped) * 0.25 + + for block in bytecode_blocks: + node = ownership_graph.get_node(block) + node.attr["fillcolor"] = "lightseagreen" + if block in block_data: + data = block_data[block] + else: + print("Unable to find memory block for bytecode at 0x{:08x}.".format(block)) + continue + prelude = Prelude(io.BufferedReader(io.BytesIO(data))) + node.attr["shape"] = "plaintext" + node.attr["style"] = "invisible" + code_info_size = prelude.code_info_size + rows = "" + remaining_bytecode = len(data) - 16 + while code_info_size >= 16: + rows += "" + code_info_size -= 16 + remaining_bytecode -= 16 + if code_info_size > 0: + rows += ("" + "" + ).format(code_info_size, code_info_size * (80 / 16), (16 - code_info_size), (80 / 16) * (16 - code_info_size)) + remaining_bytecode -= 16 + for i in range(remaining_bytecode // 16): + rows += "" + node.attr["label"] = "<{}
0x{:08x}
>".format(block, rows) + + for block in qstr_chunks: + if block not in block_data: + ownership_graph.delete_node(block) + continue + data = block_data[block] + qstrs_in_chunk = "" + offset = 0 + while offset < len(data) - 1: + qstr_hash, qstr_len = struct.unpack_from("0x{:08x}{}>".format(block, 18 * (len(wrapped) - 1), "
".join(wrapped)) + node.attr["fontname"] = "FiraCode-Bold" + if block >= long_lived_start: + node.attr["fontcolor"] = "hotpink" + else: + node.attr["fontcolor"] = "black" + node.attr["fontpath"] = "/Users/tannewt/Library/Fonts/" + node.attr["fontsize"] = 8 + + print("Total free space:", BYTES_PER_BLOCK * total_free) + print("Longest free space:", BYTES_PER_BLOCK * longest_free) + + # First render the graph of objects on the heap. + if draw_heap_ownership: + ownership_graph.layout(prog="dot") + fn = os.path.join(output_directory, "heap_ownership{:04d}.svg".format(snapshot_num)) + print(fn) + ownership_graph.draw(fn) + + # Clear edge positioning from ownership graph layout. + if draw_heap_ownership: + for edge in ownership_graph.iteredges(): + del edge.attr["pos"] + else: + for edge in ownership_graph.edges(): + ownership_graph.delete_edge(edge) + + # Second, render the heap layout in memory order. + for node in ownership_graph.nodes(): + try: + address = int(node.name) + except ValueError: + ownership_graph.remove_node(node.name) + continue + block = (address - pool_start) // 16 + x = block // 128 + y = 128 - block % 128 + try: + height = float(node.attr["height"]) + except: + height = 0.25 + #print(hex(address), "height", height, y) + #if address in block_data: + # print(hex(address), block, len(block_data[address]), x, y, height) + node.attr["pos"] = "{},{}".format(x * 80, (y - (height - 0.25) * 2) * 18) # in inches + + # Reformat block nodes so they are the correct size and do not have keys in them. + for block in sorted(map_element_blocks): + try: + node = ownership_graph.get_node(block) + except KeyError: + if block != 0: + print("Unable to find memory block for 0x{:08x}. Is there something running?".format(block)) + continue + #node.attr["fillcolor"] = "gold" + if block not in block_data: + continue + data = block_data[block] + #print("0x{:08x}".format(block)) + cells = [] + for i in range(len(data) // 8): + key, value = struct.unpack_from("") + cells.append(("", " ")) + else: + #print(" {}, {}".format(format(key), format(value))) + cells.append((key, "")) + # if value in block_data: + # edge = ownership_graph.get_edge(block, value) + # edge.attr["tailport"] = str(key) + rows = "" + for i in range(len(cells) // 2): + rows += "{}{}".format( + cells[2*i][0], + cells[2*i][1], + cells[2*i+1][0], + cells[2*i+1][1]) + node.attr["label"] = "<{}
>".format(rows) + + + ownership_graph.add_node("center", pos="{},{}".format(total_width // 2 - 40, total_height // 2), shape="plaintext", label=" ") + ownership_graph.graph_attr["viewport"] = "{},{},1,{}".format(total_width, total_height, "center") + + ownership_graph.has_layout = True + + if draw_heap_layout: + fn = os.path.join(output_directory, "heap_layout{:04d}.png".format(snapshot_num)) + print(fn) + #ownership_graph.write(fn+".dot") + ownership_graph.draw(fn) + +if __name__ == "__main__": + do_all_the_things() diff --git a/tools/analyze_mpy.py b/tools/analyze_mpy.py new file mode 100644 index 00000000000..376207a24e0 --- /dev/null +++ b/tools/analyze_mpy.py @@ -0,0 +1,418 @@ +import sys +import binascii +import io + +bytecode_format_sizes = { + "MP_OPCODE_BYTE": 1, + "MP_OPCODE_QSTR": 3, + "MP_OPCODE_VAR_UINT": None, # Unknown because uint encoding uses the top bit to indicate the end. + "MP_OPCODE_OFFSET": 3, + "MP_OPCODE_BYTE_EXTRA": 2, + "MP_OPCODE_VAR_UINT_EXTRA": None, + "MP_OPCODE_OFFSET_EXTRA": 4 +} + +bytecodes = { + 0x00: {"name": "MP_BC_LOAD_FAST_MULTI", + "format": "MP_OPCODE_BYTE"}, + 0x10: {"name": "MP_BC_LOAD_CONST_FALSE", + "format": "MP_OPCODE_BYTE"}, + 0x11: {"name": "MP_BC_LOAD_CONST_NONE", + "format": "MP_OPCODE_BYTE"}, + 0x12: {"name": "MP_BC_LOAD_CONST_TRUE", + "format": "MP_OPCODE_BYTE"}, + 0x14: {"name": "MP_BC_LOAD_CONST_SMALL_INT", + "format": "MP_OPCODE_VAR_UINT"}, + 0x16: {"name": "MP_BC_LOAD_CONST_STRING", + "format": "MP_OPCODE_QSTR"}, + 0x17: {"name": "MP_BC_LOAD_CONST_OBJ", + "format": "MP_OPCODE_VAR_UINT"}, +#define MP_BC_LOAD_CONST_OBJ (0x17) // ptr + 0x18: {"name": "MP_BC_LOAD_NULL", + "format": "MP_OPCODE_BYTE"}, + +#define MP_BC_LOAD_FAST_N (0x19) // uint + 0x1a: {"name": "MP_BC_LOAD_DEREF", + "format": "MP_OPCODE_VAR_UINT"}, + 0x1b: {"name": "MP_BC_LOAD_NAME", + "format": "MP_OPCODE_QSTR"}, + 0x1c: {"name": "MP_BC_LOAD_GLOBAL", + "format": "MP_OPCODE_QSTR"}, + 0x1d: {"name": "MP_BC_LOAD_ATTR", + "format": "MP_OPCODE_QSTR"}, + 0x1e: {"name": "MP_BC_LOAD_METHOD", + "format": "MP_OPCODE_QSTR"}, + 0x1f: {"name": "MP_BC_LOAD_SUPER_METHOD", + "format": "MP_OPCODE_QSTR"}, + 0x20: {"name": "MP_BC_LOAD_BUILD_CLASS", + "format": "MP_OPCODE_BYTE"}, +#define MP_BC_LOAD_BUILD_CLASS (0x20) +#define MP_BC_LOAD_SUBSCR (0x21) + 0x21: {"name": "MP_BC_LOAD_SUBSCR", + "format": "MP_OPCODE_BYTE"}, + +#define MP_BC_STORE_FAST_N (0x22) // uint +#define MP_BC_STORE_DEREF (0x23) // uint +#define MP_BC_STORE_NAME (0x24) // qstr + 0x24: {"name": "MP_BC_STORE_NAME", + "format": "MP_OPCODE_QSTR"}, + 0x25: {"name": "MP_BC_STORE_GLOBAL", + "format": "MP_OPCODE_QSTR"}, + 0x26: {"name": "MP_BC_STORE_ATTR", + "format": "MP_OPCODE_QSTR"}, + 0x27: {"name": "MP_BC_LOAD_SUBSCR", + "format": "MP_OPCODE_BYTE"}, + + 0x28: {"name": "MP_BC_DELETE_FAST", + "format": "MP_OPCODE_VAR_UINT"}, +#define MP_BC_DELETE_FAST (0x28) // uint +#define MP_BC_DELETE_DEREF (0x29) // uint +#define MP_BC_DELETE_NAME (0x2a) // qstr +#define MP_BC_DELETE_GLOBAL (0x2b) // qstr + + 0x30: {"name": "MP_BC_DUP_TOP", + "format": "MP_OPCODE_BYTE"}, +#define MP_BC_DUP_TOP_TWO (0x31) + 0x32: {"name": "MP_BC_POP_TOP", + "format": "MP_OPCODE_BYTE"}, + 0x33: {"name": "MP_BC_ROT_TWO", + "format": "MP_OPCODE_BYTE"}, + 0x34: {"name": "MP_BC_ROT_THREE", + "format": "MP_OPCODE_BYTE"}, + + 0x35: {"name": "MP_BC_JUMP", + "format": "MP_OPCODE_OFFSET"}, + 0x36: {"name": "MP_BC_POP_JUMP_IF_TRUE", + "format": "MP_OPCODE_OFFSET"}, + 0x37: {"name": "MP_BC_POP_JUMP_IF_FALSE", + "format": "MP_OPCODE_OFFSET"}, +#define MP_BC_JUMP_IF_TRUE_OR_POP (0x38) // rel byte code offset, 16-bit signed, in excess +#define MP_BC_JUMP_IF_FALSE_OR_POP (0x39) // rel byte code offset, 16-bit signed, in excess +#define MP_BC_SETUP_WITH (0x3d) // rel byte code offset, 16-bit unsigned +#define MP_BC_WITH_CLEANUP (0x3e) +#define MP_BC_SETUP_EXCEPT (0x3f) // rel byte code offset, 16-bit unsigned +#define MP_BC_SETUP_FINALLY (0x40) // rel byte code offset, 16-bit unsigned +#define MP_BC_END_FINALLY (0x41) +#define MP_BC_GET_ITER (0x42) +#define MP_BC_FOR_ITER (0x43) // rel byte code offset, 16-bit unsigned + 0x43: {"name": "MP_BC_FOR_ITER", + "format": "MP_OPCODE_OFFSET"}, + + 0x44: {"name": "MP_BC_POP_BLOCK", + "format": "MP_OPCODE_BYTE"}, +#define MP_BC_POP_EXCEPT (0x45) +#define MP_BC_UNWIND_JUMP (0x46) // rel byte code offset, 16-bit signed, in excess; then a byte + 0x47: {"name": "MP_BC_GET_ITER_STACK", + "format": "MP_OPCODE_BYTE"}, + + + 0x50: {"name": "MP_BC_BUILD_TUPLE", + "format": "MP_OPCODE_VAR_UINT"}, + 0x51: {"name": "MP_BC_BUILD_LIST", + "format": "MP_OPCODE_VAR_UINT"}, + 0x53: {"name": "MP_BC_BUILD_MAP", + "format": "MP_OPCODE_VAR_UINT"}, + 0x54: {"name": "MP_BC_STORE_MAP", + "format": "MP_OPCODE_BYTE"}, +#define MP_BC_BUILD_SET (0x56) // uint +#define MP_BC_BUILD_SLICE (0x58) // uint +#define MP_BC_STORE_COMP (0x57) // uint + 0x57: {"name": "MP_BC_STORE_COMP", + "format": "MP_OPCODE_VAR_UINT"}, +#define MP_BC_UNPACK_SEQUENCE (0x59) // uint +#define MP_BC_UNPACK_EX (0x5a) // uint + + 0x5b: {"name": "MP_BC_RETURN_VALUE", + "format": "MP_OPCODE_BYTE"}, + 0x5c: {"name": "MP_BC_RAISE_VARARGS", + "format": "MP_OPCODE_BYTE_EXTRA"}, +#define MP_BC_YIELD_VALUE (0x5d) +#define MP_BC_YIELD_FROM (0x5e) + +#define MP_BC_MAKE_FUNCTION (0x60) // uint + 0x60: {"name": "MP_BC_MAKE_FUNCTION", + "format": "MP_OPCODE_VAR_UINT"}, + 0x61: {"name": "MP_BC_MAKE_FUNCTION_DEFARGS", + "format": "MP_OPCODE_VAR_UINT"}, + 0x62: {"name": "MP_BC_MAKE_CLOSURE", + "format": "MP_OPCODE_VAR_UINT_EXTRA"}, + 0x63: {"name": "MP_BC_MAKE_CLOSURE", + "format": "MP_OPCODE_VAR_UINT_EXTRA"}, + 0x64: {"name": "MP_BC_CALL_FUNCTION", + "format": "MP_OPCODE_VAR_UINT"}, + 0x65: {"name": "MP_BC_CALL_FUNCTION_VAR_KW", + "format": "MP_OPCODE_VAR_UINT"}, + 0x66: {"name": "MP_BC_CALL_METHOD", + "format": "MP_OPCODE_VAR_UINT"}, + 0x67: {"name": "MP_BC_CALL_METHOD_VAR_KW", + "format": "MP_OPCODE_VAR_UINT"}, + + 0x68: {"name": "MP_BC_IMPORT_NAME", + "format": "MP_OPCODE_QSTR"}, + 0x69: {"name": "MP_BC_IMPORT_FROM", + "format": "MP_OPCODE_QSTR"}, +#define MP_BC_IMPORT_FROM (0x69) // qstr +#define MP_BC_IMPORT_STAR (0x6a) + +#define MP_BC_LOAD_CONST_SMALL_INT_MULTI (0x70) // + N(64) + 0x7f: {"name": "MP_BC_LOAD_CONST_SMALL_INT_MULTI -1", + "format": "MP_OPCODE_BYTE"}, + 0x80: {"name": "MP_BC_LOAD_CONST_SMALL_INT_MULTI 0", + "format": "MP_OPCODE_BYTE"}, + 0x81: {"name": "MP_BC_LOAD_CONST_SMALL_INT_MULTI 1", + "format": "MP_OPCODE_BYTE"}, + 0x82: {"name": "MP_BC_LOAD_CONST_SMALL_INT_MULTI 2", + "format": "MP_OPCODE_BYTE"}, + 0x83: {"name": "MP_BC_LOAD_CONST_SMALL_INT_MULTI 3", + "format": "MP_OPCODE_BYTE"}, + 0x84: {"name": "MP_BC_LOAD_CONST_SMALL_INT_MULTI 4", + "format": "MP_OPCODE_BYTE"}, +#define MP_BC_LOAD_FAST_MULTI (0xb0) // + N(16) + 0xb0: {"name": "MP_BC_LOAD_FAST_MULTI 0", + "format": "MP_OPCODE_BYTE"}, + 0xb1: {"name": "MP_BC_LOAD_FAST_MULTI 1", + "format": "MP_OPCODE_BYTE"}, + 0xb2: {"name": "MP_BC_LOAD_FAST_MULTI 2", + "format": "MP_OPCODE_BYTE"}, + 0xb3: {"name": "MP_BC_LOAD_FAST_MULTI 3", + "format": "MP_OPCODE_BYTE"}, + 0xb4: {"name": "MP_BC_LOAD_FAST_MULTI 4", + "format": "MP_OPCODE_BYTE"}, + 0xb5: {"name": "MP_BC_LOAD_FAST_MULTI 5", + "format": "MP_OPCODE_BYTE"}, + 0xb6: {"name": "MP_BC_LOAD_FAST_MULTI 6", + "format": "MP_OPCODE_BYTE"}, + 0xb7: {"name": "MP_BC_LOAD_FAST_MULTI 7", + "format": "MP_OPCODE_BYTE"}, + 0xb8: {"name": "MP_BC_LOAD_FAST_MULTI 8", + "format": "MP_OPCODE_BYTE"}, +#define MP_BC_STORE_FAST_MULTI (0xc0) // + N(16) + 0xc0: {"name": "MP_BC_STORE_FAST_MULTI 0", + "format": "MP_OPCODE_BYTE"}, + 0xc1: {"name": "MP_BC_STORE_FAST_MULTI 1", + "format": "MP_OPCODE_BYTE"}, + 0xc2: {"name": "MP_BC_STORE_FAST_MULTI 2", + "format": "MP_OPCODE_BYTE"}, + 0xc3: {"name": "MP_BC_STORE_FAST_MULTI 3", + "format": "MP_OPCODE_BYTE"}, + 0xc4: {"name": "MP_BC_STORE_FAST_MULTI 4", + "format": "MP_OPCODE_BYTE"}, + 0xc5: {"name": "MP_BC_STORE_FAST_MULTI 5", + "format": "MP_OPCODE_BYTE"}, + 0xc6: {"name": "MP_BC_STORE_FAST_MULTI 6", + "format": "MP_OPCODE_BYTE"}, + 0xc7: {"name": "MP_BC_STORE_FAST_MULTI 7", + "format": "MP_OPCODE_BYTE"}, +#define MP_BC_UNARY_OP_MULTI (0xd0) // + op(> 8 + if not opcode_size: + i += 2 + while (bytecode[i] & 0x80) != 0: + i += 1 + if bc["format"] == "MP_OPCODE_VAR_UINT_EXTRA": + i += 1 + else: + i += opcode_size + +class mpyFile: + def __init__(self, encoded_mpy): + # this matches mp-raw_code_save in py/persistentcode.c + first_byte = encoded_mpy.read(1) + if first_byte != b'M': + raise ValueError("Not a valid first byte. Should be 'M' but is {}".format(first_byte)) + self.version = encoded_mpy.read(1)[0] + self.feature_flags = encoded_mpy.read(1)[0] + self.small_int_bits = encoded_mpy.read(1)[0] + self.raw_code = RawCode(encoded_mpy) + +if __name__ == "__main__": + with open(sys.argv[1], "rb") as f: + mpy = mpyFile(f) + print(mpy.version) + print(mpy.feature_flags) + print(mpy.small_int_bits) diff --git a/tools/bitmap_font b/tools/bitmap_font new file mode 160000 index 00000000000..62dd78abdd0 --- /dev/null +++ b/tools/bitmap_font @@ -0,0 +1 @@ +Subproject commit 62dd78abdd0b823824fe15d1bab0611246145c23 diff --git a/tools/build_board_info.py b/tools/build_board_info.py new file mode 100644 index 00000000000..f2b33649494 --- /dev/null +++ b/tools/build_board_info.py @@ -0,0 +1,283 @@ +#!/usr/bin/env python3 + +import json +import os +import subprocess +import sys +import sh +import base64 +from datetime import date +from sh.contrib import git + +sys.path.append("adabot") +import adabot.github_requests as github + +SUPPORTED_PORTS = ["nrf", "atmel-samd"] + +BIN = ('bin',) +UF2 = ('uf2',) +BIN_UF2 = ('bin', 'uf2') +HEX = ('hex',) + +# Default extensions +extension_by_port = { + "nrf": UF2, + "atmel-samd": UF2, +} + +# Per board overrides +extension_by_board = { + # samd + "arduino_mkr1300": BIN, + "arduino_zero": BIN, + "feather_m0_adalogger": BIN_UF2, + "feather_m0_basic": BIN_UF2, + "feather_m0_rfm69": BIN_UF2, + "feather_m0_rfm9x": BIN_UF2, + + # nRF52840 dev kits that may not have UF2 bootloaders, + "makerdiary_nrf52840_mdk": HEX, + "makerdiary_nrf52840_mdk_usb_dongle": HEX, + "pca10056": BIN_UF2, + "pca10059": BIN_UF2, + "electronut_labs_blip": HEX +} + +aliases_by_board = { + "circuitplayground_express": ["circuitplayground_express_4h", "circuitplayground_express_digikey_pycon2019"], + "gemma_m0": ["gemma_m0_pycon2018"], + "pewpew10": ["pewpew13"] +} + +def get_languages(): + languages = [] + for f in os.scandir("../locale"): + if f.name.endswith(".po"): + languages.append(f.name[:-3]) + return languages + +def get_board_mapping(): + boards = {} + for port in SUPPORTED_PORTS: + board_path = os.path.join("../ports", port, "boards") + for board_path in os.scandir(board_path): + if board_path.is_dir(): + board_files = os.listdir(board_path.path) + board_id = board_path.name + extensions = extension_by_port[port] + extensions = extension_by_board.get(board_path.name, extensions) + aliases = aliases_by_board.get(board_path.name, []) + boards[board_id] = {"port": port, + "extensions": extensions, + "download_count": 0, + "aliases": aliases} + for alias in aliases: + boards[alias] = {"port": port, + "extensions": extensions, + "download_count": 0, + "alias": True, + "aliases": []} + return boards + +def get_version_info(): + version = None + sha = git("rev-parse", "--short", "HEAD").stdout.decode("utf-8") + try: + version = git("describe", "--tags", "--exact-match").stdout.decode("utf-8").strip() + except sh.ErrorReturnCode_128: + # No exact match + pass + + if "GITHUB_SHA" in os.environ: + sha = os.environ["GITHUB_SHA"] + + if not version: + version="{}-{}".format(date.today().strftime("%Y%m%d"), sha[:7]) + + return sha, version + +def get_current_info(): + response = github.get("/repos/adafruit/circuitpython-org/git/refs/heads/master") + if not response.ok: + print(response.text) + raise RuntimeError("cannot get master sha") + commit_sha = response.json()["object"]["sha"] + + response = github.get("/repos/adafruit/circuitpython-org/contents/_data/files.json?ref=" + commit_sha) + if not response.ok: + print(response.text) + raise RuntimeError("cannot get previous files.json") + + response = response.json() + + git_info = commit_sha, response["sha"] + current_list = json.loads(base64.b64decode(response["content"]).decode("utf-8")) + current_info = {} + for info in current_list: + current_info[info["id"]] = info + return git_info, current_info + +def create_pr(changes, updated, git_info): + commit_sha, original_blob_sha = git_info + branch_name = "new_release_" + changes["new_release"] + + # Convert the dictionary to a list of boards. Liquid templates only handle arrays. + updated_list = [] + all_ids = sorted(updated.keys()) + for id in all_ids: + info = updated[id] + info["id"] = id + updated_list.append(info) + + updated = json.dumps(updated_list, sort_keys=True, indent=4).encode("utf-8") + b"\n" + #print(updated.decode("utf-8")) + pr_title = "Automated website update for release {}".format(changes["new_release"]) + boards = "" + if changes["new_boards"]: + boards = "New boards:\n* " + "\n* ".join(changes["new_boards"]) + languages = "" + if changes["new_languages"]: + languages = "New languages:\n* " + "\n* ".join(changes["new_languages"]) + message = "Automated website update for release {} by AdaBot.\n\n{}\n\n{}\n".format( + changes["new_release"], + boards, + languages + ) + + create_branch = { + "ref": "refs/heads/" + branch_name, + "sha": commit_sha + } + response = github.post("/repos/adafruit-adabot/circuitpython-org/git/refs", json=create_branch) + if not response.ok and response.json()["message"] != "Reference already exists": + print("unable to create branch") + print(response.text) + return + + update_file = { + "message": message, + "content": base64.b64encode(updated).decode("utf-8"), + "sha": original_blob_sha, + "branch": branch_name + } + + response = github.put("/repos/adafruit-adabot/circuitpython-org/contents/_data/files.json", json=update_file) + if not response.ok: + print("unable to post new file") + print(response.text) + return + pr_info = { + "title": pr_title, + "head": "adafruit-adabot:" + branch_name, + "base": "master", + "body": message, + "maintainer_can_modify": True + } + response = github.post("/repos/adafruit/circuitpython-org/pulls", json=pr_info) + if not response.ok: + print("unable to create pr") + print(response.text) + return + print(changes) + print(pr_info) + +def update_downloads(boards, release): + response = github.get("/repos/adafruit/circuitpython/releases/tags/{}".format(release)) + if not response.ok: + print(response.text) + raise RuntimeError("cannot get previous release info") + + assets = response.json()["assets"] + for asset in assets: + board_name = asset["name"].split("-")[2] + if board_name not in boards: + continue + boards[board_name]["download_count"] += asset["download_count"] + + +def print_active_user(): + response = github.get("/user") + if response.ok: + print("Logged in as {}".format(response.json()["login"])) + else: + print("Not logged in") + +def generate_download_info(): + boards = {} + errors = [] + + new_tag = os.environ["RELEASE_TAG"] + + changes = { + "new_release": new_tag, + "new_boards": [], + "new_languages": [] + } + + print_active_user() + + sha, this_version = get_version_info() + + git_info, current_info = get_current_info() + + languages = get_languages() + + new_stable = "-" not in new_tag + + previous_releases = set() + previous_languages = set() + + # Delete the release we are replacing + for board in current_info: + info = current_info[board] + for version in info["versions"]: + previous_releases.add(version["version"]) + previous_languages.update(version["files"].keys()) + if version["stable"] == new_stable: + info["versions"].remove(version) + + board_mapping = get_board_mapping() + + for release in previous_releases: + update_downloads(board_mapping, release) + + for port in SUPPORTED_PORTS: + board_path = os.path.join("../ports", port, "boards") + for board_path in os.scandir(board_path): + if board_path.is_dir(): + board_files = os.listdir(board_path.path) + board_id = board_path.name + board_info = board_mapping[board_id] + + for alias in [board_id] + board_info["aliases"]: + alias_info = board_mapping[alias] + if alias not in current_info: + changes["new_boards"].append(alias) + current_info[alias] = {"downloads": 0, + "versions": []} + + new_version = { + "stable": new_stable, + "version": new_tag, + "files": {} + } + for language in languages: + files = [] + new_version["files"][language] = files + for extension in board_info["extensions"]: + files.append("https://github.com/adafruit/circuitpython/releases/download/{tag}/adafruit-circuitpython-{alias}-{language}-{tag}.{extension}".format(tag=new_tag, alias=alias, language=language, extension=extension)) + current_info[alias]["downloads"] = alias_info["download_count"] + current_info[alias]["versions"].append(new_version) + + changes["new_languages"] = set(languages) - previous_languages + + if changes["new_release"]: + create_pr(changes, current_info, git_info) + else: + print("No new release to update") + +if __name__ == "__main__": + if "RELEASE_TAG" in os.environ and os.environ["RELEASE_TAG"]: + generate_download_info() + else: + print("skipping website update because this isn't a tag") diff --git a/tools/build_memory_info.py b/tools/build_memory_info.py new file mode 100644 index 00000000000..a8f84bbb6aa --- /dev/null +++ b/tools/build_memory_info.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +# +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +# +# 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. + +import re +import sys + +# Handle size constants with K or M suffixes (allowed in .ld but not in Python). +K_PATTERN = re.compile(r'([0-9]+)K') +K_REPLACE = r'(\1*1024)' + +M_PATTERN = re.compile(r'([0-9]+)M') +M_REPLACE = r'(\1*1024*1024)' + +print() + +text = 0 +data = 0 +bss = 0 +# stdin is the linker output. +for line in sys.stdin: + line = line.strip() + if not line.startswith("text"): + text, data, bss = map(int, line.split()[:3]) + +regions = {} +# This file is the linker script. +with open(sys.argv[1], "r") as f: + for line in f: + line = line.strip() + if line.startswith(("FLASH", "RAM")): + regions[line.split()[0]] = line.split("=")[-1] + +for region in regions: + space = regions[region] + if "/*" in space: + space = space.split("/*")[0] + space = K_PATTERN.sub(K_REPLACE, space) + space = M_PATTERN.sub(M_REPLACE, space) + regions[region] = eval(space) + +free_flash = regions["FLASH"] - text - data +free_ram = regions["RAM"] - data - bss +print(free_flash, "bytes free in flash out of", regions["FLASH"], "bytes (", regions["FLASH"] / 1024, "kb ).") +print(free_ram, "bytes free in ram for stack out of", regions["RAM"], "bytes (", regions["RAM"] / 1024, "kb ).") +print() + +# Check that we have free flash space. GCC doesn't fail when the text + data +# sections don't fit in FLASH. It only counts data in RAM. +if free_flash < 0: + print("Too little flash!!!") + print() + sys.exit(-1) diff --git a/tools/build_release_files.py b/tools/build_release_files.py new file mode 100755 index 00000000000..09133e51fa3 --- /dev/null +++ b/tools/build_release_files.py @@ -0,0 +1,89 @@ +#! /usr/bin/env python3 + +import os +import sys +import subprocess +import shutil +import build_board_info as build_info +import time + +for port in build_info.SUPPORTED_PORTS: + result = subprocess.run("rm -rf ../ports/{port}/build*".format(port=port), shell=True) + +PARALLEL = "-j 5" +if "GITHUB_ACTION" in os.environ: + PARALLEL="-j 2" + +all_boards = build_info.get_board_mapping() +build_boards = list(all_boards.keys()) +if "BOARDS" in os.environ: + build_boards = os.environ["BOARDS"].split() + +sha, version = build_info.get_version_info() + +languages = build_info.get_languages() +exit_status = 0 +for board in build_boards: + bin_directory = "../bin/{}/".format(board) + os.makedirs(bin_directory, exist_ok=True) + board_info = all_boards[board] + + for language in languages: + bin_directory = "../bin/{board}/{language}".format(board=board, language=language) + os.makedirs(bin_directory, exist_ok=True) + start_time = time.monotonic() + + # Normally different language builds are all done based on the same set of compiled sources. + # But sometimes a particular language needs to be built from scratch, if, for instance, + # CFLAGS_INLINE_LIMIT is set for a particular language to make it fit. + clean_build_check_result = subprocess.run( + "make -C ../ports/{port} TRANSLATION={language} BOARD={board} check-release-needs-clean-build | fgrep 'RELEASE_NEEDS_CLEAN_BUILD = 1'".format( + port = board_info["port"], language=language, board=board), + shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + clean_build = clean_build_check_result.returncode == 0 + + build_dir = "build-{board}".format(board=board) + if clean_build: + build_dir += "-{language}".format(language=language) + + make_result = subprocess.run( + "make -C ../ports/{port} TRANSLATION={language} BOARD={board} BUILD={build}".format( + port = board_info["port"], language=language, board=board, build=build_dir), + shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + + build_duration = time.monotonic() - start_time + success = "\033[32msucceeded\033[0m" + if make_result.returncode != 0: + exit_status = make_result.returncode + success = "\033[31mfailed\033[0m" + + other_output = "" + + for extension in board_info["extensions"]: + temp_filename = "../ports/{port}/{build}/firmware.{extension}".format( + port=board_info["port"], build=build_dir, extension=extension) + for alias in board_info["aliases"] + [board]: + bin_directory = "../bin/{alias}/{language}".format( + alias=alias, language=language) + os.makedirs(bin_directory, exist_ok=True) + final_filename = "adafruit-circuitpython-{alias}-{language}-{version}.{extension}".format( + alias=alias, language=language, version=version, extension=extension) + final_filename = os.path.join(bin_directory, final_filename) + try: + shutil.copyfile(temp_filename, final_filename) + except FileNotFoundError: + other_output = "Cannot find file {}".format(temp_filename) + if exit_status == 0: + exit_status = 1 + + print("Build {board} for {language}{clean_build} took {build_duration:.2f}s and {success}".format( + board=board, language=language, clean_build=(" (clean_build)" if clean_build else ""), + build_duration=build_duration, success=success)) + + print(make_result.stdout.decode("utf-8")) + print(other_output) + + # Flush so we will see something before 10 minutes has passed. + print(flush=True) + +sys.exit(exit_status) diff --git a/tools/chart_code_size.py b/tools/chart_code_size.py new file mode 100644 index 00000000000..0b55787fa4a --- /dev/null +++ b/tools/chart_code_size.py @@ -0,0 +1,454 @@ +# This script renders a graph of the CircuitPython rom image. +# It takes the single elf file and uses objdump to get its contents. + +import pygraphviz as pgv +import click +import sh + +# Replace dashes with underscores +objdump = sh.arm_none_eabi_objdump + +def parse_hex(h): + return int("0x" + h, 0) + +BAD_JUMPS = ["UNPREDICTABLE", "_etext"] + +SPECIAL_NODE_COLORS = { + "main": "pink", + "exception_table": "green" +} + +@click.command() +@click.argument("elf_filename") +def do_all_the_things(elf_filename): + symbol = None + last_address = 0 + all_symbols = {} + symbols_by_debug_address = {} + symbols_by_memory_address = {} + symbols_by_linkage_name = {} + # Gather type info so we know how to treat the disassembly + debug_dump = objdump("--dwarf=info", elf_filename) + debug_dump_lines = debug_dump.stdout.decode("utf-8").split("\n") + symbol_stack = [] + symbol = None + ignore = False + min_call_site_param = 0x20000000 + for line in debug_dump_lines: + if not line: + continue + parts = line.split() + if line[1] == "<": + if parts[-1] == "0": + symbol = symbol_stack.pop() + continue + debug_type = parts[-1].strip("()") + ignore = False + # skip info about function parameters + if debug_type == "DW_TAG_formal_parameter": + ignore = True + depth = int(parts[0].split(">")[0].strip("<")) + if len(symbol_stack) == (depth - 1) and depth > 0: + symbol_stack.append(symbol) + elif symbol and "name" in symbol: + if symbol["debug_type"] == "DW_TAG_variable": + if "start_address" not in symbol: + pass + else: + symbols_by_memory_address[symbol["start_address"]] = symbol + elif symbol["debug_type"] in ["DW_TAG_member", "DW_TAG_label", "DW_TAG_typedef", "DW_TAG_enumerator", "DW_TAG_enumeration_type", "DW_TAG_base_type", "DW_TAG_structure_type", "DW_TAG_compile_unit", "DW_TAG_union_type"]: + # skip symbols that don't end up in memory. the type info is available through the debug address map + pass + else: + if symbol["name"] in all_symbols: + # print(depth, symbol["name"]) + # print(symbol) + # print(all_symbols[symbol["name"]]) + # print() + pass + all_symbols[symbol["name"]] = symbol + elif symbol and symbol["debug_type"] == "DW_TAG_GNU_call_site_parameter" and "call_site_value" in symbol: + parent = -1 + while symbol_stack[parent]["debug_type"] != "DW_TAG_subprogram": + parent -= 1 + parent = symbol_stack[parent] + + # Only point to ROM + addr = symbol["call_site_value"] + if 0x2000 <= addr < 0x20000000: + if "outgoing_pointers" not in parent: + parent["outgoing_pointers"] = set() + parent["outgoing_pointers"].add(addr) + if addr not in symbols_by_memory_address: + symbols_by_memory_address[addr] = symbol + min_call_site_param = min(addr, min_call_site_param) + symbol["name"] = "name{:x}".format(addr) + address = parse_hex(parts[0].split("<")[-1].strip(">:")) + symbol = {"debug_address": address, "debug_type": debug_type, "other": []} + if debug_type == "DW_TAG_structure_type": + symbol["struct"] = {} + elif debug_type == "DW_TAG_array_type": + symbol["subtype"] = None + symbol["bound_count"] = 0 + symbol["maxlen"] = 0 + elif debug_type == "DW_TAG_subrange_type": + symbol_stack[-1]["subtype"] = symbol + symbols_by_debug_address[address] = symbol + elif ignore: + continue + elif line[:4] == " ": + tag = parts[1].strip(":") + if tag == "DW_AT_name": + symbol["name"] = parts[-1] + elif tag == "DW_AT_type": + symbol["type"] = int(parts[-1].strip("<>"), 0) + if symbol["debug_type"] == "DW_TAG_subrange_type": + if not symbol_stack[-1]["subtype"]: + symbol_stack[-1]["subtype"] = symbol + elif symbol_stack[-1]["subtype"]["type"] == symbol["type"]: + second_subtype = True + else: + raise RuntimeError() + elif tag == "DW_AT_upper_bound": + # Skip arrays with length defined by other variables + if parts[-1][0] != "<": + upper_bound = int(parts[-1]) + if symbol_stack[-1]["bound_count"] > 0: + symbol_stack[-1]["maxlen"] *= upper_bound + 1 + else: + symbol_stack[-1]["maxlen"] = upper_bound + 1 + symbol_stack[-1]["bound_count"] += 1 + elif tag == "DW_AT_byte_size": + symbol["size"] = int(parts[-1]) + elif tag == "DW_AT_inline": + symbol["inlined"] = True + elif tag == "DW_AT_low_pc": + addr = int(parts[-1], 0) + symbols_by_memory_address[addr] = symbol + elif tag == "DW_AT_location": + if parts[-2] == "(DW_OP_addr:": + addr = parse_hex(parts[-1].strip(")")) + if addr > 0: + symbol["start_address"] = addr + elif tag == "DW_AT_linkage_name": + symbol["linkage_name"] = parts[-1] + symbols_by_linkage_name[symbol["linkage_name"]] = symbol + elif tag == "DW_AT_data_member_location": + symbol_stack[-1]["struct"][int(parts[-1])] = symbol + elif tag == "DW_AT_GNU_call_site_value": + if parts[-2] == "(DW_OP_addr:": + symbol["call_site_value"] = parse_hex(parts[-1].strip(")")) + else: + symbol["other"].append(line) + #print(parts) + pass + else: + #print(line) + pass + + MEMORY_NONE = 0 + MEMORY_POINTER = 1 + MEMORY_PY_OBJECT = 2 + + def get_size(t): + if "size" in t: + return t["size"] + return get_size(symbols_by_debug_address[t["type"]]) + + def get_pointer_map(t, depth=0): + if t["debug_type"] == "DW_TAG_pointer_type": + return {0: MEMORY_POINTER} + elif t["debug_type"] in ["DW_TAG_const_type", "DW_TAG_typedef", "DW_TAG_member", "DW_TAG_subrange_type", "DW_TAG_volatile_type"]: + if "name" in t and t["name"] == "mp_rom_obj_t": + return {0: MEMORY_PY_OBJECT} + return get_pointer_map(symbols_by_debug_address[t["type"]], depth+1) + elif t["debug_type"] in ["DW_TAG_base_type", "DW_TAG_enumeration_type"]: + return {} + elif t["debug_type"] == "DW_TAG_union_type": + # skip for now + return {} + elif "struct" in t: + combined_map = {} + for offset in t["struct"]: + member = t["struct"][offset] + submap = get_pointer_map(member) + for suboffset in submap: + combined_map[offset + suboffset] = submap[suboffset] + return combined_map + elif "subtype" in t: + subtype = symbols_by_debug_address[t["type"]] + pmap = get_pointer_map(subtype, depth+1) + size = get_size(subtype) + expanded_map = {} + for i in range(t["maxlen"]): + for offset in pmap: + expanded_map[size * i + offset] = pmap[offset] + return expanded_map + else: + print("no recurse", t) + pass + return {} + + # Do a second pass to dereference the types + for symbol_address in symbols_by_memory_address: + symbol = symbols_by_memory_address[symbol_address] + if "type" in symbol: + if symbol["debug_type"] == "DW_TAG_variable": + symbol["pointer_map"] = get_pointer_map(symbols_by_debug_address[symbol["type"]]) + type_string = [] + t = symbol["type"] + offset = [] + while t != None: + t_symbol = symbols_by_debug_address[t] + t = t_symbol.get("type", None) + if "name" in t_symbol: + type_string.append(t_symbol["name"]) + elif t_symbol["debug_type"] == "DW_TAG_array_type": + type_string.append("[]") + elif t_symbol["debug_type"] == "DW_TAG_pointer_type": + type_string.append("*") + elif t_symbol["debug_type"] == "DW_TAG_const_type": + type_string.append("const") + elif t_symbol["debug_type"] == "DW_TAG_volatile_type": + type_string.append("volatile") + else: + #print(" ", t_symbol) + pass + type_string.reverse() + symbol["type_string"] = " ".join(type_string) + #print(symbol_name, symbol["debug_type"], symbol.get("type_string", "")) + + # print() + # print() + # print(all_symbols["mp_builtin_module_table"]) + # return + + # Gather size and call info + text_dump = objdump("-Dz", "-j", ".text", elf_filename) + text_dump_lines = text_dump.stdout.decode("utf-8").split("\n") + section = None + symbol = None + symbol_type = None + for line in text_dump_lines[4:]: + if line.startswith("Disassembly of section"): + section = line.split()[-1].strip(":") + elif not line: + if symbol and "end_address" not in symbol: + symbol["end_address"] = last_address + symbol["size"] = last_address - symbol["start_address"] + symbol = None + continue + elif line[0].isnumeric(): + symbol_address, symbol_name = line.split() + symbol_address = parse_hex(symbol_address) + symbol_name = symbol_name.strip("<>:") + if symbol_name in symbols_by_linkage_name: + linked_name = symbol_name + symbol = symbols_by_linkage_name[symbol_name] + if "name" in symbol: + non_linkage = symbol["name"] + if not non_linkage.startswith("__builtin"): + symbol_name = non_linkage + all_symbols[symbol_name] = symbol + if "name" not in symbol: + symbol["name"] = symbol_name + elif symbol_address in symbols_by_memory_address: + all_symbols[symbol_name] = symbols_by_memory_address[symbol_address] + if "name" not in all_symbols[symbol_name]: + all_symbols[symbol_name]["name"] = symbol_name + elif symbol_name not in all_symbols: + if symbol_name == "nlr_push_tail_var": + fake_type = all_symbols["mp_obj_get_type"]["type"] + symbol = {"debug_type": "DW_TAG_variable", "name": symbol_name, "type": fake_type} + else: + print(line) + print(symbol_name, symbol_address) + symbol = {"debug_type": "DW_TAG_subprogram", "name": symbol_name} + all_symbols[symbol_name] = symbol + #raise RuntimeError() + + symbol = all_symbols[symbol_name] + symbol["start_address"] = symbol_address + symbols_by_memory_address[symbol_address] = symbol + symbol["section"] = section + + if symbol["debug_type"] == "DW_TAG_subprogram": + symbol["outgoing_jumps"] = set() + symbol["incoming_jumps"] = set() + symbol_type = None + elif symbol["debug_type"] == "DW_TAG_variable": + symbol["outgoing_pointers"] = set() + symbol_type = symbols_by_debug_address[symbol["type"]] + all_symbols[symbol_name] = symbol + + elif line[0] == " ": + parts = line.strip().split() + last_address = parse_hex(parts[0].strip(":")) + + offset = last_address - symbol["start_address"] + if "pointer_map" in symbol: + if offset not in symbol["pointer_map"]: + #print(offset, symbol) + pass + else: + ref = parse_hex(parts[1]) + pointer_style = symbol["pointer_map"][offset] + if pointer_style == MEMORY_POINTER: + symbol["outgoing_pointers"].add(ref & 0xfffffffe) + elif pointer_style == MEMORY_PY_OBJECT and ref & 0x3 == 0: + symbol["outgoing_pointers"].add(ref) + if len(parts[1]) == 8 and parts[1][0] == "0": + addr = parse_hex(parts[1]) + if 0x2000 <= addr < 0x20000000: + if "outgoing_pointers" not in symbol: + symbol["outgoing_pointers"] = set() + symbol["outgoing_pointers"].add(addr) + elif "<" in line and symbol["debug_type"] == "DW_TAG_subprogram": + if line[-1] == ">": + jump_to = parts[-1].strip("<>").split("+")[0] + if "name" not in symbol: + print(jump_to) + print(symbol) + if jump_to != symbol["name"] and jump_to not in BAD_JUMPS: + symbol["outgoing_jumps"].add(jump_to) + #print(symbol_name, jump_to) + if jump_to == "_etext": + print(line) + elif "UNDEFINED" in line: + continue + elif parts[2] == "ldr": + continue + else: + print(line) + else: + #print(line) + pass + + # print() + print(hex(min_call_site_param)) + print(all_symbols["exception_table"]) + # return + + print("converting outgoing pointers to names") + + # Convert outgoing pointers to names from addresses + for symbol_name in all_symbols: + symbol = all_symbols[symbol_name] + if "outgoing_pointers" not in symbol: + continue + converted = set() + for outgoing in symbol["outgoing_pointers"]: + if outgoing in symbols_by_memory_address: + outgoing = symbols_by_memory_address[outgoing] + #print(outgoing) + if outgoing["debug_type"] in ["DW_TAG_GNU_call_site", "DW_TAG_lexical_block"]: + continue + if outgoing["name"] == "audioio_wavefile_type": + print(outgoing) + converted.add(outgoing["name"]) + symbol["outgoing_pointers"] = converted + + print("linking back") + # Link back + for symbol_name in all_symbols: + symbol = all_symbols[symbol_name] + if "outgoing_jumps" in symbol: + for outgoing in symbol["outgoing_jumps"]: + if outgoing not in all_symbols: + #print(outgoing, symbol_name) + continue + #print(all_symbols[outgoing], symbol_name) + + referenced_symbol = all_symbols[outgoing] + if "incoming_jumps" not in referenced_symbol: + #print(symbol_name, "->", outgoing) + referenced_symbol["incoming_jumps"] = set() + referenced_symbol["incoming_jumps"].add(symbol_name) + if "outgoing_pointers" in symbol: + for outgoing in symbol["outgoing_pointers"]: + if outgoing not in all_symbols: + #print(outgoing, symbol_name) + continue + #print(all_symbols[outgoing], symbol_name) + + referenced_symbol = all_symbols[outgoing] + if "incoming_pointers" not in referenced_symbol: + #print(symbol_name, "->", outgoing) + referenced_symbol["incoming_pointers"] = set() + referenced_symbol["incoming_pointers"].add(symbol_name) + + print(all_symbols["exception_table"]) + + # Chart it all + print("charting {} symbols".format(len(all_symbols))) + callgraph = pgv.AGraph(directed=True) + for i, symbol_name in enumerate(all_symbols): + symbol = all_symbols[symbol_name] + # print(i, symbol_name) + # if "outgoing_jumps" in symbol: + # print(" ", len(symbol["outgoing_jumps"]), "jumps") + # if "outgoing_pointers" in symbol: + # print(" ", len(symbol["outgoing_pointers"]), "ptrs") + # if i > 3000: + # break + if ("incoming_jumps" not in symbol or len(symbol["incoming_jumps"]) == 0) and ("incoming_pointers" not in symbol or len(symbol["incoming_pointers"]) == 0): + #print(symbol_name) + continue + if "start_address" not in symbol: + continue + callgraph.add_node(symbol_name) + if "outgoing_jumps" in symbol: + for outgoing in symbol["outgoing_jumps"]: + callgraph.add_edge(symbol_name, outgoing) + if "outgoing_pointers" in symbol: + for outgoing in symbol["outgoing_pointers"]: + callgraph.add_edge(symbol_name, outgoing, color="red") + #print(symbol_name, symbol) + + # Style all of the nodes + print("styling") + for node in callgraph.iternodes(): + if node.name not in all_symbols: + continue + symbol = all_symbols[node.name] + node.attr["shape"] = "box" + text_width_ish = len(node.name) * 0.1 + if "size" not in symbol: + print(symbol) + size = symbol["size"] / 8 + square_size = size ** 0.5 + if text_width_ish > square_size: + w = text_width_ish + h = size / text_width_ish + else: + w = square_size + h = square_size + node.attr["width"] = w + node.attr["height"] = h + node.attr["label"] = node.name + "\r\n" + str(symbol["size"]) + " bytes" + node.attr["style"] = "filled" + + incoming = 0 + if "incoming_jumps" in symbol: + incoming += len(symbol["incoming_jumps"]) + if "incoming_pointers" in symbol: + incoming += len(symbol["incoming_pointers"]) + + if node.name in SPECIAL_NODE_COLORS: + node.attr["color"] = SPECIAL_NODE_COLORS[node.name] + elif incoming == 1: + node.attr["color"] = "lightblue" + elif incoming > 25: + print("delete", node.name, "because it has {} incoming".format(incoming)) + callgraph.delete_node(node.name) + elif incoming > 15: + node.attr["color"] = "red" + + print("drawing") + callgraph.layout(prog="dot") + fn = "callgraph.svg" + print(fn) + callgraph.draw(fn) + +if __name__ == "__main__": + do_all_the_things() diff --git a/tools/check_translations.py b/tools/check_translations.py new file mode 100644 index 00000000000..7c008d3da72 --- /dev/null +++ b/tools/check_translations.py @@ -0,0 +1,25 @@ +# Validate that all entries in the .pot are in every .po. Only the .pot is updated so we can detect +# if a translation was added to the source but isn't in a .po. This ensures translators can grab +# complete files to work on. + +import sys +import polib + + +template_filename = sys.argv[1] +po_filenames = sys.argv[2:] + +template = polib.pofile(template_filename) +all_ids = set([x.msgid for x in template]) +for po_filename in po_filenames: + print("Checking", po_filename) + po_file = polib.pofile(po_filename) + po_ids = set([x.msgid for x in po_file]) + + missing = all_ids - po_ids + if missing: + print("Missing message id. Please run `make translate`") + print(missing) + sys.exit(-1) + else: + print("ok") diff --git a/tools/ci_new_boards_check.py b/tools/ci_new_boards_check.py new file mode 100644 index 00000000000..7ad8af84249 --- /dev/null +++ b/tools/ci_new_boards_check.py @@ -0,0 +1,50 @@ +#! /usr/bin/env python3 + +import sys +import os +import json +import yaml + +import build_board_info + +workflow_file = '.github/workflows/build.yml' + +# Get boards in json format +boards_info_json = build_board_info.get_board_mapping() + +# Get all the boards out of the json format +info_boards = [board for board in boards_info_json.keys() if not boards_info_json[board].get("alias", False)] + +# We need to know the path of the workflow file +base_path = os.path.dirname(__file__) +yml_path = os.path.abspath(os.path.join(base_path, '..', workflow_file)) + +# Loading board list based on build jobs in the workflow file. +ci_boards = [] +with open(yml_path, "r") as f: + workflow = yaml.safe_load(f) + +ok = True +for job in workflow["jobs"]: + if not job.startswith("build"): + continue + job_boards = workflow["jobs"][job]["strategy"]["matrix"]["board"] + if job_boards != sorted(job_boards): + print("Boards for job \"{}\" not sorted. Must be:".format(job)) + print(" - \"" + "\"\n - \"".join(sorted(job_boards)) + "\"") + ok = False + ci_boards.extend(job_boards) + +# All the travis_boards elements must be on info_boards +info_boards.sort() +ci_boards.sort() + +missing_boards = set(info_boards) - set(ci_boards) + +if missing_boards: + print('Boards missing in {}:'.format(workflow_file)) + for board in missing_boards: + print(board) + +if not ok: + sys.exit(1) diff --git a/tools/convert_release_notes.py b/tools/convert_release_notes.py new file mode 100644 index 00000000000..4805f182a79 --- /dev/null +++ b/tools/convert_release_notes.py @@ -0,0 +1,57 @@ +import sys +import mistune + +print(sys.argv[1]) + +with open(sys.argv[1], "r") as source_file: + source = source_file.read() + +html = mistune.Markdown() + +print() +print("HTML") +print("=====================================") +print("From the GitHub release page:\n
") +print(html(source)) +print("
") + +class AdafruitBBCodeRenderer: + def __init__(self, **kwargs): + self.options = kwargs + + def placeholder(self): + return '' + + def paragraph(self, text): + return text + "\n\n" + + def text(self, text): + return text + + def link(self, link, title, text): + return "[url={}]{}[/url]".format(link, text) + + def header(self, text, level, raw): + return "[b][size=150]{}[/size][/b]\n".format(text) + + def codespan(self, text): + return "[color=#E74C3C][size=95]{}[/size][/color]".format(text) + + def list_item(self, text): + return "[*]{}[/*]\n".format(text.strip()) + + def list(self, body, ordered=True): + ordered_indicator = "=" if ordered else "" + return "[list{}]\n{}[/list]".format(ordered_indicator, body) + + def double_emphasis(self, text): + return "[b]{}[/b]".format(text) + +bbcode = mistune.Markdown(renderer=AdafruitBBCodeRenderer()) + +print() +print("BBCode") +print("=====================================") +print("From the [url=]GitHub release page[/url]:\n[quote]") +print(bbcode(source)) +print("[/quote]") diff --git a/tools/cpboard.py b/tools/cpboard.py new file mode 100644 index 00000000000..0b9c43c6140 --- /dev/null +++ b/tools/cpboard.py @@ -0,0 +1,684 @@ +#!/usr/bin/env python3 +# +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +# Copyright (c) 2018 Noralf Trønnes +# +# Parts taken from pyboard.py: +# Copyright (c) 2014-2016 Damien P. George +# Copyright (c) 2017 Paul Sokolovsky +# +# 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. + +import os +import re +import serial +import sys +import time + +import serial.tools.list_ports +import sh +import shutil + +class CPboardError(BaseException): + pass + +# supervisor/messages/default.h: +MSG_NEWLINE = b"\r\n" +MSG_SAFE_MODE_CRASH = b"Looks like our core CircuitPython code crashed hard. Whoops!" +MSG_SAFE_MODE_BROWN_OUT_LINE_1 = b"The microcontroller's power dipped. Please make sure your power supply provides" +MSG_SAFE_MODE_BROWN_OUT_LINE_2 = b"enough power for the whole circuit and press reset (after ejecting CIRCUITPY)." +MSG_WAIT_BEFORE_REPL = b"Press any key to enter the REPL. Use CTRL-D to reload." + +class REPL: + CHAR_CTRL_A = b'\x01' + CHAR_CTRL_B = b'\x02' + CHAR_CTRL_C = b'\x03' + CHAR_CTRL_D = b'\x04' + + def __init__(self, board): + self.board = board + self.write_chunk_size = 32 + self.safe_mode = False + self.session = b'' + + def __enter__(self): + self.reset() + return self + + def __exit__(self, exception_type, exception_value, traceback): + pass + + @property + def serial(self): + return self.board.serial + + def read(self): + if self.serial.inWaiting(): + data = self.serial.read(self.serial.inWaiting()) + else: + data = b'' + self.session += data + return data + + def read_until(self, ending, timeout=10): + data = b'' + timeout_count = 0 + while True: + if data.endswith(ending): + break + elif self.serial.inWaiting() > 0: + new_data = self.serial.read(1) + data += new_data + self.session += new_data + timeout_count = 0 + else: + timeout_count += 1 + if timeout is not None and timeout_count >= 100 * timeout: + raise TimeoutError(110, "timeout waiting for", ending) + time.sleep(0.01) + return data + + def write(self, data, chunk_size=None): + if chunk_size is None: + chunk_size = self.write_chunk_size + if not isinstance(data, bytes): + data = bytes(data, encoding='utf8') + + for i in range(0, len(data), chunk_size): + chunk = data[i:min(i + chunk_size, len(data))] + self.session += chunk + self.serial.write(chunk) + time.sleep(0.01) + + def reset(self): + # Use read() since serial.reset_input_buffer() fails with termios.error now and then + self.read() + self.session = b'' + self.write(b'\r' + REPL.CHAR_CTRL_C + REPL.CHAR_CTRL_C) # interrupt any running program + self.write(b'\r' + REPL.CHAR_CTRL_B) # enter or reset friendly repl + data = self.read_until(b'>>> ') + + def execute(self, code, timeout=10, async=False): + self.read() # Throw away + + self.write(REPL.CHAR_CTRL_A) + self.read_until(b'\r\n>') + + self.write(code) + + self.write(REPL.CHAR_CTRL_D) + if async: + return b'', b'' + self.read_until(b'OK') + + output = self.read_until(b'\x04', timeout=timeout) + output = output[:-1] + + error = self.read_until(b'\x04') + error = error[:-1] + + return output, error + + def run(self): + if self.safe_mode: + raise RuntimeError("Can't run in safe mode") + + self.reset() + + self.write(REPL.CHAR_CTRL_D) + data = self.read_until(b' output:\r\n') + if b'Running in safe mode' in data: + self.safe_mode = True + raise RuntimeError("Can't run in safe mode") + + # TODO: MSG_SAFE_MODE_CRASH + # TODO: BROWNOUT + + marker = MSG_NEWLINE + MSG_WAIT_BEFORE_REPL + MSG_NEWLINE + data = self.read_until(marker) + data = data.split(marker)[0] + + # Haven't found out why we have to strip off this... + if data.endswith(b'\r\n\r\n'): + data = data[:-4] + return data + + +class Disk: + def __init__(self, dev): + self.dev = os.path.realpath(dev) + self.mountpoint = None + with open('/etc/mtab', 'r') as f: + mtab = f.read() + mount = [mount.split(' ') for mount in mtab.splitlines() if mount.startswith(self.dev)] + if mount: + self._path = mount[0][1] + else: + name = os.path.basename(dev) + sh.pmount("-tvfat", dev, name, _timeout=10) + self.mountpoint = "/media/" + name + self._path = self.mountpoint + + def __enter__(self): + return self + + def __exit__(self, exception_type, exception_value, traceback): + try: + self.close() + except: + pass + + @property + def path(self): + return self._path + + def close(self): + if not self.mountpoint: + return + mountpoint = self.mountpoint + self.mountpoint = None + + start_time = time.monotonic() + unmounted = False + while not unmounted and start_time - time.monotonic() < 30: + try: + sh.pumount(mountpoint) + unmounted = True + except sh.ErrorReturnCode_5: + time.sleep(0.1) + + def sync(self): + disk_device = os.path.basename(self.dev)[:-1] + os.sync() + # Monitor the block device so we know when the sync request is actually finished. + with open("/sys/block/" + disk_device + "/stat", "r") as f: + disk_inflight = 1 + last_wait_time = 0 + wait_time = 1 + while disk_inflight > 0 or wait_time > last_wait_time: + f.seek(0) + stats = f.read() + block_stats = stats.split() + disk_inflight = int(block_stats[8]) + last_wait_time = wait_time + wait_time = int(block_stats[9]) + + def copy(self, src, dst=None, sync=True): + if dst is None: + dst = os.path.basename(src) + shutil.copy(src, os.path.join(self.path, dst)) + if sync: + self.sync() + + +class Firmware: + def __init__(self, board): + self.board = board + + @property + def disk(self): + disks = self.board.get_disks() + if len(disks) != 1: + raise RuntimeError("Boot disk not found for: " + self.board.device) + return Disk(disks[0]) + + @property + def info(self): + with self.disk as disk: + fname = os.path.join(disk.path, 'INFO_UF2.TXT') + with open(fname, 'r') as f: + info = f.read() + lines = info.splitlines() + res = {} + res['header'] = lines[0] + for line in lines[1:]: + k, _, v = line.partition(':') + res[k.replace(':', '')] = v.strip() + return res + + def upload(self, fw): + with open(fw, 'rb') as f: + header = f.read(32) + if header[0:4] != b'UF2\n': + raise ValueError('Only UF2 files are supported') + self.board.close() + with self.disk as disk: + disk.copy(fw, sync=False) + + +class CPboard: + @classmethod + def from_try_all(cls, name, **kwargs): + try: + return CPboard.from_build_name(name, **kwargs) + except ValueError: + pass + + vendor, _, product = name.partition(':') + if vendor and product: + return CPboard.from_usb(**kwargs, idVendor=int(vendor, 16), idProduct=int(product, 16)) + + return CPboard(name, **kwargs) + + @classmethod + def from_build_name(cls, name, **kwargs): + boards = { + #'arduino_zero' + 'circuitplayground_express' : (0x239a, 0x8019), + #'feather_m0_adalogger' : (0x239a, ), + #'feather_m0_basic' : (0x239a, ), + 'feather_m0_express' : (0x239a, 0x8023), + #'feather_m0_rfm69' : (0x239a, ), + #'feather_m0_rfm9x' : (0x239a, ), + #'feather_m0_supersized' : (0x239a, ), + #'feather_m4_express' : (0x239a, ), + #'gemma_m0' : (0x239a, ), + #'itsybitsy_m0_express' : (0x239a, ), + #'itsybitsy_m4_express' : (0x239a, ), + 'metro_m0_express' : (0x239a, 0x8014), + 'metro_m4_express' : (0x239a, 0x8021), + #'metro_m4_express_revb' : (0x239a, ), + #'pirkey_m0' : (0x239a, ), + #'trinket_m0' : (0x239a, ), + #'trinket_m0_haxpress' : (0x239a, ), + #'ugame10' + } + + try: + vendor, product = boards[name] + except KeyError: + raise ValueError("Unknown build name: " + name) + + return CPboard.from_usb(**kwargs, idVendor=vendor, idProduct=product) + + @classmethod + def from_build_name_bootloader(cls, name, **kwargs): + boards = { + #'arduino_zero' + #'circuitplayground_express' : (0x239a, ), + #'feather_m0_adalogger' : (0x239a, ), + #'feather_m0_basic' : (0x239a, ), + 'feather_m0_express' : (0x239a, 0x001b), + #'feather_m0_rfm69' : (0x239a, ), + #'feather_m0_rfm9x' : (0x239a, ), + #'feather_m0_supersized' : (0x239a, ), + #'feather_m4_express' : (0x239a, ), + #'gemma_m0' : (0x239a, ), + #'itsybitsy_m0_express' : (0x239a, ), + #'itsybitsy_m4_express' : (0x239a, ), + #'metro_m0_express' : (0x239a, 0x8014), + 'metro_m4_express' : (0x239a, 0x0021), + #'metro_m4_express_revb' : (0x239a, ), + #'pirkey_m0' : (0x239a, ), + #'trinket_m0' : (0x239a, ), + #'trinket_m0_haxpress' : (0x239a, ), + #'ugame10' + } + + try: + vendor, product = boards[name] + except KeyError: + raise ValueError("Unknown build name: " + name) + + board = CPboard.from_usb(**kwargs, idVendor=vendor, idProduct=product) + board.bootloader = True + return board + + @classmethod + def from_usb(cls, baudrate=115200, wait=0, timeout=10, **kwargs): + import usb.core + dev = usb.core.find(**kwargs) + if not dev: + s = "Can't find USB device: " + args = [] + for x in kwargs.items(): + try: + args.append('%s=0x%x' % x) + except: + args.append('%s = %s' % x) + raise RuntimeError("Can't find USB device: " + ', '.join(args)) + return cls(dev, baudrate=baudrate, wait=wait, timeout=timeout) + + def __init__(self, device, baudrate=115200, wait=0, timeout=10): + self.device = device + self.usb_dev = None + try: + # Is it a usb.core.Device? + portstr = ':' + '.'.join(map(str, device.port_numbers)) + ':' + except: + pass + else: + serials = [serial for serial in os.listdir("/dev/serial/by-path") if portstr in serial] + if len(serials) != 1: + raise RuntimeError("Can't find excatly one matching usb serial device") + self.device = os.path.realpath("/dev/serial/by-path/" + serials[0]) + self.usb_dev = device + + self.baudrate = baudrate + self.wait = wait + self.timeout = timeout + self.debug = True + self.mount = None + self.serial = None + self.bootloader = False + self.repl = REPL(self) + + def __enter__(self): + self.open() + return self + + def __exit__(self, exception_type, exception_value, traceback): + self.close() + + def open(self, baudrate=None, wait=None): + if self.serial: + return + if baudrate is None: + baudrate = self.baudrate + if wait is None: + wait = self.wait + + delayed = False + for attempt in range(wait + 1): + try: + self.serial = serial.Serial(self.device, baudrate=self.baudrate, timeout=self.timeout, write_timeout=self.timeout, interCharTimeout=1) + break + except (OSError, IOError): # Py2 and Py3 have different errors + if wait == 0: + continue + if attempt == 0: + sys.stdout.write('Waiting {} seconds for board '.format(wait)) + delayed = True + time.sleep(1) + sys.stdout.write('.') + sys.stdout.flush() + else: + if delayed: + print('') + raise CPboardError('failed to access ' + self.device) + if delayed: + print('') + + def close(self): + if self.serial: + self.serial.close() + self.serial = None + + def exec(self, command, timeout=10, async=False): + with self.repl as repl: + try: + output, error = repl.execute(command, timeout=timeout, async=async) + except OSError as e: + if self.debug: + print('exec: session: ', self.repl.session) + raise CPboardError('timeout', e) + if error: + raise CPboardError('exception', output, error) + return output + + def eval(self, expression, timeout=10): + command = 'print({})'.format(expression) + with self.repl as repl: + output, error = repl.execute(command, timeout=timeout) + if error: + raise CPboardError('exception', output, error) + try: + res = eval(str(output, encoding='utf8')) + except: + raise CPboardError('failed to eval: %s' % output) + return res + + def _reset(self, mode='NORMAL'): + self.exec("import microcontroller;microcontroller.on_next_reset(microcontroller.RunMode.%s)" % mode) + try: + self.exec("import microcontroller;microcontroller.reset()", async=True) + except OSError: + pass + + def reset(self, safe_mode=False, delay=5, wait=10): + self._reset('SAFE_MODE' if safe_mode else 'NORMAL') + self.close() + time.sleep(delay) + self.open(wait) + time.sleep(delay) + + def reset_to_bootloader(self, repl=False): + if repl: + self._reset('BOOTLOADER') + self.close() + else: + self.close() + s = serial.Serial(self.device, 1200, write_timeout=4, timeout=4) + s.close() + + def get_port_info(self): + portinfo = None + for port_iter in serial.tools.list_ports.comports(): + if port_iter.device == self.device: + portinfo = port_iter + break + return portinfo + + @property + def serial_number(self): + try: # Permissions are needed to read the value + return self.usb_dev.serial_number + except: + pass + p = self.get_port_info() + return p.serial_number if p else None + + def get_disks(self): + if self.usb_dev: + portstr = ':' + '.'.join(map(str, self.usb_dev.port_numbers)) + ':' + return ["/dev/disk/by-path/" + disk for disk in os.listdir("/dev/disk/by-path") if portstr in disk] + serial = self.serial_number + if not serial: + raise RuntimeError("Serial number not found for: " + self.device) + return ["/dev/disk/by-id/" + disk for disk in os.listdir("/dev/disk/by-id") if serial in disk] + + @property + def disk(self): + disks = self.get_disks() + + part = [part for part in disks if 'part1' in part] + if not part: + raise RuntimeError("Disk not found for: " + self.device) + + return Disk(part[0]) + + @property + def firmware(self): + return Firmware(self) + + def execfile_disk(self, filename): + with self.disk as disk: + disk.copy(filename, 'code.py') + + with self.repl as repl: + try: + output = repl.run() + except OSError as e: + raise CPboardError('timeout', e) + except RuntimeError: + if self.repl.safe_mode: + raise PyboardError("Can't run in safe mode") + else: + raise + + return output + + def execfile(self, filename, timeout=10): + if os.environ.get('CPBOARD_EXEC_MODE') == 'disk': + return self.execfile_disk(filename) + else: + with open(filename, 'rb') as f: + pyfile = f.read() + return self.exec(pyfile, timeout=timeout) + + +# Implement just enough to make tests/run-tests work +PyboardError = CPboardError + +class Pyboard: + def __init__(self, device, baudrate=115200, user='micro', password='python', wait=0): + self.board = CPboard.from_try_all(device, baudrate=baudrate, wait=wait) + with self.board.disk as disk: + disk.copy('skip_if.py') + + def close(self): + self.board.close() + + def enter_raw_repl(self): + self.board.open() + + def execfile(self, filename): + return self.board.execfile(filename) + + +def eval_namedtuple(board, command): + from collections import namedtuple + s = board.exec("print(%s)" % command) + s = s.decode().strip() + items = [key.split('=') for key in s[1:-1].split(', ')] + keys = [item[0] for item in items] + vals = [item[1] for item in items] + nt = namedtuple('eval', keys) + res = nt(*[eval(val) for val in vals]) + return res + + +def os_uname(board): + return eval_namedtuple(board, "__import__('os').uname()") + +def print_verbose(cargs, *args, **kwargs): + if cargs.verbose: + print(*args, flush=True, **kwargs) + +def upload(args): + try: + board = CPboard.from_build_name_bootloader(args.board) + print_verbose(args, 'Board is already in the bootloader') + except (ValueError, RuntimeError): + board = CPboard.from_try_all(args.board) + + print_verbose(args, "Serial number :", board.serial_number) + + if not (args.quiet or board.bootloader): + board.open() + print('Current version:', os_uname(board).version, flush=True) + + if not board.bootloader: + print_verbose(args, 'Reset to bootloader...', end='') + board.reset_to_bootloader(repl=True) # Feather M0 Express doesn't respond to 1200 baud + time.sleep(5) + print_verbose(args, 'done') + + print_verbose(args, 'Bootloader:', board.firmware.info) + + print_verbose(args, 'Upload firmware...', end='') + board.firmware.upload(args.firmware) + print_verbose(args, 'done') + + print_verbose(args, 'Wait for board...', end='') + time.sleep(5) + print_verbose(args, 'done') + + if not args.quiet: + if board.bootloader: + board = CPboard.from_try_all(args.board) + board.open(wait=10) + print('New version:', os_uname(board).version, flush=True) + +def print_error_exit(args, e): + if args.debug: + return False + if not args.quiet: + print(e, file=sys.stderr) + sys.exit(1) + +def main(): + import argparse + cmd_parser = argparse.ArgumentParser(description='Circuit Python Board Tool') + cmd_parser.add_argument('board', help='build_name, vid:pid or /dev/tty') + cmd_parser.add_argument('-f', '--firmware', help='upload UF2 firmware file') + cmd_parser.add_argument('-c', '--command', help='program passed in as string') + cmd_parser.add_argument('--tty', action='store_true', help='print tty') + cmd_parser.add_argument('--verbose', '-v', action='count', default=0, help='be verbose') + cmd_parser.add_argument('-q', '--quiet', action='store_true', help='be quiet') + cmd_parser.add_argument('--debug', action='store_true', help='raise exceptions') + args = cmd_parser.parse_args() + + if args.quiet: + args.verbose = 0 + args.debug = False + + if args.firmware: + try: + upload(args) + except BaseException as e: + if not print_error_exit(args, e): + raise + sys.exit(0) + + try: + board = CPboard.from_try_all(args.board) + except BaseException as e: + if not print_error_exit(args, e): + raise + + if args.verbose: + exec_mode = os.environ.get('CPBOARD_EXEC_MODE') + if exec_mode: + print('CPBOARD_EXEC_MODE =', exec_mode) + + # Make sure we can open serial + try: + with board: + pass + except BaseException as e: + if not print_error_exit(args, e): + raise + + if args.tty: + print(board.device) + elif args.command: + with board as b: + print(b.eval(args.command)) + else: + with board as b: + print('Device: ', end='') + if b.usb_dev: + print('%04x:%04x on ' % (b.usb_dev.idVendor, b.usb_dev.idProduct), end='') + print(b.device) + print('Serial number:', b.serial_number) + uname = os_uname(b) + print('os.uname:') + print(' sysname:', uname.sysname) + print(' nodename:', uname.nodename) + print(' release:', uname.release) + print(' version:', uname.version) + print(' machine:', uname.machine) + +if __name__ == "__main__": + main() diff --git a/tools/fixup_translations.py b/tools/fixup_translations.py new file mode 100644 index 00000000000..6db7f1cc5c0 --- /dev/null +++ b/tools/fixup_translations.py @@ -0,0 +1,85 @@ +# Validate that all entries in the .pot are in every .po. Only the .pot is updated so we can detect +# if a translation was added to the source but isn't in a .po. This ensures translators can grab +# complete files to work on. + +import git +import sys +import polib + +po_filenames = sys.argv[1:] +repo = git.Repo() + +NO_TRANSLATION_WHITELIST = ["ffi_prep_closure_loc"] + +bad_commits = {} +for po_filename in po_filenames: + print("Checking", po_filename) + + commits = repo.iter_commits(paths=po_filename, reverse=True, topo_order=True) + first_translations = None + fixed_ids = set() + for commit in commits: + try: + blob = commit.tree / po_filename + except KeyError: + continue + try: + current_file = polib.pofile(blob.data_stream.read().decode("utf-8")) + except OSError: + print("skipping invalid po in", commit) + continue + if not first_translations: + first_translations = current_file + continue + print(commit.authored_date, commit) + first_translations.metadata = current_file.metadata + first_translations.header = current_file.header + for entry in first_translations: + newer_entry = current_file.find(entry.msgid) + + if newer_entry and entry.msgid == "": + entry.merge(newer_entry) + print(entry) + elif newer_entry and entry.msgstr != newer_entry.msgstr: + if newer_entry.msgstr != "" and (newer_entry.msgstr != entry.msgid or entry.msgid in NO_TRANSLATION_WHITELIST): + entry.merge(newer_entry) + entry.msgstr = newer_entry.msgstr + if "fuzzy" not in newer_entry.flags and "fuzzy" in entry.flags: + entry.flags.remove("fuzzy") + elif entry.msgid not in fixed_ids: + if commit not in bad_commits: + bad_commits[commit] = set() + bad_commits[commit].add(po_filename) + fixed_ids.add(entry.msgid) + #print(entry.msgid, "\"" + entry.msgstr + "\"", "\"" + newer_entry.msgstr + "\"",) + elif newer_entry and newer_entry.flags != entry.flags: + entry.flags = newer_entry.flags + elif newer_entry and newer_entry.obsolete != entry.obsolete: + entry.obsolete = newer_entry.obsolete + elif not newer_entry: + entry.obsolete = True + + # Add new entries to the modified pofile. + for entry in current_file: + old_entry = first_translations.find(entry.msgid, include_obsolete_entries=True) + if old_entry: + continue + first_translations.append(entry) + + # Remove obsolete translations. We can always use this script to revive them from the git history. + to_remove = [] + for entry in first_translations: + if entry.obsolete: + to_remove.append(entry) + + for remove in to_remove: + first_translations.remove(remove) + + first_translations.save(po_filename) + +print() +for commit in bad_commits: + files = bad_commits[commit] + print(commit) + for file in files: + print("\t",file) diff --git a/tools/fonts/ter-u12n.bdf b/tools/fonts/ter-u12n.bdf new file mode 100644 index 00000000000..390d0a1e870 --- /dev/null +++ b/tools/fonts/ter-u12n.bdf @@ -0,0 +1,25240 @@ +STARTFONT 2.1 +FONT -xos4-Terminus-Medium-R-Normal--12-120-72-72-C-60-ISO10646-1 +SIZE 12 72 72 +FONTBOUNDINGBOX 6 12 0 -2 +STARTPROPERTIES 20 +FAMILY_NAME "Terminus" +FOUNDRY "xos4" +SETWIDTH_NAME "Normal" +ADD_STYLE_NAME "" +COPYRIGHT "Copyright (C) 2018 Dimitar Toshkov Zhekov" +NOTICE "Licensed under the SIL Open Font License, Version 1.1" +WEIGHT_NAME "Medium" +SLANT "R" +PIXEL_SIZE 12 +POINT_SIZE 120 +RESOLUTION_X 72 +RESOLUTION_Y 72 +SPACING "C" +AVERAGE_WIDTH 60 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" +MIN_SPACE 6 +FONT_ASCENT 10 +FONT_DESCENT 2 +DEFAULT_CHAR 65533 +ENDPROPERTIES +CHARS 1326 +STARTCHAR char0 +ENCODING 0 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +D8 +88 +00 +88 +88 +00 +88 +D8 +00 +00 +ENDCHAR +STARTCHAR space +ENCODING 32 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR exclam +ENCODING 33 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +20 +20 +20 +00 +20 +20 +00 +00 +ENDCHAR +STARTCHAR quotedbl +ENCODING 34 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +50 +50 +50 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR numbersign +ENCODING 35 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +F8 +50 +50 +F8 +50 +50 +00 +00 +ENDCHAR +STARTCHAR dollar +ENCODING 36 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +70 +A8 +A0 +70 +28 +A8 +70 +20 +00 +ENDCHAR +STARTCHAR percent +ENCODING 37 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +48 +A8 +50 +10 +20 +28 +54 +48 +00 +00 +ENDCHAR +STARTCHAR ampersand +ENCODING 38 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +50 +50 +20 +68 +90 +90 +68 +00 +00 +ENDCHAR +STARTCHAR quotesingle +ENCODING 39 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +20 +20 +20 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR parenleft +ENCODING 40 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +40 +40 +40 +40 +20 +10 +00 +00 +ENDCHAR +STARTCHAR parenright +ENCODING 41 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +20 +10 +10 +10 +10 +20 +40 +00 +00 +ENDCHAR +STARTCHAR asterisk +ENCODING 42 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +50 +20 +F8 +20 +50 +00 +00 +00 +ENDCHAR +STARTCHAR plus +ENCODING 43 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +20 +20 +F8 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR comma +ENCODING 44 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +20 +20 +40 +00 +ENDCHAR +STARTCHAR hyphen +ENCODING 45 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +F8 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR period +ENCODING 46 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +20 +20 +00 +00 +ENDCHAR +STARTCHAR slash +ENCODING 47 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +08 +08 +10 +10 +20 +20 +40 +40 +00 +00 +ENDCHAR +STARTCHAR zero +ENCODING 48 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +98 +A8 +C8 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR one +ENCODING 49 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +60 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR two +ENCODING 50 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +08 +10 +20 +40 +F8 +00 +00 +ENDCHAR +STARTCHAR three +ENCODING 51 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +08 +30 +08 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR four +ENCODING 52 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +08 +18 +28 +48 +88 +F8 +08 +08 +00 +00 +ENDCHAR +STARTCHAR five +ENCODING 53 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +80 +80 +F0 +08 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR six +ENCODING 54 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +80 +80 +F0 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR seven +ENCODING 55 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +08 +08 +10 +10 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR eight +ENCODING 56 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +70 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR nine +ENCODING 57 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +88 +78 +08 +08 +70 +00 +00 +ENDCHAR +STARTCHAR colon +ENCODING 58 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +20 +20 +00 +00 +20 +20 +00 +00 +ENDCHAR +STARTCHAR semicolon +ENCODING 59 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +20 +20 +00 +00 +20 +20 +40 +00 +ENDCHAR +STARTCHAR less +ENCODING 60 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +10 +20 +40 +20 +10 +08 +00 +00 +ENDCHAR +STARTCHAR equal +ENCODING 61 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F8 +00 +00 +F8 +00 +00 +00 +00 +ENDCHAR +STARTCHAR greater +ENCODING 62 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +20 +10 +08 +10 +20 +40 +00 +00 +ENDCHAR +STARTCHAR question +ENCODING 63 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +10 +20 +00 +20 +20 +00 +00 +ENDCHAR +STARTCHAR at +ENCODING 64 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +98 +A8 +A8 +98 +80 +78 +00 +00 +ENDCHAR +STARTCHAR A +ENCODING 65 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR B +ENCODING 66 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F0 +88 +88 +F0 +88 +88 +88 +F0 +00 +00 +ENDCHAR +STARTCHAR C +ENCODING 67 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +80 +80 +80 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR D +ENCODING 68 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +E0 +90 +88 +88 +88 +88 +90 +E0 +00 +00 +ENDCHAR +STARTCHAR E +ENCODING 69 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +80 +80 +F0 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR F +ENCODING 70 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +80 +80 +F0 +80 +80 +80 +80 +00 +00 +ENDCHAR +STARTCHAR G +ENCODING 71 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +80 +80 +B8 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR H +ENCODING 72 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +88 +F8 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR I +ENCODING 73 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR J +ENCODING 74 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +38 +10 +10 +10 +10 +90 +90 +60 +00 +00 +ENDCHAR +STARTCHAR K +ENCODING 75 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +90 +A0 +C0 +C0 +A0 +90 +88 +00 +00 +ENDCHAR +STARTCHAR L +ENCODING 76 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +80 +80 +80 +80 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR M +ENCODING 77 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +D8 +A8 +A8 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR N +ENCODING 78 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +C8 +A8 +98 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR O +ENCODING 79 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR P +ENCODING 80 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F0 +88 +88 +88 +F0 +80 +80 +80 +00 +00 +ENDCHAR +STARTCHAR Q +ENCODING 81 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +88 +88 +88 +A8 +70 +08 +00 +ENDCHAR +STARTCHAR R +ENCODING 82 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F0 +88 +88 +88 +F0 +A0 +90 +88 +00 +00 +ENDCHAR +STARTCHAR S +ENCODING 83 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +80 +70 +08 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR T +ENCODING 84 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +20 +20 +20 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR U +ENCODING 85 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR V +ENCODING 86 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +88 +50 +50 +50 +20 +20 +00 +00 +ENDCHAR +STARTCHAR W +ENCODING 87 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +88 +88 +A8 +A8 +D8 +88 +00 +00 +ENDCHAR +STARTCHAR X +ENCODING 88 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +50 +20 +20 +50 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Y +ENCODING 89 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +50 +50 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR Z +ENCODING 90 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +08 +10 +20 +40 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR bracketleft +ENCODING 91 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +40 +40 +40 +40 +40 +40 +70 +00 +00 +ENDCHAR +STARTCHAR backslash +ENCODING 92 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +40 +20 +20 +10 +10 +08 +08 +00 +00 +ENDCHAR +STARTCHAR bracketright +ENCODING 93 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +10 +10 +10 +10 +10 +10 +70 +00 +00 +ENDCHAR +STARTCHAR asciicircum +ENCODING 94 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +20 +50 +88 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR underscore +ENCODING 95 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +F8 +00 +ENDCHAR +STARTCHAR grave +ENCODING 96 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR a +ENCODING 97 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +08 +78 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR b +ENCODING 98 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +80 +80 +F0 +88 +88 +88 +88 +F0 +00 +00 +ENDCHAR +STARTCHAR c +ENCODING 99 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +80 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR d +ENCODING 100 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +08 +08 +78 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR e +ENCODING 101 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +F8 +80 +80 +78 +00 +00 +ENDCHAR +STARTCHAR f +ENCODING 102 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +18 +20 +70 +20 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR g +ENCODING 103 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +78 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR h +ENCODING 104 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +80 +80 +F0 +88 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR i +ENCODING 105 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +20 +20 +00 +60 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR j +ENCODING 106 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +08 +08 +00 +18 +08 +08 +08 +08 +08 +48 +30 +ENDCHAR +STARTCHAR k +ENCODING 107 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +40 +48 +50 +60 +60 +50 +48 +00 +00 +ENDCHAR +STARTCHAR l +ENCODING 108 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +60 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR m +ENCODING 109 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F0 +A8 +A8 +A8 +A8 +A8 +00 +00 +ENDCHAR +STARTCHAR n +ENCODING 110 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F0 +88 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR o +ENCODING 111 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR p +ENCODING 112 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F0 +88 +88 +88 +88 +F0 +80 +80 +ENDCHAR +STARTCHAR q +ENCODING 113 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +78 +88 +88 +88 +88 +78 +08 +08 +ENDCHAR +STARTCHAR r +ENCODING 114 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +B8 +C0 +80 +80 +80 +80 +00 +00 +ENDCHAR +STARTCHAR s +ENCODING 115 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +78 +80 +70 +08 +08 +F0 +00 +00 +ENDCHAR +STARTCHAR t +ENCODING 116 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +70 +20 +20 +20 +20 +18 +00 +00 +ENDCHAR +STARTCHAR u +ENCODING 117 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR v +ENCODING 118 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +50 +50 +20 +20 +00 +00 +ENDCHAR +STARTCHAR w +ENCODING 119 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +A8 +A8 +A8 +70 +00 +00 +ENDCHAR +STARTCHAR x +ENCODING 120 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +50 +20 +20 +50 +88 +00 +00 +ENDCHAR +STARTCHAR y +ENCODING 121 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR z +ENCODING 122 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F8 +10 +20 +40 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR braceleft +ENCODING 123 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +18 +20 +20 +40 +20 +20 +20 +18 +00 +00 +ENDCHAR +STARTCHAR bar +ENCODING 124 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +20 +20 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR braceright +ENCODING 125 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +60 +10 +10 +08 +10 +10 +10 +60 +00 +00 +ENDCHAR +STARTCHAR asciitilde +ENCODING 126 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +48 +A8 +90 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR nbspace +ENCODING 160 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR exclamdown +ENCODING 161 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +00 +20 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR cent +ENCODING 162 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +20 +70 +A8 +A0 +A0 +A8 +70 +20 +00 +ENDCHAR +STARTCHAR sterling +ENCODING 163 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +30 +48 +40 +F0 +40 +40 +48 +F8 +00 +00 +ENDCHAR +STARTCHAR currency +ENCODING 164 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +30 +48 +48 +30 +48 +00 +00 +00 +ENDCHAR +STARTCHAR yen +ENCODING 165 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +50 +20 +70 +20 +70 +20 +00 +00 +ENDCHAR +STARTCHAR brokenbar +ENCODING 166 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +20 +00 +00 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR section +ENCODING 167 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +30 +48 +20 +50 +48 +28 +10 +48 +30 +00 +00 +ENDCHAR +STARTCHAR dieresis +ENCODING 168 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR copyright +ENCODING 169 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +78 +84 +B4 +A4 +A4 +B4 +84 +78 +00 +00 +ENDCHAR +STARTCHAR ordfeminine +ENCODING 170 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +08 +38 +48 +38 +00 +78 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR guillemotleft +ENCODING 171 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +14 +28 +50 +A0 +50 +28 +14 +00 +00 +ENDCHAR +STARTCHAR logicalnot +ENCODING 172 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F8 +08 +08 +08 +00 +00 +00 +00 +ENDCHAR +STARTCHAR softhyphen +ENCODING 173 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +78 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR registered +ENCODING 174 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +78 +84 +B4 +AC +B4 +AC +84 +78 +00 +00 +ENDCHAR +STARTCHAR macron +ENCODING 175 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +70 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR degree +ENCODING 176 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +20 +50 +20 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR plusminus +ENCODING 177 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +20 +20 +F8 +20 +20 +00 +F8 +00 +00 +ENDCHAR +STARTCHAR twosuperior +ENCODING 178 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +30 +48 +10 +20 +78 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR threesuperior +ENCODING 179 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +70 +08 +30 +08 +70 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR acute +ENCODING 180 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR mu +ENCODING 181 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +88 +88 +98 +E8 +80 +80 +ENDCHAR +STARTCHAR paragraph +ENCODING 182 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +78 +A8 +A8 +A8 +68 +28 +28 +28 +00 +00 +ENDCHAR +STARTCHAR periodcentered +ENCODING 183 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +20 +20 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR cedilla +ENCODING 184 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +20 +20 +40 +ENDCHAR +STARTCHAR onesuperior +ENCODING 185 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +10 +30 +10 +10 +38 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR ordmasculine +ENCODING 186 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +48 +48 +48 +30 +00 +78 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR guillemotright +ENCODING 187 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +A0 +50 +28 +14 +28 +50 +A0 +00 +00 +ENDCHAR +STARTCHAR onequarter +ENCODING 188 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +C0 +44 +48 +50 +20 +48 +98 +28 +78 +08 +08 +ENDCHAR +STARTCHAR onehalf +ENCODING 189 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +C0 +44 +48 +50 +20 +40 +98 +24 +08 +10 +3C +ENDCHAR +STARTCHAR threequarters +ENCODING 190 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +E0 +10 +60 +14 +E8 +10 +24 +4C +94 +3C +04 +04 +ENDCHAR +STARTCHAR questiondown +ENCODING 191 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +00 +20 +40 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Agrave +ENCODING 192 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +20 +70 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Aacute +ENCODING 193 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +70 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Acircumflex +ENCODING 194 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +50 +70 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Atilde +ENCODING 195 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +28 +50 +70 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Adieresis +ENCODING 196 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +70 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Aring +ENCODING 197 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +50 +70 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR AE +ENCODING 198 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +7C +90 +90 +FC +90 +90 +90 +9C +00 +00 +ENDCHAR +STARTCHAR Ccedilla +ENCODING 199 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +80 +80 +80 +80 +88 +70 +20 +40 +ENDCHAR +STARTCHAR Egrave +ENCODING 200 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +20 +F8 +80 +80 +F0 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR Eacute +ENCODING 201 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +F8 +80 +80 +F0 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR Ecircumflex +ENCODING 202 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +50 +F8 +80 +80 +F0 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR Edieresis +ENCODING 203 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +F8 +80 +80 +F0 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR Igrave +ENCODING 204 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +20 +70 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR Iacute +ENCODING 205 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +70 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR Icircumflex +ENCODING 206 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +50 +70 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR Idieresis +ENCODING 207 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +70 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR Eth +ENCODING 208 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +E0 +90 +88 +E8 +88 +88 +90 +E0 +00 +00 +ENDCHAR +STARTCHAR Ntilde +ENCODING 209 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +28 +50 +88 +88 +C8 +A8 +98 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Ograve +ENCODING 210 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +20 +70 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Oacute +ENCODING 211 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +70 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Ocircumflex +ENCODING 212 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +50 +70 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Otilde +ENCODING 213 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +28 +50 +70 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Odieresis +ENCODING 214 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +70 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR multiply +ENCODING 215 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +50 +20 +50 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Oslash +ENCODING 216 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +74 +88 +98 +A8 +C8 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Ugrave +ENCODING 217 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +20 +88 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Uacute +ENCODING 218 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +88 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Ucircumflex +ENCODING 219 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +50 +88 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Udieresis +ENCODING 220 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +88 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Yacute +ENCODING 221 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +88 +88 +50 +50 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR Thorn +ENCODING 222 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +80 +F0 +88 +88 +88 +F0 +80 +80 +00 +00 +ENDCHAR +STARTCHAR germandbls +ENCODING 223 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +E0 +90 +90 +F0 +88 +88 +C8 +B0 +00 +00 +ENDCHAR +STARTCHAR agrave +ENCODING 224 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +20 +70 +08 +78 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR aacute +ENCODING 225 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +70 +08 +78 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR acircumflex +ENCODING 226 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +50 +70 +08 +78 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR atilde +ENCODING 227 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +28 +50 +70 +08 +78 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR adieresis +ENCODING 228 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +70 +08 +78 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR aring +ENCODING 229 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +50 +70 +08 +78 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR ae +ENCODING 230 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +28 +68 +B0 +A0 +78 +00 +00 +ENDCHAR +STARTCHAR ccedilla +ENCODING 231 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +80 +80 +88 +70 +20 +40 +ENDCHAR +STARTCHAR egrave +ENCODING 232 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +20 +70 +88 +F8 +80 +80 +78 +00 +00 +ENDCHAR +STARTCHAR eacute +ENCODING 233 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +70 +88 +F8 +80 +80 +78 +00 +00 +ENDCHAR +STARTCHAR ecircumflex +ENCODING 234 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +50 +70 +88 +F8 +80 +80 +78 +00 +00 +ENDCHAR +STARTCHAR edieresis +ENCODING 235 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +70 +88 +F8 +80 +80 +78 +00 +00 +ENDCHAR +STARTCHAR igrave +ENCODING 236 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +20 +60 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR iacute +ENCODING 237 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +60 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR icircumflex +ENCODING 238 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +50 +60 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR idieresis +ENCODING 239 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +60 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR eth +ENCODING 240 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +A0 +40 +A0 +70 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR ntilde +ENCODING 241 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +28 +50 +F0 +88 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR ograve +ENCODING 242 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +20 +70 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR oacute +ENCODING 243 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +70 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR ocircumflex +ENCODING 244 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +50 +70 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR otilde +ENCODING 245 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +28 +50 +70 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR odieresis +ENCODING 246 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +70 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR divide +ENCODING 247 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +20 +20 +00 +F8 +00 +20 +20 +00 +00 +ENDCHAR +STARTCHAR oslash +ENCODING 248 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +74 +98 +A8 +C8 +88 +70 +00 +00 +ENDCHAR +STARTCHAR ugrave +ENCODING 249 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +20 +88 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR uacute +ENCODING 250 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +88 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR ucircumflex +ENCODING 251 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +50 +88 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR udieresis +ENCODING 252 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +88 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR yacute +ENCODING 253 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +88 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR thorn +ENCODING 254 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +80 +80 +F0 +88 +88 +88 +88 +F0 +80 +80 +ENDCHAR +STARTCHAR ydieresis +ENCODING 255 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +88 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR Amacron +ENCODING 256 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +70 +00 +70 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR amacron +ENCODING 257 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +00 +70 +08 +78 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR Abreve +ENCODING 258 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +70 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR abreve +ENCODING 259 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +70 +08 +78 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR Aogonek +ENCODING 260 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +88 +F8 +88 +88 +88 +10 +0C +ENDCHAR +STARTCHAR aogonek +ENCODING 261 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +08 +78 +88 +88 +78 +10 +0C +ENDCHAR +STARTCHAR Cacute +ENCODING 262 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +70 +88 +80 +80 +80 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR cacute +ENCODING 263 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +70 +88 +80 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Ccircumflex +ENCODING 264 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +50 +70 +88 +80 +80 +80 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR ccircumflex +ENCODING 265 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +50 +70 +88 +80 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Cdotaccent +ENCODING 266 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +70 +88 +80 +80 +80 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR cdotaccent +ENCODING 267 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +70 +88 +80 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Ccaron +ENCODING 268 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +70 +88 +80 +80 +80 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR ccaron +ENCODING 269 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +70 +88 +80 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Dcaron +ENCODING 270 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +A0 +40 +E0 +90 +88 +88 +88 +88 +90 +E0 +00 +00 +ENDCHAR +STARTCHAR dcaron +ENCODING 271 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +08 +08 +78 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR Dcroat +ENCODING 272 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +E0 +90 +88 +E8 +88 +88 +90 +E0 +00 +00 +ENDCHAR +STARTCHAR dcroat +ENCODING 273 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +08 +3C +08 +78 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR Emacron +ENCODING 274 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +70 +00 +F8 +80 +80 +F0 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR emacron +ENCODING 275 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +00 +70 +88 +F8 +80 +80 +78 +00 +00 +ENDCHAR +STARTCHAR Ebreve +ENCODING 276 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +F8 +80 +80 +F0 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR ebreve +ENCODING 277 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +70 +88 +F8 +80 +80 +78 +00 +00 +ENDCHAR +STARTCHAR Edotaccent +ENCODING 278 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +F8 +80 +80 +F0 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR edotaccent +ENCODING 279 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +70 +88 +F8 +80 +80 +78 +00 +00 +ENDCHAR +STARTCHAR Eogonek +ENCODING 280 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +80 +80 +F0 +80 +80 +80 +F8 +10 +0C +ENDCHAR +STARTCHAR eogonek +ENCODING 281 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +F8 +80 +80 +78 +20 +18 +ENDCHAR +STARTCHAR Ecaron +ENCODING 282 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +F8 +80 +80 +F0 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR ecaron +ENCODING 283 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +70 +88 +F8 +80 +80 +78 +00 +00 +ENDCHAR +STARTCHAR Gcircumflex +ENCODING 284 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +50 +70 +88 +80 +80 +B8 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR gcircumflex +ENCODING 285 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +50 +78 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR Gbreve +ENCODING 286 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +70 +88 +80 +80 +B8 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR gbreve +ENCODING 287 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +78 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR Gdotaccent +ENCODING 288 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +70 +88 +80 +80 +B8 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR gdotaccent +ENCODING 289 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +78 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR Gcommaaccent +ENCODING 290 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +80 +80 +B8 +88 +88 +70 +20 +40 +ENDCHAR +STARTCHAR gcommaaccent +ENCODING 291 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +78 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR Hcircumflex +ENCODING 292 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +50 +88 +88 +88 +F8 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR hcircumflex +ENCODING 293 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +50 +80 +80 +F0 +88 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Hbar +ENCODING 294 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +48 +FC +48 +78 +48 +48 +48 +48 +00 +00 +ENDCHAR +STARTCHAR hbar +ENCODING 295 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +F0 +40 +70 +48 +48 +48 +48 +00 +00 +ENDCHAR +STARTCHAR Itilde +ENCODING 296 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +28 +50 +70 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR itilde +ENCODING 297 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +28 +50 +60 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR Imacron +ENCODING 298 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +70 +00 +70 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR imacron +ENCODING 299 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +00 +60 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR Ibreve +ENCODING 300 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +70 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR ibreve +ENCODING 301 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +60 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR Iogonek +ENCODING 302 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +20 +20 +20 +20 +20 +20 +70 +20 +18 +ENDCHAR +STARTCHAR iogonek +ENCODING 303 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +20 +20 +00 +60 +20 +20 +20 +20 +70 +20 +18 +ENDCHAR +STARTCHAR Idotaccent +ENCODING 304 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +70 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR dotlessi +ENCODING 305 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +60 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR IJ +ENCODING 306 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +88 +88 +88 +A8 +A8 +90 +00 +00 +ENDCHAR +STARTCHAR ij +ENCODING 307 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +88 +88 +00 +98 +88 +88 +88 +88 +88 +28 +10 +ENDCHAR +STARTCHAR Jcircumflex +ENCODING 308 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +28 +38 +10 +10 +10 +10 +90 +90 +60 +00 +00 +ENDCHAR +STARTCHAR jcircumflex +ENCODING 309 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +08 +14 +18 +08 +08 +08 +08 +08 +48 +30 +ENDCHAR +STARTCHAR Kcommaaccent +ENCODING 310 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +90 +A0 +C0 +C0 +A0 +90 +A8 +20 +40 +ENDCHAR +STARTCHAR kcommaaccent +ENCODING 311 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +40 +48 +50 +60 +60 +50 +68 +20 +40 +ENDCHAR +STARTCHAR kgreenlandic +ENCODING 312 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +48 +50 +60 +60 +50 +48 +00 +00 +ENDCHAR +STARTCHAR Lacute +ENCODING 313 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +40 +80 +80 +80 +80 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR lacute +ENCODING 314 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +60 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR Lcommaaccent +ENCODING 315 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +80 +80 +80 +80 +80 +80 +80 +F8 +20 +40 +ENDCHAR +STARTCHAR lcommaaccent +ENCODING 316 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +60 +20 +20 +20 +20 +20 +20 +70 +20 +40 +ENDCHAR +STARTCHAR Lcaron +ENCODING 317 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +80 +80 +80 +80 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR lcaron +ENCODING 318 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +60 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR Ldot +ENCODING 319 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +80 +80 +80 +90 +90 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR ldot +ENCODING 320 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +60 +20 +20 +24 +24 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR Lslash +ENCODING 321 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +40 +40 +60 +C0 +40 +40 +7C +00 +00 +ENDCHAR +STARTCHAR lslash +ENCODING 322 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +60 +20 +20 +30 +60 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR Nacute +ENCODING 323 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +88 +88 +C8 +A8 +98 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR nacute +ENCODING 324 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +F0 +88 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Ncommaaccent +ENCODING 325 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +C8 +A8 +98 +88 +88 +A8 +20 +40 +ENDCHAR +STARTCHAR ncommaaccent +ENCODING 326 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F0 +88 +88 +88 +88 +A8 +20 +40 +ENDCHAR +STARTCHAR Ncaron +ENCODING 327 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +88 +88 +C8 +A8 +98 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR ncaron +ENCODING 328 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +F0 +88 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR napostrophe +ENCODING 329 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +40 +40 +80 +F0 +88 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Eng +ENCODING 330 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +C8 +A8 +98 +88 +88 +88 +08 +10 +ENDCHAR +STARTCHAR eng +ENCODING 331 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F0 +88 +88 +88 +88 +88 +08 +10 +ENDCHAR +STARTCHAR Omacron +ENCODING 332 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +70 +00 +70 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR omacron +ENCODING 333 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +00 +70 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Obreve +ENCODING 334 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +70 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR obreve +ENCODING 335 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +70 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Ohungarumlaut +ENCODING 336 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +28 +50 +70 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR ohungarumlaut +ENCODING 337 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +28 +50 +70 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR OE +ENCODING 338 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +7C +90 +90 +9C +90 +90 +90 +7C +00 +00 +ENDCHAR +STARTCHAR oe +ENCODING 339 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +A8 +A8 +B0 +A0 +78 +00 +00 +ENDCHAR +STARTCHAR Racute +ENCODING 340 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +F0 +88 +88 +88 +F0 +A0 +90 +88 +00 +00 +ENDCHAR +STARTCHAR racute +ENCODING 341 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +B8 +C0 +80 +80 +80 +80 +00 +00 +ENDCHAR +STARTCHAR Rcommaaccent +ENCODING 342 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F0 +88 +88 +88 +F0 +A0 +90 +A8 +20 +40 +ENDCHAR +STARTCHAR rcommaaccent +ENCODING 343 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +B8 +C0 +80 +80 +80 +C0 +40 +80 +ENDCHAR +STARTCHAR Rcaron +ENCODING 344 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +F0 +88 +88 +88 +F0 +A0 +90 +88 +00 +00 +ENDCHAR +STARTCHAR rcaron +ENCODING 345 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +B8 +C0 +80 +80 +80 +80 +00 +00 +ENDCHAR +STARTCHAR Sacute +ENCODING 346 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +70 +88 +80 +70 +08 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR sacute +ENCODING 347 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +78 +80 +70 +08 +08 +F0 +00 +00 +ENDCHAR +STARTCHAR Scircumflex +ENCODING 348 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +50 +70 +88 +80 +70 +08 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR scircumflex +ENCODING 349 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +50 +78 +80 +70 +08 +08 +F0 +00 +00 +ENDCHAR +STARTCHAR Scedilla +ENCODING 350 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +80 +70 +08 +08 +88 +70 +20 +40 +ENDCHAR +STARTCHAR scedilla +ENCODING 351 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +78 +80 +70 +08 +08 +F0 +20 +40 +ENDCHAR +STARTCHAR Scaron +ENCODING 352 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +70 +88 +80 +70 +08 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR scaron +ENCODING 353 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +78 +80 +70 +08 +08 +F0 +00 +00 +ENDCHAR +STARTCHAR Tcedilla +ENCODING 354 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +20 +20 +20 +20 +20 +20 +30 +10 +20 +ENDCHAR +STARTCHAR tcedilla +ENCODING 355 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +70 +20 +20 +20 +20 +18 +10 +20 +ENDCHAR +STARTCHAR Tcaron +ENCODING 356 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +F8 +20 +20 +20 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR tcaron +ENCODING 357 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +20 +20 +70 +20 +20 +20 +20 +18 +00 +00 +ENDCHAR +STARTCHAR Tbar +ENCODING 358 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +20 +20 +70 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR tbar +ENCODING 359 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +70 +20 +70 +20 +20 +18 +00 +00 +ENDCHAR +STARTCHAR Utilde +ENCODING 360 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +28 +50 +88 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR utilde +ENCODING 361 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +28 +50 +88 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR Umacron +ENCODING 362 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +70 +00 +88 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR umacron +ENCODING 363 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +00 +88 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR Ubreve +ENCODING 364 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +88 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR ubreve +ENCODING 365 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +88 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR Uring +ENCODING 366 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +50 +A8 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uring +ENCODING 367 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +50 +A8 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR Uhungarumlaut +ENCODING 368 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +28 +50 +88 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uhungarumlaut +ENCODING 369 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +28 +50 +88 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR Uogonek +ENCODING 370 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +88 +88 +88 +88 +88 +70 +20 +18 +ENDCHAR +STARTCHAR uogonek +ENCODING 371 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +88 +88 +88 +78 +10 +0C +ENDCHAR +STARTCHAR Wcircumflex +ENCODING 372 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +50 +88 +88 +88 +88 +A8 +A8 +D8 +88 +00 +00 +ENDCHAR +STARTCHAR wcircumflex +ENCODING 373 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +50 +88 +88 +A8 +A8 +A8 +70 +00 +00 +ENDCHAR +STARTCHAR Ycircumflex +ENCODING 374 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +50 +88 +88 +50 +50 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR ycircumflex +ENCODING 375 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +50 +88 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR Ydieresis +ENCODING 376 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +88 +88 +50 +50 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR Zacute +ENCODING 377 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +F8 +08 +10 +20 +40 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR zacute +ENCODING 378 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +F8 +10 +20 +40 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR Zdotaccent +ENCODING 379 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +F8 +08 +10 +20 +40 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR zdotaccent +ENCODING 380 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +F8 +10 +20 +40 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR Zcaron +ENCODING 381 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +F8 +08 +10 +20 +40 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR zcaron +ENCODING 382 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +F8 +10 +20 +40 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR longs +ENCODING 383 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +18 +20 +20 +20 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR uni0186 +ENCODING 390 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +08 +08 +08 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni018E +ENCODING 398 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +08 +08 +78 +08 +08 +08 +F8 +00 +00 +ENDCHAR +STARTCHAR Schwa +ENCODING 399 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +08 +08 +F8 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni0190 +ENCODING 400 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +80 +60 +80 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR florin +ENCODING 402 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +28 +20 +70 +20 +20 +20 +20 +A0 +40 +ENDCHAR +STARTCHAR uni019D +ENCODING 413 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +C8 +A8 +98 +88 +88 +C8 +40 +80 +ENDCHAR +STARTCHAR uni019E +ENCODING 414 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F0 +88 +88 +88 +88 +88 +08 +08 +ENDCHAR +STARTCHAR uni01B5 +ENCODING 437 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +08 +10 +F8 +20 +40 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR uni01B6 +ENCODING 438 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F8 +10 +78 +20 +40 +F8 +00 +00 +ENDCHAR +STARTCHAR Ezh +ENCODING 439 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +08 +10 +30 +08 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni01CD +ENCODING 461 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +70 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR uni01CE +ENCODING 462 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +70 +08 +78 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR uni01CF +ENCODING 463 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +70 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR uni01D0 +ENCODING 464 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +60 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR uni01D1 +ENCODING 465 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +70 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni01D2 +ENCODING 466 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +70 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni01D3 +ENCODING 467 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +88 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni01D4 +ENCODING 468 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +88 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +ENDCHAR +STARTCHAR uni01DC +ENCODING 476 +SWIDTH 1000 0 +DWIDTH 6 0 +BBX 5 10 0 0 +BITMAP +40 +20 +88 +00 +88 +88 +88 +88 +88 +78 +ENDCHAR +STARTCHAR uni01E2 +ENCODING 482 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +78 +00 +7C +90 +90 +FC +90 +90 +90 +9C +00 +00 +ENDCHAR +STARTCHAR uni01E3 +ENCODING 483 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +00 +70 +28 +68 +B0 +A0 +78 +00 +00 +ENDCHAR +STARTCHAR uni01E4 +ENCODING 484 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +78 +80 +80 +B8 +88 +9C +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni01E5 +ENCODING 485 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +78 +88 +9C +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR Gcaron +ENCODING 486 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +70 +88 +80 +80 +B8 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR gcaron +ENCODING 487 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +78 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR uni01E8 +ENCODING 488 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +88 +90 +A0 +C0 +C0 +A0 +90 +88 +00 +00 +ENDCHAR +STARTCHAR uni01E9 +ENCODING 489 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +40 +40 +48 +50 +60 +60 +50 +48 +00 +00 +ENDCHAR +STARTCHAR uni01EA +ENCODING 490 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +88 +88 +88 +88 +70 +20 +18 +ENDCHAR +STARTCHAR uni01EB +ENCODING 491 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +88 +88 +88 +70 +20 +18 +ENDCHAR +STARTCHAR uni01EC +ENCODING 492 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +70 +00 +70 +88 +88 +88 +88 +88 +88 +70 +20 +18 +ENDCHAR +STARTCHAR uni01ED +ENCODING 493 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +00 +70 +88 +88 +88 +88 +70 +20 +18 +ENDCHAR +STARTCHAR uni01EE +ENCODING 494 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +F8 +08 +10 +30 +08 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni01EF +ENCODING 495 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +F8 +08 +10 +30 +08 +08 +88 +70 +ENDCHAR +STARTCHAR uni01F0 +ENCODING 496 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +14 +08 +18 +08 +08 +08 +08 +08 +48 +30 +ENDCHAR +STARTCHAR uni01F4 +ENCODING 500 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +70 +88 +80 +80 +B8 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni01F5 +ENCODING 501 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +78 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR AEacute +ENCODING 508 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +10 +7C +90 +90 +FC +90 +90 +90 +9C +00 +00 +ENDCHAR +STARTCHAR aeacute +ENCODING 509 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +70 +28 +68 +B0 +A0 +78 +00 +00 +ENDCHAR +STARTCHAR Oslashacute +ENCODING 510 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +74 +88 +98 +A8 +C8 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR oslashacute +ENCODING 511 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +74 +98 +A8 +C8 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Scommaaccent +ENCODING 536 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +80 +70 +08 +08 +88 +70 +20 +40 +ENDCHAR +STARTCHAR scommaaccent +ENCODING 537 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +78 +80 +70 +08 +08 +F0 +20 +40 +ENDCHAR +STARTCHAR Tcommaaccent +ENCODING 538 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +20 +20 +20 +20 +20 +20 +30 +10 +20 +ENDCHAR +STARTCHAR tcommaaccent +ENCODING 539 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +70 +20 +20 +20 +20 +18 +08 +10 +ENDCHAR +STARTCHAR uni0232 +ENCODING 562 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +70 +00 +88 +88 +50 +50 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR uni0233 +ENCODING 563 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +00 +88 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR dotlessj +ENCODING 567 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +18 +08 +08 +08 +08 +08 +48 +30 +ENDCHAR +STARTCHAR uni0254 +ENCODING 596 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +08 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni0258 +ENCODING 600 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +F8 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR schwa +ENCODING 601 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +08 +F8 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni025B +ENCODING 603 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +60 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni0272 +ENCODING 626 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F0 +88 +88 +88 +88 +C8 +40 +80 +ENDCHAR +STARTCHAR ezh +ENCODING 658 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F8 +08 +10 +30 +08 +08 +88 +70 +ENDCHAR +STARTCHAR commaturnedmod +ENCODING 699 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR afii57929 +ENCODING 700 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR afii64937 +ENCODING 701 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR circumflex +ENCODING 710 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +50 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR caron +ENCODING 711 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR breve +ENCODING 728 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR dotaccent +ENCODING 729 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR ogonek +ENCODING 731 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +10 +20 +18 +ENDCHAR +STARTCHAR tilde +ENCODING 732 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +28 +50 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR hungarumlaut +ENCODING 733 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +28 +50 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR gravecomb +ENCODING 768 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR acutecomb +ENCODING 769 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0302 +ENCODING 770 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +50 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR tildecomb +ENCODING 771 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +28 +50 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0304 +ENCODING 772 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +70 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0305 +ENCODING 773 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +F8 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0306 +ENCODING 774 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0307 +ENCODING 775 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0308 +ENCODING 776 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni030A +ENCODING 778 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +50 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni030B +ENCODING 779 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +28 +50 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni030C +ENCODING 780 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0329 +ENCODING 809 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +20 +20 +ENDCHAR +STARTCHAR tonos +ENCODING 900 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR dieresistonos +ENCODING 901 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +50 +50 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR Alphatonos +ENCODING 902 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +80 +70 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR anoteleia +ENCODING 903 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +20 +20 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR Epsilontonos +ENCODING 904 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +80 +F8 +80 +80 +F0 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR Etatonos +ENCODING 905 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +80 +88 +88 +88 +F8 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Iotatonos +ENCODING 906 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +80 +70 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR Omicrontonos +ENCODING 908 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +80 +70 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Upsilontonos +ENCODING 910 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +80 +88 +88 +50 +50 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR Omegatonos +ENCODING 911 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +80 +70 +88 +88 +88 +88 +88 +50 +D8 +00 +00 +ENDCHAR +STARTCHAR iotadieresistonos +ENCODING 912 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +50 +50 +60 +20 +20 +20 +20 +18 +00 +00 +ENDCHAR +STARTCHAR Alpha +ENCODING 913 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Beta +ENCODING 914 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F0 +88 +88 +F0 +88 +88 +88 +F0 +00 +00 +ENDCHAR +STARTCHAR Gamma +ENCODING 915 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +80 +80 +80 +80 +80 +80 +80 +00 +00 +ENDCHAR +STARTCHAR Delta +ENCODING 916 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +50 +50 +88 +88 +88 +F8 +00 +00 +ENDCHAR +STARTCHAR Epsilon +ENCODING 917 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +80 +80 +F0 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR Zeta +ENCODING 918 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +08 +10 +20 +40 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR Eta +ENCODING 919 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +88 +F8 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Theta +ENCODING 920 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +A8 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Iota +ENCODING 921 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR Kappa +ENCODING 922 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +90 +A0 +C0 +C0 +A0 +90 +88 +00 +00 +ENDCHAR +STARTCHAR Lambda +ENCODING 923 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +50 +50 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Mu +ENCODING 924 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +D8 +A8 +A8 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Nu +ENCODING 925 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +C8 +A8 +98 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Xi +ENCODING 926 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +00 +00 +70 +00 +00 +00 +F8 +00 +00 +ENDCHAR +STARTCHAR Omicron +ENCODING 927 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR Pi +ENCODING 928 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +88 +88 +88 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Rho +ENCODING 929 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F0 +88 +88 +88 +F0 +80 +80 +80 +00 +00 +ENDCHAR +STARTCHAR Sigma +ENCODING 931 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +40 +20 +10 +10 +20 +40 +F8 +00 +00 +ENDCHAR +STARTCHAR Tau +ENCODING 932 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +20 +20 +20 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR Upsilon +ENCODING 933 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +50 +50 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR Phi +ENCODING 934 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +70 +A8 +A8 +A8 +A8 +70 +20 +00 +00 +ENDCHAR +STARTCHAR Chi +ENCODING 935 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +50 +20 +20 +50 +88 +88 +00 +00 +ENDCHAR +STARTCHAR Psi +ENCODING 936 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +A8 +A8 +A8 +A8 +A8 +70 +20 +20 +00 +00 +ENDCHAR +STARTCHAR Omega +ENCODING 937 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +88 +88 +88 +50 +D8 +00 +00 +ENDCHAR +STARTCHAR Iotadieresis +ENCODING 938 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +70 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR Upsilondieresis +ENCODING 939 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +88 +88 +50 +50 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR alphatonos +ENCODING 940 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +68 +90 +90 +90 +90 +68 +00 +00 +ENDCHAR +STARTCHAR epsilontonos +ENCODING 941 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +70 +88 +60 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR etatonos +ENCODING 942 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +F0 +88 +88 +88 +88 +88 +08 +08 +ENDCHAR +STARTCHAR iotatonos +ENCODING 943 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +60 +20 +20 +20 +20 +18 +00 +00 +ENDCHAR +STARTCHAR upsilondieresistonos +ENCODING 944 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +50 +50 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR alpha +ENCODING 945 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +68 +90 +90 +90 +90 +68 +00 +00 +ENDCHAR +STARTCHAR beta +ENCODING 946 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +E0 +90 +90 +F0 +88 +88 +88 +F0 +80 +80 +ENDCHAR +STARTCHAR gamma +ENCODING 947 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +88 +50 +50 +20 +20 +20 +ENDCHAR +STARTCHAR delta +ENCODING 948 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F0 +40 +20 +70 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR epsilon +ENCODING 949 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +60 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR zeta +ENCODING 950 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +10 +20 +40 +80 +80 +80 +70 +08 +10 +ENDCHAR +STARTCHAR eta +ENCODING 951 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F0 +88 +88 +88 +88 +88 +08 +08 +ENDCHAR +STARTCHAR theta +ENCODING 952 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +30 +48 +48 +78 +48 +48 +48 +30 +00 +00 +ENDCHAR +STARTCHAR iota +ENCODING 953 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +60 +20 +20 +20 +20 +18 +00 +00 +ENDCHAR +STARTCHAR kappa +ENCODING 954 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +48 +50 +60 +60 +50 +48 +00 +00 +ENDCHAR +STARTCHAR lambda +ENCODING 955 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +40 +20 +20 +50 +50 +88 +88 +00 +00 +ENDCHAR +STARTCHAR mugreek +ENCODING 956 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +88 +88 +98 +E8 +80 +80 +ENDCHAR +STARTCHAR nu +ENCODING 957 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +50 +50 +20 +20 +00 +00 +ENDCHAR +STARTCHAR xi +ENCODING 958 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +78 +80 +80 +70 +80 +80 +80 +70 +08 +10 +ENDCHAR +STARTCHAR omicron +ENCODING 959 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR pi +ENCODING 960 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F8 +88 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR rho +ENCODING 961 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +88 +88 +88 +F0 +80 +80 +ENDCHAR +STARTCHAR sigma1 +ENCODING 962 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +80 +80 +80 +70 +08 +10 +ENDCHAR +STARTCHAR sigma +ENCODING 963 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +78 +90 +90 +90 +90 +60 +00 +00 +ENDCHAR +STARTCHAR tau +ENCODING 964 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F8 +20 +20 +20 +20 +10 +00 +00 +ENDCHAR +STARTCHAR upsilon +ENCODING 965 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR phi +ENCODING 966 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +90 +A8 +A8 +A8 +A8 +70 +20 +20 +ENDCHAR +STARTCHAR chi +ENCODING 967 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +50 +20 +20 +50 +88 +88 +ENDCHAR +STARTCHAR psi +ENCODING 968 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +A8 +A8 +A8 +A8 +A8 +70 +20 +20 +ENDCHAR +STARTCHAR omega +ENCODING 969 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +50 +88 +A8 +A8 +A8 +50 +00 +00 +ENDCHAR +STARTCHAR iotadieresis +ENCODING 970 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +60 +20 +20 +20 +20 +18 +00 +00 +ENDCHAR +STARTCHAR upsilondieresis +ENCODING 971 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR omicrontonos +ENCODING 972 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +70 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR upsilontonos +ENCODING 973 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR omegatonos +ENCODING 974 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +50 +88 +A8 +A8 +A8 +50 +00 +00 +ENDCHAR +STARTCHAR theta1 +ENCODING 977 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +30 +48 +48 +3C +08 +C8 +48 +30 +00 +00 +ENDCHAR +STARTCHAR phi1 +ENCODING 981 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +20 +70 +A8 +A8 +A8 +A8 +70 +20 +00 +ENDCHAR +STARTCHAR uni03F0 +ENCODING 1008 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +C4 +28 +10 +20 +50 +8C +00 +00 +ENDCHAR +STARTCHAR uni03F1 +ENCODING 1009 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +88 +88 +88 +F0 +80 +70 +ENDCHAR +STARTCHAR uni03F2 +ENCODING 1010 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +80 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni03F3 +ENCODING 1011 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +08 +08 +00 +18 +08 +08 +08 +08 +08 +48 +30 +ENDCHAR +STARTCHAR uni03F4 +ENCODING 1012 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +F8 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni03F5 +ENCODING 1013 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +78 +80 +F0 +80 +80 +78 +00 +00 +ENDCHAR +STARTCHAR uni03F6 +ENCODING 1014 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F0 +08 +78 +08 +08 +F0 +00 +00 +ENDCHAR +STARTCHAR uni0400 +ENCODING 1024 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +20 +F8 +80 +80 +F0 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR afii10023 +ENCODING 1025 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +F8 +80 +80 +F0 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR afii10051 +ENCODING 1026 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +E0 +40 +40 +70 +48 +48 +48 +48 +08 +10 +ENDCHAR +STARTCHAR afii10052 +ENCODING 1027 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +F8 +80 +80 +80 +80 +80 +80 +80 +00 +00 +ENDCHAR +STARTCHAR afii10053 +ENCODING 1028 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +80 +F0 +80 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR afii10054 +ENCODING 1029 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +80 +70 +08 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR afii10055 +ENCODING 1030 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR afii10056 +ENCODING 1031 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +70 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR afii10057 +ENCODING 1032 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +38 +10 +10 +10 +10 +90 +90 +60 +00 +00 +ENDCHAR +STARTCHAR afii10058 +ENCODING 1033 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +60 +A0 +B0 +A8 +A8 +A8 +A8 +B0 +00 +00 +ENDCHAR +STARTCHAR afii10059 +ENCODING 1034 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +A0 +A0 +B0 +E8 +A8 +A8 +A8 +B0 +00 +00 +ENDCHAR +STARTCHAR afii10060 +ENCODING 1035 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +E0 +40 +40 +70 +48 +48 +48 +48 +00 +00 +ENDCHAR +STARTCHAR afii10061 +ENCODING 1036 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +20 +88 +90 +A0 +C0 +C0 +A0 +90 +88 +00 +00 +ENDCHAR +STARTCHAR uni040D +ENCODING 1037 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +20 +88 +88 +98 +A8 +C8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR afii10062 +ENCODING 1038 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +88 +88 +88 +88 +78 +08 +08 +70 +00 +00 +ENDCHAR +STARTCHAR afii10145 +ENCODING 1039 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +88 +88 +88 +88 +88 +F8 +20 +20 +ENDCHAR +STARTCHAR afii10017 +ENCODING 1040 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR afii10018 +ENCODING 1041 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F0 +80 +80 +F0 +88 +88 +88 +F0 +00 +00 +ENDCHAR +STARTCHAR afii10019 +ENCODING 1042 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F0 +88 +88 +F0 +88 +88 +88 +F0 +00 +00 +ENDCHAR +STARTCHAR afii10020 +ENCODING 1043 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +80 +80 +80 +80 +80 +80 +80 +00 +00 +ENDCHAR +STARTCHAR afii10021 +ENCODING 1044 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +38 +48 +48 +48 +48 +48 +48 +FC +84 +00 +ENDCHAR +STARTCHAR afii10022 +ENCODING 1045 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +80 +80 +F0 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR afii10024 +ENCODING 1046 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +A8 +A8 +A8 +70 +70 +A8 +A8 +A8 +00 +00 +ENDCHAR +STARTCHAR afii10025 +ENCODING 1047 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +08 +30 +08 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR afii10026 +ENCODING 1048 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +98 +A8 +C8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR afii10027 +ENCODING 1049 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +88 +88 +98 +A8 +C8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR afii10028 +ENCODING 1050 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +90 +A0 +C0 +C0 +A0 +90 +88 +00 +00 +ENDCHAR +STARTCHAR afii10029 +ENCODING 1051 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +38 +48 +48 +48 +48 +48 +48 +88 +00 +00 +ENDCHAR +STARTCHAR afii10030 +ENCODING 1052 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +D8 +A8 +A8 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR afii10031 +ENCODING 1053 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +88 +F8 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR afii10032 +ENCODING 1054 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR afii10033 +ENCODING 1055 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +88 +88 +88 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR afii10034 +ENCODING 1056 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F0 +88 +88 +88 +F0 +80 +80 +80 +00 +00 +ENDCHAR +STARTCHAR afii10035 +ENCODING 1057 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +80 +80 +80 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR afii10036 +ENCODING 1058 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +20 +20 +20 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR afii10037 +ENCODING 1059 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +88 +88 +78 +08 +08 +70 +00 +00 +ENDCHAR +STARTCHAR afii10038 +ENCODING 1060 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +20 +70 +A8 +A8 +A8 +A8 +A8 +A8 +70 +20 +00 +ENDCHAR +STARTCHAR afii10039 +ENCODING 1061 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +50 +20 +20 +50 +88 +88 +00 +00 +ENDCHAR +STARTCHAR afii10040 +ENCODING 1062 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +88 +88 +88 +88 +88 +7C +04 +04 +ENDCHAR +STARTCHAR afii10041 +ENCODING 1063 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +88 +88 +78 +08 +08 +08 +00 +00 +ENDCHAR +STARTCHAR afii10042 +ENCODING 1064 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +A8 +A8 +A8 +A8 +A8 +A8 +A8 +78 +00 +00 +ENDCHAR +STARTCHAR afii10043 +ENCODING 1065 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +A8 +A8 +A8 +A8 +A8 +A8 +A8 +7C +04 +04 +ENDCHAR +STARTCHAR afii10044 +ENCODING 1066 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +C0 +40 +70 +48 +48 +48 +48 +70 +00 +00 +ENDCHAR +STARTCHAR afii10045 +ENCODING 1067 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +C8 +A8 +A8 +A8 +A8 +C8 +00 +00 +ENDCHAR +STARTCHAR afii10046 +ENCODING 1068 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +40 +70 +48 +48 +48 +48 +70 +00 +00 +ENDCHAR +STARTCHAR afii10047 +ENCODING 1069 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +08 +38 +08 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR afii10048 +ENCODING 1070 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +90 +A8 +A8 +A8 +E8 +A8 +A8 +90 +00 +00 +ENDCHAR +STARTCHAR afii10049 +ENCODING 1071 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +78 +88 +88 +88 +78 +28 +48 +88 +00 +00 +ENDCHAR +STARTCHAR afii10065 +ENCODING 1072 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +08 +78 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR afii10066 +ENCODING 1073 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +80 +F0 +88 +88 +88 +88 +F0 +00 +00 +ENDCHAR +STARTCHAR afii10067 +ENCODING 1074 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +E0 +90 +90 +F0 +88 +88 +88 +F0 +00 +00 +ENDCHAR +STARTCHAR afii10068 +ENCODING 1075 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F8 +80 +80 +80 +80 +80 +00 +00 +ENDCHAR +STARTCHAR afii10069 +ENCODING 1076 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +78 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR afii10070 +ENCODING 1077 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +F8 +80 +80 +78 +00 +00 +ENDCHAR +STARTCHAR afii10072 +ENCODING 1078 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +A8 +A8 +70 +A8 +A8 +A8 +00 +00 +ENDCHAR +STARTCHAR afii10073 +ENCODING 1079 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +30 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR afii10074 +ENCODING 1080 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR afii10075 +ENCODING 1081 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +88 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR afii10076 +ENCODING 1082 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +48 +50 +60 +60 +50 +48 +00 +00 +ENDCHAR +STARTCHAR afii10077 +ENCODING 1083 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +38 +48 +48 +48 +48 +88 +00 +00 +ENDCHAR +STARTCHAR afii10078 +ENCODING 1084 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +D8 +A8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR afii10079 +ENCODING 1085 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +F8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR afii10080 +ENCODING 1086 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR afii10081 +ENCODING 1087 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F8 +88 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR afii10082 +ENCODING 1088 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F0 +88 +88 +88 +88 +F0 +80 +80 +ENDCHAR +STARTCHAR afii10083 +ENCODING 1089 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +80 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR afii10084 +ENCODING 1090 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F8 +20 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR afii10085 +ENCODING 1091 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR afii10086 +ENCODING 1092 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +20 +70 +A8 +A8 +A8 +A8 +70 +20 +00 +ENDCHAR +STARTCHAR afii10087 +ENCODING 1093 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +50 +20 +20 +50 +88 +00 +00 +ENDCHAR +STARTCHAR afii10088 +ENCODING 1094 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +88 +88 +88 +7C +04 +04 +ENDCHAR +STARTCHAR afii10089 +ENCODING 1095 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +88 +78 +08 +08 +00 +00 +ENDCHAR +STARTCHAR afii10090 +ENCODING 1096 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +A8 +A8 +A8 +A8 +A8 +78 +00 +00 +ENDCHAR +STARTCHAR afii10091 +ENCODING 1097 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +A8 +A8 +A8 +A8 +A8 +7C +04 +04 +ENDCHAR +STARTCHAR afii10092 +ENCODING 1098 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +C0 +40 +70 +48 +48 +70 +00 +00 +ENDCHAR +STARTCHAR afii10093 +ENCODING 1099 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +C8 +A8 +A8 +C8 +00 +00 +ENDCHAR +STARTCHAR afii10094 +ENCODING 1100 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +40 +40 +70 +48 +48 +70 +00 +00 +ENDCHAR +STARTCHAR afii10095 +ENCODING 1101 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +38 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR afii10096 +ENCODING 1102 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +90 +A8 +A8 +E8 +A8 +90 +00 +00 +ENDCHAR +STARTCHAR afii10097 +ENCODING 1103 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +78 +88 +88 +78 +28 +48 +00 +00 +ENDCHAR +STARTCHAR uni0450 +ENCODING 1104 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +20 +70 +88 +F8 +80 +80 +78 +00 +00 +ENDCHAR +STARTCHAR afii10071 +ENCODING 1105 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +70 +88 +F8 +80 +80 +78 +00 +00 +ENDCHAR +STARTCHAR afii10099 +ENCODING 1106 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +F0 +40 +70 +48 +48 +48 +48 +08 +10 +ENDCHAR +STARTCHAR afii10100 +ENCODING 1107 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +20 +F8 +80 +80 +80 +80 +80 +00 +00 +ENDCHAR +STARTCHAR afii10101 +ENCODING 1108 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +E0 +80 +88 +70 +00 +00 +ENDCHAR +STARTCHAR afii10102 +ENCODING 1109 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +78 +80 +70 +08 +08 +F0 +00 +00 +ENDCHAR +STARTCHAR afii10103 +ENCODING 1110 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +20 +20 +00 +60 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR afii10104 +ENCODING 1111 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +60 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR afii10105 +ENCODING 1112 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +08 +08 +00 +18 +08 +08 +08 +08 +08 +48 +30 +ENDCHAR +STARTCHAR afii10106 +ENCODING 1113 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +60 +A0 +B0 +A8 +A8 +B0 +00 +00 +ENDCHAR +STARTCHAR afii10107 +ENCODING 1114 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +A0 +A0 +F0 +A8 +A8 +B0 +00 +00 +ENDCHAR +STARTCHAR afii10108 +ENCODING 1115 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +F0 +40 +70 +48 +48 +48 +48 +00 +00 +ENDCHAR +STARTCHAR afii10109 +ENCODING 1116 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +08 +10 +48 +50 +60 +60 +50 +48 +00 +00 +ENDCHAR +STARTCHAR uni045D +ENCODING 1117 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +20 +88 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR afii10110 +ENCODING 1118 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +88 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR afii10193 +ENCODING 1119 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +88 +88 +88 +F8 +20 +20 +ENDCHAR +STARTCHAR afii10146 +ENCODING 1122 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +F0 +40 +70 +48 +48 +48 +70 +00 +00 +ENDCHAR +STARTCHAR afii10194 +ENCODING 1123 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +40 +E0 +40 +70 +48 +48 +70 +00 +00 +ENDCHAR +STARTCHAR uni046A +ENCODING 1130 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +88 +50 +20 +70 +A8 +A8 +A8 +00 +00 +ENDCHAR +STARTCHAR uni046B +ENCODING 1131 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F8 +50 +20 +70 +A8 +A8 +00 +00 +ENDCHAR +STARTCHAR afii10050 +ENCODING 1168 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +F8 +80 +80 +80 +80 +80 +80 +80 +00 +00 +ENDCHAR +STARTCHAR afii10098 +ENCODING 1169 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +08 +08 +F8 +80 +80 +80 +80 +80 +00 +00 +ENDCHAR +STARTCHAR uni0492 +ENCODING 1170 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +7C +40 +40 +40 +F0 +40 +40 +40 +00 +00 +ENDCHAR +STARTCHAR uni0493 +ENCODING 1171 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +78 +40 +40 +F0 +40 +40 +00 +00 +ENDCHAR +STARTCHAR uni0494 +ENCODING 1172 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +80 +80 +80 +F0 +88 +88 +88 +08 +10 +ENDCHAR +STARTCHAR uni0495 +ENCODING 1173 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F8 +80 +80 +E0 +90 +90 +10 +20 +ENDCHAR +STARTCHAR uni0496 +ENCODING 1174 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +A8 +A8 +A8 +70 +70 +A8 +A8 +AC +04 +04 +ENDCHAR +STARTCHAR uni0497 +ENCODING 1175 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +A8 +A8 +70 +A8 +A8 +AC +04 +04 +ENDCHAR +STARTCHAR uni0498 +ENCODING 1176 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +08 +30 +08 +08 +88 +70 +20 +20 +ENDCHAR +STARTCHAR uni0499 +ENCODING 1177 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +30 +08 +88 +70 +20 +20 +ENDCHAR +STARTCHAR uni049A +ENCODING 1178 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +90 +A0 +C0 +C0 +A0 +90 +8C +04 +04 +ENDCHAR +STARTCHAR uni049B +ENCODING 1179 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +48 +50 +60 +60 +50 +4C +04 +04 +ENDCHAR +STARTCHAR uni049C +ENCODING 1180 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +84 +A8 +B0 +E0 +E0 +B0 +A8 +84 +00 +00 +ENDCHAR +STARTCHAR uni049D +ENCODING 1181 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +A8 +B0 +E0 +E0 +B0 +A8 +00 +00 +ENDCHAR +STARTCHAR uni04A0 +ENCODING 1184 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +C4 +48 +50 +60 +60 +50 +48 +44 +00 +00 +ENDCHAR +STARTCHAR uni04A1 +ENCODING 1185 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +C8 +50 +60 +60 +50 +48 +00 +00 +ENDCHAR +STARTCHAR uni04A2 +ENCODING 1186 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +88 +F8 +88 +88 +88 +8C +04 +04 +ENDCHAR +STARTCHAR uni04A3 +ENCODING 1187 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +F8 +88 +88 +8C +04 +04 +ENDCHAR +STARTCHAR uni04A4 +ENCODING 1188 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +9C +90 +90 +F0 +90 +90 +90 +90 +00 +00 +ENDCHAR +STARTCHAR uni04A5 +ENCODING 1189 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +9C +90 +F0 +90 +90 +90 +00 +00 +ENDCHAR +STARTCHAR uni04AA +ENCODING 1194 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +80 +80 +80 +80 +88 +70 +20 +20 +ENDCHAR +STARTCHAR uni04AB +ENCODING 1195 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +80 +80 +88 +70 +20 +20 +ENDCHAR +STARTCHAR uni04AE +ENCODING 1198 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +50 +50 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR uni04AF +ENCODING 1199 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +88 +50 +50 +20 +20 +20 +ENDCHAR +STARTCHAR uni04B0 +ENCODING 1200 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +50 +50 +20 +70 +20 +20 +00 +00 +ENDCHAR +STARTCHAR uni04B1 +ENCODING 1201 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +88 +50 +50 +20 +70 +20 +ENDCHAR +STARTCHAR uni04B2 +ENCODING 1202 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +50 +20 +20 +50 +88 +8C +04 +04 +ENDCHAR +STARTCHAR uni04B3 +ENCODING 1203 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +50 +20 +20 +50 +8C +04 +04 +ENDCHAR +STARTCHAR uni04B6 +ENCODING 1206 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +88 +88 +78 +08 +08 +0C +04 +04 +ENDCHAR +STARTCHAR uni04B7 +ENCODING 1207 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +88 +78 +08 +0C +04 +04 +ENDCHAR +STARTCHAR uni04B8 +ENCODING 1208 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +A8 +A8 +78 +28 +28 +08 +00 +00 +ENDCHAR +STARTCHAR uni04B9 +ENCODING 1209 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +A8 +A8 +78 +28 +08 +00 +00 +ENDCHAR +STARTCHAR uni04BA +ENCODING 1210 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +80 +80 +80 +F0 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR uni04BB +ENCODING 1211 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +80 +80 +F0 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR uni04C0 +ENCODING 1216 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR uni04C1 +ENCODING 1217 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +A8 +A8 +A8 +70 +70 +A8 +A8 +A8 +00 +00 +ENDCHAR +STARTCHAR uni04C2 +ENCODING 1218 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +A8 +A8 +70 +A8 +A8 +A8 +00 +00 +ENDCHAR +STARTCHAR uni04CF +ENCODING 1231 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +60 +20 +20 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR uni04D0 +ENCODING 1232 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +70 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR uni04D1 +ENCODING 1233 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +70 +08 +78 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR uni04D2 +ENCODING 1234 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +70 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR uni04D3 +ENCODING 1235 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +70 +08 +78 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR uni04D4 +ENCODING 1236 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +7C +90 +90 +FC +90 +90 +90 +9C +00 +00 +ENDCHAR +STARTCHAR uni04D5 +ENCODING 1237 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +28 +68 +B0 +A0 +78 +00 +00 +ENDCHAR +STARTCHAR uni04D6 +ENCODING 1238 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +20 +F8 +80 +80 +F0 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR uni04D7 +ENCODING 1239 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +20 +70 +88 +F8 +80 +80 +78 +00 +00 +ENDCHAR +STARTCHAR uni04D8 +ENCODING 1240 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +08 +08 +F8 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR afii10846 +ENCODING 1241 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +08 +F8 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni04DA +ENCODING 1242 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +70 +88 +08 +08 +F8 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni04DB +ENCODING 1243 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +70 +88 +08 +F8 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni04DC +ENCODING 1244 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +A8 +A8 +A8 +70 +70 +A8 +A8 +A8 +00 +00 +ENDCHAR +STARTCHAR uni04DD +ENCODING 1245 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +A8 +A8 +70 +A8 +A8 +A8 +00 +00 +ENDCHAR +STARTCHAR uni04DE +ENCODING 1246 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +70 +88 +08 +30 +08 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni04DF +ENCODING 1247 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +70 +88 +30 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni04E2 +ENCODING 1250 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +70 +00 +88 +88 +98 +A8 +C8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR uni04E3 +ENCODING 1251 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +00 +88 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR uni04E4 +ENCODING 1252 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +88 +88 +98 +A8 +C8 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR uni04E5 +ENCODING 1253 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +88 +88 +88 +88 +88 +78 +00 +00 +ENDCHAR +STARTCHAR uni04E6 +ENCODING 1254 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +70 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni04E7 +ENCODING 1255 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +70 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni04E8 +ENCODING 1256 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +F8 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni04E9 +ENCODING 1257 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +F8 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni04EA +ENCODING 1258 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +70 +88 +88 +88 +F8 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni04EB +ENCODING 1259 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +70 +88 +F8 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni04EC +ENCODING 1260 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +70 +88 +08 +38 +08 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni04ED +ENCODING 1261 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +70 +88 +38 +08 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni04EE +ENCODING 1262 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +70 +00 +88 +88 +88 +88 +78 +08 +08 +70 +00 +00 +ENDCHAR +STARTCHAR uni04EF +ENCODING 1263 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +00 +88 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR uni04F0 +ENCODING 1264 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +88 +88 +88 +88 +78 +08 +08 +70 +00 +00 +ENDCHAR +STARTCHAR uni04F1 +ENCODING 1265 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +88 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR uni04F2 +ENCODING 1266 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +28 +50 +88 +88 +88 +88 +78 +08 +08 +70 +00 +00 +ENDCHAR +STARTCHAR uni04F3 +ENCODING 1267 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +28 +50 +88 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR uni04F4 +ENCODING 1268 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +88 +88 +88 +88 +78 +08 +08 +08 +00 +00 +ENDCHAR +STARTCHAR uni04F5 +ENCODING 1269 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +88 +88 +88 +78 +08 +08 +00 +00 +ENDCHAR +STARTCHAR uni04F8 +ENCODING 1272 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +88 +88 +C8 +A8 +A8 +A8 +A8 +C8 +00 +00 +ENDCHAR +STARTCHAR uni04F9 +ENCODING 1273 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +88 +88 +C8 +A8 +A8 +C8 +00 +00 +ENDCHAR +STARTCHAR uni1E0C +ENCODING 7692 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +E0 +90 +88 +88 +88 +88 +90 +E0 +20 +20 +ENDCHAR +STARTCHAR uni1E0D +ENCODING 7693 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +08 +08 +78 +88 +88 +88 +88 +78 +20 +20 +ENDCHAR +STARTCHAR Klinebelow +ENCODING 7732 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +90 +A0 +C0 +C0 +A0 +90 +88 +00 +70 +ENDCHAR +STARTCHAR klinebelow +ENCODING 7733 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +40 +48 +50 +60 +60 +50 +48 +00 +70 +ENDCHAR +STARTCHAR uni1E36 +ENCODING 7734 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +80 +80 +80 +80 +80 +80 +80 +F8 +20 +20 +ENDCHAR +STARTCHAR uni1E37 +ENCODING 7735 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +60 +20 +20 +20 +20 +20 +20 +70 +20 +20 +ENDCHAR +STARTCHAR uni1E40 +ENCODING 7744 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +88 +D8 +A8 +A8 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR uni1E41 +ENCODING 7745 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +F0 +A8 +A8 +A8 +A8 +A8 +00 +00 +ENDCHAR +STARTCHAR uni1E42 +ENCODING 7746 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +D8 +A8 +A8 +88 +88 +88 +88 +20 +20 +ENDCHAR +STARTCHAR uni1E43 +ENCODING 7747 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F0 +A8 +A8 +A8 +A8 +A8 +10 +10 +ENDCHAR +STARTCHAR uni1E44 +ENCODING 7748 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +88 +88 +C8 +A8 +98 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR uni1E45 +ENCODING 7749 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +F0 +88 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR uni1E46 +ENCODING 7750 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +C8 +A8 +98 +88 +88 +88 +20 +20 +ENDCHAR +STARTCHAR uni1E47 +ENCODING 7751 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F0 +88 +88 +88 +88 +88 +20 +20 +ENDCHAR +STARTCHAR uni1E6C +ENCODING 7788 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +20 +20 +20 +20 +20 +20 +20 +10 +10 +ENDCHAR +STARTCHAR uni1E6D +ENCODING 7789 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +70 +20 +20 +20 +20 +18 +10 +10 +ENDCHAR +STARTCHAR Edotbelow +ENCODING 7864 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +80 +80 +F0 +80 +80 +80 +F8 +20 +20 +ENDCHAR +STARTCHAR edotbelow +ENCODING 7865 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +F8 +80 +80 +78 +20 +20 +ENDCHAR +STARTCHAR Etilde +ENCODING 7868 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +28 +50 +F8 +80 +80 +F0 +80 +80 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR etilde +ENCODING 7869 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +28 +50 +70 +88 +F8 +80 +80 +78 +00 +00 +ENDCHAR +STARTCHAR uni1ECA +ENCODING 7882 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +20 +20 +20 +20 +20 +20 +70 +20 +20 +ENDCHAR +STARTCHAR uni1ECB +ENCODING 7883 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +20 +20 +00 +60 +20 +20 +20 +20 +70 +20 +20 +ENDCHAR +STARTCHAR Odotbelow +ENCODING 7884 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +88 +88 +88 +88 +70 +20 +20 +ENDCHAR +STARTCHAR odotbelow +ENCODING 7885 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +88 +88 +88 +70 +20 +20 +ENDCHAR +STARTCHAR uni1EE4 +ENCODING 7908 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +88 +88 +88 +88 +88 +70 +20 +20 +ENDCHAR +STARTCHAR uni1EE5 +ENCODING 7909 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +88 +88 +88 +78 +20 +20 +ENDCHAR +STARTCHAR Ytilde +ENCODING 7928 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +28 +50 +88 +88 +50 +50 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR ytilde +ENCODING 7929 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +28 +50 +88 +88 +88 +88 +88 +78 +08 +70 +ENDCHAR +STARTCHAR uni2000 +ENCODING 8192 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2001 +ENCODING 8193 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR enspace +ENCODING 8194 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2003 +ENCODING 8195 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2004 +ENCODING 8196 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2005 +ENCODING 8197 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2006 +ENCODING 8198 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2007 +ENCODING 8199 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2008 +ENCODING 8200 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2009 +ENCODING 8201 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni200A +ENCODING 8202 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni200B +ENCODING 8203 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR afii61664 +ENCODING 8204 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR afii301 +ENCODING 8205 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR afii299 +ENCODING 8206 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR afii300 +ENCODING 8207 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR hyphentwo +ENCODING 8208 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +78 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2011 +ENCODING 8209 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +78 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR figuredash +ENCODING 8210 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +F8 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR endash +ENCODING 8211 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +F8 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR emdash +ENCODING 8212 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +F8 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR afii00208 +ENCODING 8213 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +F8 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR dblverticalbar +ENCODING 8214 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +50 +50 +50 +50 +50 +50 +00 +00 +ENDCHAR +STARTCHAR underscoredbl +ENCODING 8215 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +F8 +00 +F8 +ENDCHAR +STARTCHAR quoteleft +ENCODING 8216 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +10 +20 +20 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR quoteright +ENCODING 8217 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +20 +20 +40 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR quotesinglbase +ENCODING 8218 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +20 +20 +40 +00 +ENDCHAR +STARTCHAR quotereversed +ENCODING 8219 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +20 +20 +10 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR quotedblleft +ENCODING 8220 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +28 +50 +50 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR quotedblright +ENCODING 8221 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +28 +28 +50 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR quotedblbase +ENCODING 8222 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +50 +50 +A0 +00 +ENDCHAR +STARTCHAR uni201F +ENCODING 8223 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +A0 +A0 +50 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR dagger +ENCODING 8224 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +70 +20 +20 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR daggerdbl +ENCODING 8225 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +70 +20 +20 +20 +20 +70 +20 +00 +00 +ENDCHAR +STARTCHAR bullet +ENCODING 8226 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +30 +78 +78 +30 +00 +00 +00 +00 +ENDCHAR +STARTCHAR ellipsis +ENCODING 8230 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +A8 +A8 +00 +00 +ENDCHAR +STARTCHAR perthousand +ENCODING 8240 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +44 +A8 +50 +20 +40 +A8 +54 +28 +00 +00 +ENDCHAR +STARTCHAR minute +ENCODING 8242 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +20 +20 +20 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR second +ENCODING 8243 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +50 +50 +50 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR guilsinglleft +ENCODING 8249 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +10 +20 +40 +20 +10 +08 +00 +00 +ENDCHAR +STARTCHAR guilsinglright +ENCODING 8250 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +20 +10 +08 +10 +20 +40 +00 +00 +ENDCHAR +STARTCHAR exclamdbl +ENCODING 8252 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +50 +50 +50 +00 +50 +50 +00 +00 +ENDCHAR +STARTCHAR overline +ENCODING 8254 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +F8 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2070 +ENCODING 8304 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +30 +48 +48 +48 +30 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2071 +ENCODING 8305 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +00 +60 +20 +20 +70 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2074 +ENCODING 8308 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +08 +18 +28 +78 +08 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2075 +ENCODING 8309 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +70 +40 +70 +08 +70 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2076 +ENCODING 8310 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +30 +40 +70 +48 +30 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2077 +ENCODING 8311 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +78 +08 +10 +20 +20 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2078 +ENCODING 8312 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +30 +48 +30 +48 +30 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2079 +ENCODING 8313 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +30 +48 +38 +08 +30 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni207A +ENCODING 8314 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +20 +20 +F8 +20 +20 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni207B +ENCODING 8315 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +78 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni207C +ENCODING 8316 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +78 +00 +78 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni207D +ENCODING 8317 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +10 +20 +20 +20 +10 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni207E +ENCODING 8318 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +20 +10 +10 +10 +20 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR nsuperior +ENCODING 8319 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +70 +48 +48 +48 +48 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2080 +ENCODING 8320 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +30 +48 +48 +48 +30 +00 +00 +ENDCHAR +STARTCHAR uni2081 +ENCODING 8321 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +10 +30 +10 +10 +38 +00 +00 +ENDCHAR +STARTCHAR uni2082 +ENCODING 8322 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +30 +48 +10 +20 +78 +00 +00 +ENDCHAR +STARTCHAR uni2083 +ENCODING 8323 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +70 +08 +30 +08 +70 +00 +00 +ENDCHAR +STARTCHAR uni2084 +ENCODING 8324 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +08 +18 +28 +78 +08 +00 +00 +ENDCHAR +STARTCHAR uni2085 +ENCODING 8325 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +70 +40 +70 +08 +70 +00 +00 +ENDCHAR +STARTCHAR uni2086 +ENCODING 8326 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +30 +40 +70 +48 +30 +00 +00 +ENDCHAR +STARTCHAR uni2087 +ENCODING 8327 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +78 +08 +10 +20 +20 +00 +00 +ENDCHAR +STARTCHAR uni2088 +ENCODING 8328 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +30 +48 +30 +48 +30 +00 +00 +ENDCHAR +STARTCHAR uni2089 +ENCODING 8329 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +30 +48 +38 +08 +30 +00 +00 +ENDCHAR +STARTCHAR uni208A +ENCODING 8330 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +20 +20 +F8 +20 +20 +00 +00 +ENDCHAR +STARTCHAR uni208B +ENCODING 8331 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +78 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni208C +ENCODING 8332 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +78 +00 +78 +00 +00 +00 +ENDCHAR +STARTCHAR uni208D +ENCODING 8333 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +10 +20 +20 +20 +10 +00 +00 +ENDCHAR +STARTCHAR uni208E +ENCODING 8334 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +20 +10 +10 +10 +20 +00 +00 +ENDCHAR +STARTCHAR uni2090 +ENCODING 8336 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +30 +08 +38 +48 +38 +00 +00 +ENDCHAR +STARTCHAR uni2091 +ENCODING 8337 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +30 +48 +78 +40 +38 +00 +00 +ENDCHAR +STARTCHAR uni2092 +ENCODING 8338 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +30 +48 +48 +48 +30 +00 +00 +ENDCHAR +STARTCHAR uni2093 +ENCODING 8339 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +88 +50 +20 +50 +88 +00 +00 +ENDCHAR +STARTCHAR uni2094 +ENCODING 8340 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +70 +08 +78 +48 +30 +00 +00 +ENDCHAR +STARTCHAR uni2095 +ENCODING 8341 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +40 +70 +48 +48 +48 +48 +00 +00 +ENDCHAR +STARTCHAR uni2096 +ENCODING 8342 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +40 +48 +50 +60 +50 +48 +00 +00 +ENDCHAR +STARTCHAR uni2097 +ENCODING 8343 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +60 +20 +20 +20 +20 +70 +00 +00 +ENDCHAR +STARTCHAR uni2098 +ENCODING 8344 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +F0 +A8 +A8 +A8 +A8 +00 +00 +ENDCHAR +STARTCHAR uni209A +ENCODING 8346 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +70 +48 +48 +48 +70 +40 +40 +ENDCHAR +STARTCHAR peseta +ENCODING 8359 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +C0 +A0 +A0 +C8 +9C +88 +88 +84 +00 +00 +ENDCHAR +STARTCHAR Euro +ENCODING 8364 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +38 +44 +F0 +40 +F0 +44 +38 +00 +00 +ENDCHAR +STARTCHAR uni20AE +ENCODING 8366 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +20 +30 +60 +30 +60 +20 +20 +00 +00 +ENDCHAR +STARTCHAR uni2102 +ENCODING 8450 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +A8 +A0 +A0 +A0 +A0 +A8 +70 +00 +00 +ENDCHAR +STARTCHAR uni210E +ENCODING 8462 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +80 +80 +F0 +88 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR uni210F +ENCODING 8463 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +F0 +40 +70 +48 +48 +48 +48 +00 +00 +ENDCHAR +STARTCHAR uni2115 +ENCODING 8469 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +C8 +A8 +D8 +A8 +98 +88 +88 +00 +00 +ENDCHAR +STARTCHAR afii61352 +ENCODING 8470 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +94 +94 +D0 +F0 +F0 +B4 +90 +94 +00 +00 +ENDCHAR +STARTCHAR uni211A +ENCODING 8474 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +C8 +A8 +A8 +A8 +A8 +A8 +70 +18 +00 +ENDCHAR +STARTCHAR uni211D +ENCODING 8477 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F0 +A8 +A8 +A8 +B0 +B0 +A8 +E4 +00 +00 +ENDCHAR +STARTCHAR trademark +ENCODING 8482 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F4 +5C +54 +54 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2124 +ENCODING 8484 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +18 +28 +50 +A0 +C0 +80 +F8 +00 +00 +ENDCHAR +STARTCHAR Ohm +ENCODING 8486 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +88 +88 +88 +50 +D8 +00 +00 +ENDCHAR +STARTCHAR aleph +ENCODING 8501 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +48 +48 +24 +68 +90 +90 +88 +48 +00 +00 +ENDCHAR +STARTCHAR arrowleft +ENCODING 8592 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +20 +60 +FC +60 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR arrowup +ENCODING 8593 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +70 +F8 +20 +20 +20 +20 +20 +00 +00 +ENDCHAR +STARTCHAR arrowright +ENCODING 8594 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +10 +18 +FC +18 +10 +00 +00 +00 +00 +ENDCHAR +STARTCHAR arrowdown +ENCODING 8595 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +20 +20 +20 +F8 +70 +20 +00 +00 +ENDCHAR +STARTCHAR arrowboth +ENCODING 8596 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +CC +FC +CC +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR arrowupdn +ENCODING 8597 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +70 +F8 +20 +20 +F8 +70 +20 +00 +00 +ENDCHAR +STARTCHAR uni21A4 +ENCODING 8612 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +24 +64 +FC +64 +24 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni21A6 +ENCODING 8614 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +90 +98 +FC +98 +90 +00 +00 +00 +00 +ENDCHAR +STARTCHAR arrowupdnbse +ENCODING 8616 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +70 +F8 +20 +F8 +70 +20 +F8 +00 +00 +ENDCHAR +STARTCHAR carriagereturn +ENCODING 8629 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +08 +08 +08 +28 +68 +F8 +60 +20 +00 +00 +ENDCHAR +STARTCHAR uni21BB +ENCODING 8635 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F0 +30 +50 +94 +84 +84 +84 +78 +00 +00 +ENDCHAR +STARTCHAR uni21CB +ENCODING 8651 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +40 +FC +00 +FC +08 +10 +00 +00 +00 +ENDCHAR +STARTCHAR uni21CC +ENCODING 8652 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +08 +FC +00 +FC +40 +20 +00 +00 +00 +ENDCHAR +STARTCHAR arrowdblleft +ENCODING 8656 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +20 +7C +E0 +7C +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR arrowdblup +ENCODING 8657 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +70 +F8 +50 +50 +50 +50 +50 +00 +00 +ENDCHAR +STARTCHAR arrowdblright +ENCODING 8658 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +10 +F8 +1C +F8 +10 +00 +00 +00 +00 +ENDCHAR +STARTCHAR arrowdbldown +ENCODING 8659 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +50 +50 +50 +F8 +70 +20 +00 +00 +ENDCHAR +STARTCHAR arrowdblboth +ENCODING 8660 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +FC +CC +FC +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni21D5 +ENCODING 8661 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +70 +F8 +50 +50 +F8 +70 +20 +00 +00 +ENDCHAR +STARTCHAR universal +ENCODING 8704 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +F8 +50 +50 +50 +20 +20 +00 +00 +ENDCHAR +STARTCHAR existential +ENCODING 8707 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +F8 +08 +08 +F8 +08 +08 +F8 +00 +00 +ENDCHAR +STARTCHAR uni2204 +ENCODING 8708 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +F8 +28 +28 +F8 +48 +48 +F8 +80 +00 +ENDCHAR +STARTCHAR emptyset +ENCODING 8709 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +08 +70 +98 +A8 +A8 +C8 +70 +80 +00 +00 +ENDCHAR +STARTCHAR increment +ENCODING 8710 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +50 +50 +88 +88 +88 +F8 +00 +00 +ENDCHAR +STARTCHAR gradient +ENCODING 8711 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +88 +88 +88 +50 +50 +20 +20 +00 +00 +ENDCHAR +STARTCHAR element +ENCODING 8712 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +38 +40 +80 +F8 +80 +40 +38 +00 +00 +ENDCHAR +STARTCHAR notelement +ENCODING 8713 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +08 +38 +50 +90 +F8 +A0 +60 +78 +40 +00 +ENDCHAR +STARTCHAR uni220A +ENCODING 8714 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +78 +80 +F8 +80 +78 +00 +00 +00 +ENDCHAR +STARTCHAR suchthat +ENCODING 8715 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +E0 +10 +08 +F8 +08 +10 +E0 +00 +00 +ENDCHAR +STARTCHAR uni220C +ENCODING 8716 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +80 +E0 +50 +48 +F8 +28 +30 +F0 +10 +00 +ENDCHAR +STARTCHAR uni220D +ENCODING 8717 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F0 +08 +F8 +08 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR minus +ENCODING 8722 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +F8 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2213 +ENCODING 8723 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +F8 +00 +20 +20 +F8 +20 +20 +00 +00 +ENDCHAR +STARTCHAR uni2214 +ENCODING 8724 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +00 +20 +20 +F8 +20 +20 +00 +00 +ENDCHAR +STARTCHAR uni2215 +ENCODING 8725 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +08 +10 +20 +40 +80 +00 +00 +00 +ENDCHAR +STARTCHAR uni2216 +ENCODING 8726 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +80 +40 +20 +10 +08 +00 +00 +00 +ENDCHAR +STARTCHAR bulletoperator +ENCODING 8729 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +30 +78 +30 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR radical +ENCODING 8730 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +0C +08 +08 +08 +88 +88 +48 +28 +18 +00 +00 +ENDCHAR +STARTCHAR infinity +ENCODING 8734 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +50 +A8 +A8 +A8 +50 +00 +00 +00 +00 +ENDCHAR +STARTCHAR orthogonal +ENCODING 8735 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +80 +80 +80 +80 +F8 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2225 +ENCODING 8741 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +50 +50 +50 +50 +50 +50 +50 +50 +00 +00 +ENDCHAR +STARTCHAR logicaland +ENCODING 8743 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +20 +20 +50 +50 +88 +88 +00 +00 +ENDCHAR +STARTCHAR logicalor +ENCODING 8744 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +50 +50 +20 +20 +00 +00 +ENDCHAR +STARTCHAR intersection +ENCODING 8745 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +70 +88 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR union +ENCODING 8746 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR approxequal +ENCODING 8776 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +68 +B0 +00 +68 +B0 +00 +00 +00 +ENDCHAR +STARTCHAR notequal +ENCODING 8800 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +F8 +20 +40 +F8 +80 +00 +00 +00 +ENDCHAR +STARTCHAR equivalence +ENCODING 8801 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F8 +00 +F8 +00 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR lessequal +ENCODING 8804 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +10 +20 +40 +80 +40 +20 +10 +00 +F8 +00 +00 +ENDCHAR +STARTCHAR greaterequal +ENCODING 8805 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +40 +20 +10 +08 +10 +20 +40 +00 +F8 +00 +00 +ENDCHAR +STARTCHAR uni226A +ENCODING 8810 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +14 +28 +50 +A0 +50 +28 +14 +00 +00 +ENDCHAR +STARTCHAR uni226B +ENCODING 8811 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +A0 +50 +28 +14 +28 +50 +A0 +00 +00 +ENDCHAR +STARTCHAR propersubset +ENCODING 8834 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +78 +80 +80 +80 +80 +78 +00 +00 +00 +ENDCHAR +STARTCHAR propersuperset +ENCODING 8835 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +F0 +08 +08 +08 +08 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR reflexsubset +ENCODING 8838 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +78 +80 +80 +80 +80 +78 +00 +F8 +00 +00 +ENDCHAR +STARTCHAR reflexsuperset +ENCODING 8839 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F0 +08 +08 +08 +08 +F0 +00 +F8 +00 +00 +ENDCHAR +STARTCHAR perpendicular +ENCODING 8869 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +20 +20 +20 +20 +20 +F8 +00 +00 +ENDCHAR +STARTCHAR uni22C2 +ENCODING 8898 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +88 +88 +88 +88 +88 +00 +00 +ENDCHAR +STARTCHAR uni22C3 +ENCODING 8899 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +88 +88 +88 +88 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR uni2300 +ENCODING 8960 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +08 +70 +98 +A8 +A8 +C8 +70 +80 +00 +00 +ENDCHAR +STARTCHAR house +ENCODING 8962 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +20 +50 +88 +88 +88 +F8 +00 +00 +ENDCHAR +STARTCHAR uni2308 +ENCODING 8968 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +40 +40 +40 +40 +40 +40 +40 +00 +00 +ENDCHAR +STARTCHAR uni2309 +ENCODING 8969 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +10 +10 +10 +10 +10 +10 +10 +00 +00 +ENDCHAR +STARTCHAR uni230A +ENCODING 8970 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +40 +40 +40 +40 +40 +40 +40 +70 +00 +00 +ENDCHAR +STARTCHAR uni230B +ENCODING 8971 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +10 +10 +10 +10 +10 +10 +70 +00 +00 +ENDCHAR +STARTCHAR revlogicalnot +ENCODING 8976 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F8 +80 +80 +80 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2319 +ENCODING 8985 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +80 +80 +80 +F8 +00 +00 +00 +00 +ENDCHAR +STARTCHAR integraltp +ENCODING 8992 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +10 +28 +28 +20 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR integralbt +ENCODING 8993 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +20 +20 +A0 +A0 +40 +00 +00 +ENDCHAR +STARTCHAR uni239B +ENCODING 9115 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +10 +10 +20 +20 +20 +40 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR uni239C +ENCODING 9116 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +40 +40 +40 +40 +40 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR uni239D +ENCODING 9117 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +40 +40 +40 +40 +20 +20 +20 +10 +10 +08 +ENDCHAR +STARTCHAR uni239E +ENCODING 9118 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +20 +20 +10 +10 +10 +08 +08 +08 +08 +08 +08 +ENDCHAR +STARTCHAR uni239F +ENCODING 9119 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +08 +08 +08 +08 +08 +08 +08 +08 +08 +08 +ENDCHAR +STARTCHAR uni23A0 +ENCODING 9120 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +08 +08 +08 +08 +10 +10 +10 +20 +20 +40 +ENDCHAR +STARTCHAR uni23A1 +ENCODING 9121 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +78 +40 +40 +40 +40 +40 +40 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR uni23A2 +ENCODING 9122 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +40 +40 +40 +40 +40 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR uni23A3 +ENCODING 9123 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +40 +40 +40 +40 +40 +40 +40 +40 +40 +78 +ENDCHAR +STARTCHAR uni23A4 +ENCODING 9124 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +78 +08 +08 +08 +08 +08 +08 +08 +08 +08 +08 +08 +ENDCHAR +STARTCHAR uni23A5 +ENCODING 9125 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +08 +08 +08 +08 +08 +08 +08 +08 +08 +08 +ENDCHAR +STARTCHAR uni23A6 +ENCODING 9126 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +08 +08 +08 +08 +08 +08 +08 +08 +08 +78 +ENDCHAR +STARTCHAR uni23A7 +ENCODING 9127 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +0C +10 +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni23A8 +ENCODING 9128 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +C0 +C0 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni23A9 +ENCODING 9129 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +10 +0C +ENDCHAR +STARTCHAR uni23AB +ENCODING 9131 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +C0 +20 +10 +10 +10 +10 +10 +10 +10 +10 +10 +10 +ENDCHAR +STARTCHAR uni23AC +ENCODING 9132 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +10 +10 +10 +10 +0C +0C +10 +10 +10 +10 +10 +ENDCHAR +STARTCHAR uni23AD +ENCODING 9133 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +10 +10 +10 +10 +10 +10 +10 +10 +10 +10 +20 +C0 +ENDCHAR +STARTCHAR uni23AE +ENCODING 9134 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni23AF +ENCODING 9135 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +FC +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni23BA +ENCODING 9146 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +FC +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni23BB +ENCODING 9147 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +FC +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni23BC +ENCODING 9148 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +FC +00 +00 +00 +ENDCHAR +STARTCHAR uni23BD +ENCODING 9149 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +FC +ENDCHAR +STARTCHAR uni23D0 +ENCODING 9168 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2409 +ENCODING 9225 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +90 +90 +F0 +90 +90 +00 +7C +10 +10 +10 +10 +00 +ENDCHAR +STARTCHAR uni240A +ENCODING 9226 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +80 +80 +80 +80 +F0 +00 +3C +20 +38 +20 +20 +00 +ENDCHAR +STARTCHAR uni240B +ENCODING 9227 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +88 +88 +88 +50 +20 +00 +7C +10 +10 +10 +10 +00 +ENDCHAR +STARTCHAR uni240C +ENCODING 9228 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +F0 +80 +E0 +80 +80 +00 +3C +20 +38 +20 +20 +00 +ENDCHAR +STARTCHAR uni240D +ENCODING 9229 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +60 +90 +80 +90 +60 +00 +38 +24 +38 +28 +24 +00 +ENDCHAR +STARTCHAR uni2424 +ENCODING 9252 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +90 +D0 +B0 +90 +90 +00 +20 +20 +20 +20 +3C +00 +ENDCHAR +STARTCHAR SF100000 +ENCODING 9472 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +FC +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2501 +ENCODING 9473 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +FC +FC +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF110000 +ENCODING 9474 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2503 +ENCODING 9475 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2508 +ENCODING 9480 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +A8 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2509 +ENCODING 9481 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +A8 +A8 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni250A +ENCODING 9482 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +00 +20 +20 +00 +20 +20 +00 +20 +20 +00 +ENDCHAR +STARTCHAR uni250B +ENCODING 9483 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +00 +30 +30 +00 +30 +30 +00 +30 +30 +00 +ENDCHAR +STARTCHAR SF010000 +ENCODING 9484 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +3C +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni250D +ENCODING 9485 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +3C +3C +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni250E +ENCODING 9486 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +3C +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni250F +ENCODING 9487 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +3C +3C +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR SF030000 +ENCODING 9488 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +E0 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2511 +ENCODING 9489 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +E0 +E0 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2512 +ENCODING 9490 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +F0 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2513 +ENCODING 9491 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +F0 +F0 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR SF020000 +ENCODING 9492 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +3C +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2515 +ENCODING 9493 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +3C +3C +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2516 +ENCODING 9494 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +3C +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2517 +ENCODING 9495 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +3C +3C +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF040000 +ENCODING 9496 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +E0 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2519 +ENCODING 9497 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +E0 +E0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni251A +ENCODING 9498 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +F0 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni251B +ENCODING 9499 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +F0 +F0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF080000 +ENCODING 9500 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +3C +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni251D +ENCODING 9501 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +3C +3C +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni251E +ENCODING 9502 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +3C +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni251F +ENCODING 9503 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +3C +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2520 +ENCODING 9504 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +3C +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2521 +ENCODING 9505 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +3C +3C +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2522 +ENCODING 9506 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +3C +3C +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2523 +ENCODING 9507 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +3C +3C +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR SF090000 +ENCODING 9508 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +E0 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2525 +ENCODING 9509 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +E0 +E0 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2526 +ENCODING 9510 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +F0 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2527 +ENCODING 9511 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +F0 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2528 +ENCODING 9512 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +F0 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2529 +ENCODING 9513 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +F0 +F0 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni252A +ENCODING 9514 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +F0 +F0 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni252B +ENCODING 9515 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +F0 +F0 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR SF060000 +ENCODING 9516 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +FC +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni252D +ENCODING 9517 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +FC +E0 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni252E +ENCODING 9518 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +FC +3C +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni252F +ENCODING 9519 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +FC +FC +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2530 +ENCODING 9520 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +FC +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2531 +ENCODING 9521 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +FC +F0 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2532 +ENCODING 9522 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +FC +3C +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2533 +ENCODING 9523 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +FC +FC +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR SF070000 +ENCODING 9524 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +FC +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2535 +ENCODING 9525 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +FC +E0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2536 +ENCODING 9526 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +FC +3C +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2537 +ENCODING 9527 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +FC +FC +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2538 +ENCODING 9528 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +FC +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2539 +ENCODING 9529 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +FC +F0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni253A +ENCODING 9530 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +FC +3C +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni253B +ENCODING 9531 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +FC +FC +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF050000 +ENCODING 9532 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +FC +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni253D +ENCODING 9533 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +FC +E0 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni253E +ENCODING 9534 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +FC +3C +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni253F +ENCODING 9535 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +FC +FC +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2540 +ENCODING 9536 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +FC +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2541 +ENCODING 9537 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +FC +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2542 +ENCODING 9538 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +FC +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2543 +ENCODING 9539 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +FC +E0 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2544 +ENCODING 9540 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +FC +3C +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2545 +ENCODING 9541 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +FC +F0 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2546 +ENCODING 9542 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +FC +3C +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2547 +ENCODING 9543 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +FC +FC +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2548 +ENCODING 9544 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +FC +FC +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2549 +ENCODING 9545 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +FC +F0 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni254A +ENCODING 9546 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +FC +3C +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni254B +ENCODING 9547 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +FC +FC +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR SF430000 +ENCODING 9552 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +FC +00 +FC +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF240000 +ENCODING 9553 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +50 +50 +50 +50 +50 +50 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF510000 +ENCODING 9554 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +3C +20 +3C +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF520000 +ENCODING 9555 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +7C +50 +50 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF390000 +ENCODING 9556 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +7C +40 +5C +50 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF220000 +ENCODING 9557 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +E0 +20 +E0 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF210000 +ENCODING 9558 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +F0 +50 +50 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF250000 +ENCODING 9559 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +F0 +10 +D0 +50 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF500000 +ENCODING 9560 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +3C +20 +3C +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF490000 +ENCODING 9561 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +50 +50 +50 +7C +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF380000 +ENCODING 9562 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +50 +50 +5C +40 +7C +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF280000 +ENCODING 9563 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +E0 +20 +E0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF270000 +ENCODING 9564 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +50 +50 +50 +F0 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF260000 +ENCODING 9565 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +50 +50 +D0 +10 +F0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF360000 +ENCODING 9566 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +3C +20 +3C +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF370000 +ENCODING 9567 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +50 +50 +50 +5C +50 +50 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF420000 +ENCODING 9568 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +50 +50 +5C +40 +5C +50 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF190000 +ENCODING 9569 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +E0 +20 +E0 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF200000 +ENCODING 9570 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +50 +50 +50 +D0 +50 +50 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF230000 +ENCODING 9571 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +50 +50 +D0 +10 +D0 +50 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF470000 +ENCODING 9572 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +FC +00 +FC +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF480000 +ENCODING 9573 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +FC +50 +50 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF410000 +ENCODING 9574 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +FC +00 +DC +50 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF450000 +ENCODING 9575 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +FC +00 +FC +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF460000 +ENCODING 9576 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +50 +50 +50 +FC +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF400000 +ENCODING 9577 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +50 +50 +DC +00 +FC +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF540000 +ENCODING 9578 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +FC +20 +FC +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF530000 +ENCODING 9579 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +50 +50 +50 +FC +50 +50 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF440000 +ENCODING 9580 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +50 +50 +50 +50 +DC +00 +DC +50 +50 +50 +50 +50 +ENDCHAR +STARTCHAR uni256D +ENCODING 9581 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +0C +10 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni256E +ENCODING 9582 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +80 +40 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni256F +ENCODING 9583 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +40 +80 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2570 +ENCODING 9584 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +10 +0C +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2571 +ENCODING 9585 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +04 +04 +08 +08 +10 +10 +20 +20 +40 +40 +80 +80 +ENDCHAR +STARTCHAR uni2572 +ENCODING 9586 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +80 +80 +40 +40 +20 +20 +10 +10 +08 +08 +04 +04 +ENDCHAR +STARTCHAR uni2573 +ENCODING 9587 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +84 +84 +48 +48 +30 +30 +30 +30 +48 +48 +84 +84 +ENDCHAR +STARTCHAR uni2574 +ENCODING 9588 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +E0 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2575 +ENCODING 9589 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +20 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2576 +ENCODING 9590 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +3C +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2577 +ENCODING 9591 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +20 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2578 +ENCODING 9592 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +E0 +E0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2579 +ENCODING 9593 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +30 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni257A +ENCODING 9594 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +3C +3C +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni257B +ENCODING 9595 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni257C +ENCODING 9596 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +FC +3C +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni257D +ENCODING 9597 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +20 +20 +20 +20 +20 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni257E +ENCODING 9598 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +FC +E0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni257F +ENCODING 9599 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +30 +30 +30 +30 +30 +30 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR upblock +ENCODING 9600 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +FC +FC +FC +FC +FC +FC +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2581 +ENCODING 9601 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +FC +ENDCHAR +STARTCHAR uni2582 +ENCODING 9602 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +FC +FC +FC +ENDCHAR +STARTCHAR uni2583 +ENCODING 9603 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +FC +FC +FC +FC +ENDCHAR +STARTCHAR dnblock +ENCODING 9604 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +FC +FC +FC +FC +FC +FC +ENDCHAR +STARTCHAR uni2585 +ENCODING 9605 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +FC +FC +FC +FC +FC +FC +FC +ENDCHAR +STARTCHAR uni2586 +ENCODING 9606 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +FC +FC +FC +FC +FC +FC +FC +FC +FC +ENDCHAR +STARTCHAR uni2587 +ENCODING 9607 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +FC +FC +FC +FC +FC +FC +FC +FC +FC +FC +ENDCHAR +STARTCHAR block +ENCODING 9608 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +FC +FC +FC +FC +FC +FC +FC +FC +FC +FC +FC +FC +ENDCHAR +STARTCHAR uni2589 +ENCODING 9609 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR uni258A +ENCODING 9610 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +F0 +F0 +F0 +F0 +F0 +F0 +F0 +F0 +F0 +F0 +F0 +F0 +ENDCHAR +STARTCHAR uni258B +ENCODING 9611 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +F0 +F0 +F0 +F0 +F0 +F0 +F0 +F0 +F0 +F0 +F0 +F0 +ENDCHAR +STARTCHAR lfblock +ENCODING 9612 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +E0 +E0 +E0 +E0 +E0 +E0 +E0 +E0 +E0 +E0 +E0 +E0 +ENDCHAR +STARTCHAR uni258D +ENCODING 9613 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR uni258E +ENCODING 9614 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +80 +80 +80 +80 +80 +80 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR uni258F +ENCODING 9615 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +80 +80 +80 +80 +80 +80 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR rtblock +ENCODING 9616 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +1C +1C +1C +1C +1C +1C +1C +1C +1C +1C +1C +1C +ENDCHAR +STARTCHAR ltshade +ENCODING 9617 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +90 +24 +90 +24 +90 +24 +90 +24 +90 +24 +90 +24 +ENDCHAR +STARTCHAR shade +ENCODING 9618 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +A8 +54 +A8 +54 +A8 +54 +A8 +54 +A8 +54 +A8 +54 +ENDCHAR +STARTCHAR dkshade +ENCODING 9619 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +D8 +B4 +D8 +B4 +D8 +B4 +D8 +B4 +D8 +B4 +D8 +B4 +ENDCHAR +STARTCHAR uni2596 +ENCODING 9622 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +E0 +E0 +E0 +E0 +E0 +E0 +ENDCHAR +STARTCHAR uni2597 +ENCODING 9623 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +1C +1C +1C +1C +1C +1C +ENDCHAR +STARTCHAR uni2598 +ENCODING 9624 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +E0 +E0 +E0 +E0 +E0 +E0 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2599 +ENCODING 9625 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +E0 +E0 +E0 +E0 +E0 +E0 +FC +FC +FC +FC +FC +FC +ENDCHAR +STARTCHAR uni259A +ENCODING 9626 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +E0 +E0 +E0 +E0 +E0 +E0 +1C +1C +1C +1C +1C +1C +ENDCHAR +STARTCHAR uni259B +ENCODING 9627 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +FC +FC +FC +FC +FC +FC +E0 +E0 +E0 +E0 +E0 +E0 +ENDCHAR +STARTCHAR uni259C +ENCODING 9628 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +FC +FC +FC +FC +FC +FC +1C +1C +1C +1C +1C +1C +ENDCHAR +STARTCHAR uni259D +ENCODING 9629 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +1C +1C +1C +1C +1C +1C +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni259E +ENCODING 9630 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +1C +1C +1C +1C +1C +1C +E0 +E0 +E0 +E0 +E0 +E0 +ENDCHAR +STARTCHAR uni259F +ENCODING 9631 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +1C +1C +1C +1C +1C +1C +FC +FC +FC +FC +FC +FC +ENDCHAR +STARTCHAR filledbox +ENCODING 9632 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +78 +78 +78 +78 +78 +00 +00 +00 +00 +ENDCHAR +STARTCHAR filledrect +ENCODING 9644 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +F8 +F8 +F8 +00 +00 +ENDCHAR +STARTCHAR uni25AE +ENCODING 9646 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +00 +00 +ENDCHAR +STARTCHAR triagup +ENCODING 9650 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +30 +30 +78 +78 +FC +FC +00 +00 +00 +ENDCHAR +STARTCHAR uni25B6 +ENCODING 9654 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +C0 +F0 +FC +FC +F0 +C0 +00 +00 +00 +ENDCHAR +STARTCHAR triagrt +ENCODING 9658 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +C0 +F0 +FC +FC +F0 +C0 +00 +00 +00 +ENDCHAR +STARTCHAR triagdn +ENCODING 9660 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +FC +FC +78 +78 +30 +30 +00 +00 +00 +ENDCHAR +STARTCHAR uni25C0 +ENCODING 9664 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +0C +3C +FC +FC +3C +0C +00 +00 +00 +ENDCHAR +STARTCHAR triaglf +ENCODING 9668 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +0C +3C +FC +FC +3C +0C +00 +00 +00 +ENDCHAR +STARTCHAR blackdiamond +ENCODING 9670 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +20 +70 +F8 +70 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR lozenge +ENCODING 9674 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +20 +50 +88 +50 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR circle +ENCODING 9675 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +30 +48 +48 +30 +00 +00 +00 +00 +ENDCHAR +STARTCHAR H18533 +ENCODING 9679 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +30 +78 +78 +30 +00 +00 +00 +00 +ENDCHAR +STARTCHAR invbullet +ENCODING 9688 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +FC +FC +FC +FC +CC +84 +84 +CC +FC +FC +FC +FC +ENDCHAR +STARTCHAR invcircle +ENCODING 9689 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +FC +FC +FC +FC +CC +B4 +B4 +CC +FC +FC +FC +FC +ENDCHAR +STARTCHAR smileface +ENCODING 9786 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +78 +84 +CC +84 +B4 +B4 +84 +78 +00 +00 +ENDCHAR +STARTCHAR invsmileface +ENCODING 9787 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +78 +FC +B4 +FC +84 +CC +FC +78 +00 +00 +ENDCHAR +STARTCHAR sun +ENCODING 9788 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +20 +A8 +70 +D8 +70 +A8 +20 +00 +00 +ENDCHAR +STARTCHAR female +ENCODING 9792 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +70 +88 +88 +88 +70 +20 +F8 +20 +00 +00 +ENDCHAR +STARTCHAR male +ENCODING 9794 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +3C +0C +14 +70 +88 +88 +88 +70 +00 +00 +ENDCHAR +STARTCHAR spade +ENCODING 9824 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +20 +70 +F8 +F8 +70 +20 +70 +00 +00 +ENDCHAR +STARTCHAR club +ENCODING 9827 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +20 +70 +20 +A8 +F8 +A8 +20 +70 +00 +00 +ENDCHAR +STARTCHAR heart +ENCODING 9829 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +50 +F8 +F8 +F8 +70 +70 +20 +00 +00 +ENDCHAR +STARTCHAR diamond +ENCODING 9830 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +20 +70 +F8 +70 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR musicalnote +ENCODING 9834 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +78 +48 +78 +40 +40 +40 +40 +80 +00 +00 +ENDCHAR +STARTCHAR musicalnotedbl +ENCODING 9835 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +78 +48 +78 +48 +48 +48 +48 +50 +80 +00 +ENDCHAR +STARTCHAR uni2713 +ENCODING 10003 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +04 +04 +08 +88 +90 +50 +20 +20 +00 +00 +ENDCHAR +STARTCHAR uni2714 +ENCODING 10004 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +0C +0C +18 +D8 +F0 +70 +60 +60 +00 +00 +ENDCHAR +STARTCHAR uni2717 +ENCODING 10007 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +48 +28 +10 +10 +28 +24 +40 +40 +00 +00 +ENDCHAR +STARTCHAR uni2718 +ENCODING 10008 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +18 +D8 +70 +30 +78 +6C +C0 +C0 +00 +00 +ENDCHAR +STARTCHAR uni27E8 +ENCODING 10216 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +10 +10 +20 +20 +40 +20 +20 +10 +10 +00 +00 +ENDCHAR +STARTCHAR uni27E9 +ENCODING 10217 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +40 +40 +20 +20 +10 +20 +20 +40 +40 +00 +00 +ENDCHAR +STARTCHAR uni27EA +ENCODING 10218 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +28 +28 +50 +50 +A0 +50 +50 +28 +28 +00 +00 +ENDCHAR +STARTCHAR uni27EB +ENCODING 10219 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +A0 +A0 +50 +50 +28 +50 +50 +A0 +A0 +00 +00 +ENDCHAR +STARTCHAR uni2800 +ENCODING 10240 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2801 +ENCODING 10241 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2802 +ENCODING 10242 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +40 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2803 +ENCODING 10243 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +40 +40 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2804 +ENCODING 10244 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +40 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2805 +ENCODING 10245 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +00 +00 +00 +40 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2806 +ENCODING 10246 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +40 +00 +40 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2807 +ENCODING 10247 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +40 +40 +00 +40 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2808 +ENCODING 10248 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2809 +ENCODING 10249 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni280A +ENCODING 10250 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +40 +40 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni280B +ENCODING 10251 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +40 +40 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni280C +ENCODING 10252 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +00 +00 +00 +40 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni280D +ENCODING 10253 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +00 +00 +00 +40 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni280E +ENCODING 10254 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +40 +40 +00 +40 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni280F +ENCODING 10255 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +40 +40 +00 +40 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2810 +ENCODING 10256 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +08 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2811 +ENCODING 10257 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +08 +08 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2812 +ENCODING 10258 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +48 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2813 +ENCODING 10259 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +48 +48 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2814 +ENCODING 10260 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +08 +00 +40 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2815 +ENCODING 10261 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +08 +08 +00 +40 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2816 +ENCODING 10262 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +48 +00 +40 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2817 +ENCODING 10263 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +48 +48 +00 +40 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2818 +ENCODING 10264 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +08 +08 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2819 +ENCODING 10265 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +08 +08 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni281A +ENCODING 10266 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +48 +48 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni281B +ENCODING 10267 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +48 +48 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni281C +ENCODING 10268 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +08 +08 +00 +40 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni281D +ENCODING 10269 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +08 +08 +00 +40 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni281E +ENCODING 10270 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +48 +48 +00 +40 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni281F +ENCODING 10271 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +48 +48 +00 +40 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2820 +ENCODING 10272 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +08 +08 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2821 +ENCODING 10273 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +00 +00 +00 +08 +08 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2822 +ENCODING 10274 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +40 +00 +08 +08 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2823 +ENCODING 10275 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +40 +40 +00 +08 +08 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2824 +ENCODING 10276 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +48 +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2825 +ENCODING 10277 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +00 +00 +00 +48 +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2826 +ENCODING 10278 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +40 +00 +48 +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2827 +ENCODING 10279 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +40 +40 +00 +48 +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2828 +ENCODING 10280 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +00 +00 +00 +08 +08 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2829 +ENCODING 10281 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +00 +00 +00 +08 +08 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni282A +ENCODING 10282 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +40 +40 +00 +08 +08 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni282B +ENCODING 10283 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +40 +40 +00 +08 +08 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni282C +ENCODING 10284 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +00 +00 +00 +48 +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni282D +ENCODING 10285 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +00 +00 +00 +48 +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni282E +ENCODING 10286 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +40 +40 +00 +48 +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni282F +ENCODING 10287 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +40 +40 +00 +48 +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2830 +ENCODING 10288 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +08 +00 +08 +08 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2831 +ENCODING 10289 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +08 +08 +00 +08 +08 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2832 +ENCODING 10290 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +48 +00 +08 +08 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2833 +ENCODING 10291 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +48 +48 +00 +08 +08 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2834 +ENCODING 10292 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +08 +00 +48 +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2835 +ENCODING 10293 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +08 +08 +00 +48 +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2836 +ENCODING 10294 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +48 +00 +48 +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2837 +ENCODING 10295 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +48 +48 +00 +48 +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2838 +ENCODING 10296 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +08 +08 +00 +08 +08 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2839 +ENCODING 10297 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +08 +08 +00 +08 +08 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni283A +ENCODING 10298 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +48 +48 +00 +08 +08 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni283B +ENCODING 10299 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +48 +48 +00 +08 +08 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni283C +ENCODING 10300 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +08 +08 +00 +48 +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni283D +ENCODING 10301 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +08 +08 +00 +48 +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni283E +ENCODING 10302 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +48 +48 +00 +48 +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni283F +ENCODING 10303 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +48 +48 +00 +48 +48 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2840 +ENCODING 10304 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2841 +ENCODING 10305 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +00 +00 +00 +00 +00 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2842 +ENCODING 10306 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +40 +00 +00 +00 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2843 +ENCODING 10307 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +40 +40 +00 +00 +00 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2844 +ENCODING 10308 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +40 +40 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2845 +ENCODING 10309 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +00 +00 +00 +40 +40 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2846 +ENCODING 10310 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +40 +00 +40 +40 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2847 +ENCODING 10311 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +40 +40 +00 +40 +40 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2848 +ENCODING 10312 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +00 +00 +00 +00 +00 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2849 +ENCODING 10313 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +00 +00 +00 +00 +00 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni284A +ENCODING 10314 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +40 +40 +00 +00 +00 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni284B +ENCODING 10315 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +40 +40 +00 +00 +00 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni284C +ENCODING 10316 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +00 +00 +00 +40 +40 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni284D +ENCODING 10317 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +00 +00 +00 +40 +40 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni284E +ENCODING 10318 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +40 +40 +00 +40 +40 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni284F +ENCODING 10319 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +40 +40 +00 +40 +40 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2850 +ENCODING 10320 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +08 +00 +00 +00 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2851 +ENCODING 10321 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +08 +08 +00 +00 +00 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2852 +ENCODING 10322 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +48 +00 +00 +00 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2853 +ENCODING 10323 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +48 +48 +00 +00 +00 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2854 +ENCODING 10324 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +08 +00 +40 +40 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2855 +ENCODING 10325 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +08 +08 +00 +40 +40 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2856 +ENCODING 10326 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +48 +00 +40 +40 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2857 +ENCODING 10327 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +48 +48 +00 +40 +40 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2858 +ENCODING 10328 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +08 +08 +00 +00 +00 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2859 +ENCODING 10329 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +08 +08 +00 +00 +00 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni285A +ENCODING 10330 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +48 +48 +00 +00 +00 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni285B +ENCODING 10331 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +48 +48 +00 +00 +00 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni285C +ENCODING 10332 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +08 +08 +00 +40 +40 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni285D +ENCODING 10333 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +08 +08 +00 +40 +40 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni285E +ENCODING 10334 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +48 +48 +00 +40 +40 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni285F +ENCODING 10335 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +48 +48 +00 +40 +40 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2860 +ENCODING 10336 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +08 +08 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2861 +ENCODING 10337 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +00 +00 +00 +08 +08 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2862 +ENCODING 10338 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +40 +00 +08 +08 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2863 +ENCODING 10339 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +40 +40 +00 +08 +08 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2864 +ENCODING 10340 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +48 +48 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2865 +ENCODING 10341 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +00 +00 +00 +48 +48 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2866 +ENCODING 10342 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +40 +00 +48 +48 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2867 +ENCODING 10343 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +40 +40 +00 +48 +48 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2868 +ENCODING 10344 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +00 +00 +00 +08 +08 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2869 +ENCODING 10345 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +00 +00 +00 +08 +08 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni286A +ENCODING 10346 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +40 +40 +00 +08 +08 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni286B +ENCODING 10347 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +40 +40 +00 +08 +08 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni286C +ENCODING 10348 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +00 +00 +00 +48 +48 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni286D +ENCODING 10349 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +00 +00 +00 +48 +48 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni286E +ENCODING 10350 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +40 +40 +00 +48 +48 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni286F +ENCODING 10351 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +40 +40 +00 +48 +48 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2870 +ENCODING 10352 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +08 +00 +08 +08 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2871 +ENCODING 10353 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +08 +08 +00 +08 +08 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2872 +ENCODING 10354 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +48 +00 +08 +08 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2873 +ENCODING 10355 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +48 +48 +00 +08 +08 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2874 +ENCODING 10356 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +08 +00 +48 +48 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2875 +ENCODING 10357 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +08 +08 +00 +48 +48 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2876 +ENCODING 10358 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +48 +00 +48 +48 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2877 +ENCODING 10359 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +48 +48 +00 +48 +48 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2878 +ENCODING 10360 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +08 +08 +00 +08 +08 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2879 +ENCODING 10361 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +08 +08 +00 +08 +08 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni287A +ENCODING 10362 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +48 +48 +00 +08 +08 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni287B +ENCODING 10363 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +48 +48 +00 +08 +08 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni287C +ENCODING 10364 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +08 +08 +00 +48 +48 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni287D +ENCODING 10365 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +08 +08 +00 +48 +48 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni287E +ENCODING 10366 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +48 +48 +00 +48 +48 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni287F +ENCODING 10367 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +48 +48 +00 +48 +48 +00 +40 +40 +00 +ENDCHAR +STARTCHAR uni2880 +ENCODING 10368 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2881 +ENCODING 10369 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +00 +00 +00 +00 +00 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2882 +ENCODING 10370 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +40 +00 +00 +00 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2883 +ENCODING 10371 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +40 +40 +00 +00 +00 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2884 +ENCODING 10372 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +40 +40 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2885 +ENCODING 10373 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +00 +00 +00 +40 +40 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2886 +ENCODING 10374 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +40 +00 +40 +40 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2887 +ENCODING 10375 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +40 +40 +00 +40 +40 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2888 +ENCODING 10376 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +00 +00 +00 +00 +00 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2889 +ENCODING 10377 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +00 +00 +00 +00 +00 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni288A +ENCODING 10378 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +40 +40 +00 +00 +00 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni288B +ENCODING 10379 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +40 +40 +00 +00 +00 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni288C +ENCODING 10380 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +00 +00 +00 +40 +40 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni288D +ENCODING 10381 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +00 +00 +00 +40 +40 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni288E +ENCODING 10382 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +40 +40 +00 +40 +40 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni288F +ENCODING 10383 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +40 +40 +00 +40 +40 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2890 +ENCODING 10384 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +08 +00 +00 +00 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2891 +ENCODING 10385 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +08 +08 +00 +00 +00 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2892 +ENCODING 10386 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +48 +00 +00 +00 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2893 +ENCODING 10387 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +48 +48 +00 +00 +00 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2894 +ENCODING 10388 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +08 +00 +40 +40 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2895 +ENCODING 10389 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +08 +08 +00 +40 +40 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2896 +ENCODING 10390 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +48 +00 +40 +40 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2897 +ENCODING 10391 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +48 +48 +00 +40 +40 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2898 +ENCODING 10392 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +08 +08 +00 +00 +00 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni2899 +ENCODING 10393 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +08 +08 +00 +00 +00 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni289A +ENCODING 10394 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +48 +48 +00 +00 +00 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni289B +ENCODING 10395 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +48 +48 +00 +00 +00 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni289C +ENCODING 10396 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +08 +08 +00 +40 +40 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni289D +ENCODING 10397 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +08 +08 +00 +40 +40 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni289E +ENCODING 10398 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +48 +48 +00 +40 +40 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni289F +ENCODING 10399 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +48 +48 +00 +40 +40 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28A0 +ENCODING 10400 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +08 +08 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28A1 +ENCODING 10401 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +00 +00 +00 +08 +08 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28A2 +ENCODING 10402 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +40 +00 +08 +08 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28A3 +ENCODING 10403 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +40 +40 +00 +08 +08 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28A4 +ENCODING 10404 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +48 +48 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28A5 +ENCODING 10405 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +00 +00 +00 +48 +48 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28A6 +ENCODING 10406 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +40 +00 +48 +48 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28A7 +ENCODING 10407 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +40 +40 +00 +48 +48 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28A8 +ENCODING 10408 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +00 +00 +00 +08 +08 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28A9 +ENCODING 10409 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +00 +00 +00 +08 +08 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28AA +ENCODING 10410 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +40 +40 +00 +08 +08 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28AB +ENCODING 10411 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +40 +40 +00 +08 +08 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28AC +ENCODING 10412 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +00 +00 +00 +48 +48 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28AD +ENCODING 10413 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +00 +00 +00 +48 +48 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28AE +ENCODING 10414 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +40 +40 +00 +48 +48 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28AF +ENCODING 10415 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +40 +40 +00 +48 +48 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28B0 +ENCODING 10416 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +08 +00 +08 +08 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28B1 +ENCODING 10417 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +08 +08 +00 +08 +08 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28B2 +ENCODING 10418 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +48 +00 +08 +08 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28B3 +ENCODING 10419 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +48 +48 +00 +08 +08 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28B4 +ENCODING 10420 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +08 +00 +48 +48 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28B5 +ENCODING 10421 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +08 +08 +00 +48 +48 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28B6 +ENCODING 10422 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +48 +00 +48 +48 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28B7 +ENCODING 10423 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +48 +48 +00 +48 +48 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28B8 +ENCODING 10424 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +08 +08 +00 +08 +08 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28B9 +ENCODING 10425 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +08 +08 +00 +08 +08 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28BA +ENCODING 10426 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +48 +48 +00 +08 +08 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28BB +ENCODING 10427 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +48 +48 +00 +08 +08 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28BC +ENCODING 10428 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +08 +08 +00 +48 +48 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28BD +ENCODING 10429 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +08 +08 +00 +48 +48 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28BE +ENCODING 10430 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +48 +48 +00 +48 +48 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28BF +ENCODING 10431 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +48 +48 +00 +48 +48 +00 +08 +08 +00 +ENDCHAR +STARTCHAR uni28C0 +ENCODING 10432 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28C1 +ENCODING 10433 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +00 +00 +00 +00 +00 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28C2 +ENCODING 10434 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +40 +00 +00 +00 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28C3 +ENCODING 10435 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +40 +40 +00 +00 +00 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28C4 +ENCODING 10436 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +40 +40 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28C5 +ENCODING 10437 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +00 +00 +00 +40 +40 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28C6 +ENCODING 10438 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +40 +00 +40 +40 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28C7 +ENCODING 10439 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +40 +40 +00 +40 +40 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28C8 +ENCODING 10440 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +00 +00 +00 +00 +00 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28C9 +ENCODING 10441 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +00 +00 +00 +00 +00 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28CA +ENCODING 10442 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +40 +40 +00 +00 +00 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28CB +ENCODING 10443 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +40 +40 +00 +00 +00 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28CC +ENCODING 10444 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +00 +00 +00 +40 +40 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28CD +ENCODING 10445 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +00 +00 +00 +40 +40 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28CE +ENCODING 10446 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +40 +40 +00 +40 +40 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28CF +ENCODING 10447 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +40 +40 +00 +40 +40 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28D0 +ENCODING 10448 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +08 +00 +00 +00 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28D1 +ENCODING 10449 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +08 +08 +00 +00 +00 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28D2 +ENCODING 10450 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +48 +00 +00 +00 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28D3 +ENCODING 10451 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +48 +48 +00 +00 +00 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28D4 +ENCODING 10452 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +08 +00 +40 +40 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28D5 +ENCODING 10453 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +08 +08 +00 +40 +40 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28D6 +ENCODING 10454 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +48 +00 +40 +40 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28D7 +ENCODING 10455 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +48 +48 +00 +40 +40 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28D8 +ENCODING 10456 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +08 +08 +00 +00 +00 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28D9 +ENCODING 10457 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +08 +08 +00 +00 +00 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28DA +ENCODING 10458 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +48 +48 +00 +00 +00 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28DB +ENCODING 10459 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +48 +48 +00 +00 +00 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28DC +ENCODING 10460 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +08 +08 +00 +40 +40 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28DD +ENCODING 10461 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +08 +08 +00 +40 +40 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28DE +ENCODING 10462 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +48 +48 +00 +40 +40 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28DF +ENCODING 10463 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +48 +48 +00 +40 +40 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28E0 +ENCODING 10464 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +08 +08 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28E1 +ENCODING 10465 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +00 +00 +00 +08 +08 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28E2 +ENCODING 10466 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +40 +00 +08 +08 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28E3 +ENCODING 10467 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +40 +40 +00 +08 +08 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28E4 +ENCODING 10468 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +48 +48 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28E5 +ENCODING 10469 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +00 +00 +00 +48 +48 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28E6 +ENCODING 10470 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +40 +40 +00 +48 +48 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28E7 +ENCODING 10471 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +40 +40 +00 +48 +48 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28E8 +ENCODING 10472 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +00 +00 +00 +08 +08 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28E9 +ENCODING 10473 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +00 +00 +00 +08 +08 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28EA +ENCODING 10474 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +40 +40 +00 +08 +08 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28EB +ENCODING 10475 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +40 +40 +00 +08 +08 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28EC +ENCODING 10476 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +00 +00 +00 +48 +48 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28ED +ENCODING 10477 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +00 +00 +00 +48 +48 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28EE +ENCODING 10478 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +40 +40 +00 +48 +48 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28EF +ENCODING 10479 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +40 +40 +00 +48 +48 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28F0 +ENCODING 10480 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +08 +00 +08 +08 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28F1 +ENCODING 10481 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +08 +08 +00 +08 +08 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28F2 +ENCODING 10482 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +48 +00 +08 +08 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28F3 +ENCODING 10483 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +48 +48 +00 +08 +08 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28F4 +ENCODING 10484 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +08 +08 +00 +48 +48 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28F5 +ENCODING 10485 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +08 +08 +00 +48 +48 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28F6 +ENCODING 10486 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +48 +48 +00 +48 +48 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28F7 +ENCODING 10487 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +40 +40 +00 +48 +48 +00 +48 +48 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28F8 +ENCODING 10488 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +08 +08 +00 +08 +08 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28F9 +ENCODING 10489 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +08 +08 +00 +08 +08 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28FA +ENCODING 10490 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +48 +48 +00 +08 +08 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28FB +ENCODING 10491 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +48 +48 +00 +08 +08 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28FC +ENCODING 10492 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +08 +08 +00 +48 +48 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28FD +ENCODING 10493 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +08 +08 +00 +48 +48 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28FE +ENCODING 10494 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +08 +08 +00 +48 +48 +00 +48 +48 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni28FF +ENCODING 10495 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +48 +48 +00 +48 +48 +00 +48 +48 +00 +48 +48 +00 +ENDCHAR +STARTCHAR uni2E2C +ENCODING 11820 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +88 +88 +00 +00 +88 +88 +00 +00 +ENDCHAR +STARTCHAR uniE0A0 +ENCODING 57504 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +80 +90 +B8 +90 +90 +90 +20 +40 +80 +80 +80 +80 +ENDCHAR +STARTCHAR uniE0A1 +ENCODING 57505 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +80 +80 +80 +80 +F0 +00 +24 +34 +2C +24 +24 +00 +ENDCHAR +STARTCHAR uniE0A2 +ENCODING 57506 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +30 +48 +48 +48 +FC +FC +CC +CC +FC +FC +00 +ENDCHAR +STARTCHAR uniE0B0 +ENCODING 57520 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +80 +C0 +E0 +F0 +F8 +FC +FC +F8 +F0 +E0 +C0 +80 +ENDCHAR +STARTCHAR uniE0B1 +ENCODING 57521 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +80 +40 +20 +10 +08 +04 +04 +08 +10 +20 +40 +80 +ENDCHAR +STARTCHAR uniE0B2 +ENCODING 57522 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +04 +0C +1C +3C +7C +FC +FC +7C +3C +1C +0C +04 +ENDCHAR +STARTCHAR uniE0B3 +ENCODING 57523 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +04 +08 +10 +20 +40 +80 +80 +40 +20 +10 +08 +04 +ENDCHAR +STARTCHAR uniF6BE +ENCODING 63166 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +00 +00 +18 +08 +08 +08 +08 +08 +48 +30 +ENDCHAR +STARTCHAR uniFFFD +ENCODING 65533 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 6 12 0 -2 +BITMAP +00 +00 +F8 +88 +88 +88 +88 +88 +88 +F8 +00 +00 +ENDCHAR +ENDFONT diff --git a/tools/gc_activity.html b/tools/gc_activity.html new file mode 100644 index 00000000000..ec0ccbf884a --- /dev/null +++ b/tools/gc_activity.html @@ -0,0 +1,137 @@ + + + + + + + + + + + + diff --git a/tools/gc_activity.md b/tools/gc_activity.md new file mode 100644 index 00000000000..d1a4c280319 --- /dev/null +++ b/tools/gc_activity.md @@ -0,0 +1,198 @@ +# GC Analysis + +Here are some terse instructions on doing heap analysis via gdb. + +First, build your port with `LOG_HEAP_ACTIVITY` defined and load it onto your +board. This will enable calls to a gc log function that isn't inlined so it uses +only one breakpoint. + +Next, double check that the `break gc.c:110` line in `output_gc_until_repl.txt` +has the correct line number. Also make sure the tar ext line connects to the +correct port. GDB is usually :3333 and JLink is :2331. + +Now, run gdb from your port directory: + +``` +arm-none-eabi-gdb -x ../tools/output_gc_until_repl.txt build-metro_m0_express/firmware.elf +``` + +This will take a little time while it breaks, backtraces and continues for every +gc change until the repl. At the end it will have a `mylog.txt` file. + +To analyze that file run: +``` +python3 ../tools/gc_activity.py mylog.txt +``` + +It will create a file `allocation_history.json` which documents the lifespan of +the allocations. It also outputs a tree of the current number of blocks +allocated by a piece of code such as: +``` +main.c:298 main 5 blocks + main.c:159 reset_mp 2 blocks + ../py/runtime.c:81 mp_init 2 blocks + ../py/objmodule.c:227 mp_module_init 2 blocks + ../py/objdict.c:595 mp_obj_dict_init 2 blocks + ../py/map.c:79 mp_map_init 2 blocks + main.c:160 reset_mp 1 blocks + ../py/objlist.c:458 mp_obj_list_init 1 blocks + main.c:164 reset_mp 1 blocks + ../py/objlist.c:458 mp_obj_list_init 1 blocks + main.c:166 reset_mp 1 blocks + ../py/objexcept.c:297 mp_obj_new_exception 1 blocks + ../py/objexcept.c:307 mp_obj_new_exception_args 1 blocks + ../py/objexcept.c:130 mp_obj_exception_make_new 1 blocks +main.c:311 main 289 blocks + main.c:211 start_mp 14 blocks + main.c:196 maybe_run 14 blocks + ../lib/utils/pyexec.c:501 pyexec_file 14 blocks + main.c:352 mp_lexer_new_from_file 14 blocks + ../py/../extmod/vfs_fat_lexer.c:80 fat_vfs_lexer_new_from_file 14 blocks + ../py/qstr.c:184 qstr_from_str 14 blocks + ../py/qstr.c:216 qstr_from_strn 8 blocks + ../py/qstr.c:240 qstr_from_strn 6 blocks + ../py/qstr.c:146 qstr_add 6 blocks + main.c:220 start_mp 275 blocks + main.c:196 maybe_run 275 blocks + ../lib/utils/pyexec.c:508 pyexec_file 275 blocks + ../lib/utils/pyexec.c:82 parse_compile_execute 4 blocks + ../py/compile.c:3511 mp_compile 3 blocks + ../py/compile.c:3451 mp_compile_to_raw_code 3 blocks + ../py/compile.c:3092 compile_scope 3 blocks + ../py/emitbc.c:419 mp_emit_bc_end_pass 3 blocks + ../py/compile.c:3513 mp_compile 1 blocks + ../py/emitglue.c:131 mp_make_function_from_raw_code 1 blocks + ../py/objfun.c:364 mp_obj_new_fun_bc 1 blocks + ../lib/utils/pyexec.c:88 parse_compile_execute 271 blocks + ../py/runtime.c:551 mp_call_function_0 271 blocks + ../py/runtime.c:577 mp_call_function_n_kw 271 blocks + ../py/objfun.c:275 fun_bc_call 271 blocks + ../py/vm.c:1161 mp_execute_bytecode 269 blocks + ../py/runtime.c:1315 mp_import_name 269 blocks + ../py/builtinimport.c:442 mp_builtin___import__ 2 blocks + ../py/objmodule.c:113 mp_obj_new_module 1 blocks + ../py/objmodule.c:115 mp_obj_new_module 1 blocks + ../py/objdict.c:599 mp_obj_new_dict 1 blocks + ../py/builtinimport.c:473 mp_builtin___import__ 267 blocks + ../py/builtinimport.c:230 do_load 140 blocks + ../py/emitglue.c:469 mp_raw_code_load_file 140 blocks + ../py/emitglue.c:356 mp_raw_code_load 140 blocks + ../py/emitglue.c:320 load_raw_code 8 blocks + ../py/emitglue.c:295 load_bytecode_qstrs 8 blocks + ../py/emitglue.c:265 load_qstr 8 blocks + ../py/qstr.c:216 qstr_from_strn 8 blocks + ../py/emitglue.c:331 load_raw_code 2 blocks + ../py/emitglue.c:277 load_obj 1 blocks + ../py/vstr.c:53 vstr_init_len 1 blocks + ../py/vstr.c:46 vstr_init 1 blocks + ../py/emitglue.c:280 load_obj 1 blocks + ../py/objstr.c:2001 mp_obj_new_str_from_vstr 1 blocks + ../py/emitglue.c:334 load_raw_code 130 blocks + ../py/emitglue.c:306 load_raw_code 6 blocks + ../py/emitglue.c:325 load_raw_code 4 blocks + ../py/emitglue.c:328 load_raw_code 19 blocks + ../py/emitglue.c:265 load_qstr 19 blocks + ../py/qstr.c:216 qstr_from_strn 8 blocks + ../py/qstr.c:240 qstr_from_strn 11 blocks + ../py/qstr.c:146 qstr_add 11 blocks + ../py/emitglue.c:334 load_raw_code 101 blocks + ../py/emitglue.c:306 load_raw_code 80 blocks + ../py/emitglue.c:320 load_raw_code 8 blocks + ../py/emitglue.c:295 load_bytecode_qstrs 8 blocks + ../py/emitglue.c:265 load_qstr 8 blocks + ../py/qstr.c:216 qstr_from_strn 8 blocks + ../py/emitglue.c:325 load_raw_code 13 blocks + ../py/builtinimport.c:231 do_load 127 blocks + ../py/builtinimport.c:181 do_execute_raw_code 127 blocks + ../py/runtime.c:551 mp_call_function_0 127 blocks + ../py/runtime.c:577 mp_call_function_n_kw 127 blocks + ../py/objfun.c:275 fun_bc_call 127 blocks + ../py/vm.c:400 mp_execute_bytecode 6 blocks + ../py/runtime.c:168 mp_store_name 6 blocks + ../py/objdict.c:612 mp_obj_dict_store 6 blocks + ../py/map.c:283 mp_map_lookup 6 blocks + ../py/map.c:130 mp_map_rehash 6 blocks + ../py/vm.c:847 mp_execute_bytecode 2 blocks + ../py/emitglue.c:131 mp_make_function_from_raw_code 2 blocks + ../py/objfun.c:364 mp_obj_new_fun_bc 2 blocks + ../py/vm.c:855 mp_execute_bytecode 3 blocks + ../py/emitglue.c:131 mp_make_function_from_raw_code 3 blocks + ../py/objfun.c:364 mp_obj_new_fun_bc 3 blocks + ../py/vm.c:903 mp_execute_bytecode 110 blocks + ../py/runtime.c:577 mp_call_function_n_kw 110 blocks + ../py/objfun.c:129 fun_builtin_var_call 110 blocks + ../py/modbuiltins.c:56 mp_builtin___build_class__ 5 blocks + ../py/objdict.c:599 mp_obj_new_dict 5 blocks + ../py/modbuiltins.c:60 mp_builtin___build_class__ 84 blocks + ../py/runtime.c:551 mp_call_function_0 84 blocks + ../py/runtime.c:577 mp_call_function_n_kw 84 blocks + ../py/objfun.c:275 fun_bc_call 84 blocks + ../py/vm.c:400 mp_execute_bytecode 17 blocks + ../py/runtime.c:168 mp_store_name 17 blocks + ../py/objdict.c:612 mp_obj_dict_store 17 blocks + ../py/map.c:283 mp_map_lookup 17 blocks + ../py/map.c:130 mp_map_rehash 17 blocks + ../py/vm.c:847 mp_execute_bytecode 9 blocks + ../py/emitglue.c:131 mp_make_function_from_raw_code 9 blocks + ../py/objfun.c:364 mp_obj_new_fun_bc 9 blocks + ../py/vm.c:855 mp_execute_bytecode 8 blocks + ../py/emitglue.c:131 mp_make_function_from_raw_code 8 blocks + ../py/objfun.c:364 mp_obj_new_fun_bc 8 blocks + ../py/vm.c:903 mp_execute_bytecode 50 blocks + ../py/runtime.c:577 mp_call_function_n_kw 50 blocks + ../py/objboundmeth.c:69 bound_meth_call 1 blocks + ../py/runtime.c:577 mp_call_function_n_kw 1 blocks + ../py/objfun.c:86 fun_builtin_2_call 1 blocks + ../py/objproperty.c:66 property_setter 1 blocks + ../py/objtype.c:816 type_call 49 blocks + ../py/objtype.c:248 mp_obj_instance_make_new 7 blocks + ../py/objtype.c:52 mp_obj_new_instance 7 blocks + ../py/objtype.c:312 mp_obj_instance_make_new 42 blocks + ../py/runtime.c:594 mp_call_method_n_kw 42 blocks + ../py/runtime.c:577 mp_call_function_n_kw 42 blocks + ../py/objfun.c:275 fun_bc_call 42 blocks + ../py/vm.c:381 mp_execute_bytecode 14 blocks + ../py/obj.c:442 mp_obj_subscr 14 blocks + ../py/objarray.c:461 array_subscr 14 blocks + ../py/vm.c:415 mp_execute_bytecode 14 blocks + ../py/runtime.c:1083 mp_store_attr 14 blocks + ../py/objtype.c:645 mp_obj_instance_attr 14 blocks + ../py/objtype.c:636 mp_obj_instance_store_attr 14 blocks + ../py/map.c:283 mp_map_lookup 14 blocks + ../py/map.c:130 mp_map_rehash 14 blocks + ../py/vm.c:903 mp_execute_bytecode 14 blocks + ../py/runtime.c:577 mp_call_function_n_kw 14 blocks + ../py/objtype.c:816 type_call 14 blocks + ../py/objarray.c:192 bytearray_make_new 14 blocks + ../py/objarray.c:100 array_new 7 blocks + ../py/objarray.c:111 array_new 7 blocks + ../py/modbuiltins.c:80 mp_builtin___build_class__ 1 blocks + ../py/objtuple.c:242 mp_obj_new_tuple 1 blocks + ../py/modbuiltins.c:82 mp_builtin___build_class__ 20 blocks + ../py/runtime.c:577 mp_call_function_n_kw 20 blocks + ../py/objtype.c:816 type_call 20 blocks + ../py/objtype.c:794 type_make_new 20 blocks + ../py/objtype.c:904 mp_obj_new_type 20 blocks + ../py/vm.c:974 mp_execute_bytecode 6 blocks + ../py/runtime.c:594 mp_call_method_n_kw 6 blocks + ../py/runtime.c:577 mp_call_function_n_kw 6 blocks + ../py/objfun.c:86 fun_builtin_2_call 6 blocks + ../py/objnamedtuple.c:169 new_namedtuple_type 6 blocks + ../py/objnamedtuple.c:140 mp_obj_new_namedtuple_type 6 blocks + ../py/vm.c:400 mp_execute_bytecode 2 blocks + ../py/runtime.c:168 mp_store_name 2 blocks + ../py/objdict.c:612 mp_obj_dict_store 2 blocks + ../py/map.c:283 mp_map_lookup 2 blocks + ../py/map.c:130 mp_map_rehash 2 blocks +main.c:321 main 2 blocks + ../lib/utils/pyexec.c:374 pyexec_friendly_repl 2 blocks + ../py/vstr.c:46 vstr_init 2 blocks +296 total blocks +``` + +To load the json file in the browser install http-server with npm +(`npm install -g http-server`) and run it from the `micropython` directory with +`http-server`. + +Navigate to `https://127.0.0.1/tools/gc_activity.html` to see the data. (You +will likely need to edit the html to point to the right place for your file.) diff --git a/tools/gc_activity.py b/tools/gc_activity.py new file mode 100644 index 00000000000..8d172ea3abd --- /dev/null +++ b/tools/gc_activity.py @@ -0,0 +1,94 @@ +import sys +import json + +# Map start block to current allocation info. +current_heap = {} +allocation_history = [] +root = {} + +def change_root(trace, size): + level = root + for frame in reversed(trace): + file_location = frame[1] + if file_location not in level: + level[file_location] = {"blocks": 0, + "file": file_location, + "function": frame[2], + "subcalls": {}} + level[file_location]["blocks"] += size + level = level[file_location]["subcalls"] + +total_actions = 0 +with open(sys.argv[1], "r") as f: + for line in f: + if not line.strip(): + break + for line in f: + action = None + if line.startswith("Breakpoint 2"): + break + next(f) # throw away breakpoint code line + next(f) # first frame + block = 0 + size = 0 + trace = [] + for line in f: + #print(line.strip()) + if line[0] == "#": + frame = line.strip().split() + if frame[1].startswith("0x"): + trace.append((frame[1], frame[-1], frame[3])) + else: + trace.append(("0x0", frame[-1], frame[1])) + elif line[0] == "$": + block = int(line.strip().split()[-1][2:], 16) + size = int(next(f).strip().split()[-1][2:], 16) + if not line.strip(): + break + + action = "unknown" + if block not in current_heap: + current_heap[block] = {"start_block": block, "size": size, "start_trace": trace, "start_time": total_actions} + action = "alloc" + change_root(trace, size) + else: + alloc = current_heap[block] + alloc["end_trace"] = trace + alloc["end_time"] = total_actions + change_root(alloc["start_trace"], -1 * alloc["size"]) + if size > 0: + action = "realloc" + current_heap[block] = {"start_block": block, "size": size, "start_trace": trace, "start_time": total_actions} + change_root(trace, size) + else: + action = "free" + if trace[0][2] == "gc_sweep": + action = "sweep" + del current_heap[block] + alloc["end_cause"] = action + allocation_history.append(alloc) + print(total_actions, action, block, size) + total_actions += 1 + +print() + +for alloc in current_heap.values(): + alloc["end_trace"] = "" + alloc["end_time"] = total_actions + allocation_history.append(alloc) + +def print_frame(frame, indent=0): + for key in sorted(frame): + if not frame[key]["blocks"] or key.startswith("../py/malloc.c") or key.startswith("../py/gc.c"): + continue + print(" " * (indent - 1), key, frame[key]["function"], frame[key]["blocks"], "blocks") + print_frame(frame[key]["subcalls"], indent + 2) + +print_frame(root) +total_blocks = 0 +for key in sorted(root): + total_blocks += root[key]["blocks"] +print(total_blocks, "total blocks") + +with open("allocation_history.json", "w") as f: + json.dump(allocation_history, f) diff --git a/tools/gen-cpydiff.py b/tools/gen-cpydiff.py deleted file mode 100644 index 8aef3751493..00000000000 --- a/tools/gen-cpydiff.py +++ /dev/null @@ -1,226 +0,0 @@ -# This file is part of the MicroPython project, http://micropython.org/ -# -# The MIT License (MIT) -# -# Copyright (c) 2016 Rami Ali -# -# 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. - -""" gen-cpydiff generates documentation which outlines operations that differ between MicroPython - and CPython. This script is called by the docs Makefile for html and Latex and may be run - manually using the command make gen-cpydiff. """ - -import os -import errno -import subprocess -import time -import re -from collections import namedtuple - -# MicroPython supports syntax of CPython 3.4 with some features from 3.5, and -# such version should be used to test for differences. If your default python3 -# executable is of lower version, you can point MICROPY_CPYTHON3 environment var -# to the correct executable. -if os.name == 'nt': - CPYTHON3 = os.getenv('MICROPY_CPYTHON3', 'python3.exe') - MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../ports/windows/micropython.exe') -else: - CPYTHON3 = os.getenv('MICROPY_CPYTHON3', 'python3') - MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../ports/unix/micropython') - -TESTPATH = '../tests/cpydiff/' -DOCPATH = '../docs/genrst/' -INDEXTEMPLATE = '../docs/differences/index_template.txt' -INDEX = 'index.rst' - -HEADER = '.. This document was generated by tools/gen-cpydiff.py\n\n' -UIMPORTLIST = {'struct', 'collections', 'json'} -CLASSMAP = {'Core': 'Core Language', 'Types': 'Builtin Types'} -INDEXPRIORITY = ['syntax', 'core_language', 'builtin_types', 'modules'] -RSTCHARS = ['=', '-', '~', '`', ':'] -SPLIT = '"""\n|categories: |description: |cause: |workaround: ' -TAB = ' ' - -Output = namedtuple('output', ['name', 'class_', 'desc', 'cause', 'workaround', 'code', - 'output_cpy', 'output_upy', 'status']) - -def readfiles(): - """ Reads test files """ - tests = list(filter(lambda x: x.endswith('.py'), os.listdir(TESTPATH))) - tests.sort() - files = [] - - for test in tests: - text = open(TESTPATH + test, 'r').read() - - try: - class_, desc, cause, workaround, code = [x.rstrip() for x in \ - list(filter(None, re.split(SPLIT, text)))] - output = Output(test, class_, desc, cause, workaround, code, '', '', '') - files.append(output) - except IndexError: - print('Incorrect format in file ' + TESTPATH + test) - - return files - -def uimports(code): - """ converts CPython module names into MicroPython equivalents """ - for uimport in UIMPORTLIST: - uimport = bytes(uimport, 'utf8') - code = code.replace(uimport, b'u' + uimport) - return code - -def run_tests(tests): - """ executes all tests """ - results = [] - for test in tests: - with open(TESTPATH + test.name, 'rb') as f: - input_cpy = f.read() - input_upy = uimports(input_cpy) - - process = subprocess.Popen(CPYTHON3, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) - output_cpy = [com.decode('utf8') for com in process.communicate(input_cpy)] - - process = subprocess.Popen(MICROPYTHON, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) - output_upy = [com.decode('utf8') for com in process.communicate(input_upy)] - - if output_cpy[0] == output_upy[0] and output_cpy[1] == output_upy[1]: - status = 'Supported' - print('Supported operation!\nFile: ' + TESTPATH + test.name) - else: - status = 'Unsupported' - - output = Output(test.name, test.class_, test.desc, test.cause, - test.workaround, test.code, output_cpy, output_upy, status) - results.append(output) - - results.sort(key=lambda x: x.class_) - return results - -def indent(block, spaces): - """ indents paragraphs of text for rst formatting """ - new_block = '' - for line in block.split('\n'): - new_block += spaces + line + '\n' - return new_block - -def gen_table(contents): - """ creates a table given any set of columns """ - xlengths = [] - ylengths = [] - for column in contents: - col_len = 0 - for entry in column: - lines = entry.split('\n') - for line in lines: - col_len = max(len(line) + 2, col_len) - xlengths.append(col_len) - for i in range(len(contents[0])): - ymax = 0 - for j in range(len(contents)): - ymax = max(ymax, len(contents[j][i].split('\n'))) - ylengths.append(ymax) - - table_divider = '+' + ''.join(['-' * i + '+' for i in xlengths]) + '\n' - table = table_divider - for i in range(len(ylengths)): - row = [column[i] for column in contents] - row = [entry + '\n' * (ylengths[i]-len(entry.split('\n'))) for entry in row] - row = [entry.split('\n') for entry in row] - for j in range(ylengths[i]): - k = 0 - for entry in row: - width = xlengths[k] - table += ''.join(['| {:{}}'.format(entry[j], width - 1)]) - k += 1 - table += '|\n' - table += table_divider - return table + '\n' - -def gen_rst(results): - """ creates restructured text documents to display tests """ - - # make sure the destination directory exists - try: - os.mkdir(DOCPATH) - except OSError as e: - if e.args[0] != errno.EEXIST and e.args[0] != errno.EISDIR: - raise - - toctree = [] - class_ = [] - for output in results: - section = output.class_.split(',') - for i in range(len(section)): - section[i] = section[i].rstrip() - if section[i] in CLASSMAP: - section[i] = CLASSMAP[section[i]] - if i >= len(class_) or section[i] != class_[i]: - if i == 0: - filename = section[i].replace(' ', '_').lower() - rst = open(DOCPATH + filename + '.rst', 'w') - rst.write(HEADER) - rst.write(section[i] + '\n') - rst.write(RSTCHARS[0] * len(section[i])) - rst.write(time.strftime("\nGenerated %a %d %b %Y %X UTC\n\n", time.gmtime())) - toctree.append(filename) - else: - rst.write(section[i] + '\n') - rst.write(RSTCHARS[min(i, len(RSTCHARS)-1)] * len(section[i])) - rst.write('\n\n') - class_ = section - rst.write('.. _cpydiff_%s:\n\n' % output.name.rsplit('.', 1)[0]) - rst.write(output.desc + '\n') - rst.write('~' * len(output.desc) + '\n\n') - if output.cause != 'Unknown': - rst.write('**Cause:** ' + output.cause + '\n\n') - if output.workaround != 'Unknown': - rst.write('**Workaround:** ' + output.workaround + '\n\n') - - rst.write('Sample code::\n\n' + indent(output.code, TAB) + '\n') - output_cpy = indent(''.join(output.output_cpy[0:2]), TAB).rstrip() - output_cpy = ('::\n\n' if output_cpy != '' else '') + output_cpy - output_upy = indent(''.join(output.output_upy[0:2]), TAB).rstrip() - output_upy = ('::\n\n' if output_upy != '' else '') + output_upy - table = gen_table([['CPy output:', output_cpy], ['uPy output:', output_upy]]) - rst.write(table) - - template = open(INDEXTEMPLATE, 'r') - index = open(DOCPATH + INDEX, 'w') - index.write(HEADER) - index.write(template.read()) - for section in INDEXPRIORITY: - if section in toctree: - index.write(indent(section + '.rst', TAB)) - toctree.remove(section) - for section in toctree: - index.write(indent(section + '.rst', TAB)) - -def main(): - """ Main function """ - - # set search path so that test scripts find the test modules (and no other ones) - os.environ['PYTHONPATH'] = TESTPATH - os.environ['MICROPYPATH'] = TESTPATH - - files = readfiles() - results = run_tests(files) - gen_rst(results) - -main() diff --git a/tools/gen_display_resources.py b/tools/gen_display_resources.py new file mode 100644 index 00000000000..65600a195ba --- /dev/null +++ b/tools/gen_display_resources.py @@ -0,0 +1,197 @@ +import argparse + +import os +import struct +import sys + +sys.path.append("bitmap_font") +sys.path.append("../../tools/bitmap_font") + +from adafruit_bitmap_font import bitmap_font + +parser = argparse.ArgumentParser(description='Generate USB descriptors.') +parser.add_argument('--font', type=str, + help='Font path', required=True) +parser.add_argument('--extra_characters', type=str, + help='Unicode string of extra characters') +parser.add_argument('--sample_file', type=argparse.FileType('r'), + help='Text file that includes strings to support.') +parser.add_argument('--output_c_file', type=argparse.FileType('w'), required=True) + +args = parser.parse_args() + +class BitmapStub: + def __init__(self, width, height, color_depth): + self.width = width + self.rows = [b''] * height + + def _load_row(self, y, row): + self.rows[y] = bytes(row) + +f = bitmap_font.load_font(args.font, BitmapStub) + +# Load extra characters from the sample file. +sample_characters = set() +if args.sample_file: + for line in args.sample_file: + # Skip comments because we add additional characters in our huffman comments. + if line.startswith("//"): + continue + for c in line.strip(): + sample_characters.add(c) + +# Merge visible ascii, sample characters and extra characters. +visible_ascii = bytes(range(0x20, 0x7f)).decode("utf-8") +all_characters = visible_ascii +for c in sample_characters: + if c not in all_characters: + all_characters += c +if args.extra_characters: + all_characters.extend(args.extra_characters) +filtered_characters = all_characters + +# Try to pre-load all of the glyphs. Misses will still be slow later. +f.load_glyphs(set(all_characters)) + +# Get each glyph. +for c in all_characters: + g = f.get_glyph(ord(c)) + if not g: + print("Font missing character:", c, ord(c)) + filtered_characters = filtered_characters.replace(c, "") + continue + if g["shift"][1] != 0: + raise RuntimeError("y shift") + +x, y, dx, dy = f.get_bounding_box() +tile_x, tile_y = x - dx, y - dy +total_bits = tile_x * len(all_characters) +total_bits += 32 - total_bits % 32 +bytes_per_row = total_bits // 8 +b = bytearray(bytes_per_row * tile_y) + +for x, c in enumerate(filtered_characters): + g = f.get_glyph(ord(c)) + start_bit = x * tile_x + g["bounds"][2] + start_y = (tile_y - 2) - (g["bounds"][1] + g["bounds"][3]) + for y, row in enumerate(g["bitmap"].rows): + for i in range(g["bounds"][0]): + byte = i // 8 + bit = i % 8 + if row[byte] & (1 << (7-bit)) != 0: + overall_bit = start_bit + (start_y + y) * bytes_per_row * 8 + i + b[overall_bit // 8] |= 1 << (7 - (overall_bit % 8)) + + +extra_characters = "" +for c in filtered_characters: + if c not in visible_ascii: + extra_characters += c + +c_file = args.output_c_file + +c_file.write("""\ + +#include "shared-bindings/displayio/Palette.h" +#include "supervisor/shared/display.h" + +""") + +c_file.write("""\ +_displayio_color_t terminal_colors[2] = { + { + .rgb888 = 0x000000, + .rgb565 = 0x0000, + .luma = 0x00, + .chroma = 0 + }, + { + .rgb888 = 0xffffff, + .rgb565 = 0xffff, + .luma = 0xff, + .chroma = 0 + }, +}; + +displayio_palette_t supervisor_terminal_color = { + .base = {.type = &displayio_palette_type }, + .colors = terminal_colors, + .color_count = 2, + .needs_refresh = false +}; +""") + +c_file.write("""\ +displayio_tilegrid_t supervisor_terminal_text_grid = {{ + .base = {{ .type = &displayio_tilegrid_type }}, + .bitmap = (displayio_bitmap_t*) &supervisor_terminal_font_bitmap, + .pixel_shader = &supervisor_terminal_color, + .x = 16, + .y = 0, + .pixel_width = {1}, + .pixel_height = {2}, + .bitmap_width_in_tiles = {0}, + .tiles_in_bitmap = {0}, + .width_in_tiles = 1, + .height_in_tiles = 1, + .tile_width = {1}, + .tile_height = {2}, + .tiles = NULL, + .partial_change = false, + .full_change = false, + .first_draw = true, + .moved = false, + .inline_tiles = false, + .in_group = true +}}; +""".format(len(all_characters), tile_x, tile_y)) + +c_file.write("""\ +const uint32_t font_bitmap_data[{}] = {{ +""".format(bytes_per_row * tile_y // 4)) + +for i, word in enumerate(struct.iter_unpack(">I", b)): + c_file.write("0x{:08x}, ".format(word[0])) + if (i + 1) % (bytes_per_row // 4) == 0: + c_file.write("\n") + +c_file.write("""\ +}; +""") + +c_file.write("""\ +displayio_bitmap_t supervisor_terminal_font_bitmap = {{ + .base = {{.type = &displayio_bitmap_type }}, + .width = {}, + .height = {}, + .data = (size_t*) font_bitmap_data, + .stride = {}, + .bits_per_value = 1, + .x_shift = 5, + .x_mask = 0x1f, + .bitmask = 0x1, + .read_only = true +}}; +""".format(len(all_characters) * tile_x, tile_y, bytes_per_row / 4)) + + +c_file.write("""\ +const fontio_builtinfont_t supervisor_terminal_font = {{ + .base = {{.type = &fontio_builtinfont_type }}, + .bitmap = &supervisor_terminal_font_bitmap, + .width = {}, + .height = {}, + .unicode_characters = (const uint8_t*) "{}", + .unicode_characters_len = {} +}}; +""".format(tile_x, tile_y, extra_characters, len(extra_characters.encode("utf-8")))) + +c_file.write("""\ +terminalio_terminal_obj_t supervisor_terminal = { + .base = { .type = &terminalio_terminal_type }, + .font = &supervisor_terminal_font, + .cursor_x = 0, + .cursor_y = 0, + .tilegrid = &supervisor_terminal_text_grid +}; +""") diff --git a/tools/gen_usb_descriptor.py b/tools/gen_usb_descriptor.py new file mode 100644 index 00000000000..10bbf506634 --- /dev/null +++ b/tools/gen_usb_descriptor.py @@ -0,0 +1,480 @@ +import argparse + +import os +import sys + +sys.path.append("../../tools/usb_descriptor") + +from adafruit_usb_descriptor import audio, audio10, cdc, hid, midi, msc, standard, util +import hid_report_descriptors + +parser = argparse.ArgumentParser(description='Generate USB descriptors.') +parser.add_argument('--manufacturer', type=str, + help='manufacturer of the device') +parser.add_argument('--product', type=str, + help='product name of the device') +parser.add_argument('--vid', type=lambda x: int(x, 16), + help='vendor id') +parser.add_argument('--pid', type=lambda x: int(x, 16), + help='product id') +parser.add_argument('--serial_number_length', type=int, default=32, + help='length needed for the serial number in digits') +parser.add_argument('--output_c_file', type=argparse.FileType('w'), required=True) +parser.add_argument('--output_h_file', type=argparse.FileType('w'), required=True) + +args = parser.parse_args() + +class StringIndex: + """Assign a monotonically increasing index to each unique string. Start with 0.""" + string_to_index = {} + index_to_variable = {} + strings = [] + + @classmethod + def index(cls, string, *, variable_name = None): + if string in cls.string_to_index: + idx = cls.string_to_index[string] + if not cls.index_to_variable[idx]: + cls.index_to_variable[idx] = variable_name + return idx + else: + idx = len(cls.strings) + cls.string_to_index[string] = idx + cls.strings.append(string) + cls.index_to_variable[idx] = variable_name + return idx + + @classmethod + def strings_in_order(cls): + return cls.strings + + + +# langid must be the 0th string descriptor +LANGID_INDEX = StringIndex.index("\u0409", variable_name="language_id") +assert LANGID_INDEX == 0 +SERIAL_NUMBER_INDEX = StringIndex.index("S" * args.serial_number_length, variable_name="usb_serial_number") + +device = standard.DeviceDescriptor( + description="top", + idVendor=args.vid, + idProduct=args.pid, + iManufacturer=StringIndex.index(args.manufacturer), + iProduct=StringIndex.index(args.product), + iSerialNumber=SERIAL_NUMBER_INDEX) + +# Interface numbers are interface-set local and endpoints are interface local +# until util.join_interfaces renumbers them. + +cdc_union = cdc.Union( + description="CDC comm", + bMasterInterface=0x00, # Adjust this after interfaces are renumbered. + bSlaveInterface_list=[0x01]) # Adjust this after interfaces are renumbered. + +cdc_call_management = cdc.CallManagement( + description="CDC comm", + bmCapabilities=0x01, + bDataInterface=0x01) # Adjust this after interfaces are renumbered. + +cdc_comm_interface = standard.InterfaceDescriptor( + description="CDC comm", + bInterfaceClass=cdc.CDC_CLASS_COMM, # Communications Device Class + bInterfaceSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model + bInterfaceProtocol=cdc.CDC_PROTOCOL_NONE, + iInterface=StringIndex.index("CircuitPython CDC control"), + subdescriptors=[ + cdc.Header( + description="CDC comm", + bcdCDC=0x0110), + cdc_call_management, + cdc.AbstractControlManagement( + description="CDC comm", + bmCapabilities=0x02), + cdc_union, + standard.EndpointDescriptor( + description="CDC comm in", + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, + wMaxPacketSize=0x0040, + bInterval=0x10) + ]) + +cdc_data_interface = standard.InterfaceDescriptor( + description="CDC data", + bInterfaceClass=cdc.CDC_CLASS_DATA, + iInterface=StringIndex.index("CircuitPython CDC data"), + subdescriptors=[ + standard.EndpointDescriptor( + description="CDC data out", + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_OUT, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK), + standard.EndpointDescriptor( + description="CDC data in", + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK), + ]) + +cdc_interfaces = [cdc_comm_interface, cdc_data_interface] + +msc_interfaces = [ + standard.InterfaceDescriptor( + description="MSC", + bInterfaceClass=msc.MSC_CLASS, + bInterfaceSubClass=msc.MSC_SUBCLASS_TRANSPARENT, + bInterfaceProtocol=msc.MSC_PROTOCOL_BULK, + iInterface=StringIndex.index("CircuitPython Mass Storage"), + subdescriptors=[ + standard.EndpointDescriptor( + description="MSC in", + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK, + bInterval=0), + standard.EndpointDescriptor( + description="MSC out", + bEndpointAddress=0x1 | standard.EndpointDescriptor.DIRECTION_OUT, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK, + bInterval=0) + ] + ) +] + +# Include only these HID devices. +# DIGITIZER works on Linux but conflicts with MOUSE, so leave it out for now. +hid_devices = ("KEYBOARD", "MOUSE", "CONSUMER", "GAMEPAD") + +combined_hid_report_descriptor = hid.ReportDescriptor( + description="MULTIDEVICE", + report_descriptor=b''.join( + hid_report_descriptors.REPORT_DESCRIPTORS[name].report_descriptor for name in hid_devices )) + +hid_report_ids_dict = { name: hid_report_descriptors.REPORT_IDS[name] for name in hid_devices } +hid_report_lengths_dict = { name: hid_report_descriptors.REPORT_LENGTHS[name] for name in hid_devices } +hid_max_report_length = max(hid_report_lengths_dict.values()) + +# ASF4 expects keyboard and generic devices to have both in and out endpoints, +# and will fail (possibly silently) if both are not supplied. +hid_endpoint_in_descriptor = standard.EndpointDescriptor( + description="HID in", + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, + bInterval=10) + +hid_interfaces = [ + standard.InterfaceDescriptor( + description="HID Multiple Devices", + bInterfaceClass=hid.HID_CLASS, + bInterfaceSubClass=hid.HID_SUBCLASS_NOBOOT, + bInterfaceProtocol=hid.HID_PROTOCOL_NONE, + iInterface=StringIndex.index("CircuitPython HID"), + subdescriptors=[ + hid.HIDDescriptor( + description="HID", + wDescriptorLength=len(bytes(combined_hid_report_descriptor))), + hid_endpoint_in_descriptor, + ] + ), + ] + +# Audio! +# In and out here are relative to CircuitPython + +# USB OUT -> midi_in_jack_emb -> midi_out_jack_ext -> CircuitPython +midi_in_jack_emb = midi.InJackDescriptor( + description="MIDI PC -> CircuitPython", + bJackType=midi.JACK_TYPE_EMBEDDED, + iJack=StringIndex.index("CircuitPython usb_midi.ports[0]")) +midi_out_jack_ext = midi.OutJackDescriptor( + description="MIDI data out to user code.", + bJackType=midi.JACK_TYPE_EXTERNAL, + input_pins=[(midi_in_jack_emb, 1)], + iJack=0) + +# USB IN <- midi_out_jack_emb <- midi_in_jack_ext <- CircuitPython +midi_in_jack_ext = midi.InJackDescriptor( + description="MIDI data in from user code.", + bJackType=midi.JACK_TYPE_EXTERNAL, + iJack=0) +midi_out_jack_emb = midi.OutJackDescriptor( + description="MIDI PC <- CircuitPython", + bJackType=midi.JACK_TYPE_EMBEDDED, + input_pins=[(midi_in_jack_ext, 1)], + iJack=StringIndex.index("CircuitPython usb_midi.ports[1]")) + + +audio_midi_interface = standard.InterfaceDescriptor( + description="Midi goodness", + bInterfaceClass=audio.AUDIO_CLASS_DEVICE, + bInterfaceSubClass=audio.AUDIO_SUBCLASS_MIDI_STREAMING, + bInterfaceProtocol=audio.AUDIO_PROTOCOL_V1, + iInterface=StringIndex.index("CircuitPython MIDI"), + subdescriptors=[ + midi.Header( + jacks_and_elements=[ + midi_in_jack_emb, + midi_in_jack_ext, + midi_out_jack_emb, + midi_out_jack_ext + ], + ), + standard.EndpointDescriptor( + description="MIDI data out to CircuitPython", + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_OUT, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK), + midi.DataEndpointDescriptor(baAssocJack=[midi_in_jack_emb]), + standard.EndpointDescriptor( + description="MIDI data in from CircuitPython", + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK, + bInterval = 0x0), + midi.DataEndpointDescriptor(baAssocJack=[midi_out_jack_emb]), + ]) + +cs_ac_interface = audio10.AudioControlInterface( + description="Empty audio control", + audio_streaming_interfaces = [], + midi_streaming_interfaces = [ + audio_midi_interface + ] + ) + +audio_control_interface = standard.InterfaceDescriptor( + description="All the audio", + bInterfaceClass=audio.AUDIO_CLASS_DEVICE, + bInterfaceSubClass=audio.AUDIO_SUBCLASS_CONTROL, + bInterfaceProtocol=audio.AUDIO_PROTOCOL_V1, + iInterface=StringIndex.index("CircuitPython Audio"), + subdescriptors=[ + cs_ac_interface, + ]) + +# Audio streaming interfaces must occur before MIDI ones. +audio_interfaces = [audio_control_interface] + cs_ac_interface.audio_streaming_interfaces + cs_ac_interface.midi_streaming_interfaces + +# This will renumber the endpoints to make them unique across descriptors, +# and renumber the interfaces in order. But we still need to fix up certain +# interface cross-references. +interfaces = util.join_interfaces(cdc_interfaces, msc_interfaces, hid_interfaces, audio_interfaces) + +# Now adjust the CDC interface cross-references. + +cdc_union.bMasterInterface = cdc_comm_interface.bInterfaceNumber +cdc_union.bSlaveInterface_list = [cdc_data_interface.bInterfaceNumber] + +cdc_call_management.bDataInterface = cdc_data_interface.bInterfaceNumber + +cdc_iad = standard.InterfaceAssociationDescriptor( + description="CDC IAD", + bFirstInterface=cdc_comm_interface.bInterfaceNumber, + bInterfaceCount=len(cdc_interfaces), + bFunctionClass=cdc.CDC_CLASS_COMM, # Communications Device Class + bFunctionSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model + bFunctionProtocol=cdc.CDC_PROTOCOL_NONE) + +descriptor_list = [] +descriptor_list.append(cdc_iad) +descriptor_list.extend(cdc_interfaces) +descriptor_list.extend(msc_interfaces) +# Only add the control interface because other audio interfaces are managed by it to ensure the +# correct ordering. +descriptor_list.append(audio_control_interface) +# Put the CDC IAD just before the CDC interfaces. +# There appears to be a bug in the Windows composite USB driver that requests the +# HID report descriptor with the wrong interface number if the HID interface is not given +# first. However, it still fetches the descriptor anyway. We could reorder the interfaces but +# the Windows 7 Adafruit_usbser.inf file thinks CDC is at Interface 0, so we'll leave it +# there for backwards compatibility. +descriptor_list.extend(hid_interfaces) + +configuration = standard.ConfigurationDescriptor( + description="Composite configuration", + wTotalLength=(standard.ConfigurationDescriptor.bLength + + sum([len(bytes(x)) for x in descriptor_list])), + bNumInterfaces=len(interfaces)) +descriptor_list.insert(0, configuration) + +string_descriptors = [standard.StringDescriptor(string) for string in StringIndex.strings_in_order()] +serial_number_descriptor = string_descriptors[SERIAL_NUMBER_INDEX] + +c_file = args.output_c_file +h_file = args.output_h_file + + +c_file.write("""\ +#include + +#include "{H_FILE_NAME}" + +""".format(H_FILE_NAME=h_file.name)) + +c_file.write("""\ +// {DESCRIPTION} : {CLASS} +""".format(DESCRIPTION=device.description, + CLASS=device.__class__)) + +c_file.write("""\ +const uint8_t usb_desc_dev[] = { +""") +for b in bytes(device): + c_file.write("0x{:02x}, ".format(b)) + +c_file.write("""\ +}; +""") + +c_file.write("""\ +const uint8_t usb_desc_cfg[] = { +""") + +# Write out all the regular descriptors as one long array (that's how ASF4 does it). +descriptor_length = 0 +for descriptor in descriptor_list: + c_file.write("""\ +// {DESCRIPTION} : {CLASS} +""".format(DESCRIPTION=descriptor.description, + CLASS=descriptor.__class__)) + + b = bytes(descriptor) + notes = descriptor.notes() + i = 0 + + # This prints each subdescriptor on a separate line. + n = 0 + while i < len(b): + length = b[i] + for j in range(length): + c_file.write("0x{:02x}, ".format(b[i + j])) + c_file.write("// " + notes[n]) + n += 1 + c_file.write("\n") + i += length + descriptor_length += len(b) + +c_file.write("""\ +}; +""") + +pointers_to_strings = [] + +for idx, descriptor in enumerate(string_descriptors): + c_file.write("""\ +// {DESCRIPTION} : {CLASS} +""".format(DESCRIPTION=descriptor.description, + CLASS=descriptor.__class__)) + + b = bytes(descriptor) + notes = descriptor.notes() + i = 0 + + # This prints each subdescriptor on a separate line. + variable_name = StringIndex.index_to_variable[idx] + if not variable_name: + variable_name = "string_descriptor{}".format(idx) + + const = "const " + if variable_name == "usb_serial_number": + const = "" + c_file.write("""\ +{const}uint16_t {NAME}[] = {{ +""".format(const=const, NAME=variable_name)) + pointers_to_strings.append("{name}".format(name=variable_name)) + n = 0 + while i < len(b): + length = b[i] + for j in range(length // 2): + c_file.write("0x{:04x}, ".format(b[i + 2*j + 1] << 8 | b[i + 2*j])) + n += 1 + c_file.write("\n") + i += length + c_file.write("""\ +}; +""") + +c_file.write("""\ +// array of pointer to string descriptors +uint16_t const * const string_desc_arr [] = +{ +""") +c_file.write(""",\ + +""".join(pointers_to_strings)) + +c_file.write(""" +}; +""") + +c_file.write("\n"); + +hid_descriptor_length = len(bytes(combined_hid_report_descriptor)) + +# Now we values we need for the .h file. +h_file.write("""\ +#ifndef MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H +#define MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H + +#include + +const uint8_t usb_desc_dev[{device_length}]; +// Make sure the control buffer is big enough to fit the descriptor. +#define CFG_TUD_ENUM_BUFFER_SIZE {max_configuration_length} +const uint8_t usb_desc_cfg[{configuration_length}]; +uint16_t usb_serial_number[{serial_number_length}]; +uint16_t const * const string_desc_arr [{string_descriptor_length}]; + +const uint8_t hid_report_descriptor[{HID_REPORT_DESCRIPTOR_LENGTH}]; + +// Vendor name included in Inquiry response, max 8 bytes +#define CFG_TUD_MSC_VENDOR "{msc_vendor}" + +// Product name included in Inquiry response, max 16 bytes +#define CFG_TUD_MSC_PRODUCT "{msc_product}" + +""" +.format(serial_number_length=len(bytes(serial_number_descriptor)) // 2, + device_length=len(bytes(device)), + configuration_length=descriptor_length, + max_configuration_length=max(hid_descriptor_length, descriptor_length), + string_descriptor_length=len(pointers_to_strings), + HID_REPORT_DESCRIPTOR_LENGTH=len(bytes(combined_hid_report_descriptor)), + msc_vendor=args.manufacturer[:8], + msc_product=args.product[:16])) + +# #define the report ID's used in the combined HID descriptor +for name, id in hid_report_ids_dict.items(): + h_file.write("""\ +#define USB_HID_REPORT_ID_{name} {id} +""".format(name=name, + id=id)) + +h_file.write("\n") + +# #define the report sizes used in the combined HID descriptor +for name, length in hid_report_lengths_dict.items(): + h_file.write("""\ +#define USB_HID_REPORT_LENGTH_{name} {length} +""".format(name=name, + length=length)) + +h_file.write("\n") + +h_file.write("""\ +#define USB_HID_NUM_DEVICES {num_devices} +#define USB_HID_MAX_REPORT_LENGTH {max_length} +""".format(num_devices=len(hid_report_lengths_dict), + max_length=hid_max_report_length)) + + + +# Write out the report descriptor and info +c_file.write("""\ +const uint8_t hid_report_descriptor[{HID_DESCRIPTOR_LENGTH}] = {{ +""".format(HID_DESCRIPTOR_LENGTH=hid_descriptor_length)) + +for b in bytes(combined_hid_report_descriptor): + c_file.write("0x{:02x}, ".format(b)) +c_file.write(""" +}; +""") + +h_file.write("""\ +#endif // MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H +""") diff --git a/tools/git-checkout-latest-tag.sh b/tools/git-checkout-latest-tag.sh new file mode 100755 index 00000000000..f6242a946de --- /dev/null +++ b/tools/git-checkout-latest-tag.sh @@ -0,0 +1,3 @@ +#!/bin/bash +git fetch --tags +git checkout $(git describe --tags `git rev-list --tags --max-count=1`) diff --git a/tools/hid_report_descriptors.py b/tools/hid_report_descriptors.py new file mode 100644 index 00000000000..f3b28ebcf38 --- /dev/null +++ b/tools/hid_report_descriptors.py @@ -0,0 +1,239 @@ +# The MIT License (MIT) +# +# Copyright (c) 2018 Dan Halbert for Adafruit Industries +# +# 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. + +import struct + +""" +HID specific descriptors +======================== + +* Author(s): Dan Halbert +""" + +from adafruit_usb_descriptor import hid + +REPORT_IDS = { + "KEYBOARD" : 1, + "MOUSE" : 2, + "CONSUMER" : 3, + "SYS_CONTROL" : 4, + "GAMEPAD" : 5, + "DIGITIZER" : 6, + } + +# Byte count for each kind of report. Length does not include report ID in first byte. +REPORT_LENGTHS = { + "KEYBOARD" : 8, + "MOUSE" : 4, + "CONSUMER" : 2, + "SYS_CONTROL" : 1, + "GAMEPAD" : 6, + "DIGITIZER" : 5, + } + +KEYBOARD_WITH_ID = hid.ReportDescriptor( + description="KEYBOARD", + report_descriptor=bytes([ + # Regular keyboard + 0x05, 0x01, # Usage Page (Generic Desktop) + 0x09, 0x06, # Usage (Keyboard) + 0xA1, 0x01, # Collection (Application) + 0x85, REPORT_IDS["KEYBOARD"], # Report ID (1) + 0x05, 0x07, # Usage Page (Keyboard) + 0x19, 224, # Usage Minimum (224) + 0x29, 231, # Usage Maximum (231) + 0x15, 0x00, # Logical Minimum (0) + 0x25, 0x01, # Logical Maximum (1) + 0x75, 0x01, # Report Size (1) + 0x95, 0x08, # Report Count (8) + 0x81, 0x02, # Input (Data, Variable, Absolute) + 0x81, 0x01, # Input (Constant) + 0x19, 0x00, # Usage Minimum (0) + 0x29, 101, # Usage Maximum (101) + 0x15, 0x00, # Logical Minimum (0) + 0x25, 101, # Logical Maximum (101) + 0x75, 0x08, # Report Size (8) + 0x95, 0x06, # Report Count (6) + 0x81, 0x00, # Input (Data, Array) + 0x05, 0x08, # Usage Page (LED) + 0x19, 0x01, # Usage Minimum (1) + 0x29, 0x05, # Usage Maximum (5) + 0x15, 0x00, # Logical Minimum (0) + 0x25, 0x01, # Logical Maximum (1) + 0x75, 0x01, # Report Size (1) + 0x95, 0x05, # Report Count (5) + 0x91, 0x02, # Output (Data, Variable, Absolute) + 0x95, 0x03, # Report Count (3) + 0x91, 0x01, # Output (Constant) + 0xC0, # End Collection + ])) + +MOUSE_WITH_ID = hid.ReportDescriptor( + description="MOUSE", + report_descriptor=bytes([ + # Regular mouse + 0x05, 0x01, # Usage Page (Generic Desktop) + 0x09, 0x02, # Usage (Mouse) + 0xA1, 0x01, # Collection (Application) + 0x09, 0x01, # Usage (Pointer) + 0xA1, 0x00, # Collection (Physical) + 0x85, REPORT_IDS["MOUSE"], # Report ID (n) + 0x05, 0x09, # Usage Page (Button) + 0x19, 0x01, # Usage Minimum (0x01) + 0x29, 0x05, # Usage Maximum (0x05) + 0x15, 0x00, # Logical Minimum (0) + 0x25, 0x01, # Logical Maximum (1) + 0x95, 0x05, # Report Count (5) + 0x75, 0x01, # Report Size (1) + 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x95, 0x01, # Report Count (1) + 0x75, 0x03, # Report Size (3) + 0x81, 0x01, # Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x05, 0x01, # Usage Page (Generic Desktop Ctrls) + 0x09, 0x30, # Usage (X) + 0x09, 0x31, # Usage (Y) + 0x15, 0x81, # Logical Minimum (-127) + 0x25, 0x7F, # Logical Maximum (127) + 0x75, 0x08, # Report Size (8) + 0x95, 0x02, # Report Count (2) + 0x81, 0x06, # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) + 0x09, 0x38, # Usage (Wheel) + 0x15, 0x81, # Logical Minimum (-127) + 0x25, 0x7F, # Logical Maximum (127) + 0x75, 0x08, # Report Size (8) + 0x95, 0x01, # Report Count (1) + 0x81, 0x06, # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) + 0xC0, # End Collection + 0xC0, # End Collection + ])) + +CONSUMER_WITH_ID = hid.ReportDescriptor( + description="CONSUMER", + report_descriptor=bytes([ + # Consumer ("multimedia") keys + 0x05, 0x0C, # Usage Page (Consumer) + 0x09, 0x01, # Usage (Consumer Control) + 0xA1, 0x01, # Collection (Application) + 0x85, REPORT_IDS["CONSUMER"], # Report ID (n) + 0x75, 0x10, # Report Size (16) + 0x95, 0x01, # Report Count (1) + 0x15, 0x01, # Logical Minimum (1) + 0x26, 0x8C, 0x02, # Logical Maximum (652) + 0x19, 0x01, # Usage Minimum (Consumer Control) + 0x2A, 0x8C, 0x02, # Usage Maximum (AC Send) + 0x81, 0x00, # Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0xC0, # End Collection + ])) + +SYS_CONTROL_WITH_ID = hid.ReportDescriptor( + description="SYS_CONTROL", + report_descriptor=bytes([ + # Power controls + 0x05, 0x01, # Usage Page (Generic Desktop Ctrls) + 0x09, 0x80, # Usage (Sys Control) + 0xA1, 0x01, # Collection (Application) + 0x85, REPORT_IDS["SYS_CONTROL"], # Report ID (n) + 0x75, 0x02, # Report Size (2) + 0x95, 0x01, # Report Count (1) + 0x15, 0x01, # Logical Minimum (1) + 0x25, 0x03, # Logical Maximum (3) + 0x09, 0x82, # Usage (Sys Sleep) + 0x09, 0x81, # Usage (Sys Power Down) + 0x09, 0x83, # Usage (Sys Wake Up) + 0x81, 0x60, # Input (Data,Array,Abs,No Wrap,Linear,No Preferred State,Null State) + 0x75, 0x06, # Report Size (6) + 0x81, 0x03, # Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0xC0, # End Collection + ])) + +GAMEPAD_WITH_ID = hid.ReportDescriptor( + description="GAMEPAD", + report_descriptor=bytes([ + # Gamepad with 16 buttons and two joysticks + 0x05, 0x01, # Usage Page (Generic Desktop Ctrls) + 0x09, 0x05, # Usage (Game Pad) + 0xA1, 0x01, # Collection (Application) + 0x85, REPORT_IDS["GAMEPAD"], # Report ID (n) + 0x05, 0x09, # Usage Page (Button) + 0x19, 0x01, # Usage Minimum (Button 1) + 0x29, 0x10, # Usage Maximum (Button 16) + 0x15, 0x00, # Logical Minimum (0) + 0x25, 0x01, # Logical Maximum (1) + 0x75, 0x01, # Report Size (1) + 0x95, 0x10, # Report Count (16) + 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x05, 0x01, # Usage Page (Generic Desktop Ctrls) + 0x15, 0x81, # Logical Minimum (-127) + 0x25, 0x7F, # Logical Maximum (127) + 0x09, 0x30, # Usage (X) + 0x09, 0x31, # Usage (Y) + 0x09, 0x32, # Usage (Z) + 0x09, 0x35, # Usage (Rz) + 0x75, 0x08, # Report Size (8) + 0x95, 0x04, # Report Count (4) + 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0xC0, # End Collection + ])) + +DIGITIZER_WITH_ID = hid.ReportDescriptor( + description="DIGITIZER", + report_descriptor=bytes([ + # Digitizer (used as an absolute pointer) + 0x05, 0x0D, # Usage Page (Digitizers) + 0x09, 0x02, # Usage (Pen) + 0xA1, 0x01, # Collection (Application) + 0x85, REPORT_IDS["DIGITIZER"], # Report ID (n) + 0x09, 0x01, # Usage (Stylus) + 0xA1, 0x00, # Collection (Physical) + 0x09, 0x32, # Usage (In-Range) + 0x09, 0x42, # Usage (Tip Switch) + 0x09, 0x44, # Usage (Barrel Switch) + 0x09, 0x45, # Usage (Eraser Switch) + 0x15, 0x00, # Logical Minimum (0) + 0x25, 0x01, # Logical Maximum (1) + 0x75, 0x01, # Report Size (1) + 0x95, 0x04, # Report Count (4) + 0x81, 0x02, # Input (Data,Var,Abs) + 0x75, 0x04, # Report Size (4) -- Filler + 0x95, 0x01, # Report Count (1) -- Filler + 0x81, 0x01, # Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x05, 0x01, # Usage Page (Generic Desktop Ctrls) + 0x15, 0x00, # Logical Minimum (0) + 0x26, 0xff, 0x7f, # Logical Maximum (32767) + 0x09, 0x30, # Usage (X) + 0x09, 0x31, # Usage (Y) + 0x75, 0x10, # Report Size (16) + 0x95, 0x02, # Report Count (2) + 0x81, 0x02, # Input (Data,Var,Abs) + 0xC0, # End Collection + 0xC0, # End Collection + ])) + +# Byte count for each kind of report. Length does not include report ID in first byte. +REPORT_DESCRIPTORS = { + "KEYBOARD" : KEYBOARD_WITH_ID, + "MOUSE" : MOUSE_WITH_ID, + "CONSUMER" : CONSUMER_WITH_ID, + "SYS_CONTROL" : SYS_CONTROL_WITH_ID, + "GAMEPAD" : GAMEPAD_WITH_ID, + "DIGITIZER" : DIGITIZER_WITH_ID, + } diff --git a/tools/huffman b/tools/huffman new file mode 160000 index 00000000000..27b1bba7619 --- /dev/null +++ b/tools/huffman @@ -0,0 +1 @@ +Subproject commit 27b1bba76198a0b343f694a6d680b5293d1c56aa diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index eeb760a5f6c..5ce24061bc8 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -78,6 +78,18 @@ class Config: MP_BC_LOAD_ATTR = 0x1e MP_BC_STORE_ATTR = 0x26 +# load opcode names +opcode_names = {} +with open("../../py/bc0.h") as f: + for line in f.readlines(): + if line.startswith("#define"): + s = line.split(maxsplit=3) + if len(s) < 3: + continue + _, name, value = s[:3] + opcode = int(value.strip("()"), 0) + opcode_names[opcode] = name + def make_opcode_format(): def OC4(a, b, c, d): return a | (b << 2) | (c << 4) | (d << 6) @@ -252,35 +264,50 @@ def freeze(self, parent_name): i += 1 RawCode.escaped_names.add(self.escaped_name) + sizes = {"bytecode": 0, "strings": 0, "raw_code_overhead": 0, "const_table_overhead": 0, "string_overhead": 0, "number_overhead": 0} # emit children first for rc in self.raw_codes: - rc.freeze(self.escaped_name + '_') + subsize = rc.freeze(self.escaped_name + '_') + for k in sizes: + sizes[k] += subsize[k] + # generate bytecode data print() print('// frozen bytecode for file %s, scope %s%s' % (self.source_file.str, parent_name, self.simple_name.str)) + print("// bytecode size", len(self.bytecode)) print('STATIC ', end='') if not config.MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE: print('const ', end='') print('byte bytecode_data_%s[%u] = {' % (self.escaped_name, len(self.bytecode))) + sizes["bytecode"] += len(self.bytecode) print(' ', end='') for i in range(self.ip2): print(' 0x%02x,' % self.bytecode[i], end='') print() + print(" // simple name") print(' ', self.simple_name.qstr_id, '& 0xff,', self.simple_name.qstr_id, '>> 8,') + print(" // source file") print(' ', self.source_file.qstr_id, '& 0xff,', self.source_file.qstr_id, '>> 8,') + print(" // code info") print(' ', end='') for i in range(self.ip2 + 4, self.ip): print(' 0x%02x,' % self.bytecode[i], end='') print() + print(" // bytecode") ip = self.ip while ip < len(self.bytecode): f, sz = mp_opcode_format(self.bytecode, ip) + opcode = self.bytecode[ip] + if opcode in opcode_names: + opcode = opcode_names[opcode] + else: + opcode = '0x%02x' % opcode if f == 1: qst = self._unpack_qstr(ip + 1).qstr_id - print(' ', '0x%02x,' % self.bytecode[ip], qst, '& 0xff,', qst, '>> 8,') + print(' {}, {} & 0xff, {} >> 8,'.format(opcode, qst, qst)) else: - print(' ', ''.join('0x%02x, ' % self.bytecode[ip + i] for i in range(sz))) + print(' {},{}'.format(opcode, ''.join(' 0x%02x,' % self.bytecode[ip + i] for i in range(1, sz)))) ip += sz print('};') @@ -295,9 +322,12 @@ def freeze(self, parent_name): obj_type = 'mp_type_str' else: obj_type = 'mp_type_bytes' - print('STATIC const mp_obj_str_t %s = {{&%s}, %u, %u, (const byte*)"%s"};' + print('STATIC const mp_obj_str_t %s = {{&%s}, %u, %u, (const byte*)"%s"}; // %s' % (obj_name, obj_type, qstrutil.compute_hash(obj, config.MICROPY_QSTR_BYTES_IN_HASH), - len(obj), ''.join(('\\x%02x' % b) for b in obj))) + len(obj), ''.join(('\\x%02x' % b) for b in obj), obj)) + sizes["strings"] += len(obj) + sizes["string_overhead"] += 16 + elif is_int_type(obj): if config.MICROPY_LONGINT_IMPL == config.MICROPY_LONGINT_IMPL_NONE: # TODO check if we can actually fit this long-int into a small-int @@ -321,14 +351,17 @@ def freeze(self, parent_name): print('STATIC const mp_obj_int_t %s = {{&mp_type_int}, ' '{.neg=%u, .fixed_dig=1, .alloc=%u, .len=%u, .dig=(uint%u_t[]){%s}}};' % (obj_name, neg, ndigs, ndigs, bits_per_dig, digs)) + sizes["number_overhead"] += 16 elif type(obj) is float: print('#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A || MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B') print('STATIC const mp_obj_float_t %s = {{&mp_type_float}, %.16g};' % (obj_name, obj)) print('#endif') + sizes["number_overhead"] += 8 elif type(obj) is complex: print('STATIC const mp_obj_complex_t %s = {{&mp_type_complex}, %.16g, %.16g};' % (obj_name, obj.real, obj.imag)) + sizes["number_overhead"] += 12 else: raise FreezeError(self, 'freezing of object %r is not implemented' % (obj,)) @@ -338,8 +371,10 @@ def freeze(self, parent_name): print('STATIC const mp_rom_obj_t const_table_data_%s[%u] = {' % (self.escaped_name, const_table_len)) for qst in self.qstrs: + sizes["const_table_overhead"] += 4 print(' MP_ROM_QSTR(%s),' % global_qstrs[qst].qstr_id) for i in range(len(self.objs)): + sizes["const_table_overhead"] += 4 if type(self.objs[i]) is float: print('#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A || MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B') print(' MP_ROM_PTR(&const_obj_%s_%u),' % (self.escaped_name, i)) @@ -353,6 +388,7 @@ def freeze(self, parent_name): else: print(' MP_ROM_PTR(&const_obj_%s_%u),' % (self.escaped_name, i)) for rc in self.raw_codes: + sizes["const_table_overhead"] += 4 print(' MP_ROM_PTR(&raw_code_%s),' % rc.escaped_name) print('};') @@ -376,6 +412,9 @@ def freeze(self, parent_name): print(' #endif') print(' },') print('};') + sizes["raw_code_overhead"] += 16 + + return sizes def read_uint(f): i = 0 @@ -467,6 +506,7 @@ def freeze_mpy(base_qstrs, raw_codes): new[q.qstr_esc] = (len(new), q.qstr_esc, q.str) new = sorted(new.values(), key=lambda x: x[0]) + print('#include "py/bc0.h"') print('#include "py/mpconfig.h"') print('#include "py/objint.h"') print('#include "py/objstr.h"') @@ -523,27 +563,45 @@ def freeze_mpy(base_qstrs, raw_codes): print(' %u, // allocated entries' % len(new)) print(' %u, // used entries' % len(new)) print(' {') + qstr_size = {"metadata": 0, "data": 0} for _, _, qstr in new: + qstr_size["metadata"] += config.MICROPY_QSTR_BYTES_IN_LEN + config.MICROPY_QSTR_BYTES_IN_HASH + qstr_size["data"] += len(qstr) print(' %s,' % qstrutil.make_bytes(config.MICROPY_QSTR_BYTES_IN_LEN, config.MICROPY_QSTR_BYTES_IN_HASH, qstr)) print(' },') print('};') + sizes = {} for rc in raw_codes: - rc.freeze(rc.source_file.str.replace('/', '_')[:-3] + '_') + sizes[rc.source_file.str] = rc.freeze(rc.source_file.str.replace('/', '_')[:-3] + '_') print() print('const char mp_frozen_mpy_names[] = {') + qstr_size["filenames"] = 1 for rc in raw_codes: module_name = rc.source_file.str print('"%s\\0"' % module_name) + qstr_size["filenames"] += len(module_name) + 1 print('"\\0"};') print('const mp_raw_code_t *const mp_frozen_mpy_content[] = {') for rc in raw_codes: print(' &raw_code_%s,' % rc.escaped_name) + size = sizes[rc.source_file.str] + print(' // Total size:', sum(size.values())) + for k in size: + print(" // {} {}".format(k, size[k])) print('};') + print() + print('// Total size:', sum([sum(x.values()) for x in sizes.values()]) + sum(qstr_size.values())) + for k in size: + total = sum([x[k] for x in sizes.values()]) + print("// {} {}".format(k, total)) + for k in qstr_size: + print("// qstr {} {}".format(k, qstr_size[k])) + def main(): import argparse cmd_parser = argparse.ArgumentParser(description='A tool to work with MicroPython .mpy files.') @@ -571,7 +629,7 @@ def main(): # set config values for qstrs, and get the existing base set of qstrs if args.qstr_header: - qcfgs, base_qstrs = qstrutil.parse_input_headers([args.qstr_header]) + qcfgs, base_qstrs, _ = qstrutil.parse_input_headers([args.qstr_header]) config.MICROPY_QSTR_BYTES_IN_LEN = int(qcfgs['BYTES_IN_LEN']) config.MICROPY_QSTR_BYTES_IN_HASH = int(qcfgs['BYTES_IN_HASH']) else: diff --git a/tools/output_gc_until_repl.txt b/tools/output_gc_until_repl.txt new file mode 100644 index 00000000000..81711deeb8d --- /dev/null +++ b/tools/output_gc_until_repl.txt @@ -0,0 +1,29 @@ +tar ext :2331 +monitor reset +set width 0 +set height 0 +set verbose off +set logging file mylog.txt +set logging overwrite on +set logging redirect on +set logging on +set remote hardware-breakpoint-limit 4 + +# gc log +break gc.c:103 +commands +backtrace +p/x start_block +p/x length +append binary memory ram.bin &_srelocate &_estack +continue +end + +break main.c:179 + +continue + +delete + +disconnect +quit diff --git a/tools/preprocess_frozen_modules.py b/tools/preprocess_frozen_modules.py new file mode 100755 index 00000000000..bb6959f0d88 --- /dev/null +++ b/tools/preprocess_frozen_modules.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +import argparse +import os +import os.path +from pathlib import Path +import semver +import subprocess + +# Compatible with Python 3.4 due to travis using trusty as default. + +def version_string(path=None, *, valid_semver=False): + version = None + try: + tag = subprocess.check_output('git describe --tags --exact-match', shell=True, cwd=path) + version = tag.strip().decode("utf-8", "strict") + except subprocess.CalledProcessError: + describe = subprocess.check_output("git describe --tags", shell=True, cwd=path) + tag, additional_commits, commitish = describe.strip().decode("utf-8", "strict").rsplit("-", maxsplit=2) + commitish = commitish[1:] + if valid_semver: + version_info = semver.parse_version_info(tag) + if not version_info.prerelease: + version = semver.bump_patch(tag) + "-alpha.0.plus." + additional_commits + "+" + commitish + else: + version = tag + ".plus." + additional_commits + "+" + commitish + else: + version = commitish + return version + +# Visit all the .py files in topdir. Replace any __version__ = "0.0.0-auto.0" type of info +# with actual version info derived from git. +def copy_and_process(in_dir, out_dir): + for root, subdirs, files in os.walk(in_dir): + + # Skip library examples directories. + if Path(root).name in ['examples', 'docs', 'tests']: + continue + + for file in files: + # Skip top-level setup.py (module install info) and conf.py (sphinx config), + # which are not part of the library + if (root == in_dir) and file in ('conf.py', 'setup.py'): + continue + + input_file_path = Path(root, file) + output_file_path = Path(out_dir, input_file_path.relative_to(in_dir)) + + if file.endswith(".py"): + if not output_file_path.parent.exists(): + output_file_path.parent.mkdir(parents=True) + with input_file_path.open("r") as input, output_file_path.open("w") as output: + for line in input: + if line.startswith("__version__"): + module_version = version_string(root, valid_semver=True) + line = line.replace("0.0.0-auto.0", module_version) + output.write(line) + +if __name__ == '__main__': + argparser = argparse.ArgumentParser(description="""\ + Copy and pre-process .py files into output directory, before freezing. + 1. Remove top-level repo directory. + 2. Update __version__ info. + 3. Remove examples. + 4. Remove non-library setup.py and conf.py""") + argparser.add_argument("in_dirs", metavar="input-dir", nargs="+", + help="top-level code dirs (may be git repo dirs)") + argparser.add_argument("-o", "--out_dir", help="output directory") + args = argparser.parse_args() + + for in_dir in args.in_dirs: + copy_and_process(in_dir, args.out_dir) diff --git a/tools/print_status.py b/tools/print_status.py new file mode 100755 index 00000000000..ed563fd68bd --- /dev/null +++ b/tools/print_status.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 + +import sys +if len(sys.argv) != 2: + print("""\ +Usage: print_status.py STATUS_FILENAME + STATUS_FILENAME contains one line with an integer status.""" + ) + sys.exit(1) +with open(sys.argv[1], 'r') as status_in: + status = int(status_in.readline()) + +print('{} with status {}'.format( + "\033[32msucceeded\033[0m" if status == 0 else "\033[31mfailed\033[0m", + status)) diff --git a/tools/python-semver b/tools/python-semver new file mode 160000 index 00000000000..2001c62d1a0 --- /dev/null +++ b/tools/python-semver @@ -0,0 +1 @@ +Subproject commit 2001c62d1a0361c44acc7076d8ce91e1d1c66141 diff --git a/tools/tinytest-codegen.py b/tools/tinytest-codegen.py index ad3b3bbec95..7a48f8a9a74 100755 --- a/tools/tinytest-codegen.py +++ b/tools/tinytest-codegen.py @@ -23,10 +23,27 @@ def chew_filename(t): def script_to_map(test_file): r = {"name": chew_filename(test_file)["func"]} - with open(test_file, "rb") as f: - r["script"] = escape(f.read()) + with open(test_file, "rb") as test: + script = test.readlines() + + # Test for import skip_if and inject it into the test as needed. + if "import skip_if\n" in script: + index = script.index("import skip_if\n") + script.pop(index) + script.insert(index, "class skip_if:\n") + with open("../tests/skip_if.py") as skip_if: + total_lines = 1 + for line in skip_if: + stripped = line.strip() + if not stripped or stripped.startswith(("#", "\"\"\"")): + continue + script.insert(index + total_lines, "\t" + line) + total_lines += 1 + r['script'] = escape(b''.join(script)) + with open(test_file + ".exp", "rb") as f: r["output"] = escape(f.read()) + return r test_function = ( diff --git a/tools/uf2 b/tools/uf2 new file mode 160000 index 00000000000..968716efd30 --- /dev/null +++ b/tools/uf2 @@ -0,0 +1 @@ +Subproject commit 968716efd30600984139d706bcbd8ec1a1b2336d diff --git a/tools/upload_release_files.py b/tools/upload_release_files.py new file mode 100755 index 00000000000..6c842dc6847 --- /dev/null +++ b/tools/upload_release_files.py @@ -0,0 +1,32 @@ +#! /usr/bin/env python3 + +import os +import os.path +import sys +import uritemplate + +sys.path.append("adabot") +import adabot.github_requests as github + +exit_status = 0 + +for dirpath, dirnames, filenames in os.walk("../bin"): + if not filenames: + continue + for filename in filenames: + full_filename = os.path.join(dirpath, filename) + label = filename.replace("adafruit-circuitpython-", "") + url_vars = {} + url_vars["name"] = filename + url_vars["label"] = label + url = uritemplate.expand(os.environ["UPLOAD_URL"], url_vars) + headers = {"content-type": "application/octet-stream"} + print(url) + with open(full_filename, "rb") as f: + response = github.post(url, data=f, headers=headers) + if not response.ok: + print("Upload of {} failed with {}.".format(filename, response.status_code)) + print(response.text) + sys.exit(response.status_code) + +sys.exit(exit_status) diff --git a/tools/usb_descriptor b/tools/usb_descriptor new file mode 160000 index 00000000000..dac9689e274 --- /dev/null +++ b/tools/usb_descriptor @@ -0,0 +1 @@ +Subproject commit dac9689e274844294bbe4fd1b78defff9ff27533